@stigmer/runner 3.11.0 → 3.12.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 +2 -0
- package/dist/.build-fingerprint +1 -1
- package/dist/activities/discover-mcp-server.d.ts +7 -0
- package/dist/activities/discover-mcp-server.js +6 -4
- package/dist/activities/discover-mcp-server.js.map +1 -1
- package/dist/activities/emit-event.d.ts +14 -2
- package/dist/activities/emit-event.js +52 -17
- package/dist/activities/emit-event.js.map +1 -1
- package/dist/activities/execute-cursor/attachment-resolver.d.ts +11 -0
- package/dist/activities/execute-cursor/attachment-resolver.js +8 -0
- package/dist/activities/execute-cursor/attachment-resolver.js.map +1 -1
- package/dist/activities/execute-cursor/blueprint-resolver.d.ts +1 -9
- package/dist/activities/execute-cursor/blueprint-resolver.js +0 -1
- package/dist/activities/execute-cursor/blueprint-resolver.js.map +1 -1
- package/dist/activities/execute-cursor/error-classifier.d.ts +19 -0
- package/dist/activities/execute-cursor/error-classifier.js +34 -3
- package/dist/activities/execute-cursor/error-classifier.js.map +1 -1
- package/dist/activities/execute-cursor/index.d.ts +52 -12
- package/dist/activities/execute-cursor/index.js +141 -67
- package/dist/activities/execute-cursor/index.js.map +1 -1
- package/dist/activities/execute-cursor/model-pricing-data.d.ts +2 -0
- package/dist/activities/execute-cursor/model-pricing-data.js +13 -3
- package/dist/activities/execute-cursor/model-pricing-data.js.map +1 -1
- package/dist/activities/execute-cursor/prompt-builder.d.ts +48 -11
- package/dist/activities/execute-cursor/prompt-builder.js +57 -10
- package/dist/activities/execute-cursor/prompt-builder.js.map +1 -1
- package/dist/activities/execute-cursor/turn-recovery.d.ts +52 -0
- package/dist/activities/execute-cursor/turn-recovery.js +193 -0
- package/dist/activities/execute-cursor/turn-recovery.js.map +1 -0
- package/dist/activities/execute-deep-agent/attachment-injector.d.ts +11 -0
- package/dist/activities/execute-deep-agent/attachment-injector.js +7 -1
- package/dist/activities/execute-deep-agent/attachment-injector.js.map +1 -1
- package/dist/activities/execute-deep-agent/index.js +0 -15
- package/dist/activities/execute-deep-agent/index.js.map +1 -1
- package/dist/activities/execute-deep-agent/mcp-gate.d.ts +0 -2
- package/dist/activities/execute-deep-agent/mcp-gate.js +0 -1
- package/dist/activities/execute-deep-agent/mcp-gate.js.map +1 -1
- package/dist/activities/execute-deep-agent/prompt-builder.d.ts +7 -8
- package/dist/activities/execute-deep-agent/prompt-builder.js +14 -7
- package/dist/activities/execute-deep-agent/prompt-builder.js.map +1 -1
- package/dist/activities/execute-deep-agent/setup.d.ts +0 -10
- package/dist/activities/execute-deep-agent/setup.js +22 -49
- package/dist/activities/execute-deep-agent/setup.js.map +1 -1
- package/dist/activities/execute-deep-agent/shell-env.d.ts +5 -1
- package/dist/activities/execute-deep-agent/shell-env.js +7 -9
- package/dist/activities/execute-deep-agent/shell-env.js.map +1 -1
- package/dist/activities/execute-deep-agent/subagent-transformer.js +7 -1
- package/dist/activities/execute-deep-agent/subagent-transformer.js.map +1 -1
- package/dist/activities/execute-deep-agent/subagent-wiring.d.ts +17 -3
- package/dist/activities/execute-deep-agent/subagent-wiring.js +14 -2
- package/dist/activities/execute-deep-agent/subagent-wiring.js.map +1 -1
- package/dist/activities/hydrate-workflow-execution.js +8 -5
- package/dist/activities/hydrate-workflow-execution.js.map +1 -1
- package/dist/activities/run-command.d.ts +5 -2
- package/dist/activities/run-command.js +22 -10
- package/dist/activities/run-command.js.map +1 -1
- package/dist/activities/run-env.d.ts +40 -0
- package/dist/activities/run-env.js +66 -0
- package/dist/activities/run-env.js.map +1 -0
- package/dist/bootstrap.js +5 -0
- package/dist/bootstrap.js.map +1 -1
- package/dist/client/stigmer-client.d.ts +83 -26
- package/dist/client/stigmer-client.js +88 -24
- package/dist/client/stigmer-client.js.map +1 -1
- package/dist/config.d.ts +6 -5
- package/dist/config.js.map +1 -1
- package/dist/encryption/config.d.ts +41 -9
- package/dist/encryption/config.js +63 -23
- package/dist/encryption/config.js.map +1 -1
- package/dist/middleware/index.d.ts +3 -0
- package/dist/middleware/index.js +7 -0
- package/dist/middleware/index.js.map +1 -1
- package/dist/middleware/path-normalization.d.ts +57 -0
- package/dist/middleware/path-normalization.js +109 -0
- package/dist/middleware/path-normalization.js.map +1 -0
- package/dist/middleware/types.d.ts +8 -0
- package/dist/payload-codecs.d.ts +2 -1
- package/dist/payload-codecs.js +7 -3
- package/dist/payload-codecs.js.map +1 -1
- package/dist/runner-manager.js +17 -3
- package/dist/runner-manager.js.map +1 -1
- package/dist/runner.js +7 -3
- package/dist/runner.js.map +1 -1
- package/dist/shared/artifact-storage.d.ts +34 -1
- package/dist/shared/artifact-storage.js +53 -10
- package/dist/shared/artifact-storage.js.map +1 -1
- package/dist/shared/attachment-download-urls.d.ts +62 -0
- package/dist/shared/attachment-download-urls.js +79 -0
- package/dist/shared/attachment-download-urls.js.map +1 -0
- package/dist/shared/channel-attachment.d.ts +1 -1
- package/dist/shared/channel-attachment.js +1 -1
- package/dist/shared/checkpointer/http-saver.d.ts +4 -20
- package/dist/shared/checkpointer/http-saver.js +15 -57
- package/dist/shared/checkpointer/http-saver.js.map +1 -1
- package/dist/shared/conversation-attachment.d.ts +2 -3
- package/dist/shared/conversation-attachment.js +2 -3
- package/dist/shared/conversation-attachment.js.map +1 -1
- package/dist/shared/conversation-catchup.d.ts +9 -2
- package/dist/shared/conversation-catchup.js +39 -6
- package/dist/shared/conversation-catchup.js.map +1 -1
- package/dist/shared/grpc-retry.d.ts +5 -1
- package/dist/shared/grpc-retry.js +5 -1
- package/dist/shared/grpc-retry.js.map +1 -1
- package/dist/shared/http-retry.d.ts +51 -9
- package/dist/shared/http-retry.js +60 -9
- package/dist/shared/http-retry.js.map +1 -1
- package/dist/shared/mcp-manager.d.ts +8 -4
- package/dist/shared/mcp-manager.js +30 -4
- package/dist/shared/mcp-manager.js.map +1 -1
- package/dist/shared/mcp-schema-sanitizer.d.ts +70 -0
- package/dist/shared/mcp-schema-sanitizer.js +197 -0
- package/dist/shared/mcp-schema-sanitizer.js.map +1 -0
- package/dist/shared/mcp-transport-guard.d.ts +2 -2
- package/dist/shared/mcp-transport-guard.js +2 -2
- package/dist/shared/model-client.d.ts +6 -0
- package/dist/shared/model-client.js +14 -3
- package/dist/shared/model-client.js.map +1 -1
- package/dist/shared/model-pricing-data.d.ts +2 -0
- package/dist/shared/model-pricing-data.js +13 -3
- package/dist/shared/model-pricing-data.js.map +1 -1
- package/dist/shared/model-registry.js +3 -2
- package/dist/shared/model-registry.js.map +1 -1
- package/dist/shared/plan-mode-permissions.d.ts +7 -0
- package/dist/shared/plan-mode-permissions.js +7 -0
- package/dist/shared/plan-mode-permissions.js.map +1 -1
- package/dist/shared/registry-endpoint.d.ts +20 -0
- package/dist/shared/registry-endpoint.js +25 -0
- package/dist/shared/registry-endpoint.js.map +1 -1
- package/dist/shared/runner-credential-keys.d.ts +24 -0
- package/dist/shared/runner-credential-keys.js +47 -0
- package/dist/shared/runner-credential-keys.js.map +1 -0
- package/dist/shared/synthesized-attachment.d.ts +4 -4
- package/dist/shared/synthesized-attachment.js +4 -4
- package/dist/workflow-engine/resolve.d.ts +19 -1
- package/dist/workflow-engine/resolve.js +37 -2
- package/dist/workflow-engine/resolve.js.map +1 -1
- package/dist/workflows/connect-mcp-server.js +2 -0
- package/dist/workflows/connect-mcp-server.js.map +1 -1
- package/dist/workflows/types.d.ts +8 -0
- package/package.json +3 -4
- package/src/__test-utils__/__tests__/vitest-global-setup.test.ts +37 -0
- package/src/__test-utils__/fake-artifact-storage.ts +10 -1
- package/src/__test-utils__/vitest-global-setup.ts +50 -0
- package/src/__tests__/bootstrap.test.ts +43 -0
- package/src/__tests__/encryption-codec.test.ts +53 -0
- package/src/__tests__/preflight.test.ts +15 -0
- package/src/activities/__tests__/discover-mcp-server.test.ts +39 -1
- package/src/activities/__tests__/error-classifier.test.ts +94 -2
- package/src/activities/__tests__/run-command.test.ts +221 -0
- package/src/activities/discover-mcp-server.ts +16 -2
- package/src/activities/emit-event.ts +65 -21
- package/src/activities/execute-cursor/__tests__/attachment-resolver.test.ts +63 -3
- package/src/activities/execute-cursor/__tests__/build-prompt.test.ts +173 -31
- package/src/activities/execute-cursor/__tests__/model-pricing.test.ts +62 -1
- package/src/activities/execute-cursor/__tests__/turn-recovery.test.ts +160 -0
- package/src/activities/execute-cursor/attachment-resolver.ts +24 -0
- package/src/activities/execute-cursor/blueprint-resolver.ts +1 -10
- package/src/activities/execute-cursor/error-classifier.ts +40 -3
- package/src/activities/execute-cursor/index.ts +175 -74
- package/src/activities/execute-cursor/model-pricing-data.ts +22 -3
- package/src/activities/execute-cursor/prompt-builder.ts +89 -22
- package/src/activities/execute-cursor/turn-recovery.ts +208 -0
- package/src/activities/execute-deep-agent/__tests__/attachment-injector.test.ts +105 -0
- package/src/activities/execute-deep-agent/__tests__/hitl-reject.test.ts +0 -2
- package/src/activities/execute-deep-agent/__tests__/hitl-resume-approve-all.test.ts +0 -1
- package/src/activities/execute-deep-agent/__tests__/hitl-resume-history.test.ts +0 -1
- package/src/activities/execute-deep-agent/__tests__/mcp-gate.test.ts +2 -7
- package/src/activities/execute-deep-agent/__tests__/plan-mode-path-normalization.test.ts +174 -0
- package/src/activities/execute-deep-agent/__tests__/prompt-builder.test.ts +71 -0
- package/src/activities/execute-deep-agent/__tests__/sequential-gate-resume.test.ts +0 -1
- package/src/activities/execute-deep-agent/__tests__/shell-env.test.ts +24 -10
- package/src/activities/execute-deep-agent/__tests__/subagent-plan-mode-permissions.test.ts +22 -17
- package/src/activities/execute-deep-agent/attachment-injector.ts +20 -1
- package/src/activities/execute-deep-agent/index.ts +0 -19
- package/src/activities/execute-deep-agent/mcp-gate.ts +0 -3
- package/src/activities/execute-deep-agent/prompt-builder.ts +27 -15
- package/src/activities/execute-deep-agent/setup.ts +22 -73
- package/src/activities/execute-deep-agent/shell-env.ts +8 -9
- package/src/activities/execute-deep-agent/subagent-transformer.ts +7 -1
- package/src/activities/execute-deep-agent/subagent-wiring.ts +26 -3
- package/src/activities/hydrate-workflow-execution.ts +8 -5
- package/src/activities/run-command.ts +25 -12
- package/src/activities/run-env.ts +79 -0
- package/src/bootstrap.ts +5 -0
- package/src/client/__tests__/stigmer-client.test.ts +104 -5
- package/src/client/stigmer-client.ts +128 -29
- package/src/config.ts +6 -5
- package/src/encryption/config.ts +87 -23
- package/src/middleware/__tests__/path-normalization.test.ts +140 -0
- package/src/middleware/index.ts +8 -0
- package/src/middleware/path-normalization.ts +125 -0
- package/src/middleware/types.ts +11 -0
- package/src/payload-codecs.ts +8 -2
- package/src/runner-manager.ts +21 -3
- package/src/runner.ts +7 -3
- package/src/shared/__tests__/artifact-storage.test.ts +154 -2
- package/src/shared/__tests__/attachment-download-urls.test.ts +70 -0
- package/src/shared/__tests__/channel-attachment.test.ts +2 -2
- package/src/shared/__tests__/conversation-catchup.test.ts +24 -0
- package/src/shared/__tests__/http-retry.test.ts +5 -4
- package/src/shared/__tests__/mcp-manager.test.ts +53 -13
- package/src/shared/__tests__/mcp-schema-sanitizer.test.ts +267 -0
- package/src/shared/__tests__/model-client.test.ts +46 -0
- package/src/shared/__tests__/model-pricing.test.ts +62 -2
- package/src/shared/__tests__/model-registry.test.ts +22 -0
- package/src/shared/__tests__/synthesized-attachment.test.ts +19 -41
- package/src/shared/artifact-storage.ts +86 -10
- package/src/shared/attachment-download-urls.ts +98 -0
- package/src/shared/channel-attachment.ts +1 -1
- package/src/shared/checkpointer/http-saver.ts +15 -60
- package/src/shared/conversation-attachment.ts +2 -3
- package/src/shared/conversation-catchup.ts +39 -6
- package/src/shared/grpc-retry.ts +5 -1
- package/src/shared/http-retry.ts +98 -9
- package/src/shared/mcp-manager.ts +35 -4
- package/src/shared/mcp-schema-sanitizer.ts +224 -0
- package/src/shared/mcp-transport-guard.ts +2 -2
- package/src/shared/model-client.ts +21 -3
- package/src/shared/model-pricing-data.ts +22 -3
- package/src/shared/model-registry.ts +7 -2
- package/src/shared/plan-mode-permissions.ts +7 -0
- package/src/shared/registry-endpoint.ts +27 -0
- package/src/shared/runner-credential-keys.ts +46 -0
- package/src/shared/synthesized-attachment.ts +4 -4
- package/src/workflow-engine/__tests__/tasks/emit-event.test.ts +127 -49
- package/src/workflow-engine/resolve.ts +48 -2
- package/src/workflows/__tests__/connect-mcp-server.test.ts +25 -0
- package/src/workflows/connect-mcp-server.ts +2 -0
- package/src/workflows/types.ts +8 -0
- package/dist/activities/execute-cursor/mcp-config.d.ts +0 -30
- package/dist/activities/execute-cursor/mcp-config.js +0 -39
- package/dist/activities/execute-cursor/mcp-config.js.map +0 -1
- package/dist/shared/datastore-attachment.d.ts +0 -99
- package/dist/shared/datastore-attachment.js +0 -184
- package/dist/shared/datastore-attachment.js.map +0 -1
- package/src/activities/execute-cursor/mcp-config.ts +0 -66
- package/src/activities/execute-deep-agent/__tests__/datastore-degradation.test.ts +0 -104
- package/src/shared/__tests__/datastore-attachment.test.ts +0 -293
- package/src/shared/datastore-attachment.ts +0 -209
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Cursor-specific MCP config mapping.
|
|
3
|
-
*
|
|
4
|
-
* Converts harness-agnostic ResolvedMcpServer into the Cursor SDK's
|
|
5
|
-
* McpServerConfig shape for Agent.create(). The resolution logic lives
|
|
6
|
-
* in shared/mcp-resolver.ts; this module only handles the final transform.
|
|
7
|
-
*/
|
|
8
|
-
export { resolveMcpServers, extractMcpServerSlugs, PlaceholderResolutionError, } from "../../shared/mcp-resolver.js";
|
|
9
|
-
/**
|
|
10
|
-
* Transform resolved MCP servers into the Cursor SDK's mcpServers config
|
|
11
|
-
* for Agent.create().
|
|
12
|
-
*/
|
|
13
|
-
export function toCursorMcpConfig(servers) {
|
|
14
|
-
const result = {};
|
|
15
|
-
for (const server of servers) {
|
|
16
|
-
if (server.connectionType === "stdio") {
|
|
17
|
-
if (!server.command)
|
|
18
|
-
continue;
|
|
19
|
-
result[server.slug] = {
|
|
20
|
-
type: "stdio",
|
|
21
|
-
command: server.command,
|
|
22
|
-
args: server.args,
|
|
23
|
-
env: server.env,
|
|
24
|
-
cwd: server.cwd,
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
else {
|
|
28
|
-
if (!server.url)
|
|
29
|
-
continue;
|
|
30
|
-
result[server.slug] = {
|
|
31
|
-
type: server.connectionType,
|
|
32
|
-
url: server.url,
|
|
33
|
-
headers: server.headers,
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
return result;
|
|
38
|
-
}
|
|
39
|
-
//# sourceMappingURL=mcp-config.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-config.js","sourceRoot":"","sources":["../../../src/activities/execute-cursor/mcp-config.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,0BAA0B,GAC3B,MAAM,8BAA8B,CAAC;AAoBtC;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,OAA4B;IAE5B,MAAM,MAAM,GAA0C,EAAE,CAAC;IAEzD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,MAAM,CAAC,cAAc,KAAK,OAAO,EAAE,CAAC;YACtC,IAAI,CAAC,MAAM,CAAC,OAAO;gBAAE,SAAS;YAC9B,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG;gBACpB,IAAI,EAAE,OAAO;gBACb,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,GAAG,EAAE,MAAM,CAAC,GAAG;gBACf,GAAG,EAAE,MAAM,CAAC,GAAG;aAChB,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,MAAM,CAAC,GAAG;gBAAE,SAAS;YAC1B,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG;gBACpB,IAAI,EAAE,MAAM,CAAC,cAAc;gBAC3B,GAAG,EAAE,MAAM,CAAC,GAAG;gBACf,OAAO,EAAE,MAAM,CAAC,OAAO;aACxB,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The runner-synthesized datastore records attachment (T05, DD-001 SD-2).
|
|
3
|
-
*
|
|
4
|
-
* When an agent declares `datastore_usages`, the runner synthesizes ONE
|
|
5
|
-
* MCP attachment serving the five record tools (DD-005) — the agent
|
|
6
|
-
* builder writes a usage line and gets tools; no McpServer resource, no
|
|
7
|
-
* Environment, no credential in any manifest. Harness-agnostic like
|
|
8
|
-
* mcp-resolver.ts: both ExecuteCursor and ExecuteDeepAgent inject the
|
|
9
|
-
* synthesized entry through their existing ResolvedMcpServer paths.
|
|
10
|
-
*
|
|
11
|
-
* Two connection shapes, one roster (the bridge's records-only roster,
|
|
12
|
-
* T05 R1):
|
|
13
|
-
* - Bridge endpoint configured (cloud): Streamable HTTP against the
|
|
14
|
-
* bridge's /records route, with the execution's own session-scoped
|
|
15
|
-
* credential as the Bearer token — the server's reach chain (DD-006
|
|
16
|
-
* Path 1) authorizes from that token; the bridge stays a
|
|
17
|
-
* non-validating passthrough.
|
|
18
|
-
* - No bridge endpoint (OSS/local): a spawned `stigmer mcp-server`
|
|
19
|
-
* stdio child with STIGMER_MCP_ROSTER=records against the local
|
|
20
|
-
* backend (zero new distribution — the CLI already embeds the
|
|
21
|
-
* bridge). No credential: the local backend is unauthenticated and
|
|
22
|
-
* OSS callers resolve as the local principal (T05 R2).
|
|
23
|
-
*
|
|
24
|
-
* Approval-free by construction (DD-001 SD-3): empty toolApprovals +
|
|
25
|
-
* pinnedToolApprovals + toolApprovalOverrides mean mergeApprovalPolicies
|
|
26
|
-
* emits no entries for this server — zero classifier involvement, and no
|
|
27
|
-
* proto surface can target it (the attachment has no McpServerUsage, and
|
|
28
|
-
* since issue #349 an agent's overrides are scoped to their own usage's
|
|
29
|
-
* server, so a same-named override elsewhere cannot reach this one).
|
|
30
|
-
* `discoveredCapabilitiesEmpty`
|
|
31
|
-
* is false and the attachment has no McpServerUsage, so the connect
|
|
32
|
-
* backfill (whose destructiveHint tightener would force-gate
|
|
33
|
-
* delete_record — silently skipped on channels under UNATTENDED mode)
|
|
34
|
-
* is structurally unable to touch it. Callers must still inject AFTER
|
|
35
|
-
* resolve + backfill; both harness call sites do.
|
|
36
|
-
*/
|
|
37
|
-
import type { DatastoreUsage } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/spec_pb";
|
|
38
|
-
import type { ResolvedMcpServer } from "./mcp-resolver.js";
|
|
39
|
-
import { type SynthesizedAttachmentOptions } from "./synthesized-attachment.js";
|
|
40
|
-
/**
|
|
41
|
-
* The synthesized attachment's slug. Reserved: a user McpServer with
|
|
42
|
-
* this slug is shadowed by the synthesized attachment (the record tools
|
|
43
|
-
* must exist whenever `datastore_usages` says so), with a warning.
|
|
44
|
-
*/
|
|
45
|
-
export declare const DATASTORE_ATTACHMENT_SLUG = "stigmer-records";
|
|
46
|
-
/** The bridge route serving the records-only roster (mcp-server T05 R1). */
|
|
47
|
-
export declare const RECORDS_ROUTE = "/records";
|
|
48
|
-
/**
|
|
49
|
-
* Synthesize the records attachment for an agent's datastore usages.
|
|
50
|
-
* Returns undefined when the agent uses no datastores — the attachment
|
|
51
|
-
* exists exactly when the usage edge does.
|
|
52
|
-
*/
|
|
53
|
-
export declare function synthesizeDatastoreAttachment(datastoreUsages: DatastoreUsage[], options: SynthesizedAttachmentOptions): ResolvedMcpServer | undefined;
|
|
54
|
-
/**
|
|
55
|
-
* The five record tools the records roster always serves (DD-005; the
|
|
56
|
-
* mcp-server's records roster registers all five unconditionally for the
|
|
57
|
-
* agent audience — only the `org` argument shape varies by audience, see
|
|
58
|
-
* mcp-server/src/domains/records/tools.ts). Because the roster never
|
|
59
|
-
* legitimately narrows, any of these missing from the connected toolset
|
|
60
|
-
* means the store is degraded (issue #325) — the prompt section and the
|
|
61
|
-
* reconciliation both derive from this one list so they cannot drift.
|
|
62
|
-
*/
|
|
63
|
-
export declare const EXPECTED_RECORD_TOOLS: readonly ["describe_datastore", "find_records", "insert_record", "update_record", "delete_record"];
|
|
64
|
-
/**
|
|
65
|
-
* Reconcile the record tools actually connected against the roster
|
|
66
|
-
* contract (issue #325). Returns the expected tools absent from
|
|
67
|
-
* `actualToolNames` — empty means healthy. Names are bare tool names
|
|
68
|
-
* exactly as reported by tools/list (the mcp-enabled-tools identity
|
|
69
|
-
* space); extraneous names are ignored.
|
|
70
|
-
*/
|
|
71
|
-
export declare function missingRecordTools(actualToolNames: Iterable<string>): string[];
|
|
72
|
-
/**
|
|
73
|
-
* The operator-facing degradation notice (issue #325): pushed as a
|
|
74
|
-
* MESSAGE_SYSTEM row on the execution status so "declared N datastores,
|
|
75
|
-
* X/5 record tools connected" is visible without reading a transcript.
|
|
76
|
-
* Lives HERE with the rest of the datastore-attachment wording — the
|
|
77
|
-
* harness only threads it.
|
|
78
|
-
*/
|
|
79
|
-
export declare function formatDatastoreDegradationNotice(declaredCount: number, missing: readonly string[]): string;
|
|
80
|
-
/**
|
|
81
|
-
* The datastores prompt section (DD-005 SD-5, the skills-section
|
|
82
|
-
* precedent). Shared by both harnesses so the section text cannot drift
|
|
83
|
-
* (the sender-identity precedent). Two honest renderings (issue #325):
|
|
84
|
-
*
|
|
85
|
-
* - Healthy (`missingToolNames` empty or omitted — the Cursor harness
|
|
86
|
-
* always calls it this way: the Cursor SDK connects MCP itself, so
|
|
87
|
-
* that harness can never observe the live roster):
|
|
88
|
-
* `<available_datastores>` names the attached datastores, points the
|
|
89
|
-
* model at describe_datastore first, and carries a standing
|
|
90
|
-
* failure-disclosure instruction — the only mechanism that covers
|
|
91
|
-
* tools which connected but fail at call time (the WhatsApp-pilot
|
|
92
|
-
* outage shape).
|
|
93
|
-
* - Degraded (deep-agent only, from missingRecordTools against the
|
|
94
|
-
* connected roster): `<unavailable_datastores>` instead — the section
|
|
95
|
-
* must not promise tools the agent does not have. Names the declared
|
|
96
|
-
* datastores, states which record tools are missing, and instructs
|
|
97
|
-
* plain disclosure over improvisation.
|
|
98
|
-
*/
|
|
99
|
-
export declare function formatDatastoresSection(datastoreUsages: DatastoreUsage[], missingToolNames?: readonly string[]): string;
|
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The runner-synthesized datastore records attachment (T05, DD-001 SD-2).
|
|
3
|
-
*
|
|
4
|
-
* When an agent declares `datastore_usages`, the runner synthesizes ONE
|
|
5
|
-
* MCP attachment serving the five record tools (DD-005) — the agent
|
|
6
|
-
* builder writes a usage line and gets tools; no McpServer resource, no
|
|
7
|
-
* Environment, no credential in any manifest. Harness-agnostic like
|
|
8
|
-
* mcp-resolver.ts: both ExecuteCursor and ExecuteDeepAgent inject the
|
|
9
|
-
* synthesized entry through their existing ResolvedMcpServer paths.
|
|
10
|
-
*
|
|
11
|
-
* Two connection shapes, one roster (the bridge's records-only roster,
|
|
12
|
-
* T05 R1):
|
|
13
|
-
* - Bridge endpoint configured (cloud): Streamable HTTP against the
|
|
14
|
-
* bridge's /records route, with the execution's own session-scoped
|
|
15
|
-
* credential as the Bearer token — the server's reach chain (DD-006
|
|
16
|
-
* Path 1) authorizes from that token; the bridge stays a
|
|
17
|
-
* non-validating passthrough.
|
|
18
|
-
* - No bridge endpoint (OSS/local): a spawned `stigmer mcp-server`
|
|
19
|
-
* stdio child with STIGMER_MCP_ROSTER=records against the local
|
|
20
|
-
* backend (zero new distribution — the CLI already embeds the
|
|
21
|
-
* bridge). No credential: the local backend is unauthenticated and
|
|
22
|
-
* OSS callers resolve as the local principal (T05 R2).
|
|
23
|
-
*
|
|
24
|
-
* Approval-free by construction (DD-001 SD-3): empty toolApprovals +
|
|
25
|
-
* pinnedToolApprovals + toolApprovalOverrides mean mergeApprovalPolicies
|
|
26
|
-
* emits no entries for this server — zero classifier involvement, and no
|
|
27
|
-
* proto surface can target it (the attachment has no McpServerUsage, and
|
|
28
|
-
* since issue #349 an agent's overrides are scoped to their own usage's
|
|
29
|
-
* server, so a same-named override elsewhere cannot reach this one).
|
|
30
|
-
* `discoveredCapabilitiesEmpty`
|
|
31
|
-
* is false and the attachment has no McpServerUsage, so the connect
|
|
32
|
-
* backfill (whose destructiveHint tightener would force-gate
|
|
33
|
-
* delete_record — silently skipped on channels under UNATTENDED mode)
|
|
34
|
-
* is structurally unable to touch it. Callers must still inject AFTER
|
|
35
|
-
* resolve + backfill; both harness call sites do.
|
|
36
|
-
*/
|
|
37
|
-
import { grpcTarget } from "./synthesized-attachment.js";
|
|
38
|
-
/**
|
|
39
|
-
* The synthesized attachment's slug. Reserved: a user McpServer with
|
|
40
|
-
* this slug is shadowed by the synthesized attachment (the record tools
|
|
41
|
-
* must exist whenever `datastore_usages` says so), with a warning.
|
|
42
|
-
*/
|
|
43
|
-
export const DATASTORE_ATTACHMENT_SLUG = "stigmer-records";
|
|
44
|
-
/** The bridge route serving the records-only roster (mcp-server T05 R1). */
|
|
45
|
-
export const RECORDS_ROUTE = "/records";
|
|
46
|
-
/**
|
|
47
|
-
* Synthesize the records attachment for an agent's datastore usages.
|
|
48
|
-
* Returns undefined when the agent uses no datastores — the attachment
|
|
49
|
-
* exists exactly when the usage edge does.
|
|
50
|
-
*/
|
|
51
|
-
export function synthesizeDatastoreAttachment(datastoreUsages, options) {
|
|
52
|
-
if (datastoreUsages.length === 0) {
|
|
53
|
-
return undefined;
|
|
54
|
-
}
|
|
55
|
-
// Approval-free by construction + backfill-proof: see file header.
|
|
56
|
-
const base = {
|
|
57
|
-
slug: DATASTORE_ATTACHMENT_SLUG,
|
|
58
|
-
toolApprovals: [],
|
|
59
|
-
pinnedToolApprovals: [],
|
|
60
|
-
toolApprovalOverrides: [],
|
|
61
|
-
discoveredCapabilitiesEmpty: false,
|
|
62
|
-
};
|
|
63
|
-
if (options.bridgeEndpoint !== null && options.bridgeEndpoint !== "") {
|
|
64
|
-
return {
|
|
65
|
-
...base,
|
|
66
|
-
connectionType: "http",
|
|
67
|
-
url: options.bridgeEndpoint.replace(/\/+$/, "") + RECORDS_ROUTE,
|
|
68
|
-
headers: options.credential !== null && options.credential !== ""
|
|
69
|
-
? { Authorization: `Bearer ${options.credential}` }
|
|
70
|
-
: undefined,
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
return {
|
|
74
|
-
...base,
|
|
75
|
-
connectionType: "stdio",
|
|
76
|
-
command: "stigmer",
|
|
77
|
-
args: ["mcp-server"],
|
|
78
|
-
env: {
|
|
79
|
-
STIGMER_MCP_ROSTER: "records",
|
|
80
|
-
STIGMER_SERVER_ADDRESS: grpcTarget(options.backendEndpoint),
|
|
81
|
-
},
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* The five record tools the records roster always serves (DD-005; the
|
|
86
|
-
* mcp-server's records roster registers all five unconditionally for the
|
|
87
|
-
* agent audience — only the `org` argument shape varies by audience, see
|
|
88
|
-
* mcp-server/src/domains/records/tools.ts). Because the roster never
|
|
89
|
-
* legitimately narrows, any of these missing from the connected toolset
|
|
90
|
-
* means the store is degraded (issue #325) — the prompt section and the
|
|
91
|
-
* reconciliation both derive from this one list so they cannot drift.
|
|
92
|
-
*/
|
|
93
|
-
export const EXPECTED_RECORD_TOOLS = [
|
|
94
|
-
"describe_datastore",
|
|
95
|
-
"find_records",
|
|
96
|
-
"insert_record",
|
|
97
|
-
"update_record",
|
|
98
|
-
"delete_record",
|
|
99
|
-
];
|
|
100
|
-
/**
|
|
101
|
-
* Reconcile the record tools actually connected against the roster
|
|
102
|
-
* contract (issue #325). Returns the expected tools absent from
|
|
103
|
-
* `actualToolNames` — empty means healthy. Names are bare tool names
|
|
104
|
-
* exactly as reported by tools/list (the mcp-enabled-tools identity
|
|
105
|
-
* space); extraneous names are ignored.
|
|
106
|
-
*/
|
|
107
|
-
export function missingRecordTools(actualToolNames) {
|
|
108
|
-
const present = new Set(actualToolNames);
|
|
109
|
-
return EXPECTED_RECORD_TOOLS.filter((name) => !present.has(name));
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* The operator-facing degradation notice (issue #325): pushed as a
|
|
113
|
-
* MESSAGE_SYSTEM row on the execution status so "declared N datastores,
|
|
114
|
-
* X/5 record tools connected" is visible without reading a transcript.
|
|
115
|
-
* Lives HERE with the rest of the datastore-attachment wording — the
|
|
116
|
-
* harness only threads it.
|
|
117
|
-
*/
|
|
118
|
-
export function formatDatastoreDegradationNotice(declaredCount, missing) {
|
|
119
|
-
const connected = EXPECTED_RECORD_TOOLS.length - missing.length;
|
|
120
|
-
return (`Datastore record tools unavailable this turn: declared ` +
|
|
121
|
-
`${declaredCount} datastore(s), ${connected}/${EXPECTED_RECORD_TOOLS.length} ` +
|
|
122
|
-
`record tools connected (missing: ${missing.join(", ")}). The agent has ` +
|
|
123
|
-
`been instructed to disclose this instead of answering from memory.`);
|
|
124
|
-
}
|
|
125
|
-
/**
|
|
126
|
-
* The datastores prompt section (DD-005 SD-5, the skills-section
|
|
127
|
-
* precedent). Shared by both harnesses so the section text cannot drift
|
|
128
|
-
* (the sender-identity precedent). Two honest renderings (issue #325):
|
|
129
|
-
*
|
|
130
|
-
* - Healthy (`missingToolNames` empty or omitted — the Cursor harness
|
|
131
|
-
* always calls it this way: the Cursor SDK connects MCP itself, so
|
|
132
|
-
* that harness can never observe the live roster):
|
|
133
|
-
* `<available_datastores>` names the attached datastores, points the
|
|
134
|
-
* model at describe_datastore first, and carries a standing
|
|
135
|
-
* failure-disclosure instruction — the only mechanism that covers
|
|
136
|
-
* tools which connected but fail at call time (the WhatsApp-pilot
|
|
137
|
-
* outage shape).
|
|
138
|
-
* - Degraded (deep-agent only, from missingRecordTools against the
|
|
139
|
-
* connected roster): `<unavailable_datastores>` instead — the section
|
|
140
|
-
* must not promise tools the agent does not have. Names the declared
|
|
141
|
-
* datastores, states which record tools are missing, and instructs
|
|
142
|
-
* plain disclosure over improvisation.
|
|
143
|
-
*/
|
|
144
|
-
export function formatDatastoresSection(datastoreUsages, missingToolNames = []) {
|
|
145
|
-
const entries = datastoreUsages
|
|
146
|
-
.map((u) => u.datastoreRef?.slug)
|
|
147
|
-
.filter((s) => !!s)
|
|
148
|
-
.map((slug) => `- ${slug}`);
|
|
149
|
-
if (missingToolNames.length > 0) {
|
|
150
|
-
return [
|
|
151
|
-
"<unavailable_datastores>",
|
|
152
|
-
"This agent is configured to use the datastores listed below, but the",
|
|
153
|
-
"following record tools failed to connect this turn:",
|
|
154
|
-
missingToolNames.join(", ") + ".",
|
|
155
|
-
"Treat these datastores as unreachable for any operation that needs a",
|
|
156
|
-
"missing tool.",
|
|
157
|
-
"",
|
|
158
|
-
...entries,
|
|
159
|
-
"",
|
|
160
|
-
"When the user's request depends on one of these datastores, tell them",
|
|
161
|
-
"plainly that the datastore cannot be reached right now. Never answer",
|
|
162
|
-
"from memory, guess, or improvise a substitute for what the datastore",
|
|
163
|
-
"would have returned.",
|
|
164
|
-
"</unavailable_datastores>",
|
|
165
|
-
].join("\n");
|
|
166
|
-
}
|
|
167
|
-
return [
|
|
168
|
-
"<available_datastores>",
|
|
169
|
-
"You have access to the following datastores through the record tools",
|
|
170
|
-
`(${EXPECTED_RECORD_TOOLS.join(", ")}).`,
|
|
171
|
-
"Before your first operation against a datastore, call describe_datastore to",
|
|
172
|
-
"learn its collections, field encodings, and which operations you are allowed",
|
|
173
|
-
"to perform.",
|
|
174
|
-
"",
|
|
175
|
-
...entries,
|
|
176
|
-
"",
|
|
177
|
-
"If any record tool is missing from your toolset or a record tool call",
|
|
178
|
-
"fails, the datastore is unreachable: tell the user plainly that you cannot",
|
|
179
|
-
"reach it right now, and do not answer from memory, guess, or improvise a",
|
|
180
|
-
"substitute for what it would have returned.",
|
|
181
|
-
"</available_datastores>",
|
|
182
|
-
].join("\n");
|
|
183
|
-
}
|
|
184
|
-
//# sourceMappingURL=datastore-attachment.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"datastore-attachment.js","sourceRoot":"","sources":["../../src/shared/datastore-attachment.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Cursor-specific MCP config mapping.
|
|
3
|
-
*
|
|
4
|
-
* Converts harness-agnostic ResolvedMcpServer into the Cursor SDK's
|
|
5
|
-
* McpServerConfig shape for Agent.create(). The resolution logic lives
|
|
6
|
-
* in shared/mcp-resolver.ts; this module only handles the final transform.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import type { ResolvedMcpServer } from "../../shared/mcp-resolver.js";
|
|
10
|
-
|
|
11
|
-
export type { ResolvedMcpServer, McpResolutionResult } from "../../shared/mcp-resolver.js";
|
|
12
|
-
export {
|
|
13
|
-
resolveMcpServers,
|
|
14
|
-
extractMcpServerSlugs,
|
|
15
|
-
PlaceholderResolutionError,
|
|
16
|
-
} from "../../shared/mcp-resolver.js";
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Cursor SDK MCP server config shape (matches @cursor/sdk McpServerConfig).
|
|
20
|
-
* Defined here to avoid tight coupling to the SDK's internal types.
|
|
21
|
-
*/
|
|
22
|
-
export type CursorMcpServerConfig =
|
|
23
|
-
| {
|
|
24
|
-
type?: "stdio";
|
|
25
|
-
command: string;
|
|
26
|
-
args?: string[];
|
|
27
|
-
env?: Record<string, string>;
|
|
28
|
-
cwd?: string;
|
|
29
|
-
}
|
|
30
|
-
| {
|
|
31
|
-
type?: "http" | "sse";
|
|
32
|
-
url: string;
|
|
33
|
-
headers?: Record<string, string>;
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Transform resolved MCP servers into the Cursor SDK's mcpServers config
|
|
38
|
-
* for Agent.create().
|
|
39
|
-
*/
|
|
40
|
-
export function toCursorMcpConfig(
|
|
41
|
-
servers: ResolvedMcpServer[],
|
|
42
|
-
): Record<string, CursorMcpServerConfig> {
|
|
43
|
-
const result: Record<string, CursorMcpServerConfig> = {};
|
|
44
|
-
|
|
45
|
-
for (const server of servers) {
|
|
46
|
-
if (server.connectionType === "stdio") {
|
|
47
|
-
if (!server.command) continue;
|
|
48
|
-
result[server.slug] = {
|
|
49
|
-
type: "stdio",
|
|
50
|
-
command: server.command,
|
|
51
|
-
args: server.args,
|
|
52
|
-
env: server.env,
|
|
53
|
-
cwd: server.cwd,
|
|
54
|
-
};
|
|
55
|
-
} else {
|
|
56
|
-
if (!server.url) continue;
|
|
57
|
-
result[server.slug] = {
|
|
58
|
-
type: server.connectionType,
|
|
59
|
-
url: server.url,
|
|
60
|
-
headers: server.headers,
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
return result;
|
|
66
|
-
}
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Datastore degradation disclosure, activity half (issue #325).
|
|
3
|
-
*
|
|
4
|
-
* The activity appends the operator-facing MESSAGE_SYSTEM notice to
|
|
5
|
-
* `initialStatus.messages` BEFORE streaming (index.ts) — deliberately not
|
|
6
|
-
* through a status builder, because the v2 and v3 stream paths each
|
|
7
|
-
* construct their own builder around that same proto. These tests pin the
|
|
8
|
-
* property that push site depends on: BOTH builders preserve pre-seeded
|
|
9
|
-
* messages (ExecutionState only appends; index rebuilds touch runtime
|
|
10
|
-
* tool-call state, and a MESSAGE_SYSTEM row carries no tool calls), so
|
|
11
|
-
* the notice survives whichever stream version runs and rides every
|
|
12
|
-
* persist. The prompt half (section selection) is pinned in
|
|
13
|
-
* shared/__tests__/datastore-attachment.test.ts.
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
import { describe, it, expect, beforeEach } from "vitest";
|
|
17
|
-
import { create } from "@bufbuild/protobuf";
|
|
18
|
-
import { AgentExecutionStatusSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
|
|
19
|
-
import type { AgentExecutionStatus } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
|
|
20
|
-
import { AgentMessageSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/message_pb";
|
|
21
|
-
import { MessageType } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
22
|
-
import {
|
|
23
|
-
EXPECTED_RECORD_TOOLS,
|
|
24
|
-
formatDatastoreDegradationNotice,
|
|
25
|
-
} from "../../../shared/datastore-attachment.js";
|
|
26
|
-
import { StatusBuilder } from "../status-builder.js";
|
|
27
|
-
import { V3StatusBuilder } from "../v3-status-builder.js";
|
|
28
|
-
import { normalize } from "../v3-protocol-normalizer.js";
|
|
29
|
-
import {
|
|
30
|
-
resetSeq,
|
|
31
|
-
makeMessageStart,
|
|
32
|
-
makeMessageFinish,
|
|
33
|
-
makeTextDelta,
|
|
34
|
-
} from "../__test-utils__/v3-event-fixtures.js";
|
|
35
|
-
|
|
36
|
-
beforeEach(() => resetSeq());
|
|
37
|
-
|
|
38
|
-
/** initialStatus as index.ts shapes it when setup reports missing tools. */
|
|
39
|
-
function statusWithDegradationNotice(): AgentExecutionStatus {
|
|
40
|
-
const status = create(AgentExecutionStatusSchema, {});
|
|
41
|
-
status.messages.push(create(AgentMessageSchema, {
|
|
42
|
-
type: MessageType.MESSAGE_SYSTEM,
|
|
43
|
-
content: formatDatastoreDegradationNotice(1, [...EXPECTED_RECORD_TOOLS]),
|
|
44
|
-
timestamp: "2026-08-11T00:00:00.000Z",
|
|
45
|
-
}));
|
|
46
|
-
return status;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
describe("datastore degradation notice survives streaming (issue #325)", () => {
|
|
50
|
-
it("v2 StatusBuilder preserves the pre-seeded notice through a streamed turn", () => {
|
|
51
|
-
const initialStatus = statusWithDegradationNotice();
|
|
52
|
-
const sb = new StatusBuilder("exec-1", initialStatus);
|
|
53
|
-
|
|
54
|
-
sb.processEvent({
|
|
55
|
-
event: "on_chat_model_stream",
|
|
56
|
-
run_id: "run-1",
|
|
57
|
-
data: { chunk: { content: "I cannot reach the datastore right now." } },
|
|
58
|
-
});
|
|
59
|
-
sb.processEvent({ event: "on_chat_model_end", run_id: "run-1", data: {} });
|
|
60
|
-
|
|
61
|
-
const messages = sb.currentStatus.messages;
|
|
62
|
-
expect(messages.length).toBeGreaterThanOrEqual(2);
|
|
63
|
-
expect(messages[0].type).toBe(MessageType.MESSAGE_SYSTEM);
|
|
64
|
-
expect(messages[0].content).toContain("0/5 record tools connected");
|
|
65
|
-
expect(messages[0].content).toContain("declared 1 datastore(s)");
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
it("v3 V3StatusBuilder preserves the pre-seeded notice through a streamed turn", () => {
|
|
69
|
-
const initialStatus = statusWithDegradationNotice();
|
|
70
|
-
const sb = new V3StatusBuilder("exec-1", initialStatus);
|
|
71
|
-
|
|
72
|
-
const protocolEvents = [
|
|
73
|
-
makeMessageStart("run-1"),
|
|
74
|
-
makeTextDelta("run-1", "I cannot reach the datastore right now."),
|
|
75
|
-
makeMessageFinish("run-1"),
|
|
76
|
-
];
|
|
77
|
-
for (const raw of protocolEvents) {
|
|
78
|
-
for (const e of normalize(raw)) {
|
|
79
|
-
sb.processEvent(e);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const messages = sb.currentStatus.messages;
|
|
84
|
-
expect(messages.length).toBeGreaterThanOrEqual(2);
|
|
85
|
-
expect(messages[0].type).toBe(MessageType.MESSAGE_SYSTEM);
|
|
86
|
-
expect(messages[0].content).toContain("0/5 record tools connected");
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
it("both builders share the initialStatus proto, so the append needs no builder", () => {
|
|
90
|
-
// The push-site contract itself: mutating initialStatus.messages is
|
|
91
|
-
// visible through whichever builder wraps it.
|
|
92
|
-
const initialStatus = create(AgentExecutionStatusSchema, {});
|
|
93
|
-
const sb = new StatusBuilder("exec-1", initialStatus);
|
|
94
|
-
initialStatus.messages.push(create(AgentMessageSchema, {
|
|
95
|
-
type: MessageType.MESSAGE_SYSTEM,
|
|
96
|
-
content: formatDatastoreDegradationNotice(2, ["delete_record"]),
|
|
97
|
-
timestamp: "2026-08-11T00:00:00.000Z",
|
|
98
|
-
}));
|
|
99
|
-
expect(sb.currentStatus.messages).toHaveLength(1);
|
|
100
|
-
expect(sb.currentStatus.messages[0].content).toContain(
|
|
101
|
-
"4/5 record tools connected",
|
|
102
|
-
);
|
|
103
|
-
});
|
|
104
|
-
});
|