@united-workforce/cli 0.6.1 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. package/README.md +120 -5
  2. package/dist/.build-fingerprint +1 -1
  3. package/dist/__tests__/agent-resolution-llm-free.test.js +9 -2
  4. package/dist/__tests__/agent-resolution-llm-free.test.js.map +1 -1
  5. package/dist/__tests__/broker-prompt.test.d.ts +10 -0
  6. package/dist/__tests__/broker-prompt.test.d.ts.map +1 -0
  7. package/dist/__tests__/broker-prompt.test.js +129 -0
  8. package/dist/__tests__/broker-prompt.test.js.map +1 -0
  9. package/dist/__tests__/broker-step-active-turns.test.d.ts +20 -0
  10. package/dist/__tests__/broker-step-active-turns.test.d.ts.map +1 -0
  11. package/dist/__tests__/broker-step-active-turns.test.js +428 -0
  12. package/dist/__tests__/broker-step-active-turns.test.js.map +1 -0
  13. package/dist/__tests__/broker-step-turn-chain-phase2.test.d.ts +13 -0
  14. package/dist/__tests__/broker-step-turn-chain-phase2.test.d.ts.map +1 -0
  15. package/dist/__tests__/broker-step-turn-chain-phase2.test.js +429 -0
  16. package/dist/__tests__/broker-step-turn-chain-phase2.test.js.map +1 -0
  17. package/dist/__tests__/config.test.js +33 -37
  18. package/dist/__tests__/config.test.js.map +1 -1
  19. package/dist/__tests__/e2e-broker-step-suspend.test.d.ts +18 -0
  20. package/dist/__tests__/e2e-broker-step-suspend.test.d.ts.map +1 -0
  21. package/dist/__tests__/e2e-broker-step-suspend.test.js +313 -0
  22. package/dist/__tests__/e2e-broker-step-suspend.test.js.map +1 -0
  23. package/dist/__tests__/e2e-broker-step.test.d.ts +13 -0
  24. package/dist/__tests__/e2e-broker-step.test.d.ts.map +1 -0
  25. package/dist/__tests__/e2e-broker-step.test.js +278 -0
  26. package/dist/__tests__/e2e-broker-step.test.js.map +1 -0
  27. package/dist/__tests__/e2e-mock-agent.test.js +1 -1
  28. package/dist/__tests__/e2e-mock-agent.test.js.map +1 -1
  29. package/dist/__tests__/e2e-thread-resume-timeout-suspend.test.d.ts +28 -0
  30. package/dist/__tests__/e2e-thread-resume-timeout-suspend.test.d.ts.map +1 -0
  31. package/dist/__tests__/e2e-thread-resume-timeout-suspend.test.js +322 -0
  32. package/dist/__tests__/e2e-thread-resume-timeout-suspend.test.js.map +1 -0
  33. package/dist/__tests__/log-tag-validity.test.d.ts +2 -0
  34. package/dist/__tests__/log-tag-validity.test.d.ts.map +1 -0
  35. package/dist/__tests__/log-tag-validity.test.js +110 -0
  36. package/dist/__tests__/log-tag-validity.test.js.map +1 -0
  37. package/dist/__tests__/setup-agent-discovery.test.js +35 -23
  38. package/dist/__tests__/setup-agent-discovery.test.js.map +1 -1
  39. package/dist/__tests__/setup-no-llm.test.js +5 -2
  40. package/dist/__tests__/setup-no-llm.test.js.map +1 -1
  41. package/dist/__tests__/step-ask.test.js +9 -6
  42. package/dist/__tests__/step-ask.test.js.map +1 -1
  43. package/dist/__tests__/step-show-json.test.js +5 -5
  44. package/dist/__tests__/step-show-json.test.js.map +1 -1
  45. package/dist/__tests__/step-show-text.test.d.ts +2 -0
  46. package/dist/__tests__/step-show-text.test.d.ts.map +1 -0
  47. package/dist/__tests__/step-show-text.test.js +192 -0
  48. package/dist/__tests__/step-show-text.test.js.map +1 -0
  49. package/dist/__tests__/step-turns-cli-subprocess.test.d.ts +21 -0
  50. package/dist/__tests__/step-turns-cli-subprocess.test.d.ts.map +1 -0
  51. package/dist/__tests__/step-turns-cli-subprocess.test.js +356 -0
  52. package/dist/__tests__/step-turns-cli-subprocess.test.js.map +1 -0
  53. package/dist/__tests__/step-turns-panorama-phase3.test.d.ts +21 -0
  54. package/dist/__tests__/step-turns-panorama-phase3.test.d.ts.map +1 -0
  55. package/dist/__tests__/step-turns-panorama-phase3.test.js +476 -0
  56. package/dist/__tests__/step-turns-panorama-phase3.test.js.map +1 -0
  57. package/dist/__tests__/step-turns.test.d.ts +24 -0
  58. package/dist/__tests__/step-turns.test.d.ts.map +1 -0
  59. package/dist/__tests__/step-turns.test.js +646 -0
  60. package/dist/__tests__/step-turns.test.js.map +1 -0
  61. package/dist/__tests__/store-turn-chain.test.d.ts +2 -0
  62. package/dist/__tests__/store-turn-chain.test.d.ts.map +1 -0
  63. package/dist/__tests__/store-turn-chain.test.js +341 -0
  64. package/dist/__tests__/store-turn-chain.test.js.map +1 -0
  65. package/dist/__tests__/thread-agent-failure-suspended.test.js +3 -3
  66. package/dist/__tests__/thread-agent-failure-suspended.test.js.map +1 -1
  67. package/dist/__tests__/thread-list-limit-offset.test.d.ts +24 -0
  68. package/dist/__tests__/thread-list-limit-offset.test.d.ts.map +1 -0
  69. package/dist/__tests__/thread-list-limit-offset.test.js +254 -0
  70. package/dist/__tests__/thread-list-limit-offset.test.js.map +1 -0
  71. package/dist/__tests__/thread-list-template-ms-date.test.js +7 -2
  72. package/dist/__tests__/thread-list-template-ms-date.test.js.map +1 -1
  73. package/dist/__tests__/thread-poke.test.js +6 -6
  74. package/dist/__tests__/thread-poke.test.js.map +1 -1
  75. package/dist/__tests__/thread-resume.test.js +2 -2
  76. package/dist/__tests__/thread-resume.test.js.map +1 -1
  77. package/dist/__tests__/thread-suspend-step.test.js +1 -1
  78. package/dist/__tests__/thread-suspend-step.test.js.map +1 -1
  79. package/dist/__tests__/thread.test.js +28 -14
  80. package/dist/__tests__/thread.test.js.map +1 -1
  81. package/dist/cli.js +910 -344
  82. package/dist/cli.js.map +1 -1
  83. package/dist/commands/broker-step.d.ts +117 -0
  84. package/dist/commands/broker-step.d.ts.map +1 -0
  85. package/dist/commands/broker-step.js +654 -0
  86. package/dist/commands/broker-step.js.map +1 -0
  87. package/dist/commands/config.d.ts.map +1 -1
  88. package/dist/commands/config.js +2 -23
  89. package/dist/commands/config.js.map +1 -1
  90. package/dist/commands/prompt.d.ts.map +1 -1
  91. package/dist/commands/prompt.js +43 -51
  92. package/dist/commands/prompt.js.map +1 -1
  93. package/dist/commands/setup.d.ts +6 -4
  94. package/dist/commands/setup.d.ts.map +1 -1
  95. package/dist/commands/setup.js +24 -27
  96. package/dist/commands/setup.js.map +1 -1
  97. package/dist/commands/step.d.ts +54 -6
  98. package/dist/commands/step.d.ts.map +1 -1
  99. package/dist/commands/step.js +484 -134
  100. package/dist/commands/step.js.map +1 -1
  101. package/dist/commands/thread.d.ts +4 -0
  102. package/dist/commands/thread.d.ts.map +1 -1
  103. package/dist/commands/thread.js +77 -151
  104. package/dist/commands/thread.js.map +1 -1
  105. package/dist/output-mappers.d.ts +8 -0
  106. package/dist/output-mappers.d.ts.map +1 -1
  107. package/dist/output-mappers.js +72 -18
  108. package/dist/output-mappers.js.map +1 -1
  109. package/dist/schemas.d.ts +3 -0
  110. package/dist/schemas.d.ts.map +1 -1
  111. package/dist/schemas.js +17 -3
  112. package/dist/schemas.js.map +1 -1
  113. package/dist/store.d.ts +147 -1
  114. package/dist/store.d.ts.map +1 -1
  115. package/dist/store.js +254 -1
  116. package/dist/store.js.map +1 -1
  117. package/dist/text-renderers.d.ts.map +1 -1
  118. package/dist/text-renderers.js +27 -2
  119. package/dist/text-renderers.js.map +1 -1
  120. package/package.json +7 -5
  121. package/src/__tests__/agent-resolution-llm-free.test.ts +14 -2
  122. package/src/__tests__/broker-prompt.test.ts +142 -0
  123. package/src/__tests__/broker-step-active-turns.test.ts +509 -0
  124. package/src/__tests__/broker-step-turn-chain-phase2.test.ts +525 -0
  125. package/src/__tests__/config.test.ts +35 -39
  126. package/src/__tests__/e2e-broker-step-suspend.test.ts +351 -0
  127. package/src/__tests__/e2e-broker-step.test.ts +320 -0
  128. package/src/__tests__/e2e-mock-agent.test.ts +1 -1
  129. package/src/__tests__/e2e-thread-resume-timeout-suspend.test.ts +360 -0
  130. package/src/__tests__/log-tag-validity.test.ts +124 -0
  131. package/src/__tests__/setup-agent-discovery.test.ts +35 -23
  132. package/src/__tests__/setup-no-llm.test.ts +5 -2
  133. package/src/__tests__/step-ask.test.ts +9 -6
  134. package/src/__tests__/step-show-json.test.ts +5 -5
  135. package/src/__tests__/step-show-text.test.ts +236 -0
  136. package/src/__tests__/step-turns-cli-subprocess.test.ts +411 -0
  137. package/src/__tests__/step-turns-panorama-phase3.test.ts +579 -0
  138. package/src/__tests__/step-turns.test.ts +734 -0
  139. package/src/__tests__/store-turn-chain.test.ts +386 -0
  140. package/src/__tests__/thread-agent-failure-suspended.test.ts +3 -3
  141. package/src/__tests__/thread-list-limit-offset.test.ts +305 -0
  142. package/src/__tests__/thread-list-template-ms-date.test.ts +7 -2
  143. package/src/__tests__/thread-poke.test.ts +6 -6
  144. package/src/__tests__/thread-resume.test.ts +2 -2
  145. package/src/__tests__/thread-suspend-step.test.ts +1 -1
  146. package/src/__tests__/thread.test.ts +29 -15
  147. package/src/cli.ts +1056 -483
  148. package/src/commands/broker-step.ts +913 -0
  149. package/src/commands/config.ts +2 -24
  150. package/src/commands/prompt.ts +43 -51
  151. package/src/commands/setup.ts +25 -29
  152. package/src/commands/step.ts +645 -176
  153. package/src/commands/thread.ts +87 -192
  154. package/src/output-mappers.ts +99 -21
  155. package/src/schemas.ts +32 -2
  156. package/src/store.ts +297 -2
  157. package/src/text-renderers.ts +35 -2
  158. package/dist/__tests__/adapter-json-roundtrip.test.d.ts +0 -2
  159. package/dist/__tests__/adapter-json-roundtrip.test.d.ts.map +0 -1
  160. package/dist/__tests__/adapter-json-roundtrip.test.js +0 -160
  161. package/dist/__tests__/adapter-json-roundtrip.test.js.map +0 -1
  162. package/dist/__tests__/spawn-agent-json.test.d.ts +0 -2
  163. package/dist/__tests__/spawn-agent-json.test.d.ts.map +0 -1
  164. package/dist/__tests__/spawn-agent-json.test.js +0 -79
  165. package/dist/__tests__/spawn-agent-json.test.js.map +0 -1
  166. package/src/__tests__/adapter-json-roundtrip.test.ts +0 -193
  167. package/src/__tests__/spawn-agent-json.test.ts +0 -100
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  ## Overview
6
6
 
