-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: abstract model and remove context (#16)
Quite a few changes, but here's breakdown: - Removed context and made it flat with Workflow - Removed workflow.message.push in favor of passing messages as second argument in recursion. This will make workflow immutable and less stable in case it goes in parallel - Moved selectAgent and getNextTask to supervisor - Moved remaining files from index to teamwork (this is where main execution happens)
- Loading branch information
Showing
11 changed files
with
254 additions
and
224 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import OpenAI, { ClientOptions } from 'openai' | ||
import { ChatCompletionCreateParamsNonStreaming } from 'openai/resources/index.mjs' | ||
|
||
import { RequiredOptionals } from '../types.js' | ||
|
||
type OpenAIOptions = { | ||
model?: string | ||
options?: ClientOptions | ||
} | ||
|
||
const defaults: RequiredOptionals<OpenAIOptions> = { | ||
model: 'gpt-4o', | ||
options: {}, | ||
} | ||
|
||
type ChatCompletionParseParams = ChatCompletionCreateParamsNonStreaming | ||
|
||
/** | ||
* Helper utility to create a model configuration with defaults. | ||
*/ | ||
export const openai = (options?: OpenAIOptions) => { | ||
const config = { | ||
...defaults, | ||
...options, | ||
} | ||
|
||
const client = new OpenAI(config.options) | ||
|
||
return { | ||
model: config.model, | ||
completions: <T extends Omit<ChatCompletionParseParams, 'model'>>(params: T) => | ||
client.beta.chat.completions.parse.bind(client.beta.chat.completions)({ | ||
...params, | ||
model: config.model, | ||
}), | ||
client, | ||
} | ||
} | ||
|
||
export type Provider = ReturnType<typeof openai> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import s from 'dedent' | ||
import { zodResponseFormat } from 'openai/helpers/zod.mjs' | ||
import { z } from 'zod' | ||
|
||
import { Provider } from '../models/openai.js' | ||
import { Message } from '../types.js' | ||
|
||
export async function getNextTask(provider: Provider, history: Message[]): Promise<string | null> { | ||
const response = await provider.completions({ | ||
messages: [ | ||
{ | ||
role: 'system', | ||
// tbd: handle subsequent failures | ||
content: s` | ||
You are a planner that breaks down complex workflows into smaller, actionable steps. | ||
Your job is to determine the next task that needs to be done based on the original workflow and what has been completed so far. | ||
If all required tasks are completed, return null. | ||
Rules: | ||
1. Each task should be self-contained and achievable | ||
2. Tasks should be specific and actionable | ||
3. Return null when the workflow is complete | ||
4. Consider dependencies and order of operations | ||
5. Use context from completed tasks to inform next steps | ||
`, | ||
}, | ||
...history, | ||
{ | ||
role: 'user', | ||
content: 'What is the next task that needs to be done?', | ||
}, | ||
], | ||
temperature: 0.2, | ||
response_format: zodResponseFormat( | ||
z.object({ | ||
task: z | ||
.string() | ||
.describe('The next task to be completed or null if the workflow is complete') | ||
.nullable(), | ||
reasoning: z | ||
.string() | ||
.describe('The reasoning for selecting the next task or why the workflow is complete'), | ||
}), | ||
'next_task' | ||
), | ||
}) | ||
|
||
try { | ||
const content = response.choices[0].message.parsed | ||
if (!content) { | ||
throw new Error('No content in response') | ||
} | ||
|
||
if (!content.task) { | ||
return null | ||
} | ||
|
||
return content.task | ||
} catch (error) { | ||
throw new Error('Failed to determine next task') | ||
} | ||
} |
Oops, something went wrong.