Skip to content

Commit

Permalink
fix: pr 2
Browse files Browse the repository at this point in the history
Signed-off-by: Milan Gallas <[email protected]>
  • Loading branch information
Milan Gallas authored and Milan Gallas committed Jan 23, 2025
1 parent d722a54 commit f137a0e
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 8 deletions.
43 changes: 41 additions & 2 deletions docs/integrations.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ Bee Agent Framework is open-source framework for building, deploying, and servin
import "dotenv/config";
import { DuckDuckGoSearch as LangChainDDG } from "@langchain/community/tools/duckduckgo_search";
import { createReactAgent as createLangGraphReactAgent } from "@langchain/langgraph/prebuilt";
import type {
MessageContentComplex,
MessageContentImageUrl,
MessageContentText,
} from "@langchain/core/messages";
import { Workflow } from "bee-agent-framework/experimental/workflows/workflow";
import { z } from "zod";
import { createConsoleReader } from "examples/helpers/io.js";
Expand All @@ -22,6 +27,39 @@ import { UnconstrainedMemory } from "bee-agent-framework/memory/unconstrainedMem
import { BaseMessage } from "bee-agent-framework/llms/primitives/message";
import { ChatMessage as LangChainMessage } from "@langchain/core/messages";

//// LangGraph content parser helper functions ////

function isMessageContentText(content: any): content is MessageContentText {
return content.type === "text";
}

function isMessageContentImageUrl(content: any): content is MessageContentImageUrl {
return content.type === "image_url";
}

function parseImageUrl(imageUrl: MessageContentImageUrl["image_url"]) {
if (typeof imageUrl === "string") {
return imageUrl;
}

return imageUrl.url;
}

function parseContent(content: MessageContentComplex[] | undefined | string) {
if (!content || typeof content === "string") {
return content;
}

return content
.filter((c) => isMessageContentText(c) || isMessageContentImageUrl(c))
.map((c) => {
return isMessageContentText(c) ? c.text : parseImageUrl(c.image_url);
})
.join("\n");
}

//// workflow ////

const workflow = new Workflow({
schema: z.object({ memory: z.instanceof(ReadOnlyMemory), answer: z.string().default("") }),
})
Expand Down Expand Up @@ -54,8 +92,9 @@ const workflow = new Workflow({
},
{ signal: ctx.signal, recursionLimit: 5 },
);
const answer = response.messages.at(-1)?.content;
return { next: Workflow.END, update: { answer: answer?.toString() } };
const content = response.messages.at(-1)?.content;

return { next: Workflow.END, update: { answer: parseContent(content) } };
});

const memory = new UnconstrainedMemory();
Expand Down
43 changes: 41 additions & 2 deletions examples/integrations/langgraph.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import "dotenv/config";
import { DuckDuckGoSearch as LangChainDDG } from "@langchain/community/tools/duckduckgo_search";
import { createReactAgent as createLangGraphReactAgent } from "@langchain/langgraph/prebuilt";
import type {
MessageContentComplex,
MessageContentImageUrl,
MessageContentText,
} from "@langchain/core/messages";
import { Workflow } from "bee-agent-framework/experimental/workflows/workflow";
import { z } from "zod";
import { createConsoleReader } from "examples/helpers/io.js";
Expand All @@ -13,6 +18,39 @@ import { UnconstrainedMemory } from "bee-agent-framework/memory/unconstrainedMem
import { BaseMessage } from "bee-agent-framework/llms/primitives/message";
import { ChatMessage as LangChainMessage } from "@langchain/core/messages";

//// LangGraph content parser helper functions ////

function isMessageContentText(content: any): content is MessageContentText {
return content.type === "text";
}

function isMessageContentImageUrl(content: any): content is MessageContentImageUrl {
return content.type === "image_url";
}

function parseImageUrl(imageUrl: MessageContentImageUrl["image_url"]) {
if (typeof imageUrl === "string") {
return imageUrl;
}

return imageUrl.url;
}

function parseContent(content: MessageContentComplex[] | undefined | string) {
if (!content || typeof content === "string") {
return content;
}

return content
.filter((c) => isMessageContentText(c) || isMessageContentImageUrl(c))
.map((c) => {
return isMessageContentText(c) ? c.text : parseImageUrl(c.image_url);
})
.join("\n");
}

//// workflow ////

const workflow = new Workflow({
schema: z.object({ memory: z.instanceof(ReadOnlyMemory), answer: z.string().default("") }),
})
Expand Down Expand Up @@ -45,8 +83,9 @@ const workflow = new Workflow({
},
{ signal: ctx.signal, recursionLimit: 5 },
);
const answer = response.messages.at(-1)?.content;
return { next: Workflow.END, update: { answer: answer?.toString() } };
const content = response.messages.at(-1)?.content;

return { next: Workflow.END, update: { answer: parseContent(content) } };
});

const memory = new UnconstrainedMemory();
Expand Down
2 changes: 1 addition & 1 deletion src/instrumentation/opentelemetry.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export class CustomLLM extends LLM<any> {
throw new Error("Method not implemented.");
}
public readonly emitter = Emitter.root.child<BaseLLMEvents>({
namespace: ["bam", "llm"],
namespace: ["custom", "llm"],
creator: this,
});
meta(): Promise<LLMMeta> {
Expand Down
5 changes: 3 additions & 2 deletions src/instrumentation/opentelemetry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,12 @@ export function buildTraceTree({
);
}

export const isMeasurementedInstance = (instance: any) =>
Boolean(
export function isMeasurementedInstance(instance: any) {
return Boolean(
instance &&
(instance instanceof BaseAgent || instance instanceof Tool || instance instanceof BaseLLM),
);
}

export function buildModuleUsageMetric({ instance }: BuildModuleUsageMetricProps) {
moduleUsageCounter.add(1, {
Expand Down
2 changes: 1 addition & 1 deletion src/instrumentation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

import { api } from "@opentelemetry/sdk-node";
import type { api } from "@opentelemetry/sdk-node";

export interface FrameworkSpan {
attributes: {
Expand Down

0 comments on commit f137a0e

Please sign in to comment.