@animalabs/agent-framework 0.23.1 → 0.24.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/README.md +212 -42
- package/dist/src/agent.d.ts +60 -9
- package/dist/src/agent.d.ts.map +1 -1
- package/dist/src/agent.js +92 -12
- package/dist/src/agent.js.map +1 -1
- package/dist/src/api/server.d.ts.map +1 -1
- package/dist/src/api/server.js +14 -12
- package/dist/src/api/server.js.map +1 -1
- package/dist/src/code-execution/engine.d.ts +177 -0
- package/dist/src/code-execution/engine.d.ts.map +1 -0
- package/dist/src/code-execution/engine.js +494 -0
- package/dist/src/code-execution/engine.js.map +1 -0
- package/dist/src/code-execution/index.d.ts +5 -10
- package/dist/src/code-execution/index.d.ts.map +1 -1
- package/dist/src/code-execution/index.js +5 -9
- package/dist/src/code-execution/index.js.map +1 -1
- package/dist/src/code-execution/isolate/calls.d.ts +114 -0
- package/dist/src/code-execution/isolate/calls.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/calls.js +145 -0
- package/dist/src/code-execution/isolate/calls.js.map +1 -0
- package/dist/src/code-execution/isolate/child-entry.d.ts +2 -0
- package/dist/src/code-execution/isolate/child-entry.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/child-entry.js +5 -0
- package/dist/src/code-execution/isolate/child-entry.js.map +1 -0
- package/dist/src/code-execution/isolate/child-main.d.ts +26 -0
- package/dist/src/code-execution/isolate/child-main.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/child-main.js +132 -0
- package/dist/src/code-execution/isolate/child-main.js.map +1 -0
- package/dist/src/code-execution/isolate/child.d.ts +44 -0
- package/dist/src/code-execution/isolate/child.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/child.js +315 -0
- package/dist/src/code-execution/isolate/child.js.map +1 -0
- package/dist/src/code-execution/isolate/frames.d.ts +80 -0
- package/dist/src/code-execution/isolate/frames.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/frames.js +210 -0
- package/dist/src/code-execution/isolate/frames.js.map +1 -0
- package/dist/src/code-execution/isolate/output.d.ts +68 -0
- package/dist/src/code-execution/isolate/output.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/output.js +143 -0
- package/dist/src/code-execution/isolate/output.js.map +1 -0
- package/dist/src/code-execution/isolate/prelude.d.ts +109 -0
- package/dist/src/code-execution/isolate/prelude.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/prelude.js +401 -0
- package/dist/src/code-execution/isolate/prelude.js.map +1 -0
- package/dist/src/code-execution/isolate/protocol.d.ts +151 -0
- package/dist/src/code-execution/isolate/protocol.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/protocol.js +150 -0
- package/dist/src/code-execution/isolate/protocol.js.map +1 -0
- package/dist/src/code-execution/isolate/render.d.ts +57 -0
- package/dist/src/code-execution/isolate/render.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/render.js +214 -0
- package/dist/src/code-execution/isolate/render.js.map +1 -0
- package/dist/src/code-execution/isolate/runner.d.ts +250 -0
- package/dist/src/code-execution/isolate/runner.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/runner.js +854 -0
- package/dist/src/code-execution/isolate/runner.js.map +1 -0
- package/dist/src/code-execution/isolate/scripts.d.ts +175 -0
- package/dist/src/code-execution/isolate/scripts.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/scripts.js +357 -0
- package/dist/src/code-execution/isolate/scripts.js.map +1 -0
- package/dist/src/code-execution/quickjs.wasm +0 -0
- package/dist/src/code-execution/tool-definition.d.ts +93 -43
- package/dist/src/code-execution/tool-definition.d.ts.map +1 -1
- package/dist/src/code-execution/tool-definition.js +176 -142
- package/dist/src/code-execution/tool-definition.js.map +1 -1
- package/dist/src/deadline-timer.d.ts +3 -0
- package/dist/src/deadline-timer.d.ts.map +1 -1
- package/dist/src/deadline-timer.js +1 -1
- package/dist/src/deadline-timer.js.map +1 -1
- package/dist/src/framework.d.ts +1036 -440
- package/dist/src/framework.d.ts.map +1 -1
- package/dist/src/framework.js +4131 -2228
- package/dist/src/framework.js.map +1 -1
- package/dist/src/gate/event-gate.d.ts +28 -1
- package/dist/src/gate/event-gate.d.ts.map +1 -1
- package/dist/src/gate/event-gate.js +88 -10
- package/dist/src/gate/event-gate.js.map +1 -1
- package/dist/src/held-writes.d.ts +16 -3
- package/dist/src/held-writes.d.ts.map +1 -1
- package/dist/src/held-writes.js +16 -3
- package/dist/src/held-writes.js.map +1 -1
- package/dist/src/index.d.ts +6 -6
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +9 -8
- package/dist/src/index.js.map +1 -1
- package/dist/src/mcpl/channel-registry.d.ts +471 -75
- package/dist/src/mcpl/channel-registry.d.ts.map +1 -1
- package/dist/src/mcpl/channel-registry.js +1673 -337
- package/dist/src/mcpl/channel-registry.js.map +1 -1
- package/dist/src/mcpl/conversation-router.d.ts +12 -7
- package/dist/src/mcpl/conversation-router.d.ts.map +1 -1
- package/dist/src/mcpl/conversation-router.js +12 -7
- package/dist/src/mcpl/conversation-router.js.map +1 -1
- package/dist/src/mcpl/convert-block.d.ts.map +1 -1
- package/dist/src/mcpl/convert-block.js +9 -5
- package/dist/src/mcpl/convert-block.js.map +1 -1
- package/dist/src/mcpl/inbound-source.d.ts +50 -0
- package/dist/src/mcpl/inbound-source.d.ts.map +1 -1
- package/dist/src/mcpl/inbound-source.js +130 -0
- package/dist/src/mcpl/inbound-source.js.map +1 -1
- package/dist/src/mcpl/index.d.ts +2 -1
- package/dist/src/mcpl/index.d.ts.map +1 -1
- package/dist/src/mcpl/index.js +3 -2
- package/dist/src/mcpl/index.js.map +1 -1
- package/dist/src/mcpl/log-value.d.ts +6 -0
- package/dist/src/mcpl/log-value.d.ts.map +1 -1
- package/dist/src/mcpl/log-value.js +8 -0
- package/dist/src/mcpl/log-value.js.map +1 -1
- package/dist/src/mcpl/modern-connection.d.ts +15 -6
- package/dist/src/mcpl/modern-connection.d.ts.map +1 -1
- package/dist/src/mcpl/modern-connection.js +168 -53
- package/dist/src/mcpl/modern-connection.js.map +1 -1
- package/dist/src/mcpl/prose-grammar.d.ts +4 -5
- package/dist/src/mcpl/prose-grammar.d.ts.map +1 -1
- package/dist/src/mcpl/prose-grammar.js +4 -5
- package/dist/src/mcpl/prose-grammar.js.map +1 -1
- package/dist/src/mcpl/protocol-family.d.ts +97 -10
- package/dist/src/mcpl/protocol-family.d.ts.map +1 -1
- package/dist/src/mcpl/protocol-family.js +173 -16
- package/dist/src/mcpl/protocol-family.js.map +1 -1
- package/dist/src/mcpl/push-coalescer.d.ts +132 -14
- package/dist/src/mcpl/push-coalescer.d.ts.map +1 -1
- package/dist/src/mcpl/push-coalescer.js +227 -50
- package/dist/src/mcpl/push-coalescer.js.map +1 -1
- package/dist/src/mcpl/push-handler.d.ts +6 -1
- package/dist/src/mcpl/push-handler.d.ts.map +1 -1
- package/dist/src/mcpl/push-handler.js +4 -1
- package/dist/src/mcpl/push-handler.js.map +1 -1
- package/dist/src/mcpl/reference-fetcher.d.ts +2 -2
- package/dist/src/mcpl/reference-fetcher.d.ts.map +1 -1
- package/dist/src/mcpl/reference-fetcher.js +4 -4
- package/dist/src/mcpl/reference-fetcher.js.map +1 -1
- package/dist/src/mcpl/server-connection.d.ts +50 -21
- package/dist/src/mcpl/server-connection.d.ts.map +1 -1
- package/dist/src/mcpl/server-connection.js +158 -74
- package/dist/src/mcpl/server-connection.js.map +1 -1
- package/dist/src/mcpl/tags.d.ts +24 -0
- package/dist/src/mcpl/tags.d.ts.map +1 -1
- package/dist/src/mcpl/tags.js +33 -0
- package/dist/src/mcpl/tags.js.map +1 -1
- package/dist/src/mcpl/tool-result-normalize.d.ts +2 -1
- package/dist/src/mcpl/tool-result-normalize.d.ts.map +1 -1
- package/dist/src/mcpl/tool-result-normalize.js.map +1 -1
- package/dist/src/mcpl/transport.d.ts +55 -7
- package/dist/src/mcpl/transport.d.ts.map +1 -1
- package/dist/src/mcpl/transport.js +163 -34
- package/dist/src/mcpl/transport.js.map +1 -1
- package/dist/src/mcpl/types.d.ts +22 -6
- package/dist/src/mcpl/types.d.ts.map +1 -1
- package/dist/src/mcpl/types.js.map +1 -1
- package/dist/src/module-registry.d.ts +4 -2
- package/dist/src/module-registry.d.ts.map +1 -1
- package/dist/src/module-registry.js +100 -13
- package/dist/src/module-registry.js.map +1 -1
- package/dist/src/modules/discord/index.d.ts.map +1 -1
- package/dist/src/modules/discord/index.js +8 -13
- package/dist/src/modules/discord/index.js.map +1 -1
- package/dist/src/modules/history/index.d.ts.map +1 -1
- package/dist/src/modules/history/index.js +27 -4
- package/dist/src/modules/history/index.js.map +1 -1
- package/dist/src/modules/history/semantic.d.ts +15 -3
- package/dist/src/modules/history/semantic.d.ts.map +1 -1
- package/dist/src/modules/history/semantic.js +27 -5
- package/dist/src/modules/history/semantic.js.map +1 -1
- package/dist/src/modules/index.d.ts +1 -1
- package/dist/src/modules/index.d.ts.map +1 -1
- package/dist/src/modules/index.js.map +1 -1
- package/dist/src/modules/unknown-tool.d.ts +4 -1
- package/dist/src/modules/unknown-tool.d.ts.map +1 -1
- package/dist/src/modules/unknown-tool.js +4 -1
- package/dist/src/modules/unknown-tool.js.map +1 -1
- package/dist/src/modules/workspace/branch-intent.d.ts +3 -1
- package/dist/src/modules/workspace/branch-intent.d.ts.map +1 -1
- package/dist/src/modules/workspace/branch-intent.js +3 -1
- package/dist/src/modules/workspace/branch-intent.js.map +1 -1
- package/dist/src/modules/workspace/edit-plan.d.ts +265 -0
- package/dist/src/modules/workspace/edit-plan.d.ts.map +1 -0
- package/dist/src/modules/workspace/edit-plan.js +794 -0
- package/dist/src/modules/workspace/edit-plan.js.map +1 -0
- package/dist/src/modules/workspace/edit-text.d.ts +117 -0
- package/dist/src/modules/workspace/edit-text.d.ts.map +1 -0
- package/dist/src/modules/workspace/edit-text.js +584 -0
- package/dist/src/modules/workspace/edit-text.js.map +1 -0
- package/dist/src/modules/workspace/effects.d.ts +5 -4
- package/dist/src/modules/workspace/effects.d.ts.map +1 -1
- package/dist/src/modules/workspace/effects.js +78 -25
- package/dist/src/modules/workspace/effects.js.map +1 -1
- package/dist/src/modules/workspace/index.d.ts +484 -61
- package/dist/src/modules/workspace/index.d.ts.map +1 -1
- package/dist/src/modules/workspace/index.js +2173 -645
- package/dist/src/modules/workspace/index.js.map +1 -1
- package/dist/src/modules/workspace/observe.d.ts +213 -38
- package/dist/src/modules/workspace/observe.d.ts.map +1 -1
- package/dist/src/modules/workspace/observe.js +416 -36
- package/dist/src/modules/workspace/observe.js.map +1 -1
- package/dist/src/modules/workspace/reconcile.d.ts.map +1 -1
- package/dist/src/modules/workspace/reconcile.js +15 -8
- package/dist/src/modules/workspace/reconcile.js.map +1 -1
- package/dist/src/modules/workspace/text.d.ts +32 -0
- package/dist/src/modules/workspace/text.d.ts.map +1 -0
- package/dist/src/modules/workspace/text.js +67 -0
- package/dist/src/modules/workspace/text.js.map +1 -0
- package/dist/src/modules/workspace/types.d.ts +210 -6
- package/dist/src/modules/workspace/types.d.ts.map +1 -1
- package/dist/src/modules/workspace/types.js.map +1 -1
- package/dist/src/modules/workspace/watcher.d.ts +3 -2
- package/dist/src/modules/workspace/watcher.d.ts.map +1 -1
- package/dist/src/modules/workspace/watcher.js.map +1 -1
- package/dist/src/operator-log.d.ts +52 -24
- package/dist/src/operator-log.d.ts.map +1 -1
- package/dist/src/operator-log.js.map +1 -1
- package/dist/src/recovery/discord-awareness-outbox.d.ts +496 -72
- package/dist/src/recovery/discord-awareness-outbox.d.ts.map +1 -1
- package/dist/src/recovery/discord-awareness-outbox.js +1196 -289
- package/dist/src/recovery/discord-awareness-outbox.js.map +1 -1
- package/dist/src/recovery/offline-branch.d.ts +26 -1
- package/dist/src/recovery/offline-branch.d.ts.map +1 -1
- package/dist/src/recovery/offline-branch.js +164 -39
- package/dist/src/recovery/offline-branch.js.map +1 -1
- package/dist/src/recovery/recover-cli.js +23 -4
- package/dist/src/recovery/recover-cli.js.map +1 -1
- package/dist/src/send-tools.d.ts +11 -0
- package/dist/src/send-tools.d.ts.map +1 -0
- package/dist/src/send-tools.js +11 -0
- package/dist/src/send-tools.js.map +1 -0
- package/dist/src/tool-result-guard.d.ts +4 -3
- package/dist/src/tool-result-guard.d.ts.map +1 -1
- package/dist/src/tool-result-guard.js +5 -4
- package/dist/src/tool-result-guard.js.map +1 -1
- package/dist/src/tool-result-history.d.ts +1 -1
- package/dist/src/tool-result-history.js +1 -1
- package/dist/src/tune-out/coordinator.d.ts +21 -0
- package/dist/src/tune-out/coordinator.d.ts.map +1 -1
- package/dist/src/tune-out/coordinator.js +139 -37
- package/dist/src/tune-out/coordinator.js.map +1 -1
- package/dist/src/types/agent.d.ts +4 -0
- package/dist/src/types/agent.d.ts.map +1 -1
- package/dist/src/types/events.d.ts +62 -9
- package/dist/src/types/events.d.ts.map +1 -1
- package/dist/src/types/framework.d.ts +62 -58
- package/dist/src/types/framework.d.ts.map +1 -1
- package/dist/src/types/module.d.ts +40 -8
- package/dist/src/types/module.d.ts.map +1 -1
- package/dist/src/types/trace.d.ts +111 -10
- package/dist/src/types/trace.d.ts.map +1 -1
- package/dist/src/usage/types.d.ts +16 -0
- package/dist/src/usage/types.d.ts.map +1 -1
- package/dist/src/usage/usage-tracker.d.ts +14 -1
- package/dist/src/usage/usage-tracker.d.ts.map +1 -1
- package/dist/src/usage/usage-tracker.js +81 -41
- package/dist/src/usage/usage-tracker.js.map +1 -1
- package/package.json +6 -5
- package/src/agent.ts +93 -12
- package/src/api/server.ts +14 -12
- package/src/code-execution/engine.ts +595 -0
- package/src/code-execution/index.ts +5 -17
- package/src/code-execution/isolate/calls.ts +199 -0
- package/src/code-execution/isolate/child-entry.ts +5 -0
- package/src/code-execution/isolate/child-main.ts +132 -0
- package/src/code-execution/isolate/child.ts +327 -0
- package/src/code-execution/isolate/frames.ts +209 -0
- package/src/code-execution/isolate/output.ts +161 -0
- package/src/code-execution/isolate/prelude.ts +409 -0
- package/src/code-execution/isolate/protocol.ts +240 -0
- package/src/code-execution/isolate/render.ts +230 -0
- package/src/code-execution/isolate/runner.ts +911 -0
- package/src/code-execution/isolate/scripts.ts +479 -0
- package/src/code-execution/quickjs.wasm +0 -0
- package/src/code-execution/quickjs.wasm.LICENSES +149 -0
- package/src/code-execution/tool-definition.ts +236 -167
- package/src/deadline-timer.ts +1 -1
- package/src/framework.ts +4507 -2406
- package/src/gate/event-gate.ts +78 -11
- package/src/held-writes.ts +17 -3
- package/src/index.ts +30 -22
- package/src/mcpl/channel-registry.ts +1825 -368
- package/src/mcpl/conversation-router.ts +12 -7
- package/src/mcpl/convert-block.ts +9 -5
- package/src/mcpl/inbound-source.ts +131 -0
- package/src/mcpl/index.ts +4 -2
- package/src/mcpl/log-value.ts +9 -0
- package/src/mcpl/modern-connection.ts +162 -53
- package/src/mcpl/prose-grammar.ts +4 -5
- package/src/mcpl/protocol-family.ts +199 -21
- package/src/mcpl/push-coalescer.ts +306 -62
- package/src/mcpl/push-handler.ts +10 -2
- package/src/mcpl/reference-fetcher.ts +4 -4
- package/src/mcpl/server-connection.ts +180 -79
- package/src/mcpl/tags.ts +36 -0
- package/src/mcpl/tool-result-normalize.ts +2 -1
- package/src/mcpl/transport.ts +162 -33
- package/src/mcpl/types.ts +23 -6
- package/src/module-registry.ts +92 -13
- package/src/modules/discord/index.ts +8 -13
- package/src/modules/history/index.ts +25 -3
- package/src/modules/history/semantic.ts +29 -6
- package/src/modules/index.ts +1 -0
- package/src/modules/unknown-tool.ts +4 -1
- package/src/modules/workspace/branch-intent.ts +3 -1
- package/src/modules/workspace/edit-plan.ts +954 -0
- package/src/modules/workspace/edit-text.ts +618 -0
- package/src/modules/workspace/effects.ts +70 -19
- package/src/modules/workspace/index.ts +2247 -642
- package/src/modules/workspace/observe.ts +465 -56
- package/src/modules/workspace/reconcile.ts +14 -7
- package/src/modules/workspace/text.ts +68 -0
- package/src/modules/workspace/types.ts +211 -6
- package/src/modules/workspace/watcher.ts +3 -2
- package/src/operator-log.ts +47 -19
- package/src/recovery/discord-awareness-outbox.ts +1500 -356
- package/src/recovery/offline-branch.ts +189 -55
- package/src/recovery/recover-cli.ts +25 -4
- package/src/send-tools.ts +11 -0
- package/src/tool-result-guard.ts +6 -5
- package/src/tool-result-history.ts +1 -1
- package/src/tune-out/coordinator.ts +163 -42
- package/src/types/agent.ts +4 -0
- package/src/types/events.ts +62 -9
- package/src/types/framework.ts +62 -58
- package/src/types/module.ts +40 -8
- package/src/types/trace.ts +121 -15
- package/src/usage/types.ts +16 -0
- package/src/usage/usage-tracker.ts +86 -43
- package/dist/src/code-execution/py-runner.d.ts +0 -191
- package/dist/src/code-execution/py-runner.d.ts.map +0 -1
- package/dist/src/code-execution/py-runner.js +0 -655
- package/dist/src/code-execution/py-runner.js.map +0 -1
- package/dist/src/code-execution/runtime-py.d.ts +0 -50
- package/dist/src/code-execution/runtime-py.d.ts.map +0 -1
- package/dist/src/code-execution/runtime-py.js +0 -677
- package/dist/src/code-execution/runtime-py.js.map +0 -1
- package/dist/src/mcpl/prose-stream-router.d.ts +0 -88
- package/dist/src/mcpl/prose-stream-router.d.ts.map +0 -1
- package/dist/src/mcpl/prose-stream-router.js +0 -291
- package/dist/src/mcpl/prose-stream-router.js.map +0 -1
- package/src/code-execution/py-runner.ts +0 -791
- package/src/code-execution/runtime-py.ts +0 -677
- package/src/mcpl/prose-stream-router.ts +0 -268
|
@@ -13,23 +13,35 @@ import { openTransport, STDERR_END_WAIT_MS } from './transport.js';
|
|
|
13
13
|
import { maskNegotiatedCapabilities } from './capability-mask.js';
|
|
14
14
|
import { CapabilityGrant, expandAdvertisementShorthand } from './capability-grant.js';
|
|
15
15
|
import { CAPABILITY_DISABLED, boundedForLog, describeCause } from './errors.js';
|
|
16
|
-
import { logDetail, logValue, logValueRedacted } from './log-value.js';
|
|
17
|
-
import { LEGACY_MCP_PROTOCOL_VERSION, MODERN_MCP_PROTOCOL_VERSION, checkServerConfig, redactServerText, } from './protocol-family.js';
|
|
16
|
+
import { logDetail, logValue, logValueRedacted, loggedCode } from './log-value.js';
|
|
17
|
+
import { LEGACY_MCP_PROTOCOL_VERSION, MODERN_MCP_PROTOCOL_VERSION, checkServerConfig, redactServerText, redactedData, serverTextRedactor, } from './protocol-family.js';
|
|
18
18
|
import { McplMethod } from './types.js';
|
|
19
19
|
/** Timeout for the initialize handshake in milliseconds.
|
|
20
20
|
* Spring Boot + JDA servers can take 5-10s to boot, so 30s is safe. */
|
|
21
21
|
const INITIALIZE_TIMEOUT_MS = 30_000;
|
|
22
|
+
/** How many errors down a `cause` chain stderrTailOf looks. */
|
|
23
|
+
const STDERR_TAIL_CAUSE_LINKS = 8;
|
|
22
24
|
/** A failed connect's `stderrTail`, the last of the server's stderr that its
|
|
23
|
-
* handshake's error keeps, when there is one
|
|
25
|
+
* handshake's error keeps, when there is one: the error's own, or the
|
|
26
|
+
* nearest one in its `cause` chain, since a launch that couldn't be reaped
|
|
27
|
+
* (McplUnreapedLaunchError) and the framework's refusals wrap the
|
|
28
|
+
* handshake's error. It looks at most STDERR_TAIL_CAUSE_LINKS causes down,
|
|
29
|
+
* so a chain that loops ends. */
|
|
24
30
|
export function stderrTailOf(error) {
|
|
25
|
-
|
|
26
|
-
|
|
31
|
+
let at = error;
|
|
32
|
+
for (let link = 0; link <= STDERR_TAIL_CAUSE_LINKS && typeof at === 'object' && at !== null; link++) {
|
|
33
|
+
const { stderrTail, cause } = at;
|
|
34
|
+
if (typeof stderrTail === 'string' && stderrTail !== '')
|
|
35
|
+
return stderrTail;
|
|
36
|
+
at = cause;
|
|
37
|
+
}
|
|
38
|
+
return undefined;
|
|
27
39
|
}
|
|
28
40
|
/** For the host's own log line about a failed connect: the server's stderr
|
|
29
|
-
* that the error keeps as `stderrTail
|
|
30
|
-
* taken out by `redact` (its
|
|
31
|
-
*
|
|
32
|
-
* none. */
|
|
41
|
+
* that the error, or the nearest error it wraps, keeps as `stderrTail`
|
|
42
|
+
* (stderrTailOf), with the server's credentials taken out by `redact` (its
|
|
43
|
+
* redactServerText), one marked line per line of it, each through
|
|
44
|
+
* log-value, since it's the server's text. '' when there's none. */
|
|
33
45
|
export function withStderr(error, redact) {
|
|
34
46
|
const tail = stderrTailOf(error);
|
|
35
47
|
if (tail === undefined)
|
|
@@ -90,11 +102,13 @@ export class McplProtocolVersionError extends Error {
|
|
|
90
102
|
data;
|
|
91
103
|
offered;
|
|
92
104
|
constructor(message, kind,
|
|
93
|
-
/** Revision the server answered with (`mismatch`; null when it gave
|
|
105
|
+
/** Revision the server answered with (`mismatch`; null when it gave
|
|
106
|
+
* none), redacted as the server's words are. */
|
|
94
107
|
returned,
|
|
95
108
|
/** Revisions the server says it supports (`rejected`, when stated). */
|
|
96
109
|
supported,
|
|
97
|
-
/** The JSON-RPC error's code and data
|
|
110
|
+
/** The JSON-RPC error's code, and its data with each string in it
|
|
111
|
+
* redacted (`rejected`). */
|
|
98
112
|
code, data,
|
|
99
113
|
/** The revision this client offered: the legacy engine's, unless a
|
|
100
114
|
* modern connection's. */
|
|
@@ -109,8 +123,13 @@ export class McplProtocolVersionError extends Error {
|
|
|
109
123
|
this.name = 'McplProtocolVersionError';
|
|
110
124
|
}
|
|
111
125
|
}
|
|
112
|
-
function protocolVersionRejection(
|
|
113
|
-
const
|
|
126
|
+
function protocolVersionRejection(config, error) {
|
|
127
|
+
const id = config.id;
|
|
128
|
+
// The server's words and data, redacted before they're bounded or kept:
|
|
129
|
+
// the error goes to the host. One build for all of them, so a
|
|
130
|
+
// configuration that can't be read is read once.
|
|
131
|
+
const redact = serverTextRedactor(config).now();
|
|
132
|
+
const data = redactedData(error.data, redact);
|
|
114
133
|
const supported = Array.isArray(data?.supported) && data.supported.every((v) => typeof v === 'string')
|
|
115
134
|
? data.supported
|
|
116
135
|
: null;
|
|
@@ -119,9 +138,10 @@ function protocolVersionRejection(id, error) {
|
|
|
119
138
|
: '';
|
|
120
139
|
return new McplProtocolVersionError(`MCPL server "${id}" does not support MCP ${MCP_PROTOCOL_VERSION}` +
|
|
121
140
|
// The server's message can be any JSON value, so it's read without
|
|
122
|
-
// throwing (describeCause) and bounded, as the
|
|
123
|
-
|
|
124
|
-
|
|
141
|
+
// throwing (describeCause), and redacted, then bounded, as the
|
|
142
|
+
// initialize error is.
|
|
143
|
+
(supported ? ` (it supports: ${boundedForLog(supported.join(', ')) || 'none listed'}).` : ` (${boundedForLog(redact(describeCause(error.message)))}).`) +
|
|
144
|
+
modernHint, 'rejected', null, supported, error.code, data);
|
|
125
145
|
}
|
|
126
146
|
const errorOf = (value) => (value instanceof Error ? value : new Error(String(value)));
|
|
127
147
|
/**
|
|
@@ -147,17 +167,18 @@ class HandshakeCleanupError extends Error {
|
|
|
147
167
|
* is confirmed, so the caller can still clean up, and should start nothing
|
|
148
168
|
* else for this server until then. connect() and connectWithReconnect()
|
|
149
169
|
* throw this, and the modern engine's ModernMcpConnection.connect() too.
|
|
150
|
-
* `cause` is the connect's own failure.
|
|
170
|
+
* `cause` is the connect's own failure. `connection` isn't enumerable, so
|
|
171
|
+
* printing the error doesn't print the connection's configuration, its
|
|
172
|
+
* credentials included.
|
|
151
173
|
*/
|
|
152
174
|
export class McplUnreapedLaunchError extends Error {
|
|
153
|
-
connection;
|
|
154
175
|
cleanup;
|
|
155
176
|
constructor(connection, failure,
|
|
156
177
|
/** The cleanup's own failure: the child it couldn't confirm exited. */
|
|
157
178
|
cleanup) {
|
|
158
179
|
super(`${failure.message}; its cleanup also failed: ${cleanup.message}`, { cause: failure });
|
|
159
|
-
this.connection = connection;
|
|
160
180
|
this.cleanup = cleanup;
|
|
181
|
+
Object.defineProperty(this, 'connection', { value: connection, enumerable: false });
|
|
161
182
|
this.name = 'McplUnreapedLaunchError';
|
|
162
183
|
}
|
|
163
184
|
}
|
|
@@ -179,8 +200,9 @@ export class McplRequestError extends Error {
|
|
|
179
200
|
outcome;
|
|
180
201
|
data;
|
|
181
202
|
constructor(message, outcome,
|
|
182
|
-
/** The JSON-RPC error's `data`,
|
|
183
|
-
*
|
|
203
|
+
/** The JSON-RPC error's `data`, when the server supplied one (e.g. which
|
|
204
|
+
* parts of a multi-part send were posted), with each string in it
|
|
205
|
+
* redacted (redactedData): a host hands it on. */
|
|
184
206
|
data) {
|
|
185
207
|
super(message);
|
|
186
208
|
this.outcome = outcome;
|
|
@@ -405,8 +427,8 @@ export class McplServerConnection extends EventEmitter {
|
|
|
405
427
|
publishDeadlineMs = DEFAULT_REQUEST_TIMEOUT_MS;
|
|
406
428
|
// Event buffering: control-plane traffic can be released independently from
|
|
407
429
|
// inference-bearing data-plane traffic. This lets a server finish its own
|
|
408
|
-
// registration (and answer host tools/call requests) while
|
|
409
|
-
//
|
|
430
|
+
// registration (and answer host tools/call requests) while its data plane
|
|
431
|
+
// stays held, as through a quiesce.
|
|
410
432
|
controlPlaneReady = false;
|
|
411
433
|
dataPlaneReady = false;
|
|
412
434
|
bufferedEvents = [];
|
|
@@ -443,6 +465,15 @@ export class McplServerConnection extends EventEmitter {
|
|
|
443
465
|
refusedHeldRequests = 0;
|
|
444
466
|
// Reconnect state (adapted from Anarchid/agent-framework@mcpl-module-proto)
|
|
445
467
|
config = null;
|
|
468
|
+
/** The redactor of the server's text for `config`, made at its first error
|
|
469
|
+
* answer, by when `config` is set, and kept: a framework-launched child's
|
|
470
|
+
* `env` is a getter that reads the awareness ledger, so a redactor built
|
|
471
|
+
* per answer would read it per answer (#540's review, R1-2). An answer
|
|
472
|
+
* takes one build of it for its words, data and log line (`now()`), so
|
|
473
|
+
* it reads the ledger at most once. It builds again only after a build
|
|
474
|
+
* that failed, which withholds that answer's text, or once a dial notes
|
|
475
|
+
* something new (serverTextRedactor). */
|
|
476
|
+
redactor = null;
|
|
446
477
|
hostCapabilities = null;
|
|
447
478
|
reconnectEnabled = false;
|
|
448
479
|
reconnectIntervalMs = 5000;
|
|
@@ -528,8 +559,8 @@ export class McplServerConnection extends EventEmitter {
|
|
|
528
559
|
console.error(`[mcpl] ${this.id}: flushing ${pending.length} buffered event(s) synchronously ` +
|
|
529
560
|
`(long pause backlog${dropped > 0 ? `; ${dropped} dropped at cap` : ''})`);
|
|
530
561
|
}
|
|
531
|
-
// Re-enter the gate for every buffered item. A control handler (
|
|
532
|
-
//
|
|
562
|
+
// Re-enter the gate for every buffered item. A control handler (a
|
|
563
|
+
// host/command quiesce, say) may pause the data plane while this
|
|
533
564
|
// snapshot is being flushed; later data items must observe that pause.
|
|
534
565
|
this.flushHeld(pending);
|
|
535
566
|
}
|
|
@@ -695,17 +726,16 @@ export class McplServerConnection extends EventEmitter {
|
|
|
695
726
|
}
|
|
696
727
|
/**
|
|
697
728
|
* Close the data plane synchronously while leaving an already-released
|
|
698
|
-
* control plane live. Used
|
|
699
|
-
*
|
|
700
|
-
* planes instead.
|
|
729
|
+
* control plane live. Used by quiesce, and by reconnectAfterFailure before
|
|
730
|
+
* its teardown. A reconnect closes both planes instead.
|
|
701
731
|
*/
|
|
702
732
|
pauseDataPlane() {
|
|
703
733
|
this.dataPlaneReady = false;
|
|
704
734
|
}
|
|
705
735
|
/**
|
|
706
736
|
* Override emit to buffer server→host events until the corresponding plane
|
|
707
|
-
* is ready. Lifecycle events always pass through so reconnect
|
|
708
|
-
*
|
|
737
|
+
* is ready. Lifecycle events always pass through so the reconnect listener
|
|
738
|
+
* runs before the fresh transport's buffered traffic is released.
|
|
709
739
|
*/
|
|
710
740
|
emit(event, ...args) {
|
|
711
741
|
const name = typeof event === 'string' ? event : '';
|
|
@@ -999,18 +1029,21 @@ export class McplServerConnection extends EventEmitter {
|
|
|
999
1029
|
clientInfo: { name: 'agent-framework', version: '1.0.0' },
|
|
1000
1030
|
},
|
|
1001
1031
|
};
|
|
1032
|
+
// When the transport fails, the end of the server's stderr often says
|
|
1033
|
+
// why, such as a missing token or a crash at startup. It goes on the
|
|
1034
|
+
// error as `stderrTail`, never into the message: an error's message
|
|
1035
|
+
// travels to traces and tool results, and a server's stderr is its own
|
|
1036
|
+
// text, which can hold a credential.
|
|
1037
|
+
const failed = (failure) => {
|
|
1038
|
+
// It goes to the host too, so it's redacted, from a window of the
|
|
1039
|
+
// stream longer than the tail, so a credential the tail's cut
|
|
1040
|
+
// would split is whole when it's matched (stderrTailRedacted).
|
|
1041
|
+
const tail = transport.stderrTailRedacted(serverTextRedactor(config)).trimEnd();
|
|
1042
|
+
return Object.assign(new Error(failure), tail ? { stderrTail: tail } : {});
|
|
1043
|
+
};
|
|
1002
1044
|
// Await the initialize response, racing an early transport close/error,
|
|
1003
1045
|
// a timeout and the owner's close. Every path cleans up its listeners.
|
|
1004
1046
|
const { mcpl: rawCapabilities, mcpToolsAdvertised, protocolVersion } = await new Promise((resolve, reject) => {
|
|
1005
|
-
// When the transport fails, the end of the server's stderr often says
|
|
1006
|
-
// why, such as a missing token or a crash at startup. It goes on the
|
|
1007
|
-
// error as `stderrTail`, never into the message: an error's message
|
|
1008
|
-
// travels to traces and tool results, and a server's stderr is its
|
|
1009
|
-
// own text, which can hold a credential.
|
|
1010
|
-
const failed = (failure) => {
|
|
1011
|
-
const tail = transport.stderrTail.trimEnd();
|
|
1012
|
-
return Object.assign(new Error(failure), tail ? { stderrTail: tail } : {});
|
|
1013
|
-
};
|
|
1014
1047
|
const cleanup = () => {
|
|
1015
1048
|
transport.off('line', onLine);
|
|
1016
1049
|
transport.off('close', onClose);
|
|
@@ -1055,20 +1088,24 @@ export class McplServerConnection extends EventEmitter {
|
|
|
1055
1088
|
// listener after cleanup() has cleared the timeout: an uncaught
|
|
1056
1089
|
// exception, which ends a host that doesn't catch them, and a
|
|
1057
1090
|
// handshake left to wait forever. It's the server's text in an
|
|
1058
|
-
// error
|
|
1091
|
+
// error the host gets, so it's redacted, then bounded as
|
|
1092
|
+
// errors.ts says: a cut or a replaced character first would
|
|
1093
|
+
// leave part of a credential the redactor can't match.
|
|
1059
1094
|
reject(msg.error.code === UNSUPPORTED_PROTOCOL_VERSION_CODE
|
|
1060
|
-
? protocolVersionRejection(config
|
|
1061
|
-
: new Error(`MCPL server "${config.id}" initialize error: ${boundedForLog(describeCause(msg.error.message))}`));
|
|
1095
|
+
? protocolVersionRejection(config, msg.error)
|
|
1096
|
+
: new Error(`MCPL server "${config.id}" initialize error: ${boundedForLog(redactServerText(describeCause(msg.error.message), config))}`));
|
|
1062
1097
|
return;
|
|
1063
1098
|
}
|
|
1064
1099
|
const result = msg.result;
|
|
1065
1100
|
// The server's answer is the established revision. This engine
|
|
1066
1101
|
// implements exactly one, so any other answer (or none) means the
|
|
1067
1102
|
// two sides never agreed on what they're speaking.
|
|
1068
|
-
const
|
|
1069
|
-
if (
|
|
1103
|
+
const answered = typeof result?.protocolVersion === 'string' ? result.protocolVersion : null;
|
|
1104
|
+
if (answered !== MCP_PROTOCOL_VERSION) {
|
|
1105
|
+
// The server's words go to the host, so they're redacted.
|
|
1106
|
+
const returned = answered === null ? null : redactServerText(answered, config);
|
|
1070
1107
|
reject(new McplProtocolVersionError(`MCPL server "${config.id}" answered initialize with protocolVersion ` +
|
|
1071
|
-
`${returned === null ? '(none)' : JSON.stringify(returned)}; this client's legacy engine speaks only ${MCP_PROTOCOL_VERSION}`, 'mismatch', returned, null));
|
|
1108
|
+
`${returned === null ? '(none)' : boundedForLog(JSON.stringify(returned))}; this client's legacy engine speaks only ${MCP_PROTOCOL_VERSION}`, 'mismatch', returned, null));
|
|
1072
1109
|
return;
|
|
1073
1110
|
}
|
|
1074
1111
|
const caps = result?.capabilities;
|
|
@@ -1079,7 +1116,7 @@ export class McplServerConnection extends EventEmitter {
|
|
|
1079
1116
|
resolve({
|
|
1080
1117
|
mcpl: experimental?.mcpl ?? null,
|
|
1081
1118
|
mcpToolsAdvertised: caps?.tools !== undefined,
|
|
1082
|
-
protocolVersion:
|
|
1119
|
+
protocolVersion: answered,
|
|
1083
1120
|
});
|
|
1084
1121
|
};
|
|
1085
1122
|
const onClose = (info) => {
|
|
@@ -1107,6 +1144,22 @@ export class McplServerConnection extends EventEmitter {
|
|
|
1107
1144
|
transport.on('error', onError);
|
|
1108
1145
|
transport.writeLine(JSON.stringify(initRequest));
|
|
1109
1146
|
});
|
|
1147
|
+
// The transport has found the child's stdin or stdout failed before the
|
|
1148
|
+
// handshake could hand it on, such as when this host's answer to a ping
|
|
1149
|
+
// the server sent met EPIPE. Nothing more is written to the child then,
|
|
1150
|
+
// so the connection couldn't serve. It's read here, once the answer has
|
|
1151
|
+
// passed its own checks, rather than as the answer arrives: a write's
|
|
1152
|
+
// EPIPE is reported only once the callback that wrote it has returned,
|
|
1153
|
+
// so a ping and the answer read in one callback would pass a check made
|
|
1154
|
+
// there. A child that outlived SIGKILL may already have said so with
|
|
1155
|
+
// nothing listening (the transport's 'unreaped' is wired only once the
|
|
1156
|
+
// handshake hands it on). So the handshake fails, and its cleanup holds
|
|
1157
|
+
// the launch if it can't reap the child. A failure of the write below
|
|
1158
|
+
// is reported only once the caller has wired the transport, so it
|
|
1159
|
+
// reaches the connection as a loss, like any later one.
|
|
1160
|
+
const pipeFailure = transport.pipeFailure;
|
|
1161
|
+
if (pipeFailure)
|
|
1162
|
+
throw failed(`MCPL server "${config.id}" stdio pipe failed with ${pipeFailure.message} during the handshake`);
|
|
1110
1163
|
// Send `initialized` notification (no id)
|
|
1111
1164
|
transport.writeLine(JSON.stringify({ jsonrpc: '2.0', method: 'notifications/initialized' }));
|
|
1112
1165
|
// §5.1 boolean shorthand expands to explicit leaves BEFORE the config
|
|
@@ -1282,9 +1335,13 @@ export class McplServerConnection extends EventEmitter {
|
|
|
1282
1335
|
const timeoutMs = this.requestTimeoutMs > 0 ? this.requestTimeoutMs : this.publishDeadlineMs;
|
|
1283
1336
|
return this.sendRequest(McplMethod.ChannelsOpen, params, { timeoutMs });
|
|
1284
1337
|
}
|
|
1285
|
-
/** Send `channels/close` request and await result.
|
|
1338
|
+
/** Send `channels/close` request and await result. It keeps a deadline as
|
|
1339
|
+
* channels/open does: a delivery waits for a channel's queued lifecycle
|
|
1340
|
+
* work, closes included, so a close that is never answered would hold the
|
|
1341
|
+
* delivery, and the turn that waits for it, for good. */
|
|
1286
1342
|
sendChannelsClose(params) {
|
|
1287
|
-
|
|
1343
|
+
const timeoutMs = this.requestTimeoutMs > 0 ? this.requestTimeoutMs : this.publishDeadlineMs;
|
|
1344
|
+
return this.sendRequest(McplMethod.ChannelsClose, params, { timeoutMs });
|
|
1288
1345
|
}
|
|
1289
1346
|
/** Send `channels/acknowledge` request and await result. */
|
|
1290
1347
|
sendChannelsAcknowledge(params) {
|
|
@@ -1367,10 +1424,11 @@ export class McplServerConnection extends EventEmitter {
|
|
|
1367
1424
|
return { ...rest, tools };
|
|
1368
1425
|
}
|
|
1369
1426
|
if (typeof result.nextCursor !== 'string') {
|
|
1370
|
-
|
|
1427
|
+
// The cursor is the server's, so it's redacted, then bounded.
|
|
1428
|
+
throw malformed(`nextCursor must be a string, got ${boundedForLog(redactServerText(JSON.stringify(result.nextCursor), this.config ?? {}))}`);
|
|
1371
1429
|
}
|
|
1372
1430
|
if (seen.has(result.nextCursor)) {
|
|
1373
|
-
throw new Error(`MCPL server "${this.id}" repeated tools/list cursor ${JSON.stringify(result.nextCursor)}`);
|
|
1431
|
+
throw new Error(`MCPL server "${this.id}" repeated tools/list cursor ${boundedForLog(redactServerText(JSON.stringify(result.nextCursor), this.config ?? {}))}`);
|
|
1374
1432
|
}
|
|
1375
1433
|
seen.add(result.nextCursor);
|
|
1376
1434
|
cursor = result.nextCursor;
|
|
@@ -1662,9 +1720,8 @@ export class McplServerConnection extends EventEmitter {
|
|
|
1662
1720
|
// boundary resets, so control traffic too (a server's channels/register
|
|
1663
1721
|
// right after initialize) must wait for the new grant rather than be
|
|
1664
1722
|
// refused against the empty one. The reconnect lifecycle event bypasses
|
|
1665
|
-
// buffering; its framework listener
|
|
1666
|
-
//
|
|
1667
|
-
// and then opens the planes.
|
|
1723
|
+
// buffering; its framework listener re-establishes the grant (§5.3
|
|
1724
|
+
// policy responses are never buffered), and then opens the planes.
|
|
1668
1725
|
this.controlPlaneReady = false;
|
|
1669
1726
|
this.dataPlaneReady = false;
|
|
1670
1727
|
this.resetPolicyForTransportBoundary();
|
|
@@ -1685,6 +1742,17 @@ export class McplServerConnection extends EventEmitter {
|
|
|
1685
1742
|
// ==========================================================================
|
|
1686
1743
|
// Private: message sending
|
|
1687
1744
|
// ==========================================================================
|
|
1745
|
+
/**
|
|
1746
|
+
* A request refused before anything is kept for it, as `error`, with its
|
|
1747
|
+
* operator's line logged after the refusal: a host logger that throws then
|
|
1748
|
+
* loses that line, and can't turn the refusal into a throw from the call.
|
|
1749
|
+
*/
|
|
1750
|
+
static refused(error, line) {
|
|
1751
|
+
return new Promise((_, reject) => {
|
|
1752
|
+
reject(error);
|
|
1753
|
+
console.error(line);
|
|
1754
|
+
});
|
|
1755
|
+
}
|
|
1688
1756
|
/**
|
|
1689
1757
|
* Send a JSON-RPC request and return a promise that resolves with the result
|
|
1690
1758
|
* or rejects with a JSON-RPC error.
|
|
@@ -1716,11 +1784,10 @@ export class McplServerConnection extends EventEmitter {
|
|
|
1716
1784
|
// pipe's error are the operator's, so they go to the log.
|
|
1717
1785
|
const pipeFailure = this.transport?.pipeFailure;
|
|
1718
1786
|
if (pipeFailure) {
|
|
1719
|
-
|
|
1720
|
-
return Promise.reject(new McplRequestError(`The request wasn't sent: this host can no longer write to the "${this.id}" server, so nothing ran. ` +
|
|
1787
|
+
return McplServerConnection.refused(new McplRequestError(`The request wasn't sent: this host can no longer write to the "${this.id}" server, so nothing ran. ` +
|
|
1721
1788
|
(this.willReconnect
|
|
1722
1789
|
? 'This host is reconnecting to it; try again later.'
|
|
1723
|
-
: "This host won't reconnect to it on its own. If you need it, ask whoever runs this host."), 'not-sent'));
|
|
1790
|
+
: "This host won't reconnect to it on its own. If you need it, ask whoever runs this host."), 'not-sent'), `MCPL server "${this.id}": ${method} not sent, since its stdio pipe failed: ${logDetail(pipeFailure.message)}`);
|
|
1724
1791
|
}
|
|
1725
1792
|
const id = this.nextRequestId++;
|
|
1726
1793
|
const request = {
|
|
@@ -1729,6 +1796,18 @@ export class McplServerConnection extends EventEmitter {
|
|
|
1729
1796
|
id,
|
|
1730
1797
|
params,
|
|
1731
1798
|
};
|
|
1799
|
+
// A request JSON can't write (a BigInt, a cycle) never leaves this host,
|
|
1800
|
+
// and calling again fails the same way, so it's refused before anything
|
|
1801
|
+
// is kept for it, in the modern engine's words (#556). The method, id and
|
|
1802
|
+
// the serializer's words are the operator's.
|
|
1803
|
+
let line;
|
|
1804
|
+
try {
|
|
1805
|
+
line = JSON.stringify(request);
|
|
1806
|
+
}
|
|
1807
|
+
catch (err) {
|
|
1808
|
+
return McplServerConnection.refused(new McplRequestError(`The request wasn't sent: this host couldn't send it to the "${this.id}" server, so nothing ran. ` +
|
|
1809
|
+
'If calling it again fails, ask whoever runs this host.', 'not-sent'), `MCPL server "${this.id}": ${method} (id=${id}) not sent, since it can't be written as JSON: ${logDetail(err instanceof Error ? err.message : err)}`);
|
|
1810
|
+
}
|
|
1732
1811
|
return new Promise((resolve, reject) => {
|
|
1733
1812
|
const pending = { resolve, reject, method };
|
|
1734
1813
|
const timeoutMs = options.timeoutMs ?? this.requestTimeoutMs;
|
|
@@ -1766,17 +1845,18 @@ export class McplServerConnection extends EventEmitter {
|
|
|
1766
1845
|
}
|
|
1767
1846
|
this.pendingRequests.set(id, pending);
|
|
1768
1847
|
try {
|
|
1769
|
-
this.transport.writeLine(
|
|
1848
|
+
this.transport.writeLine(line);
|
|
1770
1849
|
}
|
|
1771
1850
|
catch (err) {
|
|
1772
1851
|
// A synchronous write rejection sent no request. Remove its pending
|
|
1773
1852
|
// state and watchdog before reporting that it is safe to retry. The
|
|
1774
|
-
// method, id and the transport's words are the operator's
|
|
1853
|
+
// method, id and the transport's words are the operator's, logged
|
|
1854
|
+
// after the refusal, as refused() logs.
|
|
1775
1855
|
this.pendingRequests.delete(id);
|
|
1776
1856
|
if (pending.timer)
|
|
1777
1857
|
clearTimeout(pending.timer);
|
|
1778
|
-
console.error(`MCPL server "${this.id}": writing ${method} (id=${id}) failed: ${logDetail(err instanceof Error ? err.message : err)}`);
|
|
1779
1858
|
reject(new McplRequestError(`The request wasn't sent: this host couldn't write it to the "${this.id}" server, so nothing ran. Try again later.`, 'not-sent'));
|
|
1859
|
+
console.error(`MCPL server "${this.id}": writing ${method} (id=${id}) failed: ${logDetail(err instanceof Error ? err.message : err)}`);
|
|
1780
1860
|
}
|
|
1781
1861
|
});
|
|
1782
1862
|
}
|
|
@@ -2117,16 +2197,18 @@ export class McplServerConnection extends EventEmitter {
|
|
|
2117
2197
|
if (pending.timer)
|
|
2118
2198
|
clearTimeout(pending.timer);
|
|
2119
2199
|
if (response.error) {
|
|
2120
|
-
// The server's own words, after a word on whose they are,
|
|
2121
|
-
// errors.ts says, since they're the server's text
|
|
2122
|
-
//
|
|
2123
|
-
//
|
|
2124
|
-
//
|
|
2125
|
-
//
|
|
2126
|
-
//
|
|
2127
|
-
//
|
|
2128
|
-
//
|
|
2129
|
-
|
|
2200
|
+
// The server's own words, after a word on whose they are, redacted and
|
|
2201
|
+
// then bounded as errors.ts says, since they're the server's text in
|
|
2202
|
+
// an error the caller gets (redactServerText's scope), and its data's
|
|
2203
|
+
// strings redacted too. It's trimmed after it's redacted, so a
|
|
2204
|
+
// credential that ends in a space is whole when it's matched. Only a
|
|
2205
|
+
// string is words: a message of any other JSON value reads as none.
|
|
2206
|
+
// The method and id are the operator's, so they go to the log, and the
|
|
2207
|
+
// code (loggedCode) and the message, whatever JSON values they are, go
|
|
2208
|
+
// there redacted (logValueRedacted), as every other line this
|
|
2209
|
+
// connection writes is.
|
|
2210
|
+
const redact = (this.redactor ??= serverTextRedactor(this.config ?? {})).now();
|
|
2211
|
+
const said = typeof response.error.message === 'string' ? boundedForLog(redact(response.error.message).trim()) : '';
|
|
2130
2212
|
// The call is settled before its log line: its entry is gone and its
|
|
2131
2213
|
// timer cleared, so nothing else would settle it, and a host's logger
|
|
2132
2214
|
// can throw. The dispatch's containment reports such a throw. (A
|
|
@@ -2135,9 +2217,9 @@ export class McplServerConnection extends EventEmitter {
|
|
|
2135
2217
|
pending.reject(new McplRequestError(said
|
|
2136
2218
|
? `The "${this.id}" server answered with an error: ${said}`
|
|
2137
2219
|
: `The "${this.id}" server answered with an error without saying what went wrong, so whether the request took effect is unknown. ` +
|
|
2138
|
-
'Check its effect before trying again.', 'error-response', response.error.data));
|
|
2139
|
-
console.error(`MCPL server "${this.id}" answered ${pending.method} (id=${response.id}) with error ${
|
|
2140
|
-
logValueRedacted(response.error.message,
|
|
2220
|
+
'Check its effect before trying again.', 'error-response', redactedData(response.error.data, redact)));
|
|
2221
|
+
console.error(`MCPL server "${this.id}" answered ${pending.method} (id=${response.id}) with error ${loggedCode(response.error.code, redact)}: ` +
|
|
2222
|
+
logValueRedacted(response.error.message, redact));
|
|
2141
2223
|
}
|
|
2142
2224
|
else {
|
|
2143
2225
|
pending.resolve(response.result);
|
|
@@ -2246,8 +2328,10 @@ export class McplServerConnection extends EventEmitter {
|
|
|
2246
2328
|
// reconnecting, and is lost as on a close, with the permanent failure
|
|
2247
2329
|
// that raises the alert and takes its tools off the list. Its id stays
|
|
2248
2330
|
// held until close() confirms the exit. A close the host has begun
|
|
2249
|
-
// reports the failure itself. During a handshake nothing listens yet:
|
|
2250
|
-
//
|
|
2331
|
+
// reports the failure itself. During a handshake nothing listens yet: a
|
|
2332
|
+
// handshake whose pipe has failed fails, when its answer comes (it's
|
|
2333
|
+
// refused then), when the child's exit closes the transport, or at its
|
|
2334
|
+
// timeout, and its own cleanup holds the launch.
|
|
2251
2335
|
transport.on('unreaped', (failure) => {
|
|
2252
2336
|
if (this.closed || this.transport !== transport)
|
|
2253
2337
|
return;
|