diff --git a/CLAUDE.md b/CLAUDE.md index 1255718..f7702cf 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -23,10 +23,9 @@ workflow/ packages/ workflow-protocol/ # @uncaged/workflow-protocol — shared types (WorkflowPayload, StepNodePayload, WorkflowConfig, etc.) workflow-util/ # @uncaged/workflow-util — Crockford Base32, ULID, logger, frontmatter parsing/validation - workflow-moderator/ # @uncaged/workflow-moderator — Status-based graph evaluator - workflow-agent-kit/ # @uncaged/workflow-agent-kit — createAgent factory, context builder, extract pipeline + workflow-util-agent/ # @uncaged/workflow-util-agent — createAgent factory, context builder, extract pipeline workflow-agent-hermes/ # @uncaged/workflow-agent-hermes — uwf-hermes CLI binary (spawns hermes chat) - cli-workflow/ # @uncaged/cli-workflow — uwf CLI binary + cli-workflow/ # @uncaged/cli-workflow — uwf CLI binary (includes status-based moderator in src/moderator/) legacy-packages/ # Archived packages (preserved for reference, not active) examples/ # Workflow YAML examples (solve-issue.yaml) docs/ # Architecture docs @@ -34,7 +33,7 @@ workflow/ tsconfig.json # root TypeScript config ``` -- Dependency layers: `workflow-protocol` → (`workflow-util`, `workflow-moderator`) → `workflow-agent-kit` → `workflow-agent-hermes` / `cli-workflow` +- Dependency layers: `workflow-protocol` → `workflow-util` → `workflow-util-agent` → `workflow-agent-hermes` / `cli-workflow` - Packages use `workspace:^` protocol (resolves to `^x.y.z` on publish) - External CAS: `@uncaged/json-cas` (store API, hashing, schema validation) + `@uncaged/json-cas-fs` (filesystem backend) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 988e680..a384d83 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -94,8 +94,7 @@ This creates a markdown file in `.changeset/` describing the change. It will be packages/ workflow-protocol/ # Shared types and JSON Schema workflow-util/ # Encoding, IDs, logging, frontmatter - workflow-moderator/ # Status-based graph evaluator - workflow-agent-kit/ # createAgent factory, extract pipeline + workflow-util-agent/ # createAgent factory, extract pipeline workflow-agent-hermes/ # Hermes ACP agent workflow-agent-builtin/ # Built-in LLM agent workflow-agent-claude-code/ # Claude Code agent diff --git a/README.md b/README.md index 98390b9..27d11fe 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![CI](https://github.com/shazhou-ww/uncaged-workflow/actions/workflows/ci.yml/badge.svg)](https://github.com/shazhou-ww/uncaged-workflow/actions/workflows/ci.yml) [![npm](https://img.shields.io/npm/v/@uncaged/cli-workflow?label=%40uncaged%2Fcli-workflow)](https://www.npmjs.com/package/@uncaged/cli-workflow) [![npm](https://img.shields.io/npm/v/@uncaged/workflow-protocol?label=%40uncaged%2Fworkflow-protocol)](https://www.npmjs.com/package/@uncaged/workflow-protocol) -[![npm](https://img.shields.io/npm/v/@uncaged/workflow-agent-kit?label=%40uncaged%2Fworkflow-agent-kit)](https://www.npmjs.com/package/@uncaged/workflow-agent-kit) +[![npm](https://img.shields.io/npm/v/@uncaged/workflow-util-agent?label=%40uncaged%2Fworkflow-util-agent)](https://www.npmjs.com/package/@uncaged/workflow-util-agent) A stateless workflow engine driven by a single-step CLI. Workflows are YAML definitions with roles, status-based routing, and a directed graph. Threads are immutable CAS-linked chains — each `uwf thread step` runs one moderator→agent→extract cycle and exits. @@ -51,10 +51,9 @@ Layer 0 — Contract Layer 1 — Shared infra workflow-util Encoding, IDs, logging, frontmatter, paths - workflow-moderator Status-based graph evaluator Layer 2 — Agent framework - workflow-agent-kit createAgent factory, context builder, extract pipeline + workflow-util-agent createAgent factory, context builder, extract pipeline Layer 3 — Agent implementations workflow-agent-hermes Hermes ACP agent (uwf-hermes) @@ -62,7 +61,7 @@ Layer 3 — Agent implementations workflow-agent-claude-code Claude Code agent (uwf-claude-code) Layer 4 — CLI - cli-workflow uwf binary — thread lifecycle, registry, CAS, setup + cli-workflow uwf binary — thread lifecycle, registry, CAS, setup (includes status-based moderator) App (uses protocol; not in the runtime engine stack) workflow-dashboard Web UI for visual workflow editing @@ -78,8 +77,7 @@ See [docs/architecture.md](docs/architecture.md) for the full design — three-p |---------|-----|-------------|------|--------| | `cli-workflow` | `@uncaged/cli-workflow` | `uwf` CLI — thread lifecycle, workflow registry, CAS inspection, setup | cli | [README](packages/cli-workflow/README.md) | | `workflow-protocol` | `@uncaged/workflow-protocol` | Shared TypeScript types and JSON Schema constants | lib | [README](packages/workflow-protocol/README.md) | -| `workflow-moderator` | `@uncaged/workflow-moderator` | Status-based graph evaluator — next role or `$END` | lib | [README](packages/workflow-moderator/README.md) | -| `workflow-agent-kit` | `@uncaged/workflow-agent-kit` | `createAgent` factory, context builder, extract pipeline | lib | [README](packages/workflow-agent-kit/README.md) | +| `workflow-util-agent` | `@uncaged/workflow-util-agent` | `createAgent` factory, context builder, extract pipeline | lib | [README](packages/workflow-util-agent/README.md) | | `workflow-util` | `@uncaged/workflow-util` | Crockford Base32, ULID, logger, frontmatter parsing, storage paths | lib | [README](packages/workflow-util/README.md) | | `workflow-agent-hermes` | `@uncaged/workflow-agent-hermes` | `uwf-hermes` — spawns Hermes chat via ACP | agent | [README](packages/workflow-agent-hermes/README.md) | | `workflow-agent-builtin` | `@uncaged/workflow-agent-builtin` | `uwf-builtin` — built-in LLM agent with file/shell tools | agent | [README](packages/workflow-agent-builtin/README.md) | diff --git a/docs/architecture.md b/docs/architecture.md index e32cd56..df3cc9b 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -8,7 +8,7 @@ A stateless workflow engine driven by a single-step CLI. Workflows are YAML definitions stored as CAS nodes; threads are immutable chains of CAS-linked step nodes. No daemon — each `uwf thread step` invocation runs one moderator→agent→extract cycle and exits. -The implementation lives in **6** active packages under `packages/`, plus two external CAS packages (`@uncaged/json-cas`, `@uncaged/json-cas-fs`). Legacy packages reside in `legacy-packages/` and are not part of the active stack. +The implementation lives in **5** active packages under `packages/`, plus two external CAS packages (`@uncaged/json-cas`, `@uncaged/json-cas-fs`). Legacy packages reside in `legacy-packages/` and are not part of the active stack. ## Package map @@ -16,10 +16,9 @@ The implementation lives in **6** active packages under `packages/`, plus two ex |-------|---------|---------------| | Contract | `@uncaged/workflow-protocol` → `workflow-protocol` | Shared TypeScript types (`WorkflowPayload`, `StepNodePayload`, `ModeratorContext`, `WorkflowConfig`, etc.). No runtime deps beyond `@uncaged/json-cas-fs`. | | Shared infra | `@uncaged/workflow-util` → `workflow-util` | Crockford Base32, ULID generation, `createLogger`, frontmatter parsing/validation. | -| Moderator | `@uncaged/workflow-moderator` → `workflow-moderator` | Status-based graph evaluator: given a routing graph, last role, and last output, returns the next role or `$END`. | -| Agent framework | `@uncaged/workflow-agent-kit` → `workflow-agent-kit` | `createAgent` entrypoint factory, context builder, frontmatter fast-path extractor, LLM extract fallback, output format instruction builder. | +| Agent framework | `@uncaged/workflow-util-agent` → `workflow-util-agent` | `createAgent` entrypoint factory, context builder, frontmatter fast-path extractor, LLM extract fallback, output format instruction builder. | | Agent: Hermes | `@uncaged/workflow-agent-hermes` → `workflow-agent-hermes` | `uwf-hermes` CLI binary — spawns `hermes chat`, pipes prompt, captures session detail. | -| CLI | `@uncaged/cli-workflow` → `cli-workflow` | `uwf` binary — thread lifecycle, workflow registry, CAS inspection, setup. | +| CLI | `@uncaged/cli-workflow` → `cli-workflow` | `uwf` binary — thread lifecycle, workflow registry, CAS inspection, setup. Includes status-based graph evaluator in `src/moderator/` (next role or `$END`). | ### External dependencies @@ -27,7 +26,7 @@ The implementation lives in **6** active packages under `packages/`, plus two ex |---------|------| | `@uncaged/json-cas` | Content-addressed store API, XXH64 hashing, JSON Schema registration and validation. | | `@uncaged/json-cas-fs` | Filesystem backend for `json-cas`. | -| `mustache` | Template renderer for edge prompts (used by `workflow-moderator`). | +| `mustache` | Template renderer for edge prompts (used by `cli-workflow` moderator). | | `commander` | CLI argument parsing (used by `cli-workflow`). | | `dotenv` | Loads `.env` files for API keys. | | `yaml` | YAML parse/stringify. | @@ -45,10 +44,9 @@ flowchart BT end subgraph L1["Layer 1 — shared"] util["@uncaged/workflow-util"] - moderator["@uncaged/workflow-moderator"] end subgraph L2["Layer 2 — agent framework"] - kit["@uncaged/workflow-agent-kit"] + kit["@uncaged/workflow-util-agent"] end subgraph L3["Layer 3 — agent implementations"] hermes["@uncaged/workflow-agent-hermes"] @@ -58,7 +56,6 @@ flowchart BT end protocol --> jcasfs util --> protocol - moderator --> protocol kit --> protocol kit --> util kit --> jcas @@ -68,7 +65,6 @@ flowchart BT cli --> protocol cli --> util cli --> kit - cli --> moderator cli --> jcas cli --> jcasfs ``` @@ -222,7 +218,7 @@ Each agent is an external command invoked by `uwf thread step`: Contract: 1. `uwf thread step` determines the next role via the moderator 2. Agent CLI is spawned with `(thread-id, role)` as positional args -3. `workflow-agent-kit` (`createAgent`) handles the boilerplate: +3. `workflow-util-agent` (`createAgent`) handles the boilerplate: - Parses argv - Loads `.env` from storage root - Builds `AgentContext` by walking the CAS chain from `threads.yaml` head @@ -255,11 +251,11 @@ scope: role Fixed the login redirect by updating the auth middleware... ``` -The `outputFormatInstruction` (built by `buildOutputFormatInstruction` in `workflow-agent-kit`) is prepended to the role's system prompt, so the deliverable format is the first thing the agent sees. It lists the expected frontmatter fields derived from the role's `meta` JSON Schema. +The `outputFormatInstruction` (built by `buildOutputFormatInstruction` in `workflow-util-agent`) is prepended to the role's system prompt, so the deliverable format is the first thing the agent sees. It lists the expected frontmatter fields derived from the role's `meta` JSON Schema. ## Two-layer extract -Structured output extraction uses a two-layer strategy (`workflow-agent-kit`): +Structured output extraction uses a two-layer strategy (`workflow-util-agent`): ### Layer 1: frontmatter fast path (`frontmatter.ts`) @@ -283,7 +279,7 @@ If the fast path returns `null` (no frontmatter, invalid, or doesn't satisfy sch ## Prompt injection -`workflow-agent-kit` prepends two pieces of context to the agent's system prompt: +`workflow-util-agent` prepends two pieces of context to the agent's system prompt: 1. **Deliverable format instruction** — generated from the role's `meta` schema, tells the agent exactly what frontmatter fields to produce and the expected format 2. **Scope constraint** — "Focus exclusively on YOUR role's deliverable. Do not perform actions outside your role's scope." diff --git a/docs/builtin-agent-research.md b/docs/builtin-agent-research.md index 2996880..63690f5 100644 --- a/docs/builtin-agent-research.md +++ b/docs/builtin-agent-research.md @@ -78,9 +78,9 @@ Agent 解析优先级(`resolveAgentConfig`): #### 环境变量:Storage Root -文档中写的 `UWF_STORAGE_ROOT` **在当前代码中不存在**。实际优先级(`workflow-agent-kit` / `cli-workflow` 一致): +文档中写的 `UWF_STORAGE_ROOT` **在当前代码中不存在**。实际优先级(`workflow-util-agent` / `cli-workflow` 一致): -```33:43:packages/workflow-agent-kit/src/storage.ts +```33:43:packages/workflow-util-agent/src/storage.ts export function resolveStorageRoot(): string { const internal = process.env.UNCAGED_WORKFLOW_STORAGE_ROOT; if (internal !== undefined && internal !== "") { @@ -107,7 +107,7 @@ Agent 子进程通过继承的 `process.env` 与父 CLI 共享同一 storage roo ### Q2: createAgent 工厂 -workflow-agent-kit 的 `createAgent` 做了什么?它的完整生命周期是什么? +workflow-util-agent 的 `createAgent` 做了什么?它的完整生命周期是什么? **调研要点:** - `AgentOptions` 类型的 `run` 和 `continue` 回调签名 @@ -119,7 +119,7 @@ workflow-agent-kit 的 `createAgent` 做了什么?它的完整生命周期是 #### 类型定义 -```4:35:packages/workflow-agent-kit/src/types.ts +```4:35:packages/workflow-util-agent/src/types.ts export type AgentContext = ModeratorContext & { threadId: ThreadId; role: string; @@ -156,7 +156,7 @@ export type AgentOptions = { #### 生命周期(按执行顺序) -```101:152:packages/workflow-agent-kit/src/run.ts +```101:152:packages/workflow-util-agent/src/run.ts export function createAgent(options: AgentOptions): () => Promise { return async function main(): Promise { const { threadId, role } = parseArgv(process.argv); @@ -197,7 +197,7 @@ export function createAgent(options: AgentOptions): () => Promise { #### StepNode 写入结构 -```44:68:packages/workflow-agent-kit/src/run.ts +```44:68:packages/workflow-util-agent/src/run.ts async function writeStepNode(options: { store: AgentStore["store"]; schemas: AgentStore["schemas"]; @@ -274,7 +274,7 @@ export type StepContext = Omit & { `buildContextWithMeta` 还返回 `meta`: -```148:154:packages/workflow-agent-kit/src/context.ts +```148:154:packages/workflow-util-agent/src/context.ts export type BuildContextMeta = { storageRoot: string; store: Store; @@ -337,7 +337,7 @@ async function resolveFrontmatterRef(..., frontmatter: unknown): Promise #### Frontmatter fast-path(createAgent 实际使用的路径) -```148:195:packages/workflow-agent-kit/src/frontmatter.ts +```148:195:packages/workflow-util-agent/src/frontmatter.ts export async function tryFrontmatterFastPath( raw: string, outputSchema: CasRef, @@ -357,7 +357,7 @@ export async function tryFrontmatterFastPath( #### LLM extract fallback(已实现但未接入 createAgent) -```135:181:packages/workflow-agent-kit/src/extract.ts +```135:181:packages/workflow-util-agent/src/extract.ts export async function extract( rawOutput: string, outputSchema: CasRef, @@ -374,7 +374,7 @@ export async function extract( #### Correction prompt(retry) -```125:128:packages/workflow-agent-kit/src/run.ts +```125:128:packages/workflow-util-agent/src/run.ts const correctionMessage = "Your previous response did not contain valid YAML frontmatter matching the role schema.\n" + "You MUST begin your response with a YAML frontmatter block (--- delimited).\n" + @@ -425,7 +425,7 @@ export type WorkflowConfig = { #### resolveModel -```32:50:packages/workflow-agent-kit/src/extract.ts +```32:50:packages/workflow-util-agent/src/extract.ts export function resolveModel(config: WorkflowConfig, alias: ModelAlias): ResolvedLlmProvider { const modelEntry = config.models[alias]; const providerEntry = config.providers[modelEntry.provider]; @@ -438,7 +438,7 @@ export function resolveModel(config: WorkflowConfig, alias: ModelAlias): Resolve Extract 专用别名解析: -```18:30:packages/workflow-agent-kit/src/extract.ts +```18:30:packages/workflow-util-agent/src/extract.ts export function resolveExtractModelAlias(config: WorkflowConfig): ModelAlias { return config.modelOverrides?.extract ?? (config.models.extract ? "extract" : config.models.default ? "default" : config.defaultModel); } @@ -448,7 +448,7 @@ export function resolveExtractModelAlias(config: WorkflowConfig): ModelAlias { #### chatCompletionText -```87:124:packages/workflow-agent-kit/src/extract.ts +```87:124:packages/workflow-util-agent/src/extract.ts async function chatCompletionText( provider: ResolvedLlmProvider, messages: Array<{ role: "system" | "user"; content: string }>, @@ -463,7 +463,7 @@ async function chatCompletionText( | 多模态 | **无**(仅 text `content`) | | Extract 专用 | `response_format: { type: "json_object" }` | -builtin agent 的 run loop 需要**新写**带 `tools` 的 completion 客户端(可放在 `workflow-agent-builtin` 或扩展 `workflow-agent-kit` 的 `llm/` 模块),不能复用当前 `chatCompletionText` 而不改。 +builtin agent 的 run loop 需要**新写**带 `tools` 的 completion 客户端(可放在 `workflow-agent-builtin` 或扩展 `workflow-util-agent` 的 `llm/` 模块),不能复用当前 `chatCompletionText` 而不改。 --- @@ -609,7 +609,7 @@ flowchart TB Loop --> Detail end - subgraph kit ["workflow-agent-kit"] + subgraph kit ["workflow-util-agent"] Ctx["buildContextWithMeta"] FM["tryFrontmatterFastPath"] Persist["persistStep"] @@ -630,7 +630,7 @@ flowchart TB Spawn -->|"stdout: step hash"| Step ``` -**新包**:`packages/workflow-agent-builtin`,bin `uwf-builtin`,仅依赖 `workflow-agent-kit`、`workflow-protocol`、`workflow-util`(可选 `@uncaged/json-cas` 写 detail schema)。 +**新包**:`packages/workflow-agent-builtin`,bin `uwf-builtin`,仅依赖 `workflow-util-agent`、`workflow-protocol`、`workflow-util`(可选 `@uncaged/json-cas` 写 detail schema)。 **分层**: diff --git a/docs/wf-stateless-design.md b/docs/wf-stateless-design.md index 8de67d9..257891d 100644 --- a/docs/wf-stateless-design.md +++ b/docs/wf-stateless-design.md @@ -341,9 +341,8 @@ OPENROUTER_API_KEY=sk-or-... ``` packages/ -├── cli-workflow/ # @uncaged/cli-workflow — uwf CLI(thread/workflow 命令) -├── workflow-moderator/ # @uncaged/workflow-moderator — Status-based moderator 引擎 -├── workflow-agent-kit/ # @uncaged/workflow-agent-kit — Agent CLI 框架(含 extractor) +├── cli-workflow/ # @uncaged/cli-workflow — uwf CLI(thread/workflow 命令,含 src/moderator/) +├── workflow-util-agent/ # @uncaged/workflow-util-agent — Agent CLI 框架(含 extractor) ├── workflow-agent-hermes/ # @uncaged/workflow-agent-hermes — uwf-hermes CLI ├── workflow-agent-cursor/ # @uncaged/workflow-agent-cursor — uwf-cursor CLI └── workflow-protocol/ # @uncaged/workflow-protocol — 共享类型定义 diff --git a/packages/workflow-moderator/README.md b/legacy-packages/workflow-moderator/README.md similarity index 100% rename from packages/workflow-moderator/README.md rename to legacy-packages/workflow-moderator/README.md diff --git a/packages/workflow-moderator/__tests__/evaluate.test.ts b/legacy-packages/workflow-moderator/__tests__/evaluate.test.ts similarity index 100% rename from packages/workflow-moderator/__tests__/evaluate.test.ts rename to legacy-packages/workflow-moderator/__tests__/evaluate.test.ts diff --git a/packages/workflow-moderator/package.json b/legacy-packages/workflow-moderator/package.json similarity index 94% rename from packages/workflow-moderator/package.json rename to legacy-packages/workflow-moderator/package.json index 98c81ea..4f53075 100644 --- a/packages/workflow-moderator/package.json +++ b/legacy-packages/workflow-moderator/package.json @@ -32,7 +32,7 @@ "repository": { "type": "git", "url": "https://github.com/shazhou-ww/uncaged-workflow.git", - "directory": "packages/workflow-moderator" + "directory": "legacy-packages/workflow-moderator" }, "homepage": "https://github.com/shazhou-ww/uncaged-workflow#readme", "bugs": { diff --git a/packages/workflow-moderator/src/evaluate.ts b/legacy-packages/workflow-moderator/src/evaluate.ts similarity index 100% rename from packages/workflow-moderator/src/evaluate.ts rename to legacy-packages/workflow-moderator/src/evaluate.ts diff --git a/packages/workflow-moderator/src/index.ts b/legacy-packages/workflow-moderator/src/index.ts similarity index 100% rename from packages/workflow-moderator/src/index.ts rename to legacy-packages/workflow-moderator/src/index.ts diff --git a/packages/workflow-moderator/src/types.ts b/legacy-packages/workflow-moderator/src/types.ts similarity index 100% rename from packages/workflow-moderator/src/types.ts rename to legacy-packages/workflow-moderator/src/types.ts diff --git a/packages/workflow-agent-kit/tsconfig.json b/legacy-packages/workflow-moderator/tsconfig.json similarity index 100% rename from packages/workflow-agent-kit/tsconfig.json rename to legacy-packages/workflow-moderator/tsconfig.json diff --git a/packages/cli-workflow/README.md b/packages/cli-workflow/README.md index a310ed7..2b9e2fd 100644 --- a/packages/cli-workflow/README.md +++ b/packages/cli-workflow/README.md @@ -20,7 +20,7 @@ workflow → thread → step → turn This package has no library `src/index.ts` — it is consumed as a CLI binary only. -**Dependencies:** `@uncaged/json-cas`, `@uncaged/json-cas-fs`, `@uncaged/workflow-agent-kit`, `@uncaged/workflow-moderator`, `@uncaged/workflow-protocol`, `@uncaged/workflow-util`, `commander`, `dotenv`, `yaml` +**Dependencies:** `@uncaged/json-cas`, `@uncaged/json-cas-fs`, `@uncaged/workflow-util-agent`, `@uncaged/workflow-protocol`, `@uncaged/workflow-util`, `commander`, `dotenv`, `mustache`, `yaml` ## Installation @@ -190,6 +190,7 @@ src/ ├── store.ts CAS store + registry initialization ├── validate.ts Workflow YAML validation ├── schemas.ts CLI-local schema registration +├── moderator/ Status-based graph evaluator (next role or $END) └── commands/ ├── thread.ts Thread lifecycle and exec ├── step.ts Step operations (list/show/read/fork) diff --git a/packages/cli-workflow/package.json b/packages/cli-workflow/package.json index e484658..bfaad87 100644 --- a/packages/cli-workflow/package.json +++ b/packages/cli-workflow/package.json @@ -13,12 +13,12 @@ "dependencies": { "@uncaged/json-cas": "^0.5.2", "@uncaged/json-cas-fs": "^0.5.2", - "@uncaged/workflow-agent-kit": "workspace:^", - "@uncaged/workflow-moderator": "workspace:^", "@uncaged/workflow-protocol": "workspace:^", "@uncaged/workflow-util": "workspace:^", + "@uncaged/workflow-util-agent": "workspace:^", "commander": "^14.0.3", "dotenv": "^16.6.1", + "mustache": "^4.2.0", "yaml": "^2.8.4" }, "scripts": { @@ -29,6 +29,7 @@ "access": "public" }, "devDependencies": { + "@types/mustache": "^4.2.6", "vitest": "^4.1.6" }, "repository": { diff --git a/packages/cli-workflow/src/__tests__/moderator-evaluate.test.ts b/packages/cli-workflow/src/__tests__/moderator-evaluate.test.ts new file mode 100644 index 0000000..1e29c8e --- /dev/null +++ b/packages/cli-workflow/src/__tests__/moderator-evaluate.test.ts @@ -0,0 +1,132 @@ +import { describe, expect, test } from "vitest"; +import type { Target, WorkflowPayload } from "@uncaged/workflow-protocol"; + +import { evaluate } from "../moderator/evaluate.js"; + +const solveIssueGraph: WorkflowPayload["graph"] = { + $START: { + _: { role: "planner", prompt: "Start planning from the issue in the task." }, + }, + planner: { + _: { role: "developer", prompt: "Implement the plan: {{plan}}" }, + }, + developer: { + _: { role: "reviewer", prompt: "Review the changes: {{summary}}" }, + }, + reviewer: { + approved: { role: "$END", prompt: "Done." }, + rejected: { role: "developer", prompt: "Fix: {{comments}}" }, + }, +}; + +describe("evaluate", () => { + test("$START → first role (unit status _)", () => { + const result = evaluate(solveIssueGraph, "$START", { $status: "_" }); + expect(result).toEqual({ + ok: true, + value: { role: "planner", prompt: "Start planning from the issue in the task." }, + }); + }); + + test("status-based routing (reviewer rejected → developer)", () => { + const result = evaluate(solveIssueGraph, "reviewer", { + $status: "rejected", + comments: "missing tests", + }); + expect(result).toEqual({ + ok: true, + value: { role: "developer", prompt: "Fix: missing tests" }, + }); + }); + + test("status-based routing (reviewer approved → $END)", () => { + const result = evaluate(solveIssueGraph, "reviewer", { $status: "approved" }); + expect(result).toEqual({ + ok: true, + value: { role: "$END", prompt: "Done." }, + }); + }); + + test("missing role in graph → error", () => { + const result = evaluate(solveIssueGraph, "unknown-role", { $status: "_" }); + expect(result.ok).toBe(false); + if (!result.ok) { + expect(result.error.message).toBe('no transitions defined for role "unknown-role"'); + } + }); + + test("missing status in graph → error", () => { + const result = evaluate(solveIssueGraph, "reviewer", { $status: "pending" }); + expect(result.ok).toBe(false); + if (!result.ok) { + expect(result.error.message).toBe('no transition for role "reviewer" with status "pending"'); + } + }); + + test("mustache template rendering with simple fields", () => { + const result = evaluate(solveIssueGraph, "planner", { + $status: "_", + plan: "Add auth middleware", + }); + expect(result).toEqual({ + ok: true, + value: { role: "developer", prompt: "Implement the plan: Add auth middleware" }, + }); + }); + + test("mustache does not HTML-escape prompt content", () => { + const result = evaluate(solveIssueGraph, "reviewer", { + $status: "rejected", + comments: 'use & "Result" types', + }); + expect(result).toEqual({ + ok: true, + value: { role: "developer", prompt: 'Fix: use & "Result" types' }, + }); + }); + + test("triple mustache also works for unescaped output", () => { + const graph: Record> = { + reviewer: { + _: { role: "developer", prompt: "Fix: {{{comments}}}" }, + }, + }; + const result = evaluate(graph, "reviewer", { + $status: "_", + comments: "", + }); + expect(result).toEqual({ + ok: true, + value: { role: "developer", prompt: "Fix: " }, + }); + }); + + test("missing $status defaults to _ (unit routing)", () => { + const result = evaluate(solveIssueGraph, "planner", { + plan: "Add auth middleware", + }); + expect(result).toEqual({ + ok: true, + value: { role: "developer", prompt: "Implement the plan: Add auth middleware" }, + }); + }); + + test("mustache template with nested object paths", () => { + const graph: Record> = { + reviewer: { + _: { + role: "developer", + prompt: "Address: {{review.comments}}", + }, + }, + }; + const result = evaluate(graph, "reviewer", { + $status: "_", + review: { comments: "refactor the handler" }, + }); + expect(result).toEqual({ + ok: true, + value: { role: "developer", prompt: "Address: refactor the handler" }, + }); + }); +}); diff --git a/packages/cli-workflow/src/commands/thread.ts b/packages/cli-workflow/src/commands/thread.ts index eafa3f3..4cf1f05 100644 --- a/packages/cli-workflow/src/commands/thread.ts +++ b/packages/cli-workflow/src/commands/thread.ts @@ -2,8 +2,8 @@ import { execFileSync, spawn } from "node:child_process"; import { access, readFile } from "node:fs/promises"; import { dirname, isAbsolute, resolve as resolvePath } from "node:path"; import { validate } from "@uncaged/json-cas"; -import { getEnvPath, loadWorkflowConfig } from "@uncaged/workflow-agent-kit"; -import { evaluate } from "@uncaged/workflow-moderator"; +import { getEnvPath, loadWorkflowConfig } from "@uncaged/workflow-util-agent"; +import { evaluate } from "../moderator/index.js"; import type { AgentAlias, AgentConfig, diff --git a/packages/cli-workflow/src/moderator/evaluate.ts b/packages/cli-workflow/src/moderator/evaluate.ts new file mode 100644 index 0000000..ae82e4a --- /dev/null +++ b/packages/cli-workflow/src/moderator/evaluate.ts @@ -0,0 +1,53 @@ +import type { Target } from "@uncaged/workflow-protocol"; +import mustache from "mustache"; + +import type { EvaluateResult, Result } from "./types.js"; + +// Disable HTML escaping — prompts are plain text, not HTML. +mustache.escape = (text: string) => text; + +const START_ROLE = "$START"; +const UNIT_STATUS = "_"; + +type LastOutput = Record; + +const STATUS_KEY = "$status"; + +export function evaluate( + graph: Record>, + lastRole: string, + lastOutput: LastOutput, +): Result { + const status = + lastRole === START_ROLE + ? UNIT_STATUS + : typeof lastOutput[STATUS_KEY] === "string" + ? (lastOutput[STATUS_KEY] as string) + : UNIT_STATUS; + + const roleTargets = graph[lastRole]; + if (roleTargets === undefined) { + return { + ok: false, + error: new Error(`no transitions defined for role "${lastRole}"`), + }; + } + + const target = roleTargets[status]; + if (target === undefined) { + return { + ok: false, + error: new Error(`no transition for role "${lastRole}" with status "${status}"`), + }; + } + + try { + const prompt = mustache.render(target.prompt, lastOutput); + return { ok: true, value: { role: target.role, prompt } }; + } catch (error) { + return { + ok: false, + error: error instanceof Error ? error : new Error(String(error)), + }; + } +} diff --git a/packages/cli-workflow/src/moderator/index.ts b/packages/cli-workflow/src/moderator/index.ts new file mode 100644 index 0000000..91dabbc --- /dev/null +++ b/packages/cli-workflow/src/moderator/index.ts @@ -0,0 +1,2 @@ +export { evaluate } from "./evaluate.js"; +export type { EvaluateResult } from "./types.js"; diff --git a/packages/cli-workflow/src/moderator/types.ts b/packages/cli-workflow/src/moderator/types.ts new file mode 100644 index 0000000..77599f0 --- /dev/null +++ b/packages/cli-workflow/src/moderator/types.ts @@ -0,0 +1,7 @@ +export type Result = { ok: true; value: T } | { ok: false; error: E }; + +/** The result of moderator evaluation — which role to go to, and the edge prompt. */ +export type EvaluateResult = { + role: string; + prompt: string; +}; diff --git a/packages/cli-workflow/tsconfig.json b/packages/cli-workflow/tsconfig.json index 449a6f7..e0c56fc 100644 --- a/packages/cli-workflow/tsconfig.json +++ b/packages/cli-workflow/tsconfig.json @@ -7,7 +7,6 @@ "include": ["src"], "references": [ { "path": "../workflow-protocol" }, - { "path": "../workflow-moderator" }, - { "path": "../workflow-agent-kit" } + { "path": "../workflow-util-agent" } ] } diff --git a/packages/workflow-agent-builtin/README.md b/packages/workflow-agent-builtin/README.md index 2a31b7f..4855310 100644 --- a/packages/workflow-agent-builtin/README.md +++ b/packages/workflow-agent-builtin/README.md @@ -8,7 +8,7 @@ Layer 3 agent implementation. Runs an OpenAI-compatible chat completion loop wit Useful when you want a self-contained agent without an external CLI like Hermes or Claude Code. -**Dependencies:** `@uncaged/json-cas`, `@uncaged/workflow-agent-kit`, `@uncaged/workflow-util` +**Dependencies:** `@uncaged/json-cas`, `@uncaged/workflow-util-agent`, `@uncaged/workflow-util` ## Installation diff --git a/packages/workflow-agent-builtin/__tests__/prompt.test.ts b/packages/workflow-agent-builtin/__tests__/prompt.test.ts index 9bba61b..bd57af9 100644 --- a/packages/workflow-agent-builtin/__tests__/prompt.test.ts +++ b/packages/workflow-agent-builtin/__tests__/prompt.test.ts @@ -1,6 +1,6 @@ import { describe, expect, test } from "bun:test"; -import type { AgentContext } from "@uncaged/workflow-agent-kit"; +import type { AgentContext } from "@uncaged/workflow-util-agent"; import { buildBuiltinMessages } from "../src/prompt.js"; diff --git a/packages/workflow-agent-builtin/package.json b/packages/workflow-agent-builtin/package.json index 91568c1..7e87e00 100644 --- a/packages/workflow-agent-builtin/package.json +++ b/packages/workflow-agent-builtin/package.json @@ -23,7 +23,7 @@ }, "dependencies": { "@uncaged/json-cas": "^0.5.2", - "@uncaged/workflow-agent-kit": "workspace:^", + "@uncaged/workflow-util-agent": "workspace:^", "@uncaged/workflow-util": "workspace:^" }, "devDependencies": { diff --git a/packages/workflow-agent-builtin/src/agent.ts b/packages/workflow-agent-builtin/src/agent.ts index 589e605..b75c10a 100644 --- a/packages/workflow-agent-builtin/src/agent.ts +++ b/packages/workflow-agent-builtin/src/agent.ts @@ -6,7 +6,7 @@ import { loadWorkflowConfig, resolveModel, resolveStorageRoot, -} from "@uncaged/workflow-agent-kit"; +} from "@uncaged/workflow-util-agent"; import { createLogger, generateUlid } from "@uncaged/workflow-util"; import { storeBuiltinDetail } from "./detail.js"; diff --git a/packages/workflow-agent-builtin/src/llm/llm.ts b/packages/workflow-agent-builtin/src/llm/llm.ts index 6c85b7c..47c12e8 100644 --- a/packages/workflow-agent-builtin/src/llm/llm.ts +++ b/packages/workflow-agent-builtin/src/llm/llm.ts @@ -1,4 +1,4 @@ -import type { ResolvedLlmProvider } from "@uncaged/workflow-agent-kit"; +import type { ResolvedLlmProvider } from "@uncaged/workflow-util-agent"; import type { ChatMessage, diff --git a/packages/workflow-agent-builtin/src/loop.ts b/packages/workflow-agent-builtin/src/loop.ts index 602e36c..40dfafe 100644 --- a/packages/workflow-agent-builtin/src/loop.ts +++ b/packages/workflow-agent-builtin/src/loop.ts @@ -1,4 +1,4 @@ -import type { ResolvedLlmProvider } from "@uncaged/workflow-agent-kit"; +import type { ResolvedLlmProvider } from "@uncaged/workflow-util-agent"; import { createLogger } from "@uncaged/workflow-util"; import { diff --git a/packages/workflow-agent-builtin/src/prompt.ts b/packages/workflow-agent-builtin/src/prompt.ts index d091e90..199badf 100644 --- a/packages/workflow-agent-builtin/src/prompt.ts +++ b/packages/workflow-agent-builtin/src/prompt.ts @@ -1,4 +1,4 @@ -import { type AgentContext, buildRolePrompt } from "@uncaged/workflow-agent-kit"; +import { type AgentContext, buildRolePrompt } from "@uncaged/workflow-util-agent"; import type { ChatMessage } from "./llm/index.js"; diff --git a/packages/workflow-agent-builtin/tsconfig.json b/packages/workflow-agent-builtin/tsconfig.json index de22a37..28acf4f 100644 --- a/packages/workflow-agent-builtin/tsconfig.json +++ b/packages/workflow-agent-builtin/tsconfig.json @@ -5,5 +5,5 @@ "outDir": "dist" }, "include": ["src"], - "references": [{ "path": "../workflow-agent-kit" }, { "path": "../workflow-util" }] + "references": [{ "path": "../workflow-util-agent" }, { "path": "../workflow-util" }] } diff --git a/packages/workflow-agent-claude-code/README.md b/packages/workflow-agent-claude-code/README.md index 78f19c7..09f84b9 100644 --- a/packages/workflow-agent-claude-code/README.md +++ b/packages/workflow-agent-claude-code/README.md @@ -6,7 +6,7 @@ Layer 3 agent implementation. Spawns the `claude` CLI with a composed system prompt (role definition, task, prior steps, edge prompt). Parses stream or JSON stdout, caches session IDs for multi-turn continuation, and stores raw output plus structured detail in CAS. -**Dependencies:** `@uncaged/json-cas`, `@uncaged/workflow-agent-kit` +**Dependencies:** `@uncaged/json-cas`, `@uncaged/workflow-util-agent` ## Installation @@ -86,6 +86,6 @@ src/ ## Configuration -Uses session caching from `@uncaged/workflow-agent-kit` (`getCachedSessionId` / `setCachedSessionId`). No separate config file — relies on the Claude Code CLI's own authentication. +Uses session caching from `@uncaged/workflow-util-agent` (`getCachedSessionId` / `setCachedSessionId`). No separate config file — relies on the Claude Code CLI's own authentication. Maximum turns per invocation: 90 (constant in `claude-code.ts`). diff --git a/packages/workflow-agent-claude-code/__tests__/claude-code.test.ts b/packages/workflow-agent-claude-code/__tests__/claude-code.test.ts index 32f1527..cbcf7a2 100644 --- a/packages/workflow-agent-claude-code/__tests__/claude-code.test.ts +++ b/packages/workflow-agent-claude-code/__tests__/claude-code.test.ts @@ -1,5 +1,5 @@ import { describe, expect, test } from "bun:test"; -import type { AgentContext } from "@uncaged/workflow-agent-kit"; +import type { AgentContext } from "@uncaged/workflow-util-agent"; import type { ThreadId } from "@uncaged/workflow-protocol"; import { buildClaudeCodePrompt } from "../src/claude-code.js"; diff --git a/packages/workflow-agent-claude-code/package.json b/packages/workflow-agent-claude-code/package.json index 604c0d4..0fc8069 100644 --- a/packages/workflow-agent-claude-code/package.json +++ b/packages/workflow-agent-claude-code/package.json @@ -23,7 +23,7 @@ }, "dependencies": { "@uncaged/json-cas": "^0.5.2", - "@uncaged/workflow-agent-kit": "workspace:^", + "@uncaged/workflow-util-agent": "workspace:^", "@uncaged/workflow-util": "workspace:^" }, "devDependencies": { diff --git a/packages/workflow-agent-claude-code/src/claude-code.ts b/packages/workflow-agent-claude-code/src/claude-code.ts index 52dc03b..9cfacc5 100644 --- a/packages/workflow-agent-claude-code/src/claude-code.ts +++ b/packages/workflow-agent-claude-code/src/claude-code.ts @@ -8,7 +8,7 @@ import { createAgent, getCachedSessionId, setCachedSessionId, -} from "@uncaged/workflow-agent-kit"; +} from "@uncaged/workflow-util-agent"; import { createLogger } from "@uncaged/workflow-util"; import { parseClaudeCodeStreamOutput, storeClaudeCodeDetail } from "./session-detail.js"; diff --git a/packages/workflow-agent-claude-code/tsconfig.json b/packages/workflow-agent-claude-code/tsconfig.json index b367d4d..30bdbfb 100644 --- a/packages/workflow-agent-claude-code/tsconfig.json +++ b/packages/workflow-agent-claude-code/tsconfig.json @@ -2,5 +2,5 @@ "extends": "../../tsconfig.json", "compilerOptions": { "rootDir": "src", "outDir": "dist" }, "include": ["src"], - "references": [{ "path": "../workflow-agent-kit" }] + "references": [{ "path": "../workflow-util-agent" }] } diff --git a/packages/workflow-agent-hermes/README.md b/packages/workflow-agent-hermes/README.md index e82786e..a7e38e1 100644 --- a/packages/workflow-agent-hermes/README.md +++ b/packages/workflow-agent-hermes/README.md @@ -6,7 +6,7 @@ Layer 3 agent implementation. Wraps the Hermes CLI using the Agent Client Protocol (ACP). On first visit to a role it sends a composed prompt (role definition, task, history, edge prompt); on continuation it resumes the cached session. Session transcripts and raw output are stored as CAS detail nodes. -**Dependencies:** `@uncaged/json-cas`, `@uncaged/workflow-agent-kit`, `@uncaged/workflow-protocol`, `@uncaged/workflow-util` +**Dependencies:** `@uncaged/json-cas`, `@uncaged/workflow-util-agent`, `@uncaged/workflow-protocol`, `@uncaged/workflow-util` ## Installation diff --git a/packages/workflow-agent-hermes/__tests__/hermes-prompt.test.ts b/packages/workflow-agent-hermes/__tests__/hermes-prompt.test.ts index 096d318..2df6444 100644 --- a/packages/workflow-agent-hermes/__tests__/hermes-prompt.test.ts +++ b/packages/workflow-agent-hermes/__tests__/hermes-prompt.test.ts @@ -1,5 +1,5 @@ import { describe, expect, test } from "bun:test"; -import type { AgentContext } from "@uncaged/workflow-agent-kit"; +import type { AgentContext } from "@uncaged/workflow-util-agent"; import type { ThreadId } from "@uncaged/workflow-protocol"; import { buildHermesPrompt } from "../src/hermes.js"; diff --git a/packages/workflow-agent-hermes/package.json b/packages/workflow-agent-hermes/package.json index d9e9082..ab2598a 100644 --- a/packages/workflow-agent-hermes/package.json +++ b/packages/workflow-agent-hermes/package.json @@ -23,7 +23,7 @@ }, "dependencies": { "@uncaged/json-cas": "^0.5.2", - "@uncaged/workflow-agent-kit": "workspace:^", + "@uncaged/workflow-util-agent": "workspace:^", "@uncaged/workflow-protocol": "workspace:^", "@uncaged/workflow-util": "workspace:^" }, diff --git a/packages/workflow-agent-hermes/src/hermes.ts b/packages/workflow-agent-hermes/src/hermes.ts index 781e26f..2cfee8f 100644 --- a/packages/workflow-agent-hermes/src/hermes.ts +++ b/packages/workflow-agent-hermes/src/hermes.ts @@ -5,7 +5,7 @@ import { buildContinuationPrompt, buildRolePrompt, createAgent, -} from "@uncaged/workflow-agent-kit"; +} from "@uncaged/workflow-util-agent"; import { createLogger } from "@uncaged/workflow-util"; import { HermesAcpClient } from "./acp-client.js"; diff --git a/packages/workflow-agent-hermes/src/session-cache.ts b/packages/workflow-agent-hermes/src/session-cache.ts index 3c59ff2..83f8952 100644 --- a/packages/workflow-agent-hermes/src/session-cache.ts +++ b/packages/workflow-agent-hermes/src/session-cache.ts @@ -3,7 +3,7 @@ import { getCachedSessionId as getCachedSessionIdBase, setCachedSessionId as setCachedSessionIdBase, -} from "@uncaged/workflow-agent-kit"; +} from "@uncaged/workflow-util-agent"; import type { ThreadId } from "@uncaged/workflow-protocol"; export async function getCachedSessionId(threadId: ThreadId, role: string): Promise { diff --git a/packages/workflow-agent-hermes/tsconfig.json b/packages/workflow-agent-hermes/tsconfig.json index a9538da..55a2878 100644 --- a/packages/workflow-agent-hermes/tsconfig.json +++ b/packages/workflow-agent-hermes/tsconfig.json @@ -5,5 +5,5 @@ "outDir": "dist" }, "include": ["src"], - "references": [{ "path": "../workflow-agent-kit" }] + "references": [{ "path": "../workflow-util-agent" }] } diff --git a/packages/workflow-protocol/README.md b/packages/workflow-protocol/README.md index a148034..466890b 100644 --- a/packages/workflow-protocol/README.md +++ b/packages/workflow-protocol/README.md @@ -183,4 +183,4 @@ src/ ## Configuration -This package defines `WorkflowConfig` types only. Runtime config loading lives in `@uncaged/workflow-agent-kit` (`loadWorkflowConfig`). +This package defines `WorkflowConfig` types only. Runtime config loading lives in `@uncaged/workflow-util-agent` (`loadWorkflowConfig`). diff --git a/packages/workflow-agent-kit/README.md b/packages/workflow-util-agent/README.md similarity index 98% rename from packages/workflow-agent-kit/README.md rename to packages/workflow-util-agent/README.md index 669a76a..a1b75f1 100644 --- a/packages/workflow-agent-kit/README.md +++ b/packages/workflow-util-agent/README.md @@ -1,4 +1,4 @@ -# @uncaged/workflow-agent-kit +# @uncaged/workflow-util-agent Agent framework — `createAgent` factory, context builder, frontmatter fast-path, and LLM extract pipeline. @@ -13,7 +13,7 @@ Also exports prompt builders, config/storage helpers, and session ID caching for ## Installation ```bash -bun add @uncaged/workflow-agent-kit +bun add @uncaged/workflow-util-agent ``` ## API @@ -140,8 +140,8 @@ function loadWorkflowConfig(storageRoot: string): Promise ## Usage ```typescript -import { createAgent, buildRolePrompt } from "@uncaged/workflow-agent-kit"; -import type { AgentContext, AgentRunResult } from "@uncaged/workflow-agent-kit"; +import { createAgent, buildRolePrompt } from "@uncaged/workflow-util-agent"; +import type { AgentContext, AgentRunResult } from "@uncaged/workflow-util-agent"; async function run(ctx: AgentContext): Promise { const prompt = buildRolePrompt(ctx.workflow.roles[ctx.role]!); diff --git a/packages/workflow-agent-kit/__tests__/build-continuation-prompt.test.ts b/packages/workflow-util-agent/__tests__/build-continuation-prompt.test.ts similarity index 100% rename from packages/workflow-agent-kit/__tests__/build-continuation-prompt.test.ts rename to packages/workflow-util-agent/__tests__/build-continuation-prompt.test.ts diff --git a/packages/workflow-agent-kit/__tests__/build-output-format-instruction.test.ts b/packages/workflow-util-agent/__tests__/build-output-format-instruction.test.ts similarity index 100% rename from packages/workflow-agent-kit/__tests__/build-output-format-instruction.test.ts rename to packages/workflow-util-agent/__tests__/build-output-format-instruction.test.ts diff --git a/packages/workflow-agent-kit/__tests__/build-role-prompt.test.ts b/packages/workflow-util-agent/__tests__/build-role-prompt.test.ts similarity index 100% rename from packages/workflow-agent-kit/__tests__/build-role-prompt.test.ts rename to packages/workflow-util-agent/__tests__/build-role-prompt.test.ts diff --git a/packages/workflow-agent-kit/__tests__/context.test.ts b/packages/workflow-util-agent/__tests__/context.test.ts similarity index 100% rename from packages/workflow-agent-kit/__tests__/context.test.ts rename to packages/workflow-util-agent/__tests__/context.test.ts diff --git a/packages/workflow-agent-kit/__tests__/frontmatter-fast-path.test.ts b/packages/workflow-util-agent/__tests__/frontmatter-fast-path.test.ts similarity index 100% rename from packages/workflow-agent-kit/__tests__/frontmatter-fast-path.test.ts rename to packages/workflow-util-agent/__tests__/frontmatter-fast-path.test.ts diff --git a/packages/workflow-agent-kit/__tests__/resolve-extract-model.test.ts b/packages/workflow-util-agent/__tests__/resolve-extract-model.test.ts similarity index 100% rename from packages/workflow-agent-kit/__tests__/resolve-extract-model.test.ts rename to packages/workflow-util-agent/__tests__/resolve-extract-model.test.ts diff --git a/packages/workflow-agent-kit/__tests__/session-cache.test.ts b/packages/workflow-util-agent/__tests__/session-cache.test.ts similarity index 100% rename from packages/workflow-agent-kit/__tests__/session-cache.test.ts rename to packages/workflow-util-agent/__tests__/session-cache.test.ts diff --git a/packages/workflow-agent-kit/package.json b/packages/workflow-util-agent/package.json similarity index 91% rename from packages/workflow-agent-kit/package.json rename to packages/workflow-util-agent/package.json index 1716494..d2904e9 100644 --- a/packages/workflow-agent-kit/package.json +++ b/packages/workflow-util-agent/package.json @@ -1,5 +1,5 @@ { - "name": "@uncaged/workflow-agent-kit", + "name": "@uncaged/workflow-util-agent", "version": "0.5.0", "files": [ "src", @@ -35,7 +35,7 @@ "repository": { "type": "git", "url": "https://github.com/shazhou-ww/uncaged-workflow.git", - "directory": "packages/workflow-agent-kit" + "directory": "packages/workflow-util-agent" }, "homepage": "https://github.com/shazhou-ww/uncaged-workflow#readme", "bugs": { diff --git a/packages/workflow-util-agent/src/build-agent-prompt.ts b/packages/workflow-util-agent/src/build-agent-prompt.ts deleted file mode 100644 index a132f09..0000000 --- a/packages/workflow-util-agent/src/build-agent-prompt.ts +++ /dev/null @@ -1,64 +0,0 @@ -import type { AgentContext } from "@uncaged/workflow-runtime"; - -/** Max characters of step content to include in the prompt. */ -const CONTENT_QUOTA = 16_000; - -/** Builds the full agent prompt: system instructions plus summarized thread history. */ -export async function buildAgentPrompt(ctx: AgentContext): Promise { - const lines: string[] = []; - lines.push(ctx.currentRole.systemPrompt); - lines.push(""); - lines.push("## Task"); - lines.push(ctx.start.content); - - const { steps } = ctx; - if (steps.length === 0) { - return lines.join("\n"); - } - - if (steps.length === 1) { - const s = steps[0]; - lines.push(""); - lines.push(`## Step: ${s.role}`); - lines.push(""); - lines.push(`Meta: ${JSON.stringify(s.meta)}`); - appendContent(lines, s.content); - } else { - lines.push(""); - lines.push("## Previous Steps"); - for (let i = 0; i < steps.length - 1; i++) { - const s = steps[i]; - lines.push(""); - lines.push(`### Step ${i + 1}: ${s.role}`); - lines.push(`Summary: ${JSON.stringify(s.meta)}`); - } - const last = steps[steps.length - 1]; - lines.push(""); - lines.push(`## Latest Step: ${last.role}`); - lines.push(""); - lines.push(`Meta: ${JSON.stringify(last.meta)}`); - appendContent(lines, last.content); - } - - lines.push(""); - lines.push("## Tools"); - lines.push( - `Use \`uncaged-workflow thread ${ctx.threadId}\` to read full details of any previous step.`, - ); - - return lines.join("\n"); -} - -function appendContent(lines: string[], content: string | null | undefined): void { - if (content === null || content === undefined || content.trim() === "") { - return; - } - const truncated = - content.length > CONTENT_QUOTA - ? `${content.slice(0, CONTENT_QUOTA)}\n... (truncated)` - : content; - lines.push(""); - lines.push(""); - lines.push(truncated); - lines.push(""); -} diff --git a/packages/workflow-agent-kit/src/build-continuation-prompt.ts b/packages/workflow-util-agent/src/build-continuation-prompt.ts similarity index 100% rename from packages/workflow-agent-kit/src/build-continuation-prompt.ts rename to packages/workflow-util-agent/src/build-continuation-prompt.ts diff --git a/packages/workflow-agent-kit/src/build-output-format-instruction.ts b/packages/workflow-util-agent/src/build-output-format-instruction.ts similarity index 100% rename from packages/workflow-agent-kit/src/build-output-format-instruction.ts rename to packages/workflow-util-agent/src/build-output-format-instruction.ts diff --git a/packages/workflow-agent-kit/src/build-role-prompt.ts b/packages/workflow-util-agent/src/build-role-prompt.ts similarity index 100% rename from packages/workflow-agent-kit/src/build-role-prompt.ts rename to packages/workflow-util-agent/src/build-role-prompt.ts diff --git a/packages/workflow-agent-kit/src/context.ts b/packages/workflow-util-agent/src/context.ts similarity index 100% rename from packages/workflow-agent-kit/src/context.ts rename to packages/workflow-util-agent/src/context.ts diff --git a/packages/workflow-agent-kit/src/extract.ts b/packages/workflow-util-agent/src/extract.ts similarity index 100% rename from packages/workflow-agent-kit/src/extract.ts rename to packages/workflow-util-agent/src/extract.ts diff --git a/packages/workflow-agent-kit/src/frontmatter.ts b/packages/workflow-util-agent/src/frontmatter.ts similarity index 100% rename from packages/workflow-agent-kit/src/frontmatter.ts rename to packages/workflow-util-agent/src/frontmatter.ts diff --git a/packages/workflow-agent-kit/src/index.ts b/packages/workflow-util-agent/src/index.ts similarity index 100% rename from packages/workflow-agent-kit/src/index.ts rename to packages/workflow-util-agent/src/index.ts diff --git a/packages/workflow-agent-kit/src/run.ts b/packages/workflow-util-agent/src/run.ts similarity index 100% rename from packages/workflow-agent-kit/src/run.ts rename to packages/workflow-util-agent/src/run.ts diff --git a/packages/workflow-agent-kit/src/schemas.ts b/packages/workflow-util-agent/src/schemas.ts similarity index 100% rename from packages/workflow-agent-kit/src/schemas.ts rename to packages/workflow-util-agent/src/schemas.ts diff --git a/packages/workflow-agent-kit/src/session-cache.ts b/packages/workflow-util-agent/src/session-cache.ts similarity index 100% rename from packages/workflow-agent-kit/src/session-cache.ts rename to packages/workflow-util-agent/src/session-cache.ts diff --git a/packages/workflow-agent-kit/src/storage.ts b/packages/workflow-util-agent/src/storage.ts similarity index 100% rename from packages/workflow-agent-kit/src/storage.ts rename to packages/workflow-util-agent/src/storage.ts diff --git a/packages/workflow-agent-kit/src/types.ts b/packages/workflow-util-agent/src/types.ts similarity index 100% rename from packages/workflow-agent-kit/src/types.ts rename to packages/workflow-util-agent/src/types.ts diff --git a/packages/workflow-moderator/tsconfig.json b/packages/workflow-util-agent/tsconfig.json similarity index 100% rename from packages/workflow-moderator/tsconfig.json rename to packages/workflow-util-agent/tsconfig.json diff --git a/scripts/publish-all.mjs b/scripts/publish-all.mjs index fdb8de7..a8ed36e 100644 --- a/scripts/publish-all.mjs +++ b/scripts/publish-all.mjs @@ -18,8 +18,7 @@ const dryRun = args.includes("--dry-run"); const publishOrder = [ "workflow-protocol", "workflow-util", - "workflow-moderator", - "workflow-agent-kit", + "workflow-util-agent", "workflow-agent-hermes", "workflow-agent-builtin", "cli-workflow", diff --git a/tsconfig.json b/tsconfig.json index a5e606b..c2c0557 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -20,8 +20,7 @@ "references": [ { "path": "packages/workflow-util" }, { "path": "packages/workflow-protocol" }, - { "path": "packages/workflow-moderator" }, - { "path": "packages/workflow-agent-kit" }, + { "path": "packages/workflow-util-agent" }, { "path": "packages/workflow-agent-hermes" }, { "path": "packages/workflow-agent-builtin" }, { "path": "packages/cli-workflow" }