@ljwei-stak/dsh-model-route-bot 0.66.3 → 0.67.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/.dsh-plugin/bot-product.mjs +81 -5
- package/.dsh-plugin/client.js +17490 -1791
- package/README.i18n.yaml +4 -4
- package/README.md +409 -364
- package/README.zh.md +409 -364
- package/apps/integration-client/README.md +31 -7
- package/apps/integration-client/api.mjs +14 -3
- package/apps/integration-client/binding-editor.jsx +308 -109
- package/apps/integration-client/binding-model.mjs +262 -0
- package/apps/integration-client/binding.css +144 -0
- package/apps/integration-client/bot-model-status.mjs +18 -0
- package/apps/integration-client/bot-profile-identity.jsx +197 -0
- package/apps/integration-client/bot-profile.css +57 -0
- package/apps/integration-client/bot-profile.mjs +97 -0
- package/apps/integration-client/bot-settings-dialog.css +18 -0
- package/apps/integration-client/bot-settings-dialog.jsx +111 -0
- package/apps/integration-client/bot-thread-header-bridge.css +20 -0
- package/apps/integration-client/bot-thread-header.jsx +278 -0
- package/apps/integration-client/bot-threads-panel.jsx +378 -0
- package/apps/integration-client/bot-threads.css +169 -0
- package/apps/integration-client/chat-design.mjs +250 -0
- package/apps/integration-client/chat-ui.jsx +175 -0
- package/apps/integration-client/chat.css +477 -0
- package/apps/integration-client/composer-draft-binding.mjs +50 -0
- package/apps/integration-client/composer-draft-bound.jsx +14 -0
- package/apps/integration-client/composer-draft-host.jsx +142 -0
- package/apps/integration-client/composer-draft-session.jsx +287 -0
- package/apps/integration-client/composer-draft-witness.mjs +115 -0
- package/apps/integration-client/composer-draft.css +4 -0
- package/apps/integration-client/composer-draft.mjs +322 -0
- package/apps/integration-client/contact-attention.jsx +54 -0
- package/apps/integration-client/data-panel.jsx +439 -0
- package/apps/integration-client/data.css +69 -0
- package/apps/integration-client/desktop-bridge.mjs +1 -0
- package/apps/integration-client/desktop-http-socket.mjs +49 -0
- package/apps/integration-client/desktop-keyboard.mjs +32 -0
- package/apps/integration-client/desktop-pane.jsx +99 -30
- package/apps/integration-client/desktop-stream.mjs +13 -3
- package/apps/integration-client/desktop-tools.jsx +19 -0
- package/apps/integration-client/desktop-touch.mjs +27 -0
- package/apps/integration-client/desktop.css +41 -0
- package/apps/integration-client/independent-chat-controller.mjs +224 -0
- package/apps/integration-client/independent-chat-entry.jsx +61 -0
- package/apps/integration-client/independent-chat-navigation.mjs +21 -0
- package/apps/integration-client/independent-chat-page.jsx +148 -0
- package/apps/integration-client/independent-chat-rich.jsx +64 -0
- package/apps/integration-client/independent-chat-rich.mjs +30 -0
- package/apps/integration-client/independent-chat.css +73 -0
- package/apps/integration-client/index.jsx +24 -16
- package/apps/integration-client/library-panel.jsx +4 -1
- package/apps/integration-client/licenses/jsqr-1.4.0-LICENSE.txt +202 -0
- package/apps/integration-client/main-route-editor.jsx +94 -0
- package/apps/integration-client/main-route-model.mjs +100 -0
- package/apps/integration-client/model-picker.css +37 -0
- package/apps/integration-client/model-picker.jsx +83 -0
- package/apps/integration-client/native-activity.css +141 -0
- package/apps/integration-client/native-activity.jsx +276 -0
- package/apps/integration-client/native-activity.mjs +384 -0
- package/apps/integration-client/notifications-panel.jsx +186 -0
- package/apps/integration-client/notifications.css +126 -0
- package/apps/integration-client/pairing-qr.jsx +79 -0
- package/apps/integration-client/panels.jsx +126 -115
- package/apps/integration-client/product-slots.jsx +46 -0
- package/apps/integration-client/routine-recorder.mjs +23 -2
- package/apps/integration-client/secure-pairing.jsx +84 -0
- package/apps/integration-client/tasks-panel.jsx +32 -10
- package/apps/integration-client/ui-icons.jsx +17 -0
- package/apps/integration-client/usage-explorer.jsx +43 -0
- package/apps/integration-client/usage-report.mjs +71 -0
- package/apps/integration-client/usage.css +34 -0
- package/apps/integration-client/web-panel-model.mjs +140 -0
- package/apps/integration-client/web-panel-page.jsx +221 -0
- package/apps/integration-client/web-panel-pins-live.jsx +28 -0
- package/apps/integration-client/web-panel.css +139 -0
- package/apps/integration-client/workspace-model.mjs +67 -0
- package/apps/integration-client/workspace-navigation.mjs +56 -0
- package/apps/integration-client/workspace-ui.jsx +173 -0
- package/apps/integration-client/workspace.css +332 -0
- package/modules/bot-runtime/SOURCE.json +176 -50
- package/modules/bot-runtime/index.mjs +169 -13
- package/modules/bot-runtime/product-overlay/OVERLAY.json +128 -2
- package/modules/bot-runtime/product-overlay/base/src/client/header.js +244 -0
- package/modules/bot-runtime/product-overlay/base/src/client/learning-card.js +202 -0
- package/modules/bot-runtime/product-overlay/base/src/client/model-menu.js +371 -0
- package/modules/bot-runtime/product-overlay/base/src/client/secret-card.js +363 -0
- package/modules/bot-runtime/product-overlay/base/src/client/sources.js +68 -0
- package/modules/bot-runtime/product-overlay/base/src/client/turn-error.js +260 -0
- package/modules/bot-runtime/product-overlay/base/src/host/channel.js +647 -0
- package/modules/bot-runtime/product-overlay/base/src/host/memory.js +2050 -0
- package/modules/bot-runtime/product-overlay/base/src/host/models.js +314 -0
- package/modules/bot-runtime/product-overlay/base/src/host/parts.js +1473 -0
- package/modules/bot-runtime/product-overlay/base/src/host/privacy.js +368 -0
- package/modules/bot-runtime/product-overlay/base/src/host/roster.js +776 -0
- package/modules/bot-runtime/product-overlay/base/src/host/store.js +512 -0
- package/modules/bot-runtime/product-overlay/base/src/host/usage.js +653 -0
- package/modules/bot-runtime/product-overlay/patches/src/client/details-drawer.js.patch +48 -2
- package/modules/bot-runtime/product-overlay/patches/src/client/header.js.patch +41 -0
- package/modules/bot-runtime/product-overlay/patches/src/client/index.js.patch +33 -1
- package/modules/bot-runtime/product-overlay/patches/src/client/learning-card.js.patch +20 -0
- package/modules/bot-runtime/product-overlay/patches/src/client/model-menu.js.patch +24 -0
- package/modules/bot-runtime/product-overlay/patches/src/client/secret-card.js.patch +25 -0
- package/modules/bot-runtime/product-overlay/patches/src/client/sources.js.patch +52 -0
- package/modules/bot-runtime/product-overlay/patches/src/client/turn-error.js.patch +23 -0
- package/modules/bot-runtime/product-overlay/patches/src/host/channel.js.patch +46 -0
- package/modules/bot-runtime/product-overlay/patches/src/host/memory.js.patch +11 -0
- package/modules/bot-runtime/product-overlay/patches/src/host/models.js.patch +16 -0
- package/modules/bot-runtime/product-overlay/patches/src/host/parts.js.patch +95 -0
- package/modules/bot-runtime/product-overlay/patches/src/host/privacy.js.patch +11 -0
- package/modules/bot-runtime/product-overlay/patches/src/host/roster.js.patch +145 -0
- package/modules/bot-runtime/product-overlay/patches/src/host/store.js.patch +68 -0
- package/modules/bot-runtime/product-overlay/patches/src/host/usage.js.patch +11 -0
- package/modules/bot-runtime/read-model.mjs +19 -4
- package/modules/bot-runtime/vendor/ds-bot/src/client/details-drawer.js +15 -5
- package/modules/bot-runtime/vendor/ds-bot/src/client/header.js +9 -2
- package/modules/bot-runtime/vendor/ds-bot/src/client/index.js +9 -2
- package/modules/bot-runtime/vendor/ds-bot/src/client/learning-card.js +2 -2
- package/modules/bot-runtime/vendor/ds-bot/src/client/model-menu.js +5 -3
- package/modules/bot-runtime/vendor/ds-bot/src/client/secret-card.js +3 -3
- package/modules/bot-runtime/vendor/ds-bot/src/client/sources.js +25 -2
- package/modules/bot-runtime/vendor/ds-bot/src/client/turn-error.js +3 -2
- package/modules/bot-runtime/vendor/ds-bot/src/host/channel.js +14 -2
- package/modules/bot-runtime/vendor/ds-bot/src/host/memory.js +1 -1
- package/modules/bot-runtime/vendor/ds-bot/src/host/models.js +7 -0
- package/modules/bot-runtime/vendor/ds-bot/src/host/parts.js +26 -9
- package/modules/bot-runtime/vendor/ds-bot/src/host/privacy.js +1 -1
- package/modules/bot-runtime/vendor/ds-bot/src/host/roster.js +112 -3
- package/modules/bot-runtime/vendor/ds-bot/src/host/store.js +34 -1
- package/modules/bot-runtime/vendor/ds-bot/src/host/usage.js +1 -1
- package/modules/independent-runtime/index.mjs +152 -62
- package/modules/independent-runtime/remote-tools.mjs +8 -5
- package/modules/openmaus-protocol/NOTICE +10 -0
- package/modules/openmaus-protocol/README.md +15 -0
- package/modules/openmaus-protocol/SOURCE.json +68 -0
- package/modules/openmaus-protocol/dist/protocol.mjs +1203 -0
- package/modules/openmaus-protocol/index.mjs +1 -0
- package/modules/openmaus-protocol/transport.mjs +77 -0
- package/modules/openmaus-protocol/vendor/LICENSE +202 -0
- package/modules/openmaus-protocol/vendor/companion/src/e2e/README.md +405 -0
- package/modules/openmaus-protocol/vendor/companion/src/e2e/credentials.ts +128 -0
- package/modules/openmaus-protocol/vendor/companion/src/e2e/descriptor.ts +84 -0
- package/modules/openmaus-protocol/vendor/companion/src/e2e/noise.ts +456 -0
- package/modules/openmaus-protocol/vendor/companion/src/e2e/phone.ts +104 -0
- package/modules/openmaus-protocol/vendor/companion/src/e2e/session.ts +417 -0
- package/modules/openmaus-protocol/vendor/companion/src/e2e/vectors/v1.json +2565 -0
- package/modules/openmaus-protocol/vendor/companion/src/e2e/vectors/v1.sha256 +1 -0
- package/modules/openmaus-protocol/vendor/companion/src/e2e/yamux.ts +335 -0
- package/package.json +20 -6
- package/packages/bot-acp/README.md +156 -0
- package/packages/bot-acp/licenses/LICENSE-OpenMausBot +202 -0
- package/packages/bot-acp/licenses/NOTICE.md +27 -0
- package/packages/bot-acp/src/acp-adapter.mjs +795 -0
- package/packages/bot-acp/src/acp-host.mjs +148 -0
- package/packages/bot-acp/src/native-launch.mjs +121 -0
- package/packages/bot-acp/src/permission-policy.mjs +283 -0
- package/packages/bot-acp/src/rpc-codec.mjs +265 -0
- package/packages/bot-acp/src/session-core.mjs +581 -0
- package/packages/bot-acp/src/stdio-rpc.mjs +329 -0
- package/packages/bot-engines/README.md +281 -0
- package/packages/bot-engines/licenses/LICENSE-OpenMausBot +202 -0
- package/packages/bot-engines/licenses/NOTICE.md +32 -0
- package/packages/bot-engines/src/claude-engine.mjs +772 -0
- package/packages/bot-engines/src/claude-llm-adapter.mjs +797 -0
- package/packages/bot-engines/src/claude-llm-turn.mjs +292 -0
- package/packages/bot-engines/src/claude-permission-broker.mjs +130 -0
- package/packages/bot-engines/src/claude-permission-proxy.mjs +87 -0
- package/packages/bot-engines/src/claude-protocol.mjs +177 -0
- package/packages/bot-engines/src/driver-catalog.mjs +334 -0
- package/packages/bot-engines/src/host-loop-request.mjs +95 -0
- package/packages/bot-engines/src/host-registrations.mjs +105 -0
- package/packages/capability-broker/src/cli-bootstrap.mjs +86 -16
- package/packages/capability-broker/src/cli-bridge-response.mjs +80 -0
- package/packages/capability-broker/src/cli-stdio-bridge.mjs +21 -8
- package/packages/cli-runtime/src/codex-session-core.mjs +4 -0
- package/packages/cli-runtime/src/native-cli-output.mjs +57 -0
- package/packages/cli-runtime/src/native-peer.ps1 +51 -3
- package/packages/cli-runtime/src/native-process.mjs +77 -14
- package/packages/model-router-plugin/README.md +3 -3
- package/packages/model-router-plugin/package.json +1 -1
- package/packages/orchestration/src/binding-product.mjs +19 -0
- package/packages/orchestration/src/bot-data-actions.mjs +45 -0
- package/packages/orchestration/src/bot-data-chart.mjs +109 -0
- package/packages/orchestration/src/bot-data-context.mjs +44 -0
- package/packages/orchestration/src/bot-data-engine.mjs +809 -0
- package/packages/orchestration/src/bot-data-io.mjs +186 -0
- package/packages/orchestration/src/bot-data-sql.mjs +195 -0
- package/packages/orchestration/src/bot-data-surface.mjs +144 -0
- package/packages/orchestration/src/bot-data-tools.mjs +68 -0
- package/packages/orchestration/src/bot-data-worker.mjs +228 -0
- package/packages/orchestration/src/bot-independent-execution.mjs +195 -0
- package/packages/orchestration/src/bot-independent-stream.mjs +74 -0
- package/packages/orchestration/src/bot-loop.mjs +152 -19
- package/packages/orchestration/src/bot-notifications.mjs +159 -0
- package/packages/orchestration/src/bot-policy.mjs +43 -4
- package/packages/orchestration/src/bot-profile.mjs +171 -0
- package/packages/orchestration/src/bot-routine.mjs +4 -4
- package/packages/orchestration/src/bot-runtime-assembly.mjs +255 -8
- package/packages/orchestration/src/bot-runtime-switch.mjs +13 -2
- package/packages/orchestration/src/bot-serving.mjs +164 -0
- package/packages/orchestration/src/bot-session-store.mjs +105 -9
- package/packages/orchestration/src/bot-settings.mjs +50 -11
- package/packages/orchestration/src/bot-thread-admission.mjs +84 -0
- package/packages/orchestration/src/bot-thread-host.mjs +187 -0
- package/packages/orchestration/src/bot-threads.mjs +790 -0
- package/packages/orchestration/src/data-product-access.mjs +37 -0
- package/packages/orchestration/src/data-tool-contract.mjs +291 -0
- package/packages/orchestration/src/desktop-http-carrier.mjs +120 -0
- package/packages/orchestration/src/desktop-proxy.mjs +311 -0
- package/packages/orchestration/src/desktop-sessions.mjs +43 -9
- package/packages/orchestration/src/ds-lifecycle.mjs +31 -4
- package/packages/orchestration/src/grant-refresh-queue.mjs +17 -0
- package/packages/orchestration/src/independent-chat-page.mjs +39 -0
- package/packages/orchestration/src/independent-chat-service.mjs +308 -0
- package/packages/orchestration/src/independent-context-state.mjs +44 -0
- package/packages/orchestration/src/independent-message-wire.mjs +84 -0
- package/packages/orchestration/src/independent-tool-catalog.mjs +175 -0
- package/packages/orchestration/src/independent-tool-families.mjs +73 -0
- package/packages/orchestration/src/independent-tool-host.mjs +344 -0
- package/packages/orchestration/src/main-bot-grant.mjs +15 -0
- package/packages/orchestration/src/main-model-routes.mjs +208 -0
- package/packages/orchestration/src/model-accounting.mjs +99 -35
- package/packages/orchestration/src/model-auxiliary-dispatch.mjs +187 -0
- package/packages/orchestration/src/model-loop-frame.mjs +179 -0
- package/packages/orchestration/src/model-prepared-generation.mjs +175 -0
- package/packages/orchestration/src/model-request-bounds.mjs +111 -0
- package/packages/orchestration/src/native-activity-contract.mjs +491 -0
- package/packages/orchestration/src/native-activity-service.mjs +102 -0
- package/packages/orchestration/src/native-activity-store.mjs +249 -0
- package/packages/orchestration/src/native-conversation-tools.mjs +78 -0
- package/packages/orchestration/src/native-data-tools.mjs +100 -0
- package/packages/orchestration/src/native-remote-actions.mjs +742 -0
- package/packages/orchestration/src/native-team-tools.mjs +73 -0
- package/packages/orchestration/src/pairing-invite.mjs +37 -0
- package/packages/orchestration/src/product-composition.mjs +1559 -1001
- package/packages/orchestration/src/remote-machines.mjs +82 -14
- package/packages/orchestration/src/routine-execution.mjs +5 -3
- package/packages/orchestration/src/routine-session.mjs +19 -13
- package/packages/orchestration/src/secure-pairing-host.mjs +112 -0
- package/packages/orchestration/src/task-journal.mjs +29 -0
- package/packages/orchestration/src/task-product.mjs +17 -0
- package/packages/orchestration/src/team-assignment-store.mjs +120 -0
- package/packages/orchestration/src/team-bridge.mjs +282 -0
- package/packages/orchestration/src/team-scheduler.mjs +83 -0
- package/packages/orchestration/src/team-sdk-tools.mjs +84 -0
- package/packages/orchestration/src/team-tool-contract.mjs +284 -0
- package/packages/orchestration/src/ui-host-namespace.mjs +23 -0
- package/packages/orchestration/src/web-panel-actions.mjs +103 -0
- package/packages/orchestration/src/web-panel-framing.mjs +227 -0
- package/packages/orchestration/src/web-panel-store.mjs +206 -0
- package/remote-computer-agent/README.md +39 -29
- package/remote-computer-agent/build.mjs +3 -0
- package/remote-computer-agent/dist/OPENMAUSBOT_LICENSE +202 -0
- package/remote-computer-agent/dist/OPENMAUSBOT_NOTICE +10 -0
- package/remote-computer-agent/dist/OPENMAUSBOT_SOURCE.json +68 -0
- package/remote-computer-agent/dist/cli-stdio-bridge.mjs +215 -25
- package/remote-computer-agent/dist/cli-stdio-bridge.mjs.map +4 -4
- package/remote-computer-agent/dist/cli.mjs +1688 -168
- package/remote-computer-agent/dist/cli.mjs.map +4 -4
- package/remote-computer-agent/dist/index.mjs +1579 -122
- package/remote-computer-agent/dist/index.mjs.map +4 -4
- package/remote-computer-agent/dist/native-peer.ps1 +51 -3
- package/remote-computer-agent/package-lock.json +308 -2
- package/remote-computer-agent/package.json +2 -1
- package/remote-computer-agent/pair-device.ps1 +20 -0
- package/remote-computer-agent/setup.ps1 +38 -16
- package/remote-computer-agent/src/cli.ts +24 -3
- package/remote-computer-agent/src/desktop-session.ts +11 -3
- package/remote-computer-agent/src/e2e-server.ts +81 -0
- package/remote-computer-agent/src/pairing-page.ts +35 -0
- package/remote-computer-agent/src/protocol.ts +25 -25
- package/remote-computer-agent/src/secure-pairing.ts +105 -0
- package/remote-computer-agent/src/store.ts +20 -5
- package/remote-computer-agent/src/transport.ts +39 -15
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
// Pure JSON-RPC 2.0 codec for the ACP (Agent Client Protocol) stdio wire.
|
|
2
|
+
//
|
|
3
|
+
// Ported and re-grounded from OpenMausBot server/drivers/acp/host.ts and
|
|
4
|
+
// rpc-error.ts at pin 1bc4749aa8307d7d6998bf86de4ef6478460dd93 (Apache-2.0);
|
|
5
|
+
// see licenses/NOTICE.md. Everything here is pure: no child process, no clock,
|
|
6
|
+
// no policy. Bounds are explicit so a hostile or broken peer cannot grow an
|
|
7
|
+
// unbounded buffer, and a message that does not match the documented shape is
|
|
8
|
+
// counted as malformed instead of being guessed at.
|
|
9
|
+
|
|
10
|
+
import { StringDecoder } from 'node:string_decoder'
|
|
11
|
+
|
|
12
|
+
export const JSONRPC_VERSION = '2.0'
|
|
13
|
+
|
|
14
|
+
/** Default bounds. Every one is a hard limit; none of them are advisory. */
|
|
15
|
+
export const DEFAULT_MAX_FRAME_BYTES = 262_144
|
|
16
|
+
export const DEFAULT_MAX_PENDING = 64
|
|
17
|
+
export const DEFAULT_MAX_BACKLOG_BYTES = 1_048_576
|
|
18
|
+
export const DEFAULT_REQUEST_TIMEOUT_MS = 300_000
|
|
19
|
+
export const DEFAULT_IDLE_TIMEOUT_MS = 180_000
|
|
20
|
+
export const MAX_ERROR_TEXT = 1500
|
|
21
|
+
export const MAX_LOG_PREVIEW = 512
|
|
22
|
+
|
|
23
|
+
/** Fixed JSON-RPC error codes. Vendor codes are never remapped onto these. */
|
|
24
|
+
export const RPC_PARSE_ERROR = -32700
|
|
25
|
+
export const RPC_INVALID_REQUEST = -32600
|
|
26
|
+
export const RPC_METHOD_NOT_FOUND = -32601
|
|
27
|
+
export const RPC_INVALID_PARAMS = -32602
|
|
28
|
+
export const RPC_INTERNAL_ERROR = -32603
|
|
29
|
+
|
|
30
|
+
/** ACP wire constants, taken from the upstream driver at the recorded pin. */
|
|
31
|
+
export const ACP_PROTOCOL_VERSION = 1
|
|
32
|
+
export const ACP_METHODS = Object.freeze({
|
|
33
|
+
initialize: 'initialize',
|
|
34
|
+
authenticate: 'authenticate',
|
|
35
|
+
sessionNew: 'session/new',
|
|
36
|
+
sessionLoad: 'session/load',
|
|
37
|
+
sessionPrompt: 'session/prompt',
|
|
38
|
+
sessionCancel: 'session/cancel',
|
|
39
|
+
sessionUpdate: 'session/update',
|
|
40
|
+
sessionClose: 'session/close',
|
|
41
|
+
sessionRequestPermission: 'session/request_permission',
|
|
42
|
+
sessionSetModel: 'session/set_model',
|
|
43
|
+
sessionSetConfigOption: 'session/set_config_option',
|
|
44
|
+
sessionSetMode: 'session/set_mode',
|
|
45
|
+
fsReadTextFile: 'fs/read_text_file',
|
|
46
|
+
fsWriteTextFile: 'fs/write_text_file',
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
/** Client methods this adapter refuses for every session, in every version. */
|
|
50
|
+
export const CLIENT_FILE_METHODS = Object.freeze([ACP_METHODS.fsReadTextFile, ACP_METHODS.fsWriteTextFile])
|
|
51
|
+
export const TERMINAL_METHOD_PREFIX = 'terminal/'
|
|
52
|
+
|
|
53
|
+
/** A JSON-RPC id is a string or an integer. Floats, booleans and null are not ids. */
|
|
54
|
+
export function isValidMessageId(value) {
|
|
55
|
+
if (typeof value === 'string') return value.length > 0 && value.length <= 128
|
|
56
|
+
return Number.isInteger(value)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const bounded = value => (value.length > MAX_ERROR_TEXT ? `${value.slice(0, MAX_ERROR_TEXT - 1)}…` : value)
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* A wire error to Error. Vendors put the actionable cause under `data`; only
|
|
63
|
+
* known text fields surface, bounded, never a whole response body.
|
|
64
|
+
*/
|
|
65
|
+
export function errorFromWire(value, method) {
|
|
66
|
+
const error = value && typeof value === 'object' && !Array.isArray(value) ? value : {}
|
|
67
|
+
const message = typeof error.message === 'string' && error.message ? error.message : 'ACP request failed'
|
|
68
|
+
const data = error.data
|
|
69
|
+
const detail = typeof data === 'string' && data
|
|
70
|
+
? data
|
|
71
|
+
: typeof data?.details === 'string' && data.details
|
|
72
|
+
? data.details
|
|
73
|
+
: typeof data?.message === 'string' && data.message
|
|
74
|
+
? data.message
|
|
75
|
+
: typeof data?.error?.message === 'string' && data.error.message
|
|
76
|
+
? data.error.message
|
|
77
|
+
: ''
|
|
78
|
+
const context = [
|
|
79
|
+
typeof method === 'string' && method ? method : '',
|
|
80
|
+
typeof data?.service === 'string' && data.service ? `service: ${data.service}` : '',
|
|
81
|
+
typeof data?.errorName === 'string' && data.errorName ? data.errorName : '',
|
|
82
|
+
].filter(Boolean).join(', ')
|
|
83
|
+
const diagnostic = `${detail && detail !== message ? `${message}: ${detail}` : message}${context ? ` (${context})` : ''}`
|
|
84
|
+
const failure = new Error(bounded(diagnostic))
|
|
85
|
+
return Object.assign(failure, {
|
|
86
|
+
rpcCode: typeof error.code === 'number' ? error.code : null,
|
|
87
|
+
rpcData: data,
|
|
88
|
+
// -32603 is JSON-RPC's internal error; invalid params, unknown methods and
|
|
89
|
+
// auth refusals keep the session usable.
|
|
90
|
+
acpSessionFailure: error.code === RPC_INTERNAL_ERROR,
|
|
91
|
+
})
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export function rpcErrorObject(code, message, data) {
|
|
95
|
+
const error = { code, message: typeof message === 'string' ? message : 'error' }
|
|
96
|
+
if (data !== undefined) error.data = data
|
|
97
|
+
return error
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Newline-delimited JSON framing with a hard frame cap. A multi-byte character
|
|
102
|
+
* split across reads is decoded as one unit; a frame over the cap is dropped as
|
|
103
|
+
* a whole and reported once, never parsed in pieces.
|
|
104
|
+
*/
|
|
105
|
+
export function createFrameDecoder({ maxFrameBytes = DEFAULT_MAX_FRAME_BYTES, onFrame, onError } = {}) {
|
|
106
|
+
if (!Number.isSafeInteger(maxFrameBytes) || maxFrameBytes < 1024) throw new TypeError('ACP_FRAME_LIMIT_INVALID')
|
|
107
|
+
if (typeof onFrame !== 'function') throw new TypeError('ACP_FRAME_SINK_REQUIRED')
|
|
108
|
+
const decoder = new StringDecoder('utf8')
|
|
109
|
+
let buffer = ''
|
|
110
|
+
let dropping = false
|
|
111
|
+
let frames = 0, malformed = 0, oversize = 0, bytes = 0, blank = 0
|
|
112
|
+
const reportOversize = () => {
|
|
113
|
+
oversize++
|
|
114
|
+
if (typeof onError === 'function') onError(Object.assign(new Error('ACP_FRAME_LIMIT'), { acpFrameLimit: true }))
|
|
115
|
+
}
|
|
116
|
+
return Object.freeze({
|
|
117
|
+
write(chunk) {
|
|
118
|
+
let text = typeof chunk === 'string' ? chunk : decoder.write(chunk)
|
|
119
|
+
if (!text) return
|
|
120
|
+
bytes += Buffer.byteLength(text)
|
|
121
|
+
if (dropping) {
|
|
122
|
+
// An oversized frame is dropped whole: discard through its terminator.
|
|
123
|
+
const end = text.indexOf('\n')
|
|
124
|
+
if (end === -1) return
|
|
125
|
+
text = text.slice(end + 1)
|
|
126
|
+
dropping = false
|
|
127
|
+
reportOversize()
|
|
128
|
+
}
|
|
129
|
+
buffer += text
|
|
130
|
+
if (Buffer.byteLength(buffer) > maxFrameBytes) {
|
|
131
|
+
const end = buffer.indexOf('\n')
|
|
132
|
+
if (end === -1) { dropping = true; buffer = ''; reportOversize(); return }
|
|
133
|
+
buffer = buffer.slice(end + 1)
|
|
134
|
+
reportOversize()
|
|
135
|
+
}
|
|
136
|
+
let end
|
|
137
|
+
while ((end = buffer.indexOf('\n')) !== -1) {
|
|
138
|
+
const line = buffer.slice(0, end).replace(/\r$/, '')
|
|
139
|
+
buffer = buffer.slice(end + 1)
|
|
140
|
+
if (!line.trim()) { blank++; continue }
|
|
141
|
+
if (Buffer.byteLength(line) > maxFrameBytes) { reportOversize(); continue }
|
|
142
|
+
frames++
|
|
143
|
+
onFrame(line)
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
/** Feed the decoder's trailing bytes and treat a final unterminated frame as nothing said. */
|
|
147
|
+
end() {
|
|
148
|
+
const tail = decoder.end()
|
|
149
|
+
if (tail) this.write(tail)
|
|
150
|
+
buffer = ''
|
|
151
|
+
dropping = false
|
|
152
|
+
},
|
|
153
|
+
get stats() {
|
|
154
|
+
return Object.freeze({ frames, malformed, oversize, blank, bytes, pendingBytes: Buffer.byteLength(buffer) })
|
|
155
|
+
},
|
|
156
|
+
})
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Parse one frame. Returns null for anything that is not a single JSON-RPC
|
|
161
|
+
* object: batches, arrays, scalars and parse failures are all malformed.
|
|
162
|
+
*/
|
|
163
|
+
export function parseFrame(line) {
|
|
164
|
+
if (typeof line !== 'string' || !line.trim()) return null
|
|
165
|
+
let value
|
|
166
|
+
try {
|
|
167
|
+
value = JSON.parse(line)
|
|
168
|
+
} catch {
|
|
169
|
+
return null
|
|
170
|
+
}
|
|
171
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) return null
|
|
172
|
+
return value
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Classify a parsed message. A response carries an id and neither method; a
|
|
177
|
+
* server request carries both; a notification carries a method and no id.
|
|
178
|
+
* Anything else is `invalid` and must be counted, not acted on.
|
|
179
|
+
*/
|
|
180
|
+
export function classifyMessage(message) {
|
|
181
|
+
if (!message || typeof message !== 'object' || Array.isArray(message)) return { kind: 'invalid', reason: 'not-an-object' }
|
|
182
|
+
if (message.jsonrpc !== undefined && message.jsonrpc !== JSONRPC_VERSION) return { kind: 'invalid', reason: 'bad-jsonrpc' }
|
|
183
|
+
const hasId = Object.hasOwn(message, 'id') && message.id !== null && message.id !== undefined
|
|
184
|
+
const hasMethod = Object.hasOwn(message, 'method') && typeof message.method === 'string' && message.method
|
|
185
|
+
if (hasId && !isValidMessageId(message.id)) return { kind: 'invalid', reason: 'bad-id' }
|
|
186
|
+
if (hasMethod && hasId) {
|
|
187
|
+
return { kind: 'request', id: message.id, method: message.method, params: message.params, raw: message }
|
|
188
|
+
}
|
|
189
|
+
if (hasMethod) {
|
|
190
|
+
return { kind: 'notification', method: message.method, params: message.params, raw: message }
|
|
191
|
+
}
|
|
192
|
+
if (hasId) {
|
|
193
|
+
const hasResult = Object.hasOwn(message, 'result')
|
|
194
|
+
const hasError = Object.hasOwn(message, 'error') && message.error !== undefined && message.error !== null
|
|
195
|
+
if (hasError) return { kind: 'response', id: message.id, error: message.error, raw: message }
|
|
196
|
+
if (hasResult) return { kind: 'response', id: message.id, result: message.result, raw: message }
|
|
197
|
+
return { kind: 'invalid', reason: 'response-without-result-or-error' }
|
|
198
|
+
}
|
|
199
|
+
return { kind: 'invalid', reason: 'no-method-no-id' }
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/** Bounded preview for diagnostic logs: never a whole tool payload or credential. */
|
|
203
|
+
export function previewMessage(message) {
|
|
204
|
+
try {
|
|
205
|
+
const text = JSON.stringify(message) ?? ''
|
|
206
|
+
return text.length > MAX_LOG_PREVIEW ? `${text.slice(0, MAX_LOG_PREVIEW - 1)}…` : text
|
|
207
|
+
} catch {
|
|
208
|
+
return '[unserializable]'
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/** True when the agent is asking the client to touch the local filesystem. */
|
|
213
|
+
export function isClientFileMethod(method) {
|
|
214
|
+
return CLIENT_FILE_METHODS.includes(method)
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/** True when the agent is asking the client to run a local terminal. */
|
|
218
|
+
export function isTerminalMethod(method) {
|
|
219
|
+
return typeof method === 'string' && method.startsWith(TERMINAL_METHOD_PREFIX)
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Client capabilities sent on initialize. File and terminal access are off
|
|
224
|
+
* unless the Host explicitly turns them on; a hand-written prompt is never the
|
|
225
|
+
* security boundary, so the capability and the method refusal agree.
|
|
226
|
+
*/
|
|
227
|
+
export function clientCapabilities({ fileSystem = false, terminal = false, meta } = {}) {
|
|
228
|
+
const allow = fileSystem === true
|
|
229
|
+
return Object.freeze({
|
|
230
|
+
fs: { readTextFile: allow, writeTextFile: allow },
|
|
231
|
+
terminal: terminal === true,
|
|
232
|
+
...(meta && typeof meta === 'object' ? { _meta: meta } : {}),
|
|
233
|
+
})
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/** ACP advertises optional operations as capability objects; older runtimes send booleans. */
|
|
237
|
+
const advertised = value => value === true || (typeof value === 'object' && value !== null && !Array.isArray(value))
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Read the initialize result against the fixed schema. Unknown fields are kept
|
|
241
|
+
* verbatim under `raw` for diagnostics and never interpreted.
|
|
242
|
+
*/
|
|
243
|
+
export function readAgentCapabilities(initializeResult) {
|
|
244
|
+
const result = initializeResult && typeof initializeResult === 'object' && !Array.isArray(initializeResult) ? initializeResult : {}
|
|
245
|
+
const agent = result.agentCapabilities && typeof result.agentCapabilities === 'object' && !Array.isArray(result.agentCapabilities) ? result.agentCapabilities : {}
|
|
246
|
+
const session = agent.sessionCapabilities && typeof agent.sessionCapabilities === 'object' && !Array.isArray(agent.sessionCapabilities) ? agent.sessionCapabilities : {}
|
|
247
|
+
const prompt = agent.promptCapabilities && typeof agent.promptCapabilities === 'object' && !Array.isArray(agent.promptCapabilities) ? agent.promptCapabilities : {}
|
|
248
|
+
const mcp = agent.mcpCapabilities && typeof agent.mcpCapabilities === 'object' && !Array.isArray(agent.mcpCapabilities) ? agent.mcpCapabilities : {}
|
|
249
|
+
const auth = agent.auth && typeof agent.auth === 'object' && !Array.isArray(agent.auth) ? agent.auth : {}
|
|
250
|
+
const info = result.agentInfo && typeof result.agentInfo === 'object' && !Array.isArray(result.agentInfo) ? result.agentInfo : {}
|
|
251
|
+
return Object.freeze({
|
|
252
|
+
protocolVersion: typeof result.protocolVersion === 'number' ? result.protocolVersion : null,
|
|
253
|
+
agentName: typeof info.name === 'string' ? info.name : null,
|
|
254
|
+
agentVersion: typeof info.version === 'string' ? info.version : null,
|
|
255
|
+
authMethods: Array.isArray(result.authMethods) ? result.authMethods : [],
|
|
256
|
+
loadSession: agent.loadSession === true,
|
|
257
|
+
sessionResume: advertised(session.resume),
|
|
258
|
+
sessionClose: advertised(session.close),
|
|
259
|
+
authLogout: advertised(auth.logout),
|
|
260
|
+
promptImage: prompt.image === true,
|
|
261
|
+
mcpHttp: mcp.http === true,
|
|
262
|
+
mcpSse: mcp.sse === true,
|
|
263
|
+
raw: result,
|
|
264
|
+
})
|
|
265
|
+
}
|