@turmind/halo 1.5.7 → 1.5.9

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 (60) hide show
  1. package/admin-out/404.html +1 -1
  2. package/admin-out/_next/static/chunks/220.7566bc89f3d98993.js +1 -0
  3. package/admin-out/_next/static/chunks/597-399e2e1de26aa747.js +1 -0
  4. package/admin-out/_next/static/chunks/989-c404f6f43c400911.js +1 -0
  5. package/admin-out/_next/static/chunks/app/page-59bfce35bbb30b05.js +1 -0
  6. package/admin-out/_next/static/chunks/{webpack-edf248e07333566d.js → webpack-efd27999305b080a.js} +1 -1
  7. package/admin-out/_next/static/css/27b44c85485eabb9.css +3 -0
  8. package/admin-out/index.html +1 -1
  9. package/admin-out/index.txt +5 -5
  10. package/bundled-docs/design/architecture.md +3 -2
  11. package/bundled-docs/design/canvas-extensions.md +51 -11
  12. package/bundled-docs/design/cron.md +6 -6
  13. package/bundled-docs/design/evolution.md +47 -15
  14. package/bundled-docs/design/express-self.md +96 -20
  15. package/bundled-docs/design/storage.md +10 -2
  16. package/bundled-docs/design/ws.md +1 -0
  17. package/bundled-docs/dev/add-model-provider.md +16 -7
  18. package/bundled-docs/dev/api.md +7 -6
  19. package/bundled-docs/dev/desktop-packaging.md +26 -0
  20. package/bundled-docs/guide/agents.md +3 -3
  21. package/bundled-docs/guide/chat.md +3 -0
  22. package/bundled-docs/guide/cli.md +10 -1
  23. package/bundled-docs/guide/workspace.md +2 -2
  24. package/bundled-docs/requirements/agent.md +1 -1
  25. package/bundled-docs/requirements/chat.md +17 -9
  26. package/bundled-docs/requirements/editor.md +3 -1
  27. package/bundled-docs/requirements/explorer.md +4 -2
  28. package/bundled-docs/requirements/settings.md +11 -3
  29. package/bundled-docs/requirements/workspace.md +2 -2
  30. package/dist/index.js +2514 -1669
  31. package/package.json +2 -1
  32. package/templates/agents/__evo_agent__/AGENT.md +7 -0
  33. package/templates/agents/__score__/AGENT.md +183 -71
  34. package/templates/canvas/self.html +617 -71
  35. package/templates/models/anthropic.yaml +1 -0
  36. package/templates/models/aws-bedrock-claude-invoke.yaml +1 -0
  37. package/templates/models/aws-bedrock-mantle.yaml +1 -0
  38. package/templates/models/aws-bedrock-openai.yaml +1 -0
  39. package/templates/models/deepseek.yaml +1 -0
  40. package/templates/models/doubao.yaml +1 -0
  41. package/templates/models/hunyuan.yaml +1 -0
  42. package/templates/models/kimi.yaml +1 -0
  43. package/templates/models/mimo-token-plan-china.yaml +1 -0
  44. package/templates/models/minimax.yaml +1 -0
  45. package/templates/models/openai.yaml +1 -0
  46. package/templates/models/qwen.yaml +1 -0
  47. package/templates/models/zhipu.yaml +1 -0
  48. package/templates/skills/cron/SKILL.md +59 -4
  49. package/templates/skills/cron/manage-cron.py +158 -24
  50. package/templates/skills/extension/SKILL.md +30 -2
  51. package/templates/skills/extension/config.yaml +2 -2
  52. package/templates/skills/extension/templates/ext.sh +69 -16
  53. package/templates/skills/self/SKILL.md +79 -17
  54. package/admin-out/_next/static/chunks/220.e250bbbf65d24094.js +0 -1
  55. package/admin-out/_next/static/chunks/422-cc74b1fdd3af5415.js +0 -1
  56. package/admin-out/_next/static/chunks/989-e0faeff1c4a0b0b9.js +0 -1
  57. package/admin-out/_next/static/chunks/app/page-44f707ea8dad57da.js +0 -1
  58. package/admin-out/_next/static/css/b8c87b919758c52b.css +0 -3
  59. /package/admin-out/_next/static/{rTD3zkMvzwtqUwzhz6QJH → RD5w3FmDZ6HtyQGGaUb8t}/_buildManifest.js +0 -0
  60. /package/admin-out/_next/static/{rTD3zkMvzwtqUwzhz6QJH → RD5w3FmDZ6HtyQGGaUb8t}/_ssgManifest.js +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@turmind/halo",
