Compare commits

...

6 Commits

Author SHA1 Message Date
Scott Wei 7dadf874e1 refactor(workflow-protocol): require AgentFn Opt generic
Make AgentFn<Opt> always take a mandatory options argument, removing
the void conditional overload. Simplify createAgentAdapter, restore
exports needed by tests, and fix CLI test bundles to use cas.put
instead of disallowed @uncaged/* imports.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-16 18:23:07 +08:00
xiaomo ba90214af6 Merge pull request 'chore: internalize unused exports across all packages' (#283) from chore/audit-exports-cleanup into main 2026-05-16 09:59:57 +00:00
xiaoju 5bbac3e4f7 chore: internalize unused exports across all packages
Audit public API surfaces using reachability analysis from application
entry points (Worker, CLI, Dashboard). Symbols not reachable from any
application's customization tree are removed from package index.ts files.

Source files and internal usage are untouched — only the public export
surface is narrowed.

Changes by package:
- workflow-util: -7 exports (base32 internals, logger config types)
- workflow-cas: -12 exports (merkle internals, serialization details)
- workflow-execute: -24 exports (engine internals, LLM extract details)
- workflow-reactor: -4 exports (reactor config/invocation internals)
- workflow-register: -8 exports (redundant protocol re-exports, internal YAML fns)
- workflow-runtime: curated re-export subset (stop full protocol re-export)
- workflow-util-agent: -5 exports (internal agent helpers)
- workflow-agent-cursor: -1 export (validateCursorAgentConfig)
- workflow-agent-hermes: -1 export (validateHermesAgentConfig)

Note: workflow-protocol index.ts unchanged — downstream packages still
import removed symbols via internal paths. Protocol cleanup requires
updating workflow-runtime/src/types.ts first (separate PR).

Refs #273, #274, #275, #276, #277, #278, #279, #280, #281, #282
2026-05-16 09:58:56 +00:00
xiaomo 131021b1a7 Merge pull request 'chore: remove symlink dead code' (#271) from chore/remove-symlink-dead-code into main 2026-05-16 06:22:34 +00:00
xiaoju e42555fd9c chore: remove symlink dead code
Now that bundles are fully self-contained (no external @uncaged/* imports),
the symlink mechanism is no longer needed.

- Delete ensure-uncaged-workflow-symlink.ts
- Remove ensureUncagedWorkflowSymlink from all imports/exports
- Remove ExtractBundleExportsOptions type (storageRoot param)
- Simplify extractBundleExports to single-arg signature
- Clean up stale comments
2026-05-16 06:21:34 +00:00
xiaomo 3a26eb28e5 Merge pull request 'chore: make bundle fully self-contained, no external imports' (#270) from chore/no-external-bundle into main 2026-05-16 06:16:28 +00:00
20 changed files with 60 additions and 230 deletions
@@ -20,9 +20,6 @@ import { addCliArgs } from "./bundle-fixture.js";
const fixtureDescriptor = `export const descriptor = { description: "fixture", roles: {}, graph: { edges: [] } };
`;
const wfPutImport = `import { putContentMerkleNode } from "@uncaged/workflow-cas";
`;
function casStoredForm(raw: string): string {
return serializeMerkleNode(createContentMerkleNode(raw));
}
@@ -52,12 +49,12 @@ describe("cli workflow commands", () => {
const bundlePath = join(bundleDir, "demo.esm.js");
await writeFile(
bundlePath,
`${fixtureDescriptor}${wfPutImport}import fs from "node:fs";
`${fixtureDescriptor}import fs from "node:fs";
export const run = async function* (input, options) {
fs.existsSync(".");
const cas = options.cas;
const h = await putContentMerkleNode(cas, input.prompt);
const h = await cas.put(input.prompt);
yield { role: "noop", contentHash: h, meta: { done: true }, refs: [h] };
return { returnCode: 0, summary: "done" };
}
@@ -155,10 +152,9 @@ export const run = async function* (input) { return { returnCode: 0, summary: in
},
graph: { edges: [] },
};
${wfPutImport}
export const run = async function* (input, options) {
const cas = options.cas;
const h = await putContentMerkleNode(cas, input.prompt);
const h = await cas.put( input.prompt);
yield { role: "greeter", contentHash: h, meta: { greeting: "hi" }, refs: [h] };
return { returnCode: 0, summary: "ok" };
};
@@ -197,9 +193,9 @@ export const run = async function* (input, options) {
const bundlePath = join(bundleDir, "demo.esm.js");
await writeFile(
bundlePath,
`${fixtureDescriptor}${wfPutImport}export const run = async function* (_input, options) {
`${fixtureDescriptor}export const run = async function* (_input, options) {
const cas = options.cas;
const h = await putContentMerkleNode(cas, "x");
const h = await cas.put( "x");
yield { role: "a", contentHash: h, meta: {}, refs: [h] };
return { returnCode: 0, summary: "x" };
}
@@ -228,9 +224,9 @@ export const run = async function* (input, options) {
const dtsPath = join(bundleDir, "types.d.ts");
await writeFile(
bundlePath,
`${fixtureDescriptor}${wfPutImport}export const run = async function* (_input, options) {
`${fixtureDescriptor}export const run = async function* (_input, options) {
const cas = options.cas;
const h = await putContentMerkleNode(cas, "x");
const h = await cas.put( "x");
yield { role: "a", contentHash: h, meta: {}, refs: [h] };
return { returnCode: 0, summary: "x" };
}
@@ -261,9 +257,9 @@ export const run = async function* (input, options) {
const bundlePath = join(bundleDir, "demo.esm.js");
await writeFile(
bundlePath,
`${fixtureDescriptor}${wfPutImport}export const run = async function* (_input, options) {
`${fixtureDescriptor}export const run = async function* (_input, options) {
const cas = options.cas;
const h = await putContentMerkleNode(cas, "x");
const h = await cas.put( "x");
yield { role: "a", contentHash: h, meta: {}, refs: [h] };
return { returnCode: 0, summary: "x" };
}
@@ -284,16 +280,16 @@ export const run = async function* (input, options) {
const bundleDir = join(storageRoot, "src");
await mkdir(bundleDir, { recursive: true });
const bundlePath = join(bundleDir, "demo.esm.js");
const v1 = `${fixtureDescriptor}${wfPutImport}export const run = async function* (_input, options) {
const v1 = `${fixtureDescriptor}export const run = async function* (_input, options) {
const cas = options.cas;
const h = await putContentMerkleNode(cas, "v1");
const h = await cas.put( "v1");
yield { role: "a", contentHash: h, meta: {}, refs: [h] };
return { returnCode: 0, summary: "v1" };
}
`;
const v2 = `${fixtureDescriptor}${wfPutImport}export const run = async function* (_input, options) {
const v2 = `${fixtureDescriptor}export const run = async function* (_input, options) {
const cas = options.cas;
const h = await putContentMerkleNode(cas, "v2");
const h = await cas.put( "v2");
yield { role: "a", contentHash: h, meta: {}, refs: [h] };
return { returnCode: 0, summary: "v2" };
}
@@ -326,16 +322,16 @@ export const run = async function* (input, options) {
const bundleDir = join(storageRoot, "src");
await mkdir(bundleDir, { recursive: true });
const bundlePath = join(bundleDir, "demo.esm.js");
const v1 = `${fixtureDescriptor}${wfPutImport}export const run = async function* (_input, options) {
const v1 = `${fixtureDescriptor}export const run = async function* (_input, options) {
const cas = options.cas;
const h = await putContentMerkleNode(cas, "v1");
const h = await cas.put( "v1");
yield { role: "a", contentHash: h, meta: {}, refs: [h] };
return { returnCode: 0, summary: "v1" };
}
`;
const v2 = `${fixtureDescriptor}${wfPutImport}export const run = async function* (_input, options) {
const v2 = `${fixtureDescriptor}export const run = async function* (_input, options) {
const cas = options.cas;
const h = await putContentMerkleNode(cas, "v2");
const h = await cas.put( "v2");
yield { role: "a", contentHash: h, meta: {}, refs: [h] };
return { returnCode: 0, summary: "v2" };
}
@@ -378,9 +374,9 @@ export const run = async function* (input, options) {
const bundlePath = join(bundleDir, "demo.esm.js");
await writeFile(
bundlePath,
`${fixtureDescriptor}${wfPutImport}export const run = async function* (_input, options) {
`${fixtureDescriptor}export const run = async function* (_input, options) {
const cas = options.cas;
const h = await putContentMerkleNode(cas, "x");
const h = await cas.put( "x");
yield { role: "a", contentHash: h, meta: {}, refs: [h] };
return { returnCode: 0, summary: "x" };
}
@@ -391,9 +387,9 @@ export const run = async function* (input, options) {
expect(add1.ok).toBe(true);
await writeFile(
bundlePath,
`${fixtureDescriptor}${wfPutImport}export const run = async function* (_input, options) {
`${fixtureDescriptor}export const run = async function* (_input, options) {
const cas = options.cas;
const h = await putContentMerkleNode(cas, "y");
const h = await cas.put( "y");
yield { role: "a", contentHash: h, meta: {}, refs: [h] };
return { returnCode: 0, summary: "y" };
}
@@ -446,9 +442,9 @@ export const run = async function* (input, options) {
const bundlePath = join(bundleDir, "demo.esm.js");
await writeFile(
bundlePath,
`${fixtureDescriptor}${wfPutImport}export const run = async function* (_input, options) {
`${fixtureDescriptor}export const run = async function* (_input, options) {
const cas = options.cas;
const h = await putContentMerkleNode(cas, "x");
const h = await cas.put( "x");
yield { role: "a", contentHash: h, meta: {}, refs: [h] };
return { returnCode: 0, summary: "x" };
}
@@ -463,9 +459,9 @@ export const run = async function* (input, options) {
const hash1 = add1.value.hash;
await writeFile(
bundlePath,
`${fixtureDescriptor}${wfPutImport}export const run = async function* (_input, options) {
`${fixtureDescriptor}export const run = async function* (_input, options) {
const cas = options.cas;
const h = await putContentMerkleNode(cas, "y");
const h = await cas.put( "y");
yield { role: "a", contentHash: h, meta: {}, refs: [h] };
return { returnCode: 0, summary: "y" };
}
@@ -15,9 +15,7 @@ import { addCliArgs } from "./bundle-fixture.js";
import { ensureTestWorkflowRegistryConfig } from "./workflow-registry-fixture.js";
/** Three-role workflow that respects `input.steps` for fork/resume. */
const threeRoleBundleSource = `import { putContentMerkleNode } from "@uncaged/workflow-cas";
export const descriptor = {
const threeRoleBundleSource = `export const descriptor = {
description: "fork-cli",
roles: {
planner: { description: "planner", schema: {} },
@@ -30,16 +28,16 @@ export const run = async function* (input, options) {
const cas = options.cas;
const has = (r) => input.steps.some((s) => s.role === r);
if (!has("planner")) {
const h = await putContentMerkleNode(cas, "p1");
const h = await cas.put( "p1");
yield { role: "planner", contentHash: h, meta: { k: "planner" }, refs: [h] };
}
if (!has("coder")) {
const h = await putContentMerkleNode(cas, "c1");
const h = await cas.put( "c1");
yield { role: "coder", contentHash: h, meta: { k: "coder" }, refs: [h] };
}
if (!has("reviewer")) {
const body = "rev-" + String(input.steps.length);
const h = await putContentMerkleNode(cas, body);
const h = await cas.put( body);
yield { role: "reviewer", contentHash: h, meta: { k: "reviewer" }, refs: [h] };
}
return { returnCode: 0, summary: "done" };
@@ -23,9 +23,6 @@ import { resolveThreadRecord } from "../src/thread-scan.js";
import { addCliArgs } from "./bundle-fixture.js";
import { ensureTestWorkflowRegistryConfig } from "./workflow-registry-fixture.js";
const wfPutImport = `import { putContentMerkleNode } from "@uncaged/workflow-cas";
`;
const threadFixtureDescriptor = `export const descriptor = {
description: "thread-cli",
roles: {
@@ -41,25 +38,23 @@ const threadFixtureDescriptor = `export const descriptor = {
`;
const fastBundleSource = `${threadFixtureDescriptor}
${wfPutImport}
export const run = async function* (input, options) {
const cas = options.cas;
let h = await putContentMerkleNode(cas, "plan");
let h = await cas.put( "plan");
yield { role: "planner", contentHash: h, meta: { plan: input.prompt }, refs: [h] };
h = await putContentMerkleNode(cas, "code");
h = await cas.put( "code");
yield { role: "coder", contentHash: h, meta: { diff: "y" }, refs: [h] };
return { returnCode: 0, summary: "done" };
};
`;
const slowPlannerBundleSource = `${threadFixtureDescriptor}
${wfPutImport}
export const run = async function* (input, options) {
await new Promise((r) => setTimeout(r, 400));
const cas = options.cas;
let h = await putContentMerkleNode(cas, "plan");
let h = await cas.put( "plan");
yield { role: "planner", contentHash: h, meta: { plan: input.prompt }, refs: [h] };
h = await putContentMerkleNode(cas, "code");
h = await cas.put( "code");
yield { role: "coder", contentHash: h, meta: { diff: "y" }, refs: [h] };
return { returnCode: 0, summary: "done" };
};
@@ -68,37 +63,34 @@ export const run = async function* (input, options) {
const cliEntryPath = fileURLToPath(new URL("../src/cli.ts", import.meta.url));
const abortablePlannerBundleSource = `${threadFixtureDescriptor}
${wfPutImport}
export const run = async function* (input, options) {
const cas = options.cas;
let h = await putContentMerkleNode(cas, "plan");
let h = await cas.put( "plan");
yield { role: "planner", contentHash: h, meta: { plan: input.prompt }, refs: [h] };
await new Promise((r) => setTimeout(r, 10000));
h = await putContentMerkleNode(cas, "code");
h = await cas.put( "code");
yield { role: "coder", contentHash: h, meta: { diff: "y" }, refs: [h] };
return { returnCode: 0, summary: "done" };
};
`;
const pauseResumeBundleSource = `${threadFixtureDescriptor}
${wfPutImport}
export const run = async function* (_input, options) {
const cas = options.cas;
let h = await putContentMerkleNode(cas, "f");
let h = await cas.put( "f");
yield { role: "first", contentHash: h, meta: {}, refs: [h] };
await new Promise((r) => setTimeout(r, 1500));
h = await putContentMerkleNode(cas, "s");
h = await cas.put( "s");
yield { role: "second", contentHash: h, meta: {}, refs: [h] };
return { returnCode: 0, summary: "done" };
};
`;
const delayedFirstYieldBundleSource = `${threadFixtureDescriptor}
${wfPutImport}
export const run = async function* (_input, options) {
await new Promise((r) => setTimeout(r, 900));
const cas = options.cas;
const h = await putContentMerkleNode(cas, "x");
const h = await cas.put( "x");
yield { role: "only", contentHash: h, meta: {}, refs: [h] };
return { returnCode: 0, summary: "done" };
};
@@ -110,7 +110,7 @@ export async function cmdAdd(
return validated;
}
const extracted = await extractBundleExports(resolvedPath, { storageRoot });
const extracted = await extractBundleExports(resolvedPath);
if (!extracted.ok) {
return extracted;
}
+2 -15
View File
@@ -1,29 +1,16 @@
export { createCasStore } from "./cas.js";
export { collectRefs } from "./collect-refs.js";
export { hashString, hashWorkflowBundleBytes } from "./hash.js";
export { hashWorkflowBundleBytes } from "./hash.js";
export {
createContentMerkleNode,
getContentMerklePayload,
parseMerkleNode,
putContentMerkleNode,
putStepMerkleNode,
putThreadMerkleNode,
serializeMerkleNode,
} from "./merkle.js";
export type { ParsedCasThreadNode } from "./nodes.js";
export {
isCasNodeYaml,
parseCasThreadNode,
putContentNodeWithRefs,
putStartNode,
putStateNode,
serializeCasNode,
} from "./nodes.js";
export { findReachableHashes } from "./reachable.js";
export type {
CasStore,
MerkleNode,
MerkleNodeType,
StepMerklePayload,
ThreadMerklePayload,
} from "./types.js";
export type { CasStore } from "./types.js";
@@ -3,10 +3,7 @@ import { mkdir, unlink, writeFile } from "node:fs/promises";
import { createServer, type Socket } from "node:net";
import { dirname, join } from "node:path";
import { createCasStore } from "@uncaged/workflow-cas";
import {
ensureUncagedWorkflowSymlink,
importWorkflowBundleModule,
} from "@uncaged/workflow-register";
import { importWorkflowBundleModule } from "@uncaged/workflow-register";
import type { RoleOutput, WorkflowFn } from "@uncaged/workflow-runtime";
import {
createLogger,
@@ -365,7 +362,6 @@ async function main(): Promise<void> {
return;
}
await ensureUncagedWorkflowSymlink(storageRoot);
// Dynamic import required: user bundle path resolved at runtime
const modUnknown: unknown = await importWorkflowBundleModule(bundlePath);
const modRec = modUnknown as Record<string, unknown>;
+2 -28
View File
@@ -1,48 +1,22 @@
export { createWorkflow } from "./engine/create-workflow.js";
export { executeThread } from "./engine/engine.js";
export {
FORK_BRANCH_ROLE,
prepareCasFork,
tryParseWorkflowResultRecord,
walkStateFramesNewestFirst,
} from "./engine/fork-thread.js";
export { garbageCollectCas } from "./engine/gc.js";
export { createThreadPauseGate } from "./engine/thread-pause-gate.js";
export type {
ThreadHistoryEntry,
ThreadIndex,
ThreadIndexEntry,
} from "./engine/threads-index.js";
export {
appendThreadHistoryEntry,
getBundleDir,
readThreadsIndex,
removeThreadEntry,
removeThreadHistoryEntries,
upsertThreadEntry,
writeThreadsIndex,
} from "./engine/threads-index.js";
export type {
CasForkPlan,
ChainState,
ExecuteThreadIo,
ExecuteThreadOptions,
ForkContinuationOptions,
GcResult,
PrefilledDiskStep,
SupervisorDecision,
ThreadPauseGate,
} from "./engine/types.js";
export { EMPTY_CHAIN_STATE } from "./engine/types.js";
export type { GcResult } from "./engine/types.js";
export { getWorkerHostScriptPath } from "./engine/worker-entry-path.js";
export type { ExtractFn, LlmError, LlmExtractArgs } from "./extract/index.js";
export {
createExtract,
extractFunctionToolFromZodSchema,
llmErrorToCause,
llmExtract,
} from "./extract/index.js";
export { createExtract } from "./extract/index.js";
export { type WorkflowAdapterOptions, workflowAdapter } from "./workflow-adapter.js";
/** @deprecated Use {@link workflowAdapter} instead. */
export { type WorkflowAsAgentOptions, workflowAsAgent } from "./workflow-as-agent.js";
@@ -69,7 +69,7 @@ async function resolveWorkflowBundle(workflowName: string, storageRoot: string,
}
const bundlePath = join(storageRoot, "bundles", `${entry.hash}.esm.js`);
const bundleExportsResult = await extractBundleExports(bundlePath, { storageRoot });
const bundleExportsResult = await extractBundleExports(bundlePath);
if (!bundleExportsResult.ok) {
throw new Error(String(bundleExportsResult.error));
}
+2 -5
View File
@@ -154,12 +154,9 @@ 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).
* `Opt` captures agent-specific structured options (required second argument).
*/
export type AgentFn<Opt = void> = Opt extends void
? (ctx: ThreadContext) => Promise<string>
: (ctx: ThreadContext, options: Opt) => Promise<string>;
export type AgentFn<Opt> = (ctx: ThreadContext, options: Opt) => Promise<string>;
export type AdapterBinding = {
adapter: AdapterFn;
-4
View File
@@ -3,10 +3,6 @@ export { createThreadReactor } from "./thread-reactor.js";
export type {
ChatMessage,
LlmFn,
StructuredToolSpec,
ThreadReactorConfig,
ThreadReactorFn,
ThreadReactorInvokeArgs,
ToolCall,
ToolDefinition,
} from "./types.js";
@@ -1,7 +1,7 @@
import { pathToFileURL } from "node:url";
/**
* Dynamic-import a workflow bundle path (see {@link extractBundleExports} — symlink must exist first).
* Dynamic-import a workflow bundle path.
*/
export async function importWorkflowBundleModule(bundlePath: string): Promise<unknown> {
return import(pathToFileURL(bundlePath).href);
@@ -1,56 +0,0 @@
import { mkdir, readlink, symlink, unlink } from "node:fs/promises";
import path from "node:path";
import { fileURLToPath } from "node:url";
/** This module lives in `@uncaged/workflow-register/src/bundle`; grandparent dir is the package root. */
function installedWorkflowPackageDir(): string {
return fileURLToPath(new URL("../..", import.meta.url));
}
/**
* Resolve sibling @uncaged/* package directory relative to workflow-register.
* In a monorepo workspace layout the sibling packages live next to workflow-register.
*/
function siblingPackageDir(packageName: string): string {
const registerRoot = installedWorkflowPackageDir();
return path.resolve(registerRoot, "..", packageName);
}
async function ensureSymlink(linkDir: string, name: string, target: string): Promise<void> {
const linkPath = path.join(linkDir, name);
await mkdir(linkDir, { recursive: true });
try {
const existing = await readlink(linkPath);
const normalizedExisting = path.resolve(linkDir, existing);
if (normalizedExisting === target) {
return;
}
await unlink(linkPath);
} catch (e) {
const errObj = e as NodeJS.ErrnoException;
if (errObj.code !== "ENOENT" && errObj.code !== "EINVAL") {
throw e;
}
}
const linkType = process.platform === "win32" ? "junction" : "dir";
await symlink(target, linkPath, linkType);
}
/**
* Ensures `<storageRoot>/node_modules/@uncaged/*` symlinks point at installed packages
* so workflow bundles loaded from `<storageRoot>/bundles/*.esm.js` can resolve their imports.
*/
export async function ensureUncagedWorkflowSymlink(storageRoot: string): Promise<void> {
const linkDir = path.join(storageRoot, "node_modules", "@uncaged");
const packages = [
{ name: "workflow", dir: siblingPackageDir("workflow") },
{ name: "workflow-runtime", dir: siblingPackageDir("workflow-runtime") },
{ name: "workflow-cas", dir: siblingPackageDir("workflow-cas") },
{ name: "workflow-protocol", dir: siblingPackageDir("workflow-protocol") },
];
for (const pkg of packages) {
await ensureSymlink(linkDir, pkg.name, pkg.dir);
}
}
@@ -1,21 +1,15 @@
import type { WorkflowFn } from "@uncaged/workflow-protocol";
import { err, ok, type Result } from "@uncaged/workflow-util";
import { importWorkflowBundleModule } from "./bundle-import-env.js";
import { ensureUncagedWorkflowSymlink } from "./ensure-uncaged-workflow-symlink.js";
import type { ExtractBundleExportsOptions, ExtractedBundleExports } from "./types.js";
import type { ExtractedBundleExports } from "./types.js";
import { validateWorkflowDescriptor } from "./workflow-descriptor.js";
/** Load a workflow `.esm.js` bundle and read its named exports (`run`, `descriptor`). */
export async function extractBundleExports(
bundlePath: string,
options: ExtractBundleExportsOptions = { storageRoot: null },
): Promise<Result<ExtractedBundleExports, string>> {
let modUnknown: unknown;
try {
if (options.storageRoot !== null) {
await ensureUncagedWorkflowSymlink(options.storageRoot);
}
// Dynamic import required: user bundle path resolved at runtime
modUnknown = await importWorkflowBundleModule(bundlePath);
} catch (e) {
const message = e instanceof Error ? e.message : String(e);
@@ -1,17 +1,10 @@
export { buildDescriptor } from "./build-descriptor.js";
export { importWorkflowBundleModule } from "./bundle-import-env.js";
export { validateWorkflowBundle } from "./bundle-validator.js";
export { ensureUncagedWorkflowSymlink } from "./ensure-uncaged-workflow-symlink.js";
export { extractBundleExports } from "./extract-bundle-exports.js";
export { stringifyWorkflowDescriptor } from "./generate-descriptor.js";
export type {
ExtractBundleExportsOptions,
ExtractedBundleExports,
WorkflowBundleValidationInput,
WorkflowDescriptor,
WorkflowGraph,
WorkflowGraphEdge,
WorkflowRoleDescriptor,
WorkflowRoleSchema,
} from "./types.js";
export { validateWorkflowDescriptor } from "./workflow-descriptor.js";
@@ -20,8 +20,3 @@ export type ExtractedBundleExports = {
run: WorkflowFn;
descriptor: WorkflowDescriptor;
};
export type ExtractBundleExportsOptions = {
/** When set, ensures `node_modules/@uncaged/workflow` exists under this root before import. */
storageRoot: string | null;
};
-10
View File
@@ -1,16 +1,9 @@
export type {
ExtractBundleExportsOptions,
ExtractedBundleExports,
WorkflowBundleValidationInput,
WorkflowDescriptor,
WorkflowGraph,
WorkflowGraphEdge,
WorkflowRoleDescriptor,
WorkflowRoleSchema,
} from "./bundle/index.js";
export {
buildDescriptor,
ensureUncagedWorkflowSymlink,
extractBundleExports,
importWorkflowBundleModule,
stringifyWorkflowDescriptor,
@@ -21,18 +14,15 @@ export type { ProviderConfig, ResolvedModel } from "./config/index.js";
export { resolveModel, splitProviderModelRef } from "./config/index.js";
export type {
WorkflowConfig,
WorkflowHistoryEntry,
WorkflowRegistryEntry,
WorkflowRegistryFile,
} from "./registry/index.js";
export {
getRegisteredWorkflow,
listRegisteredWorkflowNames,
parseWorkflowRegistryYaml,
readWorkflowRegistry,
registerWorkflowVersion,
rollbackWorkflowToHistoryHash,
stringifyWorkflowRegistryYaml,
unregisterWorkflow,
workflowRegistryPath,
writeWorkflowRegistry,
+5 -13
View File
@@ -1,8 +1,4 @@
export { buildThreadContext } from "./build-context.js";
export { createWorkflow } from "./create-workflow.js";
export { err, ok } from "./result.js";
export type {
AdapterBinding,
AdapterFn,
AgentContext,
AgentFn,
@@ -14,7 +10,6 @@ export type {
ModeratorCondition,
ModeratorContext,
ModeratorTable,
ModeratorTransition,
Result,
RoleDefinition,
RoleFn,
@@ -22,17 +17,14 @@ export type {
RoleOutput,
RoleResult,
RoleStep,
StartStep,
ThreadContext,
WorkflowCompletion,
WorkflowDefinition,
WorkflowDescriptor,
WorkflowFn,
WorkflowGraph,
WorkflowGraphEdge,
WorkflowResult,
WorkflowRoleDescriptor,
WorkflowRoleSchema,
WorkflowRuntime,
} from "./types.js";
export { END, START } from "./types.js";
} from "@uncaged/workflow-protocol";
export { END, START } from "@uncaged/workflow-protocol";
export { buildThreadContext } from "./build-context.js";
export { createWorkflow } from "./create-workflow.js";
export { err, ok } from "./result.js";
@@ -29,10 +29,7 @@ export function createAgentAdapter<Opt>(
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 raw = await agent(ctx, options);
const contentHash = await putContentNodeWithRefs(runtime.cas, raw, []);
const extracted = await runtime.extract(
schema as z.ZodType<Record<string, unknown>>,
@@ -42,7 +39,3 @@ export function createAgentAdapter<Opt>(
};
};
}
export function createSimpleAgentAdapter(agent: AgentFn<void>): AdapterFn {
return createAgentAdapter(agent, async () => undefined as unknown as undefined);
}
+2 -3
View File
@@ -1,5 +1,4 @@
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 { SpawnCliConfig, SpawnCliError, SpawnCliResult } from "./spawn-cli.js";
export { createAgentAdapter } from "./create-agent-adapter.js";
export type { SpawnCliError } from "./spawn-cli.js";
export { spawnCli } from "./spawn-cli.js";
+3 -9
View File
@@ -1,14 +1,8 @@
export { err, ok } from "@uncaged/workflow-protocol";
export {
CROCKFORD_BASE32_ALPHABET,
decodeCrockfordBase32Bits,
decodeCrockfordToUint64,
encodeCrockfordBase32Bits,
encodeUint64AsCrockford,
} from "./base32.js";
export { encodeUint64AsCrockford } from "./base32.js";
export { env } from "./env.js";
export { createLogger } from "./logger.js";
export { mergeRefsWithContentHash, normalizeRefsField } from "./refs-field.js";
export { normalizeRefsField } from "./refs-field.js";
export { getDefaultWorkflowStorageRoot, getGlobalCasDir } from "./storage-root.js";
export type { CreateLoggerOptions, LogFn, LoggerSink, Result } from "./types.js";
export type { LogFn, Result } from "./types.js";
export { generateUlid } from "./ulid.js";