@senpi/runtime 3.0.180 → 3.0.182

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.
Files changed (135) hide show
  1. package/dist/actions/llm-decision/openclaw-llm-decision.d.ts +8 -0
  2. package/dist/actions/llm-decision/openclaw-llm-decision.d.ts.map +1 -1
  3. package/dist/actions/llm-decision/openclaw-llm-decision.js +56 -1
  4. package/dist/actions/llm-decision/openclaw-llm-decision.js.map +1 -1
  5. package/dist/approvals/approval-store.d.ts +37 -7
  6. package/dist/approvals/approval-store.d.ts.map +1 -1
  7. package/dist/approvals/approval-store.js +127 -23
  8. package/dist/approvals/approval-store.js.map +1 -1
  9. package/dist/approvals/telemetry.d.ts +27 -3
  10. package/dist/approvals/telemetry.d.ts.map +1 -1
  11. package/dist/approvals/telemetry.js +8 -4
  12. package/dist/approvals/telemetry.js.map +1 -1
  13. package/dist/approvals/tool-approval-gate.d.ts +79 -0
  14. package/dist/approvals/tool-approval-gate.d.ts.map +1 -1
  15. package/dist/approvals/tool-approval-gate.js +184 -15
  16. package/dist/approvals/tool-approval-gate.js.map +1 -1
  17. package/dist/approvals/turn-context.d.ts +271 -0
  18. package/dist/approvals/turn-context.d.ts.map +1 -0
  19. package/dist/approvals/turn-context.js +551 -0
  20. package/dist/approvals/turn-context.js.map +1 -0
  21. package/dist/cli/guide-commands.d.ts.map +1 -1
  22. package/dist/cli/guide-commands.js +17 -3
  23. package/dist/cli/guide-commands.js.map +1 -1
  24. package/dist/cli/senpi-commands.d.ts.map +1 -1
  25. package/dist/cli/senpi-commands.js +71 -4
  26. package/dist/cli/senpi-commands.js.map +1 -1
  27. package/dist/deploy/job.d.ts +32 -0
  28. package/dist/deploy/job.d.ts.map +1 -1
  29. package/dist/deploy/job.js +72 -7
  30. package/dist/deploy/job.js.map +1 -1
  31. package/dist/deploy/register.d.ts +11 -0
  32. package/dist/deploy/register.d.ts.map +1 -1
  33. package/dist/deploy/register.js +84 -2
  34. package/dist/deploy/register.js.map +1 -1
  35. package/dist/host/openclaw-host.d.ts +138 -0
  36. package/dist/host/openclaw-host.d.ts.map +1 -0
  37. package/dist/host/openclaw-host.js +177 -0
  38. package/dist/host/openclaw-host.js.map +1 -0
  39. package/dist/index.d.ts +46 -2
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/index.js +220 -12
  42. package/dist/index.js.map +1 -1
  43. package/dist/runtime/auto-update/coordinator.d.ts +203 -0
  44. package/dist/runtime/auto-update/coordinator.d.ts.map +1 -1
  45. package/dist/runtime/auto-update/coordinator.js +621 -12
  46. package/dist/runtime/auto-update/coordinator.js.map +1 -1
  47. package/dist/runtime/auto-update/gateway-restart.d.ts +60 -1
  48. package/dist/runtime/auto-update/gateway-restart.d.ts.map +1 -1
  49. package/dist/runtime/auto-update/gateway-restart.js +95 -21
  50. package/dist/runtime/auto-update/gateway-restart.js.map +1 -1
  51. package/dist/runtime/auto-update/idle-gate.d.ts +139 -0
  52. package/dist/runtime/auto-update/idle-gate.d.ts.map +1 -0
  53. package/dist/runtime/auto-update/idle-gate.js +217 -0
  54. package/dist/runtime/auto-update/idle-gate.js.map +1 -0
  55. package/dist/runtime/auto-update/install-results.d.ts +130 -0
  56. package/dist/runtime/auto-update/install-results.d.ts.map +1 -0
  57. package/dist/runtime/auto-update/install-results.js +264 -0
  58. package/dist/runtime/auto-update/install-results.js.map +1 -0
  59. package/dist/runtime/auto-update/money-call-tracker.d.ts +36 -0
  60. package/dist/runtime/auto-update/money-call-tracker.d.ts.map +1 -0
  61. package/dist/runtime/auto-update/money-call-tracker.js +129 -0
  62. package/dist/runtime/auto-update/money-call-tracker.js.map +1 -0
  63. package/dist/runtime/auto-update/register-idle-gate.d.ts +70 -0
  64. package/dist/runtime/auto-update/register-idle-gate.d.ts.map +1 -0
  65. package/dist/runtime/auto-update/register-idle-gate.js +123 -0
  66. package/dist/runtime/auto-update/register-idle-gate.js.map +1 -0
  67. package/dist/runtime/auto-update/run-update-command.d.ts +13 -0
  68. package/dist/runtime/auto-update/run-update-command.d.ts.map +1 -1
  69. package/dist/runtime/auto-update/run-update-command.js +18 -0
  70. package/dist/runtime/auto-update/run-update-command.js.map +1 -1
  71. package/dist/runtime/auto-update/state-store.d.ts +14 -1
  72. package/dist/runtime/auto-update/state-store.d.ts.map +1 -1
  73. package/dist/runtime/auto-update/state-store.js +37 -3
  74. package/dist/runtime/auto-update/state-store.js.map +1 -1
  75. package/dist/runtime/auto-update/types.d.ts +51 -0
  76. package/dist/runtime/auto-update/types.d.ts.map +1 -1
  77. package/dist/runtime/auto-update/types.js.map +1 -1
  78. package/dist/runtime/auto-update/update-marker.d.ts +95 -0
  79. package/dist/runtime/auto-update/update-marker.d.ts.map +1 -0
  80. package/dist/runtime/auto-update/update-marker.js +185 -0
  81. package/dist/runtime/auto-update/update-marker.js.map +1 -0
  82. package/dist/runtime/auto-update/update-schedule.d.ts +57 -0
  83. package/dist/runtime/auto-update/update-schedule.d.ts.map +1 -0
  84. package/dist/runtime/auto-update/update-schedule.js +75 -0
  85. package/dist/runtime/auto-update/update-schedule.js.map +1 -0
  86. package/dist/runtime/decision-errors.d.ts +7 -0
  87. package/dist/runtime/decision-errors.d.ts.map +1 -1
  88. package/dist/runtime/decision-errors.js +15 -0
  89. package/dist/runtime/decision-errors.js.map +1 -1
  90. package/dist/senpi/client.d.ts +25 -0
  91. package/dist/senpi/client.d.ts.map +1 -1
  92. package/dist/senpi/client.js +56 -0
  93. package/dist/senpi/client.js.map +1 -1
  94. package/dist/telemetry/metrics.d.ts +14 -0
  95. package/dist/telemetry/metrics.d.ts.map +1 -1
  96. package/dist/telemetry/metrics.js +24 -0
  97. package/dist/telemetry/metrics.js.map +1 -1
  98. package/dist/telemetry/otel-sdk.d.ts +12 -0
  99. package/dist/telemetry/otel-sdk.d.ts.map +1 -1
  100. package/dist/telemetry/otel-sdk.js +47 -1
  101. package/dist/telemetry/otel-sdk.js.map +1 -1
  102. package/dist/telemetry/spans/span-hooks.d.ts +18 -1
  103. package/dist/telemetry/spans/span-hooks.d.ts.map +1 -1
  104. package/dist/telemetry/spans/span-hooks.js +306 -96
  105. package/dist/telemetry/spans/span-hooks.js.map +1 -1
  106. package/dist/telemetry/tool-plane.d.ts +2 -0
  107. package/dist/telemetry/tool-plane.d.ts.map +1 -1
  108. package/dist/telemetry/tool-plane.js +1 -0
  109. package/dist/telemetry/tool-plane.js.map +1 -1
  110. package/dist/tool-surface/crib-cache.d.ts +21 -0
  111. package/dist/tool-surface/crib-cache.d.ts.map +1 -0
  112. package/dist/tool-surface/crib-cache.js +54 -0
  113. package/dist/tool-surface/crib-cache.js.map +1 -0
  114. package/dist/tool-surface/crib-hook.d.ts +78 -0
  115. package/dist/tool-surface/crib-hook.d.ts.map +1 -0
  116. package/dist/tool-surface/crib-hook.js +217 -0
  117. package/dist/tool-surface/crib-hook.js.map +1 -0
  118. package/dist/tool-surface/crib-sheet.d.ts +56 -0
  119. package/dist/tool-surface/crib-sheet.d.ts.map +1 -0
  120. package/dist/tool-surface/crib-sheet.js +129 -0
  121. package/dist/tool-surface/crib-sheet.js.map +1 -0
  122. package/dist/tool-surface/mcp-tool-source.d.ts +64 -0
  123. package/dist/tool-surface/mcp-tool-source.d.ts.map +1 -0
  124. package/dist/tool-surface/mcp-tool-source.js +189 -0
  125. package/dist/tool-surface/mcp-tool-source.js.map +1 -0
  126. package/dist/utils/event-catalog.d.ts +117 -5
  127. package/dist/utils/event-catalog.d.ts.map +1 -1
  128. package/dist/utils/event-catalog.js +19 -0
  129. package/dist/utils/event-catalog.js.map +1 -1
  130. package/dist/widgets/tool.d.ts +9 -0
  131. package/dist/widgets/tool.d.ts.map +1 -1
  132. package/dist/widgets/tool.js +1 -0
  133. package/dist/widgets/tool.js.map +1 -1
  134. package/openclaw.plugin.json +11 -1
  135. package/package.json +5 -2