7
- Layer 4 entry point for the workflow engine. The `uwf` binary orchestrates one step per invocation: load thread head from `threads.yaml`, run the moderator, spawn the configured agent CLI, run extract, append a CAS step node, and update the head pointer (or archive when `$END`).
7
+ Layer 4 entry point for the workflow engine. The `uwf` binary orchestrates one step per invocation: load the thread head, run the moderator, dispatch the role to the configured agent **over the Sumeru HTTP API via the broker** (`broker.send()`), run frontmatter extraction on the agent's reply, append a CAS step node, and update the head pointer (or archive when `$END`). Agents are no longer spawned as CLI subprocesses — `~/.uwf/config.yaml` declares an `agents` map keyed by alias, where each entry resolves to a `{host, gateway}` Sumeru endpoint that the broker contacts directly.
8
8
 
9
9
  ### Four-Layer Architecture
10
10
 
@@ -16,11 +16,11 @@ workflow → thread → step → turn
16
16
  - **Workflow** (layer 1): YAML template with roles and routing graph
17
17
  - **Thread** (layer 2): Single workflow execution instance
18
18
  - **Step** (layer 3): One moderator→agent→extract cycle
19
- - **Turn** (layer 4): Agent-internal interactions (use `step show` or CAS to inspect)
19
+ - **Turn** (layer 4): Agent-internal interactions (use `step turns` to see the whole-thread turn panorama — every step's turns, with the in-flight step marked 进行中 — or `step show` / CAS to inspect)
20
20
 
21
21
  This package has no library `src/index.ts` — it is consumed as a CLI binary only.
22
22
 
23
- **Dependencies:** `@ocas/core`, `@ocas/fs`, `@united-workforce/util-agent`, `@united-workforce/protocol`, `@united-workforce/util`, `commander`, `dotenv`, `mustache`, `yaml`
23
+ **Dependencies:** `@ocas/core`, `@ocas/cli-kit`, `@ocas/fs`, `@united-workforce/util-agent`, `@united-workforce/protocol`, `@united-workforce/util`, `dotenv`, `mustache`, `yaml`
24
24
 
25
25
  ## Installation
26
26
 
@@ -63,13 +63,35 @@ The `json` and `yaml` envelopes carry the schema hash on the `type` field so con
63
63
  | `uwf thread start <workflow> -p <prompt>` | Create a thread without executing |
64
64
  | `uwf thread exec <thread-id> [--agent <cmd>] [-c <count>] [--background]` | Execute one or more moderator→agent→extract cycles |
65
65
  | `uwf thread show <thread-id>` | Show thread head pointer |
66
- | `uwf thread list [--status <status>] [--all] [--after <date>] [--before <date>] [--skip <n>] [--take <n>]` | List threads (defaults to active: idle + running). Use `--all` to include end/cancelled/suspended, or `--status` to filter explicitly (idle, running, suspended, end, cancelled, active, or comma-separated). Supports time range and pagination. |
66
+ | `uwf thread list [--status <status>] [--all] [--after <date>] [--before <date>] [--limit <n>] [--offset <m>]` | List threads (defaults to active: idle + running). Use `--all` to include end/cancelled/suspended, or `--status` to filter explicitly (idle, running, suspended, end, cancelled, active, or comma-separated). Supports time range and pagination (`--limit`/`--offset`; `--take`/`--skip` are accepted as aliases). |
67
67
  | `uwf thread read <thread-id> [--quota N] [--before <hash>] [--start]` | Render thread as readable markdown |
68
68
 
69
69
  `thread read`, `step list`, and `step show` work on both active and ended threads.
70
70
  | `uwf thread stop <thread-id>` | Stop background execution (keep thread active) |
71
+ | `uwf thread resume <thread-id> [-p <text>] [--agent <cmd>]` | Resume a suspended thread and re-run the suspended role |
72
+ | `uwf thread poke <thread-id> -p <text> [--agent <cmd>] [-c <count>]` | Re-run the head step's agent with a supplementary prompt (replaces head step) |
71
73
  | `uwf thread cancel <thread-id>` | Cancel thread (stop + archive to history) |
72
74
 
75
+ ### Suspend / Resume
76
+
77
+ A thread enters `suspended` status from **two sources**, both landing at the same `$status: "$SUSPEND"` exit:
78
+
79
+ 1. **Voluntary** — an agent emits `$status: "$SUSPEND"` in its frontmatter (it hits a token budget, needs human input, etc.).
80
+ 2. **Timeout checkpoint** — the agent's `send` exceeds the adapter timeout. Instead of killing the step as an error, the broker reports a `kind: "suspended"` result and the step is written as a `$SUSPEND` node carrying the timeout `reason` (and the `nativeId` needed to resume). A timeout is a **checkpoint, not a death** — work already produced is preserved and the thread can be continued.
81
+
82
+ A suspended thread **cannot be advanced with `exec`** — `exec` detects the suspended head and returns immediately without running any agent.
83
+
84
+ To continue a suspended thread, use `resume`:
85
+
86
+ ```bash
87
+ uwf thread resume <thread-id> # resume with workflow's default prompt
88
+ uwf thread resume <thread-id> -p "version 1.2.0" # resume with supplementary context
89
+ ```
90
+
91
+ `resume` issues a **fresh `send`** on the same cached `(threadId, role)` session; the underlying agent adapter resumes by its native session id (`--resume <nativeId>`), so the agent continues from its own history rather than starting over. For a timeout-suspended thread, `-p` supplies a short continuation prompt (e.g. `"continue"`) — the original prompt is not re-sent.
92
+
93
+ > ⚠️ `exec` does not advance suspended threads — you **must** use `resume` to provide context and continue.
94
+
73
95
  Examples:
74
96
 
75
97
  ```bash
@@ -82,7 +104,8 @@ uwf thread list --all
82
104
  uwf thread list --status running
83
105
  uwf thread list --status active
84
106
  uwf thread list --status idle,end
85
- uwf thread list --after 7d --take 10
107
+ uwf thread list --after 7d --limit 10
108
+ uwf thread list --limit 5 --offset 10
86
109
  uwf thread read 01ARZ3NDEKTSV4RRFFQ69G5FAV --quota 8000
87
110
  uwf thread stop 01ARZ3NDEKTSV4RRFFQ69G5FAV
88
111
  ```
@@ -94,6 +117,7 @@ uwf thread stop 01ARZ3NDEKTSV4RRFFQ69G5FAV
94
117
  | `uwf step list <thread-id>` | List all steps in a thread chronologically |
95
118
  | `uwf step show <step-hash>` | Show step metadata and frontmatter |
96
119
  | `uwf step read <step-hash> [--quota <chars>]` | Read a step's turns as human-readable markdown |
120
+ | `uwf step turns <thread-id> [--role <r>] [--live] [--limit <n>] [--offset <m>]` | Show **all** turns across a thread's steps (whole-chain panorama): each completed step from its `detail.turns` (`✓`), the in-flight step from its active var (`🔄 进行中`) |
97
121
  | `uwf step fork <step-hash>` | Fork a thread from a specific step |
98
122
  | `uwf step ask <step-hash> -p <prompt> [--agent <cmd>] [--no-fork]` | Ask a follow-up question to a historical step's agent (read-only; no thread mutation) |
99
123
 
@@ -103,11 +127,29 @@ Examples:
103
127
  uwf step list 01ARZ3NDEKTSV4RRFFQ69G5FAV
104
128
  uwf step show 32GCDE899RRQ3
105
129
  uwf step read 32GCDE899RRQ3 --quota 2000
130
+ uwf step turns 01ARZ3NDEKTSV4RRFFQ69G5FAV # whole-thread panorama
131
+ uwf step turns 01ARZ3NDEKTSV4RRFFQ69G5FAV --role coder # filter to one role's steps
132
+ uwf step turns 01ARZ3NDEKTSV4RRFFQ69G5FAV --limit 20 --offset 40 # paginate the flat sequence
133
+ uwf step turns 01ARZ3NDEKTSV4RRFFQ69G5FAV --role coder --live # follow the in-flight step
106
134
  uwf step fork 32GCDE899RRQ3
107
135
  uwf step ask 32GCDE899RRQ3 -p "Why did you choose this approach?"
108
136
  uwf step ask 32GCDE899RRQ3 -p "Summarise the key findings" --no-fork
109
137
  ```
110
138
 
139
+ `step turns` is the turn-layer (layer 4) query keyed by `<thread-id>`. Unlike
140
+ `step read` — which renders a *single* completed step's `detail.turns` by step
141
+ hash, quota-bounded — `step turns` renders the **whole-thread turn panorama**: it
142
+ walks the entire thread chain and shows **every** step's turns in chronological
143
+ order, each turn attributed to its owning role/step. Completed steps are read from
144
+ their immutable `detail.turns` and marked `✓`; the in-flight step is read live from
145
+ its `@uwf/active-turns/<thread-id>/<role>` var and marked `🔄 进行中`. **All turns
146
+ show by default** (no truncation); `--limit`/`--offset` paginate the flattened
147
+ cross-step turn sequence. `--role <r>` filters the panorama to one role's steps
148
+ across the whole chain (e.g. on a multi-step thread whose head is a different role,
149
+ `--role developer` still returns the developer step's turns). With `--live` it polls
150
+ the SQLite-backed active var (not SSE) and prints each new turn as it arrives,
151
+ exiting when the in-flight step completes.
152
+
111
153
  ### Workflow (Layer 1: Templates)
112
154
 
113
155
  | Command | Description |
@@ -159,6 +201,79 @@ Engine config: `~/.uwf/config.yaml` (LLM-free — only `agents`, `defaultAgent`,
159
201
 
160
202
  ## Migration Guide
161
203
 
204
+ ### Breaking Changes (Phase 3 / #380) — broker integration & `{host, gateway}` agents
205
+
206
+ Phase 3 of the broker rollout removes the legacy `spawnAgent` /
207
+ `executeAgentCommand` / last-stdout-line JSON path from `uwf thread exec`.
208
+ The CLI now calls `broker.send({ threadId, role, prompt })` against the
209
+ Sumeru HTTP API and runs frontmatter extraction on the broker's
210
+ `result.output`. The CLI itself never starts an agent process.
211
+
212
+ This is a breaking 0.x change to `~/.uwf/config.yaml`:
213
+
214
+ | Old (`{command, args}`) | New (`{host, gateway}`) |
215
+ |-------------------------|-------------------------|
216
+ | `agents.<alias>.command` | `agents.<alias>.host` |
217
+ | `agents.<alias>.args` | `agents.<alias>.gateway` |
218
+
219
+ Rewrite each agent entry. Before:
220
+
221
+ ```yaml
222
+ agents:
223
+ hermes:
224
+ command: uwf-hermes
225
+ args: ["--verbose"]
226
+ claude-code:
227
+ command: uwf-claude-code
228
+ args: []
229
+ defaultAgent: hermes
230
+ agentOverrides: {}
231
+ ```
232
+
233
+ After:
234
+
235
+ ```yaml
236
+ agents:
237
+ hermes:
238
+ host: http://127.0.0.1:7900
239
+ gateway: hermes
240
+ claude-code:
241
+ host: http://127.0.0.1:7900
242
+ gateway: claude-code
243
+ defaultAgent: hermes
244
+ agentOverrides: {}
245
+ ```
246
+
247
+ The engine config validator (`normalizeAgents` in
248
+ `@united-workforce/util-agent`) now rejects any entry that still carries
249
+ `command` or `args` with a clear migration error. `uwf config set
250
+ agents.<alias>.command ...` is likewise rejected.
251
+
252
+ #### `--agent` override
253
+
254
+ `uwf thread exec --agent <value>` now accepts two shapes:
255
+
256
+ - An alias declared in `agents.*` (e.g. `--agent hermes`).
257
+ - An inline `"<host> <gateway>"` pair (e.g.
258
+ `--agent "http://127.0.0.1:7900 claude-code"`).
259
+
260
+ The legacy bare command override (`--agent uwf-hermes`) is removed.
261
+
262
+ #### `step ask` / `step fork` deferred to Phase 4
263
+
264
+ `uwf step ask` and `uwf step fork` are temporarily disabled in this
265
+ phase. Invoking them returns a clear "not yet supported in Phase 3"
266
+ error rather than silently using the legacy spawn path. Both will be
267
+ restored in Phase 4 once the broker exposes the per-step session
268
+ replay APIs they require.
269
+
270
+ #### Multi-step session reuse & resume
271
+
272
+ The broker rows the `(threadId, role) → sessionId` mapping in its
273
+ SQLite session store. Subsequent steps for the same role on the same
274
+ thread reuse the cached Sumeru session. `uwf thread resume` reuses the
275
+ same cached session — no new Sumeru session is created on resume.
276
+
162
277
  ### Breaking Changes (v0.5 → v0.6) — output envelope
163
278
 
164
279
  `uwf` now emits an ocas envelope (`{ type, value }`) for `--format json` and `--format yaml`, and the default format changed from `json` to `text`.
@@ -1 +1 @@
1
- 8f6475d4155e0628083a10a7c1b3bc83482b887cdcfd2a704a00492f70553d87
1
+ {"hash":"5705b01e563b540d0df2cfb3d50a0ddab22afcd05b62b89bded9a14c0b14e27a","outputs":["__tests__/agent-resolution-llm-free.test.d.ts","__tests__/agent-resolution-llm-free.test.d.ts.map","__tests__/agent-resolution-llm-free.test.js","__tests__/agent-resolution-llm-free.test.js.map","__tests__/broker-prompt.test.d.ts","__tests__/broker-prompt.test.d.ts.map","__tests__/broker-prompt.test.js","__tests__/broker-prompt.test.js.map","__tests__/broker-step-active-turns.test.d.ts","__tests__/broker-step-active-turns.test.d.ts.map","__tests__/broker-step-active-turns.test.js","__tests__/broker-step-active-turns.test.js.map","__tests__/broker-step-turn-chain-phase2.test.d.ts","__tests__/broker-step-turn-chain-phase2.test.d.ts.map","__tests__/broker-step-turn-chain-phase2.test.js","__tests__/broker-step-turn-chain-phase2.test.js.map","__tests__/build-step-entry.test.d.ts","__tests__/build-step-entry.test.d.ts.map","__tests__/build-step-entry.test.js","__tests__/build-step-entry.test.js.map","__tests__/clear-thread-failed-attempts.test.d.ts","__tests__/clear-thread-failed-attempts.test.d.ts.map","__tests__/clear-thread-failed-attempts.test.js","__tests__/clear-thread-failed-attempts.test.js.map","__tests__/concurrency.test.d.ts","__tests__/concurrency.test.d.ts.map","__tests__/concurrency.test.js","__tests__/concurrency.test.js.map","__tests__/config-text-renderer.test.d.ts","__tests__/config-text-renderer.test.d.ts.map","__tests__/config-text-renderer.test.js","__tests__/config-text-renderer.test.js.map","__tests__/config.test.d.ts","__tests__/config.test.d.ts.map","__tests__/config.test.js","__tests__/config.test.js.map","__tests__/current-role.test.d.ts","__tests__/current-role.test.d.ts.map","__tests__/current-role.test.js","__tests__/current-role.test.js.map","__tests__/e2e-broker-step-suspend.test.d.ts","__tests__/e2e-broker-step-suspend.test.d.ts.map","__tests__/e2e-broker-step-suspend.test.js","__tests__/e2e-broker-step-suspend.test.js.map","__tests__/e2e-broker-step.test.d.ts","__tests__/e2e-broker-step.test.d.ts.map","__tests__/e2e-broker-step.test.js","__tests__/e2e-broker-step.test.js.map","__tests__/e2e-mock-agent.test.d.ts","__tests__/e2e-mock-agent.test.d.ts.map","__tests__/e2e-mock-agent.test.js","__tests__/e2e-mock-agent.test.js.map","__tests__/e2e-thread-resume-timeout-suspend.test.d.ts","__tests__/e2e-thread-resume-timeout-suspend.test.d.ts.map","__tests__/e2e-thread-resume-timeout-suspend.test.js","__tests__/e2e-thread-resume-timeout-suspend.test.js.map","__tests__/format-text-default.test.d.ts","__tests__/format-text-default.test.d.ts.map","__tests__/format-text-default.test.js","__tests__/format-text-default.test.js.map","__tests__/format-text-registry.test.d.ts","__tests__/format-text-registry.test.d.ts.map","__tests__/format-text-registry.test.js","__tests__/format-text-registry.test.js.map","__tests__/include-tag.test.d.ts","__tests__/include-tag.test.d.ts.map","__tests__/include-tag.test.js","__tests__/include-tag.test.js.map","__tests__/issue-180-workflow-ref-removed.test.d.ts","__tests__/issue-180-workflow-ref-removed.test.d.ts.map","__tests__/issue-180-workflow-ref-removed.test.js","__tests__/issue-180-workflow-ref-removed.test.js.map","__tests__/log-tag-validity.test.d.ts","__tests__/log-tag-validity.test.d.ts.map","__tests__/log-tag-validity.test.js","__tests__/log-tag-validity.test.js.map","__tests__/log-text-renderer.test.d.ts","__tests__/log-text-renderer.test.d.ts.map","__tests__/log-text-renderer.test.js","__tests__/log-text-renderer.test.js.map","__tests__/log.test.d.ts","__tests__/log.test.d.ts.map","__tests__/log.test.js","__tests__/log.test.js.map","__tests__/moderator-evaluate.test.d.ts","__tests__/moderator-evaluate.test.d.ts.map","__tests__/moderator-evaluate.test.js","__tests__/moderator-evaluate.test.js.map","__tests__/output-mapper-thread-list-startedat.test.d.ts","__tests__/output-mapper-thread-list-startedat.test.d.ts.map","__tests__/output-mapper-thread-list-startedat.test.js","__tests__/output-mapper-thread-list-startedat.test.js.map","__tests__/output-mapper-workflow-add.test.d.ts","__tests__/output-mapper-workflow-add.test.d.ts.map","__tests__/output-mapper-workflow-add.test.js","__tests__/output-mapper-workflow-add.test.js.map","__tests__/pid-recycling.test.d.ts","__tests__/pid-recycling.test.d.ts.map","__tests__/pid-recycling.test.js","__tests__/pid-recycling.test.js.map","__tests__/preload.d.ts","__tests__/preload.d.ts.map","__tests__/preload.js","__tests__/preload.js.map","__tests__/prompt.test.d.ts","__tests__/prompt.test.d.ts.map","__tests__/prompt.test.js","__tests__/prompt.test.js.map","__tests__/resolve-head-hash.test.d.ts","__tests__/resolve-head-hash.test.d.ts.map","__tests__/resolve-head-hash.test.js","__tests__/resolve-head-hash.test.js.map","__tests__/setup-agent-discovery.test.d.ts","__tests__/setup-agent-discovery.test.d.ts.map","__tests__/setup-agent-discovery.test.js","__tests__/setup-agent-discovery.test.js.map","__tests__/setup-complexity.test.d.ts","__tests__/setup-complexity.test.d.ts.map","__tests__/setup-complexity.test.js","__tests__/setup-complexity.test.js.map","__tests__/setup-no-llm.test.d.ts","__tests__/setup-no-llm.test.d.ts.map","__tests__/setup-no-llm.test.js","__tests__/setup-no-llm.test.js.map","__tests__/solve-issue-tea-worktree.test.d.ts","__tests__/solve-issue-tea-worktree.test.d.ts.map","__tests__/solve-issue-tea-worktree.test.js","__tests__/solve-issue-tea-worktree.test.js.map","__tests__/step-ask.test.d.ts","__tests__/step-ask.test.d.ts.map","__tests__/step-ask.test.js","__tests__/step-ask.test.js.map","__tests__/step-read.test.d.ts","__tests__/step-read.test.d.ts.map","__tests__/step-read.test.js","__tests__/step-read.test.js.map","__tests__/step-show-json.test.d.ts","__tests__/step-show-json.test.d.ts.map","__tests__/step-show-json.test.js","__tests__/step-show-json.test.js.map","__tests__/step-show-text.test.d.ts","__tests__/step-show-text.test.d.ts.map","__tests__/step-show-text.test.js","__tests__/step-show-text.test.js.map","__tests__/step-timing.test.d.ts","__tests__/step-timing.test.d.ts.map","__tests__/step-timing.test.js","__tests__/step-timing.test.js.map","__tests__/step-turns-cli-subprocess.test.d.ts","__tests__/step-turns-cli-subprocess.test.d.ts.map","__tests__/step-turns-cli-subprocess.test.js","__tests__/step-turns-cli-subprocess.test.js.map","__tests__/step-turns-panorama-phase3.test.d.ts","__tests__/step-turns-panorama-phase3.test.d.ts.map","__tests__/step-turns-panorama-phase3.test.js","__tests__/step-turns-panorama-phase3.test.js.map","__tests__/step-turns.test.d.ts","__tests__/step-turns.test.d.ts.map","__tests__/step-turns.test.js","__tests__/step-turns.test.js.map","__tests__/store-global-cas.test.d.ts","__tests__/store-global-cas.test.d.ts.map","__tests__/store-global-cas.test.js","__tests__/store-global-cas.test.js.map","__tests__/store-storage-root.test.d.ts","__tests__/store-storage-root.test.d.ts.map","__tests__/store-storage-root.test.js","__tests__/store-storage-root.test.js.map","__tests__/store-turn-chain.test.d.ts","__tests__/store-turn-chain.test.d.ts.map","__tests__/store-turn-chain.test.js","__tests__/store-turn-chain.test.js.map","__tests__/store-unified-threads.test.d.ts","__tests__/store-unified-threads.test.d.ts.map","__tests__/store-unified-threads.test.js","__tests__/store-unified-threads.test.js.map","__tests__/thread-agent-failure-suspended.test.d.ts","__tests__/thread-agent-failure-suspended.test.d.ts.map","__tests__/thread-agent-failure-suspended.test.js","__tests__/thread-agent-failure-suspended.test.js.map","__tests__/thread-cancel-status.test.d.ts","__tests__/thread-cancel-status.test.d.ts.map","__tests__/thread-cancel-status.test.js","__tests__/thread-cancel-status.test.js.map","__tests__/thread-cancel-text-renderer.test.d.ts","__tests__/thread-cancel-text-renderer.test.d.ts.map","__tests__/thread-cancel-text-renderer.test.js","__tests__/thread-cancel-text-renderer.test.js.map","__tests__/thread-join.test.d.ts","__tests__/thread-join.test.d.ts.map","__tests__/thread-join.test.js","__tests__/thread-join.test.js.map","__tests__/thread-list-filters.test.d.ts","__tests__/thread-list-filters.test.d.ts.map","__tests__/thread-list-filters.test.js","__tests__/thread-list-filters.test.js.map","__tests__/thread-list-limit-offset.test.d.ts","__tests__/thread-list-limit-offset.test.d.ts.map","__tests__/thread-list-limit-offset.test.js","__tests__/thread-list-limit-offset.test.js.map","__tests__/thread-list-template-ms-date.test.d.ts","__tests__/thread-list-template-ms-date.test.d.ts.map","__tests__/thread-list-template-ms-date.test.js","__tests__/thread-list-template-ms-date.test.js.map","__tests__/thread-list-workflow-corrupt.test.d.ts","__tests__/thread-list-workflow-corrupt.test.d.ts.map","__tests__/thread-list-workflow-corrupt.test.js","__tests__/thread-list-workflow-corrupt.test.js.map","__tests__/thread-location.test.d.ts","__tests__/thread-location.test.d.ts.map","__tests__/thread-location.test.js","__tests__/thread-location.test.js.map","__tests__/thread-poke.test.d.ts","__tests__/thread-poke.test.d.ts.map","__tests__/thread-poke.test.js","__tests__/thread-poke.test.js.map","__tests__/thread-read-quota.test.d.ts","__tests__/thread-read-quota.test.d.ts.map","__tests__/thread-read-quota.test.js","__tests__/thread-read-quota.test.js.map","__tests__/thread-read-xml-tags.test.d.ts","__tests__/thread-read-xml-tags.test.d.ts.map","__tests__/thread-read-xml-tags.test.js","__tests__/thread-read-xml-tags.test.js.map","__tests__/thread-resume.test.d.ts","__tests__/thread-resume.test.d.ts.map","__tests__/thread-resume.test.js","__tests__/thread-resume.test.js.map","__tests__/thread-show-status.test.d.ts","__tests__/thread-show-status.test.d.ts.map","__tests__/thread-show-status.test.js","__tests__/thread-show-status.test.js.map","__tests__/thread-start-cwd-cli.test.d.ts","__tests__/thread-start-cwd-cli.test.d.ts.map","__tests__/thread-start-cwd-cli.test.js","__tests__/thread-start-cwd-cli.test.js.map","__tests__/thread-step-count.test.d.ts","__tests__/thread-step-count.test.d.ts.map","__tests__/thread-step-count.test.js","__tests__/thread-step-count.test.js.map","__tests__/thread-stop-text-renderer.test.d.ts","__tests__/thread-stop-text-renderer.test.d.ts.map","__tests__/thread-stop-text-renderer.test.js","__tests__/thread-stop-text-renderer.test.js.map","__tests__/thread-suspend-step.test.d.ts","__tests__/thread-suspend-step.test.d.ts.map","__tests__/thread-suspend-step.test.js","__tests__/thread-suspend-step.test.js.map","__tests__/thread-suspended-display.test.d.ts","__tests__/thread-suspended-display.test.d.ts.map","__tests__/thread-suspended-display.test.js","__tests__/thread-suspended-display.test.js.map","__tests__/thread-test-helpers.d.ts","__tests__/thread-test-helpers.d.ts.map","__tests__/thread-test-helpers.js","__tests__/thread-test-helpers.js.map","__tests__/thread.test.d.ts","__tests__/thread.test.d.ts.map","__tests__/thread.test.js","__tests__/thread.test.js.map","__tests__/validate-semantic.test.d.ts","__tests__/validate-semantic.test.d.ts.map","__tests__/validate-semantic.test.js","__tests__/validate-semantic.test.js.map","__tests__/workflow-list-recursive.test.d.ts","__tests__/workflow-list-recursive.test.d.ts.map","__tests__/workflow-list-recursive.test.js","__tests__/workflow-list-recursive.test.js.map","__tests__/workflow-paths.test.d.ts","__tests__/workflow-paths.test.d.ts.map","__tests__/workflow-paths.test.js","__tests__/workflow-paths.test.js.map","__tests__/workflow-resolution.test.d.ts","__tests__/workflow-resolution.test.d.ts.map","__tests__/workflow-resolution.test.js","__tests__/workflow-resolution.test.js.map","__tests__/workflow-show-resolution.test.d.ts","__tests__/workflow-show-resolution.test.d.ts.map","__tests__/workflow-show-resolution.test.js","__tests__/workflow-show-resolution.test.js.map","__tests__/workflow-validate.test.d.ts","__tests__/workflow-validate.test.d.ts.map","__tests__/workflow-validate.test.js","__tests__/workflow-validate.test.js.map","__tests__/write-envelope.test.d.ts","__tests__/write-envelope.test.d.ts.map","__tests__/write-envelope.test.js","__tests__/write-envelope.test.js.map","background/background.d.ts","background/background.d.ts.map","background/background.js","background/background.js.map","background/index.d.ts","background/index.d.ts.map","background/index.js","background/index.js.map","background/types.d.ts","background/types.d.ts.map","background/types.js","background/types.js.map","cli.d.ts","cli.d.ts.map","cli.js","cli.js.map","commands/broker-step.d.ts","commands/broker-step.d.ts.map","commands/broker-step.js","commands/broker-step.js.map","commands/config.d.ts","commands/config.d.ts.map","commands/config.js","commands/config.js.map","commands/log.d.ts","commands/log.d.ts.map","commands/log.js","commands/log.js.map","commands/prompt.d.ts","commands/prompt.d.ts.map","commands/prompt.js","commands/prompt.js.map","commands/setup.d.ts","commands/setup.d.ts.map","commands/setup.js","commands/setup.js.map","commands/shared.d.ts","commands/shared.d.ts.map","commands/shared.js","commands/shared.js.map","commands/step.d.ts","commands/step.d.ts.map","commands/step.js","commands/step.js.map","commands/thread-time-parser.d.ts","commands/thread-time-parser.d.ts.map","commands/thread-time-parser.js","commands/thread-time-parser.js.map","commands/thread.d.ts","commands/thread.d.ts.map","commands/thread.js","commands/thread.js.map","commands/workflow.d.ts","commands/workflow.d.ts.map","commands/workflow.js","commands/workflow.js.map","concurrency/concurrency.d.ts","concurrency/concurrency.d.ts.map","concurrency/concurrency.js","concurrency/concurrency.js.map","concurrency/index.d.ts","concurrency/index.d.ts.map","concurrency/index.js","concurrency/index.js.map","concurrency/types.d.ts","concurrency/types.d.ts.map","concurrency/types.js","concurrency/types.js.map","format.d.ts","format.d.ts.map","format.js","format.js.map","include.d.ts","include.d.ts.map","include.js","include.js.map","moderator/__tests__/evaluate.test.d.ts","moderator/__tests__/evaluate.test.d.ts.map","moderator/__tests__/evaluate.test.js","moderator/__tests__/evaluate.test.js.map","moderator/evaluate.d.ts","moderator/evaluate.d.ts.map","moderator/evaluate.js","moderator/evaluate.js.map","moderator/index.d.ts","moderator/index.d.ts.map","moderator/index.js","moderator/index.js.map","moderator/types.d.ts","moderator/types.d.ts.map","moderator/types.js","moderator/types.js.map","output-mappers.d.ts","output-mappers.d.ts.map","output-mappers.js","output-mappers.js.map","schemas.d.ts","schemas.d.ts.map","schemas.js","schemas.js.map","store.d.ts","store.d.ts.map","store.js","store.js.map","text-renderers.d.ts","text-renderers.d.ts.map","text-renderers.js","text-renderers.js.map","validate-semantic.d.ts","validate-semantic.d.ts.map","validate-semantic.js","validate-semantic.js.map","validate.d.ts","validate.d.ts.map","validate.js","validate.js.map"]}
@@ -11,20 +11,27 @@ describe("agent resolution works without LLM fields in config.yaml (issue #143)"
11
11
  });
12
12
  test("loadWorkflowConfig succeeds on a minimal engine-only config", async () => {
13
13
  tempDir = mkdtempSync(join(tmpdir(), "uwf-engine-cfg-"));
14
- writeFileSync(join(tempDir, "config.yaml"), "agents:\n hermes: { command: uwf-hermes, args: [] }\ndefaultAgent: hermes\n", "utf8");
14
+ writeFileSync(join(tempDir, "config.yaml"), "agents:\n hermes: { host: 'http://127.0.0.1:7900', gateway: hermes }\ndefaultAgent: hermes\n", "utf8");
15
15
  const cfg = await loadWorkflowConfig(tempDir);
16
16
  expect(cfg.defaultAgent).toBe("hermes");
17
17
  expect(cfg.agents.hermes).toBeDefined();
18
+ expect(cfg.agents.hermes.host).toBe("http://127.0.0.1:7900");
19
+ expect(cfg.agents.hermes.gateway).toBe("hermes");
18
20
  expect(cfg.agentOverrides).toBeNull();
19
21
  });
20
22
  test("loadWorkflowConfig ignores legacy provider/model fields", async () => {
21
23
  tempDir = mkdtempSync(join(tmpdir(), "uwf-engine-cfg-"));
22
- writeFileSync(join(tempDir, "config.yaml"), "providers:\n openai: { baseUrl: x, apiKey: y }\nmodels:\n default: { provider: openai, name: gpt-4o }\ndefaultModel: default\nagents:\n hermes: { command: uwf-hermes, args: [] }\ndefaultAgent: hermes\n", "utf8");
24
+ writeFileSync(join(tempDir, "config.yaml"), "providers:\n openai: { baseUrl: x, apiKey: y }\nmodels:\n default: { provider: openai, name: gpt-4o }\ndefaultModel: default\nagents:\n hermes: { host: 'http://127.0.0.1:7900', gateway: hermes }\ndefaultAgent: hermes\n", "utf8");
23
25
  const cfg = (await loadWorkflowConfig(tempDir));
24
26
  expect(cfg.defaultAgent).toBe("hermes");
25
27
  expect(cfg.providers).toBeUndefined();
26
28
  expect(cfg.models).toBeUndefined();
27
29
  expect(cfg.defaultModel).toBeUndefined();
28
30
  });
31
+ test("loadWorkflowConfig rejects legacy {command, args} agent shape", async () => {
32
+ tempDir = mkdtempSync(join(tmpdir(), "uwf-engine-cfg-"));
33
+ writeFileSync(join(tempDir, "config.yaml"), "agents:\n hermes: { command: uwf-hermes, args: [] }\ndefaultAgent: hermes\n", "utf8");
34
+ await expect(loadWorkflowConfig(tempDir)).rejects.toThrow(/legacy \{command, args\} fields/);
35
+ });
29
36
  });
30
37
  //# sourceMappingURL=agent-resolution-llm-free.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"agent-resolution-llm-free.test.js","sourceRoot":"","sources":["../../src/__tests__/agent-resolution-llm-free.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7D,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAE3D,QAAQ,CAAC,uEAAuE,EAAE,GAAG,EAAE;IACrF,IAAI,OAAe,CAAC;IACpB,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,OAAO;YAAE,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,6DAA6D,EAAE,KAAK,IAAI,EAAE;QAC7E,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC;QACzD,aAAa,CACX,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,EAC5B,8EAA8E,EAC9E,MAAM,CACP,CAAC;QACF,MAAM,GAAG,GAAG,MAAM,kBAAkB,CAAC,OAAO,CAAC,CAAC;QAC9C,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;QACxC,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,QAAQ,EAAE,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;QACzE,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC;QACzD,aAAa,CACX,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,EAC5B,8MAA8M,EAC9M,MAAM,CACP,CAAC;QACF,MAAM,GAAG,GAAG,CAAC,MAAM,kBAAkB,CAAC,OAAO,CAAC,CAA4B,CAAC;QAC3E,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,aAAa,EAAE,CAAC;QACtC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,aAAa,EAAE,CAAC;QACnC,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,aAAa,EAAE,CAAC;IAC3C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"agent-resolution-llm-free.test.js","sourceRoot":"","sources":["../../src/__tests__/agent-resolution-llm-free.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7D,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAE3D,QAAQ,CAAC,uEAAuE,EAAE,GAAG,EAAE;IACrF,IAAI,OAAe,CAAC;IACpB,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,OAAO;YAAE,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,6DAA6D,EAAE,KAAK,IAAI,EAAE;QAC7E,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC;QACzD,aAAa,CACX,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,EAC5B,+FAA+F,EAC/F,MAAM,CACP,CAAC;QACF,MAAM,GAAG,GAAG,MAAM,kBAAkB,CAAC,OAAO,CAAC,CAAC;QAC9C,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;QACxC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QAC7D,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACjD,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,QAAQ,EAAE,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;QACzE,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC;QACzD,aAAa,CACX,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,EAC5B,+NAA+N,EAC/N,MAAM,CACP,CAAC;QACF,MAAM,GAAG,GAAG,CAAC,MAAM,kBAAkB,CAAC,OAAO,CAAC,CAA4B,CAAC;QAC3E,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,aAAa,EAAE,CAAC;QACtC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,aAAa,EAAE,CAAC;QACnC,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,aAAa,EAAE,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;QAC/E,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC;QACzD,aAAa,CACX,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,EAC5B,8EAA8E,EAC9E,MAAM,CACP,CAAC;QACF,MAAM,MAAM,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,iCAAiC,CAAC,CAAC;IAC/F,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Unit tests for `assembleBrokerPrompt` (#387).
3
+ *
4
+ * Verifies the broker path assembles the same five-part prompt the legacy
5
+ * spawned-agent path produced: output-format instruction, thread progress,
6
+ * role prompt (goal/procedure/output), task prompt, and the
7
+ * continuation/edge-prompt context (branching on first visit vs re-entry).
8
+ */
9
+ export {};
10
+ //# sourceMappingURL=broker-prompt.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"broker-prompt.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/broker-prompt.test.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Unit tests for `assembleBrokerPrompt` (#387).
3
+ *
4
+ * Verifies the broker path assembles the same five-part prompt the legacy
5
+ * spawned-agent path produced: output-format instruction, thread progress,
6
+ * role prompt (goal/procedure/output), task prompt, and the
7
+ * continuation/edge-prompt context (branching on first visit vs re-entry).
8
+ */
9
+ import { describe, expect, test } from "vitest";
10
+ import { assembleBrokerPrompt } from "../commands/broker-step.js";
11
+ const THREAD_ID = "06FCBROKERPROMPTTEST000001";
12
+ const OUTPUT_FORMAT_INSTRUCTION = "## Deliverable Format\n\nemit YAML frontmatter";
13
+ function buildWorkflow() {
14
+ return {
15
+ version: 1,
16
+ name: "review-flow",
17
+ description: "two-role review flow",
18
+ roles: {
19
+ developer: {
20
+ description: "writes code",
21
+ goal: "implement the requested behavior",
22
+ capabilities: ["coding"],
23
+ procedure: "follow the spec and write tests",
24
+ output: "a patch plus a short summary",
25
+ frontmatter: "schema_developer",
26
+ },
27
+ reviewer: {
28
+ description: "reviews code",
29
+ goal: "review the implementation",
30
+ capabilities: [],
31
+ procedure: "check the diff carefully",
32
+ output: "approve or reject",
33
+ frontmatter: "schema_reviewer",
34
+ },
35
+ },
36
+ graph: {},
37
+ };
38
+ }
39
+ function stepContext(role, content, output) {
40
+ return {
41
+ role,
42
+ output,
43
+ detail: "detail_ref",
44
+ agent: "test-agent",
45
+ edgePrompt: "",
46
+ startedAtMs: 0,
47
+ completedAtMs: 1,
48
+ cwd: "",
49
+ assembledPrompt: null,
50
+ usage: null,
51
+ previousAttempts: null,
52
+ content,
53
+ };
54
+ }
55
+ describe("assembleBrokerPrompt", () => {
56
+ test("first visit with no prior steps embeds role prompt, task, and edge prompt", () => {
57
+ const prompt = assembleBrokerPrompt({
58
+ workflow: buildWorkflow(),
59
+ role: "developer",
60
+ threadId: THREAD_ID,
61
+ startPrompt: "Build the login form",
62
+ steps: [],
63
+ edgePrompt: "Implement the behavior defined in the spec files",
64
+ outputFormatInstruction: OUTPUT_FORMAT_INSTRUCTION,
65
+ });
66
+ // 1. output-format instruction
67
+ expect(prompt).toContain("## Deliverable Format");
68
+ // 2. thread progress
69
+ expect(prompt).toContain("## Thread Progress");
70
+ expect(prompt).toContain("This is the first step of the thread");
71
+ // 3. role prompt (goal + procedure + output)
72
+ expect(prompt).toContain("## Goal");
73
+ expect(prompt).toContain("implement the requested behavior");
74
+ expect(prompt).toContain("## Procedure");
75
+ expect(prompt).toContain("follow the spec and write tests");
76
+ expect(prompt).toContain("## Output");
77
+ expect(prompt).toContain("a patch plus a short summary");
78
+ // 4. task prompt
79
+ expect(prompt).toContain("## Task");
80
+ expect(prompt).toContain("Build the login form");
81
+ // 5. edge prompt (no prior steps → "Current Instruction")
82
+ expect(prompt).toContain("## Current Instruction");
83
+ expect(prompt).toContain("Implement the behavior defined in the spec files");
84
+ });
85
+ test("first visit with prior steps includes step content as continuation context", () => {
86
+ const steps = [
87
+ stepContext("planner", "Here is the detailed plan for the feature.", { $status: "done" }),
88
+ ];
89
+ const prompt = assembleBrokerPrompt({
90
+ workflow: buildWorkflow(),
91
+ role: "developer",
92
+ threadId: THREAD_ID,
93
+ startPrompt: "Build the login form",
94
+ steps,
95
+ edgePrompt: "Implement the plan",
96
+ outputFormatInstruction: OUTPUT_FORMAT_INSTRUCTION,
97
+ });
98
+ // Developer has not spoken yet → first visit, prior steps shown WITH content.
99
+ expect(prompt).toContain("## What Happened Since Your Last Turn");
100
+ expect(prompt).toContain("Here is the detailed plan for the feature.");
101
+ expect(prompt).toContain("## Moderator Instruction");
102
+ expect(prompt).toContain("Implement the plan");
103
+ // Thread progress reflects the prior step.
104
+ expect(prompt).toContain("Thread step 2");
105
+ });
106
+ test("re-entry shows only steps since last visit (meta-only continuation)", () => {
107
+ const steps = [
108
+ stepContext("developer", "My first implementation attempt.", { $status: "done" }),
109
+ stepContext("reviewer", "Please fix the validation logic.", { $status: "reject" }),
110
+ ];
111
+ const prompt = assembleBrokerPrompt({
112
+ workflow: buildWorkflow(),
113
+ role: "developer",
114
+ threadId: THREAD_ID,
115
+ startPrompt: "Build the login form",
116
+ steps,
117
+ edgePrompt: "Address the reviewer feedback",
118
+ outputFormatInstruction: OUTPUT_FORMAT_INSTRUCTION,
119
+ });
120
+ // Re-entry: continuation lists the reviewer step since the last developer turn.
121
+ expect(prompt).toContain("## What Happened Since Your Last Turn");
122
+ expect(prompt).toContain("reviewer");
123
+ expect(prompt).toContain("## Moderator Instruction");
124
+ expect(prompt).toContain("Address the reviewer feedback");
125
+ // Meta-only re-entry omits raw step content from before the last visit.
126
+ expect(prompt).not.toContain("My first implementation attempt.");
127
+ });
128
+ });
129
+ //# sourceMappingURL=broker-prompt.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"broker-prompt.test.js","sourceRoot":"","sources":["../../src/__tests__/broker-prompt.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Phase 2 (#398 + #419) — realtime turn persistence in `executeBrokerStep`.
3
+ *
4
+ * Updated for Phase 2 (#419):
5
+ * - Turns are now written with `prev`+`owner` chain instead of accumulating in
6
+ * `@uwf/active-turns/<tid>/<role>` array var
7
+ * - Detail node no longer contains `turns` array — use `turnsOfStep()` to retrieve
8
+ * - Thread-keyed active vars (`@uwf/active-step/<tid>`, `@uwf/active-turn-head/<tid>`)
9
+ *
10
+ * Covers the acceptance steps:
11
+ * Step 1 — broker-step's `onTurn` writes each turn with `prev`+`owner` chain;
12
+ * the turn chain grows 1→2→3.
13
+ * Step 2 — on completion, detail has `turnCount===3` (no `turns` array);
14
+ * turns are accessible via `turnsOfStep()`.
15
+ * Step 3 — a crash-rerun is a fresh attempt: new step-start isolates old turns
16
+ * via different `owner` reference.
17
+ * Step 4 — cross-process visibility: thread-keyed turn head var is observable.
18
+ */
19
+ export {};
20
+ //# sourceMappingURL=broker-step-active-turns.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"broker-step-active-turns.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/broker-step-active-turns.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG"}