negotium 0.1.7 → 0.1.8
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 +2 -2
- package/dist/chunk-0ay6cjdy.js +1331 -0
- package/dist/chunk-0ay6cjdy.js.map +16 -0
- package/dist/chunk-1k7t7bnx.js +97 -0
- package/dist/chunk-1k7t7bnx.js.map +10 -0
- package/dist/chunk-5ahkew9c.js +806 -0
- package/dist/chunk-5ahkew9c.js.map +17 -0
- package/dist/chunk-6cpn7ht2.js +287 -0
- package/dist/chunk-6cpn7ht2.js.map +13 -0
- package/dist/chunk-6kctn20e.js +3529 -0
- package/dist/chunk-6kctn20e.js.map +20 -0
- package/dist/chunk-7xqj7aex.js +77 -0
- package/dist/chunk-7xqj7aex.js.map +11 -0
- package/dist/chunk-9p0ww3tk.js +41 -0
- package/dist/chunk-9p0ww3tk.js.map +10 -0
- package/dist/chunk-a92a7nrk.js +252 -0
- package/dist/chunk-a92a7nrk.js.map +10 -0
- package/dist/chunk-c500xe9z.js +33 -0
- package/dist/chunk-c500xe9z.js.map +10 -0
- package/dist/chunk-cds1qxsf.js +1644 -0
- package/dist/chunk-cds1qxsf.js.map +17 -0
- package/dist/chunk-e4407g8x.js +274 -0
- package/dist/chunk-e4407g8x.js.map +10 -0
- package/dist/chunk-e5pbggsh.js +363 -0
- package/dist/chunk-e5pbggsh.js.map +11 -0
- package/dist/chunk-edb07sjp.js +567 -0
- package/dist/chunk-edb07sjp.js.map +14 -0
- package/dist/chunk-exd0v74a.js +3012 -0
- package/dist/chunk-exd0v74a.js.map +32 -0
- package/dist/chunk-fgrme9tr.js +4398 -0
- package/dist/chunk-fgrme9tr.js.map +47 -0
- package/dist/chunk-fka9eqe1.js +581 -0
- package/dist/chunk-fka9eqe1.js.map +11 -0
- package/dist/chunk-g82jygez.js +108 -0
- package/dist/chunk-g82jygez.js.map +10 -0
- package/dist/chunk-ghs2j1fr.js +312 -0
- package/dist/chunk-ghs2j1fr.js.map +10 -0
- package/dist/chunk-gmy11efb.js +125 -0
- package/dist/chunk-gmy11efb.js.map +10 -0
- package/dist/chunk-gxma4c70.js +110 -0
- package/dist/chunk-gxma4c70.js.map +10 -0
- package/dist/chunk-hkdqhm34.js +61 -0
- package/dist/chunk-hkdqhm34.js.map +10 -0
- package/dist/chunk-hpa0cpzh.js +134 -0
- package/dist/chunk-hpa0cpzh.js.map +10 -0
- package/dist/chunk-hwy3n31w.js +21 -0
- package/dist/chunk-hwy3n31w.js.map +9 -0
- package/dist/chunk-j2behpy7.js +214 -0
- package/dist/chunk-j2behpy7.js.map +10 -0
- package/dist/chunk-jc0at0tc.js +102 -0
- package/dist/chunk-jc0at0tc.js.map +10 -0
- package/dist/chunk-jkqq5ef6.js +243 -0
- package/dist/chunk-jkqq5ef6.js.map +11 -0
- package/dist/chunk-jzkw2f01.js +51 -0
- package/dist/chunk-jzkw2f01.js.map +10 -0
- package/dist/chunk-jzz91jwh.js +70 -0
- package/dist/chunk-jzz91jwh.js.map +10 -0
- package/dist/chunk-k9z47mab.js +247 -0
- package/dist/chunk-k9z47mab.js.map +12 -0
- package/dist/chunk-n17yxpa8.js +23 -0
- package/dist/chunk-n17yxpa8.js.map +10 -0
- package/dist/chunk-naa09ags.js +2143 -0
- package/dist/chunk-naa09ags.js.map +15 -0
- package/dist/chunk-ns3ke88n.js +142 -0
- package/dist/chunk-ns3ke88n.js.map +10 -0
- package/dist/chunk-p3cr2ejg.js +1626 -0
- package/dist/chunk-p3cr2ejg.js.map +15 -0
- package/dist/chunk-q5bcpf23.js +2925 -0
- package/dist/chunk-q5bcpf23.js.map +20 -0
- package/dist/chunk-rafc55bs.js +424 -0
- package/dist/chunk-rafc55bs.js.map +11 -0
- package/dist/chunk-rbrxjvbj.js +2830 -0
- package/dist/chunk-rbrxjvbj.js.map +23 -0
- package/dist/chunk-sa874j5c.js +9 -0
- package/dist/chunk-sa874j5c.js.map +10 -0
- package/dist/chunk-sgsz2fpq.js +289 -0
- package/dist/chunk-sgsz2fpq.js.map +10 -0
- package/dist/chunk-sm6fh5c5.js +569 -0
- package/dist/chunk-sm6fh5c5.js.map +14 -0
- package/dist/chunk-t9zcg8f1.js +499 -0
- package/dist/chunk-t9zcg8f1.js.map +13 -0
- package/dist/chunk-vp2db42d.js +121 -0
- package/dist/chunk-vp2db42d.js.map +10 -0
- package/dist/chunk-w13jjf4a.js +46 -0
- package/dist/chunk-w13jjf4a.js.map +10 -0
- package/dist/chunk-x1arr7ze.js +63 -0
- package/dist/chunk-x1arr7ze.js.map +10 -0
- package/dist/chunk-xfq68rch.js +583 -0
- package/dist/chunk-xfq68rch.js.map +11 -0
- package/dist/main.js +132 -20
- package/dist/main.js.map +4 -4
- package/dist/runtime/scripts/faster-whisper-wrapper.py +87 -0
- package/dist/runtime/scripts/mcp-patchright-http.mjs +349 -0
- package/dist/runtime/src/agents/api-topic-agent-switch.ts +178 -0
- package/dist/runtime/src/agents/archiver.ts +396 -0
- package/dist/runtime/src/agents/auth-check.ts +64 -0
- package/dist/runtime/src/agents/claude-provider.ts +737 -0
- package/dist/runtime/src/agents/claude-registry.ts +115 -0
- package/dist/runtime/src/agents/codex-native-multi-agent.ts +177 -0
- package/dist/runtime/src/agents/codex-provider.ts +785 -0
- package/dist/runtime/src/agents/codex-registry.ts +115 -0
- package/dist/runtime/src/agents/codex-tree-kill.ts +365 -0
- package/dist/runtime/src/agents/contracts.ts +69 -0
- package/dist/runtime/src/agents/deep-map.ts +13 -0
- package/dist/runtime/src/agents/execution-host.ts +91 -0
- package/dist/runtime/src/agents/fixtures/claude-attachments.jsonl +2 -0
- package/dist/runtime/src/agents/fixtures/codex-shell.jsonl +5 -0
- package/dist/runtime/src/agents/fork.ts +65 -0
- package/dist/runtime/src/agents/hosted-agent.ts +48 -0
- package/dist/runtime/src/agents/idle-archiver.ts +128 -0
- package/dist/runtime/src/agents/index.ts +205 -0
- package/dist/runtime/src/agents/maestro-provider.ts +206 -0
- package/dist/runtime/src/agents/maestro-registry.ts +31 -0
- package/dist/runtime/src/agents/mcp-tools/ask-user.ts +280 -0
- package/dist/runtime/src/agents/mcp-tools/common.ts +21 -0
- package/dist/runtime/src/agents/mcp-tools/self-config.ts +220 -0
- package/dist/runtime/src/agents/mcp-tools/spawn-subagent.ts +525 -0
- package/dist/runtime/src/agents/mcp-tools/visuals.ts +88 -0
- package/dist/runtime/src/agents/model-catalog.ts +151 -0
- package/dist/runtime/src/agents/registry.ts +24 -0
- package/dist/runtime/src/agents/rollout/claude.ts +331 -0
- package/dist/runtime/src/agents/rollout/codex.ts +569 -0
- package/dist/runtime/src/agents/rollout/shared.ts +205 -0
- package/dist/runtime/src/agents/self-config-core.ts +415 -0
- package/dist/runtime/src/agents/task-events.ts +44 -0
- package/dist/runtime/src/agents/tool-format.ts +352 -0
- package/dist/runtime/src/agents/topic-agent-switch.ts +193 -0
- package/dist/runtime/src/agents/topic-cleanup.ts +231 -0
- package/dist/runtime/src/agents/vault-tool-policy.ts +33 -0
- package/dist/runtime/src/application/execute-external-user-turn.ts +23 -0
- package/dist/runtime/src/application/submit-user-message.ts +47 -0
- package/dist/runtime/src/application/switch-topic-effort.ts +48 -0
- package/dist/runtime/src/application/switch-topic-model.ts +79 -0
- package/dist/runtime/src/application/topic-service.ts +139 -0
- package/dist/runtime/src/application/vault-command.ts +170 -0
- package/dist/runtime/src/bus.ts +319 -0
- package/dist/runtime/src/index.ts +333 -0
- package/dist/runtime/src/mcp/agent-health-server.ts +309 -0
- package/dist/runtime/src/mcp/background-bash-server.ts +346 -0
- package/dist/runtime/src/mcp/canonical-bridge-config.ts +84 -0
- package/dist/runtime/src/mcp/canonical-proxy-server.ts +171 -0
- package/dist/runtime/src/mcp/dm-ipc.ts +60 -0
- package/dist/runtime/src/mcp/mcp-helpers.ts +40 -0
- package/dist/runtime/src/mcp/paddleocr-server.ts +105 -0
- package/dist/runtime/src/mcp/peer-bridge.ts +114 -0
- package/dist/runtime/src/mcp/runtime-spec.ts +134 -0
- package/dist/runtime/src/mcp/session-comm/bridge-ipc-config.ts +27 -0
- package/dist/runtime/src/mcp/session-comm/peer-forward.ts +165 -0
- package/dist/runtime/src/mcp/session-comm/runtime.ts +115 -0
- package/dist/runtime/src/mcp/session-comm/server.ts +649 -0
- package/dist/runtime/src/mcp/session-comm/topic-config.ts +131 -0
- package/dist/runtime/src/mcp/session-comm/topics.ts +229 -0
- package/dist/runtime/src/mcp/stdio-protect.ts +84 -0
- package/dist/runtime/src/mcp/system-health-server.ts +130 -0
- package/dist/runtime/src/mcp/task-server.ts +173 -0
- package/dist/runtime/src/mcp/token-stats-server.ts +98 -0
- package/dist/runtime/src/mcp/vault-http.ts +219 -0
- package/dist/runtime/src/mcp/vault-run.ts +153 -0
- package/dist/runtime/src/mcp/vault-server.ts +104 -0
- package/dist/runtime/src/mcp/wiki-server.ts +755 -0
- package/dist/runtime/src/media/file-events.ts +33 -0
- package/dist/runtime/src/media/text-extractor.ts +312 -0
- package/dist/runtime/src/media/video.ts +92 -0
- package/dist/runtime/src/outbox/file-ops.ts +210 -0
- package/dist/runtime/src/outbox/index.ts +8 -0
- package/dist/runtime/src/outbox/utils.ts +51 -0
- package/dist/runtime/src/platform/background-bash/manager.ts +279 -0
- package/dist/runtime/src/platform/config.ts +371 -0
- package/dist/runtime/src/platform/constants.ts +18 -0
- package/dist/runtime/src/platform/debug-users.ts +14 -0
- package/dist/runtime/src/platform/delay.ts +1 -0
- package/dist/runtime/src/platform/error.ts +9 -0
- package/dist/runtime/src/platform/file-utils.ts +16 -0
- package/dist/runtime/src/platform/jsonl.ts +202 -0
- package/dist/runtime/src/platform/lifecycle.ts +174 -0
- package/dist/runtime/src/platform/logger.ts +31 -0
- package/dist/runtime/src/platform/maestro-bootstrap-env.ts +3 -0
- package/dist/runtime/src/platform/mcp-config.ts +865 -0
- package/dist/runtime/src/platform/modules.ts +145 -0
- package/dist/runtime/src/platform/node-plugins.ts +46 -0
- package/dist/runtime/src/platform/playwright/manager.ts +1233 -0
- package/dist/runtime/src/prompts/agents/wiki-archiver.md +261 -0
- package/dist/runtime/src/prompts/builders.ts +357 -0
- package/dist/runtime/src/prompts/sessions/channel-system.md +48 -0
- package/dist/runtime/src/prompts/sessions/manager-system.md +37 -0
- package/dist/runtime/src/prompts/sessions/topic-system.md +47 -0
- package/dist/runtime/src/prompts/sessions/visual-design.md +86 -0
- package/dist/runtime/src/query/active-rooms.ts +532 -0
- package/dist/runtime/src/query/control.ts +313 -0
- package/dist/runtime/src/query/index.ts +24 -0
- package/dist/runtime/src/query/session-inbox-cleanup.ts +44 -0
- package/dist/runtime/src/query/session-inbox-path.ts +42 -0
- package/dist/runtime/src/query/state.ts +94 -0
- package/dist/runtime/src/query/types.ts +83 -0
- package/dist/runtime/src/runtime/ask-callbacks.ts +153 -0
- package/dist/runtime/src/runtime/attachments.ts +151 -0
- package/dist/runtime/src/runtime/background-sessions.ts +83 -0
- package/dist/runtime/src/runtime/channel-context.ts +107 -0
- package/dist/runtime/src/runtime/errors.ts +69 -0
- package/dist/runtime/src/runtime/event-heartbeat.ts +77 -0
- package/dist/runtime/src/runtime/file-hooks.ts +81 -0
- package/dist/runtime/src/runtime/footer.ts +23 -0
- package/dist/runtime/src/runtime/inbox.ts +946 -0
- package/dist/runtime/src/runtime/tasks.ts +56 -0
- package/dist/runtime/src/runtime/topic-config.ts +29 -0
- package/dist/runtime/src/runtime/turn-runner.ts +2286 -0
- package/dist/runtime/src/runtime/usage-alert.ts +84 -0
- package/dist/runtime/src/runtime/visual-html.ts +109 -0
- package/dist/runtime/src/runtime/visual-store.ts +430 -0
- package/dist/runtime/src/runtime/visuals.ts +171 -0
- package/dist/runtime/src/security/sanitize.ts +27 -0
- package/dist/runtime/src/security/sensitive-path.ts +34 -0
- package/dist/runtime/src/storage/activity-log.ts +152 -0
- package/dist/runtime/src/storage/api-messages.ts +617 -0
- package/dist/runtime/src/storage/api-topic-brief.ts +127 -0
- package/dist/runtime/src/storage/api-topic-config.ts +192 -0
- package/dist/runtime/src/storage/api-topics.ts +844 -0
- package/dist/runtime/src/storage/app-settings.ts +44 -0
- package/dist/runtime/src/storage/browser-profiles.ts +133 -0
- package/dist/runtime/src/storage/conversations.ts +268 -0
- package/dist/runtime/src/storage/forum/agent-settings.ts +20 -0
- package/dist/runtime/src/storage/forum/index.ts +4 -0
- package/dist/runtime/src/storage/forum/repository.ts +283 -0
- package/dist/runtime/src/storage/forum/schema.ts +300 -0
- package/dist/runtime/src/storage/forum-db.ts +23 -0
- package/dist/runtime/src/storage/runtime-events.ts +130 -0
- package/dist/runtime/src/storage/runtime-leases.ts +189 -0
- package/dist/runtime/src/storage/runtime-process-leases.ts +216 -0
- package/dist/runtime/src/storage/runtime-topic-state.ts +148 -0
- package/dist/runtime/src/storage/runtime-turn-requests.ts +300 -0
- package/dist/runtime/src/storage/self-schedules.ts +298 -0
- package/dist/runtime/src/storage/session-asks.ts +347 -0
- package/dist/runtime/src/storage/sqlite.ts +129 -0
- package/dist/runtime/src/storage/tasks.ts +179 -0
- package/dist/runtime/src/storage/token-stats.ts +144 -0
- package/dist/runtime/src/storage/topic-archive-state.ts +59 -0
- package/dist/runtime/src/storage/topic-archive.ts +74 -0
- package/dist/runtime/src/storage/topic-settings.ts +67 -0
- package/dist/runtime/src/storage/topic-transcript.ts +98 -0
- package/dist/runtime/src/storage/vault-crypto.ts +65 -0
- package/dist/runtime/src/storage/vault.ts +225 -0
- package/dist/runtime/src/storage/wiki-summary-names.ts +33 -0
- package/dist/runtime/src/storage/wiki.ts +85 -0
- package/dist/runtime/src/topics/create.ts +123 -0
- package/dist/runtime/src/topics/derive.ts +398 -0
- package/dist/runtime/src/topics/lifecycle.ts +311 -0
- package/dist/runtime/src/topics/links.ts +7 -0
- package/dist/runtime/src/topics/personal-general.ts +65 -0
- package/dist/runtime/src/topics/session.ts +381 -0
- package/dist/runtime/src/types/api.ts +497 -0
- package/dist/runtime/src/types.ts +255 -0
- package/dist/runtime/src/version.ts +1 -0
- package/dist/runtime/tsconfig.json +13 -0
- package/package.json +16 -3
- package/dist/main.d.ts +0 -3
- package/dist/main.d.ts.map +0 -1
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
PENDING_ASK_TTL_MS
|
|
4
|
+
} from "./chunk-sgsz2fpq.js";
|
|
5
|
+
import {
|
|
6
|
+
deliverPeerReply
|
|
7
|
+
} from "./chunk-1k7t7bnx.js";
|
|
8
|
+
import {
|
|
9
|
+
db
|
|
10
|
+
} from "./chunk-7xqj7aex.js";
|
|
11
|
+
import"./chunk-k9z47mab.js";
|
|
12
|
+
import"./chunk-hwy3n31w.js";
|
|
13
|
+
|
|
14
|
+
// ../../packages/core/src/runtime/ask-callbacks.ts
|
|
15
|
+
db.exec(`
|
|
16
|
+
CREATE TABLE IF NOT EXISTS remote_ask_callbacks (
|
|
17
|
+
target_query_id TEXT PRIMARY KEY,
|
|
18
|
+
request_id TEXT NOT NULL,
|
|
19
|
+
node_name TEXT NOT NULL,
|
|
20
|
+
node_cell_id TEXT NOT NULL,
|
|
21
|
+
topic_id TEXT NOT NULL,
|
|
22
|
+
user_id TEXT NOT NULL,
|
|
23
|
+
created_at INTEGER NOT NULL
|
|
24
|
+
)
|
|
25
|
+
`);
|
|
26
|
+
var pendingAsks = new Map;
|
|
27
|
+
var MAX_ASK_AGE_MS = PENDING_ASK_TTL_MS;
|
|
28
|
+
function registerAskCallback(entry) {
|
|
29
|
+
pendingAsks.set(entry.targetQueryId, entry);
|
|
30
|
+
if (entry.remoteReply) {
|
|
31
|
+
db.query(`INSERT INTO remote_ask_callbacks
|
|
32
|
+
(target_query_id, request_id, node_name, node_cell_id, topic_id, user_id, created_at)
|
|
33
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
34
|
+
ON CONFLICT(target_query_id) DO UPDATE SET
|
|
35
|
+
request_id = excluded.request_id,
|
|
36
|
+
node_name = excluded.node_name,
|
|
37
|
+
node_cell_id = excluded.node_cell_id,
|
|
38
|
+
topic_id = excluded.topic_id,
|
|
39
|
+
user_id = excluded.user_id,
|
|
40
|
+
created_at = excluded.created_at`).run(entry.targetQueryId, entry.remoteReply.requestId, entry.remoteReply.nodeName, entry.remoteReply.nodeCellId, entry.remoteReply.topicId, entry.remoteReply.userId, entry.createdAt);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function resolveAskCallback(queryId) {
|
|
44
|
+
const entry = pendingAsks.get(queryId);
|
|
45
|
+
if (!entry)
|
|
46
|
+
return null;
|
|
47
|
+
if (Date.now() - entry.createdAt > MAX_ASK_AGE_MS) {
|
|
48
|
+
entry.timedOut = true;
|
|
49
|
+
}
|
|
50
|
+
pendingAsks.delete(queryId);
|
|
51
|
+
db.query("DELETE FROM remote_ask_callbacks WHERE target_query_id = ?").run(queryId);
|
|
52
|
+
return entry;
|
|
53
|
+
}
|
|
54
|
+
function purgeStaleAsks(now = Date.now()) {
|
|
55
|
+
for (const [id, entry] of pendingAsks) {
|
|
56
|
+
if (now - entry.createdAt > MAX_ASK_AGE_MS)
|
|
57
|
+
pendingAsks.delete(id);
|
|
58
|
+
}
|
|
59
|
+
db.query("DELETE FROM remote_ask_callbacks WHERE created_at < ?").run(now - MAX_ASK_AGE_MS);
|
|
60
|
+
}
|
|
61
|
+
function cancelAskCallbacksForTopic(topicId) {
|
|
62
|
+
let cancelled = 0;
|
|
63
|
+
for (const [queryId, entry] of pendingAsks) {
|
|
64
|
+
if (entry.callerTopicId !== topicId)
|
|
65
|
+
continue;
|
|
66
|
+
pendingAsks.delete(queryId);
|
|
67
|
+
db.query("DELETE FROM remote_ask_callbacks WHERE target_query_id = ?").run(queryId);
|
|
68
|
+
cancelled++;
|
|
69
|
+
}
|
|
70
|
+
return cancelled;
|
|
71
|
+
}
|
|
72
|
+
async function failInterruptedRemoteAskCallbacks() {
|
|
73
|
+
const rows = db.query(`SELECT target_query_id, request_id, node_name, node_cell_id, topic_id, user_id
|
|
74
|
+
FROM remote_ask_callbacks
|
|
75
|
+
ORDER BY created_at ASC`).all();
|
|
76
|
+
let failed = 0;
|
|
77
|
+
for (const row of rows) {
|
|
78
|
+
const delivered = await deliverPeerReply({
|
|
79
|
+
nodeName: row.node_name,
|
|
80
|
+
nodeCellId: row.node_cell_id,
|
|
81
|
+
topicId: row.topic_id,
|
|
82
|
+
userId: row.user_id,
|
|
83
|
+
requestId: row.request_id
|
|
84
|
+
}, "peer", "The remote worker restarted before this ask completed. Please retry the request.", "error");
|
|
85
|
+
if (!delivered)
|
|
86
|
+
continue;
|
|
87
|
+
db.query("DELETE FROM remote_ask_callbacks WHERE target_query_id = ?").run(row.target_query_id);
|
|
88
|
+
failed++;
|
|
89
|
+
}
|
|
90
|
+
return failed;
|
|
91
|
+
}
|
|
92
|
+
export {
|
|
93
|
+
resolveAskCallback,
|
|
94
|
+
registerAskCallback,
|
|
95
|
+
purgeStaleAsks,
|
|
96
|
+
failInterruptedRemoteAskCallbacks,
|
|
97
|
+
cancelAskCallbacksForTopic
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
export { registerAskCallback, resolveAskCallback, cancelAskCallbacksForTopic, failInterruptedRemoteAskCallbacks };
|
|
101
|
+
|
|
102
|
+
//# debugId=348F6EFA936C4E6A64756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../packages/core/src/runtime/ask-callbacks.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/**\n * Ask callback registry (requestId → caller topic + cleanup).\n *\n * ask_session registers a callback here after the target AI turn is\n * dispatched; when the target AI completes, the turn runner resolves it and\n * routes the result back to the caller topic automatically.\n *\n * Ported from the in-memory registry half of otium's `api/routes/sessions.ts`\n * (the ask/tell REST routes stayed in the host).\n */\n\nimport { deliverPeerReply, type RemoteReplyRoute } from \"#mcp/session-comm/peer-forward\";\nimport { db } from \"#storage/forum-db\";\nimport { PENDING_ASK_TTL_MS, type PendingAskUserId } from \"#storage/session-asks\";\n\ndb.exec(`\n CREATE TABLE IF NOT EXISTS remote_ask_callbacks (\n target_query_id TEXT PRIMARY KEY,\n request_id TEXT NOT NULL,\n node_name TEXT NOT NULL,\n node_cell_id TEXT NOT NULL,\n topic_id TEXT NOT NULL,\n user_id TEXT NOT NULL,\n created_at INTEGER NOT NULL\n )\n`);\n\ninterface PendingAskIdentity {\n userId: PendingAskUserId;\n from: string;\n to: string;\n requestId?: string;\n}\n\nexport interface AskPending {\n requestId: string;\n contextId?: string;\n callerTopicId: string;\n callerUserId: string;\n targetQueryId: string;\n createdAt: number;\n timedOut?: boolean; // set when resolved past TTL — caller gets timeout notice\n pendingAsk?: PendingAskIdentity;\n remoteReply?: RemoteReplyRoute;\n}\n\n/** Active callbacks stay in memory for the normal completion path. Remote\n * reply routes are also persisted so a process restart can explicitly fail\n * the interrupted ask instead of leaving its caller waiting forever. */\nconst pendingAsks = new Map<string, AskPending>(); // keyed by targetQueryId (the AI turn's queryId)\nconst MAX_ASK_AGE_MS = PENDING_ASK_TTL_MS;\n\n/** Register an ask callback. Called after the target AI turn is dispatched. */\nexport function registerAskCallback(entry: AskPending): void {\n pendingAsks.set(entry.targetQueryId, entry);\n if (entry.remoteReply) {\n db.query(\n `INSERT INTO remote_ask_callbacks\n (target_query_id, request_id, node_name, node_cell_id, topic_id, user_id, created_at)\n VALUES (?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(target_query_id) DO UPDATE SET\n request_id = excluded.request_id,\n node_name = excluded.node_name,\n node_cell_id = excluded.node_cell_id,\n topic_id = excluded.topic_id,\n user_id = excluded.user_id,\n created_at = excluded.created_at`,\n ).run(\n entry.targetQueryId,\n entry.remoteReply.requestId,\n entry.remoteReply.nodeName,\n entry.remoteReply.nodeCellId,\n entry.remoteReply.topicId,\n entry.remoteReply.userId,\n entry.createdAt,\n );\n }\n}\n\n/** Resolve an ask callback after the target AI finishes.\n * Called from the turn runner when the agent stream ends — matches by the AI\n * turn's queryId. Returns the AskPending or null if not found.\n * Past TTL: returns entry with timedOut=true (caller gets timeout notice). */\nexport function resolveAskCallback(queryId: string): AskPending | null {\n const entry = pendingAsks.get(queryId);\n if (!entry) return null;\n if (Date.now() - entry.createdAt > MAX_ASK_AGE_MS) {\n entry.timedOut = true;\n }\n pendingAsks.delete(queryId);\n db.query(\"DELETE FROM remote_ask_callbacks WHERE target_query_id = ?\").run(queryId);\n return entry;\n}\n\n/** Clean up stale asks that outlived their TTL (periodic, lightweight). */\nexport function purgeStaleAsks(now: number = Date.now()): void {\n for (const [id, entry] of pendingAsks) {\n if (now - entry.createdAt > MAX_ASK_AGE_MS) pendingAsks.delete(id);\n }\n db.query(\"DELETE FROM remote_ask_callbacks WHERE created_at < ?\").run(now - MAX_ASK_AGE_MS);\n}\n\n/** Drop callbacks whose caller topic was hard-deleted. */\nexport function cancelAskCallbacksForTopic(topicId: string): number {\n let cancelled = 0;\n for (const [queryId, entry] of pendingAsks) {\n if (entry.callerTopicId !== topicId) continue;\n pendingAsks.delete(queryId);\n db.query(\"DELETE FROM remote_ask_callbacks WHERE target_query_id = ?\").run(queryId);\n cancelled++;\n }\n return cancelled;\n}\n\ninterface DurableRemoteAskCallbackRow {\n target_query_id: string;\n request_id: string;\n node_name: string;\n node_cell_id: string;\n topic_id: string;\n user_id: string;\n}\n\n/** Fail remote asks whose target turn was interrupted by the previous process.\n * Call once during startup after the peer session bridge is registered. */\nexport async function failInterruptedRemoteAskCallbacks(): Promise<number> {\n const rows = db\n .query(\n `SELECT target_query_id, request_id, node_name, node_cell_id, topic_id, user_id\n FROM remote_ask_callbacks\n ORDER BY created_at ASC`,\n )\n .all() as DurableRemoteAskCallbackRow[];\n let failed = 0;\n for (const row of rows) {\n const delivered = await deliverPeerReply(\n {\n nodeName: row.node_name,\n nodeCellId: row.node_cell_id,\n topicId: row.topic_id,\n userId: row.user_id,\n requestId: row.request_id,\n },\n \"peer\",\n \"The remote worker restarted before this ask completed. Please retry the request.\",\n \"error\",\n );\n if (!delivered) continue;\n db.query(\"DELETE FROM remote_ask_callbacks WHERE target_query_id = ?\").run(row.target_query_id);\n failed++;\n }\n return failed;\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";;;;;;;;;;;;;;AAeA,GAAG,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAUP;AAwBD,IAAM,cAAc,IAAI;AACxB,IAAM,iBAAiB;AAGhB,SAAS,mBAAmB,CAAC,OAAyB;AAAA,EAC3D,YAAY,IAAI,MAAM,eAAe,KAAK;AAAA,EAC1C,IAAI,MAAM,aAAa;AAAA,IACrB,GAAG,MACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0CAUF,EAAE,IACA,MAAM,eACN,MAAM,YAAY,WAClB,MAAM,YAAY,UAClB,MAAM,YAAY,YAClB,MAAM,YAAY,SAClB,MAAM,YAAY,QAClB,MAAM,SACR;AAAA,EACF;AAAA;AAOK,SAAS,kBAAkB,CAAC,SAAoC;AAAA,EACrE,MAAM,QAAQ,YAAY,IAAI,OAAO;AAAA,EACrC,KAAK;AAAA,IAAO,OAAO;AAAA,EACnB,IAAI,KAAK,IAAI,IAAI,MAAM,YAAY,gBAAgB;AAAA,IACjD,MAAM,WAAW;AAAA,EACnB;AAAA,EACA,YAAY,OAAO,OAAO;AAAA,EAC1B,GAAG,MAAM,4DAA4D,EAAE,IAAI,OAAO;AAAA,EAClF,OAAO;AAAA;AAIF,SAAS,cAAc,CAAC,MAAc,KAAK,IAAI,GAAS;AAAA,EAC7D,YAAY,IAAI,UAAU,aAAa;AAAA,IACrC,IAAI,MAAM,MAAM,YAAY;AAAA,MAAgB,YAAY,OAAO,EAAE;AAAA,EACnE;AAAA,EACA,GAAG,MAAM,uDAAuD,EAAE,IAAI,MAAM,cAAc;AAAA;AAIrF,SAAS,0BAA0B,CAAC,SAAyB;AAAA,EAClE,IAAI,YAAY;AAAA,EAChB,YAAY,SAAS,UAAU,aAAa;AAAA,IAC1C,IAAI,MAAM,kBAAkB;AAAA,MAAS;AAAA,IACrC,YAAY,OAAO,OAAO;AAAA,IAC1B,GAAG,MAAM,4DAA4D,EAAE,IAAI,OAAO;AAAA,IAClF;AAAA,EACF;AAAA,EACA,OAAO;AAAA;AAcT,eAAsB,iCAAiC,GAAoB;AAAA,EACzE,MAAM,OAAO,GACV,MACC;AAAA;AAAA,+BAGF,EACC,IAAI;AAAA,EACP,IAAI,SAAS;AAAA,EACb,WAAW,OAAO,MAAM;AAAA,IACtB,MAAM,YAAY,MAAM,iBACtB;AAAA,MACE,UAAU,IAAI;AAAA,MACd,YAAY,IAAI;AAAA,MAChB,SAAS,IAAI;AAAA,MACb,QAAQ,IAAI;AAAA,MACZ,WAAW,IAAI;AAAA,IACjB,GACA,QACA,oFACA,OACF;AAAA,IACA,KAAK;AAAA,MAAW;AAAA,IAChB,GAAG,MAAM,4DAA4D,EAAE,IAAI,IAAI,eAAe;AAAA,IAC9F;AAAA,EACF;AAAA,EACA,OAAO;AAAA;",
|
|
8
|
+
"debugId": "348F6EFA936C4E6A64756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
startDefaultNode
|
|
4
|
+
} from "./chunk-p3cr2ejg.js";
|
|
5
|
+
import"./chunk-edb07sjp.js";
|
|
6
|
+
import {
|
|
7
|
+
executeVaultCommand,
|
|
8
|
+
isVaultCommandLine,
|
|
9
|
+
registerTopic
|
|
10
|
+
} from "./chunk-exd0v74a.js";
|
|
11
|
+
import"./chunk-sm6fh5c5.js";
|
|
12
|
+
import"./chunk-jc0at0tc.js";
|
|
13
|
+
import"./chunk-sgsz2fpq.js";
|
|
14
|
+
import"./chunk-1k7t7bnx.js";
|
|
15
|
+
import {
|
|
16
|
+
answerPendingAskUserQuestion,
|
|
17
|
+
startAiTurn
|
|
18
|
+
} from "./chunk-rbrxjvbj.js";
|
|
19
|
+
import"./chunk-ghs2j1fr.js";
|
|
20
|
+
import"./chunk-fgrme9tr.js";
|
|
21
|
+
import {
|
|
22
|
+
appendApiMessage,
|
|
23
|
+
runtimeBus
|
|
24
|
+
} from "./chunk-0ay6cjdy.js";
|
|
25
|
+
import {
|
|
26
|
+
getTopicByNameForUser
|
|
27
|
+
} from "./chunk-xfq68rch.js";
|
|
28
|
+
import"./chunk-9p0ww3tk.js";
|
|
29
|
+
import"./chunk-vp2db42d.js";
|
|
30
|
+
import"./chunk-gmy11efb.js";
|
|
31
|
+
import {
|
|
32
|
+
abortRoom
|
|
33
|
+
} from "./chunk-t9zcg8f1.js";
|
|
34
|
+
import"./chunk-7xqj7aex.js";
|
|
35
|
+
import"./chunk-x1arr7ze.js";
|
|
36
|
+
import"./chunk-5ahkew9c.js";
|
|
37
|
+
import"./chunk-6cpn7ht2.js";
|
|
38
|
+
import {
|
|
39
|
+
isAgentKind
|
|
40
|
+
} from "./chunk-k9z47mab.js";
|
|
41
|
+
import"./chunk-hwy3n31w.js";
|
|
42
|
+
|
|
43
|
+
// ../cli/src/commands/chat.ts
|
|
44
|
+
import { randomUUID } from "crypto";
|
|
45
|
+
import { createInterface } from "readline";
|
|
46
|
+
|
|
47
|
+
// ../cli/src/render.ts
|
|
48
|
+
var dim = (s) => `\x1B[2m${s}\x1B[0m`;
|
|
49
|
+
var bold = (s) => `\x1B[1m${s}\x1B[0m`;
|
|
50
|
+
var cyan = (s) => `\x1B[36m${s}\x1B[0m`;
|
|
51
|
+
var red = (s) => `\x1B[31m${s}\x1B[0m`;
|
|
52
|
+
function renderBusEvent(event, opts = {}) {
|
|
53
|
+
if (opts.topicId && event.topicId !== opts.topicId)
|
|
54
|
+
return;
|
|
55
|
+
switch (event.type) {
|
|
56
|
+
case "message": {
|
|
57
|
+
const msg = event.payload;
|
|
58
|
+
if (opts.selfUserId && msg.authorId === opts.selfUserId)
|
|
59
|
+
return;
|
|
60
|
+
if (msg.kind === "tool") {
|
|
61
|
+
console.log(dim(` ${firstLine(msg.text)}`));
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const author = msg.authorId === "ai" ? cyan(bold("ai")) : bold(msg.authorId);
|
|
65
|
+
console.log(`${author}${msg.agentType ? dim(` (${msg.agentType})`) : ""}: ${msg.text}`);
|
|
66
|
+
if (msg.kind === "ask_user_question" && msg.askUserQuestion) {
|
|
67
|
+
msg.askUserQuestion.choices.forEach((choice, index) => {
|
|
68
|
+
const description = choice.description ? dim(` \u2014 ${choice.description}`) : "";
|
|
69
|
+
console.log(` ${index + 1}) ${choice.label}${description}`);
|
|
70
|
+
});
|
|
71
|
+
console.log(dim(" choose by number or exact label"));
|
|
72
|
+
}
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
case "message-updated":
|
|
76
|
+
return;
|
|
77
|
+
case "ai-status": {
|
|
78
|
+
const status = event.payload;
|
|
79
|
+
const kind = String(status.kind ?? "");
|
|
80
|
+
if (kind === "ai-active" || kind === "typing")
|
|
81
|
+
return;
|
|
82
|
+
if (kind === "tool-call") {
|
|
83
|
+
console.log(dim(` \u2699 ${firstLine(String(status.label ?? status.tool ?? "tool"))}`));
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (kind === "error") {
|
|
87
|
+
console.log(red(` \u2716 ${firstLine(String(status.message ?? "error"))}`));
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (kind === "aborted") {
|
|
91
|
+
console.log(dim(" \u23F9 aborted"));
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
case "topic-created": {
|
|
97
|
+
const topic = event.payload;
|
|
98
|
+
console.log(dim(` + topic created: ${topic.title ?? topic.id}`));
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
case "topic-deleted":
|
|
102
|
+
console.log(dim(` - topic deleted: ${event.topicId}`));
|
|
103
|
+
return;
|
|
104
|
+
default:
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
function firstLine(s) {
|
|
109
|
+
const line = s.split(`
|
|
110
|
+
`, 1)[0] ?? "";
|
|
111
|
+
return line.length > 120 ? `${line.slice(0, 117)}...` : line;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// ../cli/src/commands/chat.ts
|
|
115
|
+
var DEFAULT_USER = "local";
|
|
116
|
+
var DEFAULT_TOPIC = "chat";
|
|
117
|
+
var VAULT_SET_COMMAND_PATTERN = /^\/vault(?:@\w+)?\s+set(?:\s|$)/i;
|
|
118
|
+
function scrubVaultSetCommandsFromHistory(history) {
|
|
119
|
+
for (let index = history.length - 1;index >= 0; index -= 1) {
|
|
120
|
+
if (VAULT_SET_COMMAND_PATTERN.test(history[index]?.trim() ?? "")) {
|
|
121
|
+
history.splice(index, 1);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
function ensureTopic(title, agent) {
|
|
126
|
+
const existing = getTopicByNameForUser(title, DEFAULT_USER);
|
|
127
|
+
if (existing)
|
|
128
|
+
return existing;
|
|
129
|
+
return registerTopic({
|
|
130
|
+
title,
|
|
131
|
+
userId: DEFAULT_USER,
|
|
132
|
+
kind: "agent",
|
|
133
|
+
...agent && isAgentKind(agent) ? { agent } : {}
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
async function chatCommand(args) {
|
|
137
|
+
const topicArg = args.find((a) => !a.startsWith("--"));
|
|
138
|
+
const agentArg = args.find((a) => a.startsWith("--agent="))?.slice("--agent=".length);
|
|
139
|
+
const node = await startDefaultNode();
|
|
140
|
+
let topic = ensureTopic(topicArg ?? DEFAULT_TOPIC, agentArg);
|
|
141
|
+
console.log(`negotium node on :${node.port} \u2014 topic "${topic.title}" (agent: ${topic.agent})`);
|
|
142
|
+
console.log(`commands: /vault, /switch <topic>, /abort, /quit
|
|
143
|
+
`);
|
|
144
|
+
const rl = createInterface({
|
|
145
|
+
input: process.stdin,
|
|
146
|
+
output: process.stdout,
|
|
147
|
+
prompt: "> "
|
|
148
|
+
});
|
|
149
|
+
let pendingAsk = null;
|
|
150
|
+
const unsubscribe = runtimeBus().subscribe((event) => {
|
|
151
|
+
renderBusEvent(event, { topicId: topic.id, selfUserId: DEFAULT_USER });
|
|
152
|
+
if (event.topicId !== topic.id)
|
|
153
|
+
return;
|
|
154
|
+
if (event.type === "message") {
|
|
155
|
+
const msg = event.payload;
|
|
156
|
+
if (msg.kind === "ask_user_question" && msg.askUserQuestion) {
|
|
157
|
+
pendingAsk = { messageId: msg.id, choices: msg.askUserQuestion.choices };
|
|
158
|
+
rl.prompt();
|
|
159
|
+
}
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
if (event.type === "message-updated" && pendingAsk) {
|
|
163
|
+
const payload = event.payload;
|
|
164
|
+
if (payload.messageId === pendingAsk.messageId && (payload.patch?.askUserQuestion?.expired || payload.patch?.askUserQuestion?.selectedLabel)) {
|
|
165
|
+
pendingAsk = null;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
rl.prompt();
|
|
170
|
+
rl.on("line", (line) => {
|
|
171
|
+
const text = line.trim();
|
|
172
|
+
if (VAULT_SET_COMMAND_PATTERN.test(text)) {
|
|
173
|
+
scrubVaultSetCommandsFromHistory(rl.history);
|
|
174
|
+
}
|
|
175
|
+
if (!text) {
|
|
176
|
+
rl.prompt();
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
if (text === "/quit" || text === "/exit") {
|
|
180
|
+
rl.close();
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
if (text === "/abort") {
|
|
184
|
+
const aborted = abortRoom(topic.id);
|
|
185
|
+
console.log(aborted ? "aborted." : "nothing running.");
|
|
186
|
+
rl.prompt();
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
if (text.startsWith("/switch ")) {
|
|
190
|
+
topic = ensureTopic(text.slice("/switch ".length).trim(), agentArg);
|
|
191
|
+
pendingAsk = null;
|
|
192
|
+
console.log(`\u2192 topic "${topic.title}" (agent: ${topic.agent})`);
|
|
193
|
+
rl.prompt();
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
if (isVaultCommandLine(text)) {
|
|
197
|
+
const result = executeVaultCommand(DEFAULT_USER, text);
|
|
198
|
+
if (result)
|
|
199
|
+
console.log(result);
|
|
200
|
+
rl.prompt();
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
if (pendingAsk) {
|
|
204
|
+
const choiceIndex = /^\d+$/.test(text) ? Number(text) - 1 : -1;
|
|
205
|
+
const choice = (choiceIndex >= 0 ? pendingAsk.choices[choiceIndex] : undefined) ?? pendingAsk.choices.find((item) => item.label === text);
|
|
206
|
+
if (!choice) {
|
|
207
|
+
console.log("invalid choice \u2014 enter one of the displayed numbers or labels.");
|
|
208
|
+
rl.prompt();
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
const answered = answerPendingAskUserQuestion(topic.id, pendingAsk.messageId, choice.label, DEFAULT_USER);
|
|
212
|
+
if (!answered.ok) {
|
|
213
|
+
console.log(`could not answer: ${answered.error}`);
|
|
214
|
+
} else {
|
|
215
|
+
pendingAsk = null;
|
|
216
|
+
}
|
|
217
|
+
rl.prompt();
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
appendApiMessage({
|
|
221
|
+
id: randomUUID(),
|
|
222
|
+
topicId: topic.id,
|
|
223
|
+
authorId: DEFAULT_USER,
|
|
224
|
+
text,
|
|
225
|
+
createdAt: new Date().toISOString()
|
|
226
|
+
});
|
|
227
|
+
startAiTurn({ topic, userId: DEFAULT_USER, prompt: text, allowAutoContinue: true });
|
|
228
|
+
rl.prompt();
|
|
229
|
+
});
|
|
230
|
+
await new Promise((resolve) => {
|
|
231
|
+
rl.on("close", async () => {
|
|
232
|
+
unsubscribe();
|
|
233
|
+
await node.stop();
|
|
234
|
+
resolve();
|
|
235
|
+
});
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
export {
|
|
239
|
+
scrubVaultSetCommandsFromHistory,
|
|
240
|
+
chatCommand
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
//# debugId=20EC4A89B5E9550D64756E2164756E21
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../cli/src/commands/chat.ts", "../../cli/src/render.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/**\n * `negotium chat [topic]` — interactive terminal host.\n *\n * This command doubles as the reference implementation for anyone writing a\n * channel adapter: everything it does (ensure topic → persist user message →\n * startAiTurn → render bus events) is exactly what a Telegram/web/otium host\n * does with a different renderer.\n */\n\nimport { randomUUID } from \"node:crypto\";\nimport { createInterface } from \"node:readline\";\nimport {\n type AgentKind,\n abortRoom,\n answerPendingAskUserQuestion,\n appendApiMessage,\n executeVaultCommand,\n getTopicByNameForUser,\n isAgentKind,\n isVaultCommandLine,\n type MessageDto,\n registerTopic,\n runtimeBus,\n startAiTurn,\n type TopicDto,\n} from \"@negotium/core\";\nimport { startDefaultNode } from \"@negotium/node\";\nimport { renderBusEvent } from \"@/render\";\n\nconst DEFAULT_USER = \"local\";\nconst DEFAULT_TOPIC = \"chat\";\nconst VAULT_SET_COMMAND_PATTERN = /^\\/vault(?:@\\w+)?\\s+set(?:\\s|$)/i;\n\n/**\n * Remove secret-bearing Vault writes from readline's in-memory history.\n *\n * Node records a line before emitting the `line` event, so this must run at\n * the beginning of the handler rather than after executing the command.\n */\nexport function scrubVaultSetCommandsFromHistory(history: string[]): void {\n for (let index = history.length - 1; index >= 0; index -= 1) {\n if (VAULT_SET_COMMAND_PATTERN.test(history[index]?.trim() ?? \"\")) {\n history.splice(index, 1);\n }\n }\n}\n\nfunction ensureTopic(title: string, agent?: string): TopicDto {\n const existing = getTopicByNameForUser(title, DEFAULT_USER);\n if (existing) return existing;\n return registerTopic({\n title,\n userId: DEFAULT_USER,\n kind: \"agent\",\n ...(agent && isAgentKind(agent) ? { agent: agent as AgentKind } : {}),\n });\n}\n\nexport async function chatCommand(args: string[]): Promise<void> {\n const topicArg = args.find((a) => !a.startsWith(\"--\"));\n const agentArg = args.find((a) => a.startsWith(\"--agent=\"))?.slice(\"--agent=\".length);\n\n const node = await startDefaultNode();\n let topic = ensureTopic(topicArg ?? DEFAULT_TOPIC, agentArg);\n\n console.log(`negotium node on :${node.port} — topic \"${topic.title}\" (agent: ${topic.agent})`);\n console.log(\"commands: /vault, /switch <topic>, /abort, /quit\\n\");\n\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n prompt: \"> \",\n }) as ReturnType<typeof createInterface> & { history: string[] };\n let pendingAsk: {\n messageId: string;\n choices: NonNullable<MessageDto[\"askUserQuestion\"]>[\"choices\"];\n } | null = null;\n const unsubscribe = runtimeBus().subscribe((event) => {\n renderBusEvent(event, { topicId: topic.id, selfUserId: DEFAULT_USER });\n if (event.topicId !== topic.id) return;\n if (event.type === \"message\") {\n const msg = event.payload as MessageDto;\n if (msg.kind === \"ask_user_question\" && msg.askUserQuestion) {\n pendingAsk = { messageId: msg.id, choices: msg.askUserQuestion.choices };\n rl.prompt();\n }\n return;\n }\n if (event.type === \"message-updated\" && pendingAsk) {\n const payload = event.payload as { messageId?: string; patch?: Partial<MessageDto> };\n if (\n payload.messageId === pendingAsk.messageId &&\n (payload.patch?.askUserQuestion?.expired || payload.patch?.askUserQuestion?.selectedLabel)\n ) {\n pendingAsk = null;\n }\n }\n });\n\n rl.prompt();\n\n rl.on(\"line\", (line) => {\n const text = line.trim();\n if (VAULT_SET_COMMAND_PATTERN.test(text)) {\n scrubVaultSetCommandsFromHistory(rl.history);\n }\n if (!text) {\n rl.prompt();\n return;\n }\n if (text === \"/quit\" || text === \"/exit\") {\n rl.close();\n return;\n }\n if (text === \"/abort\") {\n const aborted = abortRoom(topic.id);\n console.log(aborted ? \"aborted.\" : \"nothing running.\");\n rl.prompt();\n return;\n }\n if (text.startsWith(\"/switch \")) {\n topic = ensureTopic(text.slice(\"/switch \".length).trim(), agentArg);\n pendingAsk = null;\n console.log(`→ topic \"${topic.title}\" (agent: ${topic.agent})`);\n rl.prompt();\n return;\n }\n if (isVaultCommandLine(text)) {\n const result = executeVaultCommand(DEFAULT_USER, text);\n if (result) console.log(result);\n rl.prompt();\n return;\n }\n\n if (pendingAsk) {\n const choiceIndex = /^\\d+$/.test(text) ? Number(text) - 1 : -1;\n const choice =\n (choiceIndex >= 0 ? pendingAsk.choices[choiceIndex] : undefined) ??\n pendingAsk.choices.find((item) => item.label === text);\n if (!choice) {\n console.log(\"invalid choice — enter one of the displayed numbers or labels.\");\n rl.prompt();\n return;\n }\n const answered = answerPendingAskUserQuestion(\n topic.id,\n pendingAsk.messageId,\n choice.label,\n DEFAULT_USER,\n );\n if (!answered.ok) {\n console.log(`could not answer: ${answered.error}`);\n } else {\n pendingAsk = null;\n }\n rl.prompt();\n return;\n }\n\n appendApiMessage({\n id: randomUUID(),\n topicId: topic.id,\n authorId: DEFAULT_USER,\n text,\n createdAt: new Date().toISOString(),\n });\n startAiTurn({ topic, userId: DEFAULT_USER, prompt: text, allowAutoContinue: true });\n rl.prompt();\n });\n\n await new Promise<void>((resolve) => {\n rl.on(\"close\", async () => {\n unsubscribe();\n await node.stop();\n resolve();\n });\n });\n}\n",
|
|
6
|
+
"/**\n * Terminal rendering for RuntimeBus events — the CLI's half of the host\n * boundary. Deliberately dumb: everything the runtime wants a channel to show\n * arrives on the bus, so this file is the whole \"adapter\" a channel needs.\n */\n\nimport type { MessageDto, RuntimeBusEvent } from \"@negotium/core\";\n\nconst dim = (s: string) => `\\x1b[2m${s}\\x1b[0m`;\nconst bold = (s: string) => `\\x1b[1m${s}\\x1b[0m`;\nconst cyan = (s: string) => `\\x1b[36m${s}\\x1b[0m`;\nconst red = (s: string) => `\\x1b[31m${s}\\x1b[0m`;\n\nexport interface RenderOptions {\n /** Only render events for this topic id (chat mode). Undefined = all. */\n topicId?: string;\n /** Suppress echoing messages authored by this user (they typed them). */\n selfUserId?: string;\n}\n\nexport function renderBusEvent(event: RuntimeBusEvent, opts: RenderOptions = {}): void {\n if (opts.topicId && event.topicId !== opts.topicId) return;\n\n switch (event.type) {\n case \"message\": {\n const msg = event.payload as MessageDto;\n if (opts.selfUserId && msg.authorId === opts.selfUserId) return;\n if (msg.kind === \"tool\") {\n console.log(dim(` ${firstLine(msg.text)}`));\n return;\n }\n const author = msg.authorId === \"ai\" ? cyan(bold(\"ai\")) : bold(msg.authorId);\n console.log(`${author}${msg.agentType ? dim(` (${msg.agentType})`) : \"\"}: ${msg.text}`);\n if (msg.kind === \"ask_user_question\" && msg.askUserQuestion) {\n msg.askUserQuestion.choices.forEach((choice, index) => {\n const description = choice.description ? dim(` — ${choice.description}`) : \"\";\n console.log(` ${index + 1}) ${choice.label}${description}`);\n });\n console.log(dim(\" choose by number or exact label\"));\n }\n return;\n }\n case \"message-updated\":\n // Edit-in-place progress (tool status, subagent cards) — too chatty for\n // a line-oriented terminal; the final state arrives as ai-status/message.\n return;\n case \"ai-status\": {\n const status = event.payload as Record<string, unknown>;\n const kind = String(status.kind ?? \"\");\n if (kind === \"ai-active\" || kind === \"typing\") return;\n if (kind === \"tool-call\") {\n console.log(dim(` ⚙ ${firstLine(String(status.label ?? status.tool ?? \"tool\"))}`));\n return;\n }\n if (kind === \"error\") {\n console.log(red(` ✖ ${firstLine(String(status.message ?? \"error\"))}`));\n return;\n }\n if (kind === \"aborted\") {\n console.log(dim(\" ⏹ aborted\"));\n return;\n }\n return;\n }\n case \"topic-created\": {\n const topic = event.payload as { id: string; title?: string };\n console.log(dim(` + topic created: ${topic.title ?? topic.id}`));\n return;\n }\n case \"topic-deleted\":\n console.log(dim(` - topic deleted: ${event.topicId}`));\n return;\n default:\n return;\n }\n}\n\nfunction firstLine(s: string): string {\n const line = s.split(\"\\n\", 1)[0] ?? \"\";\n return line.length > 120 ? `${line.slice(0, 117)}...` : line;\n}\n"
|
|
7
|
+
],
|
|
8
|
+
"mappings": "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",
|
|
9
|
+
"debugId": "20EC4A89B5E9550D64756E2164756E21",
|
|
10
|
+
"names": []
|
|
11
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import"./chunk-exd0v74a.js";
|
|
3
|
+
import"./chunk-sm6fh5c5.js";
|
|
4
|
+
import"./chunk-jc0at0tc.js";
|
|
5
|
+
import"./chunk-sgsz2fpq.js";
|
|
6
|
+
import"./chunk-1k7t7bnx.js";
|
|
7
|
+
import"./chunk-rbrxjvbj.js";
|
|
8
|
+
import"./chunk-ghs2j1fr.js";
|
|
9
|
+
import"./chunk-fgrme9tr.js";
|
|
10
|
+
import"./chunk-0ay6cjdy.js";
|
|
11
|
+
import"./chunk-xfq68rch.js";
|
|
12
|
+
import"./chunk-9p0ww3tk.js";
|
|
13
|
+
import"./chunk-vp2db42d.js";
|
|
14
|
+
import"./chunk-gmy11efb.js";
|
|
15
|
+
import"./chunk-t9zcg8f1.js";
|
|
16
|
+
import"./chunk-7xqj7aex.js";
|
|
17
|
+
import {
|
|
18
|
+
checkAgentAuth
|
|
19
|
+
} from "./chunk-x1arr7ze.js";
|
|
20
|
+
import"./chunk-5ahkew9c.js";
|
|
21
|
+
import"./chunk-6cpn7ht2.js";
|
|
22
|
+
import {
|
|
23
|
+
DATA_DIR,
|
|
24
|
+
RUN_DIR,
|
|
25
|
+
STATE_DIR,
|
|
26
|
+
SUPPORTED_AGENTS,
|
|
27
|
+
WORKSPACE_DIR
|
|
28
|
+
} from "./chunk-k9z47mab.js";
|
|
29
|
+
import"./chunk-hwy3n31w.js";
|
|
30
|
+
|
|
31
|
+
// ../cli/src/commands/init.ts
|
|
32
|
+
function initCommand() {
|
|
33
|
+
console.log(`negotium node initialized
|
|
34
|
+
`);
|
|
35
|
+
console.log(` state: ${STATE_DIR}`);
|
|
36
|
+
console.log(` data: ${DATA_DIR}`);
|
|
37
|
+
console.log(` run: ${RUN_DIR}`);
|
|
38
|
+
console.log(` workspace: ${WORKSPACE_DIR}
|
|
39
|
+
`);
|
|
40
|
+
console.log("agents:");
|
|
41
|
+
for (const agent of SUPPORTED_AGENTS) {
|
|
42
|
+
const auth = checkAgentAuth(agent);
|
|
43
|
+
console.log(` ${agent.padEnd(8)} ${auth.ok ? "ready" : `unavailable \u2014 ${auth.error}`}`);
|
|
44
|
+
}
|
|
45
|
+
console.log("\nnext: `negotium chat` or `negotium serve`");
|
|
46
|
+
}
|
|
47
|
+
export {
|
|
48
|
+
initCommand
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
//# debugId=50619C00BC7776D764756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../cli/src/commands/init.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/** `negotium init` — bootstrap the node state dir and report agent auth. */\n\nimport {\n checkAgentAuth,\n DATA_DIR,\n RUN_DIR,\n STATE_DIR,\n SUPPORTED_AGENTS,\n WORKSPACE_DIR,\n} from \"@negotium/core\";\n\nexport function initCommand(): void {\n // Importing core already created the layout — this command makes it visible.\n console.log(\"negotium node initialized\\n\");\n console.log(` state: ${STATE_DIR}`);\n console.log(` data: ${DATA_DIR}`);\n console.log(` run: ${RUN_DIR}`);\n console.log(` workspace: ${WORKSPACE_DIR}\\n`);\n\n console.log(\"agents:\");\n for (const agent of SUPPORTED_AGENTS) {\n const auth = checkAgentAuth(agent);\n console.log(` ${agent.padEnd(8)} ${auth.ok ? \"ready\" : `unavailable — ${auth.error}`}`);\n }\n console.log(\"\\nnext: `negotium chat` or `negotium serve`\");\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAWO,SAAS,WAAW,GAAS;AAAA,EAElC,QAAQ,IAAI;AAAA,CAA6B;AAAA,EACzC,QAAQ,IAAI,gBAAgB,WAAW;AAAA,EACvC,QAAQ,IAAI,gBAAgB,UAAU;AAAA,EACtC,QAAQ,IAAI,gBAAgB,SAAS;AAAA,EACrC,QAAQ,IAAI,gBAAgB;AAAA,CAAiB;AAAA,EAE7C,QAAQ,IAAI,SAAS;AAAA,EACrB,WAAW,SAAS,kBAAkB;AAAA,IACpC,MAAM,OAAO,eAAe,KAAK;AAAA,IACjC,QAAQ,IAAI,KAAK,MAAM,OAAO,CAAC,KAAK,KAAK,KAAK,UAAU,sBAAgB,KAAK,SAAS;AAAA,EACxF;AAAA,EACA,QAAQ,IAAI,6CAA6C;AAAA;",
|
|
8
|
+
"debugId": "50619C00BC7776D764756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
McpManifest,
|
|
4
|
+
mcpServerSpecSchema
|
|
5
|
+
} from "./chunk-edb07sjp.js";
|
|
6
|
+
import"./chunk-hwy3n31w.js";
|
|
7
|
+
|
|
8
|
+
// ../cli/src/commands/mcp.ts
|
|
9
|
+
function mcpCommand(args) {
|
|
10
|
+
const manifest = new McpManifest;
|
|
11
|
+
const [sub, ...rest] = args;
|
|
12
|
+
switch (sub) {
|
|
13
|
+
case undefined:
|
|
14
|
+
case "list": {
|
|
15
|
+
const specs = manifest.list();
|
|
16
|
+
if (specs.length === 0) {
|
|
17
|
+
console.log("no MCP servers assigned to this node yet \u2014 `negotium mcp add '<json>'`");
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
for (const spec of specs) {
|
|
21
|
+
const enabled = manifest.isEnabled(spec.key) ? "on " : "off";
|
|
22
|
+
const where = spec.transport === "http" ? `http :${spec.portRange?.base}-${spec.portRange?.max}` : "stdio";
|
|
23
|
+
console.log(`[${enabled}] ${spec.key} ${where} ${spec.command} ${spec.args?.join(" ") ?? ""}`);
|
|
24
|
+
}
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
case "add": {
|
|
28
|
+
const raw = rest.join(" ").trim();
|
|
29
|
+
if (!raw) {
|
|
30
|
+
console.error(`usage: negotium mcp add '{"key":"browser","transport":"http","command":"bunx",` + `"args":["mcp-patchright","--port","{port}"],"portRange":{"base":9100,"max":9199},"scope":"instance"}'`);
|
|
31
|
+
process.exitCode = 1;
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const spec = mcpServerSpecSchema.parse(JSON.parse(raw));
|
|
35
|
+
manifest.add(spec);
|
|
36
|
+
console.log(`added "${spec.key}" to this node's manifest`);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
case "remove": {
|
|
40
|
+
const key = rest[0];
|
|
41
|
+
if (!key) {
|
|
42
|
+
console.error("usage: negotium mcp remove <key>");
|
|
43
|
+
process.exitCode = 1;
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
console.log(manifest.remove(key) ? `removed "${key}"` : `no such key "${key}"`);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
case "enable":
|
|
50
|
+
case "disable": {
|
|
51
|
+
const key = rest[0];
|
|
52
|
+
if (!key) {
|
|
53
|
+
console.error(`usage: negotium mcp ${sub} <key>`);
|
|
54
|
+
process.exitCode = 1;
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
manifest.setEnabled(key, sub === "enable");
|
|
58
|
+
console.log(`${sub}d "${key}"`);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
default:
|
|
62
|
+
console.error(`unknown subcommand "${sub}" \u2014 use list|add|remove|enable|disable`);
|
|
63
|
+
process.exitCode = 1;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
export {
|
|
67
|
+
mcpCommand
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
//# debugId=3AA6F59DE8ACECF964756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../cli/src/commands/mcp.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/** `negotium mcp <list|add|remove|enable|disable>` — per-node MCP manifest. */\n\nimport { McpManifest, mcpServerSpecSchema } from \"@negotium/mcp-host\";\n\nexport function mcpCommand(args: string[]): void {\n const manifest = new McpManifest();\n const [sub, ...rest] = args;\n\n switch (sub) {\n case undefined:\n case \"list\": {\n const specs = manifest.list();\n if (specs.length === 0) {\n console.log(\"no MCP servers assigned to this node yet — `negotium mcp add '<json>'`\");\n return;\n }\n for (const spec of specs) {\n const enabled = manifest.isEnabled(spec.key) ? \"on \" : \"off\";\n const where =\n spec.transport === \"http\"\n ? `http :${spec.portRange?.base}-${spec.portRange?.max}`\n : \"stdio\";\n console.log(\n `[${enabled}] ${spec.key} ${where} ${spec.command} ${spec.args?.join(\" \") ?? \"\"}`,\n );\n }\n return;\n }\n case \"add\": {\n const raw = rest.join(\" \").trim();\n if (!raw) {\n console.error(\n 'usage: negotium mcp add \\'{\"key\":\"browser\",\"transport\":\"http\",\"command\":\"bunx\",' +\n '\"args\":[\"mcp-patchright\",\"--port\",\"{port}\"],\"portRange\":{\"base\":9100,\"max\":9199},\"scope\":\"instance\"}\\'',\n );\n process.exitCode = 1;\n return;\n }\n const spec = mcpServerSpecSchema.parse(JSON.parse(raw));\n manifest.add(spec);\n console.log(`added \"${spec.key}\" to this node's manifest`);\n return;\n }\n case \"remove\": {\n const key = rest[0];\n if (!key) {\n console.error(\"usage: negotium mcp remove <key>\");\n process.exitCode = 1;\n return;\n }\n console.log(manifest.remove(key) ? `removed \"${key}\"` : `no such key \"${key}\"`);\n return;\n }\n case \"enable\":\n case \"disable\": {\n const key = rest[0];\n if (!key) {\n console.error(`usage: negotium mcp ${sub} <key>`);\n process.exitCode = 1;\n return;\n }\n manifest.setEnabled(key, sub === \"enable\");\n console.log(`${sub}d \"${key}\"`);\n return;\n }\n default:\n console.error(`unknown subcommand \"${sub}\" — use list|add|remove|enable|disable`);\n process.exitCode = 1;\n }\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";;;;;;;;AAIO,SAAS,UAAU,CAAC,MAAsB;AAAA,EAC/C,MAAM,WAAW,IAAI;AAAA,EACrB,OAAO,QAAQ,QAAQ;AAAA,EAEvB,QAAQ;AAAA,SACD;AAAA,SACA,QAAQ;AAAA,MACX,MAAM,QAAQ,SAAS,KAAK;AAAA,MAC5B,IAAI,MAAM,WAAW,GAAG;AAAA,QACtB,QAAQ,IAAI,6EAAuE;AAAA,QACnF;AAAA,MACF;AAAA,MACA,WAAW,QAAQ,OAAO;AAAA,QACxB,MAAM,UAAU,SAAS,UAAU,KAAK,GAAG,IAAI,QAAQ;AAAA,QACvD,MAAM,QACJ,KAAK,cAAc,SACf,SAAS,KAAK,WAAW,QAAQ,KAAK,WAAW,QACjD;AAAA,QACN,QAAQ,IACN,IAAI,YAAY,KAAK,QAAQ,UAAU,KAAK,WAAW,KAAK,MAAM,KAAK,GAAG,KAAK,IACjF;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAAA,SACK,OAAO;AAAA,MACV,MAAM,MAAM,KAAK,KAAK,GAAG,EAAE,KAAK;AAAA,MAChC,KAAK,KAAK;AAAA,QACR,QAAQ,MACN,mFACE,uGACJ;AAAA,QACA,QAAQ,WAAW;AAAA,QACnB;AAAA,MACF;AAAA,MACA,MAAM,OAAO,oBAAoB,MAAM,KAAK,MAAM,GAAG,CAAC;AAAA,MACtD,SAAS,IAAI,IAAI;AAAA,MACjB,QAAQ,IAAI,UAAU,KAAK,8BAA8B;AAAA,MACzD;AAAA,IACF;AAAA,SACK,UAAU;AAAA,MACb,MAAM,MAAM,KAAK;AAAA,MACjB,KAAK,KAAK;AAAA,QACR,QAAQ,MAAM,kCAAkC;AAAA,QAChD,QAAQ,WAAW;AAAA,QACnB;AAAA,MACF;AAAA,MACA,QAAQ,IAAI,SAAS,OAAO,GAAG,IAAI,YAAY,SAAS,gBAAgB,MAAM;AAAA,MAC9E;AAAA,IACF;AAAA,SACK;AAAA,SACA,WAAW;AAAA,MACd,MAAM,MAAM,KAAK;AAAA,MACjB,KAAK,KAAK;AAAA,QACR,QAAQ,MAAM,uBAAuB,WAAW;AAAA,QAChD,QAAQ,WAAW;AAAA,QACnB;AAAA,MACF;AAAA,MACA,SAAS,WAAW,KAAK,QAAQ,QAAQ;AAAA,MACzC,QAAQ,IAAI,GAAG,SAAS,MAAM;AAAA,MAC9B;AAAA,IACF;AAAA;AAAA,MAEE,QAAQ,MAAM,uBAAuB,gDAA0C;AAAA,MAC/E,QAAQ,WAAW;AAAA;AAAA;",
|
|
8
|
+
"debugId": "3AA6F59DE8ACECF964756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|