visionclaw 0.1.191-beta.2 → 0.1.191-beta.4

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 (93) hide show
  1. package/dist/agent/engines/claude/cli-resolver.d.ts +16 -0
  2. package/dist/agent/engines/claude/cli-resolver.d.ts.map +1 -0
  3. package/dist/agent/engines/claude/cli-resolver.js +83 -0
  4. package/dist/agent/engines/claude/cli-resolver.js.map +1 -0
  5. package/dist/agent/engines/claude/session-browser-policy.d.ts +9 -0
  6. package/dist/agent/engines/claude/session-browser-policy.d.ts.map +1 -0
  7. package/dist/agent/engines/claude/session-browser-policy.js +49 -0
  8. package/dist/agent/engines/claude/session-browser-policy.js.map +1 -0
  9. package/dist/agent/engines/claude/session.d.ts +275 -0
  10. package/dist/agent/engines/claude/session.d.ts.map +1 -0
  11. package/dist/agent/engines/claude/session.js +1140 -0
  12. package/dist/agent/engines/claude/session.js.map +1 -0
  13. package/dist/agent/engines/client-factory.d.ts +58 -0
  14. package/dist/agent/engines/client-factory.d.ts.map +1 -0
  15. package/dist/agent/engines/client-factory.js +376 -0
  16. package/dist/agent/engines/client-factory.js.map +1 -0
  17. package/dist/agent/engines/engine.d.ts +8 -0
  18. package/dist/agent/engines/engine.d.ts.map +1 -0
  19. package/dist/agent/engines/engine.js +15 -0
  20. package/dist/agent/engines/engine.js.map +1 -0
  21. package/dist/agent/engines/openai/file-session.d.ts +49 -0
  22. package/dist/agent/engines/openai/file-session.d.ts.map +1 -0
  23. package/dist/agent/engines/openai/file-session.js +108 -0
  24. package/dist/agent/engines/openai/file-session.js.map +1 -0
  25. package/dist/agent/engines/openai/file-tools.d.ts +35 -0
  26. package/dist/agent/engines/openai/file-tools.d.ts.map +1 -0
  27. package/dist/agent/engines/openai/file-tools.js +194 -0
  28. package/dist/agent/engines/openai/file-tools.js.map +1 -0
  29. package/dist/agent/engines/openai/session.d.ts +160 -0
  30. package/dist/agent/engines/openai/session.d.ts.map +1 -0
  31. package/dist/agent/engines/openai/session.js +799 -0
  32. package/dist/agent/engines/openai/session.js.map +1 -0
  33. package/dist/agent/engines/openai/tools.d.ts +13 -0
  34. package/dist/agent/engines/openai/tools.d.ts.map +1 -0
  35. package/dist/agent/engines/openai/tools.js +248 -0
  36. package/dist/agent/engines/openai/tools.js.map +1 -0
  37. package/dist/agent/engines/session-types.d.ts +130 -0
  38. package/dist/agent/engines/session-types.d.ts.map +1 -0
  39. package/dist/agent/engines/session-types.js +2 -0
  40. package/dist/agent/engines/session-types.js.map +1 -0
  41. package/dist/agent/engines/system-prompt-log.d.ts +9 -0
  42. package/dist/agent/engines/system-prompt-log.d.ts.map +1 -0
  43. package/dist/agent/engines/system-prompt-log.js +46 -0
  44. package/dist/agent/engines/system-prompt-log.js.map +1 -0
  45. package/dist/agent/heartbeat-manager.d.ts +4 -0
  46. package/dist/agent/heartbeat-manager.d.ts.map +1 -1
  47. package/dist/agent/heartbeat-manager.js +27 -0
  48. package/dist/agent/heartbeat-manager.js.map +1 -1
  49. package/dist/agent/loop.d.ts.map +1 -1
  50. package/dist/agent/loop.js +19 -17
  51. package/dist/agent/loop.js.map +1 -1
  52. package/dist/agent/provider-fallback.d.ts +97 -0
  53. package/dist/agent/provider-fallback.d.ts.map +1 -0
  54. package/dist/agent/provider-fallback.js +223 -0
  55. package/dist/agent/provider-fallback.js.map +1 -0
  56. package/dist/agent/providers/claude/session.d.ts +16 -1
  57. package/dist/agent/providers/claude/session.d.ts.map +1 -1
  58. package/dist/agent/providers/claude/session.js +35 -2
  59. package/dist/agent/providers/claude/session.js.map +1 -1
  60. package/dist/agent/providers/client-factory.d.ts.map +1 -1
  61. package/dist/agent/providers/client-factory.js +7 -5
  62. package/dist/agent/providers/client-factory.js.map +1 -1
  63. package/dist/agent/providers/openai/session.d.ts +1 -0
  64. package/dist/agent/providers/openai/session.d.ts.map +1 -1
  65. package/dist/agent/providers/openai/session.js +3 -0
  66. package/dist/agent/providers/openai/session.js.map +1 -1
  67. package/dist/agent/providers/session-types.d.ts +8 -0
  68. package/dist/agent/providers/session-types.d.ts.map +1 -1
  69. package/dist/agent/session-manager.d.ts +8 -0
  70. package/dist/agent/session-manager.d.ts.map +1 -1
  71. package/dist/agent/session-manager.js +11 -0
  72. package/dist/agent/session-manager.js.map +1 -1
  73. package/dist/agent/wake-cycle-runner.d.ts +8 -0
  74. package/dist/agent/wake-cycle-runner.d.ts.map +1 -1
  75. package/dist/agent/wake-cycle-runner.js +59 -6
  76. package/dist/agent/wake-cycle-runner.js.map +1 -1
  77. package/dist/i18n/messages.d.ts +8 -0
  78. package/dist/i18n/messages.d.ts.map +1 -1
  79. package/dist/i18n/messages.js +9 -0
  80. package/dist/i18n/messages.js.map +1 -1
  81. package/dist/onboarding/onboarding-service-client.d.ts +23 -0
  82. package/dist/onboarding/onboarding-service-client.d.ts.map +1 -1
  83. package/dist/onboarding/onboarding-service-client.js.map +1 -1
  84. package/dist/openai-credentials.d.ts +31 -0
  85. package/dist/openai-credentials.d.ts.map +1 -0
  86. package/dist/openai-credentials.js +38 -0
  87. package/dist/openai-credentials.js.map +1 -0
  88. package/dist/skills/installed.d.ts +11 -0
  89. package/dist/skills/installed.d.ts.map +1 -0
  90. package/dist/skills/installed.js +35 -0
  91. package/dist/skills/installed.js.map +1 -0
  92. package/dist-agent/bundle.cjs +19179 -21809
  93. package/package.json +1 -1