@@ -0,0 +1,56 @@
1
+ /**
2
+ * The crib sheet: the `senpi__*` tool names, with their required arguments,
3
+ * for an OpenClaw 10.x agent in tool-search directory mode (R3).
4
+ *
5
+ * In directory mode OpenClaw lists only `source === "openclaw"` tools in the
6
+ * deferred-tool directory and folds every MCP tool into one generic sentence
7
+ * (`openclaw-worktrees/v2026.10.10-beta.3/src/agents/tool-search-directory.ts:127-221`),
8
+ * so no `senpi__*` name reaches the model, while skills and guides keep naming
9
+ * them. The sheet puts the names back, as text the hook returns in
10
+ * `prependSystemContext`, ahead of the stable system-prompt prefix. It is
11
+ * cache-stable only while its bytes do not change, so the builder is pure and
12
+ * deterministic: the same set of tools in any order renders the same string.
13
+ *
14
+ * Every entry is the full catalog name (`senpi__create_position`), the exact
15
+ * text the dispatcher accepts as `id`; the model never assembles a name.
16
+ */
17
+ /** One MCP tool as the crib needs it. */
18
+ export interface McpToolSummary {
19
+ /** Bare MCP name, as `tools/list` returns it (`create_position`). */
20
+ name: string;
21
+ /** `inputSchema.required ?? []`, sorted. */
22
+ required: string[];
23
+ /** `Object.keys(inputSchema.properties ?? {})`, sorted. */
24
+ properties: string[];
25
+ }
26
+ /** Options for {@link buildCribSheet}. */
27
+ export interface BuildCribSheetOptions {
28
+ /** Cap on the whole sheet, header included. Default {@link CRIB_SHEET_MAX_CHARS}. */
29
+ maxChars?: number;
30
+ /** The gateway's MCP server name, the catalog prefix. Default `senpi`. */
31
+ serverName?: string;
32
+ /**
33
+ * Optional arguments worth naming, by bare tool name. One renders as `arg?`
34
+ * only when the tool's `properties` has it, so a stale hint never names a
35
+ * missing argument. Default `{}` (open decision D11 decides whether any ship).
36
+ */
37
+ optionalHints?: Readonly<Record<string, readonly string[]>>;
38
+ /**
39
+ * The tool-search dispatcher's name as the host lists it (`dispatch_action`
40
+ * on 10.10; read from the host's tool list by the hook). Default
41
+ * {@link DEFAULT_DISPATCHER_NAME}.
42
+ */
43
+ dispatcherName?: string;
44
+ }
45
+ /** Default cap. The 59-tool MCP catalog renders in under 4,000 chars with arguments. */
46
+ export declare const CRIB_SHEET_MAX_CHARS = 6000;
47
+ /** The dispatcher name on the pinned host (`TOOL_CALL_RAW_TOOL_NAME`, 10.10 `src/agents/tool-search-types.ts:12`). */
48
+ export declare const DEFAULT_DISPATCHER_NAME = "dispatch_action";
49
+ /**
50
+ * Builds the sheet, or `null` when there is no tool to name.
51
+ *
52
+ * Over `maxChars` it first drops the argument lists; if the names alone still
53
+ * do not fit, it keeps whole groups in order and ends with `+N more`.
54
+ */
55
+ export declare function buildCribSheet(tools: readonly McpToolSummary[], opts?: BuildCribSheetOptions): string | null;
56
+ //# sourceMappingURL=crib-sheet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crib-sheet.d.ts","sourceRoot":"","sources":["../../src/tool-surface/crib-sheet.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,yCAAyC;AACzC,MAAM,WAAW,cAAc;IAC7B,qEAAqE;IACrE,IAAI,EAAE,MAAM,CAAC;IACb,4CAA4C;IAC5C,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,2DAA2D;IAC3D,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,0CAA0C;AAC1C,MAAM,WAAW,qBAAqB;IACpC,qFAAqF;IACrF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,aAAa,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,CAAC;IAC5D;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,wFAAwF;AACxF,eAAO,MAAM,oBAAoB,OAAQ,CAAC;AAE1C,sHAAsH;AACtH,eAAO,MAAM,uBAAuB,oBAAoB,CAAC;AAYzD;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,SAAS,cAAc,EAAE,EAChC,IAAI,GAAE,qBAA0B,GAC/B,MAAM,GAAG,IAAI,CAmCf"}
@@ -0,0 +1,129 @@
1
+ /**
2
+ * The crib sheet: the `senpi__*` tool names, with their required arguments,
3
+ * for an OpenClaw 10.x agent in tool-search directory mode (R3).
4
+ *
5
+ * In directory mode OpenClaw lists only `source === "openclaw"` tools in the
6
+ * deferred-tool directory and folds every MCP tool into one generic sentence
7
+ * (`openclaw-worktrees/v2026.10.10-beta.3/src/agents/tool-search-directory.ts:127-221`),
8
+ * so no `senpi__*` name reaches the model, while skills and guides keep naming
9
+ * them. The sheet puts the names back, as text the hook returns in
10
+ * `prependSystemContext`, ahead of the stable system-prompt prefix. It is
11
+ * cache-stable only while its bytes do not change, so the builder is pure and
12
+ * deterministic: the same set of tools in any order renders the same string.
13
+ *
14
+ * Every entry is the full catalog name (`senpi__create_position`), the exact
15
+ * text the dispatcher accepts as `id`; the model never assembles a name.
16
+ */
17
+ /** Default cap. The 59-tool MCP catalog renders in under 4,000 chars with arguments. */
18
+ export const CRIB_SHEET_MAX_CHARS = 6_000;
19
+ /** The dispatcher name on the pinned host (`TOOL_CALL_RAW_TOOL_NAME`, 10.10 `src/agents/tool-search-types.ts:12`). */
20
+ export const DEFAULT_DISPATCHER_NAME = "dispatch_action";
21
+ /** The schema tool on 10.x (`TOOL_DESCRIBE_RAW_TOOL_NAME`). */
22
+ const DESCRIBE_TOOL_NAME = "tool_describe";
23
+ /** The search tool on 10.x (`TOOL_SEARCH_RAW_TOOL_NAME`). */
24
+ const SEARCH_TOOL_NAME = "tool_search";
25
+ /**
26
+ * Builds the sheet, or `null` when there is no tool to name.
27
+ *
28
+ * Over `maxChars` it first drops the argument lists; if the names alone still
29
+ * do not fit, it keeps whole groups in order and ends with `+N more`.
30
+ */
31
+ export function buildCribSheet(tools, opts = {}) {
32
+ const maxChars = opts.maxChars ?? CRIB_SHEET_MAX_CHARS;
33
+ const server = opts.serverName ?? "senpi";
34
+ const dispatcher = opts.dispatcherName ?? DEFAULT_DISPATCHER_NAME;
35
+ const hints = opts.optionalHints ?? {};
36
+ const byName = new Map();
37
+ for (const tool of tools) {
38
+ if (typeof tool?.name === "string" && tool.name.length > 0 && !byName.has(tool.name))
39
+ byName.set(tool.name, tool);
40
+ }
41
+ if (byName.size === 0)
42
+ return null;
43
+ const groups = groupByPrefix([...byName.values()]);
44
+ const example = byName.has("create_position") ? "create_position" : [...byName.keys()].sort()[0];
45
+ const withArgs = render(groups, header(server, dispatcher, example, true), (t) => entry(server, t, hints));
46
+ if (withArgs.length <= maxChars)
47
+ return withArgs;
48
+ const namesHeader = header(server, dispatcher, example, false);
49
+ const namesOnly = render(groups, namesHeader, (t) => `${server}__${t.name}`);
50
+ if (namesOnly.length <= maxChars)
51
+ return namesOnly;
52
+ const total = byName.size;
53
+ const lines = [];
54
+ let used = namesHeader.length;
55
+ let shown = 0;
56
+ for (const group of groups) {
57
+ const line = groupLine(group, (t) => `${server}__${t.name}`);
58
+ const remainingAfter = total - shown - group.tools.length;
59
+ const markerAfter = remainingAfter > 0 ? 1 + moreLine(remainingAfter).length : 0;
60
+ if (used + 1 + line.length + markerAfter > maxChars)
61
+ break;
62
+ lines.push(line);
63
+ used += 1 + line.length;
64
+ shown += group.tools.length;
65
+ }
66
+ lines.push(moreLine(total - shown));
67
+ return [namesHeader, ...lines].join("\n");
68
+ }
69
+ /**
70
+ * The sheet's opening lines. They carry the four facts the model needs: the
71
+ * tools are absent from the tool list and the directory; they are called
72
+ * through the dispatcher with the full name as `id`; skills drop the prefix;
73
+ * `tool_describe` gives the full schema.
74
+ */
75
+ function header(server, dispatcher, example, withArgs) {
76
+ return [
77
+ "## Senpi tools",
78
+ `The Senpi tools below are not in your tool list and not in the deferred-tool directory. ` +
79
+ `To call one, use ${dispatcher} with {"id": "${server}__<name>", "args": {...}}. ` +
80
+ `Skills and guides name these tools without the ${server}__ prefix (${example}); add it (${server}__${example}). ` +
81
+ (withArgs
82
+ ? `Required arguments are in parentheses; run ${DESCRIBE_TOOL_NAME} on a name for its full argument schema.`
83
+ : `Run ${DESCRIBE_TOOL_NAME} on a name for its argument schema.`),
84
+ ].join("\n");
85
+ }
86
+ function render(groups, head, fmt) {
87
+ return [head, ...groups.map((g) => groupLine(g, fmt))].join("\n");
88
+ }
89
+ function groupLine(group, fmt) {
90
+ return `${group.prefix}: ${group.tools.map(fmt).join(", ")}`;
91
+ }
92
+ function moreLine(n) {
93
+ return `+${n} more Senpi tools: find them with ${SEARCH_TOOL_NAME}.`;
94
+ }
95
+ /**
96
+ * `senpi__name(req1, req2, opt?)`; required args sorted, hints in the order
97
+ * given. A tool that takes no arguments renders `senpi__name()`; one whose
98
+ * arguments are all optional (and unhinted) renders the bare name, so it does
99
+ * not read as taking none.
100
+ */
101
+ function entry(server, tool, hints) {
102
+ const required = [...new Set(tool.required ?? [])].sort();
103
+ const properties = new Set(tool.properties ?? []);
104
+ const optional = (hints[tool.name] ?? []).filter((arg) => properties.has(arg) && !required.includes(arg));
105
+ const args = [...required, ...[...new Set(optional)].map((arg) => `${arg}?`)];
106
+ if (args.length === 0 && properties.size > 0)
107
+ return `${server}__${tool.name}`;
108
+ return `${server}__${tool.name}(${args.join(", ")})`;
109
+ }
110
+ /**
111
+ * Groups tools by their first `_` segment (the MCP server namespaces its tools
112
+ * that way: `market`, `strategy`, …), groups and names sorted by code unit so
113
+ * the order does not depend on the locale.
114
+ */
115
+ function groupByPrefix(tools) {
116
+ const groups = new Map();
117
+ for (const tool of tools) {
118
+ const cut = tool.name.indexOf("_");
119
+ const prefix = cut > 0 ? tool.name.slice(0, cut) : tool.name;
120
+ const list = groups.get(prefix) ?? [];
121
+ list.push(tool);
122
+ groups.set(prefix, list);
123
+ }
124
+ const byCodeUnit = (a, b) => (a < b ? -1 : a > b ? 1 : 0);
125
+ return [...groups.entries()]
126
+ .sort(([a], [b]) => byCodeUnit(a, b))
127
+ .map(([prefix, list]) => ({ prefix, tools: list.sort((a, b) => byCodeUnit(a.name, b.name)) }));
128
+ }
129
+ //# sourceMappingURL=crib-sheet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crib-sheet.js","sourceRoot":"","sources":["../../src/tool-surface/crib-sheet.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ import type { McpToolSummary } from "./crib-sheet.js";
2
+ /** OpenClaw `toolFilter` (`McpServerToolFilterConfig`): include then exclude, exact text or `*` globs. */
3
+ export interface McpToolFilter {
4
+ include?: string[];
5
+ exclude?: string[];
6
+ }
7
+ /** The parts of a gateway MCP server entry the lister needs. */
8
+ export interface GatewayMcpEntry {
9
+ url: string;
10
+ headers: Record<string, string>;
11
+ toolFilter?: McpToolFilter;
12
+ }
13
+ /**
14
+ * Reads `mcp.servers.<serverName>` from a whole OpenClaw config.
15
+ *
16
+ * @returns `null` when the entry is missing, `enabled: false`, has no http(s)
17
+ * `url`, or is not streamable HTTP. OpenClaw runs an entry with a `command`
18
+ * over stdio, and an http entry over SSE unless its canonical `transport`
19
+ * (trimmed, lowercased) is `streamable-http`, so an entry with no transport
20
+ * is SSE too (`openclaw-worktrees/v2026.10.10-beta.3/src/agents/mcp-transport-config.ts:115-138`,
21
+ * `src/config/mcp-config-normalize.ts:16-21`). This lister speaks only
22
+ * streamable HTTP. senpi-agent writes `transport: "streamable-http"`.
23
+ * Number and boolean header values are stringified, as OpenClaw's schema
24
+ * allows them. The `toolFilter` is returned for the caller to apply.
25
+ */
26
+ export declare function readGatewayMcpEntry(config: unknown, serverName?: string): GatewayMcpEntry | null;
27
+ /**
28
+ * OpenClaw's include-then-exclude policy on a bare MCP tool name
29
+ * (`isMcpToolAllowed`, `src/agents/mcp-tool-filter.ts:55-64`, same on 10.4 and 10.10).
30
+ */
31
+ export declare function isMcpToolAllowed(toolFilter: McpToolFilter | undefined, toolName: string): boolean;
32
+ /** The slice of an MCP client the lister uses (the SDK `Client`, or a test double). */
33
+ export interface McpListClient {
34
+ listTools(params?: {
35
+ cursor?: string;
36
+ }, options?: {
37
+ timeout?: number;
38
+ }): Promise<{
39
+ tools: Array<{
40
+ name: string;
41
+ inputSchema?: unknown;
42
+ }>;
43
+ nextCursor?: string;
44
+ }>;
45
+ close(): Promise<void>;
46
+ }
47
+ /** Options for {@link listMcpTools}. */
48
+ export interface ListMcpToolsOptions {
49
+ /** Deadline for the whole listing, connect included. */
50
+ timeoutMs: number;
51
+ /** Test seam: opens the client. Defaults to the SDK streamable-HTTP client. */
52
+ connect?: (entry: GatewayMcpEntry, timeoutMs: number) => Promise<McpListClient>;
53
+ }
54
+ /**
55
+ * Lists the entry's tools through `tools/list`, following `nextCursor`, then
56
+ * applies the entry's `toolFilter` and maps each tool to an
57
+ * {@link McpToolSummary}. The client is always closed. `SenpiClient` is not
58
+ * used: the crib must see the gateway's server entry, not the runtime's.
59
+ *
60
+ * @throws On a connect or page failure, a repeated cursor, too many pages, or
61
+ * when the whole listing outlives `timeoutMs`.
62
+ */
63
+ export declare function listMcpTools(entry: GatewayMcpEntry, opts: ListMcpToolsOptions): Promise<McpToolSummary[]>;
64
+ //# sourceMappingURL=mcp-tool-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-tool-source.d.ts","sourceRoot":"","sources":["../../src/tool-surface/mcp-tool-source.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,0GAA0G;AAC1G,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,gEAAgE;AAChE,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,UAAU,CAAC,EAAE,aAAa,CAAC;CAC5B;AAUD;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,SAAU,GAAG,eAAe,GAAG,IAAI,CA4BjG;AAwCD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,aAAa,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAMjG;AAED,uFAAuF;AACvF,MAAM,WAAW,aAAa;IAC5B,SAAS,CACP,MAAM,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,EAC5B,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAC7B,OAAO,CAAC;QAAE,KAAK,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,WAAW,CAAC,EAAE,OAAO,CAAA;SAAE,CAAC,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC3F,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,wCAAwC;AACxC,MAAM,WAAW,mBAAmB;IAClC,wDAAwD;IACxD,SAAS,EAAE,MAAM,CAAC;IAClB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;CACjF;AAuBD;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAAC,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CA+C/G"}
@@ -0,0 +1,189 @@
1
+ /**
2
+ * Where the crib's tool names come from: the gateway's own `mcp.servers.<name>`
3
+ * entry, not the runtime's `SENPI_MCP_URL` (R3). The crib lists tools from that
4
+ * entry's `url` with its `headers` and applies its `toolFilter` with
5
+ * OpenClaw's semantics, so it names exactly what the gateway's catalog holds,
6
+ * including under a per-profile URL or filter.
7
+ */
8
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
9
+ import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
10
+ function rec(value) {
11
+ return value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
12
+ }
13
+ function stringEntries(value) {
14
+ return Array.isArray(value) ? value.filter((v) => typeof v === "string") : [];
15
+ }
16
+ /**
17
+ * Reads `mcp.servers.<serverName>` from a whole OpenClaw config.
18
+ *
19
+ * @returns `null` when the entry is missing, `enabled: false`, has no http(s)
20
+ * `url`, or is not streamable HTTP. OpenClaw runs an entry with a `command`
21
+ * over stdio, and an http entry over SSE unless its canonical `transport`
22
+ * (trimmed, lowercased) is `streamable-http`, so an entry with no transport
23
+ * is SSE too (`openclaw-worktrees/v2026.10.10-beta.3/src/agents/mcp-transport-config.ts:115-138`,
24
+ * `src/config/mcp-config-normalize.ts:16-21`). This lister speaks only
25
+ * streamable HTTP. senpi-agent writes `transport: "streamable-http"`.
26
+ * Number and boolean header values are stringified, as OpenClaw's schema
27
+ * allows them. The `toolFilter` is returned for the caller to apply.
28
+ */
29
+ export function readGatewayMcpEntry(config, serverName = "senpi") {
30
+ const entry = rec(rec(rec(config)?.mcp)?.servers)?.[serverName];
31
+ const e = rec(entry);
32
+ if (!e || e.enabled === false)
33
+ return null;
34
+ if (typeof e.command === "string")
35
+ return null;
36
+ if (typeof e.transport !== "string" || e.transport.trim().toLowerCase() !== "streamable-http")
37
+ return null;
38
+ if (typeof e.url !== "string")
39
+ return null;
40
+ let parsed;
41
+ try {
42
+ parsed = new URL(e.url);
43
+ }
44
+ catch {
45
+ return null;
46
+ }
47
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:")
48
+ return null;
49
+ const headers = {};
50
+ for (const [key, value] of Object.entries(rec(e.headers) ?? {})) {
51
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean")
52
+ headers[key] = String(value);
53
+ }
54
+ const result = { url: e.url, headers };
55
+ const filter = rec(e.toolFilter);
56
+ if (filter) {
57
+ const include = stringEntries(filter.include);
58
+ const exclude = stringEntries(filter.exclude);
59
+ if (include.length > 0 || exclude.length > 0) {
60
+ result.toolFilter = { ...(include.length > 0 ? { include } : {}), ...(exclude.length > 0 ? { exclude } : {}) };
61
+ }
62
+ }
63
+ return result;
64
+ }
65
+ /**
66
+ * Line-for-line port of OpenClaw `matchesMcpToolFilterPattern`
67
+ * (`openclaw-worktrees/v2026.10.10-beta.3/src/agents/mcp-tool-filter.ts:6-38`).
68
+ */
69
+ function matchesMcpToolFilterPattern(pattern, value) {
70
+ const trimmed = pattern.trim();
71
+ if (!trimmed) {
72
+ return false;
73
+ }
74
+ if (!trimmed.includes("*")) {
75
+ return trimmed === value;
76
+ }
77
+ const parts = trimmed.split("*");
78
+ const first = parts[0] ?? "";
79
+ const last = parts.at(-1) ?? "";
80
+ if (first && !value.startsWith(first)) {
81
+ return false;
82
+ }
83
+ let cursor = first.length;
84
+ const endBound = last ? value.length - last.length : value.length;
85
+ if (last && (!value.endsWith(last) || endBound < cursor)) {
86
+ return false;
87
+ }
88
+ for (const part of parts.slice(1, -1)) {
89
+ if (!part) {
90
+ continue;
91
+ }
92
+ const index = value.indexOf(part, cursor);
93
+ if (index === -1 || index + part.length > endBound) {
94
+ return false;
95
+ }
96
+ cursor = index + part.length;
97
+ }
98
+ return true;
99
+ }
100
+ /**
101
+ * OpenClaw's include-then-exclude policy on a bare MCP tool name
102
+ * (`isMcpToolAllowed`, `src/agents/mcp-tool-filter.ts:55-64`, same on 10.4 and 10.10).
103
+ */
104
+ export function isMcpToolAllowed(toolFilter, toolName) {
105
+ const matches = (pattern) => matchesMcpToolFilterPattern(pattern, toolName);
106
+ return ((!toolFilter?.include?.length || toolFilter.include.some(matches)) &&
107
+ !toolFilter?.exclude?.some(matches));
108
+ }
109
+ /** Upper bound on pages, so a server that never ends its cursor chain cannot spin the refresh. */
110
+ const MAX_PAGES = 50;
111
+ async function connectSdkClient(entry) {
112
+ const transport = new StreamableHTTPClientTransport(new URL(entry.url), {
113
+ requestInit: { headers: entry.headers },
114
+ });
115
+ const client = new Client({ name: "senpi-runtime-tool-surface", version: "1.0.0" });
116
+ await client.connect(transport);
117
+ return client;
118
+ }
119
+ function toSummary(tool) {
120
+ const schema = rec(tool.inputSchema);
121
+ return {
122
+ name: tool.name,
123
+ required: [...new Set(stringEntries(schema?.required))].sort(),
124
+ properties: Object.keys(rec(schema?.properties) ?? {}).sort(),
125
+ };
126
+ }
127
+ /**
128
+ * Lists the entry's tools through `tools/list`, following `nextCursor`, then
129
+ * applies the entry's `toolFilter` and maps each tool to an
130
+ * {@link McpToolSummary}. The client is always closed. `SenpiClient` is not
131
+ * used: the crib must see the gateway's server entry, not the runtime's.
132
+ *
133
+ * @throws On a connect or page failure, a repeated cursor, too many pages, or
134
+ * when the whole listing outlives `timeoutMs`.
135
+ */
136
+ export async function listMcpTools(entry, opts) {
137
+ const deadline = Date.now() + opts.timeoutMs;
138
+ let timer;
139
+ let expired = false;
140
+ const timeout = new Promise((_, reject) => {
141
+ timer = setTimeout(() => {
142
+ expired = true;
143
+ reject(new Error(`tools/list timed out after ${opts.timeoutMs} ms`));
144
+ }, opts.timeoutMs);
145
+ timer.unref?.();
146
+ });
147
+ let client;
148
+ try {
149
+ const connect = opts.connect ?? ((e) => connectSdkClient(e));
150
+ const connecting = connect(entry, opts.timeoutMs);
151
+ // A connect that lands after the deadline still gets closed.
152
+ connecting.then((c) => {
153
+ if (expired)
154
+ void c.close().catch(() => undefined);
155
+ }, () => undefined);
156
+ client = await Promise.race([connecting, timeout]);
157
+ const out = [];
158
+ const seen = new Set();
159
+ let cursor;
160
+ for (let page = 0;; page += 1) {
161
+ if (page >= MAX_PAGES)
162
+ throw new Error(`tools/list returned more than ${MAX_PAGES} pages`);
163
+ const remaining = Math.max(1, deadline - Date.now());
164
+ const result = await Promise.race([
165
+ client.listTools(cursor === undefined ? undefined : { cursor }, { timeout: remaining }),
166
+ timeout,
167
+ ]);
168
+ for (const tool of result.tools ?? []) {
169
+ if (typeof tool?.name === "string" && isMcpToolAllowed(entry.toolFilter, tool.name))
170
+ out.push(toSummary(tool));
171
+ }
172
+ const next = typeof result.nextCursor === "string" && result.nextCursor.length > 0 ? result.nextCursor : undefined;
173
+ if (next === undefined)
174
+ break;
175
+ if (seen.has(next))
176
+ throw new Error(`tools/list repeated cursor ${JSON.stringify(next)}`);
177
+ seen.add(next);
178
+ cursor = next;
179
+ }
180
+ return out;
181
+ }
182
+ finally {
183
+ if (timer)
184
+ clearTimeout(timer);
185
+ if (client)
186
+ await client.close().catch(() => undefined);
187
+ }
188
+ }
189
+ //# sourceMappingURL=mcp-tool-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-tool-source.js","sourceRoot":"","sources":["../../src/tool-surface/mcp-tool-source.ts"],"names":[],"mappings":"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"}
@@ -81,6 +81,10 @@ export declare const EVENT_NAME: {
81
81
  readonly autoUpdateInstallFailed: "auto_update.install_failed";
82
82
  readonly autoUpdateRestartFailed: "auto_update.restart_failed";
83
83
  readonly autoUpdateDegraded: "auto_update.degraded";
84
+ readonly autoUpdateRestartRequested: "auto_update.restart_requested";
85
+ readonly autoUpdateApplyFailed: "auto_update.apply_failed";
86
+ readonly autoUpdateInstallResult: "auto_update.install_result";
87
+ readonly autoUpdateDeferred: "auto_update.deferred";
84
88
  readonly skillRouterDecision: "skill_router.decision";
85
89
  readonly skillRouterError: "skill_router.error";
86
90
  readonly skillsCheckCompleted: "skills.check_completed";
@@ -232,6 +236,10 @@ export interface EventAttributes {
232
236
  "auto_update.install_failed": AutoUpdateInstallFailedAttrs;
233
237
  "auto_update.restart_failed": AutoUpdateRestartFailedAttrs;
234
238
  "auto_update.degraded": AutoUpdateDegradedAttrs;
239
+ "auto_update.restart_requested": AutoUpdateRestartRequestedAttrs;
240
+ "auto_update.apply_failed": AutoUpdateApplyFailedAttrs;
241
+ "auto_update.install_result": AutoUpdateInstallResultAttrs;
242
+ "auto_update.deferred": AutoUpdateDeferredAttrs;
235
243
  "skill_router.decision": SkillRouterDecisionAttrs;
236
244
  "skill_router.error": SkillRouterErrorAttrs;
237
245
  "skills.check_completed": SkillsCheckCompletedAttrs;
@@ -759,20 +767,45 @@ export interface ToolCalledAttrs {
759
767
  "senpi.tool.outcome": string;
760
768
  /** Low-cardinality error class on an abnormal outcome (`errorTypeOf`, or `user_denied`/`approval_timeout` for a `denied` outcome). */
761
769
  "error.type"?: string;
770
+ /**
771
+ * `true` when the name is what the model asked an OpenClaw 10.x tool-search dispatcher for
772
+ * (`dispatch_action` / `tool_call` params `id`) and no inner call ran, e.g. `Unknown tool id`.
773
+ */
774
+ "senpi.tool.bridge"?: boolean;
762
775
  }
763
776
  /**
764
777
  * One MCP tool approval-gate decision — the audit trail of what the user chose and why. Fires on
765
- * EVERY terminal resolution: `allow-once` / `allow-always` (info) and `deny` / `timeout` (escalated
766
- * to warn). Complements `tool.called{denied}` (the execution-outcome plane): this is the
778
+ * EVERY terminal resolution: `allow-once` / `allow-always` (info) and `deny` / `timeout` /
779
+ * `cancelled` (escalated to warn). `cancelled` is a run abort with the prompt open, a host with no
780
+ * route or surface to ask (10.x), or the gate's own scheduled-turn block (`cancel_reason`). Complements `tool.called{denied}` (the execution-outcome plane): this is the
767
781
  * gate-decision plane, and the only place the approve path (`allow-once` vs `allow-always`) is
768
782
  * recorded — so allow-always adoption is queryable.
769
783
  */
770
784
  export interface ToolApprovalResolvedAttrs {
771
785
  "gen_ai.tool.name": string;
772
- /** `allow-once` | `allow-always` | `deny` | `timeout`. */
786
+ /** `allow-once` | `allow-always` | `deny` | `timeout` | `cancelled`. */
773
787
  "senpi.tool_approval.decision": string;
774
788
  /** `"true"` for a state-changing tool; `"false"` for a read gated only in `all` mode. */
775
789
  "senpi.tool.is_trade": string;
790
+ /**
791
+ * Milliseconds from the gate's `requireApproval` to the resolution; 0 when
792
+ * the gate cancelled the call itself. A no-route or no-surface `cancelled`
793
+ * lands within milliseconds, a user abort after the user's wait.
794
+ */
795
+ "senpi.tool_approval.wait_ms"?: number;
796
+ /** The turn's session key (the span convention for a session). Absent when the hook gave none. */
797
+ "gen_ai.conversation.id"?: string;
798
+ /**
799
+ * The turn's kind, from the run's host trigger: `chat` (trigger `user`),
800
+ * `cron`, `heartbeat`, `other` (`memory`, `manual`, `overflow`) or
801
+ * `unknown` (the run was not seen at prompt build).
802
+ */
803
+ "senpi.turn.kind"?: string;
804
+ /**
805
+ * Set when the runtime cancelled the call itself, before asking:
806
+ * `scheduled_turn` (a gated call in a cron or heartbeat turn on 10.x, D13).
807
+ */
808
+ "senpi.tool_approval.cancel_reason"?: string;
776
809
  }
777
810
  /**
778
811
  * The MCP tool approval gate's fail-open catch fired — a money-safety gate momentarily disengaged and
@@ -785,7 +818,7 @@ export interface ToolApprovalGateErrorAttrs {
785
818
  "error.type"?: string;
786
819
  }
787
820
  /**
788
- * Shared shape for the eight `auto_update.*` plugin self-update lifecycle events — one poll's version
821
+ * Shared shape for the twelve `auto_update.*` plugin self-update lifecycle events — one poll's version
789
822
  * check, the resulting notify/apply/restart transitions, and their failure modes. Fired by
790
823
  * {@link AutoUpdateCoordinator}, outside any signal/trading flow, so these carry no `senpi.strategy.*`
791
824
  * identity (the plugin process, not a strategy, is the subject). Free-text (a thrown error's message
@@ -807,11 +840,24 @@ export interface AutoUpdateAvailableAttrs {
807
840
  "senpi.auto_update.latest_version": string;
808
841
  "senpi.auto_update.update_type": string;
809
842
  }
810
- /** The package install succeeded and a gateway restart was requested. */
843
+ /**
844
+ * The update took effect. On an OpenClaw 5.x host this fires when the in-process install succeeded
845
+ * and the restart was requested (the historical meaning). On a 10.x host it fires on the first boot
846
+ * whose loaded version reaches the target, since nothing is installed until the wrapper consumes
847
+ * the marker; `restart_mode` is then `restart-to-apply`.
848
+ */
811
849
  export interface AutoUpdateAppliedAttrs {
812
850
  "senpi.auto_update.from_version": string;
813
851
  "senpi.auto_update.to_version": string;
814
852
  "senpi.auto_update.restart_mode": string;
853
+ /** 10.x only: ISO time the restart that applied the update was requested. */
854
+ "senpi.auto_update.requested_at"?: string;
855
+ /** 10.x only, when known: ISO time the target version was first seen in this pending episode. */
856
+ "senpi.auto_update.first_seen_at"?: string;
857
+ /** 10.x only: ms from the restart request to this boot's reconcile (stop + wrapper install + start). */
858
+ "senpi.auto_update.apply_ms"?: number;
859
+ /** 10.x only, when known: ms from first seen to this boot's reconcile (spread + idle wait + apply). */
860
+ "senpi.auto_update.pending_ms"?: number;
815
861
  }
816
862
  /** An already-applied version is still waiting on the gateway restart that was requested for it. */
817
863
  export interface AutoUpdateAwaitingRestartAttrs {
@@ -841,6 +887,72 @@ export interface AutoUpdateRestartFailedAttrs {
841
887
  export interface AutoUpdateDegradedAttrs {
842
888
  "senpi.auto_update.reason": string;
843
889
  }
890
+ /**
891
+ * OpenClaw 10.x only: the install marker for `to_version` was written and the gateway restart was
892
+ * requested through `mutateConfigFile`. The wrapper installs the version before the next gateway
893
+ * spawn; `auto_update.applied` follows on that boot.
894
+ */
895
+ export interface AutoUpdateRestartRequestedAttrs {
896
+ "senpi.auto_update.from_version": string;
897
+ "senpi.auto_update.to_version": string;
898
+ /** Always `restart-to-apply`. */
899
+ "senpi.auto_update.restart_mode": string;
900
+ /** True when the box was busy and the 24 h deferral cap forced the restart in the quiet window. */
901
+ "senpi.auto_update.forced": boolean;
902
+ /** Only when `forced`: the idle-gate blockers the forced restart overrode, sorted, comma-joined. */
903
+ "senpi.auto_update.blockers"?: string;
904
+ }
905
+ /**
906
+ * A requested update did not load: more than 30 min after the restart request (or with no request
907
+ * time on record) the loaded version is still below `to_version`. The awaiting-restart state is
908
+ * dropped and the next tick starts over, instead of trusting the persisted applied version forever.
909
+ */
910
+ export interface AutoUpdateApplyFailedAttrs {
911
+ "senpi.auto_update.to_version": string;
912
+ "senpi.auto_update.loaded_version": string;
913
+ }
914
+ /**
915
+ * OpenClaw 10.x only: one runtime install outcome the senpi-agent wrapper recorded in
916
+ * `senpi-state/runtime-update-results.json` (`install-results.ts`), reported by the gateway that
917
+ * starts next. Each attribute mirrors one entry field and is absent when the entry had none.
918
+ */
919
+ export interface AutoUpdateInstallResultAttrs {
920
+ /** `marker` (the install before a gateway spawn) or `floor` (the boot-time `SENPI_RUNTIME_MIN_VERSION` check). */
921
+ "senpi.auto_update.source"?: string;
922
+ /** `updated` | `failed` | `timeout` | `not-newer` | `invalid` | `lease-skip` | `still-below`. */
923
+ "senpi.auto_update.outcome": string;
924
+ /** The npm spec the wrapper installed or refused to install. */
925
+ "senpi.auto_update.spec"?: string;
926
+ /** Installed version before the step. */
927
+ "senpi.auto_update.from_version"?: string;
928
+ /** Installed version read back after the install. */
929
+ "senpi.auto_update.to_version"?: string;
930
+ /** The marker's target version, or the floor minimum. */
931
+ "senpi.auto_update.target_version"?: string;
932
+ /** Run time of the `openclaw plugins update` CLI call; absent when none ran. */
933
+ "senpi.auto_update.duration_ms"?: number;
934
+ /** Why the step did not update: the first line, at most 300 chars. Absent on success. */
935
+ "senpi.auto_update.reason"?: string;
936
+ /** ISO time the wrapper's step ended (the entry's `at`). */
937
+ "senpi.auto_update.ended_at"?: string;
938
+ /** The entry id, the de-duplication key. */
939
+ "senpi.auto_update.result_id"?: string;
940
+ /** OpenClaw version of the image the wrapper ran. */
941
+ "senpi.auto_update.openclaw_version"?: string;
942
+ }
943
+ /**
944
+ * OpenClaw 10.x only: a newer version is waiting (`pending-idle:<v>`). Fired when the box enters
945
+ * the wait and again only when the target or the blocker set changes, not on every re-check.
946
+ */
947
+ export interface AutoUpdateDeferredAttrs {
948
+ "senpi.auto_update.to_version": string;
949
+ /** Sorted, comma-joined: `spread` (waiting for `eligible_at`), else the idle-gate blockers. */
950
+ "senpi.auto_update.blockers": string;
951
+ /** ISO time the box may first apply (first seen + spread offset + jitter). */
952
+ "senpi.auto_update.eligible_at"?: string;
953
+ /** ISO time the version was first seen in this pending episode. */
954
+ "senpi.auto_update.first_seen_at"?: string;
955
+ }
844
956
  /**
845
957
  * What the skill router did with one eligible user turn (`skill_router.decision.outcome`):
846
958
  * - `classified`: the endpoint answered; `injected` says whether a pointer went in.