Commit Graph

633 Commits

Author SHA1 Message Date
scottwei c9fcb15384 Merge branch 'main' into jshang/workflow-dashboard 2026-05-22 10:52:53 +00:00
xiaoju 76fab22827 fix: explicitly forbid extra frontmatter fields in output format instruction
buildOutputFormatInstruction now includes explicit language telling agents to
output ONLY schema-defined fields and to focus on their role's deliverable.

Fixes #394
2026-05-22 10:49:04 +00:00
xingyue 176844d7f5 fix: add sessionId to raw fallback, fix test meta→frontmatter+description 2026-05-22 18:42:27 +08:00
xingyue 31695e89a8 feat: add workflow-agent-claude-code package
Claude Code CLI adapter for the workflow engine, mirroring
workflow-agent-hermes architecture. Spawns `claude -p` with
`--output-format json` for structured output parsing.

Refs #391
2026-05-22 18:38:18 +08:00
xiaomo 669875fb46 Merge pull request 'feat: validate model connectivity during uwf setup' (#392) from feat/335-setup-validate-model into main 2026-05-22 10:32:01 +00:00
xiaoju 6d94be34a9 feat: validate model connectivity during uwf setup
Send a test completion request after configuration to verify the model
is reachable. If validation fails, warn the user and suggest trying a
different model or checking their settings.

Fixes #335
2026-05-22 10:30:39 +00:00
xiaomo d95fe45a3d Merge pull request 'feat: add --count/-c flag to uwf thread step' (#390) from feat/373-thread-step-count into main 2026-05-22 10:11:13 +00:00
xiaoju 4d47effd39 fix: generate frontmatter instruction dynamically from role schema
Replace hardcoded 5-field example with schema-driven generation.
Now shows actual enum values, types, and required markers for
each role's frontmatter schema.

Fixes #389

小橘 <xiaoju@shazhou.work>
2026-05-22 10:03:45 +00:00
xiaoju 67870392ab fix: dynamic frontmatter field extraction from role schema
Replace hardcoded 5-field candidate with schema-driven extraction.
Now reads outputSchema properties and picks matching fields from
parsed frontmatter, supporting role-specific fields like plan,
approved, success.

Falls back to standard 5 fields when schema has no properties.

Fixes #388

小橘 <xiaoju@shazhou.work>
2026-05-22 09:57:30 +00:00
jiashuang 9316b843f6 init workflow service 2026-05-22 17:46:53 +08:00
xiaoju 487c48effa fix: revert output protocol changes from #385
Agent CLI outputs plain CAS hash (not JSON), engine parses plain hash.
StepOutput no longer carries sessionId — session info is already in CAS detail.
Keeps the valuable parts of #385: sessionId in AgentRunResult (process-internal),
continue support, and frontmatter retry loop.
2026-05-22 09:39:36 +00:00
xiaoju f0f840e6e0 fix: StepOutput.sessionId → string | null, legacy fallback → null 2026-05-22 09:16:13 +00:00
xiaoju 7ff90cef4f feat: agent session protocol — sessionId in result, continue support, frontmatter retry
Breaking changes:
- AgentRunResult now requires sessionId field
- AgentOptions now requires continue function
- Agent CLI outputs JSON {stepHash, sessionId} instead of plain CAS hash
- Engine parses JSON output (with legacy CAS hash fallback)

New features:
- Frontmatter validation retry: if agent output lacks valid frontmatter,
  engine calls agent.continue() up to 2 times with correction message
- Session tracking: sessionId flows from agent → engine → StepOutput
- Hermes agent: session parse failure is now a hard error (no raw text fallback)
- Hermes agent: supports --resume for continue sessions

Closes #384
2026-05-22 09:13:05 +00:00
xiaoju e62d51d845 Merge remote-tracking branch 'origin/feat/remove-llm-extract' into feat/384-agent-session-protocol 2026-05-22 09:06:24 +00:00
xiaoju 99a2890be2 feat: remove LLM extract fallback, require YAML frontmatter
Agent output must contain valid YAML frontmatter matching the role schema.
If frontmatter parsing fails, the step fails immediately with a clear error
instead of falling back to an LLM extraction that can fabricate values.

The extract module remains as a public API export but is no longer used
in the agent run loop.

Breaking change: agents that relied on LLM extraction to produce valid
output will now fail. They must output proper frontmatter.
2026-05-22 08:58:01 +00:00
xiaoju 3b7d0564bb feat: uwf cas put-text for storing plain text in CAS
- Register built-in text schema ({type: 'string'}) alongside workflow schemas
- Add cmdCasPutText command: uwf cas put-text <text>
- Update CLI reference in workflow-util
- Update solve-issue.yaml procedure to use put-text

Refs #380
2026-05-22 08:53:27 +00:00
xiaoju 45dacf540b feat: thread step --count/-c <number> to run multiple steps
Add --count/-c flag to 'uwf thread step' for running N steps in one
invocation, stopping early if $END is reached.

- cmdThreadStep now loops up to count times, delegates to cmdThreadStepOnce
- CLI parses -c/--count, defaults to 1 (backward compatible single output)
- Validation rejects 0, negative, and non-integer counts
- 7 new tests covering CLI parsing and count validation

Fixes #373

Co-authored-by: uwf-hermes (solve-issue workflow)
2026-05-22 08:06:26 +00:00
xiaoju e67932c83c fix: accept omitted condition in fallback transitions
Fallback transitions (last entry in graph node) omit the condition
field in YAML, resulting in undefined instead of null. The validator
and materializer now handle this:

- validate.ts: accept undefined as valid condition value
- workflow.ts: normalizeGraph() coerces undefined → null before CAS put

This was broken by the graph fallback pattern introduced in #370.
2026-05-22 07:38:24 +00:00
xiaoju e5ae9a134c feat: register $first/$last JSONata functions in moderator
Register custom $first(role) and $last(role) functions in the JSONata
evaluator. These search the steps array and return the matching role's
frontmatter (output) directly, replacing verbose steps[-1].output.x
expressions with semantic $last('role').field syntax.

- workflow-moderator: register functions via expr.registerFunction()
- Updated all condition expressions in .workflows/ and examples/
- Added tests for $last, $first, and unmatched role (undefined)

Fixes #376
2026-05-22 06:29:56 +00:00
xiaoju 02f7f0b708 refactor!: rename RoleDefinition.meta → frontmatter
BREAKING CHANGE: All workflow YAML files must use 'frontmatter' instead of 'meta'.

- workflow-protocol: RoleDefinition.meta → frontmatter, schema updated
- cli-workflow: validate.ts, workflow.ts — resolveMetaRef → resolveFrontmatterRef
- workflow-agent-kit: run.ts — metaSchema → frontmatterSchema
- All YAML files updated (examples/, .workflows/)

Fixes #374
2026-05-22 06:05:07 +00:00
xiaoju 995f273fa5 address review: move CLI reference to workflow-util, inline in prompt
- Move generateCliReference() to @uncaged/workflow-util
- buildRolePrompt inlines CLI reference directly (no agent tool call)
- Fix Role terminology to use new field names
- Add maintenance comment in cli-reference.ts
- Fix test assertions
2026-05-22 03:29:01 +00:00
xiaoju 866154ad73 feat: add uwf skill cli command and Prepare section in role prompt
- Add 'uwf skill cli' command that prints markdown CLI reference
- buildRolePrompt now generates ## Prepare section:
  - Always prompts agent to run 'uwf skill cli' (explicit skill)
  - Renders capabilities as keyword hints for implicit skill loading

Fixes #369
2026-05-22 03:20:04 +00:00
xiaoju 3fb60ee649 chore: exclude legacy-packages and scripts from biome check
- Add legacy-packages/ and scripts/ to biome ignore
- Allow noDefaultExport in vitest.config.* and .d.ts
- Allow console in cli.ts and setup.ts (CLI user output)
- Fix unused imports in cas.ts and setup.ts
2026-05-22 02:09:18 +00:00
xiaoju a3114bf840 chore: apply biome formatting across codebase 2026-05-22 02:06:05 +00:00
xiaoju e59ae9aca1 feat: support project-local workflow discovery
- Add .workflows/*.yaml scanning from project root (cwd)
- Resolution: project-local first, then global registry
- On-the-fly CAS materialization for local workflows
- Filename/name consistency check
- uwf workflow list shows origin (local/global)

Fixes #365
2026-05-22 01:01:45 +00:00
xiaoju c60c310074 refactor: rename RoleDefinition fields for clarity
- identity → goal
- prepare → capabilities (string[])
- execute → procedure
- report → output
- outputSchema → meta

Fixes #364
2026-05-22 00:46:06 +00:00
xiaoju 192ad656a4 refactor: remove systemPrompt, make four-phase fields required
Breaking change per review:
- Remove systemPrompt from RoleDefinition entirely
- identity/prepare/execute/report are now required (string, not nullable)
- Remove all legacy fallback logic in buildRolePrompt
- Simplify validate.ts, workflow.ts materialize
- Migrate all test fixtures and example workflows

Refs #359
2026-05-21 03:07:56 +00:00
xiaoju 505f85e3c4 feat: add buildRolePrompt in agent-kit, integrate with uwf-hermes
- New buildRolePrompt() in workflow-agent-kit: four-phase prompt assembly
  with fallback to systemPrompt
- Export from agent-kit index
- Update uwf-hermes to use buildRolePrompt instead of raw systemPrompt
- Add tests for all modes: four-phase, legacy, mixed

Refs #359, #362
2026-05-21 02:31:56 +00:00
xiaoju fc7d482b4f feat: add four-phase role description (identity/prepare/execute/report)
- Extend RoleDefinition with identity, prepare, execute, report fields
- Make systemPrompt optional (nullable) for four-phase workflows
- Update ROLE_DEFINITION JSON Schema (all new fields optional)
- Update validate.ts to accept new fields
- Update workflow.ts to strip null fields before CAS storage
- Update thread read to prefer identity over systemPrompt
- Add --version flag to uwf CLI
- Bump all packages to 0.5.0

Refs #359
2026-05-21 01:41:20 +00:00
xiaoju f9979c3c89 chore: upgrade json-cas to 0.4.x, fix Store → BootstrapCapableStore
- @uncaged/json-cas ^0.3.0 → ^0.4.0
- @uncaged/json-cas-fs ^0.3.0 → ^0.4.0 (now publishes .d.ts + .js)
- UwfStore.store typed as BootstrapCapableStore
- tsc --build now clean (no more node_modules type errors)

小橘 🍊(NEKO Team)
2026-05-19 10:29:57 +00:00
xiaoju 6c14259184 chore: remove pnpm-lock.yaml files, bun only
小橘 🍊(NEKO Team)
2026-05-19 07:58:24 +00:00
xiaoju 7b9cb6a9c8 chore: rename uwf-* → workflow-*, cli-uwf → cli-workflow
Reclaim the workflow-* package names now that legacy packages are archived.

Package renames:
- @uncaged/uwf-protocol → @uncaged/workflow-protocol
- @uncaged/uwf-moderator → @uncaged/workflow-moderator
- @uncaged/uwf-agent-kit → @uncaged/workflow-agent-kit
- @uncaged/uwf-agent-hermes → @uncaged/workflow-agent-hermes
- @uncaged/cli-uwf → @uncaged/cli-workflow

All internal imports, tsconfig references, and docs updated.
CLI binary name 'uwf' unchanged.

小橘 🍊(NEKO Team)
2026-05-19 07:52:16 +00:00
xiaoju 68246e20b1 fix: remove workflow-util dependency on workflow-protocol
Inline Result type and ok/err helpers into workflow-util to break
dependency on the now-archived workflow-protocol package.

Also add explicit @uncaged/json-cas dep to uwf-protocol (was only
available as transitive dep via json-cas-fs).

小橘 🍊(NEKO Team)
2026-05-19 07:22:15 +00:00
xiaoju d63d58ccb5 chore: reorganize repo — legacy packages to legacy-packages/, templates to examples/
- Move 15 old workflow-* packages to legacy-packages/ (inactive, preserved for reference)
- Rename templates/ → examples/ for clarity
- Rewrite docs/architecture.md to reflect current uwf architecture
- Active packages remain in packages/: cli-uwf, uwf-agent-hermes, uwf-agent-kit, uwf-moderator, uwf-protocol, workflow-util

小橘 🍊(NEKO Team)
2026-05-19 07:19:40 +00:00
xiaoju 762ecec872 feat(cli-uwf): thread read shows Content + new step-details command
- thread read: add ### Content section (last assistant message) before ### Output
- Remove --detail flag (replaced by step-details command)
- New: uwf thread step-details <step-hash> — full detail dump as yaml

Closes #357
2026-05-19 06:44:18 +00:00
xiaoju c0ac4ade09 fix(uwf-agent-hermes): consume outputFormatInstruction in prompt
buildHermesPrompt was ignoring ctx.outputFormatInstruction — the
deliverable format and scope constraint were injected into context
but never passed to the agent.

Now prepends it before systemPrompt (deliverable-first principle).

Refs #355
2026-05-19 06:23:13 +00:00
xiaoju 892ccab8d5 feat(uwf-agent-kit): frontmatter fast path + prompt injection
Port RFC #351 frontmatter markdown to uwf-* path:
- tryFrontmatterFastPath(): parse → validate → JSON Schema check via json-cas
- Happy path skips LLM extract, fallback to existing extract()
- buildOutputFormatInstruction(): generates deliverable format from JSON Schema
- Injected into agent context before execution
- Scope reminder: 'Focus exclusively on YOUR role's deliverable'
- 14 new tests (vitest)

Closes #355
2026-05-19 06:20:15 +00:00
xiaoju 8a7e756fe3 feat(workflow-util-agent): prompt restructure + scope focus — Phase 3
- buildOutputFormatInstruction(schema): auto-generates frontmatter
  format guide from Zod schema, injected at top of system prompt
- Adapter prepends deliverable format before role's systemPrompt
- buildThreadInput reordered: Task → Steps → Parent → Tools
- Scope reminder: 'Focus exclusively on YOUR role's deliverable'
- 8 tests for buildOutputFormatInstruction

Refs #351
2026-05-19 05:56:27 +00:00
xiaoju d5f47d1a18 feat(workflow-util-agent): two-layer frontmatter safeguard in adapter
Phase 2 of RFC #351 — adapter tries frontmatter first (zero LLM cost),
falls back to runtime.extract() when frontmatter is missing/invalid.

- tryFrontmatterMeta(): parse → validate → schema.safeParse
- Happy path stores body (no frontmatter) in CAS
- Fallback stores full raw in CAS + LLM extract
- 5 tests covering both paths

Refs #351
2026-05-19 05:46:36 +00:00
xiaoju 37c35560e9 docs: fix parseMinimalYaml JSDoc (nit from #352 review)
Refs #351
2026-05-19 05:41:18 +00:00
xiaomo f174b96028 Merge pull request 'feat(workflow-util): frontmatter markdown parser — RFC #351 Phase 1' (#352) from feat/351-frontmatter-markdown-phase1 into main 2026-05-19 04:56:58 +00:00
xiaoju 43978360ff feat(workflow-util): add frontmatter markdown parser and validator
Phase 1 of RFC #351 — define AgentFrontmatter type, parseFrontmatterMarkdown()
and validateFrontmatter() with 45 tests.

- Built-in minimal YAML parser (no new deps)
- Never throws on malformed input — degrades gracefully
- All fields use T | null (no optional properties)

Refs #351
2026-05-19 04:41:56 +00:00
xiaoju dacebe1841 feat(thread-read): show role system prompt in each step
Each step block now includes a '### Prompt' section showing the
role's systemPrompt from the workflow definition.

Refs #349
2026-05-19 03:23:50 +00:00
xiaoju c42125946d feat(thread-read): expand detail recursively via cas_ref
--detail now uses expandDeep to recursively resolve all cas_ref
fields in the detail merkle tree, showing full turn content
instead of raw hashes.

Refs #349
2026-05-19 03:19:40 +00:00
xiaoju 4c9ce72395 feat: uwf thread read — human-readable markdown with pagination
- Outputs markdown directly (not JSON/YAML)
- --quota <chars>: character budget, loads steps backward until exceeded (default 4000)
- --before <step-hash>: load steps before this hash (exclusive), omits start
- --start: force include start section even with --before
- --detail: expand detail CAS node content for each step
- Skip hint with uwf thread read command for pagination
- Reuses walkChain/collectOrderedSteps/expandOutput

Closes #349
2026-05-19 03:15:38 +00:00
xiaoju cf9e2cd3d6 fix: parse session_id from stderr (hermes --quiet writes it there)
hermes --quiet outputs session_id to stderr and AI response to stdout.
The agent was only parsing stdout, so session_id was never found and
detail always fell back to raw output.

Now checks stderr first, then stdout as fallback.
2026-05-18 17:05:54 +00:00
xiaoju 546237db85 fix: parseSessionIdFromStdout scans all lines, not just last
--quiet mode outputs session_id on the first line, not the last.
The old code only checked the last non-empty line and broke immediately
if it didn't match, causing session detail to always be empty.

Fixes the empty detail bug when hermes agent runs in quiet mode.
2026-05-18 16:57:24 +00:00
xiaoju bd5e5a435b simplify: thread fork only takes step-hash
Remove thread-id argument — CAS node is self-contained, no need to
specify which thread it belongs to. Just verify the hash is a valid
StartNode or StepNode.

Refs #342
2026-05-18 16:38:55 +00:00
xiaoju 06eb2dff3b feat: add thread steps and thread fork commands
- uwf thread steps <thread-id>: walk CAS chain, list all steps chronologically
- uwf thread fork <thread-id> <step-hash>: create new thread from history point
- New types: StartEntry, StepEntry, ThreadStepsOutput, ThreadForkOutput
- Supports both active and archived threads

Refs #342
2026-05-18 16:30:12 +00:00
xiaoju 710d42d6b9 refactor(agent-kit): base AgentContext on ModeratorContext
AgentContext now extends ModeratorContext (start + steps) with threadId, role, store, and expanded workflow. Hermes and mock-agent read prompt/steps/systemPrompt from the new shape.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-18 16:14:13 +00:00