Merge pull request 'feat(protocol): AgentFn<Opt> type + createAgentAdapter bridge' (#256) from feat/252-agent-fn into main
This commit is contained in:
@@ -6,5 +6,9 @@
|
|||||||
"composite": true
|
"composite": true
|
||||||
},
|
},
|
||||||
"include": ["src/**/*.ts"],
|
"include": ["src/**/*.ts"],
|
||||||
"references": [{ "path": "../workflow-runtime" }, { "path": "../workflow-util-agent" }]
|
"references": [
|
||||||
|
{ "path": "../workflow-cas" },
|
||||||
|
{ "path": "../workflow-runtime" },
|
||||||
|
{ "path": "../workflow-util-agent" }
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
"extends": "../../tsconfig.json",
|
"extends": "../../tsconfig.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"rootDir": "src",
|
"rootDir": "src",
|
||||||
"outDir": "dist"
|
"outDir": "dist",
|
||||||
|
"composite": true
|
||||||
},
|
},
|
||||||
"include": ["src"],
|
"include": ["src"],
|
||||||
"references": [{ "path": "../workflow-protocol" }, { "path": "../workflow-util" }]
|
"references": [{ "path": "../workflow-protocol" }, { "path": "../workflow-util" }]
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ export type {
|
|||||||
AdapterFn,
|
AdapterFn,
|
||||||
AdvanceOutcome,
|
AdvanceOutcome,
|
||||||
AgentContext,
|
AgentContext,
|
||||||
|
AgentFn,
|
||||||
CasStore,
|
CasStore,
|
||||||
ExtractFn,
|
ExtractFn,
|
||||||
ExtractResult,
|
ExtractResult,
|
||||||
|
|||||||
@@ -151,6 +151,15 @@ export type RoleFn<T> = (ctx: ThreadContext, runtime: WorkflowRuntime) => Promis
|
|||||||
|
|
||||||
export type AdapterFn = <T>(prompt: string, schema: z.ZodType<T>) => RoleFn<T>;
|
export type AdapterFn = <T>(prompt: string, schema: z.ZodType<T>) => RoleFn<T>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Core agent function. Input is always {@link ThreadContext}, output is always string.
|
||||||
|
* `Opt` captures agent-specific structured options.
|
||||||
|
* Agents with no extra options use `AgentFn` (Opt defaults to void).
|
||||||
|
*/
|
||||||
|
export type AgentFn<Opt = void> = Opt extends void
|
||||||
|
? (ctx: ThreadContext) => Promise<string>
|
||||||
|
: (ctx: ThreadContext, options: Opt) => Promise<string>;
|
||||||
|
|
||||||
export type AdapterBinding = {
|
export type AdapterBinding = {
|
||||||
adapter: AdapterFn;
|
adapter: AdapterFn;
|
||||||
overrides: Partial<Record<string, AdapterFn>> | null;
|
overrides: Partial<Record<string, AdapterFn>> | null;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ export type {
|
|||||||
AdapterBinding,
|
AdapterBinding,
|
||||||
AdapterFn,
|
AdapterFn,
|
||||||
AgentContext,
|
AgentContext,
|
||||||
|
AgentFn,
|
||||||
CasStore,
|
CasStore,
|
||||||
ExtractFn,
|
ExtractFn,
|
||||||
ExtractResult,
|
ExtractResult,
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ export type {
|
|||||||
AdapterFn,
|
AdapterFn,
|
||||||
AdvanceOutcome,
|
AdvanceOutcome,
|
||||||
AgentContext,
|
AgentContext,
|
||||||
|
AgentFn,
|
||||||
CasStore,
|
CasStore,
|
||||||
ExtractFn,
|
ExtractFn,
|
||||||
ExtractResult,
|
ExtractResult,
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
import { putContentNodeWithRefs } from "@uncaged/workflow-cas";
|
||||||
|
import type {
|
||||||
|
AdapterFn,
|
||||||
|
AgentFn,
|
||||||
|
RoleResult,
|
||||||
|
ThreadContext,
|
||||||
|
WorkflowRuntime,
|
||||||
|
} from "@uncaged/workflow-runtime";
|
||||||
|
import type * as z from "zod/v4";
|
||||||
|
|
||||||
|
export type ExtractOptionsFn<Opt> = (
|
||||||
|
ctx: ThreadContext,
|
||||||
|
prompt: string,
|
||||||
|
runtime: WorkflowRuntime,
|
||||||
|
) => Promise<Opt>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bridges {@link AgentFn} to {@link AdapterFn}.
|
||||||
|
*
|
||||||
|
* 1. extract(ctx, prompt, runtime) → Opt
|
||||||
|
* 2. agent(ctx, options) → raw string
|
||||||
|
* 3. Store raw string in CAS
|
||||||
|
* 4. runtime.extract(schema, contentHash) → typed meta T
|
||||||
|
*/
|
||||||
|
export function createAgentAdapter<Opt>(
|
||||||
|
agent: AgentFn<Opt>,
|
||||||
|
extract: ExtractOptionsFn<Opt>,
|
||||||
|
): AdapterFn {
|
||||||
|
return <T>(prompt: string, schema: z.ZodType<T>) => {
|
||||||
|
return async (ctx: ThreadContext, runtime: WorkflowRuntime): Promise<RoleResult<T>> => {
|
||||||
|
const options = await extract(ctx, prompt, runtime);
|
||||||
|
const raw = await (agent as (ctx: ThreadContext, optionsParam: Opt) => Promise<string>)(
|
||||||
|
ctx,
|
||||||
|
options,
|
||||||
|
);
|
||||||
|
const contentHash = await putContentNodeWithRefs(runtime.cas, raw, []);
|
||||||
|
const extracted = await runtime.extract(
|
||||||
|
schema as z.ZodType<Record<string, unknown>>,
|
||||||
|
contentHash,
|
||||||
|
);
|
||||||
|
return { meta: extracted.meta as T, childThread: null };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createSimpleAgentAdapter(agent: AgentFn<void>): AdapterFn {
|
||||||
|
return createAgentAdapter(agent, async () => undefined as unknown as undefined);
|
||||||
|
}
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
export { buildAgentPrompt, buildThreadInput } from "./build-agent-prompt.js";
|
export { buildAgentPrompt, buildThreadInput } from "./build-agent-prompt.js";
|
||||||
|
export type { ExtractOptionsFn } from "./create-agent-adapter.js";
|
||||||
|
export { createAgentAdapter, createSimpleAgentAdapter } from "./create-agent-adapter.js";
|
||||||
export type { TextAdapterResult, TextProducerFn } from "./create-text-adapter.js";
|
export type { TextAdapterResult, TextProducerFn } from "./create-text-adapter.js";
|
||||||
export { createTextAdapter } from "./create-text-adapter.js";
|
export { createTextAdapter } from "./create-text-adapter.js";
|
||||||
export type { SpawnCliConfig, SpawnCliError, SpawnCliResult } from "./spawn-cli.js";
|
export type { SpawnCliConfig, SpawnCliError, SpawnCliResult } from "./spawn-cli.js";
|
||||||
|
|||||||
Reference in New Issue
Block a user