@zhixuan92/multi-model-agent 5.0.1 → 5.0.3
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.
- package/README.md +8 -9
- package/dist/cli/index.d.ts +62 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +345 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/info.d.ts +22 -0
- package/dist/cli/info.d.ts.map +1 -0
- package/dist/cli/info.js +100 -0
- package/dist/cli/info.js.map +1 -0
- package/dist/cli/logs.d.ts +15 -0
- package/dist/cli/logs.d.ts.map +1 -0
- package/dist/cli/logs.js +102 -0
- package/dist/cli/logs.js.map +1 -0
- package/dist/cli/print-token.d.ts +18 -0
- package/dist/cli/print-token.d.ts.map +1 -0
- package/dist/cli/print-token.js +60 -0
- package/dist/cli/print-token.js.map +1 -0
- package/dist/cli/serve.d.ts +28 -0
- package/dist/cli/serve.d.ts.map +1 -0
- package/dist/cli/serve.js +405 -0
- package/dist/cli/serve.js.map +1 -0
- package/dist/cli/status.d.ts +49 -0
- package/dist/cli/status.d.ts.map +1 -0
- package/dist/cli/status.js +155 -0
- package/dist/cli/status.js.map +1 -0
- package/dist/cli/sync-skills.d.ts +58 -0
- package/dist/cli/sync-skills.d.ts.map +1 -0
- package/dist/cli/sync-skills.js +266 -0
- package/dist/cli/sync-skills.js.map +1 -0
- package/dist/cli/telemetry.d.ts +10 -0
- package/dist/cli/telemetry.d.ts.map +1 -0
- package/dist/cli/telemetry.js +161 -0
- package/dist/cli/telemetry.js.map +1 -0
- package/dist/cli/toggle.d.ts +26 -0
- package/dist/cli/toggle.d.ts.map +1 -0
- package/dist/cli/toggle.js +185 -0
- package/dist/cli/toggle.js.map +1 -0
- package/dist/http/async-dispatch.d.ts +44 -0
- package/dist/http/async-dispatch.d.ts.map +1 -0
- package/dist/http/async-dispatch.js +175 -0
- package/dist/http/async-dispatch.js.map +1 -0
- package/dist/http/auth.d.ts +20 -0
- package/dist/http/auth.d.ts.map +1 -0
- package/dist/http/auth.js +56 -0
- package/dist/http/auth.js.map +1 -0
- package/dist/http/canonicalize-file-paths.d.ts +8 -0
- package/dist/http/canonicalize-file-paths.d.ts.map +1 -0
- package/dist/http/canonicalize-file-paths.js +43 -0
- package/dist/http/canonicalize-file-paths.js.map +1 -0
- package/dist/http/cwd-validator.d.ts +11 -0
- package/dist/http/cwd-validator.d.ts.map +1 -0
- package/dist/http/cwd-validator.js +130 -0
- package/dist/http/cwd-validator.js.map +1 -0
- package/dist/http/errors.d.ts +4 -0
- package/dist/http/errors.d.ts.map +1 -0
- package/dist/http/errors.js +9 -0
- package/dist/http/errors.js.map +1 -0
- package/dist/http/execution-context.d.ts +18 -0
- package/dist/http/execution-context.d.ts.map +1 -0
- package/dist/http/execution-context.js +61 -0
- package/dist/http/execution-context.js.map +1 -0
- package/dist/http/handler-deps.d.ts +19 -0
- package/dist/http/handler-deps.d.ts.map +1 -0
- package/dist/http/handler-deps.js +2 -0
- package/dist/http/handler-deps.js.map +1 -0
- package/dist/http/handlers/control/batch-slice.d.ts +4 -0
- package/dist/http/handlers/control/batch-slice.d.ts.map +1 -0
- package/dist/http/handlers/control/batch-slice.js +40 -0
- package/dist/http/handlers/control/batch-slice.js.map +1 -0
- package/dist/http/handlers/control/batch.d.ts +23 -0
- package/dist/http/handlers/control/batch.d.ts.map +1 -0
- package/dist/http/handlers/control/batch.js +332 -0
- package/dist/http/handlers/control/batch.js.map +1 -0
- package/dist/http/handlers/control/context-blocks.d.ts +22 -0
- package/dist/http/handlers/control/context-blocks.d.ts.map +1 -0
- package/dist/http/handlers/control/context-blocks.js +111 -0
- package/dist/http/handlers/control/context-blocks.js.map +1 -0
- package/dist/http/handlers/introspection/health.d.ts +20 -0
- package/dist/http/handlers/introspection/health.d.ts.map +1 -0
- package/dist/http/handlers/introspection/health.js +18 -0
- package/dist/http/handlers/introspection/health.js.map +1 -0
- package/dist/http/handlers/introspection/status.d.ts +26 -0
- package/dist/http/handlers/introspection/status.d.ts.map +1 -0
- package/dist/http/handlers/introspection/status.js +136 -0
- package/dist/http/handlers/introspection/status.js.map +1 -0
- package/dist/http/handlers/tools/audit.d.ts +4 -0
- package/dist/http/handlers/tools/audit.d.ts.map +1 -0
- package/dist/http/handlers/tools/audit.js +43 -0
- package/dist/http/handlers/tools/audit.js.map +1 -0
- package/dist/http/handlers/tools/debug.d.ts +4 -0
- package/dist/http/handlers/tools/debug.d.ts.map +1 -0
- package/dist/http/handlers/tools/debug.js +43 -0
- package/dist/http/handlers/tools/debug.js.map +1 -0
- package/dist/http/handlers/tools/delegate.d.ts +4 -0
- package/dist/http/handlers/tools/delegate.d.ts.map +1 -0
- package/dist/http/handlers/tools/delegate.js +43 -0
- package/dist/http/handlers/tools/delegate.js.map +1 -0
- package/dist/http/handlers/tools/execute-plan.d.ts +4 -0
- package/dist/http/handlers/tools/execute-plan.d.ts.map +1 -0
- package/dist/http/handlers/tools/execute-plan.js +45 -0
- package/dist/http/handlers/tools/execute-plan.js.map +1 -0
- package/dist/http/handlers/tools/investigate.d.ts +4 -0
- package/dist/http/handlers/tools/investigate.d.ts.map +1 -0
- package/dist/http/handlers/tools/investigate.js +64 -0
- package/dist/http/handlers/tools/investigate.js.map +1 -0
- package/dist/http/handlers/tools/journal-recall.d.ts +4 -0
- package/dist/http/handlers/tools/journal-recall.d.ts.map +1 -0
- package/dist/http/handlers/tools/journal-recall.js +40 -0
- package/dist/http/handlers/tools/journal-recall.js.map +1 -0
- package/dist/http/handlers/tools/journal-record.d.ts +8 -0
- package/dist/http/handlers/tools/journal-record.d.ts.map +1 -0
- package/dist/http/handlers/tools/journal-record.js +40 -0
- package/dist/http/handlers/tools/journal-record.js.map +1 -0
- package/dist/http/handlers/tools/research.d.ts +4 -0
- package/dist/http/handlers/tools/research.d.ts.map +1 -0
- package/dist/http/handlers/tools/research.js +64 -0
- package/dist/http/handlers/tools/research.js.map +1 -0
- package/dist/http/handlers/tools/retry.d.ts +4 -0
- package/dist/http/handlers/tools/retry.d.ts.map +1 -0
- package/dist/http/handlers/tools/retry.js +73 -0
- package/dist/http/handlers/tools/retry.js.map +1 -0
- package/dist/http/handlers/tools/review.d.ts +4 -0
- package/dist/http/handlers/tools/review.d.ts.map +1 -0
- package/dist/http/handlers/tools/review.js +43 -0
- package/dist/http/handlers/tools/review.js.map +1 -0
- package/dist/http/journal-lock.d.ts +4 -0
- package/dist/http/journal-lock.d.ts.map +1 -0
- package/dist/http/journal-lock.js +34 -0
- package/dist/http/journal-lock.js.map +1 -0
- package/dist/http/middleware/body-reader.d.ts +16 -0
- package/dist/http/middleware/body-reader.d.ts.map +1 -0
- package/dist/http/middleware/body-reader.js +44 -0
- package/dist/http/middleware/body-reader.js.map +1 -0
- package/dist/http/middleware/caller-identity.d.ts +16 -0
- package/dist/http/middleware/caller-identity.d.ts.map +1 -0
- package/dist/http/middleware/caller-identity.js +16 -0
- package/dist/http/middleware/caller-identity.js.map +1 -0
- package/dist/http/middleware/decompress.d.ts +14 -0
- package/dist/http/middleware/decompress.d.ts.map +1 -0
- package/dist/http/middleware/decompress.js +51 -0
- package/dist/http/middleware/decompress.js.map +1 -0
- package/dist/http/project-registry.d.ts +54 -0
- package/dist/http/project-registry.d.ts.map +1 -0
- package/dist/http/project-registry.js +130 -0
- package/dist/http/project-registry.js.map +1 -0
- package/dist/http/request-observability.d.ts +8 -0
- package/dist/http/request-observability.d.ts.map +1 -0
- package/dist/http/request-observability.js +20 -0
- package/dist/http/request-observability.js.map +1 -0
- package/dist/http/request-pipeline.d.ts +16 -0
- package/dist/http/request-pipeline.d.ts.map +1 -0
- package/dist/http/request-pipeline.js +144 -0
- package/dist/http/request-pipeline.js.map +1 -0
- package/dist/http/server.d.ts +17 -0
- package/dist/http/server.d.ts.map +1 -0
- package/dist/http/server.js +300 -0
- package/dist/http/server.js.map +1 -0
- package/dist/http/types.d.ts +20 -0
- package/dist/http/types.d.ts.map +1 -0
- package/dist/http/types.js +2 -0
- package/dist/http/types.js.map +1 -0
- package/dist/skill-install/disabled-state.d.ts +35 -0
- package/dist/skill-install/disabled-state.d.ts.map +1 -0
- package/dist/skill-install/disabled-state.js +96 -0
- package/dist/skill-install/disabled-state.js.map +1 -0
- package/dist/skill-install/discover.d.ts +29 -0
- package/dist/skill-install/discover.d.ts.map +1 -0
- package/dist/skill-install/discover.js +104 -0
- package/dist/skill-install/discover.js.map +1 -0
- package/dist/skill-install/include-utils.d.ts +27 -0
- package/dist/skill-install/include-utils.d.ts.map +1 -0
- package/dist/skill-install/include-utils.js +90 -0
- package/dist/skill-install/include-utils.js.map +1 -0
- package/dist/skill-install/manifest.d.ts +82 -0
- package/dist/skill-install/manifest.d.ts.map +1 -0
- package/dist/skill-install/manifest.js +215 -0
- package/dist/skill-install/manifest.js.map +1 -0
- package/dist/skill-install/skill-installer-common.d.ts +26 -0
- package/dist/skill-install/skill-installer-common.d.ts.map +1 -0
- package/dist/skill-install/skill-installer-common.js +139 -0
- package/dist/skill-install/skill-installer-common.js.map +1 -0
- package/dist/skill-install/skill-installers/claude-code.d.ts +43 -0
- package/dist/skill-install/skill-installers/claude-code.d.ts.map +1 -0
- package/dist/skill-install/skill-installers/claude-code.js +65 -0
- package/dist/skill-install/skill-installers/claude-code.js.map +1 -0
- package/dist/skill-install/skill-installers/codex-cli.d.ts +27 -0
- package/dist/skill-install/skill-installers/codex-cli.d.ts.map +1 -0
- package/dist/skill-install/skill-installers/codex-cli.js +84 -0
- package/dist/skill-install/skill-installers/codex-cli.js.map +1 -0
- package/dist/skill-install/skill-installers/cursor.d.ts +72 -0
- package/dist/skill-install/skill-installers/cursor.d.ts.map +1 -0
- package/dist/skill-install/skill-installers/cursor.js +81 -0
- package/dist/skill-install/skill-installers/cursor.js.map +1 -0
- package/dist/skill-install/skill-installers/gemini-cli.d.ts +50 -0
- package/dist/skill-install/skill-installers/gemini-cli.d.ts.map +1 -0
- package/dist/skill-install/skill-installers/gemini-cli.js +72 -0
- package/dist/skill-install/skill-installers/gemini-cli.js.map +1 -0
- package/dist/skill-install/skill-manifest-sync.d.ts +11 -0
- package/dist/skill-install/skill-manifest-sync.d.ts.map +1 -0
- package/dist/skill-install/skill-manifest-sync.js +65 -0
- package/dist/skill-install/skill-manifest-sync.js.map +1 -0
- package/dist/skills/_shared/auth.md +41 -0
- package/dist/skills/_shared/error-handling.md +31 -0
- package/dist/skills/_shared/polling.md +88 -0
- package/dist/skills/_shared/response-shape.md +55 -0
- package/dist/skills/_shared/review-policy.md +15 -0
- package/dist/skills/mma-audit/SKILL.md +270 -0
- package/dist/skills/mma-context-blocks/SKILL.md +148 -0
- package/dist/skills/mma-debug/SKILL.md +208 -0
- package/dist/skills/mma-delegate/SKILL.md +216 -0
- package/dist/skills/mma-execute-plan/SKILL.md +214 -0
- package/dist/skills/mma-explore/SKILL.md +190 -0
- package/dist/skills/mma-investigate/SKILL.md +258 -0
- package/dist/skills/mma-journal-recall/SKILL.md +242 -0
- package/dist/skills/mma-journal-record/SKILL.md +202 -0
- package/dist/skills/mma-research/SKILL.md +223 -0
- package/dist/skills/mma-retry/SKILL.md +221 -0
- package/dist/skills/mma-review/SKILL.md +209 -0
- package/dist/skills/multi-model-agent/SKILL.md +206 -0
- package/dist/telemetry/consent.d.ts +4 -0
- package/dist/telemetry/consent.d.ts.map +1 -0
- package/dist/telemetry/consent.js +40 -0
- package/dist/telemetry/consent.js.map +1 -0
- package/dist/telemetry/flusher.d.ts +19 -0
- package/dist/telemetry/flusher.d.ts.map +1 -0
- package/dist/telemetry/flusher.js +277 -0
- package/dist/telemetry/flusher.js.map +1 -0
- package/dist/telemetry/generation.d.ts +9 -0
- package/dist/telemetry/generation.d.ts.map +1 -0
- package/dist/telemetry/generation.js +33 -0
- package/dist/telemetry/generation.js.map +1 -0
- package/dist/telemetry/identity.d.ts +9 -0
- package/dist/telemetry/identity.d.ts.map +1 -0
- package/dist/telemetry/identity.js +35 -0
- package/dist/telemetry/identity.js.map +1 -0
- package/dist/telemetry/install-id.d.ts +13 -0
- package/dist/telemetry/install-id.d.ts.map +1 -0
- package/dist/telemetry/install-id.js +49 -0
- package/dist/telemetry/install-id.js.map +1 -0
- package/dist/telemetry/install-meta.d.ts +10 -0
- package/dist/telemetry/install-meta.d.ts.map +1 -0
- package/dist/telemetry/install-meta.js +15 -0
- package/dist/telemetry/install-meta.js.map +1 -0
- package/dist/telemetry/queue.d.ts +35 -0
- package/dist/telemetry/queue.d.ts.map +1 -0
- package/dist/telemetry/queue.js +287 -0
- package/dist/telemetry/queue.js.map +1 -0
- package/dist/telemetry/recorder.d.ts +39 -0
- package/dist/telemetry/recorder.d.ts.map +1 -0
- package/dist/telemetry/recorder.js +173 -0
- package/dist/telemetry/recorder.js.map +1 -0
- package/package.json +43 -24
- package/scripts/postinstall.js +36 -0
- package/bin/mmagent.mjs +0 -47
- package/postinstall.mjs +0 -8
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mma-journal-recall
|
|
3
|
+
description: >-
|
|
4
|
+
Use when you're about to design or attempt something and want to know what
|
|
5
|
+
THIS project already learned — ask a vague conceptual question (no tags or
|
|
6
|
+
keywords needed); a read-only worker searches the learnings graph and returns
|
|
7
|
+
the relevant prior lessons + how they relate. Fire before re-treading ground
|
|
8
|
+
that may already have been explored. NOT for recording a new learning
|
|
9
|
+
(mma-journal-record), codebase questions (mma-investigate), or external
|
|
10
|
+
research (mma-research).
|
|
11
|
+
when_to_use: >-
|
|
12
|
+
A question about THIS project's learnings, before attempting or designing
|
|
13
|
+
something — ask a vague conceptual question; skip if recording a new learning,
|
|
14
|
+
asking the codebase, or researching external docs.
|
|
15
|
+
version: 5.0.3
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# mma-journal-recall
|
|
19
|
+
|
|
20
|
+
## Overview
|
|
21
|
+
|
|
22
|
+
Recall relevant project learnings from the journal via a read-only mmagent worker. The worker reads the learnings graph at `.mmagent/journal/` and synthesizes answers to vague conceptual queries.
|
|
23
|
+
|
|
24
|
+
**Core principle:** Recall is retrieval (read, traverse graph, synthesize). Delegate it. The main agent stays on using the results — deciding what to do with the prior lessons.
|
|
25
|
+
|
|
26
|
+
## When to Use
|
|
27
|
+
|
|
28
|
+
**Use when:**
|
|
29
|
+
- Before attempting something, ask "what have we learned about this?".
|
|
30
|
+
- The query is a conceptual question ("dispatch cancellation reliability?", "rate-limiting patterns?"), not exact tags or keywords.
|
|
31
|
+
- You want prior learnings + their relationships, not isolated chunks.
|
|
32
|
+
- The project has an active journal (started with `mma-journal-record`).
|
|
33
|
+
|
|
34
|
+
**Don't use when:**
|
|
35
|
+
- You're recording a new learning → `mma-journal-record` (write route).
|
|
36
|
+
- You're asking about the codebase structure → `mma-investigate` (read codebase).
|
|
37
|
+
- You're researching external docs/web → `mma-research` / `WebSearch`.
|
|
38
|
+
- The journal is empty or not yet initialized.
|
|
39
|
+
|
|
40
|
+
## Endpoint
|
|
41
|
+
|
|
42
|
+
`POST /journal-recall?cwd=<abs-path>`
|
|
43
|
+
|
|
44
|
+
@include _shared/auth.md
|
|
45
|
+
|
|
46
|
+
## Request body
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"query": "what have we learned about dispatch cancellation reliability?",
|
|
51
|
+
"contextBlockIds": []
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
| Field | Type | Required | Notes |
|
|
56
|
+
|---|---|---|---|
|
|
57
|
+
| `query` | string | yes | A vague conceptual question about prior learnings. No tags or keywords needed. |
|
|
58
|
+
| `contextBlockIds` | string[] | no | IDs from `mma-context-blocks` — enables follow-up / delta recall |
|
|
59
|
+
| `tools` | `'none' \| 'readonly'` | no | Default `'readonly'`. `'full'` and `'no-shell'` are rejected — recall is read-only |
|
|
60
|
+
|
|
61
|
+
> Worker tier for `mma-journal-recall` is hardcoded to `complex` and is not caller-configurable. Sending `agentType` is rejected with HTTP 400.
|
|
62
|
+
|
|
63
|
+
**Why `query` is vague, not keyword-filtered:**
|
|
64
|
+
|
|
65
|
+
❌ `{ "query": "dispatch" }` — too narrow, might miss "cancellation reliability" nodes that don't mention the word "dispatch" in title.
|
|
66
|
+
✅ `{ "query": "what have we learned about dispatch cancellation reliability?" }` — the worker understands the concept and finds related nodes.
|
|
67
|
+
|
|
68
|
+
**Why:** the worker traverses the journal's typed graph (supersedes, refines, contradicts, depends-on) and synthesizes across related nodes. Semantic matching is the LLM's job, just like `mma-investigate`.
|
|
69
|
+
|
|
70
|
+
## Full example
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
BATCH=$(curl -f --show-error -s -X POST \
|
|
74
|
+
-H "X-MMA-Client: $MMA_CLIENT" \
|
|
75
|
+
-H "X-MMA-Main-Model: $MMA_MAIN_MODEL" \
|
|
76
|
+
-H "Authorization: Bearer $TOKEN" \
|
|
77
|
+
-H "Content-Type: application/json" \
|
|
78
|
+
-d '{"query":"what have we learned about dispatch cancellation reliability?"}' \
|
|
79
|
+
"http://localhost:$PORT/journal-recall?cwd=/project")
|
|
80
|
+
BATCH_ID=$(echo "$BATCH" | jq -r '.batchId')
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
@include _shared/polling.md
|
|
84
|
+
|
|
85
|
+
@include _shared/response-shape.md
|
|
86
|
+
|
|
87
|
+
## Per-task report shape
|
|
88
|
+
|
|
89
|
+
Each task carries a `investigation` field on its per-task report (same shape as `mma-investigate`):
|
|
90
|
+
|
|
91
|
+
```json
|
|
92
|
+
{
|
|
93
|
+
"investigation": {
|
|
94
|
+
"citations": [
|
|
95
|
+
{ "file": "nodes/0012-dispatch-cancellation-lifecycle.md", "lines": "1-50", "claim": "Cancellation handlers must check context before writing." }
|
|
96
|
+
],
|
|
97
|
+
"confidence": { "level": "high", "rationale": "Direct citations from journal nodes." },
|
|
98
|
+
"diagnostics": {
|
|
99
|
+
"malformedCitationLines": 0,
|
|
100
|
+
"missingRequiredSections": [],
|
|
101
|
+
"invalidRequiredSections": []
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
The authoritative success signals are `completed`, `message`, and `findings`. See "v5 wire shape" below for the full envelope.
|
|
108
|
+
|
|
109
|
+
## v5 wire shape (read route)
|
|
110
|
+
|
|
111
|
+
Every task result is a `ComposePayload` — seven main-agent fields plus a telemetry block.
|
|
112
|
+
The main-agent fields are authoritative; the telemetry block is diagnostics.
|
|
113
|
+
|
|
114
|
+
```json
|
|
115
|
+
{
|
|
116
|
+
"completed": true,
|
|
117
|
+
"message": "Recall complete; 4 relevant learnings found.",
|
|
118
|
+
"findings": [
|
|
119
|
+
{
|
|
120
|
+
"id": "F1",
|
|
121
|
+
"severity": "critical",
|
|
122
|
+
"category": "correctness",
|
|
123
|
+
"claim": "Cancellation handlers must check context before writing to avoid corruption.",
|
|
124
|
+
"evidence": "nodes/0012-dispatch-cancellation-lifecycle.md:20-35 — verbatim substring from journal node.",
|
|
125
|
+
"suggestion": null,
|
|
126
|
+
"source": "implementer"
|
|
127
|
+
}
|
|
128
|
+
],
|
|
129
|
+
"summary": "The project learned that dispatch cancellation must synchronize context reads (node 0012) and never write without checking. Related node 0008 (refines) adds that timeout-based cancellation has race conditions under high load.",
|
|
130
|
+
"filesChanged": [],
|
|
131
|
+
"commitSha": null,
|
|
132
|
+
"blockId": null,
|
|
133
|
+
"telemetry": {
|
|
134
|
+
"totalDurationMs": 1234,
|
|
135
|
+
"totalCostUSD": 0.08,
|
|
136
|
+
"workerSelfAssessment": "done",
|
|
137
|
+
"reviewVerdict": null,
|
|
138
|
+
"commitOutcome": "not_applicable",
|
|
139
|
+
"stopReason": "normal",
|
|
140
|
+
"haltedStage": null,
|
|
141
|
+
"stages": [...]
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Key fields
|
|
147
|
+
|
|
148
|
+
| Field | When populated | Notes |
|
|
149
|
+
|---|---|---|
|
|
150
|
+
| `completed` | always | `true` when at least one criterion succeeded; `false` on annotator transport failure OR unmet annotate preconditions |
|
|
151
|
+
| `message` | always | human-readable summary; names blocking gates or finding IDs on failure |
|
|
152
|
+
| `findings` | always | `source: 'implementer'` for recall; findings are the deliverable on read routes |
|
|
153
|
+
| `workerSelfAssessment` | always | `'done'` or `'failed'` — never `done_with_concerns` |
|
|
154
|
+
| `blockId` | always `null` (for write routes); string (for read routes) | recall is a read route, so `blockId` is a string — a reusable context block for delta follow-up |
|
|
155
|
+
|
|
156
|
+
### No second review
|
|
157
|
+
|
|
158
|
+
The LLM-judge stage (`annotate`) runs once, after the worker's output. Its preconditions for read-route `completed: true`:
|
|
159
|
+
|
|
160
|
+
```
|
|
161
|
+
gates.implement.outcome === 'advance'
|
|
162
|
+
&& gates.implement.payload.workerSelfAssessment === 'done'
|
|
163
|
+
&& (criteriaSucceeded.length > 0 || criteriaErrors.length === 0)
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Findings are the deliverable — a recall that surfaces 5 relevant lessons is `completed: true`. Finding nothing relevant is also a valid completion (returns `findings: []`).
|
|
167
|
+
|
|
168
|
+
### `completed: false` — what it means
|
|
169
|
+
|
|
170
|
+
Only on annotator transport failure, or if the journal is inaccessible/corrupted. The `message` names the blocking gate. Re-dispatch with a broader `query` if the worker's findings were too narrow.
|
|
171
|
+
|
|
172
|
+
## Best practices
|
|
173
|
+
|
|
174
|
+
This skill is one step in a larger flow described in `multi-model-agent` → "Best practices". Recipes that involve `mma-journal-recall`:
|
|
175
|
+
|
|
176
|
+
- **Recipe A — Recall before attempting.** Call `mma-journal-recall` with your question before running `mma-delegate` / `mma-execute-plan` to avoid re-treading prior dead ends.
|
|
177
|
+
- **Recipe B — Recall → plan → execute.** `mma-journal-recall` → write a plan based on the learnings → `mma-execute-plan`.
|
|
178
|
+
- **Recipe C — Delta follow-up recall.** Feed a prior recall's `contextBlockId` into a follow-up call to dig deeper: `contextBlockIds: [priorResult.contextBlockId]`.
|
|
179
|
+
|
|
180
|
+
Anti-pattern alert: **Misusing recall as codebase search.** Recall is for the *project's learnings graph*, not the codebase. If you want to search code → `mma-investigate`. If you want to ask the journal → `mma-journal-recall`.
|
|
181
|
+
|
|
182
|
+
## Common pitfalls
|
|
183
|
+
|
|
184
|
+
❌ **Using exact tags instead of a conceptual question**
|
|
185
|
+
> query: "dispatch cancellation"
|
|
186
|
+
|
|
187
|
+
The worker expects a sentence with context, not keywords. **Fix:** phrase it as a question:
|
|
188
|
+
> query: "what have we learned about dispatch cancellation and how it interacts with timeouts?"
|
|
189
|
+
|
|
190
|
+
❌ **Asking about the codebase instead of the journal**
|
|
191
|
+
> query: "where is DispatchCanceller called?"
|
|
192
|
+
|
|
193
|
+
That's a codebase question. Use `mma-investigate` instead. Journal recall is for *learnings* stored in `.mmagent/journal/`, not code.
|
|
194
|
+
|
|
195
|
+
❌ **Assuming the journal exists**
|
|
196
|
+
> query: "what do we know about X?"
|
|
197
|
+
|
|
198
|
+
If the project hasn't used `mma-journal-record`, the journal is empty. The worker will return `not_applicable`. **Fix:** check whether the journal is active in the project first, or start recording learnings with `mma-journal-record`.
|
|
199
|
+
|
|
200
|
+
## Terminal context block
|
|
201
|
+
|
|
202
|
+
Every completed **read-route** task (audit / review / debug / investigate / recall / research) auto-registers a reusable terminal context block containing its report (headline + findings). The block id is returned on each per-task result as **`contextBlockId`**. Write routes (delegate / execute-plan / retry / journal-record) return `contextBlockId: null` — their record is the commit, not a block. This block is immutable, lives for the session duration, and counts against the project's `maxEntries` quota (default 500).
|
|
203
|
+
|
|
204
|
+
Use it for delta follow-ups — feed prior results' block ids into a later call's `contextBlockIds`, filtering out nulls:
|
|
205
|
+
|
|
206
|
+
contextBlockIds: priorResults.map(r => r.contextBlockId).filter((id) => id !== null)
|
|
207
|
+
|
|
208
|
+
**Use cases:**
|
|
209
|
+
- Recall round 2: pass round 1's block into round 2's `contextBlockIds` to dig deeper on a specific thread.
|
|
210
|
+
- Recall → plan → execute chain: feed recall findings as a context block into `mma-execute-plan` as shared prior context.
|
|
211
|
+
- Multi-agent follow-up: capture a recall's block and hand it to another tool chain.
|
|
212
|
+
|
|
213
|
+
The block is registered server-side at task completion; no caller action is needed to create it. Delete it explicitly via `DELETE /context-blocks/:id` when no longer needed, or let it expire on session teardown.
|
|
214
|
+
|
|
215
|
+
## Outcome semantics
|
|
216
|
+
|
|
217
|
+
Every task result carries outcome fields that describe the recall's conclusion status:
|
|
218
|
+
|
|
219
|
+
| Field | Type | Meaning |
|
|
220
|
+
|---|---|---|
|
|
221
|
+
| `findingsOutcome` | `'found' \| 'not_applicable'` | Answers the question: did the recall produce substantive learnings? |
|
|
222
|
+
| `findingsOutcomeReason` | `string \| null` | When `findingsOutcome` is set, this explains why (e.g. "No relevant journal nodes found for the query" or "Journal is empty"). |
|
|
223
|
+
| `outcomeInferred` | `boolean` | `true` if the system inferred the outcome from findings count; `false` if the worker explicitly stated it. |
|
|
224
|
+
| `outcomeMalformed` | `boolean` | `true` if the outcome line was malformed and had to be repaired; `false` otherwise. |
|
|
225
|
+
|
|
226
|
+
### Enum values
|
|
227
|
+
|
|
228
|
+
- **`found`** — the recall produced one or more relevant prior learnings (findings) across one or more journal nodes.
|
|
229
|
+
- **`not_applicable`** — the recall could not proceed (the journal is empty, inaccessible, or nothing in it answers the query).
|
|
230
|
+
|
|
231
|
+
### Empty journal ≠ failure
|
|
232
|
+
|
|
233
|
+
A recall that searches the journal and finds nothing relevant is a valid `completed: true` outcome; it simply answers "no prior learnings match that question" — which is useful information before attempting something new.
|
|
234
|
+
|
|
235
|
+
### Per-route legal outcomes
|
|
236
|
+
|
|
237
|
+
The legal outcomes for this route are: `['found', 'not_applicable']`
|
|
238
|
+
|
|
239
|
+
- **`found`** — one or more prior learnings surfaced from the journal.
|
|
240
|
+
- **`not_applicable`** — the journal is empty, inaccessible, or no learnings match the query.
|
|
241
|
+
|
|
242
|
+
@include _shared/error-handling.md
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mma-journal-record
|
|
3
|
+
description: >-
|
|
4
|
+
Use when you've abandoned an approach, hit a constraint, or concluded
|
|
5
|
+
something worth remembering — record it to the persistent journal as a
|
|
6
|
+
fire-and-forget decision audit trail for future sessions.
|
|
7
|
+
when_to_use: >-
|
|
8
|
+
You've completed analysis and want to log the outcome — abandoned an approach,
|
|
9
|
+
hit a blocking constraint, or reached a conclusion worth remembering. NOT for
|
|
10
|
+
recall/investigate/delegate; those are read routes. Journal stores conclusions
|
|
11
|
+
for cross-session reference.
|
|
12
|
+
version: 5.0.3
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# mma-journal-record
|
|
16
|
+
|
|
17
|
+
## Overview
|
|
18
|
+
|
|
19
|
+
Record a learning, constraint, or decision outcome to the persistent journal via a fire-and-forget mmagent worker. The worker stores the entry and returns immediately; you continue on your main context.
|
|
20
|
+
|
|
21
|
+
**Core principle:** Journal is an audit trail of what you've decided, discovered, or abandoned. Record it once per session; don't re-investigate.
|
|
22
|
+
|
|
23
|
+
## When to Use
|
|
24
|
+
|
|
25
|
+
**Use when:**
|
|
26
|
+
- You've abandoned an approach and want to log why
|
|
27
|
+
- You've hit a blocking constraint worth remembering
|
|
28
|
+
- You've reached a conclusion (e.g., "Pattern X doesn't work in this codebase")
|
|
29
|
+
- You've decided not to pursue a direction and want to avoid repeating that decision next session
|
|
30
|
+
|
|
31
|
+
**Don't use when:**
|
|
32
|
+
- You're asking a question → `mma-investigate`
|
|
33
|
+
- You're dispatching work → `mma-delegate`
|
|
34
|
+
- You want to retrieve past entries → journal is append-only, not searchable; use `git log` or `.mmagent/journal/` files directly
|
|
35
|
+
- You're mid-task and want to pause → that's what `blockedBy` is for; journal is for conclusions, not temporary blockers
|
|
36
|
+
|
|
37
|
+
## Endpoint
|
|
38
|
+
|
|
39
|
+
`POST /journal-record?cwd=<abs-path>`
|
|
40
|
+
|
|
41
|
+
@include _shared/auth.md
|
|
42
|
+
|
|
43
|
+
## Request body
|
|
44
|
+
|
|
45
|
+
```json
|
|
46
|
+
{
|
|
47
|
+
"learnings": [
|
|
48
|
+
"Tried worker self-report for grouped-dispatch cancellation; dropped it — git diff is the source of truth. Lesson: use getRealFilesChanged.",
|
|
49
|
+
"Bun.spawn lacks process groups; keep node:child_process for codex subprocess management."
|
|
50
|
+
],
|
|
51
|
+
"tagHints": ["dispatch", "cancellation"]
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**Batch your learnings into ONE call.** Collect every learning from the session and send them together in `learnings[]` — do NOT fire multiple concurrent `journal-record` calls. One worker integrates them sequentially in a single pass (fast and collision-free).
|
|
56
|
+
|
|
57
|
+
| Field | Type | Required | Notes |
|
|
58
|
+
|---|---|---|---|
|
|
59
|
+
| `learnings` | string[] | yes | 1–20 entries, each 20–8000 chars. Each is a natural-language entry: what you decided, why, or what you learned. Keep them concrete. |
|
|
60
|
+
| `tagHints` | string[] | no | Optional tags applied across ALL learnings (batch-scoped); the worker revises/normalizes per node. Advisory. |
|
|
61
|
+
|
|
62
|
+
**What gets stored & where:**
|
|
63
|
+
|
|
64
|
+
Entries are integrated into a graph-structured journal store at `.mmagent/journal/`:
|
|
65
|
+
- `nodes/` — individual learning entries (keyed by unique node ID)
|
|
66
|
+
- `index.md` — searchable index of all entries, tags, and cross-references
|
|
67
|
+
- `log.md` — append-only event log of create/refine/supersede/merge operations
|
|
68
|
+
|
|
69
|
+
The worker creates, refines, or supersedes nodes in the graph (never appends blindly). You can query the index or log directly to track learning history. Writes are confined to the project's `.mmagent/` directory (no traversal).
|
|
70
|
+
|
|
71
|
+
## Full example
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
BATCH=$(curl -f --show-error -s -X POST \
|
|
75
|
+
-H "X-MMA-Client: $MMA_CLIENT" \
|
|
76
|
+
-H "X-MMA-Main-Model: $MMA_MAIN_MODEL" \
|
|
77
|
+
-H "Authorization: Bearer $TOKEN" \
|
|
78
|
+
-H "Content-Type: application/json" \
|
|
79
|
+
-d '{
|
|
80
|
+
"learnings": [
|
|
81
|
+
"Tried worker self-report for grouped-dispatch cancellation; dropped it — git diff is the source of truth. Lesson: use getRealFilesChanged."
|
|
82
|
+
],
|
|
83
|
+
"tagHints": ["dispatch", "cancellation"]
|
|
84
|
+
}' \
|
|
85
|
+
"http://localhost:$PORT/journal-record?cwd=/project")
|
|
86
|
+
BATCH_ID=$(echo "$BATCH" | jq -r '.batchId')
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
@include _shared/polling.md
|
|
90
|
+
|
|
91
|
+
@include _shared/response-shape.md
|
|
92
|
+
|
|
93
|
+
## Per-task report shape
|
|
94
|
+
|
|
95
|
+
Each task carries a structured report containing the graph operation metadata:
|
|
96
|
+
|
|
97
|
+
```json
|
|
98
|
+
{
|
|
99
|
+
"summary": "recorded 2, failed 0; created 0012, superseded 0009",
|
|
100
|
+
"filesChanged": [".mmagent/journal/nodes/0012.md", ".mmagent/journal/index.md", ".mmagent/journal/log.md"],
|
|
101
|
+
"recorded": [
|
|
102
|
+
{ "learningIndex": 0, "op": "create", "ids": ["0012"] },
|
|
103
|
+
{ "learningIndex": 1, "op": "supersede", "ids": ["0013"] }
|
|
104
|
+
],
|
|
105
|
+
"failed": []
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
`recorded` and `failed` partition the input learnings by `learningIndex`. To retry, re-send the `failed[]` entries' `learning` text as a new `learnings[]` batch (reuse the original `tagHints`/`contextBlockIds`).
|
|
110
|
+
|
|
111
|
+
The authoritative success signal is `completed` + the presence of `filesChanged`. See "v5 wire shape" below for the full envelope.
|
|
112
|
+
|
|
113
|
+
## v5 wire shape (reviewed write route)
|
|
114
|
+
|
|
115
|
+
Every task result is a `ComposePayload` — seven main-agent fields plus a telemetry block.
|
|
116
|
+
The main-agent fields are authoritative; the telemetry block is diagnostics.
|
|
117
|
+
|
|
118
|
+
```json
|
|
119
|
+
{
|
|
120
|
+
"completed": true,
|
|
121
|
+
"message": "Journal entry created (node 0012); superseded prior learning (node 0009)",
|
|
122
|
+
"findings": [],
|
|
123
|
+
"summary": "created 0012; superseded 0009",
|
|
124
|
+
"filesChanged": [".mmagent/journal/nodes/0012.md", ".mmagent/journal/index.md", ".mmagent/journal/log.md"],
|
|
125
|
+
"commitSha": null,
|
|
126
|
+
"blockId": null,
|
|
127
|
+
"telemetry": {
|
|
128
|
+
"totalDurationMs": 5400,
|
|
129
|
+
"totalCostUSD": 0.04,
|
|
130
|
+
"workerSelfAssessment": "done",
|
|
131
|
+
"reviewVerdict": "approved",
|
|
132
|
+
"commitOutcome": "not_applicable",
|
|
133
|
+
"stopReason": "normal",
|
|
134
|
+
"haltedStage": null,
|
|
135
|
+
"stages": [
|
|
136
|
+
{ "name": "prepare", "outcome": "advance", "durationMs": 2, "costUSD": 0 },
|
|
137
|
+
{ "name": "register-block", "outcome": "skip", "comment": "register-block does not apply to route=journal", "durationMs": 0, "costUSD": 0 },
|
|
138
|
+
{ "name": "implement", "outcome": "advance", "durationMs": 3200, "costUSD": 0.02 },
|
|
139
|
+
{ "name": "review", "outcome": "advance", "durationMs": 1800, "costUSD": 0.01 },
|
|
140
|
+
{ "name": "rework", "outcome": "skip", "comment": "rework skipped because review approved", "durationMs": 0, "costUSD": 0 },
|
|
141
|
+
{ "name": "commit", "outcome": "skip", "comment": "commit does not apply to non-git routes", "durationMs": 0, "costUSD": 0 },
|
|
142
|
+
{ "name": "annotate", "outcome": "advance", "durationMs": 340, "costUSD": 0.01 },
|
|
143
|
+
{ "name": "compose", "outcome": "advance", "durationMs": 56, "costUSD": 0 },
|
|
144
|
+
{ "name": "terminal", "outcome": "advance", "durationMs": 2, "costUSD": 0 }
|
|
145
|
+
]
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Key fields
|
|
151
|
+
|
|
152
|
+
| Field | When populated | Notes |
|
|
153
|
+
|---|---|---|
|
|
154
|
+
| `completed` | always | `true` when entry is created/refined/superseded and approved; `false` on review rejection, path traversal, or write failure |
|
|
155
|
+
| `message` | always | human-readable summary (e.g., "created 0012; superseded 0009"); read on failure for diagnostic |
|
|
156
|
+
| `findings` | always | issues surfaced by the reviewer (e.g., unclear learning, duplicate with 0009). Empty if approved as-is. |
|
|
157
|
+
| `filesChanged` | always | graph journal paths modified: `nodes/`, `index.md`, `log.md` (relative to `cwd`) |
|
|
158
|
+
| `workerSelfAssessment` | always | `'done'` or `'failed'` — worker's assessment of completeness |
|
|
159
|
+
| `blockId` | always `null` | journal is a task route, not register-context-block |
|
|
160
|
+
| `commitSha` | always `null` | journal entries are graph mutations, not git commits |
|
|
161
|
+
| `reviewVerdict` | via telemetry | `'approved'` \| `'rejected_with_rework'` \| `'rejected'` — reviewer's verdict on the learned entry |
|
|
162
|
+
|
|
163
|
+
### Reviewed write lifecycle
|
|
164
|
+
|
|
165
|
+
Unlike read routes (audit/investigate/debug), journal runs a full review cycle: **implement** → **review** → [optional **rework**] → **commit** (skipped for non-git routes) → **annotate**. If the reviewer finds issues (e.g., the learning is ambiguous, the node supersedes multiple prior entries), a rework round applies targeted edits before finalization.
|
|
166
|
+
|
|
167
|
+
### `completed: false` — what it means
|
|
168
|
+
|
|
169
|
+
Path traversal detected, write permission denied, or directory creation failed. The `message` names the blocking issue.
|
|
170
|
+
|
|
171
|
+
## Best practices
|
|
172
|
+
|
|
173
|
+
**One entry per decision, not per turn.**
|
|
174
|
+
Log once when you decide not to pursue a direction; don't log "just checked X" on every iteration.
|
|
175
|
+
|
|
176
|
+
**Keep entries concrete.**
|
|
177
|
+
❌ "Didn't work"
|
|
178
|
+
✅ "Tried multicast-style dispatch with worker dedup; git diff is the source of truth, workers can't track cancellations atomically. Use getRealFilesChanged instead."
|
|
179
|
+
|
|
180
|
+
**Use tags to build searchable structure.**
|
|
181
|
+
```bash
|
|
182
|
+
# Later, grep your journal for all perf decisions:
|
|
183
|
+
grep -r "^" .mmagent/journal/ | grep -i "perf:"
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Common pitfalls
|
|
187
|
+
|
|
188
|
+
❌ **Using journal as a scratchpad**
|
|
189
|
+
> "Thinking about X. Maybe Y? Need to check Z."
|
|
190
|
+
|
|
191
|
+
Journal is for **conclusions**, not work-in-progress. Keep notes in a separate working file if you need to brainstorm.
|
|
192
|
+
|
|
193
|
+
❌ **Logging without context**
|
|
194
|
+
> "Doesn't work."
|
|
195
|
+
|
|
196
|
+
Future-you (or a teammate) won't remember what "doesn't work" means. Always include the decision frame: what did you try, why did you try it, what was the outcome, and what will you do instead?
|
|
197
|
+
|
|
198
|
+
## Context blocks
|
|
199
|
+
|
|
200
|
+
Write-route tasks (delegate / execute-plan / journal / retry) do **not** register terminal context blocks. Their artifact is the filesystem mutation (git commit for delegate; graph mutations for journal). Read-route tasks (audit / review / debug / investigate / research) auto-register blocks containing their findings.
|
|
201
|
+
|
|
202
|
+
@include _shared/error-handling.md
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mma-research
|
|
3
|
+
description: >-
|
|
4
|
+
Use when you need external multi-source research with citations — arxiv,
|
|
5
|
+
semantic_scholar, github_search, brave-with-site:-filters — for a focused
|
|
6
|
+
question. Worker is bibliographic, not opinionated. Pair with mma-investigate
|
|
7
|
+
(internal) under mma-explore for divergent landscape scans.
|
|
8
|
+
when_to_use: >-
|
|
9
|
+
An external-research question has surfaced (state of the art, prior art, what
|
|
10
|
+
others do, what published methods exist) AND mmagent is running. Delegate the
|
|
11
|
+
multi-source web/adapter research to a worker so the main context stays on
|
|
12
|
+
judgment. NOT for codebase questions — those are mma-investigate.
|
|
13
|
+
version: 5.0.3
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# mma-research
|
|
17
|
+
|
|
18
|
+
## Overview
|
|
19
|
+
|
|
20
|
+
Run external multi-source research via a single mmagent worker. The worker
|
|
21
|
+
consults configured adapters (arxiv, semantic_scholar, github_search) and
|
|
22
|
+
— when Brave keys are configured — escalates to Brave web search with `site:`
|
|
23
|
+
filters. The worker is bibliographic: it returns a numbered narrative with a
|
|
24
|
+
`## Sources used` table. It does not opinion or rank.
|
|
25
|
+
|
|
26
|
+
**Core principle:** External research is labor (search, fetch, summarise).
|
|
27
|
+
Delegate it. The main agent stays on judgment — deciding what the citations
|
|
28
|
+
mean and which directions to pursue.
|
|
29
|
+
|
|
30
|
+
## When to Use
|
|
31
|
+
|
|
32
|
+
**Use when:**
|
|
33
|
+
- "What's the state of the art for X?"
|
|
34
|
+
- "Who has published on Y?"
|
|
35
|
+
- "What's prior art for Z?"
|
|
36
|
+
- The question is external (web, papers, github topics) — not your codebase.
|
|
37
|
+
|
|
38
|
+
**Don't use when:**
|
|
39
|
+
- The question is about THIS codebase → `mma-investigate`
|
|
40
|
+
- You need divergent ideation across both internal and external (multiple
|
|
41
|
+
directions with synthesis) → `mma-explore` (orchestrates mma-investigate + mma-research)
|
|
42
|
+
- A single web fetch is all you need → `WebFetch` inline
|
|
43
|
+
|
|
44
|
+
## Endpoint
|
|
45
|
+
|
|
46
|
+
`POST /research?cwd=<abs-path>`
|
|
47
|
+
|
|
48
|
+
@include _shared/auth.md
|
|
49
|
+
|
|
50
|
+
## Configuration prerequisites
|
|
51
|
+
|
|
52
|
+
The `mma-research` worker integrates with Semantic Scholar to search academic papers. This adapter is optional but recommended for comprehensive peer-reviewed source coverage.
|
|
53
|
+
|
|
54
|
+
**Required environment variable:**
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
export SEMANTIC_SCHOLAR_API_KEY="your-key-from-semanticscholar.org"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Obtain a free API key from [Semantic Scholar API](https://www.semanticscholar.org/product/api).
|
|
61
|
+
|
|
62
|
+
**Degraded behavior:**
|
|
63
|
+
|
|
64
|
+
If the Semantic Scholar API key is not configured:
|
|
65
|
+
- The worker continues with available adapters (arxiv, github_search, brave-search)
|
|
66
|
+
- Semantic Scholar queries are skipped without errors
|
|
67
|
+
- Research completes successfully but may lack academic-paper coverage
|
|
68
|
+
- No failure occurs; graceful fallback is automatic
|
|
69
|
+
|
|
70
|
+
## Request body
|
|
71
|
+
|
|
72
|
+
```json
|
|
73
|
+
{
|
|
74
|
+
"researchQuestion": "What approaches exist for streaming JSON parsing under 100KB?",
|
|
75
|
+
"background": "We currently use a single-pass push parser; we want to evaluate alternatives.",
|
|
76
|
+
"subtype": "default",
|
|
77
|
+
"contextBlockIds": []
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
| Field | Type | Required | Notes |
|
|
82
|
+
|---|---|---|---|
|
|
83
|
+
| `researchQuestion` | string | yes | 20–8000 chars |
|
|
84
|
+
| `background` | string | yes | 20–8000 chars; what you already know / are trying to do |
|
|
85
|
+
| `subtype` | `'default'` | no (defaults to `'default'`) | Reserved for future criteria sets; only `default` is wired today. |
|
|
86
|
+
| `contextBlockIds` | string[] | no | IDs from `mma-context-blocks` |
|
|
87
|
+
|
|
88
|
+
> Worker tier is hardcoded `complex`. Sending `agentType` or `tools` is rejected with HTTP 400.
|
|
89
|
+
|
|
90
|
+
The `default` subtype's criteria target primary-source preference, practitioner consensus, recency, counter-perspectives, and cross-domain analogues — the worker is bibliographic, not opinionated.
|
|
91
|
+
|
|
92
|
+
## Full example
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
BATCH=$(curl -f -sS -X POST \
|
|
96
|
+
-H "Authorization: Bearer $TOKEN" \
|
|
97
|
+
-H "X-MMA-Client: $MMA_CLIENT" \
|
|
98
|
+
-H "X-MMA-Main-Model: $MMA_MAIN_MODEL" \
|
|
99
|
+
-H "Content-Type: application/json" \
|
|
100
|
+
-d '{
|
|
101
|
+
"researchQuestion": "State-of-the-art SIMD JSON parsers under 100KB?",
|
|
102
|
+
"background": "We use a single-pass push parser; want SIMD alternatives."
|
|
103
|
+
}' \
|
|
104
|
+
"http://localhost:$PORT/research?cwd=/project")
|
|
105
|
+
BATCH_ID=$(echo "$BATCH" | jq -r '.batchId')
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
@include _shared/polling.md
|
|
109
|
+
|
|
110
|
+
@include _shared/response-shape.md
|
|
111
|
+
|
|
112
|
+
## Per-task report shape (v5 envelope)
|
|
113
|
+
|
|
114
|
+
Each `results[N]` is the v5 `ComposePayload`:
|
|
115
|
+
|
|
116
|
+
```json
|
|
117
|
+
{
|
|
118
|
+
"completed": true,
|
|
119
|
+
"message": "Research complete; 4 sources synthesised.",
|
|
120
|
+
"findings": [
|
|
121
|
+
{
|
|
122
|
+
"id": "F1",
|
|
123
|
+
"severity": "medium",
|
|
124
|
+
"category": "evidence",
|
|
125
|
+
"claim": "Pattern X is the canonical approach as of 2026 per upstream RFC.",
|
|
126
|
+
"evidence": "https://example.org/rfc/...",
|
|
127
|
+
"source": "implementer"
|
|
128
|
+
}
|
|
129
|
+
],
|
|
130
|
+
"summary": "Pattern X dominates; pattern Y is a 2024 fork.",
|
|
131
|
+
"filesChanged": [],
|
|
132
|
+
"commitSha": null,
|
|
133
|
+
"blockId": null,
|
|
134
|
+
"telemetry": {
|
|
135
|
+
"totalDurationMs": 12400,
|
|
136
|
+
"totalCostUSD": 0.06,
|
|
137
|
+
"workerSelfAssessment": "done",
|
|
138
|
+
"reviewVerdict": null,
|
|
139
|
+
"commitOutcome": "not_applicable",
|
|
140
|
+
"stopReason": "normal",
|
|
141
|
+
"haltedStage": null,
|
|
142
|
+
"stages": [
|
|
143
|
+
{ "name": "prepare", "outcome": "advance" },
|
|
144
|
+
{ "name": "implement", "outcome": "advance" },
|
|
145
|
+
{ "name": "annotate", "outcome": "advance" },
|
|
146
|
+
{ "name": "compose", "outcome": "advance" },
|
|
147
|
+
{ "name": "terminal", "outcome": "advance" }
|
|
148
|
+
]
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
| Field | Notes |
|
|
154
|
+
|---|---|
|
|
155
|
+
| `completed: true` | At least one criterion succeeded; sources synthesised. |
|
|
156
|
+
| `completed: false` | Annotator transport failure OR worker self-assessed as `failed`. `message` names the blocking gate. |
|
|
157
|
+
| `findings` | The deliverable. `source: 'implementer'`. Empty `findings` on a research route means "no signal found" — still a valid completion. |
|
|
158
|
+
| `workerSelfAssessment` | `'done'` or `'failed'` — never `done_with_concerns`. |
|
|
159
|
+
| `blockId` | Always `null` — research is a task route, not register-context-block. |
|
|
160
|
+
| `contextBlockId` | The terminal context block id for this read-route task (its report as a reusable block). Pass it into a later call's `contextBlockIds` for delta follow-ups. |
|
|
161
|
+
|
|
162
|
+
Legacy aliases (still emitted for back-compat):
|
|
163
|
+
|
|
164
|
+
```
|
|
165
|
+
results[0].structuredReport.findings[] // mirror of findings above
|
|
166
|
+
results[0].structuredReport.sourcesUsed[] // table of sources tried
|
|
167
|
+
results[0].output // raw narrative report
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Terminal context block
|
|
171
|
+
|
|
172
|
+
Every completed **read-route** task (audit / review / debug / investigate / research) auto-registers a reusable terminal context block containing its report (headline + findings). The block id is returned on each per-task result as **`contextBlockId`**. Write routes (delegate / execute-plan / retry) return `contextBlockId: null` — their record is the commit, not a block. This block is immutable, lives for the session duration, and counts against the project's `maxEntries` quota (default 500).
|
|
173
|
+
|
|
174
|
+
Use it for delta follow-ups — feed prior results' block ids into a later call's `contextBlockIds`, filtering out nulls:
|
|
175
|
+
|
|
176
|
+
contextBlockIds: priorResults.map(r => r.contextBlockId).filter((id) => id !== null)
|
|
177
|
+
|
|
178
|
+
## Best practices
|
|
179
|
+
|
|
180
|
+
- Keep `researchQuestion` topical (keywords, not full sentences).
|
|
181
|
+
- Use `background` to give the worker context that helps it phrase queries.
|
|
182
|
+
- For multi-round research, register the previous round's findings via
|
|
183
|
+
`mma-context-blocks` and pass `contextBlockIds`.
|
|
184
|
+
|
|
185
|
+
## Common pitfalls
|
|
186
|
+
|
|
187
|
+
❌ **Asking a codebase question here.** External adapters can't grep your repo. **Fix:** use `mma-investigate`.
|
|
188
|
+
|
|
189
|
+
❌ **Inlining the user's full question verbatim.** Multi-sentence excerpts produce poor adapter queries. **Fix:** the worker re-phrases internally; you just pass the question and let it work.
|
|
190
|
+
|
|
191
|
+
❌ **Expecting opinionated output.** This worker reports what's out there with citations. Ranking and synthesis happen elsewhere — in `mma-explore` or in your own judgment. **Fix:** if you need ranked options, use `mma-explore`.
|
|
192
|
+
|
|
193
|
+
## Outcome semantics
|
|
194
|
+
|
|
195
|
+
Every task result carries outcome fields that describe the research investigation's conclusion status:
|
|
196
|
+
|
|
197
|
+
| Field | Type | Meaning |
|
|
198
|
+
|---|---|---|
|
|
199
|
+
| `findingsOutcome` | `'found' \| 'clean' \| 'not_applicable'` | Answers the question: did the research produce candidate sources and insights? |
|
|
200
|
+
| `findingsOutcomeReason` | `string \| null` | When `findingsOutcome` is set, this explains why (e.g. "3 primary sources identified across arxiv and semantic_scholar" or "No sources found matching the research criteria"). |
|
|
201
|
+
| `outcomeInferred` | `boolean` | `true` if the system inferred the outcome from findings count; `false` if the researcher explicitly stated it. |
|
|
202
|
+
| `outcomeMalformed` | `boolean` | `true` if the outcome line was malformed and had to be repaired; `false` otherwise. |
|
|
203
|
+
|
|
204
|
+
### Enum values
|
|
205
|
+
|
|
206
|
+
- **`found`** — the research identified one or more candidate sources or insights (findings) across one or more search criteria. This indicates the question has published material or prior art available.
|
|
207
|
+
- **`clean`** — the research completed but produced zero findings. This is valid for out-of-scope or nascent topics and indicates "no signal found."
|
|
208
|
+
- **`not_applicable`** — the research could not proceed (e.g., question was out of scope, search system unavailable, or preconditions failed). This is the "cannot research" state.
|
|
209
|
+
|
|
210
|
+
### Empty findings ≠ failure
|
|
211
|
+
|
|
212
|
+
A crucial semantic: **empty findings does NOT mean `completed: false` or a failed research task.** Research that proceeds thoroughly and produces zero sources is a valid `completed: true` outcome; it answers the question "I searched widely and found nothing," which is valuable information. An empty-findings result often surfaces a `not_applicable` outcome (topic too new, domain too narrow) but zero findings is still a success.
|
|
213
|
+
|
|
214
|
+
### Per-route legal outcomes
|
|
215
|
+
|
|
216
|
+
The legal outcomes for this route are: `['found', 'not_applicable']`
|
|
217
|
+
|
|
218
|
+
- **`found`** — one or more candidate sources or insights were identified via the research criteria.
|
|
219
|
+
- **`not_applicable`** — the research could not proceed or the question was out of scope.
|
|
220
|
+
|
|
221
|
+
The outcome `clean` (zero findings + success) is not legal for `mma-research` because a research task always either identifies sources or indicates the topic is inaccessible.
|
|
222
|
+
|
|
223
|
+
@include _shared/error-handling.md
|