diff --git a/app/(playground)/p/[agentId]/beta-proto/graph/actions.ts b/app/(playground)/p/[agentId]/beta-proto/graph/actions.ts index 0f1129a0..ac1b46f4 100644 --- a/app/(playground)/p/[agentId]/beta-proto/graph/actions.ts +++ b/app/(playground)/p/[agentId]/beta-proto/graph/actions.ts @@ -637,34 +637,17 @@ ${instructionSources.map((source) => ` `${source.content}`).join("\n")} diff --git a/app/(playground)/p/[agentId]/beta-proto/graph/server-actions.ts b/app/(playground)/p/[agentId]/beta-proto/graph/server-actions.ts index 9010c1c2..97296896 100644 --- a/app/(playground)/p/[agentId]/beta-proto/graph/server-actions.ts +++ b/app/(playground)/p/[agentId]/beta-proto/graph/server-actions.ts @@ -1,12 +1,7 @@ "use server"; import { openai } from "@ai-sdk/openai"; -import { - type CoreMessage, - jsonSchema, - streamText as sdkStreamText, - streamObject, -} from "ai"; +import { streamObject } from "ai"; import { createStreamableValue } from "ai/rsc"; import { UnstructuredClient } from "unstructured-client"; @@ -20,26 +15,10 @@ import { Langfuse } from "langfuse"; import { Strategy } from "unstructured-client/sdk/models/shared"; import { schema as artifactSchema } from "../artifact/schema"; import type { FileId } from "../files/types"; -import type { GiselleNodeArchetype } from "../giselle-node/blueprints"; import type { AgentId } from "../types"; import { elementsToMarkdown } from "../utils/unstructured"; import type { Graph } from "./types"; -const webSearchSchema = jsonSchema<{ keywords: string[] }>({ - $schema: "https://json-schema.org/draft/2020-12/schema", - title: "keyword schema", - type: "object", - properties: { - keywords: { - type: "array", - items: { - type: "string", - }, - }, - }, - required: ["keywords"], -}); - type GenerateArtifactStreamParams = { userPrompt: string; systemPrompt?: string; @@ -92,58 +71,6 @@ export async function generateArtifactStream( return { object: stream.value }; } -type GenerateWebSearchStreamInputs = { - userPrompt: string; - systemPrompt?: string; -}; -export async function generateWebSearchStream( - inputs: GenerateWebSearchStreamInputs, -) { - const lf = new Langfuse(); - const trace = lf.trace({ - id: `giselle-${Date.now()}`, - }); - const stream = createStreamableValue(); - - (async () => { - const model = "gpt-4o-mini"; - const generation = trace.generation({ - input: inputs.userPrompt, - model, - }); - const { partialObjectStream } = await streamObject({ - model: openai(model), - system: inputs.systemPrompt ?? "You generate an answer to a question. ", - prompt: inputs.userPrompt, - schema: artifactSchema, - onFinish: async (result) => { - const meter = metrics.getMeter("OpenAI"); - const tokenCounter = meter.createCounter("token_consumed", { - description: "Number of OpenAI API tokens consumed by each request", - }); - const subscriptionId = await getUserSubscriptionId(); - const isR06User = await isRoute06User(); - tokenCounter.add(result.usage.totalTokens, { - subscriptionId, - isR06User, - }); - generation.end({ - output: result, - }); - await lf.shutdownAsync(); - }, - }); - - for await (const partialObject of partialObjectStream) { - stream.update(partialObject); - } - - stream.done(); - })(); - - return { object: stream.value }; -} - export async function setGraphToDb(agentId: AgentId, graph: Graph) { await db .update(agents) diff --git a/app/(playground)/p/[agentId]/beta-proto/web-search/panel.tsx b/app/(playground)/p/[agentId]/beta-proto/web-search/panel.tsx index 546ebe6e..7df6685d 100644 --- a/app/(playground)/p/[agentId]/beta-proto/web-search/panel.tsx +++ b/app/(playground)/p/[agentId]/beta-proto/web-search/panel.tsx @@ -73,7 +73,7 @@ export const WebSearchPropertyPanel: FC = ({ )} -
{(node.output as PartialGeneratedObject).thinking}
+
{(node.output as PartialGeneratedObject).plan}
{(node.output as PartialGeneratedObject).webSearch && (
( + { + $schema: "https://json-schema.org/draft/2020-12/schema", + title: "keyword schema", + type: "object", + properties: { + plan: { + type: "string", + description: "Describe the plan that you will archive user request", + }, + keywords: { + type: "array", + items: { + type: "string", + description: + "Suggest appropriate search queries with relevant keywords at least 3-5 words long", + }, + description: "The keywords to search for user request", + }, + }, + required: ["plan", "keywords"], + }, +); diff --git a/app/(playground)/p/[agentId]/beta-proto/web-search/server-action.ts b/app/(playground)/p/[agentId]/beta-proto/web-search/server-action.ts index dba363d7..05429c8c 100644 --- a/app/(playground)/p/[agentId]/beta-proto/web-search/server-action.ts +++ b/app/(playground)/p/[agentId]/beta-proto/web-search/server-action.ts @@ -1,6 +1,12 @@ "use server"; +import { getUserSubscriptionId, isRoute06User } from "@/app/(auth)/lib"; +import { openai } from "@ai-sdk/openai"; +import { metrics } from "@opentelemetry/api"; +import { streamObject } from "ai"; import { createStreamableValue } from "ai/rsc"; +import Langfuse from "langfuse"; +import { webSearchSchema } from "./schema"; const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); @@ -11,25 +17,49 @@ interface GenerateWebSearchStreamInputs { export async function generateWebSearchStream( inputs: GenerateWebSearchStreamInputs, ) { + const lf = new Langfuse(); + const trace = lf.trace({ + id: `giselle-${Date.now()}`, + }); const stream = createStreamableValue(); (async () => { - stream.update({}); - - await sleep(500); - - stream.update({ - thinking: "Search the web", + const model = "gpt-4o-mini"; + const generation = trace.generation({ + input: inputs.userPrompt, + model, }); - - await sleep(500); - stream.update({ - thinking: "Search the web to find information relevant to your request.", + const { partialObjectStream, object } = await streamObject({ + model: openai(model), + system: inputs.systemPrompt ?? "You generate an answer to a question. ", + prompt: inputs.userPrompt, + schema: webSearchSchema, + onFinish: async (result) => { + const meter = metrics.getMeter("OpenAI"); + const tokenCounter = meter.createCounter("token_consumed", { + description: "Number of OpenAI API tokens consumed by each request", + }); + const subscriptionId = await getUserSubscriptionId(); + const isR06User = await isRoute06User(); + tokenCounter.add(result.usage.totalTokens, { + subscriptionId, + isR06User, + }); + generation.end({ + output: result, + }); + await lf.shutdownAsync(); + }, }); + for await (const partialObject of partialObjectStream) { + stream.update(partialObject); + } + + const result = await object; await sleep(500); stream.update({ - thinking: "Search the web to find information relevant to your request.", + ...result, webSearch: { name: "Why Deno is the best choice for biginner", }, @@ -37,7 +67,7 @@ export async function generateWebSearchStream( await sleep(1000); stream.update({ - thinking: "Search the web to find information relevant to your request.", + ...result, webSearch: { name: "Why Deno is the best choice for biginner", items: [ @@ -53,7 +83,7 @@ export async function generateWebSearchStream( await sleep(1000); stream.update({ - thinking: "Search the web to find information relevant to your request.", + ...result, webSearch: { name: "Why Deno is the best choice for biginner", items: [ @@ -74,7 +104,7 @@ export async function generateWebSearchStream( }); await sleep(1000); stream.update({ - thinking: "Search the web to find information relevant to your request.", + ...result, webSearch: { name: "Why Deno is the best choice for biginner", items: [ diff --git a/app/(playground)/p/[agentId]/beta-proto/web-search/types.ts b/app/(playground)/p/[agentId]/beta-proto/web-search/types.ts index 53ff21c2..d63a738e 100644 --- a/app/(playground)/p/[agentId]/beta-proto/web-search/types.ts +++ b/app/(playground)/p/[agentId]/beta-proto/web-search/types.ts @@ -35,7 +35,7 @@ interface WebSearchItem { } export interface GeneratedObject { - thinking: string; + plan: string; webSearch: WebSearch; description: string; }