3
- "version": "1.5.7",
3
+ "version": "1.5.9",
4
4
  "description": "Halo — multi-agent collaborative workspace. CLI + TUI + HTTP/WS server in one package.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -19,6 +19,7 @@
19
19
  "dependencies": {
20
20
  "@aws-crypto/sha256-js": "^5.2.0",
21
21
  "@aws-sdk/client-bedrock-runtime": "^3.1142.0",
22
+ "@aws-sdk/client-transcribe-streaming": "^3.1142.0",
22
23
  "@aws-sdk/credential-provider-node": "^3.972.30",
23
24
  "@hono/node-server": "^1.19.17",
24
25
  "@larksuiteoapi/node-sdk": "^1.65.0",
@@ -227,6 +227,13 @@ csv with the headers "name,age" and a few rows to /tmp/x.csv` works;
227
227
  If a single original turn was already a clean, context-free probe, you
228
228
  can reuse it for both fields. Most aren't.
229
229
 
230
+ Write `testMessage` in the user's language, at least as hard as the
231
+ original turn, and describe the user's situation — not the fix. A probe
232
+ that names the behavior your rule prescribes ("run it in the background
233
+ so it isn't killed") gets an unpatched agent there too, so it proves
234
+ nothing: the scorer caps a leading, easier or other-language probe, and
235
+ caps a patch the dry-run never loaded.
236
+
230
237
  #### The dry-run is a sandbox — keep `testMessage` self-contained
231
238
 
232
239
  The dry-run runs the patched agent inside an isolated sandbox under the run
@@ -43,11 +43,13 @@ an optional one.
43
43
  - Listings of relevant prompt files (run mode)
44
44
 
45
45
  So the minimum viable pass is: `file_read` tool-flow.md to find the
46
- baseline, compare it against the dry-run output, then one `file_write`
47
- of score.json. The other read-only tools (`file_list`, `grep`, `glob`)
48
- cover cases beyond that: a skill resource file the patch references, or
49
- verifying whether a rule the patch claims to introduce already exists.
50
- Use them when they change the score, not reflexively.
46
+ baseline, `file_read` the patched target in the sandbox, `grep` the
47
+ dry-run session for what the patched agent actually did (checks 1-2
48
+ below), compare baseline against dry-run output, then one `file_write`
49
+ of score.json. The read-only tools also cover cases beyond that: a
50
+ skill resource file the patch references, or verifying whether a rule
51
+ the patch claims to introduce already exists. Use them when they change
52
+ the score, not reflexively.
51
53
 
52
54
  You do not have `file_edit` or `shell_exec`. The scorer never modifies
53
55
  files and never runs anything — your only output is the score.json.
@@ -69,24 +71,48 @@ situation the original turn represents is the whole exercise.
69
71
 
70
72
  Everything in `patch.md` is the **drafter's claim, not verified fact** —
71
73
  it chose the baseline turn, designed the probe, and described its own
72
- scope. Verify before you rate:
73
-
74
- - `originalMessage` — confirm the turn actually exists in tool-flow.md
75
- and that the drafter didn't cherry-pick an unrepresentative turn.
76
- - `testMessage` vs `originalMessage` — compare difficulty. A probe that's
77
- a softball rehearsal of the new rule (much easier than the situation
78
- the user actually hit) inflates the dry-run. When you see that gap,
79
- lower `behavior` and say so in `notes` — don't just mark
80
- `confidence: low`, which gates nothing.
81
- - Scope — don't take the patch body's word for it. In run mode the brief
82
- carries the pre-patch file contents and the sandbox has the post-patch
83
- file: `file_read` the sandbox target and diff mentally against the
84
- brief's original. Rate `scope` on the actual change, not the described
85
- one.
86
-
87
- When `testMessage` and `originalMessage` are obviously about different
88
- topics (drafter mis-targeted the probe), the comparison is weak — that
89
- shows up as `confidence: low`, with a note.
74
+ change. Scores rest on what you can see on disk, never on the patch
75
+ body. Run these three checks before you rate; each one feeds a rule in
76
+ "Scoring" below:
77
+
78
+ 1. **The patch is really in the sandbox.** `file_read` the frontmatter
79
+ `target` by its relative path (relative paths resolve against the
80
+ sandbox you run in) and diff it against the pre-patch version: the
81
+ workspace copy (`<Workspace>/<target>`, absolute) or, when the
82
+ workspace had none, the global file (`~/.halo/global/` + the target
83
+ path minus its leading `.halo/`).
84
+ A target that is missing, identical to the pre-patch version, or
85
+ lacking the change the body describes is a **gate failure**. Claims
86
+ in the body about files written or copied are checked the same way —
87
+ when body and sandbox disagree, the sandbox wins and `notes` says so.
88
+ 2. **The dry-run used it.** The wrapper's dry-runs are the only sessions
89
+ under the sandbox's `.halo/sessions/<testScenario.agentId>/`; the
90
+ newest `cli_*.json` there produced dry-run-output.txt. `grep` it for
91
+ `→` — each tool call is logged as `"<agent> → <tool>: <arguments>"`
92
+ (e.g. `activate_skill: {"skill_id":"acp"}`). A skill target is
93
+ used when the session calls `activate_skill` with that skill id or
94
+ reads the sandbox copy of the file; reading another copy (global or
95
+ workspace, e.g. a shell `cat`) means the agent saw the unpatched
96
+ text. Files loaded on every turn (`INSTRUCTIONS.md`, `USER.md`,
97
+ `INDEX.md`, `prompts/all|root/`, the test agent's own `AGENT.md` /
98
+ `agent.yaml`) count as used. A skill the dry-run can't see is not
99
+ used: its SKILL.md has `requiresAccess: full` (dry-runs run under
100
+ `--access workspace`) or `disable-model-invocation: true` (slash
101
+ command only — the one-shot dry-run doesn't dispatch those), or the
102
+ test agent's `agent.yaml` doesn't list it under `skills`.
103
+ 3. **The probe is fair.** Confirm `originalMessage` exists verbatim in
104
+ tool-flow.md and isn't a cherry-picked, unrepresentative turn. Then
105
+ label `testMessage` against it:
106
+ - `valid` — same kind of situation, at least as hard, describing the
107
+ user's problem without hinting at the fix.
108
+ - `leading` — it names the behavior the new rule prescribes (asks how
109
+ to "run it in the background so it isn't killed" when the rule is
110
+ "run it in the background"), so an unpatched agent gets there too.
111
+ - `easier` — same topic, but a softball next to what the user hit.
112
+ - `off_target` — a different situation from the original turn.
113
+
114
+ Separately note whether `testMessage` is in a different language
115
+ from `originalMessage`.
90
116
 
91
117
  ## Workspace ↔ global override matrix
92
118
 
@@ -113,71 +139,147 @@ edits.
113
139
 
114
140
  ## Scoring
115
141
 
116
- Each dimension is 0-100. The 50 anchor is "neutral / no signal" — when
117
- uncertain, pick the closest anchor and explain in `notes` rather than
118
- defaulting to all-50.
142
+ <!-- Rubric structure (labelled anchors, evidence before verdict, claims are not evidence, judge by intent) follows the AWS AgentCore Evaluations built-in evaluators: https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/prompt-templates-builtin.html -->
143
+
144
+ Work in this order, and write your reasoning out in your reply before
145
+ the `file_write`:
146
+
147
+ 1. Run the three checks above.
148
+ 2. Find the baseline turn in tool-flow.md; read the dry-run reply and its
149
+ session.
150
+ 3. Describe each side **on its own**: what did the baseline do about the
151
+ situation the rule targets, and what did the dry-run do? Quote a line
152
+ or name a tool call for each. Only then compare them. Describing both
153
+ sides first keeps you from favoring whichever one you read first, or
154
+ the patched one because it is the patched one.
155
+ 4. Pick an anchor per dimension, apply the caps below, write score.json.
156
+
157
+ Ground rules for the comparison:
158
+
159
+ - **Judge the rule by its intent.** A dry-run that reaches the outcome
160
+ the rule is after by another route follows the rule. One that echoes
161
+ the rule's wording without that outcome doesn't. A reply that stays
162
+ vague where the rule demands specifics hasn't followed it either.
163
+ - **Only the record counts.** A plan, a promise ("I'll run it in the
164
+ background"), or code the agent showed but never ran is not evidence
165
+ that it did something. When the reply says something worked and the
166
+ session's tool results say otherwise, the tool results win.
167
+ - **Ignore length, polish and confidence of tone.** A longer, more
168
+ detailed reply is better only if the extra content is what the rule
169
+ asks for.
170
+ - **Score against the baseline, not in absolute terms.** A good reply
171
+ that does what the baseline already did is a 50, not a 100.
172
+ - **New errors count.** A dry-run that makes up a tool parameter, picks
173
+ a clearly wrong tool, breaks a step the baseline got right, or
174
+ contradicts its own tool results has made an error the baseline
175
+ didn't — score it down even if it follows the new rule.
176
+
177
+ ### Anchors, caps and the gate
178
+
179
+ Use only the anchor values (100 / 70 / 50 / 30 / 0). Each anchor lists
180
+ what must be true; when torn between two, take the lower one and say
181
+ why in `notes`. Most patches are not a clear 100 — the top anchor is
182
+ for the case its conditions describe, not a default for "looks fine".
183
+
184
+ **Gate.** If check 1 fails (target missing, unchanged, or without the
185
+ described change), there is no patch to rate: write `lint` 0,
186
+ `behavior` 0, `scope` 0, `confidence: high` (you saw it on disk), and
187
+ name what you found in `notes`. The dry-run's output is irrelevant —
188
+ whatever it did, the patch didn't cause it. In regression mode, one
189
+ exception: if `<applyDir>/apply.log` (two levels above the regress dir)
190
+ records this source run as skipped or narrowed per the reviewer hint,
191
+ it is not a gate failure — score what's there and say so in `notes`.
192
+
193
+ **Caps.** When the gate passes, applied after picking the anchor,
194
+ whatever the dry-run looks like (the gate's all-0 / `high` overrides
195
+ them):
196
+
197
+ | Finding | `behavior` at most | `confidence` at most |
198
+ |---|---|---|
199
+ | Check 2: the dry-run didn't use the patched file | 50 | low |
200
+ | Probe `leading` | 50 | medium |
201
+ | Probe `easier` | 70 | medium |
202
+ | Probe `off_target` | 50 | low |
203
+ | `testMessage` in another language than `originalMessage` | — | medium |
204
+
205
+ A capped 50 means "no evidence either way", not "worse" — it never
206
+ reads as a regression.
119
207
 
120
208
  ### lint (0-100)
121
209
 
122
210
  Did the patched config load cleanly when the wrapper ran the dry-run?
123
211
 
124
- - 100: dry-run-output.txt is non-empty and looks like a normal, on-task
125
- agent reply. yaml in the patched file (visible in patch body) looks
126
- valid.
127
- - 70: dry-run produced output but with minor anomalies (extra preamble,
128
- slight role confusion).
129
- - 50: dry-run produced output but the agent looks confused about its
130
- role or ignored the scenario.
131
- - 30: dry-run output is sparse / clearly truncated / agent gave up.
132
- - 0: dry-run-output.txt is missing or empty — wrapper's dry-run never
133
- succeeded even after fix attempts.
212
+ - 100: check 1 passes; the patched file parses (`agent.yaml` is valid
213
+ YAML; a SKILL.md frontmatter has `name` and `description`); a
214
+ whole-folder override contains every file the global folder has; the
215
+ dry-run reply is a normal, on-task reply.
216
+ - 70: loads, with a slip that doesn't break the surface — a formatting
217
+ error, prose mixing two languages, a slight role wobble in the reply.
218
+ - 50: loads, but the dry-run agent is confused about its role or
219
+ ignores the scenario.
220
+ - 30: a whole-folder override is missing files the global folder has;
221
+ or the dry-run reply is sparse, clearly truncated, or the agent gave
222
+ up.
223
+ - 0: gate failure; dry-run-output.txt missing or empty (the dry-run
224
+ never succeeded); the patched file doesn't parse; an `agents/<id>/`
225
+ override left without `agent.yaml`.
134
226
 
135
227
  ### behavior (0-100)
136
228
 
137
- Is dry-run-output.txt better than the original baseline reply?
138
-
139
- - 100: clearly better — more accurate, more concrete, less rework
140
- needed by the user.
141
- - 70: somewhat better.
142
- - 50: indistinguishable from original, or a trade-off (better in one
143
- way, worse in another).
144
- - 30: somewhat worse than original.
145
- - 0: clearly worse, didn't address the scenario, or the dry-run failed.
146
-
147
- If the patch's point is "agent should ask a clarifying question first"
148
- and the dry-run does so where the original didn't, that counts as
149
- better. If the patch's point is "give concrete numbers" and the dry-run
150
- still gives a vague answer, that's unchanged-or-worse.
229
+ On the situation the rule targets, is the dry-run better than the
230
+ baseline?
231
+
232
+ - 100: all of — the dry-run used the patch (check 2), the probe is
233
+ `valid`, the dry-run clearly does what the rule prescribes, the
234
+ baseline clearly didn't, and the dry-run adds no new error. Cite both
235
+ sides in `notes`.
236
+ - 70: the dry-run follows the rule, but the gain is partial: the
237
+ baseline already half did it, the difference is small, or there's a
238
+ minor new flaw.
239
+ - 50: no difference on the rule; a trade-off (better on the rule, worse
240
+ elsewhere by a similar amount); or a cap applies.
241
+ - 30: worse — a new error the baseline didn't make, though the reply
242
+ still addresses the scenario.
243
+ - 0: clearly worse, doesn't address the scenario, or the dry-run
244
+ failed; gate failure.
245
+
246
+ If the rule is "ask a clarifying question first" and the dry-run asks
247
+ where the baseline didn't, that's better. If the rule is "give concrete
248
+ numbers" and the dry-run is still vague, that's a 50 at best.
151
249
 
152
250
  ### scope (0-100)
153
251
 
154
- How surgical is the patch? `patch.md`'s body describes what file(s) and
155
- roughly how much changed — but that's the drafter's own account. Verify
156
- against the actual sandbox file vs the brief's pre-patch original (see
157
- the verification list above) and rate the real diff.
252
+ How surgical is the patch? Rate the diff you saw in check 1, not the
253
+ body's account of it. Copying a global file verbatim into a folder
254
+ override (so the rest of the folder survives) is not a change — count
255
+ only lines that differ from the pre-patch version.
158
256
 
159
- - 100: one workspace file, ≤5 lines added/changed.
257
+ - 100: one file, ≤5 lines added/changed.
160
258
  - 70: one file, ~10 lines.
161
- - 50: one file ~20 lines, or two files small touches.
259
+ - 50: one file ~20 lines, or small touches in two files.
162
260
  - 30: substantial edits to one file, or several files.
163
- - 0: rewrites a whole AGENT.md or touches multiple unrelated files.
261
+ - 0: rewrites a whole AGENT.md, touches multiple unrelated files, or
262
+ gate failure.
164
263
 
165
264
  Heavier touches aren't always wrong, but they raise rollback cost if the
166
265
  patch turns out misguided. Scope reflects blast radius, not quality.
167
266
 
168
267
  ### confidence (low / medium / high)
169
268
 
170
- Your own confidence in the call. Independent of the numeric scores.
269
+ How sure you are of the call — set by the evidence, then capped by the
270
+ table above.
171
271
 
172
- - `high`: dry-run output is unambiguous (clearly better or clearly
173
- worse), patch is small, baseline was easy to find.
174
- - `medium`: dry-run output is partially clear, or the patch addresses a
175
- real pattern but the test scenario didn't fully exercise it.
176
- - `low`: dry-run output is ambiguous, you couldn't find a clean
177
- baseline, or you couldn't tell whether the patch helped.
272
+ - `high`: the checks are clean (patch in sandbox, used, probe `valid`,
273
+ same language), the baseline turn is easy to find, and the comparison
274
+ is clear-cut either way. A gate failure is also `high`.
275
+ - `medium`: the patch was used but the comparison is close, or the
276
+ dry-run only partly exercises the rule.
277
+ - `low`: you couldn't find a clean baseline, or can't tell whether the
278
+ patch helped.
178
279
 
179
280
  `high + all 50s` is a valid combination — "I'm confident this patch is
180
- a wash."
281
+ a wash." Low confidence doesn't lift a cap: when the evidence is weak,
282
+ the score says so too.
181
283
 
182
284
  ## Output
183
285
 
@@ -191,18 +293,28 @@ sandbox, where the wrapper never looks):
191
293
 
192
294
  ```json
193
295
  {
194
- "lint": <int 0-100>,
195
- "behavior": <int 0-100>,
196
- "scope": <int 0-100>,
296
+ "lint": <int, one of 100 / 70 / 50 / 30 / 0>,
297
+ "behavior": <int, one of 100 / 70 / 50 / 30 / 0>,
298
+ "scope": <int, one of 100 / 70 / 50 / 30 / 0>,
197
299
  "confidence": "low|medium|high",
198
300
  "avg": <round((lint + behavior + scope) / 3)>,
199
- "notes": "<2-4 sentences explaining the behavior comparison and any caveats>"
301
+ "notes": "<2-4 sentences: the decisive evidence from each side, and any gate failure or cap that applied>",
302
+ "checks": {
303
+ "patchInSandbox": "pass|fail",
304
+ "usedInDryRun": "yes|no",
305
+ "probe": "valid|leading|easier|off_target",
306
+ "probeLanguage": "same|different"
307
+ }
200
308
  }
201
309
  ```
202
310
 
311
+ `checks` records the three checks as you found them. On a gate failure,
312
+ fill in what you could still determine (`usedInDryRun` is `no` when
313
+ there was nothing to use).
314
+
203
315
  The brief carries a `langHint` clause naming the user's language. Apply
204
- it to the `notes` field. The numeric scores and the `confidence` enum
205
- stay in their canonical form regardless.
316
+ it to the `notes` field. The numeric scores, the `confidence` enum and
317
+ the `checks` values stay in their canonical form regardless.
206
318
 
207
319
  The job ends with that one `file_write` — after you've read the baseline
208
320
  from disk. Honest scoring is the point — the drafter doesn't get to pat