diff --git a/.gitignore b/.gitignore index ed3930e..88d27f1 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,4 @@ npm-debug.log* # Trajectories - don't commit active work .trajectories/active/ +.agent-relay/ diff --git a/.trajectories/completed/traj_1774688780754_79342892.json b/.trajectories/completed/traj_1774688780754_79342892.json new file mode 100644 index 0000000..ae386bd --- /dev/null +++ b/.trajectories/completed/traj_1774688780754_79342892.json @@ -0,0 +1,429 @@ +{ + "id": "traj_1774688780754_79342892", + "version": 1, + "task": { + "title": "llm-compaction-workflow", + "source": { + "system": "workflow-runner", + "id": "316d644a208b6cbe98d91249" + } + }, + "status": "completed", + "startedAt": "2026-03-28T09:06:20.754Z", + "agents": [ + { + "name": "orchestrator", + "role": "workflow-runner", + "joinedAt": "2026-03-28T09:06:20.754Z" + }, + { + "name": "architect", + "role": "specialist", + "joinedAt": "2026-03-28T09:06:24.455Z" + }, + { + "name": "llm-builder", + "role": "specialist", + "joinedAt": "2026-03-28T09:08:31.260Z" + }, + { + "name": "prompt-builder", + "role": "specialist", + "joinedAt": "2026-03-28T09:08:31.260Z" + }, + { + "name": "cli-builder", + "role": "specialist", + "joinedAt": "2026-03-28T09:12:17.236Z" + }, + { + "name": "reviewer", + "role": "specialist", + "joinedAt": "2026-03-28T09:23:49.608Z" + } + ], + "chapters": [ + { + "id": "ch_4d156a3a", + "title": "Planning", + "agentName": "orchestrator", + "startedAt": "2026-03-28T09:06:20.754Z", + "events": [ + { + "ts": 1774688780754, + "type": "note", + "content": "Purpose: Replace mechanical trajectory compaction with LLM-powered intelligent summarization" + }, + { + "ts": 1774688780754, + "type": "note", + "content": "Approach: 6-step dag workflow — Parsed 6 steps, 5 dependent steps, DAG validated, no cycles" + } + ], + "endedAt": "2026-03-28T09:06:24.457Z" + }, + { + "id": "ch_419d8c8b", + "title": "Execution: design-llm-compaction", + "agentName": "architect", + "startedAt": "2026-03-28T09:06:24.457Z", + "events": [ + { + "ts": 1774688784457, + "type": "note", + "content": "\"design-llm-compaction\": Design the LLM-powered trajectory compaction system", + "raw": { + "agent": "architect" + } + }, + { + "ts": 1774688911257, + "type": "completion-marker", + "content": "\"design-llm-compaction\" marker-based completion — Legacy STEP_COMPLETE marker observed (6 signal(s), 3 file change(s); signals=COMPLETE, COMPLETE, COMPLETE, COMPLETE, ▐▛███▜▌ Claude Code v2.1.71, DESIGN_COMPACTION_COMPLETE; files=modified:.gitignore, modified:package.json, modified:workflows/llm-compaction.ts)", + "significance": "medium", + "raw": { + "stepName": "design-llm-compaction", + "completionMode": "marker", + "reason": "Legacy STEP_COMPLETE marker observed", + "evidence": { + "summary": "6 signal(s), 3 file change(s)", + "signals": [ + "COMPLETE", + "COMPLETE", + "COMPLETE", + "COMPLETE", + "▐▛███▜▌ Claude Code v2.1.71", + "DESIGN_COMPACTION_COMPLETE" + ], + "files": [ + "modified:.gitignore", + "modified:package.json", + "modified:workflows/llm-compaction.ts" + ] + } + } + }, + { + "ts": 1774688911258, + "type": "finding", + "content": "\"design-llm-compaction\" completed → thinking", + "significance": "medium" + } + ], + "endedAt": "2026-03-28T09:08:31.260Z" + }, + { + "id": "ch_7645f0e3", + "title": "Execution: create-llm-engine, create-prompts-parser", + "agentName": "orchestrator", + "startedAt": "2026-03-28T09:08:31.260Z", + "events": [], + "endedAt": "2026-03-28T09:08:31.261Z" + }, + { + "id": "ch_dd383217", + "title": "Execution: create-llm-engine", + "agentName": "llm-builder", + "startedAt": "2026-03-28T09:08:31.261Z", + "events": [ + { + "ts": 1774688911261, + "type": "note", + "content": "\"create-llm-engine\": Build the LLM compaction engine", + "raw": { + "agent": "llm-builder" + } + } + ], + "endedAt": "2026-03-28T09:08:31.261Z" + }, + { + "id": "ch_f02ba462", + "title": "Execution: create-prompts-parser", + "agentName": "prompt-builder", + "startedAt": "2026-03-28T09:08:31.261Z", + "events": [ + { + "ts": 1774688911261, + "type": "note", + "content": "\"create-prompts-parser\": Build the compaction prompts and output parser", + "raw": { + "agent": "prompt-builder" + } + }, + { + "ts": 1774689131682, + "type": "completion-evidence", + "content": "\"create-llm-engine\" verification-based completion — Verification passed (6 signal(s), 6 file change(s), exit=0; signals=COMPLETE, COMPLETE, COMPLETE, COMPLETE, OpenAI Codex v0.116.0 (research preview), LLM_ENGINE_COMPLETE; files=created:src/compact/index.ts, created:src/compact/markdown.ts, created:src/compact/parser.ts, created:src/compact/prompts.ts, created:src/compact/provider.ts, created:src/compact/serializer.ts; exit=0)", + "significance": "medium", + "raw": { + "stepName": "create-llm-engine", + "completionMode": "verification", + "reason": "Verification passed", + "evidence": { + "summary": "6 signal(s), 6 file change(s), exit=0", + "signals": [ + "COMPLETE", + "COMPLETE", + "COMPLETE", + "COMPLETE", + "OpenAI Codex v0.116.0 (research preview)", + "LLM_ENGINE_COMPLETE" + ], + "files": [ + "created:src/compact/index.ts", + "created:src/compact/markdown.ts", + "created:src/compact/parser.ts", + "created:src/compact/prompts.ts", + "created:src/compact/provider.ts", + "created:src/compact/serializer.ts" + ], + "exitCode": 0 + } + } + }, + { + "ts": 1774689131682, + "type": "finding", + "content": "\"create-llm-engine\" completed → LLM_ENGINE_COMPLETE", + "significance": "medium" + }, + { + "ts": 1774689137231, + "type": "completion-evidence", + "content": "\"create-prompts-parser\" verification-based completion — Verification passed (6 signal(s), 1 relevant channel post(s), 6 file change(s), exit=0; signals=COMPLETE, COMPLETE, COMPLETE, OpenAI Codex v0.116.0 (research preview), PROMPTS_PARSER_COMPLETE, **[create-prompts-parser] Output:**; channel=**[create-prompts-parser] Output:**\n```\nCreated [prompts.ts](/Users/khaliqgant/Projects/Agent%20Workforce/trajectories/src/compact/prompts.ts), [parser.ts](/Use; files=created:src/compact/index.ts, created:src/compact/markdown.ts, created:src/compact/parser.ts, created:src/compact/prompts.ts, created:src/compact/provider.ts, created:src/compact/serializer.ts; exit=0)", + "significance": "medium", + "raw": { + "stepName": "create-prompts-parser", + "completionMode": "verification", + "reason": "Verification passed", + "evidence": { + "summary": "6 signal(s), 1 relevant channel post(s), 6 file change(s), exit=0", + "signals": [ + "COMPLETE", + "COMPLETE", + "COMPLETE", + "OpenAI Codex v0.116.0 (research preview)", + "PROMPTS_PARSER_COMPLETE", + "**[create-prompts-parser] Output:**" + ], + "channelPosts": [ + "**[create-prompts-parser] Output:**\n```\nCreated [prompts.ts](/Users/khaliqgant/Projects/Agent%20Workforce/trajectories/src/compact/prompts.ts), [parser.ts](/Use" + ], + "files": [ + "created:src/compact/index.ts", + "created:src/compact/markdown.ts", + "created:src/compact/parser.ts", + "created:src/compact/prompts.ts", + "created:src/compact/provider.ts", + "created:src/compact/serializer.ts" + ], + "exitCode": 0 + } + } + }, + { + "ts": 1774689137231, + "type": "finding", + "content": "\"create-prompts-parser\" completed → PROMPTS_PARSER_COMPLETE", + "significance": "medium" + } + ], + "endedAt": "2026-03-28T09:12:17.234Z" + }, + { + "id": "ch_b2f5776c", + "title": "Convergence: create-llm-engine + create-prompts-parser", + "agentName": "orchestrator", + "startedAt": "2026-03-28T09:12:17.234Z", + "events": [ + { + "ts": 1774689137236, + "type": "reflection", + "content": "create-llm-engine + create-prompts-parser resolved. 2/2 steps completed. All steps completed on first attempt. Unblocking: update-cli.", + "significance": "high", + "raw": { + "confidence": 1, + "focalPoints": [ + "create-llm-engine: completed", + "create-prompts-parser: completed" + ] + } + } + ], + "endedAt": "2026-03-28T09:12:17.237Z" + }, + { + "id": "ch_23ae0978", + "title": "Execution: update-cli", + "agentName": "cli-builder", + "startedAt": "2026-03-28T09:12:17.237Z", + "events": [ + { + "ts": 1774689137237, + "type": "note", + "content": "\"update-cli\": Update the CLI compact command to use LLM compaction", + "raw": { + "agent": "cli-builder" + } + }, + { + "ts": 1774689829605, + "type": "completion-evidence", + "content": "\"update-cli\" verification-based completion — Verification passed (5 signal(s), 1 relevant channel post(s), 5 file change(s), exit=0; signals=0, Updated [`src/cli/commands/compact.ts`](/Users/khaliqgant/Projects/Agent%20Workforce/trajectories/src/cli/commands/compact.ts) to support LLM compaction with mechanical fallback. The command now:, OpenAI Codex v0.116.0 (research preview), CLI_UPDATE_COMPLETE, **[update-cli] Output:**; channel=**[update-cli] Output:**\n```\n-selects LLM compaction when a provider is available unless `--mechanical` is set\n- keeps `loadTrajectories()` intact\n- uses the LL; files=modified:src/cli/commands/compact.ts, created:src/compact/config.ts, modified:src/compact/index.ts, modified:src/compact/provider.ts, created:tests/compact/llm-compact.test.ts; exit=0)", + "significance": "medium", + "raw": { + "stepName": "update-cli", + "completionMode": "verification", + "reason": "Verification passed", + "evidence": { + "summary": "5 signal(s), 1 relevant channel post(s), 5 file change(s), exit=0", + "signals": [ + "0", + "Updated [`src/cli/commands/compact.ts`](/Users/khaliqgant/Projects/Agent%20Workforce/trajectories/src/cli/commands/compact.ts) to support LLM compaction with mechanical fallback. The command now:", + "OpenAI Codex v0.116.0 (research preview)", + "CLI_UPDATE_COMPLETE", + "**[update-cli] Output:**" + ], + "channelPosts": [ + "**[update-cli] Output:**\n```\n-selects LLM compaction when a provider is available unless `--mechanical` is set\n- keeps `loadTrajectories()` intact\n- uses the LL" + ], + "files": [ + "modified:src/cli/commands/compact.ts", + "created:src/compact/config.ts", + "modified:src/compact/index.ts", + "modified:src/compact/provider.ts", + "created:tests/compact/llm-compact.test.ts" + ], + "exitCode": 0 + } + } + }, + { + "ts": 1774689829605, + "type": "finding", + "content": "\"update-cli\" completed → CLI_UPDATE_COMPLETE", + "significance": "medium" + } + ], + "endedAt": "2026-03-28T09:23:49.608Z" + }, + { + "id": "ch_dace44da", + "title": "Execution: review-compaction", + "agentName": "reviewer", + "startedAt": "2026-03-28T09:23:49.609Z", + "events": [ + { + "ts": 1774689829609, + "type": "note", + "content": "\"review-compaction\": Review the LLM compaction system", + "raw": { + "agent": "reviewer" + } + }, + { + "ts": 1774689979495, + "type": "completion-marker", + "content": "\"review-compaction\" marker-based completion — Legacy STEP_COMPLETE marker observed (6 signal(s), 3 relevant channel post(s); signals=**[update-cli] Review Complete**, COMPLETE, review-compaction, ▐▛███▜▌ Claude Code v2.1.71, COMPACTION_REVIEW_COMPLETE, review-compaction; channel=**[update-cli] Review Complete**\n\nVerified the LLM compaction implementation:\n\n- **Typecheck**: ✅ passes\n- **Tests**: ✅ 4/4 passing (serializer, parser, markdow | **[review-compaction] Review Complete**\n\nAll 10 verification points checked:\n\n1. **No new npm deps** - ✅ package.json unchanged; providers use raw `fetch`\n2. ** | **[review-compaction] Output:**\n```\n\n defaults\\n9. **Mechanical with --mechanical** -\n ✅ `should)", + "significance": "medium", + "raw": { + "stepName": "review-compaction", + "completionMode": "marker", + "reason": "Legacy STEP_COMPLETE marker observed", + "evidence": { + "summary": "6 signal(s), 3 relevant channel post(s)", + "signals": [ + "**[update-cli] Review Complete**", + "COMPLETE", + "review-compaction", + "▐▛███▜▌ Claude Code v2.1.71", + "COMPACTION_REVIEW_COMPLETE", + "review-compaction" + ], + "channelPosts": [ + "**[update-cli] Review Complete**\n\nVerified the LLM compaction implementation:\n\n- **Typecheck**: ✅ passes\n- **Tests**: ✅ 4/4 passing (serializer, parser, markdow", + "**[review-compaction] Review Complete**\n\nAll 10 verification points checked:\n\n1. **No new npm deps** - ✅ package.json unchanged; providers use raw `fetch`\n2. **", + "**[review-compaction] Output:**\n```\n\n defaults\\n9. **Mechanical with --mechanical** -\n ✅ `should" + ] + } + } + }, + { + "ts": 1774689979496, + "type": "finding", + "content": "\"review-compaction\" completed → ✳", + "significance": "medium" + } + ], + "endedAt": "2026-03-28T09:26:19.497Z" + }, + { + "id": "ch_56e8a010", + "title": "Execution: commit", + "agentName": "llm-builder", + "startedAt": "2026-03-28T09:26:19.497Z", + "events": [ + { + "ts": 1774689979497, + "type": "note", + "content": "\"commit\": In /Users/khaliqgant/Projects/Agent Workforce/trajectories:", + "raw": { + "agent": "llm-builder" + } + }, + { + "ts": 1774690181929, + "type": "completion-evidence", + "content": "\"commit\" verification-based completion — Verification passed (4 signal(s), exit=0; signals=0, OpenAI Codex v0.116.0 (research preview), OpenAI Codex v0.116.0 (research preview), COMMIT_COMPLETE; exit=0)", + "significance": "medium", + "raw": { + "stepName": "commit", + "completionMode": "verification", + "reason": "Verification passed", + "evidence": { + "summary": "4 signal(s), exit=0", + "signals": [ + "0", + "OpenAI Codex v0.116.0 (research preview)", + "OpenAI Codex v0.116.0 (research preview)", + "COMMIT_COMPLETE" + ], + "exitCode": 0 + } + } + }, + { + "ts": 1774690181929, + "type": "finding", + "content": "\"commit\" completed → COMMIT_COMPLETE", + "significance": "medium" + } + ], + "endedAt": "2026-03-28T09:29:41.940Z" + }, + { + "id": "ch_ad7eed65", + "title": "Retrospective", + "agentName": "orchestrator", + "startedAt": "2026-03-28T09:29:41.940Z", + "events": [ + { + "ts": 1774690181940, + "type": "reflection", + "content": "All 6 steps completed in 23min. (completed in 23 minutes)", + "significance": "high" + } + ], + "endedAt": "2026-03-28T09:29:41.940Z" + } + ], + "completedAt": "2026-03-28T09:29:41.940Z", + "retrospective": { + "summary": "All 6 steps completed in 23min.", + "approach": "dag workflow (5 agents)", + "confidence": 1, + "learnings": [], + "challenges": [] + } +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 5b18b43..af351a7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,10 @@ "version": "0.5.2", "license": "MIT", "dependencies": { + "@agent-relay/sdk": "^3.2.22", "@clack/prompts": "^0.7.0", + "@relayauth/sdk": "^0.1.4", + "@relayfile/sdk": "^0.1.6", "commander": "^12.0.0", "zod": "^3.23.0" }, @@ -29,6 +32,94 @@ "node": ">=20.0.0" } }, + "node_modules/@agent-relay/config": { + "version": "3.2.22", + "resolved": "https://registry.npmjs.org/@agent-relay/config/-/config-3.2.22.tgz", + "integrity": "sha512-+/wHXQEcog7yjKMVdka1qzuYacv6J+K1z0Z6QJAXNVWC2xnNy58osnAE1AQfIweZQjd4PSaSpYMuHNjYrR2uDA==", + "dependencies": { + "zod": "^3.23.8", + "zod-to-json-schema": "^3.23.1" + } + }, + "node_modules/@agent-relay/sdk": { + "version": "3.2.22", + "resolved": "https://registry.npmjs.org/@agent-relay/sdk/-/sdk-3.2.22.tgz", + "integrity": "sha512-ArDrpEodG+k2AoCaDC3PTOIqjhc3BW/Uvu1A87XsPYbU0jdLKgDaPbHBwfzj8cIculiDtvKp0mfPkrEkJU73kQ==", + "dependencies": { + "@agent-relay/config": "3.2.22", + "@relaycast/sdk": "^1.1.0", + "@sinclair/typebox": "^0.34.48", + "chalk": "^4.1.2", + "listr2": "^10.2.1", + "ws": "^8.18.3", + "yaml": "^2.7.0" + }, + "peerDependencies": { + "@anthropic-ai/claude-agent-sdk": ">=0.1.0", + "@google/adk": ">=0.5.0", + "@langchain/langgraph": ">=1.2.0", + "@mariozechner/pi-coding-agent": ">=0.50.0", + "@openai/agents": ">=0.7.0", + "ai": ">=5.0.0", + "crewai": ">=1.0.0" + }, + "peerDependenciesMeta": { + "@anthropic-ai/claude-agent-sdk": { + "optional": true + }, + "@google/adk": { + "optional": true + }, + "@langchain/langgraph": { + "optional": true + }, + "@mariozechner/pi-coding-agent": { + "optional": true + }, + "@openai/agents": { + "optional": true + }, + "ai": { + "optional": true + }, + "crewai": { + "optional": true + } + } + }, + "node_modules/@agent-relay/sdk/node_modules/listr2": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-10.2.1.tgz", + "integrity": "sha512-7I5knELsJKTUjXG+A6BkKAiGkW1i25fNa/xlUl9hFtk15WbE9jndA89xu5FzQKrY5llajE1hfZZFMILXkDHk/Q==", + "license": "MIT", + "dependencies": { + "cli-truncate": "^5.2.0", + "eventemitter3": "^5.0.4", + "log-update": "^6.1.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^10.0.0" + }, + "engines": { + "node": ">=22.13.0" + } + }, + "node_modules/@agent-relay/sdk/node_modules/wrap-ansi": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-10.0.0.tgz", + "integrity": "sha512-SGcvg80f0wUy2/fXES19feHMz8E0JoXv2uNgHOu4Dgi2OrCy1lqwFYEJz1BLbDI0exjPMe/ZdzZ/YpGECBG/aQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.3", + "string-width": "^8.2.0", + "strip-ansi": "^7.1.2" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/@biomejs/biome": { "version": "1.9.4", "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-1.9.4.tgz", @@ -220,6 +311,7 @@ }, "node_modules/@clack/prompts/node_modules/is-unicode-supported": { "version": "1.3.0", + "extraneous": true, "inBundle": true, "license": "MIT", "engines": { @@ -710,6 +802,64 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@relayauth/sdk": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@relayauth/sdk/-/sdk-0.1.4.tgz", + "integrity": "sha512-DLC/TF/R4QFNhGh3TELG0MujJhQR4p+WQJcm+wGKUlkLUxdbtoT8AtAGlc7bWXaYfSnba7yq3W6gST9YVtdAXA==", + "dependencies": { + "@relayauth/types": "0.1.0", + "hono": "^4" + } + }, + "node_modules/@relayauth/types": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@relayauth/types/-/types-0.1.0.tgz", + "integrity": "sha512-ruPDNqUf2bolh5ZCNwYsyxJKvSgCRUJOQFBifF+IbdLZ3XY17M21tjK+Ttie/auDyOEejPv07Yno8PtpHRK99w==" + }, + "node_modules/@relaycast/sdk": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@relaycast/sdk/-/sdk-1.1.0.tgz", + "integrity": "sha512-9mCpcinrwNxA5BJjWtv3mrI8onior88bHtUZaSCaEaSlXwhhY1Q4Rw2JggOFuDYpBM7MumVHzuc6ZajVSwTYHw==", + "dependencies": { + "@relaycast/types": "1.1.0", + "zod": "^4.3.6" + } + }, + "node_modules/@relaycast/sdk/node_modules/zod": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", + "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/@relaycast/types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@relaycast/types/-/types-1.1.0.tgz", + "integrity": "sha512-d0zByxvWK2PeZRnrhzbmDkE8Yar84/XH1H+89qGJj3lA82kTf/7Z76a2cqOIoxFXLgIjK959w9hTctXLem+lhA==", + "dependencies": { + "zod": "^4.3.6" + } + }, + "node_modules/@relaycast/types/node_modules/zod": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", + "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/@relayfile/sdk": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@relayfile/sdk/-/sdk-0.1.6.tgz", + "integrity": "sha512-XxYcTqBAgL9vZuejfmPXqnpRC7MvMYb0HZFjrG/r87TDA1HU7lstA1i4VEq6RhdHUS7Rt0nloM4TL/l/uaA4lg==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.57.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.57.1.tgz", @@ -1060,6 +1210,12 @@ "win32" ] }, + "node_modules/@sinclair/typebox": { + "version": "0.34.49", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", + "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", + "license": "MIT" + }, "node_modules/@types/estree": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", @@ -1221,7 +1377,6 @@ "version": "7.3.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz", "integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==", - "dev": true, "license": "MIT", "dependencies": { "environment": "^1.0.0" @@ -1237,7 +1392,6 @@ "version": "6.2.2", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -1250,7 +1404,6 @@ "version": "6.2.3", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", - "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -1332,6 +1485,37 @@ "node": ">=18" } }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/check-error": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", @@ -1362,7 +1546,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", - "dev": true, "license": "MIT", "dependencies": { "restore-cursor": "^5.0.0" @@ -1375,14 +1558,13 @@ } }, "node_modules/cli-truncate": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-5.1.1.tgz", - "integrity": "sha512-SroPvNHxUnk+vIW/dOSfNqdy1sPEFkrTk6TUtqLCnBlo3N7TNYYkzzN7uSD6+jVjrdO4+p8nH7JzH6cIvUem6A==", - "dev": true, + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-5.2.0.tgz", + "integrity": "sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw==", "license": "MIT", "dependencies": { - "slice-ansi": "^7.1.0", - "string-width": "^8.0.0" + "slice-ansi": "^8.0.0", + "string-width": "^8.2.0" }, "engines": { "node": ">=20" @@ -1391,6 +1573,40 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/cli-truncate/node_modules/slice-ansi": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-8.0.0.tgz", + "integrity": "sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.3", + "is-fullwidth-code-point": "^5.1.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, "node_modules/colorette": { "version": "2.0.20", "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", @@ -1456,14 +1672,12 @@ "version": "10.6.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", - "dev": true, "license": "MIT" }, "node_modules/environment": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", - "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -1535,7 +1749,6 @@ "version": "5.0.4", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", - "dev": true, "license": "MIT" }, "node_modules/expect-type": { @@ -1592,7 +1805,6 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.5.0.tgz", "integrity": "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==", - "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -1601,6 +1813,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/hono": { + "version": "4.12.9", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.9.tgz", + "integrity": "sha512-wy3T8Zm2bsEvxKZM5w21VdHDDcwVS1yUFFY6i8UobSsKfFceT7TOwhbhfKsDyx7tYQlmRM5FLpIuYvNFyjctiA==", + "license": "MIT", + "engines": { + "node": ">=16.9.0" + } + }, "node_modules/husky": { "version": "9.1.7", "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", @@ -1621,7 +1851,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", - "dev": true, "license": "MIT", "dependencies": { "get-east-asian-width": "^1.3.1" @@ -1740,7 +1969,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", - "dev": true, "license": "MIT", "dependencies": { "ansi-escapes": "^7.0.0", @@ -1791,7 +2019,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", - "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -1878,7 +2105,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", - "dev": true, "license": "MIT", "dependencies": { "mimic-function": "^5.0.0" @@ -2061,7 +2287,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", - "dev": true, "license": "MIT", "dependencies": { "onetime": "^7.0.0", @@ -2078,7 +2303,6 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", - "dev": true, "license": "MIT" }, "node_modules/rollup": { @@ -2137,7 +2361,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, "license": "ISC", "engines": { "node": ">=14" @@ -2156,7 +2379,6 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^6.2.1", @@ -2217,7 +2439,6 @@ "version": "8.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.0.tgz", "integrity": "sha512-6hJPQ8N0V0P3SNmP6h2J99RLuzrWz2gvT7VnK5tKvrNqJoyS9W4/Fb8mo31UiPvy00z7DQXkP2hnKBVav76thw==", - "dev": true, "license": "MIT", "dependencies": { "get-east-asian-width": "^1.5.0", @@ -2234,7 +2455,6 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", - "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" @@ -2279,6 +2499,18 @@ "node": ">= 6" } }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/thenify": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", @@ -3119,7 +3351,6 @@ "version": "9.0.2", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^6.2.1", @@ -3137,7 +3368,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", - "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^10.3.0", @@ -3151,11 +3381,31 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/ws": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz", + "integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/yaml": { "version": "2.8.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz", "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", - "dev": true, "license": "ISC", "bin": { "yaml": "bin.mjs" @@ -3175,6 +3425,15 @@ "funding": { "url": "https://github.com/sponsors/colinhacks" } + }, + "node_modules/zod-to-json-schema": { + "version": "3.25.2", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.2.tgz", + "integrity": "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==", + "license": "ISC", + "peerDependencies": { + "zod": "^3.25.28 || ^4" + } } } } diff --git a/package.json b/package.json index 79f130f..87c1183 100644 --- a/package.json +++ b/package.json @@ -46,12 +46,17 @@ "type": "git", "url": "https://github.com/AgentWorkforce/trajectories" }, - "files": ["dist"], + "files": [ + "dist" + ], "engines": { "node": ">=20.0.0" }, "dependencies": { + "@agent-relay/sdk": "^3.2.22", "@clack/prompts": "^0.7.0", + "@relayauth/sdk": "^0.1.4", + "@relayfile/sdk": "^0.1.6", "commander": "^12.0.0", "zod": "^3.23.0" }, diff --git a/workflows/llm-compaction.ts b/workflows/llm-compaction.ts new file mode 100644 index 0000000..99e0b41 --- /dev/null +++ b/workflows/llm-compaction.ts @@ -0,0 +1,376 @@ +/** + * llm-compaction.ts + * + * Workflow: Replace the mechanical compaction in compact.ts with + * LLM-powered intelligent summarization. + * + * Current state: compactTrajectories() does keyword-based decision grouping + * and string deduplication. No understanding of what actually happened. + * + * Target state: An LLM reads raw trajectory data (chapters, events, decisions, + * findings, retrospectives) and produces: + * 1. A narrative summary of what was accomplished + * 2. Key decisions with real reasoning (not keyword-matched categories) + * 3. Extracted conventions/patterns that should inform future work + * 4. Lessons learned from failures/challenges + * 5. A compact .md file that's actually useful to read + * + * The LLM compaction should work with any provider (OpenAI, Anthropic, local) + * via a simple chat completion interface. + * + * Run: agent-relay run workflows/llm-compaction.ts + */ + +import { workflow } from "@agent-relay/sdk/workflows"; + +const TRAJ_ROOT = "/Users/khaliqgant/Projects/Agent Workforce/trajectories"; + +async function main() { + const result = await workflow("llm-compaction") + .description( + "Replace mechanical trajectory compaction with LLM-powered intelligent summarization", + ) + .pattern("dag") + .channel("wf-llm-compaction") + .maxConcurrency(4) + .timeout(3_600_000) + + .agent("architect", { + cli: "claude", + role: "Designs the LLM compaction system", + }) + .agent("llm-builder", { + cli: "codex", + preset: "worker", + role: "Builds the LLM compaction engine", + }) + .agent("prompt-builder", { + cli: "codex", + preset: "worker", + role: "Builds prompts and output parsing", + }) + .agent("cli-builder", { + cli: "codex", + preset: "worker", + role: "Updates the CLI compact command", + }) + .agent("reviewer", { cli: "claude", role: "Reviews the implementation" }) + + .step("design-llm-compaction", { + agent: "architect", + task: `Design the LLM-powered trajectory compaction system. + +Read these files: +- ${TRAJ_ROOT}/src/cli/commands/compact.ts (current mechanical compaction — ~400 lines) +- ${TRAJ_ROOT}/src/core/types.ts (Trajectory, Chapter, TrajectoryEvent, Decision, Finding, Retrospective types) +- ${TRAJ_ROOT}/src/core/trajectory.ts (trajectory lifecycle) + +Current problems with compactTrajectories(): +1. Groups decisions by keyword matching ("architecture", "api", "database") — misses nuance +2. Just dedupes learnings as strings — doesn't synthesize +3. Produces a JSON blob — not a readable document +4. No understanding of what was attempted vs what worked +5. No extraction of reusable patterns/conventions + +Design the replacement: + +1. **LLM Provider Interface** (${TRAJ_ROOT}/src/compact/provider.ts): + - CompactionLLM interface: { complete(messages, options): string } + - OpenAIProvider, AnthropicProvider, LocalProvider implementations + - Config from env: TRAJECTORIES_LLM_PROVIDER, TRAJECTORIES_LLM_MODEL, API key + - Fallback: if no LLM configured, use current mechanical compaction + +2. **Trajectory Serializer** (${TRAJ_ROOT}/src/compact/serializer.ts): + - serializeForLLM(trajectories): string — converts raw trajectories to a + structured text format the LLM can read efficiently + - Strips noise (raw tool call data, low-significance events) + - Keeps: decisions, findings, errors, high-significance events, retrospectives + - Budgets tokens: truncate chapters beyond a max (configurable) + - Includes file-level context: "Files changed: src/auth.ts, src/db/schema.ts" + +3. **Compaction Prompts** (${TRAJ_ROOT}/src/compact/prompts.ts): + - COMPACTION_SYSTEM_PROMPT: role definition for the summarizer + - COMPACTION_USER_PROMPT: template with serialized trajectories + - Output format: structured JSON with narrative sections + - Prompt engineering for consistency: "You are reviewing N agent work sessions..." + +4. **Output Parser** (${TRAJ_ROOT}/src/compact/parser.ts): + - Parse LLM JSON response into CompactedTrajectory + - Validate required fields + - Fallback: if LLM returns invalid JSON, extract what we can + +5. **Compacted Output Format** — enhanced from current: + - narrative: string — 2-3 paragraph summary of what happened + - decisions: Array<{ question, chosen, reasoning, impact }> — LLM-analyzed + - conventions: Array<{ pattern, rationale, scope }> — extracted conventions + - lessons: Array<{ lesson, context, recommendation }> — synthesized learnings + - openQuestions: string[] — things left unresolved + - filesAffected: string[] — keep as-is + - commits: string[] — keep as-is + +6. **Markdown Output** (${TRAJ_ROOT}/src/compact/markdown.ts): + - Generate a readable .md file alongside the JSON + - Sections: Summary, Key Decisions, Conventions Established, Lessons Learned, Open Questions + - This is what humans actually read + +Output: interfaces, file structure, prompt outline, token budget strategy. +Keep output under 100 lines. End with DESIGN_COMPACTION_COMPLETE.`, + verification: { + type: "output_contains", + value: "DESIGN_COMPACTION_COMPLETE", + }, + timeout: 300_000, + }) + + .step("create-llm-engine", { + agent: "llm-builder", + dependsOn: ["design-llm-compaction"], + task: `Build the LLM compaction engine. + +Design: {{steps.design-llm-compaction.output}} + +Create in ${TRAJ_ROOT}/src/compact/: + +1. provider.ts — LLM provider interface + implementations: + - CompactionLLM interface: complete(messages: Message[], options?: CompletionOptions): Promise + - Message: { role: 'system' | 'user' | 'assistant', content: string } + - CompletionOptions: { maxTokens?: number, temperature?: number, jsonMode?: boolean } + - OpenAIProvider: uses fetch to POST /v1/chat/completions (no SDK dep) + Env: OPENAI_API_KEY, TRAJECTORIES_LLM_MODEL (default: gpt-4o) + - AnthropicProvider: uses fetch to POST /v1/messages + Env: ANTHROPIC_API_KEY, TRAJECTORIES_LLM_MODEL (default: claude-sonnet-4-20250514) + - resolveProvider(): auto-detect from env vars, fallback to null + - No new npm dependencies — raw fetch only + +2. serializer.ts — Trajectory → LLM-readable text: + - serializeForLLM(trajectories: Trajectory[], maxTokens?: number): string + - For each trajectory: + - Header: "## Session: {title} ({status}, {duration})" + - Agents: who participated and their roles + - Chapters: title + high/medium/critical events only (skip low) + - Decisions: full question + chosen + reasoning + - Findings: what + where + significance + - Retrospective: summary + approach + challenges + learnings + - Files changed + commits + - Token budgeting: estimate ~4 chars per token + If total > maxTokens (default 30000), truncate chapters proportionally + - Skip: raw tool call data, tool results, low-significance events + +3. index.ts — Re-export everything + +End with LLM_ENGINE_COMPLETE.`, + verification: { type: "output_contains", value: "LLM_ENGINE_COMPLETE" }, + timeout: 900_000, + }) + + .step("create-prompts-parser", { + agent: "prompt-builder", + dependsOn: ["design-llm-compaction"], + task: `Build the compaction prompts and output parser. + +Design: {{steps.design-llm-compaction.output}} + +Create in ${TRAJ_ROOT}/src/compact/: + +1. prompts.ts — Compaction prompt templates: + + COMPACTION_SYSTEM_PROMPT: + "You are a technical analyst reviewing agent work sessions (trajectories). + Your job is to produce a concise, insightful summary that captures: + - What was accomplished and how + - Key decisions and their reasoning + - Patterns/conventions established that should be followed in future work + - Lessons learned from challenges and failures + - Open questions or unresolved issues + + Be specific. Reference actual file paths, function names, and technical details. + Don't be generic — this summary replaces the raw data." + + buildCompactionPrompt(serializedTrajectories: string, options?: PromptOptions): Message[] + - Constructs system + user messages + - User message includes the serialized trajectories + - Requests structured JSON output matching CompactedOutput schema + - Includes output schema in the prompt for format guidance + + PromptOptions: { focusAreas?: string[], maxOutputTokens?: number } + +2. parser.ts — Parse LLM response: + - parseCompactionResponse(llmOutput: string): LLMCompactedOutput + - LLMCompactedOutput: { + narrative: string, + decisions: Array<{ question, chosen, reasoning, impact }>, + conventions: Array<{ pattern, rationale, scope }>, + lessons: Array<{ lesson, context, recommendation }>, + openQuestions: string[], + } + - Try JSON.parse first + - If fails: try extracting JSON from markdown code blocks + - If fails: try extracting sections from prose (regex for ## headers) + - Validate: narrative required, decisions/conventions/lessons arrays + - Merge with mechanical data (files, commits, agents) for full CompactedTrajectory + +3. markdown.ts — Generate readable .md: + - generateCompactionMarkdown(compacted: CompactedTrajectory & LLMCompactedOutput): string + - Format: + # Trajectory Compaction: {dateRange} + + ## Summary + {narrative} + + ## Key Decisions ({count}) + | Question | Decision | Impact | + |----------|----------|--------| + + ## Conventions Established + - **{pattern}**: {rationale} (scope: {scope}) + + ## Lessons Learned + - {lesson} — {recommendation} + + ## Open Questions + - {question} + + ## Stats + - Sessions: {count}, Agents: {names}, Files: {count}, Commits: {count} + - Date range: {start} - {end} + +End with PROMPTS_PARSER_COMPLETE.`, + verification: { + type: "output_contains", + value: "PROMPTS_PARSER_COMPLETE", + }, + timeout: 900_000, + }) + + .step("update-cli", { + agent: "cli-builder", + dependsOn: ["create-llm-engine", "create-prompts-parser"], + task: `Update the CLI compact command to use LLM compaction. + +Modify ${TRAJ_ROOT}/src/cli/commands/compact.ts: + +1. Add --llm flag (default: true if LLM provider detected, false otherwise) +2. Add --mechanical flag to force old behavior +3. Add --focus flag: comma-separated focus areas for the LLM +4. Add --markdown flag (default: true): also output .md file + +Updated flow: +a) Load trajectories (existing loadTrajectories — keep as-is) +b) If --mechanical or no LLM provider: use existing compactTrajectories() +c) If LLM available: + 1. serializeForLLM(trajectories) → text + 2. buildCompactionPrompt(text, options) → messages + 3. provider.complete(messages) → llmOutput + 4. parseCompactionResponse(llmOutput) → llmCompacted + 5. Merge with mechanical data (files, commits, agents) + 6. Save JSON to .trajectories/compacted/ + 7. Save .md alongside if --markdown + 8. Print summary + +d) Keep dry-run working with LLM (show prompt + estimated tokens) +e) Show cost estimate: "Estimated: ~{tokens} input tokens, ~{output} output tokens" + +Also create: +- ${TRAJ_ROOT}/src/compact/config.ts — Configuration: + - getCompactionConfig(): reads from env or .trajectories/config.json + - Config: { provider, model, maxInputTokens, maxOutputTokens, temperature } + - Defaults: provider=auto, maxInput=30000, maxOutput=4000, temperature=0.3 + +Add tests: +- ${TRAJ_ROOT}/tests/compact/llm-compact.test.ts + - Test serializer with sample trajectories + - Test parser with sample LLM output + - Test markdown generation + - Test fallback to mechanical when no LLM + +End with CLI_UPDATE_COMPLETE.`, + verification: { type: "output_contains", value: "CLI_UPDATE_COMPLETE" }, + timeout: 900_000, + }) + + .step("review-compaction", { + agent: "reviewer", + dependsOn: ["update-cli"], + task: `Review the LLM compaction system. + +Files: +- ${TRAJ_ROOT}/src/compact/provider.ts +- ${TRAJ_ROOT}/src/compact/serializer.ts +- ${TRAJ_ROOT}/src/compact/prompts.ts +- ${TRAJ_ROOT}/src/compact/parser.ts +- ${TRAJ_ROOT}/src/compact/markdown.ts +- ${TRAJ_ROOT}/src/compact/config.ts +- ${TRAJ_ROOT}/src/compact/index.ts +- ${TRAJ_ROOT}/src/cli/commands/compact.ts (modified) +- ${TRAJ_ROOT}/tests/compact/llm-compact.test.ts + +Verify: +1. No new npm dependencies (raw fetch only for LLM calls) +2. Graceful fallback: no API key → mechanical compaction +3. Token budgeting prevents exceeding model context window +4. Parser handles malformed LLM output without crashing +5. Prompt is specific enough to get useful output, not generic summaries +6. Markdown output is clean and readable +7. Dry-run shows prompt + cost estimate without calling LLM +8. Config can be set via env vars OR .trajectories/config.json +9. Existing mechanical compaction still works with --mechanical flag +10. Tests cover serializer, parser, markdown, and fallback + +Fix issues. Keep output under 50 lines. End with COMPACTION_REVIEW_COMPLETE.`, + verification: { + type: "output_contains", + value: "COMPACTION_REVIEW_COMPLETE", + }, + timeout: 300_000, + }) + + .step("commit", { + agent: "llm-builder", + dependsOn: ["review-compaction"], + task: `In ${TRAJ_ROOT}: +1. git checkout -b feat/llm-compaction +2. git add src/compact/ src/cli/commands/compact.ts tests/compact/ +3. git commit -m "feat: LLM-powered trajectory compaction + +Replaces mechanical keyword-based compaction with intelligent LLM summarization. + +New compact/ module: + - provider.ts: OpenAI + Anthropic providers (raw fetch, no deps) + - serializer.ts: trajectory → LLM-readable text with token budgeting + - prompts.ts: system + user prompts for compaction + - parser.ts: parse LLM JSON output with fallbacks + - markdown.ts: generate readable .md summaries + - config.ts: env vars or .trajectories/config.json + +CLI updates: + - trail compact now uses LLM by default (if API key present) + - --mechanical flag for old behavior + - --focus for targeted summaries + - --markdown flag (default: true) for .md output + - Dry-run shows prompt + cost estimate + +Output includes: + - Narrative summary (what happened, how) + - Key decisions with reasoning and impact + - Extracted conventions/patterns for future work + - Synthesized lessons from challenges + - Open questions / unresolved issues + +Backwards compatible: falls back to mechanical if no LLM provider." +4. git push origin feat/llm-compaction + +Report commit hash. End with COMMIT_COMPLETE.`, + verification: { type: "output_contains", value: "COMMIT_COMPLETE" }, + timeout: 120_000, + }) + + .onError("retry", { maxRetries: 1, retryDelayMs: 10_000 }) + .run({ cwd: process.cwd() }); + + console.log("LLM compaction complete:", result.status); +} + +main().catch((error) => { + console.error(error); + process.exitCode = 1; +});