@@ -0,0 +1,16 @@
1
+ export type ClaudeCliResolution = {
2
+ kind: "native";
3
+ path: string;
4
+ } | {
5
+ kind: "legacy-cli-js";
6
+ path: string;
7
+ } | {
8
+ kind: "sdk-default";
9
+ };
10
+ export declare function resolveClaudeCliExecutable(): ClaudeCliResolution;
11
+ /** Convenience wrapper — return just the path, or `undefined` when we should
12
+ * leave the option unset and let the SDK do its own lookup. */
13
+ export declare function getClaudeExecutablePath(): string | undefined;
14
+ /** For tests. */
15
+ export declare function _resetClaudeCliResolverCache(): void;
16
+ //# sourceMappingURL=cli-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-resolver.d.ts","sourceRoot":"","sources":["../../../../src/agent/engines/claude/cli-resolver.ts"],"names":[],"mappings":"AA8BA,MAAM,MAAM,mBAAmB,GAC3B;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACvC;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,CAAC;AAQ5B,wBAAgB,0BAA0B,IAAI,mBAAmB,CAIhE;AAED;gEACgE;AAChE,wBAAgB,uBAAuB,IAAI,MAAM,GAAG,SAAS,CAG5D;AAsCD,iBAAiB;AACjB,wBAAgB,4BAA4B,IAAI,IAAI,CAEnD"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Resolve the executable path that `@anthropic-ai/claude-agent-sdk` should
3
+ * spawn as its "Claude Code" subprocess.
4
+ *
5
+ * Why we need this:
6
+ * - In 0.2.108–0.2.112 the SDK shipped a `cli.js` alongside `sdk.mjs`, and
7
+ * the intended way to pin it from a bundled app was to pass
8
+ * `pathToClaudeCodeExecutable` pointing at that file.
9
+ * - Starting with 0.2.113 (published 2026-04-14) the SDK tarball dropped
10
+ * `cli.js` entirely and switched to a platform-specific native binary
11
+ * shipped via an optional peer package
12
+ * `@anthropic-ai/claude-agent-sdk-<platform>-<arch>`.
13
+ * - Our previous implementation hard-coded `cli.js`, so a stock
14
+ * `pnpm install` that pulled the newer SDK caused the child process to
15
+ * fail with `MODULE_NOT_FOUND`, which in turn surfaced as an async EPIPE
16
+ * in the parent.
17
+ *
18
+ * Resolution order:
19
+ * 1. The native binary from `claude-agent-sdk-<platform>-<arch>/claude`
20
+ * (the forward-compatible choice for 0.2.113+).
21
+ * 2. A legacy `cli.js` next to `sdk.mjs` (still valid for 0.2.112 and older).
22
+ * 3. `null`, meaning: let the SDK resolve the executable itself. Recent SDK
23
+ * versions implement the same fallback chain internally and throw a
24
+ * clear `ReferenceError` if nothing is found, which is much easier to
25
+ * diagnose than a silent EPIPE.
26
+ */
27
+ import { createRequire } from "module";
28
+ import fs from "fs";
29
+ import path from "path";
30
+ /**
31
+ * Resolve once per process — filesystem lookups here are cheap but the result
32
+ * never changes for a given installation.
33
+ */
34
+ let cached;
35
+ export function resolveClaudeCliExecutable() {
36
+ if (cached)
37
+ return cached;
38
+ cached = doResolve();
39
+ return cached;
40
+ }
41
+ /** Convenience wrapper — return just the path, or `undefined` when we should
42
+ * leave the option unset and let the SDK do its own lookup. */
43
+ export function getClaudeExecutablePath() {
44
+ const r = resolveClaudeCliExecutable();
45
+ return r.kind === "sdk-default" ? undefined : r.path;
46
+ }
47
+ function doResolve() {
48
+ const _require = createRequire(import.meta.url);
49
+ // 1. Modern native binary (claude-agent-sdk >= 0.2.113).
50
+ const nativePkg = `@anthropic-ai/claude-agent-sdk-${process.platform}-${process.arch}`;
51
+ try {
52
+ const pkgJsonPath = _require.resolve(`${nativePkg}/package.json`);
53
+ const pkgDir = path.dirname(pkgJsonPath);
54
+ // The package ships a single executable named `claude`.
55
+ const candidate = path.join(pkgDir, "claude");
56
+ if (fs.existsSync(candidate)) {
57
+ return { kind: "native", path: candidate };
58
+ }
59
+ }
60
+ catch {
61
+ // Optional dep not installed — fall through to legacy cli.js.
62
+ }
63
+ // 2. Legacy JS entry (claude-agent-sdk <= 0.2.112).
64
+ try {
65
+ const sdkDir = path.dirname(_require.resolve("@anthropic-ai/claude-agent-sdk"));
66
+ const candidate = path.join(sdkDir, "cli.js");
67
+ if (fs.existsSync(candidate)) {
68
+ return { kind: "legacy-cli-js", path: candidate };
69
+ }
70
+ }
71
+ catch {
72
+ // No SDK at all — let the caller's catch handle this.
73
+ }
74
+ // 3. Give up and let the SDK resolve on its own. Newer versions still have
75
+ // a reasonable internal lookup and will throw a clear error if nothing
76
+ // works, rather than silently spawning a missing module.
77
+ return { kind: "sdk-default" };
78
+ }
79
+ /** For tests. */
80
+ export function _resetClaudeCliResolverCache() {
81
+ cached = undefined;
82
+ }
83
+ //# sourceMappingURL=cli-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-resolver.js","sourceRoot":"","sources":["../../../../src/agent/engines/claude/cli-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAOxB;;;GAGG;AACH,IAAI,MAAuC,CAAC;AAE5C,MAAM,UAAU,0BAA0B;IACxC,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,MAAM,GAAG,SAAS,EAAE,CAAC;IACrB,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;gEACgE;AAChE,MAAM,UAAU,uBAAuB;IACrC,MAAM,CAAC,GAAG,0BAA0B,EAAE,CAAC;IACvC,OAAO,CAAC,CAAC,IAAI,KAAK,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACvD,CAAC;AAED,SAAS,SAAS;IAChB,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEhD,yDAAyD;IACzD,MAAM,SAAS,GAAG,kCAAkC,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;IACvF,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,SAAS,eAAe,CAAC,CAAC;QAClE,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QACzC,wDAAwD;QACxD,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAC9C,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC7B,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QAC7C,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,8DAA8D;IAChE,CAAC;IAED,oDAAoD;IACpD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CACzB,QAAQ,CAAC,OAAO,CAAC,gCAAgC,CAAC,CACnD,CAAC;QACF,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAC9C,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC7B,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QACpD,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,sDAAsD;IACxD,CAAC;IAED,2EAA2E;IAC3E,0EAA0E;IAC1E,4DAA4D;IAC5D,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC;AACjC,CAAC;AAED,iBAAiB;AACjB,MAAM,UAAU,4BAA4B;IAC1C,MAAM,GAAG,SAAS,CAAC;AACrB,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Ensure Chrome is running (Playwriter mode). On the first Playwriter tool call
3
+ * of each turn we force a clean restart to reset stale extension connections;
4
+ * later calls in the same turn only ensure Chrome is up.
5
+ *
6
+ * Returns true when a connection reset was performed for this turn.
7
+ */
8
+ export declare function ensurePlaywriterChrome(didResetConnectionsThisTurn: boolean): boolean;
9
+ //# sourceMappingURL=session-browser-policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-browser-policy.d.ts","sourceRoot":"","sources":["../../../../src/agent/engines/claude/session-browser-policy.ts"],"names":[],"mappings":"AAsBA;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,2BAA2B,EAAE,OAAO,GACnC,OAAO,CAmBT"}
@@ -0,0 +1,49 @@
1
+ import { execSync } from "node:child_process";
2
+ import { logger } from "../../../logger.js";
3
+ /**
4
+ * Force Chrome to restart once per turn before the first Playwriter tool call.
5
+ * This clears stale extension relay connections from earlier sessions so the
6
+ * Playwriter MCP sees a single fresh extension connection.
7
+ */
8
+ function restartChromeForPlaywriter() {
9
+ try {
10
+ execSync("pkill -x 'Google Chrome'", { stdio: "ignore" });
11
+ }
12
+ catch {
13
+ // pkill exits non-zero when Chrome is not running — expected.
14
+ }
15
+ try {
16
+ execSync('open -a "Google Chrome"', { stdio: "ignore" });
17
+ }
18
+ catch (err) {
19
+ logger.warn(`Failed to restart Chrome for Playwriter: ${err instanceof Error ? err.message : String(err)}`);
20
+ }
21
+ }
22
+ /**
23
+ * Ensure Chrome is running (Playwriter mode). On the first Playwriter tool call
24
+ * of each turn we force a clean restart to reset stale extension connections;
25
+ * later calls in the same turn only ensure Chrome is up.
26
+ *
27
+ * Returns true when a connection reset was performed for this turn.
28
+ */
29
+ export function ensurePlaywriterChrome(didResetConnectionsThisTurn) {
30
+ if (!didResetConnectionsThisTurn) {
31
+ logger.system("Resetting Chrome before Playwriter session");
32
+ restartChromeForPlaywriter();
33
+ return true;
34
+ }
35
+ try {
36
+ execSync("pgrep -x 'Google Chrome'", { stdio: "ignore" });
37
+ }
38
+ catch {
39
+ logger.system("Chrome not running — launching for Playwriter extension");
40
+ try {
41
+ execSync('open -a "Google Chrome"', { stdio: "ignore" });
42
+ }
43
+ catch (err) {
44
+ logger.warn(`Failed to launch Chrome: ${err instanceof Error ? err.message : String(err)}`);
45
+ }
46
+ }
47
+ return false;
48
+ }
49
+ //# sourceMappingURL=session-browser-policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-browser-policy.js","sourceRoot":"","sources":["../../../../src/agent/engines/claude/session-browser-policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C;;;;GAIG;AACH,SAAS,0BAA0B;IACjC,IAAI,CAAC;QACH,QAAQ,CAAC,0BAA0B,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC5D,CAAC;IAAC,MAAM,CAAC;QACP,8DAA8D;IAChE,CAAC;IAED,IAAI,CAAC;QACH,QAAQ,CAAC,yBAAyB,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC3D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,IAAI,CAAC,4CAA4C,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC9G,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CACpC,2BAAoC;IAEpC,IAAI,CAAC,2BAA2B,EAAE,CAAC;QACjC,MAAM,CAAC,MAAM,CAAC,4CAA4C,CAAC,CAAC;QAC5D,0BAA0B,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACH,QAAQ,CAAC,0BAA0B,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC5D,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,CAAC,MAAM,CAAC,yDAAyD,CAAC,CAAC;QACzE,IAAI,CAAC;YACH,QAAQ,CAAC,yBAAyB,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC3D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,CAAC,IAAI,CAAC,4BAA4B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC9F,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,275 @@
1
+ import { type Query, type SDKMessage, type SDKUserMessage } from "@anthropic-ai/claude-agent-sdk";
2
+ import type { MessageParam } from "@anthropic-ai/sdk/resources";
3
+ import type { SessionMode } from "../../mailbox.js";
4
+ import type { ScreenshotInjector } from "../../screenshot-injector.js";
5
+ import type { AgentSessionConstructorArgs, AgentSessionLike, AgentStreamMessage, InjectMessageOptions, SendAndStreamOptions, UsageSnapshot } from "../session-types.js";
6
+ export type { SDKMessage, SDKUserMessage };
7
+ export type { SystemPromptConfig } from "../session-types.js";
8
+ /**
9
+ * Used-token threshold (fraction of context window) at which we trigger
10
+ * compaction for **large** context windows (>= {@link COMPACT_MAX_CONTEXT_WINDOW}).
11
+ *
12
+ * Smaller windows scale up to {@link COMPACT_SMALL_WINDOW_USED_PCT_THRESHOLD}
13
+ * via {@link getCompactUsedPctThreshold}.
14
+ */
15
+ export declare const COMPACT_LARGE_WINDOW_USED_PCT_THRESHOLD = 0.7;
16
+ export declare const MAX_BASE64_IMAGE_BLOCKS = 10;
17
+ /** When total image blocks (real + placeholder) exceed this, trigger compaction
18
+ * to avoid hitting Claude API's 100-image limit. */
19
+ export declare const IMAGE_COMPACT_THRESHOLD = 80;
20
+ /**
21
+ * Wraps the V1 query() API with a long-lived async generator for streaming
22
+ * input. This allows injecting additional user messages while the agent is
23
+ * processing (interrupt messages), instead of waiting for the query to
24
+ * finish before sending the next message.
25
+ */
26
+ export declare class ClaudeAgentSession implements AgentSessionLike {
27
+ private config;
28
+ private buildSystemPrompt;
29
+ private runtimeSurface;
30
+ private getDualSessionEnabled;
31
+ private getAndroidUseEnabled;
32
+ /** Working directory for the SDK subprocess. Defaults to profile config dir. */
33
+ private readonly sessionCwd;
34
+ private nativeTools;
35
+ /** Resolved external MCP servers (playwright, serpapi, etc.) for this runtime. */
36
+ private externalMcpServers;
37
+ /** Dynamic MCP servers added at runtime via manage_mcp_servers tool. */
38
+ private dynamicMcpServers;
39
+ private currentQuery;
40
+ private warmQuery;
41
+ private warmUpPromise;
42
+ private warmReadyAtMs;
43
+ private sessionId;
44
+ private transcriptPath;
45
+ readonly mode: SessionMode;
46
+ /**
47
+ * Pending message queue for the long-lived generator.
48
+ * When a message is injected, it's pushed here and the waiting
49
+ * generator is woken up via the resolver.
50
+ */
51
+ private pendingMessages;
52
+ private messageResolver;
53
+ private generatorClosed;
54
+ private _orphanedInjections;
55
+ private lastCompactRequestAtMs;
56
+ private compactInFlight;
57
+ private stopRequested;
58
+ /**
59
+ * Tracks whether we've seeded `<profile>/.claude/settings.local.json`
60
+ * with our auto-memory directory override this process-lifetime. The seed
61
+ * helper is itself idempotent, but this flag keeps hot paths (every
62
+ * `consume()` / `warmUp()`) from hitting the filesystem repeatedly.
63
+ */
64
+ private autoMemorySeedDone;
65
+ /** Optional: auto-injects screenshots after Playwright tool calls. */
66
+ private _screenshotInjector;
67
+ /** AbortController passed to the SDK; aborting it cleanly stops the running query. */
68
+ private abortController;
69
+ private warmAbortController;
70
+ /**
71
+ * Timer that proactively replaces the pre-warmed subprocess at
72
+ * `WARM_REFRESH_TTL_MS` intervals. Cleared when the warm is consumed,
73
+ * on stop, or before arming a new one.
74
+ */
75
+ private warmRefreshTimer;
76
+ private lastUsageSnapshot;
77
+ private playwriterConnectionsResetThisTurn;
78
+ constructor({ config, buildSystemPrompt, runtimeSurface, sessionContext, }: AgentSessionConstructorArgs);
79
+ set screenshotInjector(injector: ScreenshotInjector | null);
80
+ /**
81
+ * Seed `<profile>/.claude/settings.local.json` once per process so the
82
+ * CLI's auto-memory lands inside the active profile instead of the
83
+ * default `~/.claude/projects/...` tree. Called from every CLI-spawn
84
+ * path (warm + cold); the underlying helper is itself idempotent.
85
+ *
86
+ * Gated on the `autoMemorySeedDone` flag so the happy path doesn't
87
+ * re-read/re-write the file every turn. The flag is set **only on
88
+ * success** — if the first attempt fails (permissions, disk full, etc.)
89
+ * the next warm/cold spawn will retry until it lands, instead of
90
+ * silently leaving the CLI on its default memory path for the rest of
91
+ * the session.
92
+ */
93
+ private ensureAutoMemorySeeded;
94
+ /**
95
+ * Build a fresh mcpServers record with a new visionclaw tool server instance.
96
+ * This avoids the "Already connected to a transport" error when the same
97
+ * McpServer instance is reused across concurrent/sequential query() calls.
98
+ */
99
+ private buildMcpServers;
100
+ private buildNativeToolOptions;
101
+ private buildHooks;
102
+ /**
103
+ * Build the shared Claude query options used for both pre-warm and live runs.
104
+ */
105
+ private buildQueryOptions;
106
+ /**
107
+ * Cancel any pending proactive-refresh timer. Idempotent.
108
+ */
109
+ private clearWarmRefreshTimer;
110
+ /**
111
+ * Arm the proactive-refresh timer. Caller must ensure any previous timer
112
+ * is cleared. Uses `.unref()` so the process can exit while a warm
113
+ * subprocess is idle — the refresh is purely a background optimization
114
+ * and should never hold the event loop alive on its own.
115
+ */
116
+ private scheduleWarmRefresh;
117
+ /**
118
+ * Handler for the refresh timer. Covers two cases:
119
+ * 1. Normal TTL refresh: `warmQuery` is non-null → close the stale
120
+ * subprocess and start a fresh one.
121
+ * 2. Retry after a previous failure: `warmQuery` is null → just
122
+ * attempt warmUp again (no teardown needed).
123
+ *
124
+ * If the warm was already consumed between timer arming and firing,
125
+ * the consume path would have cleared the timer, so we shouldn't
126
+ * reach here in that case.
127
+ */
128
+ private performWarmRefresh;
129
+ /**
130
+ * Post-warmUp follow-up for performWarmRefresh. Kept in its own method so
131
+ * TS's control-flow narrowing in performWarmRefresh doesn't treat these
132
+ * fields as having their pre-await values.
133
+ */
134
+ private handleWarmRefreshOutcome;
135
+ /**
136
+ * Send the initial user message and return the query generator to stream
137
+ * responses. The underlying async generator stays open so that additional
138
+ * messages can be injected via injectMessage().
139
+ */
140
+ warmUp(): Promise<void>;
141
+ sendAndStream(content: MessageParam["content"], options?: SendAndStreamOptions): AsyncIterable<AgentStreamMessage>;
142
+ /**
143
+ * Inject a new user message into the running query stream.
144
+ * The agent will see this as a follow-up user message in the conversation.
145
+ * Only works while a query is active (between sendAndStream and closeInput).
146
+ *
147
+ * @returns true if the message was injected, false if the generator is closed.
148
+ */
149
+ injectMessage(content: MessageParam["content"], options?: InjectMessageOptions): boolean;
150
+ /**
151
+ * Signal the input generator to close.
152
+ * Any injected messages still in the pending queue are counted as
153
+ * orphaned — they were accepted by injectMessage but never delivered
154
+ * to the SDK.
155
+ */
156
+ closeInput(): void;
157
+ /**
158
+ * Returns true if injected messages were lost when the generator closed.
159
+ */
160
+ get hasOrphanedInjections(): boolean;
161
+ get isInputClosed(): boolean;
162
+ /**
163
+ * Request that the current agent turn be stopped.
164
+ * Uses the SDK's AbortController to cleanly signal the running query to
165
+ * stop, then closes the input stream so the loop returns to idle.
166
+ */
167
+ requestStop(): void;
168
+ isStopRequested(): boolean;
169
+ clearStop(): void;
170
+ /**
171
+ * Update the persisted session ID.
172
+ *
173
+ * Only saves on first capture (null → id). Once set, a different ID from
174
+ * the SDK is ignored — it means the resume failed and the SDK created a
175
+ * throwaway conversation. Persisting it would corrupt session.json and
176
+ * orphan the real transcript.
177
+ */
178
+ captureSessionId(id: string | undefined): void;
179
+ captureTranscriptPath(p: string | undefined | null): void;
180
+ getSessionId(): string | null;
181
+ /**
182
+ * Proactively request compaction by running the /compact slash command as a
183
+ * separate one-turn query resumed from the current session.
184
+ *
185
+ * This is more reliable than injecting "/compact" into the streaming prompt
186
+ * because the running query may treat it as ordinary text.
187
+ */
188
+ requestCompaction(): Promise<void>;
189
+ captureUsageSnapshot(snapshot: UsageSnapshot): void;
190
+ /**
191
+ * Update the usage snapshot after the SDK performs mid-query auto-compaction.
192
+ * Uses `pre_tokens` (the post-compaction token count) and the last known
193
+ * context window to compute an accurate `usedPct`, preventing the post-query
194
+ * `maybeCompact` from triggering a redundant compaction.
195
+ */
196
+ capturePostCompactionSnapshot(postCompactionTokens: number): void;
197
+ /**
198
+ * Unified between-turn compaction gate. Triggers compaction when **either**:
199
+ * 1. Token usage exceeds the context-window threshold, OR
200
+ * 2. Total image blocks (real + placeholder) in the transcript reach
201
+ * `imageThreshold`, approaching Claude API's 100-image limit.
202
+ *
203
+ * Both triggers share the same cooldown and in-flight guard so we never
204
+ * run two back-to-back compactions in the same between-turn pass.
205
+ */
206
+ maybeCompact(options?: {
207
+ /**
208
+ * Optional explicit override. When set, takes precedence over the
209
+ * context-window-aware auto-scaling done by
210
+ * {@link getCompactUsedPctThreshold}.
211
+ */
212
+ usedPctThreshold?: number;
213
+ cooldownMs?: number;
214
+ imageThreshold?: number;
215
+ }): Promise<void>;
216
+ getTranscriptPath(): string | null;
217
+ /**
218
+ * Derive the transcript path from the session ID and config dir, even before
219
+ * the SDK subprocess has started and reported it via hooks.
220
+ */
221
+ private deriveTranscriptPath;
222
+ getUsageSnapshot(): UsageSnapshot | null;
223
+ /** Returns the live Query object, or null if no query is active. */
224
+ getCurrentQuery(): Query | null;
225
+ /**
226
+ * Validation adapter around `Query.getContextUsage()` (SDK 0.2.114+).
227
+ *
228
+ * The SDK's `Query` interface exposes `getContextUsage()` as a control
229
+ * request over the streaming bridge. It returns a rich breakdown:
230
+ *
231
+ * ```ts
232
+ * {
233
+ * categories: { name: string; tokens: number; color: string; isDeferred?: boolean }[];
234
+ * totalTokens: number;
235
+ * maxTokens: number; // context window for the *active* model
236
+ * rawMaxTokens: number; // nominal max before any reductions
237
+ * percentage: number; // UI percentage (0..100)
238
+ * gridRows: ...[]; // TUI-only
239
+ * model: string;
240
+ * memoryFiles: { path: string; type: string; tokens: number }[];
241
+ * mcpTools: { name: string; serverName: string; tokens: number }[];
242
+ * }
243
+ * ```
244
+ *
245
+ * We map it onto our existing {@link UsageSnapshot} shape:
246
+ * - `usedInputTokens` ← `totalTokens`
247
+ * - `contextWindow` ← `maxTokens` (post-reduction; matches what the
248
+ * model actually has to work with right now)
249
+ * - `usedPct` ← computed from the two above, NOT from the
250
+ * SDK's `percentage` field. The SDK's value is
251
+ * UI-scale (0..100); our consumers expect 0..1.
252
+ * Computing locally keeps both fields internally
253
+ * consistent.
254
+ * - `allImageBlocks` — intentionally preserved from any existing
255
+ * snapshot; `getContextUsage` doesn't know about
256
+ * raw image-block counts in the transcript, so
257
+ * we don't clobber the value that
258
+ * {@link captureUsageSnapshot} maintains.
259
+ *
260
+ * This is purely a read adapter — no callers in compaction or the
261
+ * wake loop should depend on it yet. It exists to let us sanity-check
262
+ * the live SDK response before wiring any behavior changes around it.
263
+ * Returns null when no live query is active, when the method is absent
264
+ * on the active Query instance (e.g. an older CLI), or when the call
265
+ * errors transiently.
266
+ *
267
+ * TODO: we should update snapshot based on this.
268
+ */
269
+ getLiveContextUsage(): Promise<UsageSnapshot | null>;
270
+ /** Replace the full set of dynamic MCP servers (used when loading from disk). */
271
+ setDynamicMcpServers(servers: Record<string, Record<string, unknown>>): void;
272
+ /** Get the current dynamic MCP servers record. */
273
+ getDynamicMcpServers(): Record<string, Record<string, unknown>>;
274
+ }
275
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../../src/agent/engines/claude/session.ts"],"names":[],"mappings":"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"}