@bd7pil/ocrc 0.9.0
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/LICENSE +34 -0
- package/README.md +330 -0
- package/dist/cli/host-backends.js +216 -0
- package/dist/cli/host-backends.js.map +1 -0
- package/dist/cli/host.js +185 -0
- package/dist/cli/host.js.map +1 -0
- package/dist/cli/index.js +67 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init.js +68 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/install.js +220 -0
- package/dist/cli/install.js.map +1 -0
- package/dist/cli/pair.js +11 -0
- package/dist/cli/pair.js.map +1 -0
- package/dist/cli/uninstall.js +75 -0
- package/dist/cli/uninstall.js.map +1 -0
- package/dist/connectivity/auth/cf-access.js +20 -0
- package/dist/connectivity/auth/cf-access.js.map +1 -0
- package/dist/connectivity/auth/index.js +2 -0
- package/dist/connectivity/auth/index.js.map +1 -0
- package/dist/connectivity/auth/select.js +19 -0
- package/dist/connectivity/auth/select.js.map +1 -0
- package/dist/connectivity/auth/token.js +157 -0
- package/dist/connectivity/auth/token.js.map +1 -0
- package/dist/connectivity/exposure/cloudflared.js +77 -0
- package/dist/connectivity/exposure/cloudflared.js.map +1 -0
- package/dist/connectivity/exposure/index.js +2 -0
- package/dist/connectivity/exposure/index.js.map +1 -0
- package/dist/connectivity/exposure/providers.js +49 -0
- package/dist/connectivity/exposure/providers.js.map +1 -0
- package/dist/connectivity/pairing.js +29 -0
- package/dist/connectivity/pairing.js.map +1 -0
- package/dist/core/agent/acp-backend.js +539 -0
- package/dist/core/agent/acp-backend.js.map +1 -0
- package/dist/core/agent/acp-connect.js +92 -0
- package/dist/core/agent/acp-connect.js.map +1 -0
- package/dist/core/agent/acp-normalizer.js +81 -0
- package/dist/core/agent/acp-normalizer.js.map +1 -0
- package/dist/core/agent/acp-replay.js +89 -0
- package/dist/core/agent/acp-replay.js.map +1 -0
- package/dist/core/agent/acp-store.js +129 -0
- package/dist/core/agent/acp-store.js.map +1 -0
- package/dist/core/agent/backend.js +2 -0
- package/dist/core/agent/backend.js.map +1 -0
- package/dist/core/agent/diff-util.js +70 -0
- package/dist/core/agent/diff-util.js.map +1 -0
- package/dist/core/agent/event.js +12 -0
- package/dist/core/agent/event.js.map +1 -0
- package/dist/core/agent/opencode-backend.js +598 -0
- package/dist/core/agent/opencode-backend.js.map +1 -0
- package/dist/core/agent/opencode-normalizer.js +69 -0
- package/dist/core/agent/opencode-normalizer.js.map +1 -0
- package/dist/core/agent/registry.js +55 -0
- package/dist/core/agent/registry.js.map +1 -0
- package/dist/core/agent/v2-backend.js +176 -0
- package/dist/core/agent/v2-backend.js.map +1 -0
- package/dist/core/card-bus.js +74 -0
- package/dist/core/card-bus.js.map +1 -0
- package/dist/core/channels.js +95 -0
- package/dist/core/channels.js.map +1 -0
- package/dist/core/history.js +91 -0
- package/dist/core/history.js.map +1 -0
- package/dist/core/list-files.js +50 -0
- package/dist/core/list-files.js.map +1 -0
- package/dist/core/opencode-events.js +29 -0
- package/dist/core/opencode-events.js.map +1 -0
- package/dist/core/primary-election.js +91 -0
- package/dist/core/primary-election.js.map +1 -0
- package/dist/core/push.js +152 -0
- package/dist/core/push.js.map +1 -0
- package/dist/core/relay.js +400 -0
- package/dist/core/relay.js.map +1 -0
- package/dist/core/scheduler.js +150 -0
- package/dist/core/scheduler.js.map +1 -0
- package/dist/core/state.js +222 -0
- package/dist/core/state.js.map +1 -0
- package/dist/core/stream-accumulator.js +76 -0
- package/dist/core/stream-accumulator.js.map +1 -0
- package/dist/core/structured-card.js +2 -0
- package/dist/core/structured-card.js.map +1 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/opencode/global-events.js +57 -0
- package/dist/opencode/global-events.js.map +1 -0
- package/dist/opencode/list-sessions.js +122 -0
- package/dist/opencode/list-sessions.js.map +1 -0
- package/dist/opencode/submit.js +39 -0
- package/dist/opencode/submit.js.map +1 -0
- package/dist/opencode/workspaces.js +51 -0
- package/dist/opencode/workspaces.js.map +1 -0
- package/dist/plugin/config.js +128 -0
- package/dist/plugin/config.js.map +1 -0
- package/dist/plugin/control-plane.js +133 -0
- package/dist/plugin/control-plane.js.map +1 -0
- package/dist/plugin/entry.js +409 -0
- package/dist/plugin/entry.js.map +1 -0
- package/dist/plugin/v2/event-map.js +193 -0
- package/dist/plugin/v2/event-map.js.map +1 -0
- package/dist/plugin/v2/types.js +15 -0
- package/dist/plugin/v2/types.js.map +1 -0
- package/dist/transport/interface.js +2 -0
- package/dist/transport/interface.js.map +1 -0
- package/dist/transport/telegram/esc.js +9 -0
- package/dist/transport/telegram/esc.js.map +1 -0
- package/dist/transport/telegram/handlers/info-commands.js +101 -0
- package/dist/transport/telegram/handlers/info-commands.js.map +1 -0
- package/dist/transport/telegram/handlers.js +1348 -0
- package/dist/transport/telegram/handlers.js.map +1 -0
- package/dist/transport/telegram/i18n/en.js +538 -0
- package/dist/transport/telegram/i18n/en.js.map +1 -0
- package/dist/transport/telegram/i18n/index.js +83 -0
- package/dist/transport/telegram/i18n/index.js.map +1 -0
- package/dist/transport/telegram/i18n/zh.js +538 -0
- package/dist/transport/telegram/i18n/zh.js.map +1 -0
- package/dist/transport/telegram/index.js +792 -0
- package/dist/transport/telegram/index.js.map +1 -0
- package/dist/transport/telegram/main-keyboard.js +36 -0
- package/dist/transport/telegram/main-keyboard.js.map +1 -0
- package/dist/transport/telegram/managers/abort-suppression-manager.js +33 -0
- package/dist/transport/telegram/managers/abort-suppression-manager.js.map +1 -0
- package/dist/transport/telegram/managers/external-input-suppression-manager.js +51 -0
- package/dist/transport/telegram/managers/external-input-suppression-manager.js.map +1 -0
- package/dist/transport/telegram/managers/interaction-manager.js +254 -0
- package/dist/transport/telegram/managers/interaction-manager.js.map +1 -0
- package/dist/transport/telegram/managers/permission-manager.js +242 -0
- package/dist/transport/telegram/managers/permission-manager.js.map +1 -0
- package/dist/transport/telegram/managers/question-manager.js +191 -0
- package/dist/transport/telegram/managers/question-manager.js.map +1 -0
- package/dist/transport/telegram/managers/rename-manager.js +56 -0
- package/dist/transport/telegram/managers/rename-manager.js.map +1 -0
- package/dist/transport/telegram/menus.js +77 -0
- package/dist/transport/telegram/menus.js.map +1 -0
- package/dist/transport/telegram/permission-flow.js +156 -0
- package/dist/transport/telegram/permission-flow.js.map +1 -0
- package/dist/transport/telegram/question-flow.js +224 -0
- package/dist/transport/telegram/question-flow.js.map +1 -0
- package/dist/transport/telegram/render/block-parser.js +365 -0
- package/dist/transport/telegram/render/block-parser.js.map +1 -0
- package/dist/transport/telegram/render/block-plain-text.js +87 -0
- package/dist/transport/telegram/render/block-plain-text.js.map +1 -0
- package/dist/transport/telegram/render/block-splitter.js +152 -0
- package/dist/transport/telegram/render/block-splitter.js.map +1 -0
- package/dist/transport/telegram/render/chunker.js +71 -0
- package/dist/transport/telegram/render/chunker.js.map +1 -0
- package/dist/transport/telegram/render/limits.js +13 -0
- package/dist/transport/telegram/render/limits.js.map +1 -0
- package/dist/transport/telegram/render/markdown-normalizer.js +102 -0
- package/dist/transport/telegram/render/markdown-normalizer.js.map +1 -0
- package/dist/transport/telegram/render/markdown-to-telegram-v2.js +116 -0
- package/dist/transport/telegram/render/markdown-to-telegram-v2.js.map +1 -0
- package/dist/transport/telegram/render/part-signature.js +14 -0
- package/dist/transport/telegram/render/part-signature.js.map +1 -0
- package/dist/transport/telegram/render/pipeline.js +23 -0
- package/dist/transport/telegram/render/pipeline.js.map +1 -0
- package/dist/transport/telegram/render/rich-blocks.js +311 -0
- package/dist/transport/telegram/render/rich-blocks.js.map +1 -0
- package/dist/transport/telegram/render/text-splitter.js +64 -0
- package/dist/transport/telegram/render/text-splitter.js.map +1 -0
- package/dist/transport/telegram/render/types.js +2 -0
- package/dist/transport/telegram/render/types.js.map +1 -0
- package/dist/transport/telegram/renderer.js +305 -0
- package/dist/transport/telegram/renderer.js.map +1 -0
- package/dist/transport/telegram/streaming/duration-formatter.js +68 -0
- package/dist/transport/telegram/streaming/duration-formatter.js.map +1 -0
- package/dist/transport/telegram/streaming/finalize-assistant-response.js +37 -0
- package/dist/transport/telegram/streaming/finalize-assistant-response.js.map +1 -0
- package/dist/transport/telegram/streaming/response-streamer.js +400 -0
- package/dist/transport/telegram/streaming/response-streamer.js.map +1 -0
- package/dist/transport/telegram/streaming/running-tool-tracker.js +150 -0
- package/dist/transport/telegram/streaming/running-tool-tracker.js.map +1 -0
- package/dist/transport/telegram/streaming/stream-throttle.js +57 -0
- package/dist/transport/telegram/streaming/stream-throttle.js.map +1 -0
- package/dist/transport/telegram/streaming/tool-call-streamer.js +390 -0
- package/dist/transport/telegram/streaming/tool-call-streamer.js.map +1 -0
- package/dist/transport/telegram/streaming-render.js +182 -0
- package/dist/transport/telegram/streaming-render.js.map +1 -0
- package/dist/transport/telegram/types/interaction.js +2 -0
- package/dist/transport/telegram/types/interaction.js.map +1 -0
- package/dist/transport/telegram/types/model.js +25 -0
- package/dist/transport/telegram/types/model.js.map +1 -0
- package/dist/transport/telegram/types/permission.js +2 -0
- package/dist/transport/telegram/types/permission.js.map +1 -0
- package/dist/transport/telegram/types/question.js +2 -0
- package/dist/transport/telegram/types/question.js.map +1 -0
- package/dist/transport/telegram/types/rename.js +2 -0
- package/dist/transport/telegram/types/rename.js.map +1 -0
- package/dist/transport/telegram/types/scheduled-task.js +23 -0
- package/dist/transport/telegram/types/scheduled-task.js.map +1 -0
- package/dist/transport/telegram/types/session.js +2 -0
- package/dist/transport/telegram/types/session.js.map +1 -0
- package/dist/transport/telegram/ui.js +28 -0
- package/dist/transport/telegram/ui.js.map +1 -0
- package/dist/transport/web/index.js +148 -0
- package/dist/transport/web/index.js.map +1 -0
- package/dist/transport/web/middleware/cf-access.js +104 -0
- package/dist/transport/web/middleware/cf-access.js.map +1 -0
- package/dist/transport/web/opencode-config.js +15 -0
- package/dist/transport/web/opencode-config.js.map +1 -0
- package/dist/transport/web/routes/abort.js +12 -0
- package/dist/transport/web/routes/abort.js.map +1 -0
- package/dist/transport/web/routes/approval.js +16 -0
- package/dist/transport/web/routes/approval.js.map +1 -0
- package/dist/transport/web/routes/catalog.js +11 -0
- package/dist/transport/web/routes/catalog.js.map +1 -0
- package/dist/transport/web/routes/channels.js +53 -0
- package/dist/transport/web/routes/channels.js.map +1 -0
- package/dist/transport/web/routes/commands.js +15 -0
- package/dist/transport/web/routes/commands.js.map +1 -0
- package/dist/transport/web/routes/context.js +17 -0
- package/dist/transport/web/routes/context.js.map +1 -0
- package/dist/transport/web/routes/controls.js +34 -0
- package/dist/transport/web/routes/controls.js.map +1 -0
- package/dist/transport/web/routes/create-session.js +21 -0
- package/dist/transport/web/routes/create-session.js.map +1 -0
- package/dist/transport/web/routes/diff.js +7 -0
- package/dist/transport/web/routes/diff.js.map +1 -0
- package/dist/transport/web/routes/files.js +22 -0
- package/dist/transport/web/routes/files.js.map +1 -0
- package/dist/transport/web/routes/logs.js +9 -0
- package/dist/transport/web/routes/logs.js.map +1 -0
- package/dist/transport/web/routes/m8.js +69 -0
- package/dist/transport/web/routes/m8.js.map +1 -0
- package/dist/transport/web/routes/mcp.js +7 -0
- package/dist/transport/web/routes/mcp.js.map +1 -0
- package/dist/transport/web/routes/message.js +32 -0
- package/dist/transport/web/routes/message.js.map +1 -0
- package/dist/transport/web/routes/overrides.js +20 -0
- package/dist/transport/web/routes/overrides.js.map +1 -0
- package/dist/transport/web/routes/question.js +32 -0
- package/dist/transport/web/routes/question.js.map +1 -0
- package/dist/transport/web/routes/rename.js +12 -0
- package/dist/transport/web/routes/rename.js.map +1 -0
- package/dist/transport/web/routes/schedules.js +28 -0
- package/dist/transport/web/routes/schedules.js.map +1 -0
- package/dist/transport/web/routes/session.js +20 -0
- package/dist/transport/web/routes/session.js.map +1 -0
- package/dist/transport/web/routes/sessions.js +25 -0
- package/dist/transport/web/routes/sessions.js.map +1 -0
- package/dist/transport/web/routes/subagents.js +11 -0
- package/dist/transport/web/routes/subagents.js.map +1 -0
- package/dist/transport/web/routes/suggestions.js +7 -0
- package/dist/transport/web/routes/suggestions.js.map +1 -0
- package/dist/transport/web/routes/todo.js +7 -0
- package/dist/transport/web/routes/todo.js.map +1 -0
- package/dist/transport/web/routes/version.js +5 -0
- package/dist/transport/web/routes/version.js.map +1 -0
- package/dist/transport/web/routes/workspaces.js +7 -0
- package/dist/transport/web/routes/workspaces.js.map +1 -0
- package/dist/transport/web/server.js +111 -0
- package/dist/transport/web/server.js.map +1 -0
- package/dist/transport/web/session-summary.js +46 -0
- package/dist/transport/web/session-summary.js.map +1 -0
- package/dist/transport/web/ws-hub.js +83 -0
- package/dist/transport/web/ws-hub.js.map +1 -0
- package/dist/utils/logger.js +105 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/markdown.js +129 -0
- package/dist/utils/markdown.js.map +1 -0
- package/dist/utils/paths.js +18 -0
- package/dist/utils/paths.js.map +1 -0
- package/dist/utils/version.js +44 -0
- package/dist/utils/version.js.map +1 -0
- package/package.json +91 -0
- package/web/dist/_app/env.js +1 -0
- package/web/dist/_app/immutable/assets/0.DxN3RsuG.css +1 -0
- package/web/dist/_app/immutable/assets/2.BNuGfmZP.css +1 -0
- package/web/dist/_app/immutable/assets/3.CTDprntu.css +1 -0
- package/web/dist/_app/immutable/chunks/BUpwHpMJ.js +1 -0
- package/web/dist/_app/immutable/chunks/BjY4dxcB.js +2 -0
- package/web/dist/_app/immutable/chunks/C2FuqD3s.js +1 -0
- package/web/dist/_app/immutable/chunks/CUHGq08X.js +2 -0
- package/web/dist/_app/immutable/chunks/CWj6FrbW.js +1 -0
- package/web/dist/_app/immutable/chunks/ClvoqtGj.js +1 -0
- package/web/dist/_app/immutable/chunks/DIEDQ_hk.js +1 -0
- package/web/dist/_app/immutable/entry/app.BoRpcVMj.js +2 -0
- package/web/dist/_app/immutable/entry/start.Cj-PQNTq.js +1 -0
- package/web/dist/_app/immutable/nodes/0.y9YEms5p.js +3 -0
- package/web/dist/_app/immutable/nodes/1.CPhhiRM2.js +1 -0
- package/web/dist/_app/immutable/nodes/2.B_c84Mc9.js +1 -0
- package/web/dist/_app/immutable/nodes/3.ClTd0J3D.js +64 -0
- package/web/dist/_app/version.json +1 -0
- package/web/dist/apple-touch-icon.png +0 -0
- package/web/dist/favicon.png +0 -0
- package/web/dist/favicon.svg +17 -0
- package/web/dist/icon-192.png +0 -0
- package/web/dist/icon-512-maskable.png +0 -0
- package/web/dist/icon-512.png +0 -0
- package/web/dist/index.html +73 -0
- package/web/dist/manifest.webmanifest +28 -0
- package/web/dist/service-worker.js +1 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { sessionIdOf, errorMessageOf } from '../opencode-events.js';
|
|
2
|
+
/** One-line tool-arg summary (was inside stream-accumulator; opencode-specific). */
|
|
3
|
+
function summarizeArgs(tool, input) {
|
|
4
|
+
if (!input)
|
|
5
|
+
return '';
|
|
6
|
+
if (tool === 'bash' && typeof input.cmd === 'string') {
|
|
7
|
+
return input.cmd.length > 60 ? input.cmd.slice(0, 57) + '...' : input.cmd;
|
|
8
|
+
}
|
|
9
|
+
const keys = Object.keys(input);
|
|
10
|
+
if (keys.length === 0)
|
|
11
|
+
return '';
|
|
12
|
+
const first = String(input[keys[0]]);
|
|
13
|
+
return first.length > 60 ? first.slice(0, 57) + '...' : first;
|
|
14
|
+
}
|
|
15
|
+
function mapToolStatus(s) {
|
|
16
|
+
return s === 'error' ? 'error' : s === 'done' || s === 'completed' ? 'done' : 'running';
|
|
17
|
+
}
|
|
18
|
+
function normalizePart(part) {
|
|
19
|
+
if (!part)
|
|
20
|
+
return null;
|
|
21
|
+
// Opencode parts carry an id; synthesize a stable one when missing so the
|
|
22
|
+
// accumulator can still key it (matches the relay's previous effectiveId).
|
|
23
|
+
const id = typeof part.id === 'string'
|
|
24
|
+
? part.id
|
|
25
|
+
: `${part.type ?? 'unknown'}:${JSON.stringify(part.state?.input ?? {}).slice(0, 60)}`;
|
|
26
|
+
if (part.type === 'text')
|
|
27
|
+
return { id, type: 'text', text: part.text };
|
|
28
|
+
if (part.type === 'reasoning')
|
|
29
|
+
return { id, type: 'reasoning', text: part.text };
|
|
30
|
+
if (part.type === 'tool' && typeof part.tool === 'string') {
|
|
31
|
+
return { id, type: 'tool', tool: part.tool, args: summarizeArgs(part.tool, part.state?.input), status: mapToolStatus(part.state?.status) };
|
|
32
|
+
}
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
/** Normalize one opencode event, or null when it's not relevant to the relay. */
|
|
36
|
+
export function normalizeOpencodeEvent(ev) {
|
|
37
|
+
const type = ev.type;
|
|
38
|
+
if (!type)
|
|
39
|
+
return null;
|
|
40
|
+
const p = ev.properties ?? {};
|
|
41
|
+
const sessionId = sessionIdOf(ev);
|
|
42
|
+
if (type === 'message.part.updated') {
|
|
43
|
+
if (!sessionId)
|
|
44
|
+
return null;
|
|
45
|
+
const part = normalizePart(p.part);
|
|
46
|
+
if (!part)
|
|
47
|
+
return null;
|
|
48
|
+
return { kind: 'part', sessionId, messageId: p.part?.messageID, part };
|
|
49
|
+
}
|
|
50
|
+
if (type === 'message.part.delta') {
|
|
51
|
+
if (!sessionId)
|
|
52
|
+
return null;
|
|
53
|
+
const partId = typeof p.partID === 'string' ? p.partID : undefined;
|
|
54
|
+
if (!partId || p.field !== 'text' || typeof p.delta !== 'string')
|
|
55
|
+
return null;
|
|
56
|
+
return { kind: 'delta', sessionId, messageId: typeof p.messageID === 'string' ? p.messageID : undefined, partId, text: p.delta };
|
|
57
|
+
}
|
|
58
|
+
if (type === 'session.idle') {
|
|
59
|
+
if (!sessionId)
|
|
60
|
+
return null;
|
|
61
|
+
return { kind: 'idle', sessionId };
|
|
62
|
+
}
|
|
63
|
+
if (type === 'session.error') {
|
|
64
|
+
return { kind: 'error', sessionId: sessionId ?? 'unknown', message: errorMessageOf(p) };
|
|
65
|
+
}
|
|
66
|
+
// message.updated and everything else are not relay-relevant.
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=opencode-normalizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opencode-normalizer.js","sourceRoot":"","sources":["../../../src/core/agent/opencode-normalizer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A trivial registry over a single backend — every session resolves to it. For
|
|
3
|
+
* single-backend callers (the opencode plugin, a one-agent host) and tests that
|
|
4
|
+
* don't need session→backend persistence.
|
|
5
|
+
*/
|
|
6
|
+
export function singleBackendRegistry(backend) {
|
|
7
|
+
return {
|
|
8
|
+
list: () => [{ id: backend.id, capabilities: backend.capabilities }],
|
|
9
|
+
all: () => [{ id: backend.id, backend }],
|
|
10
|
+
get: (id) => (id === backend.id ? backend : undefined),
|
|
11
|
+
has: (id) => id === backend.id,
|
|
12
|
+
primaryId: () => backend.id,
|
|
13
|
+
activeId: () => backend.id,
|
|
14
|
+
active: () => backend,
|
|
15
|
+
idForSession: () => backend.id,
|
|
16
|
+
forSession: () => backend,
|
|
17
|
+
tag: () => { },
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export function createBackendRegistry(opts) {
|
|
21
|
+
const { state } = opts;
|
|
22
|
+
if (opts.backends.length === 0)
|
|
23
|
+
throw new Error('BackendRegistry needs at least one backend');
|
|
24
|
+
const byId = new Map(opts.backends.map((b) => [b.id, b.backend]));
|
|
25
|
+
const primary = opts.primaryId && byId.has(opts.primaryId) ? opts.primaryId : opts.backends[0].id;
|
|
26
|
+
const resolveId = (sid) => {
|
|
27
|
+
const tagged = state.getSessionBackend(sid);
|
|
28
|
+
if (tagged && byId.has(tagged))
|
|
29
|
+
return tagged;
|
|
30
|
+
return primary;
|
|
31
|
+
};
|
|
32
|
+
const activeId = () => {
|
|
33
|
+
const a = state.getActiveBackend();
|
|
34
|
+
return a && byId.has(a) ? a : primary;
|
|
35
|
+
};
|
|
36
|
+
return {
|
|
37
|
+
list: () => opts.backends.map((b) => ({ id: b.id, capabilities: b.backend.capabilities })),
|
|
38
|
+
all: () => opts.backends.slice(),
|
|
39
|
+
get: (id) => byId.get(id),
|
|
40
|
+
has: (id) => byId.has(id),
|
|
41
|
+
primaryId: () => primary,
|
|
42
|
+
activeId,
|
|
43
|
+
// Closure arrow like every other member — a method shorthand relying on
|
|
44
|
+
// `this` breaks when destructured (e.g. `const { active } = registry`).
|
|
45
|
+
active: () => byId.get(activeId()),
|
|
46
|
+
idForSession: resolveId,
|
|
47
|
+
forSession: (sid) => byId.get(resolveId(sid)),
|
|
48
|
+
tag: (sid, backendId) => {
|
|
49
|
+
if (byId.has(backendId) && state.getSessionBackend(sid) !== backendId) {
|
|
50
|
+
state.setSessionBackend(sid, backendId);
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/core/agent/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { createLogger } from '../../utils/logger.js';
|
|
2
|
+
const log = createLogger('v2-backend');
|
|
3
|
+
const CAPABILITIES = {
|
|
4
|
+
liveMirror: true, // in-process: the host IS the local session runner
|
|
5
|
+
tuiSelect: false, // no TUI navigation in V2 ctx
|
|
6
|
+
workspaces: false, // P2a: directory routing
|
|
7
|
+
freeformWorkspace: false,
|
|
8
|
+
diff: false,
|
|
9
|
+
todos: false,
|
|
10
|
+
catalog: false, // ctx has no models/agents enumeration slice (yet)
|
|
11
|
+
mcp: false,
|
|
12
|
+
commands: false,
|
|
13
|
+
sessionControls: false,
|
|
14
|
+
imageInput: false,
|
|
15
|
+
};
|
|
16
|
+
function msTime(v) {
|
|
17
|
+
if (typeof v === 'number')
|
|
18
|
+
return v;
|
|
19
|
+
if (typeof v === 'string') {
|
|
20
|
+
const t = Date.parse(v);
|
|
21
|
+
return Number.isFinite(t) ? t : undefined;
|
|
22
|
+
}
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
function mapSessionInfo(info) {
|
|
26
|
+
const model = typeof info.model === 'string' ? info.model : info.model ? [info.model.providerID, info.model.modelID].filter(Boolean).join('/') : undefined;
|
|
27
|
+
const tokens = info.tokens && (info.tokens.input !== undefined || info.tokens.output !== undefined)
|
|
28
|
+
? { input: Number(info.tokens.input ?? 0), output: Number(info.tokens.output ?? 0) }
|
|
29
|
+
: undefined;
|
|
30
|
+
return {
|
|
31
|
+
agent: typeof info.agent === 'string' ? info.agent : undefined,
|
|
32
|
+
model: model || undefined,
|
|
33
|
+
cost: typeof info.cost === 'number' ? info.cost : undefined,
|
|
34
|
+
tokens,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
export function createV2Backend(ctx) {
|
|
38
|
+
/** Sessions seen on the event stream — V2 ctx has no session.list. Seeded by
|
|
39
|
+
* create/get calls and kept fresh by the control-plane's event feed. */
|
|
40
|
+
const seen = new Map();
|
|
41
|
+
const remember = (info) => {
|
|
42
|
+
const id = info?.id;
|
|
43
|
+
if (typeof id !== 'string' || !id)
|
|
44
|
+
return;
|
|
45
|
+
seen.set(id, {
|
|
46
|
+
id,
|
|
47
|
+
title: typeof info.title === 'string' ? info.title : seen.get(id)?.title,
|
|
48
|
+
updatedAt: Date.now(),
|
|
49
|
+
agent: typeof info.agent === 'string' ? info.agent : seen.get(id)?.agent,
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
const backend = {
|
|
53
|
+
id: 'opencode',
|
|
54
|
+
capabilities: CAPABILITIES,
|
|
55
|
+
async prompt(sessionId, input) {
|
|
56
|
+
await ctx.session.prompt({ sessionID: sessionId, id: { text: input.text } });
|
|
57
|
+
},
|
|
58
|
+
async abort(id) {
|
|
59
|
+
await ctx.session.interrupt({ sessionID: id });
|
|
60
|
+
},
|
|
61
|
+
async hasSession(id) {
|
|
62
|
+
if (seen.has(id))
|
|
63
|
+
return true;
|
|
64
|
+
try {
|
|
65
|
+
remember(await ctx.session.get({ sessionID: id }));
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
async listSessions() {
|
|
73
|
+
return [...seen.values()]
|
|
74
|
+
.sort((a, b) => b.updatedAt - a.updatedAt)
|
|
75
|
+
.map((s) => ({ id: s.id, title: s.title, updatedAt: s.updatedAt }));
|
|
76
|
+
},
|
|
77
|
+
async listSessionSummaries() {
|
|
78
|
+
return [...seen.values()]
|
|
79
|
+
.sort((a, b) => b.updatedAt - a.updatedAt)
|
|
80
|
+
.map((s) => ({ id: s.id, title: s.title, agent: s.agent, lastActiveAt: s.updatedAt, unread: false }));
|
|
81
|
+
},
|
|
82
|
+
async createSession(opts) {
|
|
83
|
+
const info = (await ctx.session.create({
|
|
84
|
+
id: { title: opts.title },
|
|
85
|
+
...(opts.directory ? { location: { directory: opts.directory } } : {}),
|
|
86
|
+
}));
|
|
87
|
+
remember(info);
|
|
88
|
+
return { id: String(info?.id ?? '') };
|
|
89
|
+
},
|
|
90
|
+
async deleteSession(_id) {
|
|
91
|
+
// V2 ctx does not expose session removal (yet).
|
|
92
|
+
throw new Error('session deletion is not supported on opencode V2 hosts yet');
|
|
93
|
+
},
|
|
94
|
+
async renameSession(id, title) {
|
|
95
|
+
await ctx.session.rename({ sessionID: id, id: { title } });
|
|
96
|
+
const s = seen.get(id);
|
|
97
|
+
if (s)
|
|
98
|
+
s.title = title;
|
|
99
|
+
},
|
|
100
|
+
async getSessionMeta(id) {
|
|
101
|
+
remember(await ctx.session.get({ sessionID: id }));
|
|
102
|
+
return mapSessionInfo(await ctx.session.get({ sessionID: id }));
|
|
103
|
+
},
|
|
104
|
+
async getContext(id) {
|
|
105
|
+
const info = await ctx.session.get({ sessionID: id });
|
|
106
|
+
remember(info);
|
|
107
|
+
return { ...mapSessionInfo(info), directory: info.directory };
|
|
108
|
+
},
|
|
109
|
+
// ── reads not exposed by the V2 ctx — honest empties (capability-gated) ──
|
|
110
|
+
async getHistory(_id, _limit, _offset) {
|
|
111
|
+
return [];
|
|
112
|
+
},
|
|
113
|
+
async getMessageBlocks(_sessionId, _messageId) {
|
|
114
|
+
return [];
|
|
115
|
+
},
|
|
116
|
+
async getDiff(_id) {
|
|
117
|
+
return [];
|
|
118
|
+
},
|
|
119
|
+
async getTodos(_id) {
|
|
120
|
+
return [];
|
|
121
|
+
},
|
|
122
|
+
async getSessionsStatus() {
|
|
123
|
+
const all = [...seen.values()];
|
|
124
|
+
return { sessions: all.length, busy: 0, backend: 'opencode-v2' };
|
|
125
|
+
},
|
|
126
|
+
async ping() {
|
|
127
|
+
// In-process: the host is alive iff we are.
|
|
128
|
+
return true;
|
|
129
|
+
},
|
|
130
|
+
// ── catalog / commands ──
|
|
131
|
+
async getAgents(_directory) {
|
|
132
|
+
return [];
|
|
133
|
+
},
|
|
134
|
+
async getModels(_directory) {
|
|
135
|
+
return [];
|
|
136
|
+
},
|
|
137
|
+
async getMcp(_directory) {
|
|
138
|
+
return [];
|
|
139
|
+
},
|
|
140
|
+
async listWorkspaces() {
|
|
141
|
+
return [];
|
|
142
|
+
},
|
|
143
|
+
async listCommands() {
|
|
144
|
+
return [];
|
|
145
|
+
},
|
|
146
|
+
async runCommand(_id, _command, _args) {
|
|
147
|
+
throw new Error('slash-commands are not supported on opencode V2 hosts yet');
|
|
148
|
+
},
|
|
149
|
+
// ── permissions ──
|
|
150
|
+
async resolvePermission(id, requestId, decision) {
|
|
151
|
+
// V2 PermissionReply is exactly "once" | "always" | "reject" — same
|
|
152
|
+
// semantics as V1/OCRC, zero mapping (docs/v2-api-notes.md §3).
|
|
153
|
+
await ctx.permission.reply({ sessionID: id, requestID: requestId, reply: decision });
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
/** Session-registry maintenance, fed by the control plane's event loop. */
|
|
157
|
+
function observeSessionEvent(ev) {
|
|
158
|
+
if (!ev.sessionID)
|
|
159
|
+
return;
|
|
160
|
+
if (ev.type === 'session.deleted') {
|
|
161
|
+
seen.delete(ev.sessionID);
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
if (ev.type === 'session.created' || ev.type === 'session.updated' || ev.type === 'session.renamed') {
|
|
165
|
+
const prev = seen.get(ev.sessionID);
|
|
166
|
+
seen.set(ev.sessionID, {
|
|
167
|
+
id: ev.sessionID,
|
|
168
|
+
title: ev.title ?? prev?.title,
|
|
169
|
+
agent: ev.agent ?? prev?.agent,
|
|
170
|
+
updatedAt: Date.now(),
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return { backend, observeSessionEvent };
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=v2-backend.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"v2-backend.js","sourceRoot":"","sources":["../../../src/core/agent/v2-backend.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { createLogger } from '../utils/logger.js';
|
|
2
|
+
const log = createLogger('card-bus');
|
|
3
|
+
const DEFAULT_BUFFER = 256;
|
|
4
|
+
export function createCardBus(bufferSize = DEFAULT_BUFFER) {
|
|
5
|
+
const perSession = new Map();
|
|
6
|
+
const all = new Set();
|
|
7
|
+
const buffers = new Map();
|
|
8
|
+
const seqCounters = new Map();
|
|
9
|
+
function sessionIdOf(c) {
|
|
10
|
+
return 'sessionId' in c ? c.sessionId : undefined;
|
|
11
|
+
}
|
|
12
|
+
function safe(fn, c) {
|
|
13
|
+
try {
|
|
14
|
+
fn(c);
|
|
15
|
+
}
|
|
16
|
+
catch (err) {
|
|
17
|
+
const sid = 'sessionId' in c ? c.sessionId : undefined;
|
|
18
|
+
log.warn('subscriber error', err.message, { kind: c.kind, sessionId: sid });
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
publish(card) {
|
|
23
|
+
const sid = sessionIdOf(card);
|
|
24
|
+
// Stamp a per-session monotonic seq + a stable id (callers may pre-set id
|
|
25
|
+
// for streaming/assistant so the UI upserts the turn in place).
|
|
26
|
+
if (sid) {
|
|
27
|
+
const next = (seqCounters.get(sid) ?? 0) + 1;
|
|
28
|
+
seqCounters.set(sid, next);
|
|
29
|
+
card.seq = next;
|
|
30
|
+
}
|
|
31
|
+
if (!card.id)
|
|
32
|
+
card.id = `${card.kind}:${card.seq ?? Date.now()}`;
|
|
33
|
+
log.debug(`cardBus.publish: kind=${card.kind} id=${card.id} seq=${card.seq ?? '-'} sessionId=${sid ?? 'none'}`);
|
|
34
|
+
if (sid) {
|
|
35
|
+
const buf = buffers.get(sid) ?? [];
|
|
36
|
+
buf.push(card);
|
|
37
|
+
if (buf.length > bufferSize)
|
|
38
|
+
buf.shift();
|
|
39
|
+
buffers.set(sid, buf);
|
|
40
|
+
perSession.get(sid)?.forEach((fn) => safe(fn, card));
|
|
41
|
+
}
|
|
42
|
+
all.forEach((fn) => safe(fn, card));
|
|
43
|
+
},
|
|
44
|
+
subscribe(sessionId, fn) {
|
|
45
|
+
let s = perSession.get(sessionId);
|
|
46
|
+
if (!s) {
|
|
47
|
+
s = new Set();
|
|
48
|
+
perSession.set(sessionId, s);
|
|
49
|
+
}
|
|
50
|
+
s.add(fn);
|
|
51
|
+
return () => { s.delete(fn); };
|
|
52
|
+
},
|
|
53
|
+
subscribeAll(fn) {
|
|
54
|
+
all.add(fn);
|
|
55
|
+
return () => { all.delete(fn); };
|
|
56
|
+
},
|
|
57
|
+
recent(sessionId, limit = bufferSize) {
|
|
58
|
+
const buf = buffers.get(sessionId) ?? [];
|
|
59
|
+
return buf.slice(-limit);
|
|
60
|
+
},
|
|
61
|
+
oldestSeq(sessionId) {
|
|
62
|
+
return buffers.get(sessionId)?.[0]?.seq;
|
|
63
|
+
},
|
|
64
|
+
currentSeq(sessionId) {
|
|
65
|
+
return seqCounters.get(sessionId) ?? 0;
|
|
66
|
+
},
|
|
67
|
+
drop(sessionId) {
|
|
68
|
+
buffers.delete(sessionId);
|
|
69
|
+
perSession.delete(sessionId);
|
|
70
|
+
seqCounters.delete(sessionId);
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=card-bus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"card-bus.js","sourceRoot":"","sources":["../../src/core/card-bus.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
import { createLogger } from '../utils/logger.js';
|
|
4
|
+
const log = createLogger('channels');
|
|
5
|
+
const DEFAULT_IDS = [
|
|
6
|
+
{ id: 'tg-default', channel: 'telegram' },
|
|
7
|
+
{ id: 'wechat-default', channel: 'wechat' },
|
|
8
|
+
{ id: 'lark-default', channel: 'lark' },
|
|
9
|
+
];
|
|
10
|
+
function defaults() {
|
|
11
|
+
return DEFAULT_IDS.map(({ id, channel }) => ({
|
|
12
|
+
id,
|
|
13
|
+
channel,
|
|
14
|
+
enabled: channel === 'telegram', // the channel that actually ships today
|
|
15
|
+
credentials: {},
|
|
16
|
+
replyGranularity: 'standard', // ZCode 标准回复: hide the tool-call process
|
|
17
|
+
workspaces: { mode: 'all' },
|
|
18
|
+
}));
|
|
19
|
+
}
|
|
20
|
+
export function createChannelsStore(path) {
|
|
21
|
+
let bots = defaults();
|
|
22
|
+
function load() {
|
|
23
|
+
if (!existsSync(path))
|
|
24
|
+
return;
|
|
25
|
+
try {
|
|
26
|
+
const raw = JSON.parse(readFileSync(path, 'utf-8'));
|
|
27
|
+
if (!Array.isArray(raw.bots))
|
|
28
|
+
return;
|
|
29
|
+
// Merge by id so newly-added channel defaults appear on upgrade while
|
|
30
|
+
// persisted values win over defaults.
|
|
31
|
+
for (const saved of raw.bots) {
|
|
32
|
+
const target = bots.find((b) => b.id === saved?.id);
|
|
33
|
+
if (target)
|
|
34
|
+
Object.assign(target, saved, { channel: target.channel });
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
log.warn(`failed to load ${path}: ${err.message}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
let writeQueued;
|
|
42
|
+
function persist() {
|
|
43
|
+
if (writeQueued)
|
|
44
|
+
clearTimeout(writeQueued);
|
|
45
|
+
writeQueued = setTimeout(() => {
|
|
46
|
+
try {
|
|
47
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
48
|
+
const tmp = `${path}.tmp`;
|
|
49
|
+
writeFileSync(tmp, JSON.stringify({ bots }, null, 2), { mode: 0o600 });
|
|
50
|
+
renameSync(tmp, path);
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
log.warn(`persist failed: ${err.message}`);
|
|
54
|
+
}
|
|
55
|
+
}, 100);
|
|
56
|
+
writeQueued.unref?.();
|
|
57
|
+
}
|
|
58
|
+
load();
|
|
59
|
+
return {
|
|
60
|
+
list: () => bots.map((b) => ({ ...b })),
|
|
61
|
+
get: (id) => {
|
|
62
|
+
const b = bots.find((x) => x.id === id);
|
|
63
|
+
return b ? { ...b } : undefined;
|
|
64
|
+
},
|
|
65
|
+
update: (id, patch) => {
|
|
66
|
+
const b = bots.find((x) => x.id === id);
|
|
67
|
+
if (!b)
|
|
68
|
+
return undefined;
|
|
69
|
+
if (patch.enabled !== undefined)
|
|
70
|
+
b.enabled = patch.enabled;
|
|
71
|
+
if (patch.credentials !== undefined)
|
|
72
|
+
b.credentials = { ...patch.credentials };
|
|
73
|
+
if (patch.replyGranularity !== undefined)
|
|
74
|
+
b.replyGranularity = patch.replyGranularity;
|
|
75
|
+
if (patch.workspaces !== undefined)
|
|
76
|
+
b.workspaces = patch.workspaces;
|
|
77
|
+
persist();
|
|
78
|
+
return { ...b };
|
|
79
|
+
},
|
|
80
|
+
reset: (id) => {
|
|
81
|
+
const fresh = defaults().find((b) => b.id === id);
|
|
82
|
+
const idx = bots.findIndex((b) => b.id === id);
|
|
83
|
+
if (!fresh || idx === -1)
|
|
84
|
+
return undefined;
|
|
85
|
+
bots[idx] = fresh;
|
|
86
|
+
persist();
|
|
87
|
+
return { ...fresh };
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
/** Default on-disk location: ~/.ocrc/channels.json */
|
|
92
|
+
export function channelsPath(home) {
|
|
93
|
+
return join(home, 'channels.json');
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=channels.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channels.js","sourceRoot":"","sources":["../../src/core/channels.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
export function summarizeToolArgs(tool, input) {
|
|
2
|
+
if (tool === 'bash')
|
|
3
|
+
return (input?.command ?? '').slice(0, 60);
|
|
4
|
+
if (tool === 'read' || tool === 'edit' || tool === 'write')
|
|
5
|
+
return input?.filePath ?? '';
|
|
6
|
+
if (tool === 'grep' || tool === 'find')
|
|
7
|
+
return input?.pattern ?? input?.query ?? '';
|
|
8
|
+
return '';
|
|
9
|
+
}
|
|
10
|
+
export function messageToCards(sessionId, msg) {
|
|
11
|
+
// opencode SDK returns { info: {id, role, time, agent, model, ...}, parts: [...] }.
|
|
12
|
+
const info = msg.info ?? msg;
|
|
13
|
+
const parts = msg.parts ?? info?.parts ?? [];
|
|
14
|
+
const role = info?.role;
|
|
15
|
+
if (role === 'user') {
|
|
16
|
+
const textParts = [];
|
|
17
|
+
for (const part of parts) {
|
|
18
|
+
if (part.type === 'text' && typeof part.text === 'string') {
|
|
19
|
+
textParts.push(part.text);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
const ts = (typeof info.time?.created === 'number' ? info.time.created : info.ts) ?? Date.now();
|
|
23
|
+
return [{
|
|
24
|
+
kind: 'user',
|
|
25
|
+
sessionId,
|
|
26
|
+
text: textParts.join('') || '(empty)',
|
|
27
|
+
ts,
|
|
28
|
+
}];
|
|
29
|
+
}
|
|
30
|
+
if (role === 'assistant') {
|
|
31
|
+
const blocks = [];
|
|
32
|
+
for (const part of parts) {
|
|
33
|
+
if (part.type === 'text' && typeof part.text === 'string') {
|
|
34
|
+
blocks.push({ type: 'text', text: part.text });
|
|
35
|
+
}
|
|
36
|
+
if (part.type === 'tool' && typeof part.tool === 'string') {
|
|
37
|
+
const status = part.state?.status ?? 'running';
|
|
38
|
+
blocks.push({
|
|
39
|
+
type: 'tool',
|
|
40
|
+
tool: part.tool,
|
|
41
|
+
args: summarizeToolArgs(part.tool, part.state?.input ?? {}),
|
|
42
|
+
// opencode's terminal status is 'completed' (never 'done'); without
|
|
43
|
+
// mapping it, finished tools stay 'running' and blink forever.
|
|
44
|
+
status: status === 'error' ? 'error'
|
|
45
|
+
: status === 'completed' || status === 'done' ? 'done'
|
|
46
|
+
: 'running',
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const meta = {};
|
|
51
|
+
const agentName = typeof info.agent === 'string' ? info.agent : info.agent?.name;
|
|
52
|
+
if (agentName)
|
|
53
|
+
meta.agent = agentName;
|
|
54
|
+
const modelStr = typeof info.model === 'string'
|
|
55
|
+
? info.model
|
|
56
|
+
: info.model?.modelID ?? info.model?.id;
|
|
57
|
+
if (modelStr)
|
|
58
|
+
meta.model = modelStr;
|
|
59
|
+
if (typeof info.cost === 'number')
|
|
60
|
+
meta.cost = info.cost;
|
|
61
|
+
if (info.tokens)
|
|
62
|
+
meta.tokens = info.tokens;
|
|
63
|
+
return [{
|
|
64
|
+
kind: 'assistant',
|
|
65
|
+
sessionId,
|
|
66
|
+
blocks,
|
|
67
|
+
meta,
|
|
68
|
+
}];
|
|
69
|
+
}
|
|
70
|
+
return [];
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Default cap on history depth. Long sessions (hundreds of messages with
|
|
74
|
+
* subagent tool calls) blow up client-side rendering — 569-card sessions
|
|
75
|
+
* froze the browser. Callers can pass `limit` to override.
|
|
76
|
+
*/
|
|
77
|
+
export const DEFAULT_HISTORY_LIMIT = 50;
|
|
78
|
+
export function cardsFromMessages(sessionId, messages, limit = DEFAULT_HISTORY_LIMIT, offset = 0) {
|
|
79
|
+
// Window [len - limit - offset, len - offset): offset=0 is the default
|
|
80
|
+
// "last `limit` messages" view; larger offsets page backwards through
|
|
81
|
+
// older history (client-side "load earlier" in long sessions).
|
|
82
|
+
const end = Math.max(0, messages.length - Math.max(0, offset));
|
|
83
|
+
const start = limit > 0 ? Math.max(0, end - limit) : 0;
|
|
84
|
+
const recent = messages.slice(start, end);
|
|
85
|
+
const cards = [];
|
|
86
|
+
for (const msg of recent) {
|
|
87
|
+
cards.push(...messageToCards(sessionId, msg));
|
|
88
|
+
}
|
|
89
|
+
return cards;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=history.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"history.js","sourceRoot":"","sources":["../../src/core/history.ts"],"names":[],"mappings":"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"}
|