@dotdrelle/wiki-manager 0.15.64 → 0.15.70
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/.env.example +10 -3
- package/README.md +54 -0
- package/agent-runtimes.example.json +68 -0
- package/agents.docker-compose.yml +35 -1
- package/docker-compose.yml +3 -3
- package/package.json +3 -2
- package/src/agent/graph.js +15 -14
- package/src/agent/graph.test.js +1 -1
- package/src/agent/skillRecursion.test.js +13 -12
- package/src/cli/wiki-manager.js +124 -36
- package/src/commands/slash.js +48 -13
- package/src/contracts/schemas.js +67 -0
- package/src/core/activity.js +5 -0
- package/src/core/agentEvents.js +18 -1
- package/src/core/agentLoop.js +3 -3
- package/src/core/agentLoop.test.js +1 -1
- package/src/core/buildInfo.json +2 -2
- package/src/core/dockerCompose.test.js +8 -40
- package/src/core/env.js +14 -0
- package/src/core/env.test.js +19 -0
- package/src/core/googleGrants.test.js +1 -1
- package/src/core/mcp.js +1 -1
- package/src/core/runtimeEventAdapter.js +81 -0
- package/src/core/runtimeEventAdapter.test.js +61 -0
- package/src/core/skillChainView.test.js +2 -2
- package/src/core/skillCompiler.test.js +1 -1
- package/src/core/skillInvocation.js +13 -8
- package/src/core/startupCheck.js +58 -0
- package/src/core/startupCheck.test.js +29 -1
- package/src/orchestrator/agentRegistry.js +1 -22
- package/src/orchestrator/assignmentManager.js +16 -4
- package/src/orchestrator/capabilityRegistry.js +8 -1
- package/src/orchestrator/dispatcher.js +361 -2
- package/src/orchestrator/dispatcher.test.js +112 -1
- package/src/orchestrator/objectiveResolver.js +10 -6
- package/src/orchestrator/objectiveResolver.test.js +26 -27
- package/src/orchestrator/providers/deepAgentsProvider.js +168 -0
- package/src/orchestrator/providers/deepAgentsProvider.test.js +178 -0
- package/src/orchestrator/providers/dispatcherExternalRuntime.test.js +409 -0
- package/src/orchestrator/providers/fakeRuntimeProvider.js +164 -0
- package/src/orchestrator/providers/fakeRuntimeProvider.test.js +201 -0
- package/src/orchestrator/providers/runtimeProvider.js +101 -0
- package/src/orchestrator/providers/runtimeProviders.js +325 -0
- package/src/orchestrator/providers/runtimeProviders.test.js +361 -0
- package/src/orchestrator/resultAggregator.js +35 -2
- package/src/orchestrator/resultAggregator.test.js +62 -0
- package/src/runtime/recoveryManager.js +70 -5
- package/src/runtime/runner.js +6 -6
- package/src/runtime/runner.test.js +1 -1
- package/src/runtime/skillChain.e2e.test.js +2 -2
- package/src/runtime/supervisor.js +5 -10
- package/src/shell/RightPane.tsx +25 -9
- package/src/shell/StartupScreen.tsx +44 -7
- package/src/shell/repl.js +12 -12
- package/src/shell/repl.test.js +18 -5
- package/src/shell/tui.tsx +6 -6
- package/src/shell/useAgent.ts +1 -1
- package/src/shell/useSession.ts +1 -1
- package/wiki-workspace +19 -3
package/.env.example
CHANGED
|
@@ -39,11 +39,8 @@ WORKSPACES_ROOT=/path/to/workspaces
|
|
|
39
39
|
# "documents": { "headers": { "Authorization": "Bearer <DOCUMENTS_MCP_AUTH_TOKEN>" } }
|
|
40
40
|
#
|
|
41
41
|
# Leave empty to disable authentication on that agent (not recommended in production).
|
|
42
|
-
|
|
43
42
|
CME_MCP_AUTH_TOKEN=
|
|
44
43
|
DOCUMENTS_MCP_AUTH_TOKEN=
|
|
45
|
-
# Generated by `wiki-workspace agents up` when missing.
|
|
46
|
-
CONNECTORS_MCP_AUTH_TOKEN=
|
|
47
44
|
|
|
48
45
|
# ── Agent ports (optional, change only if defaults conflict) ───────────────────
|
|
49
46
|
|
|
@@ -55,6 +52,16 @@ CONNECTORS_MCP_AUTH_TOKEN=
|
|
|
55
52
|
#
|
|
56
53
|
# Enable the opt-in agent-connectors service:
|
|
57
54
|
CONNECTORS_ENABLED=false
|
|
55
|
+
CONNECTORS_MCP_AUTH_TOKEN=
|
|
56
|
+
|
|
57
|
+
# Agentic runtime gateway (Deep Agents) — enabled by default, started by
|
|
58
|
+
# `agents up`. The manager never starts it, only discovers it via
|
|
59
|
+
# agent-runtimes.json; set GATEWAY_ENABLED=false to opt out.
|
|
60
|
+
GATEWAY_ENABLED=true
|
|
61
|
+
# GATEWAY_PORT=7789
|
|
62
|
+
# Generated by `agents up` if empty, like the other agent tokens; the manager
|
|
63
|
+
# sends it as the Bearer header on every gateway call.
|
|
64
|
+
GATEWAY_AUTH_TOKEN=
|
|
58
65
|
#
|
|
59
66
|
# The wikiLLM Google OAuth application is baked into the agent-connectors image
|
|
60
67
|
# at build time, from agent-external/agent-connectors/.env.build.local. Neither
|
package/README.md
CHANGED
|
@@ -120,6 +120,59 @@ in isolated workspaces.
|
|
|
120
120
|
|
|
121
121
|

