feat: add @uncaged/workflow-agent-react package (#222)
This commit is contained in:
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"name": "@uncaged/workflow-agent-react",
|
||||||
|
"version": "0.3.5",
|
||||||
|
"type": "module",
|
||||||
|
"main": "src/index.ts",
|
||||||
|
"types": "src/index.ts",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"types": "./src/index.ts",
|
||||||
|
"default": "./src/index.ts"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"test": "bun test"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@uncaged/workflow-protocol": "workspace:*",
|
||||||
|
"@uncaged/workflow-reactor": "workspace:*",
|
||||||
|
"@uncaged/workflow-util-agent": "workspace:*"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"zod": "^4.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"zod": "^4.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
import type {
|
||||||
|
AdapterFn,
|
||||||
|
RoleResult,
|
||||||
|
ThreadContext,
|
||||||
|
WorkflowRuntime,
|
||||||
|
} from "@uncaged/workflow-protocol";
|
||||||
|
import { createThreadReactor } from "@uncaged/workflow-reactor";
|
||||||
|
import { buildThreadInput } from "@uncaged/workflow-util-agent";
|
||||||
|
import * as z from "zod/v4";
|
||||||
|
|
||||||
|
import type { ReactAdapterConfig } from "./types.js";
|
||||||
|
|
||||||
|
function stripJsonSchemaMeta(json: Record<string, unknown>): Record<string, unknown> {
|
||||||
|
const { $schema: _drop, ...rest } = json;
|
||||||
|
return rest;
|
||||||
|
}
|
||||||
|
|
||||||
|
function readToolName(parametersSchema: Record<string, unknown>): string {
|
||||||
|
const title = parametersSchema.title;
|
||||||
|
if (typeof title === "string" && title.trim().length > 0) {
|
||||||
|
return title.trim();
|
||||||
|
}
|
||||||
|
return "resolve";
|
||||||
|
}
|
||||||
|
|
||||||
|
function readToolDescription(parametersSchema: Record<string, unknown>): string {
|
||||||
|
const d = parametersSchema.description;
|
||||||
|
if (typeof d === "string" && d.trim().length > 0) {
|
||||||
|
return d.trim();
|
||||||
|
}
|
||||||
|
return "Submit the final structured result.";
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createReactAdapter(config: ReactAdapterConfig): AdapterFn {
|
||||||
|
return <T>(prompt: string, schema: z.ZodType<T>) => {
|
||||||
|
const reactor = createThreadReactor<ThreadContext>({
|
||||||
|
llm: config.llm,
|
||||||
|
staticTools: config.tools,
|
||||||
|
structuredToolFromSchema: (s) => {
|
||||||
|
const rawJsonSchema = z.toJSONSchema(s) as Record<string, unknown>;
|
||||||
|
const parameters = stripJsonSchemaMeta(rawJsonSchema);
|
||||||
|
const name = readToolName(parameters);
|
||||||
|
return {
|
||||||
|
name,
|
||||||
|
tool: {
|
||||||
|
type: "function" as const,
|
||||||
|
function: {
|
||||||
|
name,
|
||||||
|
description: readToolDescription(parameters),
|
||||||
|
parameters,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
systemPromptForStructuredTool: (_name) => prompt,
|
||||||
|
toolHandler: async (call, _thread) => {
|
||||||
|
return config.toolHandler(call.function.name, call.function.arguments);
|
||||||
|
},
|
||||||
|
maxRounds: config.maxRounds,
|
||||||
|
});
|
||||||
|
|
||||||
|
return async (ctx: ThreadContext, _runtime: WorkflowRuntime): Promise<RoleResult<T>> => {
|
||||||
|
const input = await buildThreadInput(ctx);
|
||||||
|
const result = await reactor({ thread: ctx, input, schema });
|
||||||
|
if (!result.ok) throw new Error(result.error);
|
||||||
|
return { meta: result.value, childThread: null };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
export { createReactAdapter } from "./create-react-adapter.js";
|
||||||
|
export type { ReactAdapterConfig, ReactToolHandler } from "./types.js";
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import type { LlmFn, ToolDefinition } from "@uncaged/workflow-reactor";
|
||||||
|
|
||||||
|
export type ReactToolHandler = (name: string, args: string) => Promise<string>;
|
||||||
|
|
||||||
|
export type ReactAdapterConfig = {
|
||||||
|
llm: LlmFn;
|
||||||
|
tools: readonly ToolDefinition[];
|
||||||
|
toolHandler: ReactToolHandler;
|
||||||
|
maxRounds: number;
|
||||||
|
};
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"rootDir": "src",
|
||||||
|
"outDir": "dist",
|
||||||
|
"composite": true
|
||||||
|
},
|
||||||
|
"include": ["src/**/*.ts"],
|
||||||
|
"references": [
|
||||||
|
{ "path": "../workflow-protocol" },
|
||||||
|
{ "path": "../workflow-reactor" },
|
||||||
|
{ "path": "../workflow-util-agent" }
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -29,6 +29,7 @@
|
|||||||
{ "path": "packages/workflow-agent-cursor" },
|
{ "path": "packages/workflow-agent-cursor" },
|
||||||
{ "path": "packages/workflow-agent-hermes" },
|
{ "path": "packages/workflow-agent-hermes" },
|
||||||
{ "path": "packages/workflow-util-agent" },
|
{ "path": "packages/workflow-util-agent" },
|
||||||
|
{ "path": "packages/workflow-agent-react" },
|
||||||
{ "path": "packages/cli-workflow" },
|
{ "path": "packages/cli-workflow" },
|
||||||
{ "path": "packages/workflow-template-solve-issue" },
|
{ "path": "packages/workflow-template-solve-issue" },
|
||||||
{ "path": "packages/workflow-template-develop" }
|
{ "path": "packages/workflow-template-develop" }
|
||||||
|
|||||||
Reference in New Issue
Block a user