@lobu/worker 3.3.0 → 3.4.1

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.
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ /**
3
+ * Detects and redacts "sandbox leaks" — cases where the agent presents a
4
+ * local workspace path (or a Claude `sandbox://` URL) as if it were a
5
+ * user-downloadable artifact, without having actually called
6
+ * `UploadUserFile`.
7
+ *
8
+ * Key design decision: we only flag **structural** delivery claims, not
9
+ * free-text mentions. An agent that *describes* workspace paths in a probe
10
+ * or ls-style answer is legitimate; an agent that hands the path to the
11
+ * user as a clickable link or file URL is not. This eliminates the false
12
+ * positives that the previous broad substring check produced.
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.checkSandboxLeak = checkSandboxLeak;
16
+ /**
17
+ * Matches Claude's `sandbox://` file-reference scheme. Any occurrence of
18
+ * this is unambiguously a delivery claim — the scheme exists for exactly
19
+ * that purpose.
20
+ */
21
+ const SANDBOX_URL_RE = /\bsandbox:\/{1,2}[^\s)\]}'"<>]+/gi;
22
+ /**
23
+ * Matches a markdown link target pointing at a local workspace path, e.g.
24
+ * `[report](/app/workspaces/foo/bar.pdf)` or `[x](file:///workspace/y)`.
25
+ * The capture group is the URL/path portion so we can rewrite it.
26
+ */
27
+ const LOCAL_MD_LINK_RE = /\]\(\s*((?:file:\/\/)?(?:\/app\/workspaces\/|\/workspace\/)[^\s)]+)\s*\)/gi;
28
+ /**
29
+ * Matches HTML `href`/`src` pointing at a local workspace path. Capture
30
+ * group 1 is the attribute name (`href` or `src`) so we can preserve it on
31
+ * redact; capture group 2 is the URL target.
32
+ */
33
+ const LOCAL_HREF_RE = /\b(href|src)\s*=\s*["']((?:file:\/\/)?(?:\/app\/workspaces\/|\/workspace\/)[^"']+)["']/gi;
34
+ /**
35
+ * Inspect the agent's final user-facing message for unfulfilled file-delivery
36
+ * claims. If `sawUploadedFileEvent` is true (the agent actually called
37
+ * UploadUserFile during this turn), no check is performed — the agent did
38
+ * deliver something, and any remaining path references are assumed
39
+ * descriptive.
40
+ */
41
+ function checkSandboxLeak(finalText, sawUploadedFileEvent) {
42
+ if (sawUploadedFileEvent || !finalText) {
43
+ return { leaked: false, redactedText: finalText };
44
+ }
45
+ const hasSandboxUrl = SANDBOX_URL_RE.test(finalText);
46
+ const hasMdLink = LOCAL_MD_LINK_RE.test(finalText);
47
+ const hasHref = LOCAL_HREF_RE.test(finalText);
48
+ // Reset lastIndex — `test()` on /g regexes advances state.
49
+ SANDBOX_URL_RE.lastIndex = 0;
50
+ LOCAL_MD_LINK_RE.lastIndex = 0;
51
+ LOCAL_HREF_RE.lastIndex = 0;
52
+ if (!hasSandboxUrl && !hasMdLink && !hasHref) {
53
+ return { leaked: false, redactedText: finalText };
54
+ }
55
+ // Redact: neutralise the link targets so the user doesn't see a broken
56
+ // "clickable" path, but keep the surrounding prose intact.
57
+ let redacted = finalText;
58
+ redacted = redacted.replace(SANDBOX_URL_RE, "[local file, not uploaded]");
59
+ redacted = redacted.replace(LOCAL_MD_LINK_RE, "](about:blank)");
60
+ redacted = redacted.replace(LOCAL_HREF_RE, (_match, attr) => `${attr}="about:blank"`);
61
+ const note = "\n\n_Note: I referenced a local file but did not actually upload it. " +
62
+ "Ask me to retry and I will use `UploadUserFile` to deliver it._";
63
+ return { leaked: true, redactedText: `${redacted}${note}` };
64
+ }
65
+ //# sourceMappingURL=sandbox-leak.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox-leak.js","sourceRoot":"","sources":["../../src/openclaw/sandbox-leak.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;AAwCH,4CAoCC;AA1ED;;;;GAIG;AACH,MAAM,cAAc,GAAG,mCAAmC,CAAC;AAE3D;;;;GAIG;AACH,MAAM,gBAAgB,GACpB,4EAA4E,CAAC;AAE/E;;;;GAIG;AACH,MAAM,aAAa,GACjB,0FAA0F,CAAC;AAU7F;;;;;;GAMG;AACH,SAAgB,gBAAgB,CAC9B,SAAiB,EACjB,oBAA6B;IAE7B,IAAI,oBAAoB,IAAI,CAAC,SAAS,EAAE,CAAC;QACvC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC;IACpD,CAAC;IAED,MAAM,aAAa,GAAG,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACrD,MAAM,SAAS,GAAG,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACnD,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAE9C,2DAA2D;IAC3D,cAAc,CAAC,SAAS,GAAG,CAAC,CAAC;IAC7B,gBAAgB,CAAC,SAAS,GAAG,CAAC,CAAC;IAC/B,aAAa,CAAC,SAAS,GAAG,CAAC,CAAC;IAE5B,IAAI,CAAC,aAAa,IAAI,CAAC,SAAS,IAAI,CAAC,OAAO,EAAE,CAAC;QAC7C,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC;IACpD,CAAC;IAED,uEAAuE;IACvE,2DAA2D;IAC3D,IAAI,QAAQ,GAAG,SAAS,CAAC;IACzB,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,cAAc,EAAE,4BAA4B,CAAC,CAAC;IAC1E,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,CAAC;IAChE,QAAQ,GAAG,QAAQ,CAAC,OAAO,CACzB,aAAa,EACb,CAAC,MAAM,EAAE,IAAY,EAAE,EAAE,CAAC,GAAG,IAAI,gBAAgB,CAClD,CAAC;IAEF,MAAM,IAAI,GACR,uEAAuE;QACvE,iEAAiE,CAAC;IAEpE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,QAAQ,GAAG,IAAI,EAAE,EAAE,CAAC;AAC9D,CAAC"}
@@ -1,12 +1,4 @@
1
- import { type ConfigProviderMeta, type McpToolDef } from "@lobu/core";
2
- interface McpStatus {
3
- id: string;
4
- name: string;
5
- requiresAuth: boolean;
6
- requiresInput: boolean;
7
- authenticated: boolean;
8
- configured: boolean;
9
- }
1
+ import { type ConfigProviderMeta, type McpStatus, type McpToolDef } from "@lobu/core";
10
2
  export interface ProviderConfig {
11
3
  credentialEnvVarName?: string;
12
4
  defaultProvider?: string;
@@ -41,7 +33,18 @@ export declare function invalidateSessionContextCache(): void;
41
33
  * Caches the result until invalidated by a config_changed SSE event.
42
34
  * Skips MCP server config (OpenClaw doesn't use Claude SDK's MCP format).
43
35
  */
44
- export declare function getOpenClawSessionContext(): Promise<{
36
+ export declare function getOpenClawSessionContext(opts?: {
37
+ mcpExposure?: "tools" | "cli";
38
+ }): Promise<{
39
+ /**
40
+ * Identity/soul/user instructions for this agent. Returned separately from
41
+ * `gatewayInstructions` so the worker can prepend identity BEFORE the
42
+ * pi-coding-agent base prompt (which would otherwise anchor the model with
43
+ * "You are an expert coding assistant" before the agent's real persona is
44
+ * declared).
45
+ */
46
+ agentInstructions: string;
47
+ /** Platform / network / skills / MCP setup instructions (no identity). */
45
48
  gatewayInstructions: string;
46
49
  providerConfig: ProviderConfig;
47
50
  skillsConfig: SkillContent[];
@@ -1 +1 @@
1
- {"version":3,"file":"session-context.d.ts","sourceRoot":"","sources":["../../src/openclaw/session-context.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,kBAAkB,EAEvB,KAAK,UAAU,EAChB,MAAM,YAAY,CAAC;AAKpB,UAAU,SAAS;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,OAAO,CAAC;IACtB,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;IACvB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,KAAK,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAChB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC,CAAC;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjD,6DAA6D;IAC7D,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IACrD,wFAAwF;IACxF,sBAAsB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjD;AAED,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAqCD;;;GAGG;AACH,wBAAgB,6BAA6B,IAAI,IAAI,CAGpD;AAiED;;;;;GAKG;AACH,wBAAsB,yBAAyB,IAAI,OAAO,CAAC;IACzD,mBAAmB,EAAE,MAAM,CAAC;IAC5B,cAAc,EAAE,cAAc,CAAC;IAC/B,YAAY,EAAE,YAAY,EAAE,CAAC;IAC7B,SAAS,EAAE,SAAS,EAAE,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;IACvC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC,CAAC,CAoGD"}
1
+ {"version":3,"file":"session-context.d.ts","sourceRoot":"","sources":["../../src/openclaw/session-context.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,kBAAkB,EAEvB,KAAK,SAAS,EACd,KAAK,UAAU,EAChB,MAAM,YAAY,CAAC;AAKpB,MAAM,WAAW,cAAc;IAC7B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,KAAK,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAChB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC,CAAC;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjD,6DAA6D;IAC7D,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IACrD,wFAAwF;IACxF,sBAAsB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjD;AAED,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAwCD;;;GAGG;AACH,wBAAgB,6BAA6B,IAAI,IAAI,CAGpD;AAqGD;;;;;GAKG;AACH,wBAAsB,yBAAyB,CAC7C,IAAI,GAAE;IAAE,WAAW,CAAC,EAAE,OAAO,GAAG,KAAK,CAAA;CAAO,GAC3C,OAAO,CAAC;IACT;;;;;;OAMG;IACH,iBAAiB,EAAE,MAAM,CAAC;IAC1B,0EAA0E;IAC1E,mBAAmB,EAAE,MAAM,CAAC;IAC5B,cAAc,EAAE,cAAc,CAAC;IAC/B,YAAY,EAAE,YAAY,EAAE,CAAC;IAC7B,SAAS,EAAE,SAAS,EAAE,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;IACvC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC,CAAC,CAkHD"}
@@ -7,6 +7,7 @@ const url_utils_1 = require("../core/url-utils");
7
7
  const logger = (0, core_1.createLogger)("openclaw-session-context");
8
8
  const CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes
9
9
  const DEFAULT_SESSION_CONTEXT = {
10
+ agentInstructions: "",
10
11
  gatewayInstructions: "",
11
12
  providerConfig: {},
12
13
  skillsConfig: [],
@@ -24,7 +25,7 @@ function invalidateSessionContextCache() {
24
25
  cachedResult = null;
25
26
  logger.info("Session context cache invalidated");
26
27
  }
27
- function buildMcpInstructions(mcpStatus, mcpToolIds) {
28
+ function buildMcpInstructions(mcpStatus, mcpToolIds, mcpExposure = "tools") {
28
29
  if (!mcpStatus || mcpStatus.length === 0) {
29
30
  return "";
30
31
  }
@@ -38,7 +39,13 @@ function buildMcpInstructions(mcpStatus, mcpToolIds) {
38
39
  }
39
40
  const lines = ["## MCP Tools Requiring Setup"];
40
41
  for (const mcp of needsAuthentication) {
41
- lines.push(`- ⚠️ **${mcp.name}** (id: ${mcp.id}): Authentication is required. Call \`${mcp.id}_login\` to start login. After the user completes login, call \`${mcp.id}_login_check\`. Newly available MCP tools will refresh on the next message.`);
42
+ const loginCmd = mcpExposure === "cli"
43
+ ? `run \`${mcp.id} auth login\` in Bash`
44
+ : `call \`${mcp.id}_login\``;
45
+ const checkCmd = mcpExposure === "cli"
46
+ ? `run \`${mcp.id} auth check\``
47
+ : `call \`${mcp.id}_login_check\``;
48
+ lines.push(`- ⚠️ **${mcp.name}** (id: ${mcp.id}): Authentication is required. To start login, ${loginCmd}. After the user completes login, ${checkCmd}. Newly available MCP tools will refresh on the next message.`);
42
49
  }
43
50
  for (const mcp of needsConfiguration) {
44
51
  lines.push(`- ⚠️ **${mcp.name}** (id: ${mcp.id}): Additional MCP input is required before this server can be used. Tell the user an admin must configure the MCP inputs in settings.`);
@@ -51,6 +58,33 @@ function buildMcpInstructions(mcpStatus, mcpToolIds) {
51
58
  }
52
59
  return lines.join("\n");
53
60
  }
61
+ /**
62
+ * CLI-mode header introducing the `<server> <tool>` idiom. Appended to gateway
63
+ * instructions when `mcpExposure === "cli"` so the model understands how to
64
+ * invoke MCP tools through bash instead of as first-class function calls.
65
+ */
66
+ function buildMcpCliInstructions(mcpStatus) {
67
+ if (!mcpStatus || mcpStatus.length === 0)
68
+ return "";
69
+ const servers = mcpStatus.map((m) => `- \`${m.id}\` — ${m.name}`).join("\n");
70
+ return `## Available MCP CLIs
71
+
72
+ MCP servers are exposed as Bash commands. One command per server. Invoke tools by piping JSON on stdin:
73
+
74
+ \`\`\`bash
75
+ <server> <tool> <<'EOF'
76
+ { ...json args... }
77
+ EOF
78
+ \`\`\`
79
+
80
+ Discovery:
81
+ - \`<server> --help\` — list a server's tools
82
+ - \`<server> <tool> --schema\` — print the JSON Schema for a tool
83
+ - \`<server> auth login|check|logout\` — manage OAuth where required
84
+
85
+ Servers:
86
+ ${servers}`;
87
+ }
54
88
  function buildMcpServerInstructions(mcpInstructions) {
55
89
  const entries = Object.entries(mcpInstructions).filter(([, v]) => v);
56
90
  if (entries.length === 0)
@@ -67,8 +101,11 @@ function buildMcpServerInstructions(mcpInstructions) {
67
101
  * Caches the result until invalidated by a config_changed SSE event.
68
102
  * Skips MCP server config (OpenClaw doesn't use Claude SDK's MCP format).
69
103
  */
70
- async function getOpenClawSessionContext() {
71
- if (cachedResult && Date.now() - cachedResult.cachedAt < CACHE_TTL_MS) {
104
+ async function getOpenClawSessionContext(opts = {}) {
105
+ const mcpExposure = opts.mcpExposure ?? "tools";
106
+ if (cachedResult &&
107
+ cachedResult.mcpExposure === mcpExposure &&
108
+ Date.now() - cachedResult.cachedAt < CACHE_TTL_MS) {
72
109
  logger.debug("Returning cached session context");
73
110
  return cachedResult;
74
111
  }
@@ -94,25 +131,30 @@ async function getOpenClawSessionContext() {
94
131
  const data = (await response.json());
95
132
  logger.info(`Received session context: ${data.platformInstructions.length} chars platform instructions, ${data.mcpStatus.length} MCP status entries, provider: ${data.providerConfig?.defaultProvider || "none"}, cliBackends: ${data.providerConfig?.cliBackends?.map((b) => b.name).join(", ") || "none"}`);
96
133
  const toolMcpIds = new Set(Object.keys(data.mcpTools || {}));
97
- const mcpSetupInstructions = buildMcpInstructions(data.mcpStatus, toolMcpIds);
134
+ const mcpSetupInstructions = buildMcpInstructions(data.mcpStatus, toolMcpIds, mcpExposure);
98
135
  // Include MCP server instructions for all servers (with or without tools).
99
136
  // These provide workspace context (available connectors, entity schemas, etc.)
100
137
  // that helps the agent use the tools effectively.
101
138
  const mcpServerInstructions = buildMcpServerInstructions(data.mcpInstructions || {});
139
+ const mcpCliInstructions = mcpExposure === "cli" ? buildMcpCliInstructions(data.mcpStatus) : "";
140
+ // Identity/soul/user instructions are returned separately so the worker
141
+ // can prepend them BEFORE the pi-coding-agent base prompt.
142
+ const agentInstructions = data.agentInstructions || "";
102
143
  const gatewayInstructions = [
103
- data.agentInstructions,
104
144
  data.platformInstructions,
105
145
  data.networkInstructions,
106
146
  data.skillsInstructions,
147
+ mcpCliInstructions,
107
148
  mcpSetupInstructions,
108
149
  mcpServerInstructions,
109
150
  ]
110
151
  .filter(Boolean)
111
152
  .join("\n\n");
112
153
  const mcpTools = data.mcpTools || {};
113
- logger.info(`Built gateway instructions: agent (${(data.agentInstructions || "").length} chars) + platform (${data.platformInstructions.length} chars) + network (${data.networkInstructions.length} chars) + skills (${(data.skillsInstructions || "").length} chars) + MCP setup (${mcpSetupInstructions.length} chars) + MCP server instructions (${mcpServerInstructions.length} chars), mcpTools: ${Object.keys(mcpTools).length} servers`);
154
+ logger.info(`Built gateway instructions: agent (${agentInstructions.length} chars, prepended) + platform (${data.platformInstructions.length} chars) + network (${data.networkInstructions.length} chars) + skills (${(data.skillsInstructions || "").length} chars) + MCP setup (${mcpSetupInstructions.length} chars) + MCP server instructions (${mcpServerInstructions.length} chars), mcpTools: ${Object.keys(mcpTools).length} servers`);
114
155
  const mcpContext = data.mcpContext || {};
115
156
  const result = {
157
+ agentInstructions,
116
158
  gatewayInstructions,
117
159
  providerConfig: data.providerConfig || {},
118
160
  skillsConfig: data.skillsConfig || [],
@@ -124,7 +166,7 @@ async function getOpenClawSessionContext() {
124
166
  // transient upstream failure that should be retried on the next message.
125
167
  const hasEmptyAuthenticatedMcp = data.mcpStatus.some((mcp) => mcp.authenticated && !toolMcpIds.has(mcp.id));
126
168
  if (!hasEmptyAuthenticatedMcp) {
127
- cachedResult = { ...result, cachedAt: Date.now() };
169
+ cachedResult = { ...result, mcpExposure, cachedAt: Date.now() };
128
170
  }
129
171
  else {
130
172
  logger.warn("Skipping session context cache — authenticated MCP(s) returned no tools", {
@@ -1 +1 @@
1
- {"version":3,"file":"session-context.js","sourceRoot":"","sources":["../../src/openclaw/session-context.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session-context.js","sourceRoot":"","sources":["../../src/openclaw/session-context.ts"],"names":[],"mappings":"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"}
@@ -7,6 +7,7 @@ interface ResolvedMemoryFlushConfig {
7
7
  systemPrompt: string;
8
8
  prompt: string;
9
9
  }
10
+ export declare function replaceBasePromptIdentity(basePrompt: string, identity: string): string;
10
11
  export declare function estimatePromptTokenCost(promptText: string, imageCount: number): number;
11
12
  export declare function resolveMemoryFlushConfig(rawOptions: Record<string, unknown>): ResolvedMemoryFlushConfig;
12
13
  export declare class OpenClawWorker implements WorkerExecutor {
@@ -1 +1 @@
1
- {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../src/openclaw/worker.ts"],"names":[],"mappings":";AAMA,OAAO,EAIL,KAAK,eAAe,EACrB,MAAM,YAAY,CAAC;AAWpB,OAAO,KAAK,EAGV,YAAY,EACZ,cAAc,EACf,MAAM,eAAe,CAAC;AAkDvB,UAAU,yBAAyB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AAoID,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GACjB,MAAM,CAIR;AAED,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAClC,yBAAyB,CA2B3B;AAED,qBAAa,cAAe,YAAW,cAAc;IACnD,OAAO,CAAC,gBAAgB,CAAmB;IACpC,eAAe,EAAE,eAAe,CAAC;IACxC,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,iBAAiB,CAA4B;gBAEzC,MAAM,EAAE,YAAY;IAmChC;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAyRxB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAS9B,kBAAkB,IAAI,eAAe,GAAG,IAAI;IAI5C,OAAO,CAAC,mBAAmB;YAIb,gCAAgC;YAqFhC,YAAY;YAk4BZ,kBAAkB;YAwBlB,kBAAkB;IAgEhC,OAAO,KAAK,aAAa,GAMxB;IAED,OAAO,CAAC,MAAM,CAAC,OAAO;IAItB,OAAO,CAAC,qBAAqB;IAiE7B,2EAA2E;IAC3E,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAoB;YAE7C,oBAAoB;YAgDpB,yBAAyB;YAkBzB,oCAAoC;CAiCnD"}
1
+ {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../src/openclaw/worker.ts"],"names":[],"mappings":";AAMA,OAAO,EAIL,KAAK,eAAe,EACrB,MAAM,YAAY,CAAC;AAWpB,OAAO,KAAK,EAGV,YAAY,EACZ,cAAc,EACf,MAAM,eAAe,CAAC;AAmDvB,UAAU,yBAAyB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AAiCD,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,MAAM,CAOR;AAsHD,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GACjB,MAAM,CAIR;AAED,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAClC,yBAAyB,CA2B3B;AAED,qBAAa,cAAe,YAAW,cAAc;IACnD,OAAO,CAAC,gBAAgB,CAAmB;IACpC,eAAe,EAAE,eAAe,CAAC;IACxC,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,iBAAiB,CAA4B;gBAEzC,MAAM,EAAE,YAAY;IAmChC;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAmRxB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAS9B,kBAAkB,IAAI,eAAe,GAAG,IAAI;IAI5C,OAAO,CAAC,mBAAmB;YAIb,gCAAgC;YAqFhC,YAAY;YAq9BZ,kBAAkB;YAwBlB,kBAAkB;IAmEhC,OAAO,KAAK,aAAa,GAOxB;IAED,OAAO,CAAC,MAAM,CAAC,OAAO;IAItB,OAAO,CAAC,qBAAqB;IAiE7B,2EAA2E;IAC3E,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAoB;YAE7C,oBAAoB;YAgDpB,yBAAyB;YAkBzB,oCAAoC;CAiCnD"}
@@ -35,6 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  })();
36
36
  Object.defineProperty(exports, "__esModule", { value: true });
37
37
  exports.OpenClawWorker = void 0;
38
+ exports.replaceBasePromptIdentity = replaceBasePromptIdentity;
38
39
  exports.estimatePromptTokenCost = estimatePromptTokenCost;
39
40
  exports.resolveMemoryFlushConfig = resolveMemoryFlushConfig;
40
41
  const fs = __importStar(require("node:fs/promises"));
@@ -57,6 +58,7 @@ const tool_implementations_1 = require("../shared/tool-implementations");
57
58
  const custom_tools_1 = require("./custom-tools");
58
59
  const instructions_1 = require("./instructions");
59
60
  const model_resolver_1 = require("./model-resolver");
61
+ const sandbox_leak_1 = require("./sandbox-leak");
60
62
  const plugin_loader_1 = require("./plugin-loader");
61
63
  const processor_1 = require("./processor");
62
64
  const session_context_1 = require("./session-context");
@@ -71,6 +73,29 @@ const DEFAULT_MEMORY_FLUSH_CONFIG = {
71
73
  systemPrompt: "Session nearing compaction. Store durable memories now.",
72
74
  prompt: "Write any lasting notes to memory using available memory tools. Reply with NO_REPLY if nothing to store.",
73
75
  };
76
+ /**
77
+ * Pi-coding-agent's buildSystemPrompt() (in `@mariozechner/pi-coding-agent`)
78
+ * always opens the system prompt with this exact sentence. Lobu agents can
79
+ * override their identity via IDENTITY.md, but unless we strip out this
80
+ * opener the model sees two competing role declarations and tends to favour
81
+ * "expert coding assistant" because it appears first.
82
+ *
83
+ * This helper substitutes the opener with the agent's identity and keeps the
84
+ * rest of the base prompt (tools list, guidelines, docs paths, cwd) intact.
85
+ *
86
+ * If the upstream package ever changes the opener wording, this becomes a
87
+ * no-op and `replaced === original`. In that case we fall back to prepending
88
+ * the identity with a small framing note so identity still wins ordering.
89
+ */
90
+ const PI_CODING_AGENT_OPENER_RE = /^You are an expert coding assistant operating inside pi, a coding agent harness\.[^\n]*/;
91
+ function replaceBasePromptIdentity(basePrompt, identity) {
92
+ if (PI_CODING_AGENT_OPENER_RE.test(basePrompt)) {
93
+ return basePrompt.replace(PI_CODING_AGENT_OPENER_RE, identity);
94
+ }
95
+ // Upstream wording drifted — prepend identity with a framing note rather
96
+ // than silently letting the upstream opener win.
97
+ return `${identity}\n\nThe section below describes the runtime tooling available to you. It does not change your role.\n\n${basePrompt}`;
98
+ }
74
99
  function isLikelyImageGenerationRequest(prompt) {
75
100
  const lower = prompt.toLowerCase();
76
101
  const explicitToolInstruction = lower.includes("generateimage tool") || lower.includes("use generateimage");
@@ -364,22 +389,20 @@ class OpenClawWorker {
364
389
  const audioPermissionHint = hintGatewayUrl && hintWorkerToken
365
390
  ? await this.maybeBuildAudioPermissionHintMessage(outputSnapshot, hintGatewayUrl, hintWorkerToken)
366
391
  : null;
367
- const leakedSandboxLink = !sawUploadedFileEvent &&
368
- /(sandbox:\/|\/app\/workspaces\/|\/workspace\/)/i.test(outputSnapshot);
369
- const fileDeliveryFailureMessage = leakedSandboxLink
370
- ? "I created a local file, but I did not actually upload it for you. Local sandbox/workspace links are not user-accessible, so this file-delivery attempt failed. Please ask me to try again and I must use UploadUserFile."
371
- : null;
372
392
  const finalResult = this.progressProcessor.getFinalResult();
373
- if (fileDeliveryFailureMessage) {
374
- logger.warn("Detected sandbox/local file link without UploadUserFile success; replacing final response");
375
- await this.workerTransport.sendStreamDelta(fileDeliveryFailureMessage, true, true);
376
- }
377
- else if (finalResult) {
393
+ if (finalResult) {
394
+ const leakCheck = (0, sandbox_leak_1.checkSandboxLeak)(finalResult.text, sawUploadedFileEvent);
395
+ if (leakCheck.leaked) {
396
+ logger.warn("Detected unfulfilled file-delivery claim in final message; redacting link targets");
397
+ }
378
398
  const finalText = audioPermissionHint
379
- ? `${finalResult.text}\n\n${audioPermissionHint}`
380
- : finalResult.text;
399
+ ? `${leakCheck.redactedText}\n\n${audioPermissionHint}`
400
+ : leakCheck.redactedText;
381
401
  logger.info(`📤 Sending final result (${finalText.length} chars) with deduplication flag`);
382
- await this.workerTransport.sendStreamDelta(finalText, false, finalResult.isFinal);
402
+ // When a leak was redacted, the already-streamed content contains the
403
+ // pre-redaction URLs — a delta-append would leave them on the client.
404
+ // Force a full replacement so the client discards the leaky prefix.
405
+ await this.workerTransport.sendStreamDelta(finalText, leakCheck.leaked, finalResult.isFinal);
383
406
  }
384
407
  else if (audioPermissionHint) {
385
408
  logger.info("📤 Sending audio permission settings hint to user");
@@ -489,9 +512,23 @@ class OpenClawWorker {
489
512
  const verboseLogging = rawOptions.verboseLogging === true;
490
513
  const memoryFlushConfig = resolveMemoryFlushConfig(rawOptions);
491
514
  this.progressProcessor.setVerboseLogging(verboseLogging);
515
+ // Resolve how MCP tools should be exposed to the agent. In embedded mode,
516
+ // operators can swap the many first-class MCP tools for a small set of
517
+ // per-server just-bash CLIs (keeps the tool list lean).
518
+ const configuredMcpExposure = rawOptions.toolsConfig?.mcpExposure;
519
+ const envMcpExposure = process.env.LOBU_MCP_EXPOSURE;
520
+ const requestedMcpExposure = configuredMcpExposure === "cli" || envMcpExposure === "cli"
521
+ ? "cli"
522
+ : "tools";
523
+ const isEmbedded = process.env.DEPLOYMENT_MODE === "embedded";
524
+ if (requestedMcpExposure === "cli" && !isEmbedded) {
525
+ logger.warn("mcpExposure='cli' requested but DEPLOYMENT_MODE is not 'embedded' — falling back to 'tools'.");
526
+ }
527
+ const mcpExposure = requestedMcpExposure === "cli" && isEmbedded ? "cli" : "tools";
492
528
  // Fetch session context BEFORE model resolution so AGENT_DEFAULT_PROVIDER
493
- // is available when resolveModelRef() needs a fallback provider.
494
- const context = await (0, session_context_1.getOpenClawSessionContext)();
529
+ // is available when resolveModelRef() needs a fallback provider. Pass
530
+ // `mcpExposure` so MCP setup instructions use the right call syntax.
531
+ const context = await (0, session_context_1.getOpenClawSessionContext)({ mcpExposure });
495
532
  // Sync enabled skills to workspace filesystem so the agent can `cat` them.
496
533
  // Remove stale skill directories to avoid serving removed/disabled skills.
497
534
  const skillsWorkspaceDir = this.getWorkingDirectory();
@@ -662,10 +699,49 @@ class OpenClawWorker {
662
699
  allowedTools: rawOptions.allowedTools,
663
700
  disallowedTools: rawOptions.disallowedTools,
664
701
  });
702
+ // Build a mutable snapshot of MCP runtime state. The embedded CLI handlers
703
+ // read through `mcpRuntimeRef.current` so that `auth check` / `logout` can
704
+ // swap in refreshed tools/state without rebuilding Bash. `refresh()` re-
705
+ // fetches session context — `checkMcpLogin`/`logoutMcp` already invalidate
706
+ // the gateway cache, so the next fetch reaches the gateway.
707
+ const mcpRuntimeRef = {
708
+ current: {
709
+ mcpTools: context.mcpTools,
710
+ mcpStatus: context.mcpStatus,
711
+ mcpContext: context.mcpContext,
712
+ },
713
+ ...(mcpExposure === "cli" && {
714
+ refresh: async () => {
715
+ try {
716
+ const fresh = await (0, session_context_1.getOpenClawSessionContext)({ mcpExposure });
717
+ return {
718
+ mcpTools: fresh.mcpTools,
719
+ mcpStatus: fresh.mcpStatus,
720
+ mcpContext: fresh.mcpContext,
721
+ };
722
+ }
723
+ catch (err) {
724
+ logger.warn(`Failed to refresh MCP session context after auth: ${err instanceof Error ? err.message : String(err)}`);
725
+ return null;
726
+ }
727
+ },
728
+ }),
729
+ };
730
+ const gwParams = {
731
+ gatewayUrl: process.env.DISPATCHER_URL ?? "",
732
+ workerToken: process.env.WORKER_TOKEN ?? "",
733
+ channelId: this.config.channelId,
734
+ conversationId: this.config.conversationId,
735
+ platform: this.config.platform,
736
+ };
665
737
  let embeddedBashOps;
666
- if (process.env.DEPLOYMENT_MODE === "embedded") {
738
+ if (isEmbedded) {
667
739
  const { createEmbeddedBashOps } = await Promise.resolve().then(() => __importStar(require("../embedded/just-bash-bootstrap")));
668
- embeddedBashOps = await createEmbeddedBashOps();
740
+ embeddedBashOps = await createEmbeddedBashOps({
741
+ mcpRuntimeRef,
742
+ gw: gwParams,
743
+ mcpExposure,
744
+ });
669
745
  }
670
746
  let tools = (0, tools_1.createOpenClawTools)(workspaceDir, {
671
747
  bashOperations: embeddedBashOps,
@@ -702,7 +778,9 @@ class OpenClawWorker {
702
778
  logger.info(`Set runtime API key for ${provider}`);
703
779
  }
704
780
  else {
705
- const fallbackEnvVar = (0, provider_auth_hints_1.getApiKeyEnvVarForProvider)(provider);
781
+ // Look up the env var by the canonical gateway slug (e.g. "z-ai" → Z_AI_API_KEY),
782
+ // not the model-registry alias (e.g. "zai" → ZAI_API_KEY which nobody sets).
783
+ const fallbackEnvVar = (0, provider_auth_hints_1.getApiKeyEnvVarForProvider)(rawProvider);
706
784
  const fallbackValue = credentialStore.get(fallbackEnvVar) || process.env[fallbackEnvVar];
707
785
  if (fallbackValue) {
708
786
  authStorage.setRuntimeApiKey(provider, fallbackValue);
@@ -758,13 +836,6 @@ Replace "YOUR_PROMPT_HERE" with the user's request. These agents can read/write
758
836
 
759
837
  You have access to GetChannelHistory to view previous messages in this thread.
760
838
  Use it when the user references past discussions or you need context.`);
761
- const gwParams = {
762
- gatewayUrl,
763
- workerToken,
764
- channelId: this.config.channelId,
765
- conversationId: this.config.conversationId,
766
- platform: this.config.platform,
767
- };
768
839
  const customTools = (0, custom_tools_1.createOpenClawCustomTools)({
769
840
  ...gwParams,
770
841
  onCustomEvent: async (name, data) => {
@@ -775,11 +846,19 @@ Use it when the user references past discussions or you need context.`);
775
846
  });
776
847
  },
777
848
  });
778
- // Register MCP tools as first-class callable tools (alongside virtual memory wrappers)
779
- const mcpToolDefs = (0, custom_tools_1.createMcpToolDefinitions)(context.mcpTools, gwParams, context.mcpContext);
780
- if (mcpToolDefs.length > 0) {
781
- customTools.push(...mcpToolDefs);
782
- logger.info(`Registered ${mcpToolDefs.length} MCP tool(s): ${mcpToolDefs.map((t) => t.name).join(", ")}`);
849
+ // Register first-class MCP tools + auth tools. Skipped entirely in CLI
850
+ // mode MCP tools are instead reachable via the per-server just-bash CLI
851
+ // wired in above, and `<server> auth login|check|logout` supersedes the
852
+ // `<id>_login` / `<id>_login_check` / `<id>_logout` trio.
853
+ if (mcpExposure === "cli") {
854
+ logger.info("mcpExposure='cli' — skipping first-class MCP tool registration (tools reachable via <server> <tool> in Bash).");
855
+ }
856
+ else {
857
+ const mcpToolDefs = (0, custom_tools_1.createMcpToolDefinitions)(context.mcpTools, gwParams, context.mcpContext);
858
+ if (mcpToolDefs.length > 0) {
859
+ customTools.push(...mcpToolDefs);
860
+ logger.info(`Registered ${mcpToolDefs.length} MCP tool(s): ${mcpToolDefs.map((t) => t.name).join(", ")}`);
861
+ }
783
862
  }
784
863
  // Load OpenClaw plugins
785
864
  const pluginsConfig = rawOptions.pluginsConfig;
@@ -789,10 +868,12 @@ Use it when the user references past discussions or you need context.`);
789
868
  customTools.push(...pluginTools);
790
869
  logger.info(`Loaded ${pluginTools.length} tool(s) from ${loadedPlugins.length} plugin(s)`);
791
870
  }
792
- const authToolDefs = (0, custom_tools_1.createMcpAuthToolDefinitions)(context.mcpStatus, gwParams, new Set(customTools.map((tool) => tool.name)));
793
- if (authToolDefs.length > 0) {
794
- customTools.push(...authToolDefs);
795
- logger.info(`Registered ${authToolDefs.length} MCP auth tool(s): ${authToolDefs.map((t) => t.name).join(", ")}`);
871
+ if (mcpExposure !== "cli") {
872
+ const authToolDefs = (0, custom_tools_1.createMcpAuthToolDefinitions)(context.mcpStatus, gwParams, new Set(customTools.map((tool) => tool.name)));
873
+ if (authToolDefs.length > 0) {
874
+ customTools.push(...authToolDefs);
875
+ logger.info(`Registered ${authToolDefs.length} MCP auth tool(s): ${authToolDefs.map((t) => t.name).join(", ")}`);
876
+ }
796
877
  }
797
878
  // Apply plugin provider registrations to ModelRegistry
798
879
  const modelRegistry = new pi_coding_agent_1.ModelRegistry(authStorage);
@@ -874,8 +955,25 @@ Use it when the user references past discussions or you need context.`);
874
955
  modelRegistry,
875
956
  });
876
957
  session = createdSession.session;
958
+ // Pi-coding-agent's base prompt opens with "You are an expert coding
959
+ // assistant operating inside pi, a coding agent harness…" — that anchor
960
+ // overrides any IDENTITY.md the agent ships with. Replace just that
961
+ // opener with the agent's real identity (or the lobu default) so the
962
+ // tools/guidelines/cwd footer below it still applies, but the role on
963
+ // top is the one we actually want.
877
964
  const basePrompt = session.systemPrompt;
878
- session.agent.setSystemPrompt(`${basePrompt}\n\n${finalInstructionsUpdated}`);
965
+ const identity = context.agentInstructions?.trim();
966
+ const finalSystemPrompt = identity
967
+ ? [
968
+ replaceBasePromptIdentity(basePrompt, identity),
969
+ finalInstructionsUpdated,
970
+ ]
971
+ .filter(Boolean)
972
+ .join("\n\n---\n\n")
973
+ : [basePrompt, finalInstructionsUpdated]
974
+ .filter(Boolean)
975
+ .join("\n\n---\n\n");
976
+ session.agent.setSystemPrompt(finalSystemPrompt);
879
977
  let resolveTurnDone = null;
880
978
  let turnNonce = 0;
881
979
  let suppressProgressOutput = false;
@@ -1102,7 +1200,7 @@ Use it when the user references past discussions or you need context.`);
1102
1200
  },
1103
1201
  ctx: pluginHookContext,
1104
1202
  });
1105
- const errorWithHint = await this.maybeBuildAuthHintMessage(sessionError, provider, modelId, gatewayUrl, workerToken);
1203
+ const errorWithHint = await this.maybeBuildAuthHintMessage(sessionError, rawProvider, modelId, gatewayUrl, workerToken);
1106
1204
  return {
1107
1205
  success: false,
1108
1206
  exitCode: 1,
@@ -1200,15 +1298,18 @@ Use it when the user references past discussions or you need context.`);
1200
1298
  logger.info(`Downloading ${files.length} input files...`);
1201
1299
  const workspaceDir = this.workspaceManager.getCurrentWorkingDirectory();
1202
1300
  const inputDir = path.join(workspaceDir, "input");
1203
- const dispatcherUrl = process.env.DISPATCHER_URL;
1204
- const workerToken = process.env.WORKER_TOKEN;
1205
1301
  for (const file of files) {
1206
1302
  try {
1303
+ if (!file.downloadUrl) {
1304
+ logger.warn({ fileName: file.name, fileId: file.id }, "Inbound file has no downloadUrl; gateway must publish it as an artifact before forwarding");
1305
+ continue;
1306
+ }
1207
1307
  logger.info(`Downloading file: ${file.name} (${file.id})`);
1208
- const response = await fetch(`${dispatcherUrl}/internal/files/download?fileId=${file.id}`, {
1209
- headers: {
1210
- Authorization: `Bearer ${workerToken}`,
1211
- },
1308
+ // The gateway pre-publishes every inbound attachment as a signed,
1309
+ // time-limited artifact and embeds the URL in `downloadUrl`. We
1310
+ // fetch through the worker's egress proxy — no platform tokens or
1311
+ // worker JWT cross this boundary anymore.
1312
+ const response = await fetch(file.downloadUrl, {
1212
1313
  signal: AbortSignal.timeout(60_000),
1213
1314
  });
1214
1315
  if (!response.ok) {