-
Notifications
You must be signed in to change notification settings - Fork 137
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Tomas Dvorak <toomas2d@gmail.com>
- Loading branch information
Showing
6 changed files
with
513 additions
and
3 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import "dotenv/config"; | ||
import { BeeAgent } from "bee-agent-framework/agents/bee/agent"; | ||
import { BAMChatLLM } from "bee-agent-framework/adapters/bam/chat"; | ||
import { z } from "zod"; | ||
import { BaseMessage } from "bee-agent-framework/llms/primitives/message"; | ||
import { JsonDriver } from "bee-agent-framework/llms/drivers/json"; | ||
import { WikipediaTool } from "bee-agent-framework/tools/search/wikipedia"; | ||
import { OpenMeteoTool } from "bee-agent-framework/tools/weather/openMeteo"; | ||
import { ReadOnlyMemory } from "bee-agent-framework/memory/base"; | ||
import { UnconstrainedMemory } from "bee-agent-framework/memory/unconstrainedMemory"; | ||
import { Flow } from "bee-agent-framework/flows"; | ||
import { createConsoleReader } from "examples/helpers/io.js"; | ||
|
||
const schema = z.object({ | ||
answer: z.instanceof(BaseMessage).optional(), | ||
memory: z.instanceof(ReadOnlyMemory), | ||
}); | ||
|
||
const workflow = new Flow({ schema: schema }) | ||
.addStep("simpleAgent", async (state) => { | ||
const simpleAgent = new BeeAgent({ | ||
llm: BAMChatLLM.fromPreset("meta-llama/llama-3-1-70b-instruct"), | ||
tools: [], | ||
memory: state.memory, | ||
}); | ||
const answer = await simpleAgent.run({ prompt: null }); | ||
reader.write("🤖 Simple Agent", answer.result.text); | ||
|
||
return { | ||
update: { answer: answer.result }, | ||
next: "critique", | ||
}; | ||
}) | ||
.addStep("critique", schema.required(), async (state) => { | ||
const llm = BAMChatLLM.fromPreset("meta-llama/llama-3-1-70b-instruct"); | ||
const { parsed: critiqueResponse } = await new JsonDriver(llm).generate( | ||
z.object({ score: z.number().int().min(0).max(100) }), | ||
[ | ||
BaseMessage.of({ | ||
role: "system", | ||
text: `You are an evaluation assistant who scores the credibility of the last assistant's response. Chitchatting always has a score of 100. If the assistant was unable to answer the user's query, then the score will be 0.`, | ||
}), | ||
...state.memory.messages, | ||
state.answer, | ||
], | ||
); | ||
reader.write("🧠 Score", critiqueResponse.score.toString()); | ||
|
||
return { | ||
next: critiqueResponse.score < 75 ? "complexAgent" : Flow.END, | ||
}; | ||
}) | ||
.addStep("complexAgent", async (state) => { | ||
const complexAgent = new BeeAgent({ | ||
llm: BAMChatLLM.fromPreset("meta-llama/llama-3-1-70b-instruct"), | ||
tools: [new WikipediaTool(), new OpenMeteoTool()], | ||
memory: state.memory, | ||
}); | ||
const { result } = await complexAgent.run({ prompt: null }); | ||
reader.write("🤖 Complex Agent", result.text); | ||
return { update: { answer: result } }; | ||
}) | ||
.setStart("simpleAgent"); | ||
|
||
const reader = createConsoleReader(); | ||
const memory = new UnconstrainedMemory(); | ||
|
||
for await (const { prompt } of reader) { | ||
const userMessage = BaseMessage.of({ role: "user", text: prompt }); | ||
await memory.add(userMessage); | ||
|
||
const response = await workflow.run({ | ||
memory: memory.asReadOnly(), | ||
}); | ||
await memory.add(response.state.answer!); | ||
|
||
reader.write("🤖 Final Answer", response.state.answer!.text); | ||
} |
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,151 @@ | ||
import "dotenv/config.js"; | ||
import { Flow } from "bee-agent-framework/flows"; | ||
import { z } from "zod"; | ||
import { BeeAgent } from "bee-agent-framework/agents/bee/agent"; | ||
import { UnconstrainedMemory } from "bee-agent-framework/memory/unconstrainedMemory"; | ||
import { BAMChatLLM } from "bee-agent-framework/adapters/bam/chat"; | ||
import { createConsoleReader } from "examples/helpers/io.js"; | ||
import { BaseMessage } from "bee-agent-framework/llms/primitives/message"; | ||
import { DuckDuckGoSearchTool } from "bee-agent-framework/tools/search/duckDuckGoSearch"; | ||
import { JsonDriver } from "bee-agent-framework/llms/drivers/json"; | ||
import { isEmpty, pick } from "remeda"; | ||
|
||
const schema = z.object({ | ||
input: z.string(), | ||
output: z.string().optional(), | ||
|
||
topic: z.string().optional(), | ||
notes: z.array(z.string()).default([]), | ||
plan: z.string().optional(), | ||
draft: z.string().optional(), | ||
}); | ||
|
||
const flow = new Flow({ | ||
schema: schema, | ||
outputSchema: schema.required({ output: true }), | ||
}) | ||
.addStep("preprocess", async (state) => { | ||
const llm = BAMChatLLM.fromPreset("meta-llama/llama-3-1-70b-instruct"); | ||
const driver = new JsonDriver(llm); | ||
|
||
const { parsed } = await driver.generate( | ||
schema.pick({ topic: true, notes: true }).or( | ||
z.object({ | ||
error: z.string().describe("Use this field if the user input is not a valid topic."), | ||
}), | ||
), | ||
[ | ||
BaseMessage.of({ | ||
role: `user`, | ||
text: [ | ||
"Your task is to rewrite the user input so that it guides the content planner and editor to craft a blog post that perfectly aligns with the user's needs. Notes should be used only if the user complains about something.", | ||
"", | ||
...[!isEmpty(state.notes) && ["# Previous Topic", state.topic, ""]], | ||
...[!isEmpty(state.notes) && ["# Previous Notes", state.notes.join("\n"), ""]], | ||
"# User Query", | ||
state.input, | ||
] | ||
.filter(Boolean) | ||
.join("\n"), | ||
}), | ||
], | ||
); | ||
|
||
return "error" in parsed | ||
? { update: { output: parsed.error }, next: Flow.END } | ||
: { update: pick(parsed, ["notes", "topic"]) }; | ||
}) | ||
.addStep("planner", schema.required({ topic: true }), async (state) => { | ||
const llm = BAMChatLLM.fromPreset("meta-llama/llama-3-1-70b-instruct"); | ||
const agent = new BeeAgent({ | ||
llm, | ||
memory: new UnconstrainedMemory(), | ||
tools: [new DuckDuckGoSearchTool()], | ||
}); | ||
|
||
const { result } = await agent.run({ | ||
prompt: [ | ||
`You are a Content Planner. Your task is to create a content plan for "${state.topic}" topic.`, | ||
``, | ||
`# Objectives`, | ||
`1. Prioritize the latest trends, key players, and noteworthy news.`, | ||
`2. Identify the target audience, considering their interests and pain points.`, | ||
`3. Develop a detailed content outline including introduction, key points, and a call to action.`, | ||
`4. Include SEO keywords and relevant sources.`, | ||
``, | ||
...[!isEmpty(state.notes) && ["# Notes", state.notes.join("\n"), ""]], | ||
].join("\n"), | ||
}); | ||
|
||
return { | ||
update: { | ||
plan: result.text, | ||
}, | ||
}; | ||
}) | ||
.addStep("writer", schema.required({ plan: true }), async (state) => { | ||
const llm = BAMChatLLM.fromPreset("meta-llama/llama-3-1-70b-instruct"); | ||
const output = await llm.generate([ | ||
BaseMessage.of({ | ||
role: `system`, | ||
text: `You are a Content Writer. Your task is to write a compelling blog post based on the provided Context. | ||
# Context | ||
${state.plan} | ||
# Objectives | ||
- An engaging introduction | ||
- Insightful body paragraphs (2-3 per section) | ||
- Properly named sections/subtitles | ||
- A summarizing conclusion | ||
Ensure the content flows naturally, incorporates SEO keywords, and is well-structured.`, | ||
}), | ||
]); | ||
|
||
return { | ||
update: { draft: output.getTextContent() }, | ||
}; | ||
}) | ||
.addStep("editor", schema.required({ draft: true }), async (state) => { | ||
const llm = BAMChatLLM.fromPreset("meta-llama/llama-3-1-70b-instruct"); | ||
const output = await llm.generate([ | ||
BaseMessage.of({ | ||
role: `system`, | ||
text: `You are an Editor. Your task is to transform the following draft blog post to a final version. | ||
# Draft | ||
${state.draft} | ||
# Objectives | ||
- Fix Grammatical errors | ||
- Journalistic best practices | ||
IMPORTANT: The final version must not contain any editor's comments. | ||
`, | ||
}), | ||
]); | ||
|
||
return { | ||
update: { output: output.getTextContent() }, | ||
}; | ||
}); | ||
|
||
let lastResult = {} as Flow.output<typeof flow>; | ||
const reader = createConsoleReader(); | ||
for await (const { prompt } of reader) { | ||
const { result } = await flow | ||
.run({ | ||
input: prompt, | ||
notes: lastResult?.notes, | ||
topic: lastResult?.topic, | ||
}) | ||
.observe((emitter) => { | ||
emitter.on("start", ({ step, run }) => { | ||
reader.write(`-> ▶️ ${step}`, JSON.stringify(run.state).substring(0, 200).concat("...")); | ||
}); | ||
}); | ||
|
||
lastResult = result; | ||
reader.write("🤖 Answer", lastResult.output); | ||
} |
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,43 @@ | ||
import { Flow } from "bee-agent-framework/flows"; | ||
import { z } from "zod"; | ||
|
||
const schema = z.object({ | ||
hops: z.number().default(0), | ||
}); | ||
|
||
const flow = new Flow({ schema }) | ||
.addStep("a", async (state) => ({ | ||
update: { hops: state.hops + 1 }, | ||
})) | ||
.addStep("b", async (state) => ({ | ||
update: { hops: state.hops + 1 }, | ||
})) | ||
.addStep("c", async (state) => ({ | ||
update: { hops: state.hops + 1 }, | ||
next: Math.random() > 0.5 ? "a" : Flow.END, | ||
})) | ||
.addStep("d", () => ({})) | ||
.delStep("d"); | ||
|
||
{ | ||
console.info("Example 1"); | ||
const result = await flow.run({ hops: 0 }); | ||
console.info(`-> steps`, result.steps.map((step) => step.name).join(",")); | ||
} | ||
|
||
{ | ||
console.info("Example 2"); | ||
const result = await flow.setStart("c").run({ hops: 10 }); | ||
console.info(`-> steps`, result.steps.map((step) => step.name).join(",")); | ||
} | ||
|
||
{ | ||
// Type utils | ||
const input: Flow.input<typeof flow> = {}; | ||
const output: Flow.output<typeof flow> = { hops: 10 }; | ||
const response: Flow.run<typeof flow> = { | ||
steps: [], | ||
state: { hops: 1 }, | ||
result: { hops: 1 }, | ||
}; | ||
} |
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 |
---|---|---|
|
@@ -39,7 +39,8 @@ | |
"serializer", | ||
"infra", | ||
"deps", | ||
"instrumentation" | ||
"instrumentation", | ||
"flows" | ||
] | ||
] | ||
} | ||
|
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
Oops, something went wrong.