Merge pull request 'feat(protocol): AgentFn<Opt> type + createAgentAdapter bridge' (#256) from feat/252-agent-fn into main

This commit is contained in:
2026-05-14 08:53:30 +00:00
8 changed files with 69 additions and 2 deletions
+5 -1
View File
@@ -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 -1
View File
@@ -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" }]
+1
View File
@@ -13,6 +13,7 @@ export type {
AdapterFn, AdapterFn,
AdvanceOutcome, AdvanceOutcome,
AgentContext, AgentContext,
AgentFn,
CasStore, CasStore,
ExtractFn, ExtractFn,
ExtractResult, ExtractResult,
+9
View File
@@ -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;
+1
View File
@@ -5,6 +5,7 @@ export type {
AdapterBinding, AdapterBinding,
AdapterFn, AdapterFn,
AgentContext, AgentContext,
AgentFn,
CasStore, CasStore,
ExtractFn, ExtractFn,
ExtractResult, ExtractResult,
+1
View File
@@ -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";