|
|
122
122
|
|
|
123
|
+
## How wikiLLM compares
|
|
124
|
+
|
|
125
|
+
Several open projects now build a Markdown wiki with an LLM. They target
|
|
126
|
+
**different problems** — the useful questions are *what goes in, what comes out,
|
|
127
|
+
and who operates it*. Snapshot as of 2026; all of these move quickly.
|
|
128
|
+
|
|
129
|
+
Each cell keeps its detail and carries a score — ✅ first-class · 🟡 partial or
|
|
130
|
+
indirect · ❌ not a goal — and the last column names the project that **covers
|
|
131
|
+
that need best**.
|
|
132
|
+
|
|
133
|
+
| Dimension / need | **wikiLLM** (this project) | **OpenWiki** — `langchain-ai/openwiki` | **DeepWiki-Open** — `asyncfuncai/deepwiki-open` | **GraphRAG** — `microsoft/graphrag` | Best coverage |
|
|
134
|
+
| --- | --- | --- | --- | --- | --- |
|
|
135
|
+
| Built for | Turning scattered **business documents** into a team wiki, then regenerating deliverables from it | Giving **coding agents** a readable map of a codebase | Auto-documenting a **code repository** with diagrams | Answering **global questions** over a large text corpus | *depends on your goal* |
|
|
136
|
+
| Ingest arbitrary business documents (Confluence, PDF, Office, SaaS) | ✅ Confluence exports, PDF/Office files, notes, SaaS connectors | 🟡 personal-mode connectors only — Notion, Gmail, Slack | ❌ code repos only | 🟡 plain-text files only, and no wiki as output | **wikiLLM** |
|
|
137
|
+
| Document a source-code repository | ❌ nothing to ingest from a repo | ✅ *code mode*, with claims linked to source evidence (OKF) | ✅ repo → interactive wiki + Mermaid diagrams | ❌ not a goal | **OpenWiki / DeepWiki-Open** |
|
|
138
|
+
| Primary output | ✅ Maintained wiki **+ regenerated deliverables** from your templates (reports, pages, exports) | 🟡 A wiki about the codebase, for agents to read | 🟡 An interactive wiki + architecture diagrams | ❌ An entity graph + community summaries (Parquet), not a wiki | **wikiLLM** (only one producing deliverables) |
|
|
139
|
+
| Keep the wiki current over time | ✅ Re-ingest on demand or on a schedule | ✅ `--update` flag / CI action | 🟡 Regenerated per run | ✅ `graphrag update` (delta merge) | **wikiLLM / OpenWiki** |
|
|
140
|
+
| Knowledge structure | Deterministic concept folders + a derived community graph | Linked pages + evidence-grounded claims | LLM-generated pages + diagrams | Leiden communities over an entity/relationship graph | *task-dependent* |
|
|
141
|
+
| Browsable wiki UI for a team | ✅ Web UI: wiki browser, dependency graph, chat, run/execution view (single-user today) | 🟡 Local-only browser visualiser (127.0.0.1) + CLI chat | ✅ Self-hostable web app (Next.js + Python) with RAG chat | ❌ Library / CLI — no UI | **DeepWiki-Open / wikiLLM** |
|
|
142
|
+
| Evidence-grounded claims & citations | 🟡 Cites retrieved context, never invents facts | ✅ Grounded claims tied to versioned source | 🟡 RAG-cited answers | ✅ Citations to source text units | **OpenWiki / GraphRAG** |
|
|
143
|
+
| Corpus-wide graph Q&A over the knowledge | 🟡 BM25 + vector retrieval feeding generation | ❌ not a goal | 🟡 RAG chat scoped to one repo | ✅ Entity graph + local/global community search | **GraphRAG** |
|
|
144
|
+
| Multiple isolated projects on one install | ✅ Workspaces, each with its own services, ports and secrets | ❌ one wiki per run | ❌ one wiki per repo | ❌ one index per corpus | **wikiLLM** |
|
|
145
|
+
| Orchestration & governance | ✅ Capability-based dispatcher (**Donna**): human approval by default, per-run budgets, idempotent writes, crash recovery | ❌ One Deep Agent loop (LangGraph) | ❌ One generation pipeline | ❌ Deterministic indexing pipeline | **wikiLLM** |
|
|
146
|
+
| Durable runs — crash recovery, queued work | ✅ Boot-time re-attachment + extra runs queued | 🟡 Resumable page-job queue (`.run.json`) | ❌ regenerate from scratch | ❌ re-run the index | **wikiLLM** |
|
|
147
|
+
| Source connectors as separate services | ✅ Confluence, document conversion, e-mail — each an independent MCP agent | 🟡 Built-in connector set | ❌ | ❌ | **wikiLLM** |
|
|
148
|
+
| Run fully offline with local models | ✅ Per-workspace provider config, OpenAI-compatible or a gateway (Ollama, vLLM, MLX…) | ✅ 13+ providers incl. Ollama / LM Studio | ✅ incl. Ollama | ✅ any OpenAI-compatible endpoint | *any* |
|
|
149
|
+
| License | ❌ PolyForm **Noncommercial** | ✅ MIT | ✅ MIT | ✅ MIT | **OpenWiki / DeepWiki-Open / GraphRAG** |
|
|
150
|
+
|
|
151
|
+
**The short version:**
|
|
152
|
+
|
|
153
|
+
- **OpenWiki** and **DeepWiki-Open** document *source code*. Point wikiLLM at a
|
|
154
|
+
repository and there is nothing for it to ingest; point either of them at a
|
|
155
|
+
stack of Confluence pages and a Word document and that is not their job.
|
|
156
|
+
- **GraphRAG** builds *retrieval structure*, not a wiki you read or deliverables
|
|
157
|
+
you ship — it is a strong back end for corpus-wide Q&A, and complementary
|
|
158
|
+
rather than competing.
|
|
159
|
+
- **wikiLLM** is the only one of the four whose output is *both* a browsable wiki
|
|
160
|
+
*and* regenerated business documents, and the only one with the operational
|
|
161
|
+
layer — isolated projects, bounded approvals, automatic recovery, a web
|
|
162
|
+
console — that a shared internal tool needs.
|
|
163
|
+
|
|
164
|
+
**What wikiLLM does *not* try to do (today):**
|
|
165
|
+
|
|
166
|
+
- Document a codebase for coding agents — that is OpenWiki / DeepWiki-Open
|
|
167
|
+
territory.
|
|
168
|
+
- Serve a true multi-user instance with per-user identity and an attributed
|
|
169
|
+
audit trail. This is a single-user deployment baseline (see the scope note
|
|
170
|
+
above); multi-user is specified and planned next.
|
|
171
|
+
- Expose a graph-query API over the corpus the way GraphRAG does; retrieval is
|
|
172
|
+
BM25 plus a vector index feeding generation.
|
|
173
|
+
- Ship or host the multi-provider AI gateway — routing to several providers is
|
|
174
|
+
supported, the gateway itself is infrastructure you bring.
|
|
175
|
+
|
|
123
176
|
## Quick start — your first wiki in ~5 minutes
|
|
124
177
|
|
|
125
178
|
The fastest way in: a **browsable wiki, its dependency graph, and a grounded
|
|
@@ -402,6 +455,7 @@ answer "what is this and how do I start it", and stop there.
|
|
|
402
455
|
| [`docs/configuration.md`](docs/configuration.md) | Every configuration key: root `.env`, Compose overrides, `mcp.endpoints.json`, workspace `.env`, `.wikirc.yaml`, parallelism |
|
|
403
456
|
| [`docs/technical-reference.md`](docs/technical-reference.md) | Workspace model, services, the `donna` shell, agent tooling, orchestration and activity contracts, security model |
|
|
404
457
|
| [`docs/authoring-skills.md`](docs/authoring-skills.md) | Writing a workspace skill: what splits a body into runs, chains, concurrency, parameters, and the interpretation rules |
|
|
458
|
+
| [`docs/agentic-runtime.md`](docs/agentic-runtime.md) | The external agentic runtime: `agent-runtimes.json`, the `RuntimeProvider` contract, the gateway, and governance |
|
|
405
459
|
| [`docs/claude-desktop.md`](docs/claude-desktop.md) | Using a workspace from Claude Desktop |
|
|
406
460
|
| [`CLAUDE.md`](CLAUDE.md) | Repository guidance: invariants to preserve when changing this code |
|
|
407
461
|
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_comment": "Agentic runtimes for this manager (RFC § 37), seeded to agent-runtimes.json on first scaffold — enabled by default, matching the scaffold's GATEWAY_ENABLED=true (set GATEWAY_ENABLED=false in .env, or enabled:false here, to opt out). Rules: (1) a capability is read-only unless it declares mutationClass or defaultRequiresApproval; (2) the 'plan' operation is always a dry-run and never pauses for approval; (3) read/write pairs are TWO capabilities, not two operations, so the approval class stays per-capability; (4) the runtime has eyes (read tools), ideas (free reasoning) and a mouth (gated side-effects), but no hands on the workspace — the hands are the DAG. See llm-wiki-manager/docs/agentic-runtime.md.",
|
|
3
|
+
"runtimes": [
|
|
4
|
+
{
|
|
5
|
+
"id": "deepagents",
|
|
6
|
+
"type": "deepagents",
|
|
7
|
+
"endpoint": "http://localhost:7789",
|
|
8
|
+
"enabled": true,
|
|
9
|
+
"capabilities": [
|
|
10
|
+
{
|
|
11
|
+
"name": "agent.review",
|
|
12
|
+
"operations": ["run"],
|
|
13
|
+
"description": "Read-only audit of a wiki workspace: compare source documents against the existing concept pages, identify missing or under-covered classes, and produce a structured gap report. No mutation.",
|
|
14
|
+
"aliases": ["audit", "review", "analyze", "compare", "check"]
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"name": "agent.consistency",
|
|
18
|
+
"operations": ["run"],
|
|
19
|
+
"description": "Read-only detection of contradictions and inconsistencies between wiki pages and their sources, citing the conflicting passages. No mutation.",
|
|
20
|
+
"aliases": ["consistency", "coherence", "contradictions", "conflicts"]
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"name": "agent.synthesize",
|
|
24
|
+
"operations": ["run"],
|
|
25
|
+
"description": "Read-only cross-source synthesis: build a structured summary of several documents on one subject, using web search tools when available to complement the sources. No mutation.",
|
|
26
|
+
"aliases": ["synthesize", "summarize", "synthesis"]
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"_comment": "operations: 'plan' reports the proposal only (no pause, dry-run); 'run' integrates it and waits for human approval (defaultRequiresApproval).",
|
|
30
|
+
"name": "agent.plan",
|
|
31
|
+
"operations": ["plan", "run"],
|
|
32
|
+
"description": "Given an analysis, propose a deterministic DAG plan (ingest, build, sync) as a validated fragment. The 'plan' operation only reports the proposal; 'run' integrates it and waits for human approval.",
|
|
33
|
+
"aliases": ["plan", "propose"],
|
|
34
|
+
"aliasOperations": { "plan": "plan", "propose": "plan", "apply": "run", "execute": "run" },
|
|
35
|
+
"defaultRequiresApproval": true
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"name": "agent.answer",
|
|
39
|
+
"operations": ["run"],
|
|
40
|
+
"description": "Read-only research answer: investigate a question using the wiki sources and web search, and reply with a grounded answer. No mutation.",
|
|
41
|
+
"aliases": ["answer", "question", "explain"]
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"_comment": "mutationClass 'ingest': writes the findings into the workspace inbox, approval required.",
|
|
45
|
+
"name": "agent.research",
|
|
46
|
+
"operations": ["run"],
|
|
47
|
+
"description": "Web research grounded in the wiki: answer a complex question using wiki sources and web search, then write the findings into the workspace inbox. Mutation, approval required.",
|
|
48
|
+
"aliases": ["research", "investigate"],
|
|
49
|
+
"mutationClass": "ingest"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"name": "agent.preview",
|
|
53
|
+
"operations": ["run"],
|
|
54
|
+
"description": "Compose the notification report from the workspace profile and show it, without sending. No mutation.",
|
|
55
|
+
"aliases": ["preview", "draft", "compose"]
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"_comment": "defaultRequiresApproval: sending the mail pauses for human approval.",
|
|
59
|
+
"name": "agent.notify",
|
|
60
|
+
"operations": ["run"],
|
|
61
|
+
"description": "Read the workspace profile for the notification recipient, then send the report by email. Mutation, approval required.",
|
|
62
|
+
"aliases": ["notify", "send", "email", "report"],
|
|
63
|
+
"defaultRequiresApproval": true
|
|
64
|
+
}
|
|
65
|
+
]
|
|
66
|
+
}
|
|
67
|
+
]
|
|
68
|
+
}
|
|
@@ -25,6 +25,12 @@
|
|
|
25
25
|
# DOCUMENT_LLM_MODEL — lightonai/LightOnOCR-2-1B
|
|
26
26
|
# DOCUMENT_LLM_API_KEY — OpenAI/OpenAI-compatible API key for document OCR
|
|
27
27
|
# DOCUMENT_LLM_TIMEOUT_SECONDS — 120
|
|
28
|
+
# GATEWAY_PORT — 7789
|
|
29
|
+
# GATEWAY_ENABLED — false; true to start the agentic runtime gateway
|
|
30
|
+
# GATEWAY_AUTH_TOKEN — bearer token for the gateway (generated if empty);
|
|
31
|
+
# the manager sends it on every call. The model is
|
|
32
|
+
# NOT configured here: the manager sends its active
|
|
33
|
+
# profile model with every run.
|
|
28
34
|
#
|
|
29
35
|
# Set these variables in a .env file at the directory where you run wiki-workspace,
|
|
30
36
|
# or export them in your shell before running wiki-workspace agents up.
|
|
@@ -62,7 +68,7 @@ services:
|
|
|
62
68
|
restart: unless-stopped
|
|
63
69
|
|
|
64
70
|
documents:
|
|
65
|
-
image: dotdrelle/agent-
|
|
71
|
+
image: dotdrelle/agent-documents:latest
|
|
66
72
|
user: "${UID:-1000}:${GID:-1000}"
|
|
67
73
|
ports:
|
|
68
74
|
- "${DOCUMENTS_MCP_PORT:-3337}:8080"
|
|
@@ -134,3 +140,31 @@ services:
|
|
|
134
140
|
- ${AGENTS_DATA_DIR:-./.agents-data}/connectors:/data
|
|
135
141
|
- ${WORKSPACES_ROOT:?Set WORKSPACES_ROOT to the directory containing all workspace folders}:/workspaces
|
|
136
142
|
restart: unless-stopped
|
|
143
|
+
|
|
144
|
+
# Agentic runtime gateway — the external Deep Agents service the manager
|
|
145
|
+
# routes open-ended analysis to (agent-runtimes.json, endpoint 7789).
|
|
146
|
+
# Opt-in like connectors: set GATEWAY_ENABLED=true. The manager never starts
|
|
147
|
+
# this service, only discovers it; its failure leaves every DAG untouched.
|
|
148
|
+
gateway:
|
|
149
|
+
profiles: [gateway]
|
|
150
|
+
image: dotdrelle/wiki-agentic-gateway:latest
|
|
151
|
+
user: "${UID:-1000}:${GID:-1000}"
|
|
152
|
+
ports:
|
|
153
|
+
- "${GATEWAY_PORT:-7789}:7789"
|
|
154
|
+
environment:
|
|
155
|
+
- GATEWAY_CONFIG_DIR=/config
|
|
156
|
+
- GATEWAY_AUTH_TOKEN=${GATEWAY_AUTH_TOKEN:-}
|
|
157
|
+
- NODE_USE_ENV_PROXY=${NODE_USE_ENV_PROXY:-}
|
|
158
|
+
- HTTPS_PROXY=${HTTPS_PROXY:-}
|
|
159
|
+
- HTTP_PROXY=${HTTP_PROXY:-}
|
|
160
|
+
- NO_PROXY=${NO_PROXY:-localhost,127.0.0.1,host.docker.internal}
|
|
161
|
+
extra_hosts:
|
|
162
|
+
- host.docker.internal:host-gateway
|
|
163
|
+
volumes:
|
|
164
|
+
# One file, two readers: the manager routes on agent-runtimes.json, the
|
|
165
|
+
# gateway serves the capabilities of its own entry from the same file.
|
|
166
|
+
# Absolute path, computed by wiki-workspace from the manager state dir.
|
|
167
|
+
- ${AGENT_RUNTIMES_FILE:?Set AGENT_RUNTIMES_FILE}:/config/agent-runtimes.json:ro
|
|
168
|
+
- ${AGENTS_DATA_DIR:-./.agents-data}/gateway:/config
|
|
169
|
+
- ${WORKSPACES_ROOT:?Set WORKSPACES_ROOT to the directory containing all workspace folders}:/workspaces
|
|
170
|
+
restart: unless-stopped
|
package/docker-compose.yml
CHANGED
|
@@ -110,10 +110,10 @@ services:
|
|
|
110
110
|
- host.docker.internal:host-gateway
|
|
111
111
|
restart: unless-stopped
|
|
112
112
|
|
|
113
|
-
# ── agent-
|
|
113
|
+
# ── agent-production ─────────────────────────────────────────────────
|
|
114
114
|
|
|
115
115
|
production-mcp:
|
|
116
|
-
image: dotdrelle/agent-
|
|
116
|
+
image: dotdrelle/agent-production:latest
|
|
117
117
|
user: "${UID:-1000}:${GID:-1000}"
|
|
118
118
|
labels:
|
|
119
119
|
wiki-manager.description: "Production MCP server for ingest/build/export jobs."
|
|
@@ -130,7 +130,7 @@ services:
|
|
|
130
130
|
# error. Every compose-deployed ingest then ran without the Lot 4 barrier
|
|
131
131
|
# and left the published map stale — the very defect that work fixed.
|
|
132
132
|
# `copy` stays out on purpose: it is the legacy step, opt-in only.
|
|
133
|
-
- PRODUCTION_ALLOWED_STEPS=${PRODUCTION_ALLOWED_STEPS:-doctor,ingest,ingest_plan,ingest_apply,
|
|
133
|
+
- PRODUCTION_ALLOWED_STEPS=${PRODUCTION_ALLOWED_STEPS:-doctor,ingest,ingest_plan,ingest_apply,build,export,polish,restore,pipeline}
|
|
134
134
|
- PRODUCTION_REQUIRE_CONFIRMATION=${PRODUCTION_REQUIRE_CONFIRMATION:-false}
|
|
135
135
|
# Parallelism levers — effective concurrency ≈ recommendedConcurrency.
|
|
136
136
|
# Intermediate defaults (4/8). Low profile 2/4, high profile 8/16.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dotdrelle/wiki-manager",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.70",
|
|
4
4
|
"description": "Agentic shell and orchestration cockpit for llm-wiki workspaces.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
},
|
|
20
20
|
"scripts": {
|
|
21
21
|
"start": "bun ./bin/wiki-manager.js",
|
|
22
|
-
"test": "node --test src/core/skillInvocation.test.js src/core/skillCompiler.test.js src/runtime/skillRun.test.js src/runtime/controlDrain.test.js src/runtime/controlCancellation.test.js src/cli/runtimeStartup.test.js src/cli/wiki-manager.test.js src/agent/graph.test.js src/agent/skillRecursion.test.js src/contracts/schemas.test.js src/core/activity.test.js src/core/env.test.js src/core/agentsCompose.test.js src/core/profileServiceStatus.test.js src/core/workspaceProfile.test.js src/core/buildInfo.test.js src/core/agentEvents.test.js src/core/skillChainView.test.js src/core/runtimeLog.test.js src/activity/activityAggregator.test.js src/graph/runGraphProjector.test.js src/core/workflow.test.js src/core/planPatch.test.js src/core/agentLoop.test.js src/core/plan.test.js src/core/mcp.test.js src/core/toolLoop.test.js src/core/documentIntake.test.js src/core/dockerCompose.test.js src/core/otherWorkspacesRunning.test.js src/core/wikiSetup.test.js src/core/wikiWorkspace.test.js src/core/wikirc.test.js src/core/workspaceInherit.test.js src/core/cacert.test.js src/core/composeOverrides.test.js src/core/setEnvValue.test.js src/core/commandFailure.test.js src/core/currentArtifact.test.js src/core/googleGrants.test.js src/core/modelFetch.test.js src/core/startupCheck.test.js src/core/queueStore.test.js src/orchestrator/agentRegistry.test.js src/orchestrator/capabilityRegistry.test.js src/orchestrator/capabilityResolver.test.js src/orchestrator/planValidator.test.js src/orchestrator/planIntegrator.test.js src/orchestrator/taskStatuses.test.js src/orchestrator/scheduler.test.js src/orchestrator/attemptManager.test.js src/orchestrator/resultAggregator.test.js src/orchestrator/approvalPolicy.test.js src/orchestrator/dispatcher.test.js src/orchestrator/objectiveResolver.test.js src/commands/slash.test.js src/shell/repl.test.js src/shell/setupWizardModality.test.js src/shell/setupWizardPlaceholders.test.js src/shell/setupWizardSuggestions.test.js src/shell/setupWizardDiscovery.test.js src/shell/wrapText.test.js src/runtime/lifecycle.test.js src/runtime/store.test.js src/runtime/workspaceIsolation.test.js src/runtime/controlMessages.test.js src/runtime/recoveryManager.test.js src/runtime/server.test.js src/runtime/supervisor.test.js src/runtime/delegation.test.js src/runtime/runner.test.js src/runtime/runner.e2e.test.js src/runtime/skillChain.e2e.test.js src/runtime/donna-contract.test.js src/runtime/approvals.test.js src/runtime/auth.test.js",
|
|
22
|
+
"test": "node --test src/core/skillInvocation.test.js src/core/skillCompiler.test.js src/runtime/skillRun.test.js src/runtime/controlDrain.test.js src/runtime/controlCancellation.test.js src/cli/runtimeStartup.test.js src/cli/wiki-manager.test.js src/agent/graph.test.js src/agent/skillRecursion.test.js src/contracts/schemas.test.js src/core/activity.test.js src/core/env.test.js src/core/agentsCompose.test.js src/core/profileServiceStatus.test.js src/core/workspaceProfile.test.js src/core/buildInfo.test.js src/core/agentEvents.test.js src/core/skillChainView.test.js src/core/runtimeLog.test.js src/core/runtimeEventAdapter.test.js src/activity/activityAggregator.test.js src/graph/runGraphProjector.test.js src/core/workflow.test.js src/core/planPatch.test.js src/core/agentLoop.test.js src/core/plan.test.js src/core/mcp.test.js src/core/toolLoop.test.js src/core/documentIntake.test.js src/core/dockerCompose.test.js src/core/otherWorkspacesRunning.test.js src/core/wikiSetup.test.js src/core/wikiWorkspace.test.js src/core/wikirc.test.js src/core/workspaceInherit.test.js src/core/cacert.test.js src/core/composeOverrides.test.js src/core/setEnvValue.test.js src/core/commandFailure.test.js src/core/currentArtifact.test.js src/core/googleGrants.test.js src/core/modelFetch.test.js src/core/startupCheck.test.js src/core/queueStore.test.js src/orchestrator/agentRegistry.test.js src/orchestrator/capabilityRegistry.test.js src/orchestrator/capabilityResolver.test.js src/orchestrator/planValidator.test.js src/orchestrator/planIntegrator.test.js src/orchestrator/taskStatuses.test.js src/orchestrator/scheduler.test.js src/orchestrator/attemptManager.test.js src/orchestrator/resultAggregator.test.js src/orchestrator/approvalPolicy.test.js src/orchestrator/dispatcher.test.js src/orchestrator/objectiveResolver.test.js src/orchestrator/providers/fakeRuntimeProvider.test.js src/orchestrator/providers/runtimeProviders.test.js src/orchestrator/providers/dispatcherExternalRuntime.test.js src/orchestrator/providers/deepAgentsProvider.test.js src/commands/slash.test.js src/shell/repl.test.js src/shell/setupWizardModality.test.js src/shell/setupWizardPlaceholders.test.js src/shell/setupWizardSuggestions.test.js src/shell/setupWizardDiscovery.test.js src/shell/wrapText.test.js src/runtime/lifecycle.test.js src/runtime/store.test.js src/runtime/workspaceIsolation.test.js src/runtime/controlMessages.test.js src/runtime/recoveryManager.test.js src/runtime/server.test.js src/runtime/supervisor.test.js src/runtime/delegation.test.js src/runtime/runner.test.js src/runtime/runner.e2e.test.js src/runtime/skillChain.e2e.test.js src/runtime/donna-contract.test.js src/runtime/approvals.test.js src/runtime/auth.test.js",
|
|
23
23
|
"check-versions": "node scripts/check-versions.js",
|
|
24
24
|
"prepack": "node scripts/check-versions.js",
|
|
25
25
|
"prepublishOnly": "node scripts/check-versions.js",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"docker-compose.override.example.yml",
|
|
39
39
|
"agents.docker-compose.override.example.yml",
|
|
40
40
|
"mcp.endpoints.example.json",
|
|
41
|
+
"agent-runtimes.example.json",
|
|
41
42
|
".env.example",
|
|
42
43
|
"tsconfig.json",
|
|
43
44
|
"bunfig.toml",
|
package/src/agent/graph.js
CHANGED
|
@@ -891,7 +891,7 @@ export async function handleRuntimeControlTool(session, tool, args = {}) {
|
|
|
891
891
|
delegated: true,
|
|
892
892
|
runId: inRun.runId,
|
|
893
893
|
summary: inRun.summary ?? null,
|
|
894
|
-
message: `Action
|
|
894
|
+
message: `Action started (${String(inRun.runId).slice(0, 8)}) after real-plan validation: ${inRun.summary?.tasks ?? 0} task(s), ${inRun.summary?.agent ?? 'resolved agent'}. Execution in progress.`,
|
|
895
895
|
});
|
|
896
896
|
}
|
|
897
897
|
const result = await postRuntimeDelegate(objective, { url, workspace });
|
|
@@ -900,9 +900,9 @@ export async function handleRuntimeControlTool(session, tool, args = {}) {
|
|
|
900
900
|
delegated: true,
|
|
901
901
|
runId: result.runId,
|
|
902
902
|
summary: result.delegation ?? null,
|
|
903
|
-
message: `Action
|
|
903
|
+
message: `Action started (${String(result.runId).slice(0, 8)}) after real-plan validation: ${result.delegation?.tasks ?? 0} task(s), ${result.delegation?.agent ?? 'resolved agent'}. Execution in progress.`,
|
|
904
904
|
})
|
|
905
|
-
: `
|
|
905
|
+
: `Delegation refused: ${result?.error ?? JSON.stringify(result)}`;
|
|
906
906
|
}
|
|
907
907
|
if (tool === 'run_skill') {
|
|
908
908
|
const skillName = String(args.skillName ?? '').trim();
|
|
@@ -952,12 +952,13 @@ export async function handleRuntimeControlTool(session, tool, args = {}) {
|
|
|
952
952
|
par ressemblance.
|
|
953
953
|
|
|
954
954
|
La garde de cycle ci-dessus ne voit que les répétitions. Elle laissait
|
|
955
|
-
donc passer la cascade réellement observée sur un `/wiki-ingest` :
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
955
|
+
donc passer la cascade réellement observée sur un `/wiki-ingest` : une
|
|
956
|
+
intention compilée décrivait mot pour mot le corps d'une compétence
|
|
957
|
+
sœur, dont l'intention décrivait à son tour la suivante. Trois
|
|
958
|
+
compétences distinctes, aucun cycle, et la grille de concepts comme la
|
|
959
|
+
taxonomie reconstruites plusieurs fois pour une seule demande.
|
|
960
|
+
(Ces compétences sœurs ont disparu avec la simplification 0.15.66 ; la
|
|
961
|
+
garde, elle, reste.)
|
|
961
962
|
|
|
962
963
|
Une intention compilée EST déjà le travail à faire : elle se délègue.
|
|
963
964
|
La composition explicite reste ouverte — un corps qui nomme sa cible dit
|
|
@@ -1266,7 +1267,7 @@ export function buildAgentSystemPrompt(state) {
|
|
|
1266
1267
|
? `Workspace profile (.wiki/profile.md) — durable user preferences, apply these to every reply (tone, tutoiement/vouvoiement, formatting, etc.):\n${workspaceProfile}`
|
|
1267
1268
|
: null,
|
|
1268
1269
|
currentArtifactPromptLine(currentArtifactFor(state.session)),
|
|
1269
|
-
'Runtime control: you have runtime__status, runtime__cancel, runtime__kill and runtime__enqueue. When the user asks to stop, remove, clean or kill the current run, its jobs or the queue ("supprime le job et la queue", "arr\u00eate tout"), call runtime__kill (or runtime__cancel for a soft stop of just the run) and confirm what was stopped. When the user explicitly asks to delete, reset, abandon or replace the current plan, call runtime__kill with purge=true; never set purge=true for a simple stop. For questions about what is running or queued, call runtime__status and answer from its data. You have no approval tool: a pending approval is granted only by the user through the approval button or the /approve command. Never grant, claim or report an approval yourself; when the user asks to proceed with pending mutations, tell them to use those controls. When the user asks for a NEW action while a run is active, do not execute it: propose runtime__enqueue (run it after) or, if they insist it replaces the current work, runtime__kill then the new action.',
|
|
1270
|
+
'Runtime control: you have runtime__status, runtime__cancel, runtime__kill and runtime__enqueue. When the user asks to stop, remove, clean or kill the current run, its jobs or the queue ("supprime le job et la queue", "arr\u00eate tout"), call runtime__kill (or runtime__cancel for a soft stop of just the run) and confirm what was stopped. When the user explicitly asks to delete, reset, abandon or replace the current plan, call runtime__kill with purge=true; never set purge=true for a simple stop. For questions about what is running or queued, call runtime__status and answer from its data. You have no approval tool: a pending approval is granted only by the user through the approval button or the /approve command. Never grant, claim or report an approval yourself; when the user asks to proceed with pending mutations, tell them to use those controls. A request to approve, validate, confirm or accept a pending run is a human control action: NEVER call runtime__delegate (or any capability) for it — answer with the control to use and nothing else. When the user asks for a NEW action while a run is active, do not execute it: propose runtime__enqueue (run it after) or, if they insist it replaces the current work, runtime__kill then the new action.',
|
|
1270
1271
|
'When the user asks to refresh, show, or update the displayed plan or status, call runtime__status. This is a state refresh request, not a new business capability, and must never be delegated.',
|
|
1271
1272
|
'Report every runtime control outcome exactly as the tool returned it \u2014 never embellish. If runtime__kill reports 0 run(s)/0 task(s)/0 purged, say there was nothing active to stop or purge; do NOT claim a run, plan, pending approval or queue item was removed. If runtime__status returns an error or could not be read, say the runtime state could not be retrieved and do not describe a state you never obtained. Never assert that something was cleaned, cancelled, approved or purged unless that specific tool result confirms it.',
|
|
1272
1273
|
'Durable profile updates are actions in this stabilized version: delegate them instead of writing directly.',
|
|
@@ -1295,8 +1296,8 @@ export function buildLimitedAgentResponse(state, reason = 'no workspace loaded w
|
|
|
1295
1296
|
}
|
|
1296
1297
|
|
|
1297
1298
|
export function formatLlmUnavailableMessage(reason) {
|
|
1298
|
-
const clean = String(reason ?? '
|
|
1299
|
-
return `⚠ LLM
|
|
1299
|
+
const clean = String(reason ?? 'unknown reason').replace(/\s+/g, ' ').trim();
|
|
1300
|
+
return `⚠ LLM unavailable: ${clean || 'unknown reason'}`;
|
|
1300
1301
|
}
|
|
1301
1302
|
|
|
1302
1303
|
function toolsForClassification(classification, writeTools, session = null) {
|
|
@@ -1455,7 +1456,7 @@ export function createAgentGraph(options = {}) {
|
|
|
1455
1456
|
const llm = state.session.llm ?? options.llm ?? null;
|
|
1456
1457
|
|
|
1457
1458
|
if (!llm) {
|
|
1458
|
-
return { response: formatLlmUnavailableMessage('
|
|
1459
|
+
return { response: formatLlmUnavailableMessage('no LLM client configured'), pendingToolCalls: null, readyToStream: false };
|
|
1459
1460
|
}
|
|
1460
1461
|
|
|
1461
1462
|
const iterations = state.toolIterations ?? 0;
|
|
@@ -1751,7 +1752,7 @@ export function createAgentGraph(options = {}) {
|
|
|
1751
1752
|
forceDelegation: canDelegate,
|
|
1752
1753
|
};
|
|
1753
1754
|
}
|
|
1754
|
-
const failure = '
|
|
1755
|
+
const failure = 'Response rejected: Donna exposed an internal instruction or an incorrect manual procedure.';
|
|
1755
1756
|
emitAgentEvent(state.session, 'assistant_message', 'agent_guard', { content: failure });
|
|
1756
1757
|
return { response: failure, pendingToolCalls: null, readyToStream: false };
|
|
1757
1758
|
}
|
package/src/agent/graph.test.js
CHANGED
|
@@ -292,7 +292,7 @@ test('agent graph reports LLM unavailable without Donna active boilerplate', asy
|
|
|
292
292
|
const agent = createAgentGraph();
|
|
293
293
|
const result = await agent.invoke({ input: 'salut', session: sessionBase({ llm: null }) });
|
|
294
294
|
|
|
295
|
-
assert.equal(result.response, '⚠ LLM
|
|
295
|
+
assert.equal(result.response, '⚠ LLM unavailable: no LLM client configured');
|
|
296
296
|
assert.doesNotMatch(result.response, /Donna is active/);
|
|
297
297
|
});
|
|
298
298
|
|
|
@@ -98,21 +98,22 @@ test('borne la profondeur même sans cycle', async () => {
|
|
|
98
98
|
});
|
|
99
99
|
|
|
100
100
|
/*
|
|
101
|
-
Cascade observée
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
101
|
+
Cascade observée à l'époque des compétences concepts : un `/wiki-ingest`
|
|
102
|
+
relançait les compétences voisines plusieurs fois pour une seule demande,
|
|
103
|
+
parce que la deuxième intention compilée était mot pour mot le corps d'une
|
|
104
|
+
compétence sœur et que le sélecteur par description la reconnaissait
|
|
105
|
+
légitimement. Ces compétences (rebuild-concepts/reclassify/taxonomy) ont
|
|
106
|
+
disparu avec la simplification 0.15.66 ; la garde contre la récursion, elle,
|
|
107
|
+
reste — c'est elle que ces tests verrouillent.
|
|
107
108
|
*/
|
|
108
109
|
const callWithObjective = (state, skillName, objective) =>
|
|
109
110
|
handleRuntimeControlTool(state, 'run_skill', { skillName, _userInput: objective })
|
|
110
111
|
.then((raw) => JSON.parse(raw));
|
|
111
112
|
|
|
112
113
|
test('refuse une compétence voisine que l’intention décrit sans la nommer', async () => {
|
|
113
|
-
const objective = 'Run the production pipeline steps
|
|
114
|
+
const objective = 'Run the production pipeline steps ingest, build, export and polish, in that order.';
|
|
114
115
|
const ran = [];
|
|
115
|
-
const result = await callWithObjective(session(['wiki-ingest'], ran), 'wiki-
|
|
116
|
+
const result = await callWithObjective(session(['wiki-ingest'], ran), 'wiki-build', objective);
|
|
116
117
|
|
|
117
118
|
assert.equal(result.ok, false);
|
|
118
119
|
assert.equal(result.code, 'nested_skill_match_blocked');
|
|
@@ -145,20 +146,20 @@ test('un chemin de fichier commençant par un nom de compétence ne vaut pas inv
|
|
|
145
146
|
});
|
|
146
147
|
|
|
147
148
|
test('hors de toute chaîne, la sélection par description reste permise', async () => {
|
|
148
|
-
const result = await callWithObjective(session(undefined), 'wiki-
|
|
149
|
+
const result = await callWithObjective(session(undefined), 'wiki-build', 'regenerate the deliverables from the templates');
|
|
149
150
|
|
|
150
151
|
assert.equal(result.ok, true);
|
|
151
152
|
});
|
|
152
153
|
|
|
153
154
|
/*
|
|
154
155
|
Le nom seul ne prouve rien. Plusieurs compétences du scaffold portent un nom
|
|
155
|
-
qui est aussi un mot courant : « Run the production pipeline steps
|
|
156
|
-
|
|
156
|
+
qui est aussi un mot courant : « Run the production pipeline steps ingest,
|
|
157
|
+
build, export and polish » nomme `pipeline`, dont le lancement rejoue
|
|
157
158
|
ingest + build + export + polish. Une intention doit citer sa cible EN TANT QUE
|
|
158
159
|
compétence, pas l'employer comme mot.
|
|
159
160
|
*/
|
|
160
161
|
test('un nom employé comme mot courant ne vaut pas invocation', async () => {
|
|
161
|
-
const objective = 'Run the production pipeline steps
|
|
162
|
+
const objective = 'Run the production pipeline steps ingest, build, export and polish, in that order.';
|
|
162
163
|
const ran = [];
|
|
163
164
|
const result = await callWithObjective(session(['wiki-ingest'], ran), 'pipeline', objective);
|
|
164
165
|
|