@dotdrelle/wiki-manager 0.15.96 → 0.15.98
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/package.json +2 -2
- package/src/agent/graph.js +62 -5
- package/src/agent/graph.test.js +113 -1
- package/src/cli/wiki-manager.js +47 -33
- package/src/commands/slash.js +7 -2
- package/src/core/agentEvents.js +31 -1
- package/src/core/agentEvents.test.js +59 -0
- package/src/core/buildInfo.json +2 -2
- package/src/core/mcp.js +1 -1
- package/src/core/testGate.test.js +33 -0
- package/src/core/toolLoop.js +7 -1
- package/src/runtime/controlClassify.test.js +31 -0
- package/src/runtime/runner.js +13 -4
- package/src/runtime/runner.test.js +20 -0
- package/src/runtime/server.js +173 -35
- package/src/runtime/server.test.js +145 -14
- package/src/runtime/skillRun.js +2 -2
- package/src/runtime/skillRun.test.js +5 -3
- package/src/shell/openExternal.js +43 -0
- package/src/shell/repl.js +1 -1
package/src/runtime/skillRun.js
CHANGED
|
@@ -165,7 +165,7 @@ export async function generateSkillAcknowledgment(session, { publicInput, object
|
|
|
165
165
|
// slow provider must not block the skill-launch HTTP response forever.
|
|
166
166
|
const reply = await llm.complete({
|
|
167
167
|
system: 'You are Donna, the workspace assistant. You acknowledge a launched workflow in the user\'s language. Be concise: exactly one short sentence.',
|
|
168
|
-
input: `The user just launched the workspace skill ${publicInput}. It was compiled into ${count} step(s) and
|
|
168
|
+
input: `The user just launched the workspace skill ${publicInput}. It was compiled into ${count} step(s) and has been queued.\n\nWrite ONE short sentence in ${language} that confirms the launch, echoes the skill and its arguments, and says progress will be reported. Do not claim the work is running, executing or done: a mutating step waits for the user's approval before it runs. Do not ask a question, do not propose options, and do not offer to check, monitor or cancel anything: the runtime reports progress on its own and this acknowledgement is not a decision point. Return only that sentence, nothing else.`,
|
|
169
169
|
signal: AbortSignal.timeout(8_000),
|
|
170
170
|
});
|
|
171
171
|
const text = String(reply ?? '').trim();
|
|
@@ -179,7 +179,7 @@ export async function generateSkillAcknowledgment(session, { publicInput, object
|
|
|
179
179
|
emitRuntimeLog(session, `skill-acknowledgment: LLM call failed, using the neutral fallback — ${err instanceof Error ? err.message : String(err)}`);
|
|
180
180
|
}
|
|
181
181
|
}
|
|
182
|
-
return `Started ${publicInput} — ${count} step(s)
|
|
182
|
+
return `Started ${publicInput} — ${count} step(s) queued.`;
|
|
183
183
|
}
|
|
184
184
|
|
|
185
185
|
function argumentError(message) {
|
|
@@ -95,19 +95,21 @@ test('generateSkillAcknowledgment asks Donna in the session language and echoes
|
|
|
95
95
|
assert.match(calls[0].input, /es/);
|
|
96
96
|
assert.match(calls[0].input, /\/deliver deliverable="Informe"/);
|
|
97
97
|
// The acknowledgement is not a decision point: it must not invite the user
|
|
98
|
-
// into a dialog the runtime cannot act on
|
|
98
|
+
// into a dialog the runtime cannot act on, and it must not claim the work is
|
|
99
|
+
// already executing — a mutating step waits for approval.
|
|
99
100
|
assert.match(calls[0].input, /Do not ask a question/);
|
|
101
|
+
assert.match(calls[0].input, /Do not claim the work is running/);
|
|
100
102
|
});
|
|
101
103
|
|
|
102
104
|
test('generateSkillAcknowledgment degrades to a neutral message without an LLM client', async () => {
|
|
103
105
|
const reply = await generateSkillAcknowledgment({ language: 'fr' }, { publicInput: '/wiki-ingest docs', objectives: 2 });
|
|
104
|
-
assert.equal(reply, 'Started /wiki-ingest docs — 2 step(s)
|
|
106
|
+
assert.equal(reply, 'Started /wiki-ingest docs — 2 step(s) queued.');
|
|
105
107
|
});
|
|
106
108
|
|
|
107
109
|
test('generateSkillAcknowledgment falls back when the LLM call fails', async () => {
|
|
108
110
|
const session = { language: 'en', llm: { complete: async () => { throw new Error('down'); } } };
|
|
109
111
|
const reply = await generateSkillAcknowledgment(session, { publicInput: '/deliver', objectives: 1 });
|
|
110
|
-
assert.equal(reply, 'Started /deliver — 1 step(s)
|
|
112
|
+
assert.equal(reply, 'Started /deliver — 1 step(s) queued.');
|
|
111
113
|
});
|
|
112
114
|
|
|
113
115
|
test('generateSkillAcknowledgment announces an LLM failure instead of degrading silently', async () => {
|
|
@@ -51,3 +51,46 @@ export function openExternalUrl(value, { run = execFileSync } = {}) {
|
|
|
51
51
|
}
|
|
52
52
|
return null;
|
|
53
53
|
}
|
|
54
|
+
|
|
55
|
+
// A Chromium `--app=<url>` window is chromeless from the start — no tab
|
|
56
|
+
// strip, no address bar — and, when the origin serves a manifest (llm-wiki's
|
|
57
|
+
// `/manifest.webmanifest`), it picks up the site's name/icon/theme-color and
|
|
58
|
+
// window-controls-overlay exactly like a formally "installed" PWA, with no
|
|
59
|
+
// prior install step required. `/openui`'s whole point is a desktop-feeling
|
|
60
|
+
// window, so it tries this before falling back to `openExternalUrl`'s plain
|
|
61
|
+
// tab. Same candidate/fallback shape as `openerCandidates` above, and the same
|
|
62
|
+
// contract: returns the opened URL, or null when no Chromium browser answered.
|
|
63
|
+
function appModeCandidates() {
|
|
64
|
+
if (process.platform === 'darwin') {
|
|
65
|
+
return [
|
|
66
|
+
['open', ['-na', 'Google Chrome', '--args']],
|
|
67
|
+
['open', ['-na', 'Microsoft Edge', '--args']],
|
|
68
|
+
];
|
|
69
|
+
}
|
|
70
|
+
if (process.platform === 'win32') {
|
|
71
|
+
return [
|
|
72
|
+
['cmd', ['/c', 'start', '', 'chrome']],
|
|
73
|
+
['cmd', ['/c', 'start', '', 'msedge']],
|
|
74
|
+
];
|
|
75
|
+
}
|
|
76
|
+
return [
|
|
77
|
+
['google-chrome', []],
|
|
78
|
+
['chromium', []],
|
|
79
|
+
['chromium-browser', []],
|
|
80
|
+
['microsoft-edge', []],
|
|
81
|
+
];
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function openAppWindowUrl(value, { run = execFileSync } = {}) {
|
|
85
|
+
const url = normalizeExternalUrl(value);
|
|
86
|
+
if (!url) return null;
|
|
87
|
+
for (const [command, args] of appModeCandidates()) {
|
|
88
|
+
try {
|
|
89
|
+
run(command, [...args, `--app=${url}`], { stdio: 'ignore', timeout: 5_000 });
|
|
90
|
+
return url;
|
|
91
|
+
} catch {
|
|
92
|
+
// Missing binary or non-zero exit: try the next candidate.
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return null;
|
|
96
|
+
}
|
package/src/shell/repl.js
CHANGED
|
@@ -94,7 +94,7 @@ const COMMAND_COMPLETION_DESCRIPTIONS = {
|
|
|
94
94
|
'/clear': 'Clear the conversation screen.',
|
|
95
95
|
'/chat': 'Switch free text to direct LLM chat without tools.',
|
|
96
96
|
'/agent': 'Switch to agent mode, or run one agent request with /agent <question>.',
|
|
97
|
-
'/openui': 'Open the workspace web UI
|
|
97
|
+
'/openui': 'Open the workspace web UI as a chromeless desktop window (Chrome/Edge), or a browser tab as fallback.',
|
|
98
98
|
'/run': 'Inspect, cancel, kill runtime runs, or start a capability run.',
|
|
99
99
|
'/approve': 'Approve a pending runtime run or tool.',
|
|
100
100
|
};
|