visionclaw 0.1.193-dev.fix-replace-image-placeholders-with-text.1 → 0.1.193

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 (245) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/agent/api-proxy.d.ts.map +1 -1
  3. package/dist/agent/api-proxy.js +185 -25
  4. package/dist/agent/api-proxy.js.map +1 -1
  5. package/dist/agent/applied-credential-signature.d.ts +53 -0
  6. package/dist/agent/applied-credential-signature.d.ts.map +1 -0
  7. package/dist/agent/applied-credential-signature.js +137 -0
  8. package/dist/agent/applied-credential-signature.js.map +1 -0
  9. package/dist/agent/command-handlers.d.ts.map +1 -1
  10. package/dist/agent/command-handlers.js +18 -7
  11. package/dist/agent/command-handlers.js.map +1 -1
  12. package/dist/agent/context.js +1 -1
  13. package/dist/agent/context.js.map +1 -1
  14. package/dist/agent/engines/claude/cli-resolver.d.ts +16 -0
  15. package/dist/agent/engines/claude/cli-resolver.d.ts.map +1 -0
  16. package/dist/agent/engines/claude/cli-resolver.js +83 -0
  17. package/dist/agent/engines/claude/cli-resolver.js.map +1 -0
  18. package/dist/agent/engines/claude/session-browser-policy.d.ts +9 -0
  19. package/dist/agent/engines/claude/session-browser-policy.d.ts.map +1 -0
  20. package/dist/agent/engines/claude/session-browser-policy.js +49 -0
  21. package/dist/agent/engines/claude/session-browser-policy.js.map +1 -0
  22. package/dist/agent/engines/claude/session.d.ts +291 -0
  23. package/dist/agent/engines/claude/session.d.ts.map +1 -0
  24. package/dist/agent/engines/claude/session.js +1177 -0
  25. package/dist/agent/engines/claude/session.js.map +1 -0
  26. package/dist/agent/engines/client-factory.d.ts +63 -0
  27. package/dist/agent/engines/client-factory.d.ts.map +1 -0
  28. package/dist/agent/engines/client-factory.js +382 -0
  29. package/dist/agent/engines/client-factory.js.map +1 -0
  30. package/dist/agent/engines/engine.d.ts +8 -0
  31. package/dist/agent/engines/engine.d.ts.map +1 -0
  32. package/dist/agent/engines/engine.js +15 -0
  33. package/dist/agent/engines/engine.js.map +1 -0
  34. package/dist/agent/engines/openai/file-session.d.ts +49 -0
  35. package/dist/agent/engines/openai/file-session.d.ts.map +1 -0
  36. package/dist/agent/engines/openai/file-session.js +108 -0
  37. package/dist/agent/engines/openai/file-session.js.map +1 -0
  38. package/dist/agent/engines/openai/file-tools.d.ts +35 -0
  39. package/dist/agent/engines/openai/file-tools.d.ts.map +1 -0
  40. package/dist/agent/engines/openai/file-tools.js +194 -0
  41. package/dist/agent/engines/openai/file-tools.js.map +1 -0
  42. package/dist/agent/engines/openai/session.d.ts +190 -0
  43. package/dist/agent/engines/openai/session.d.ts.map +1 -0
  44. package/dist/agent/engines/openai/session.js +1066 -0
  45. package/dist/agent/engines/openai/session.js.map +1 -0
  46. package/dist/agent/engines/openai/tools.d.ts +13 -0
  47. package/dist/agent/engines/openai/tools.d.ts.map +1 -0
  48. package/dist/agent/engines/openai/tools.js +248 -0
  49. package/dist/agent/engines/openai/tools.js.map +1 -0
  50. package/dist/agent/engines/session-types.d.ts +146 -0
  51. package/dist/agent/engines/session-types.d.ts.map +1 -0
  52. package/dist/agent/engines/session-types.js +2 -0
  53. package/dist/agent/engines/session-types.js.map +1 -0
  54. package/dist/agent/engines/system-prompt-log.d.ts +9 -0
  55. package/dist/agent/engines/system-prompt-log.d.ts.map +1 -0
  56. package/dist/agent/engines/system-prompt-log.js +46 -0
  57. package/dist/agent/engines/system-prompt-log.js.map +1 -0
  58. package/dist/agent/providers/claude/session.d.ts +17 -2
  59. package/dist/agent/providers/claude/session.d.ts.map +1 -1
  60. package/dist/agent/providers/claude/session.js +64 -7
  61. package/dist/agent/providers/claude/session.js.map +1 -1
  62. package/dist/agent/providers/openai/session.d.ts +1 -0
  63. package/dist/agent/providers/openai/session.d.ts.map +1 -1
  64. package/dist/agent/providers/openai/session.js +4 -0
  65. package/dist/agent/providers/openai/session.js.map +1 -1
  66. package/dist/agent/providers/session-types.d.ts +6 -0
  67. package/dist/agent/providers/session-types.d.ts.map +1 -1
  68. package/dist/agent/session-manager.d.ts +8 -0
  69. package/dist/agent/session-manager.d.ts.map +1 -1
  70. package/dist/agent/session-manager.js +14 -1
  71. package/dist/agent/session-manager.js.map +1 -1
  72. package/dist/agent/transcript/transcript-backfill.d.ts +54 -0
  73. package/dist/agent/transcript/transcript-backfill.d.ts.map +1 -0
  74. package/dist/agent/transcript/transcript-backfill.js +604 -0
  75. package/dist/agent/transcript/transcript-backfill.js.map +1 -0
  76. package/dist/agent/transcript/transcript-indexer.d.ts +273 -0
  77. package/dist/agent/transcript/transcript-indexer.d.ts.map +1 -0
  78. package/dist/agent/transcript/transcript-indexer.js +1217 -0
  79. package/dist/agent/transcript/transcript-indexer.js.map +1 -0
  80. package/dist/agent/transcript/transcript-memory-migrations.d.ts +25 -0
  81. package/dist/agent/transcript/transcript-memory-migrations.d.ts.map +1 -0
  82. package/dist/agent/transcript/transcript-memory-migrations.js +87 -0
  83. package/dist/agent/transcript/transcript-memory-migrations.js.map +1 -0
  84. package/dist/agent/transcript-memory-migrations.d.ts +25 -0
  85. package/dist/agent/transcript-memory-migrations.d.ts.map +1 -0
  86. package/dist/agent/transcript-memory-migrations.js +87 -0
  87. package/dist/agent/transcript-memory-migrations.js.map +1 -0
  88. package/dist/agent/transcript-summarizer.d.ts +24 -0
  89. package/dist/agent/transcript-summarizer.d.ts.map +1 -0
  90. package/dist/agent/transcript-summarizer.js +347 -0
  91. package/dist/agent/transcript-summarizer.js.map +1 -0
  92. package/dist/agent/tunnel-credential-handler.d.ts +90 -0
  93. package/dist/agent/tunnel-credential-handler.d.ts.map +1 -0
  94. package/dist/agent/tunnel-credential-handler.js +162 -0
  95. package/dist/agent/tunnel-credential-handler.js.map +1 -0
  96. package/dist/agent/usage/usage-backfill-handler.d.ts +18 -0
  97. package/dist/agent/usage/usage-backfill-handler.d.ts.map +1 -0
  98. package/dist/agent/usage/usage-backfill-handler.js +69 -0
  99. package/dist/agent/usage/usage-backfill-handler.js.map +1 -0
  100. package/dist/agent/usage/usage-gate.d.ts +25 -0
  101. package/dist/agent/usage/usage-gate.d.ts.map +1 -0
  102. package/dist/agent/usage/usage-gate.js +83 -0
  103. package/dist/agent/usage/usage-gate.js.map +1 -0
  104. package/dist/agent/usage/usage-handler.d.ts +7 -0
  105. package/dist/agent/usage/usage-handler.d.ts.map +1 -0
  106. package/dist/agent/usage/usage-handler.js +28 -0
  107. package/dist/agent/usage/usage-handler.js.map +1 -0
  108. package/dist/agent/usage/usage-report-builder.d.ts +26 -0
  109. package/dist/agent/usage/usage-report-builder.d.ts.map +1 -0
  110. package/dist/agent/usage/usage-report-builder.js +80 -0
  111. package/dist/agent/usage/usage-report-builder.js.map +1 -0
  112. package/dist/agent/usage/usage-report-queue.d.ts +26 -0
  113. package/dist/agent/usage/usage-report-queue.d.ts.map +1 -0
  114. package/dist/agent/usage/usage-report-queue.js +199 -0
  115. package/dist/agent/usage/usage-report-queue.js.map +1 -0
  116. package/dist/agent/usage/usage-report-types.d.ts +41 -0
  117. package/dist/agent/usage/usage-report-types.d.ts.map +1 -0
  118. package/dist/agent/usage/usage-report-types.js +2 -0
  119. package/dist/agent/usage/usage-report-types.js.map +1 -0
  120. package/dist/agent/usage/usage-reporter.d.ts +31 -0
  121. package/dist/agent/usage/usage-reporter.d.ts.map +1 -0
  122. package/dist/agent/usage/usage-reporter.js +102 -0
  123. package/dist/agent/usage/usage-reporter.js.map +1 -0
  124. package/dist/agent/usage-backfill-handler.d.ts +18 -0
  125. package/dist/agent/usage-backfill-handler.d.ts.map +1 -0
  126. package/dist/agent/usage-backfill-handler.js +69 -0
  127. package/dist/agent/usage-backfill-handler.js.map +1 -0
  128. package/dist/agent/usage-gate.d.ts +25 -0
  129. package/dist/agent/usage-gate.d.ts.map +1 -0
  130. package/dist/agent/usage-gate.js +83 -0
  131. package/dist/agent/usage-gate.js.map +1 -0
  132. package/dist/agent/usage-report-builder.d.ts +26 -0
  133. package/dist/agent/usage-report-builder.d.ts.map +1 -0
  134. package/dist/agent/usage-report-builder.js +80 -0
  135. package/dist/agent/usage-report-builder.js.map +1 -0
  136. package/dist/agent/usage-report-queue.d.ts +26 -0
  137. package/dist/agent/usage-report-queue.d.ts.map +1 -0
  138. package/dist/agent/usage-report-queue.js +199 -0
  139. package/dist/agent/usage-report-queue.js.map +1 -0
  140. package/dist/agent/usage-report-types.d.ts +41 -0
  141. package/dist/agent/usage-report-types.d.ts.map +1 -0
  142. package/dist/agent/usage-report-types.js +2 -0
  143. package/dist/agent/usage-report-types.js.map +1 -0
  144. package/dist/agent/usage-reporter.d.ts +31 -0
  145. package/dist/agent/usage-reporter.d.ts.map +1 -0
  146. package/dist/agent/usage-reporter.js +102 -0
  147. package/dist/agent/usage-reporter.js.map +1 -0
  148. package/dist/agent/wake-cycle-tool-tracker.d.ts +39 -0
  149. package/dist/agent/wake-cycle-tool-tracker.d.ts.map +1 -0
  150. package/dist/agent/wake-cycle-tool-tracker.js +72 -0
  151. package/dist/agent/wake-cycle-tool-tracker.js.map +1 -0
  152. package/dist/billing/payg-handler.d.ts +29 -0
  153. package/dist/billing/payg-handler.d.ts.map +1 -0
  154. package/dist/billing/payg-handler.js +92 -0
  155. package/dist/billing/payg-handler.js.map +1 -0
  156. package/dist/billing/payment-handler.d.ts +24 -0
  157. package/dist/billing/payment-handler.d.ts.map +1 -0
  158. package/dist/billing/payment-handler.js +101 -0
  159. package/dist/billing/payment-handler.js.map +1 -0
  160. package/dist/builtin-skills/catalog/phone-adb-automation/SKILL.md +412 -0
  161. package/dist/builtin-skills/catalog/phone-adb-automation/phone_input.sh +132 -0
  162. package/dist/builtin-skills/catalog/phone-adb-automation/phone_launch.sh +166 -0
  163. package/dist/builtin-skills/catalog/phone-adb-automation/phone_screenshot.sh +87 -0
  164. package/dist/builtin-skills/catalog/phone-adb-automation/phone_security_kbd.py +174 -0
  165. package/dist/builtin-skills/catalog/phone-adb-automation/phone_setup.sh +274 -0
  166. package/dist/builtin-skills/catalog/phone-adb-automation/phone_swipe.sh +111 -0
  167. package/dist/builtin-skills/catalog/phone-adb-automation/phone_tap.sh +87 -0
  168. package/dist/builtin-skills/catalog/phone-adb-automation/phone_ui_parse.py +176 -0
  169. package/dist/builtin-skills/catalog/phone-adb-automation/phone_wake_unlock.sh +67 -0
  170. package/dist/builtin-skills/transcribe-audio/SKILL.md +122 -0
  171. package/dist/config/index.d.ts +7 -0
  172. package/dist/config/index.d.ts.map +1 -1
  173. package/dist/config/index.js +64 -1
  174. package/dist/config/index.js.map +1 -1
  175. package/dist/data-processing/convert-demo-cli.d.ts +7 -0
  176. package/dist/data-processing/convert-demo-cli.d.ts.map +1 -0
  177. package/dist/data-processing/convert-demo-cli.js +30 -0
  178. package/dist/data-processing/convert-demo-cli.js.map +1 -0
  179. package/dist/data-processing/convert-demo.d.ts +26 -0
  180. package/dist/data-processing/convert-demo.d.ts.map +1 -0
  181. package/dist/data-processing/convert-demo.js +233 -0
  182. package/dist/data-processing/convert-demo.js.map +1 -0
  183. package/dist/obs/rdp/icons/icons/app_windows.svg +4 -0
  184. package/dist/obs/rdp/icons/icons/clip_get.svg +4 -0
  185. package/dist/obs/rdp/icons/icons/clip_send.svg +4 -0
  186. package/dist/obs/rdp/icons/icons/clip_shared.svg +4 -0
  187. package/dist/obs/rdp/icons/icons/clipboard.svg +4 -0
  188. package/dist/obs/rdp/icons/icons/clipboard_shared.svg +4 -0
  189. package/dist/obs/rdp/icons/icons/control.svg +4 -0
  190. package/dist/obs/rdp/icons/icons/desktop.svg +4 -0
  191. package/dist/obs/rdp/icons/icons/display.svg +4 -0
  192. package/dist/obs/rdp/icons/icons/launchpad.svg +4 -0
  193. package/dist/obs/rdp/icons/icons/mission_control.svg +4 -0
  194. package/dist/obs/rdp/icons/icons/screenshot.svg +4 -0
  195. package/dist/obs/rdp/icons/icons/zoom_actual.svg +4 -0
  196. package/dist/obs/rdp/icons/icons/zoom_fit.svg +4 -0
  197. package/dist/obs/rdp/icons/icons/zoom_in.svg +4 -0
  198. package/dist/obs/rdp/icons/icons/zoom_out.svg +4 -0
  199. package/dist/obs/tunnel-telemetry.d.ts +46 -0
  200. package/dist/obs/tunnel-telemetry.d.ts.map +1 -0
  201. package/dist/obs/tunnel-telemetry.js +70 -0
  202. package/dist/obs/tunnel-telemetry.js.map +1 -0
  203. package/dist/onboarding/cloudflared-cert.d.ts +15 -0
  204. package/dist/onboarding/cloudflared-cert.d.ts.map +1 -0
  205. package/dist/onboarding/cloudflared-cert.js +57 -0
  206. package/dist/onboarding/cloudflared-cert.js.map +1 -0
  207. package/dist/onboarding/index.d.ts.map +1 -1
  208. package/dist/onboarding/index.js +15 -6
  209. package/dist/onboarding/index.js.map +1 -1
  210. package/dist/onboarding/playwriter-extension.d.ts +19 -0
  211. package/dist/onboarding/playwriter-extension.d.ts.map +1 -0
  212. package/dist/onboarding/playwriter-extension.js +246 -0
  213. package/dist/onboarding/playwriter-extension.js.map +1 -0
  214. package/dist/onboarding/provisioning-spec.d.ts +1 -0
  215. package/dist/onboarding/provisioning-spec.d.ts.map +1 -1
  216. package/dist/onboarding/provisioning-spec.js +1 -0
  217. package/dist/onboarding/provisioning-spec.js.map +1 -1
  218. package/dist/onboarding/setup-steps.d.ts.map +1 -1
  219. package/dist/onboarding/setup-steps.js +6 -7
  220. package/dist/onboarding/setup-steps.js.map +1 -1
  221. package/dist/service/gbox-tun.d.ts +14 -0
  222. package/dist/service/gbox-tun.d.ts.map +1 -0
  223. package/dist/service/gbox-tun.js +315 -0
  224. package/dist/service/gbox-tun.js.map +1 -0
  225. package/dist/skills/installed.d.ts +11 -0
  226. package/dist/skills/installed.d.ts.map +1 -0
  227. package/dist/skills/installed.js +35 -0
  228. package/dist/skills/installed.js.map +1 -0
  229. package/dist/tools/coordinate-resolver.d.ts +30 -0
  230. package/dist/tools/coordinate-resolver.d.ts.map +1 -0
  231. package/dist/tools/coordinate-resolver.js +104 -0
  232. package/dist/tools/coordinate-resolver.js.map +1 -0
  233. package/dist/utils/claude-transcripts.d.ts.map +1 -1
  234. package/dist/utils/claude-transcripts.js +9 -0
  235. package/dist/utils/claude-transcripts.js.map +1 -1
  236. package/dist/utils/playwriter-relay.d.ts +9 -0
  237. package/dist/utils/playwriter-relay.d.ts.map +1 -0
  238. package/dist/utils/playwriter-relay.js +77 -0
  239. package/dist/utils/playwriter-relay.js.map +1 -0
  240. package/dist/utils/wechat-monitor.d.ts +21 -0
  241. package/dist/utils/wechat-monitor.d.ts.map +1 -0
  242. package/dist/utils/wechat-monitor.js +88 -0
  243. package/dist/utils/wechat-monitor.js.map +1 -0
  244. package/dist-agent/bundle.cjs +1272 -677
  245. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ ## [0.1.193](https://github.com/babelcloud/visionclaw/compare/v0.1.192...v0.1.193) (2026-05-11)
2
+
3
+ ### Bug Fixes
4
+
5
+ ### Features
6
+
7
+ * Improve agent speed and more stable
8
+ * Better /refresh command to avoid stuck
9
+
10
+
1
11
  ## [0.1.192](https://github.com/babelcloud/visionclaw/compare/v0.1.191...v0.1.192) (2026-05-06)
2
12
 
3
13
  ### Bug Fixes
@@ -1 +1 @@
1
- {"version":3,"file":"api-proxy.d.ts","sourceRoot":"","sources":["../../src/agent/api-proxy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AASH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAuDD;;;GAGG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE;IACxC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,cAAc,CAAC,CA8H1B"}
1
+ {"version":3,"file":"api-proxy.d.ts","sourceRoot":"","sources":["../../src/agent/api-proxy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAUH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAiND;;;GAGG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE;IACxC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,cAAc,CAAC,CAmK1B"}
@@ -15,6 +15,7 @@ import http from "node:http";
15
15
  import https from "node:https";
16
16
  import fs from "node:fs";
17
17
  import path from "node:path";
18
+ import zlib from "node:zlib";
18
19
  import { URL } from "node:url";
19
20
  import { logger } from "../logger.js";
20
21
  let singleton = null;
@@ -27,13 +28,6 @@ const httpsAgent = new https.Agent({
27
28
  maxSockets: 10,
28
29
  ALPNProtocols: ["http/1.1"],
29
30
  });
30
- /**
31
- * Extract `<system-reminder>` text blocks from messages.
32
- *
33
- * The Claude Agent SDK injects these into user messages to provide the model
34
- * with skill descriptions, context reminders, and other metadata. We extract
35
- * them so the API log captures what the model actually sees.
36
- */
37
31
  function extractSystemReminders(messages) {
38
32
  const reminders = [];
39
33
  for (const msg of messages) {
@@ -50,6 +44,140 @@ function extractSystemReminders(messages) {
50
44
  }
51
45
  return reminders;
52
46
  }
47
+ function getHeaderValue(headers, name) {
48
+ const value = headers[name];
49
+ if (Array.isArray(value))
50
+ return value[0];
51
+ return value;
52
+ }
53
+ /**
54
+ * Decompress a buffered upstream response body for logging only.
55
+ *
56
+ * The proxy forwards the original (possibly compressed) bytes to the SDK
57
+ * client verbatim, so the SDK's transparent decompression keeps working.
58
+ * For our JSONL log we want the readable text instead, so we honor
59
+ * `content-encoding` here.
60
+ */
61
+ function decodeResponseBodyForLogging(responseBody, headers) {
62
+ if (responseBody.length === 0)
63
+ return "";
64
+ const encoding = getHeaderValue(headers, "content-encoding");
65
+ const normalized = encoding?.toLowerCase().trim();
66
+ try {
67
+ if (normalized === "gzip" || normalized === "x-gzip") {
68
+ return zlib.gunzipSync(responseBody).toString("utf-8");
69
+ }
70
+ if (normalized === "deflate") {
71
+ return zlib.inflateSync(responseBody).toString("utf-8");
72
+ }
73
+ if (normalized === "br") {
74
+ return zlib.brotliDecompressSync(responseBody).toString("utf-8");
75
+ }
76
+ }
77
+ catch (err) {
78
+ logger.warn(`[api-proxy] failed to decompress upstream body (encoding=${normalized ?? "none"}): ${err instanceof Error ? err.message : String(err)}`);
79
+ }
80
+ return responseBody.toString("utf-8");
81
+ }
82
+ function getUpstreamRequestId(headers) {
83
+ return getHeaderValue(headers, "request-id")
84
+ ?? getHeaderValue(headers, "x-request-id")
85
+ ?? getHeaderValue(headers, "anthropic-request-id")
86
+ ?? getHeaderValue(headers, "cf-request-id")
87
+ ?? getHeaderValue(headers, "x-amzn-trace-id")
88
+ ?? getHeaderValue(headers, "cf-ray")
89
+ ?? null;
90
+ }
91
+ function parseAnthropicResponseBody(responseBodyRaw) {
92
+ try {
93
+ return JSON.parse(responseBodyRaw);
94
+ }
95
+ catch {
96
+ return parseAnthropicSseFinalMessage(responseBodyRaw) ?? responseBodyRaw;
97
+ }
98
+ }
99
+ function parseAnthropicSseFinalMessage(responseBodyRaw) {
100
+ const events = responseBodyRaw.split(/\n\n+/u);
101
+ let finalMessage;
102
+ const contentBlocks = [];
103
+ let stopReason;
104
+ let stopSequence;
105
+ let usage;
106
+ for (const event of events) {
107
+ const dataLines = event
108
+ .split("\n")
109
+ .filter((line) => line.startsWith("data:"))
110
+ .map((line) => line.slice("data:".length).trim())
111
+ .filter((line) => line.length > 0 && line !== "[DONE]");
112
+ for (const dataLine of dataLines) {
113
+ let payload;
114
+ try {
115
+ payload = JSON.parse(dataLine);
116
+ }
117
+ catch {
118
+ continue;
119
+ }
120
+ if (payload.type === "message_start") {
121
+ finalMessage = payload.message;
122
+ continue;
123
+ }
124
+ if (payload.type === "content_block_start") {
125
+ const index = payload.index;
126
+ if (typeof index === "number") {
127
+ contentBlocks[index] = payload.content_block;
128
+ }
129
+ continue;
130
+ }
131
+ if (payload.type === "content_block_delta") {
132
+ const index = payload.index;
133
+ const delta = payload.delta;
134
+ if (typeof index !== "number" || !delta)
135
+ continue;
136
+ const block = contentBlocks[index] ?? {};
137
+ contentBlocks[index] = block;
138
+ if (delta.type === "text_delta" && typeof delta.text === "string") {
139
+ block.text = `${typeof block.text === "string" ? block.text : ""}${delta.text}`;
140
+ }
141
+ else if (delta.type === "input_json_delta" && typeof delta.partial_json === "string") {
142
+ block.partial_json = `${typeof block.partial_json === "string" ? block.partial_json : ""}${delta.partial_json}`;
143
+ }
144
+ continue;
145
+ }
146
+ if (payload.type === "message_delta") {
147
+ const delta = payload.delta;
148
+ stopReason = delta?.stop_reason;
149
+ stopSequence = delta?.stop_sequence;
150
+ usage = payload.usage;
151
+ }
152
+ }
153
+ }
154
+ if (!finalMessage)
155
+ return undefined;
156
+ return {
157
+ ...finalMessage,
158
+ content: contentBlocks.filter(Boolean).map(finalizeContentBlock),
159
+ stop_reason: stopReason,
160
+ stop_sequence: stopSequence,
161
+ usage: usage ?? finalMessage.usage,
162
+ };
163
+ }
164
+ function finalizeContentBlock(block) {
165
+ if (typeof block.partial_json !== "string")
166
+ return block;
167
+ const { partial_json: partialJson, ...rest } = block;
168
+ try {
169
+ return {
170
+ ...rest,
171
+ input: JSON.parse(partialJson),
172
+ };
173
+ }
174
+ catch {
175
+ return {
176
+ ...rest,
177
+ input_json_raw: partialJson,
178
+ };
179
+ }
180
+ }
53
181
  /**
54
182
  * Start the API logging proxy. Returns a handle with the assigned port.
55
183
  * Subsequent calls return the same singleton.
@@ -87,25 +215,11 @@ export async function startApiProxy(opts) {
87
215
  });
88
216
  req.on("end", () => {
89
217
  const body = Buffer.concat(chunks);
90
- // Log the request (best-effort)
218
+ const requestBodyRaw = body.toString("utf-8");
219
+ let parsedRequestBody;
91
220
  if (isMessagesEndpoint && body.length > 0) {
92
221
  try {
93
- const parsed = JSON.parse(body.toString("utf-8"));
94
- const messages = parsed.messages;
95
- const tools = parsed.tools;
96
- const entry = {
97
- timestamp: new Date().toISOString(),
98
- model: parsed.model,
99
- system: parsed.system,
100
- tools: tools ?? [],
101
- system_reminders: messages ? extractSystemReminders(messages) : [],
102
- messages_count: messages?.length ?? 0,
103
- messages_roles: messages?.map((m) => m.role ?? "unknown") ?? [],
104
- request_size_bytes: body.length,
105
- };
106
- const date = new Date().toISOString().slice(0, 10);
107
- const logPath = path.join(logDir, `api-calls-${date}.jsonl`);
108
- fs.appendFileSync(logPath, JSON.stringify(entry) + "\n", "utf-8");
222
+ parsedRequestBody = JSON.parse(requestBodyRaw);
109
223
  }
110
224
  catch {
111
225
  // Best-effort logging — don't break the proxy
@@ -122,8 +236,54 @@ export async function startApiProxy(opts) {
122
236
  headers: fwdHeaders,
123
237
  agent: httpsAgent,
124
238
  }, (proxyRes) => {
239
+ const responseChunks = [];
125
240
  res.writeHead(proxyRes.statusCode ?? 502, proxyRes.headers);
126
- proxyRes.pipe(res);
241
+ proxyRes.on("data", (chunk) => {
242
+ responseChunks.push(chunk);
243
+ res.write(chunk);
244
+ });
245
+ proxyRes.on("end", () => {
246
+ if (!res.writableEnded) {
247
+ res.end();
248
+ }
249
+ if (isMessagesEndpoint && body.length > 0) {
250
+ try {
251
+ const responseBody = Buffer.concat(responseChunks);
252
+ const responseBodyRaw = decodeResponseBodyForLogging(responseBody, proxyRes.headers);
253
+ const parsedResponseBody = parseAnthropicResponseBody(responseBodyRaw);
254
+ const messages = parsedRequestBody?.messages;
255
+ const entry = {
256
+ timestamp: new Date().toISOString(),
257
+ method: req.method,
258
+ url: req.url,
259
+ model: parsedRequestBody?.model,
260
+ request_body: parsedRequestBody ?? requestBodyRaw,
261
+ request_body_raw: requestBodyRaw,
262
+ system_reminders: messages ? extractSystemReminders(messages) : [],
263
+ messages_count: messages?.length ?? 0,
264
+ request_size_bytes: body.length,
265
+ response_status_code: proxyRes.statusCode,
266
+ upstream_request_id: getUpstreamRequestId(proxyRes.headers),
267
+ response_headers: proxyRes.headers,
268
+ response_body: parsedResponseBody,
269
+ response_body_raw: responseBodyRaw,
270
+ response_size_bytes: responseBody.length,
271
+ };
272
+ const date = new Date().toISOString().slice(0, 10);
273
+ const logPath = path.join(logDir, `api-calls-${date}.jsonl`);
274
+ fs.appendFileSync(logPath, `${JSON.stringify(entry)}\n`, "utf-8");
275
+ }
276
+ catch {
277
+ // Best-effort logging — don't break the proxy
278
+ }
279
+ }
280
+ });
281
+ proxyRes.on("error", (err) => {
282
+ logger.warn(`[api-proxy] upstream response error: ${err.message}`);
283
+ if (!res.writableEnded) {
284
+ res.destroy(err);
285
+ }
286
+ });
127
287
  });
128
288
  proxyReq.on("error", (err) => {
129
289
  if (!req.destroyed) {
@@ -1 +1 @@
1
- {"version":3,"file":"api-proxy.js","sourceRoot":"","sources":["../../src/agent/api-proxy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"api-proxy.js","sourceRoot":"","sources":["../../src/agent/api-proxy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Applied-credential signature manifest.
3
+ *
4
+ * Persisted alongside materialised tunnel credentials at
5
+ * `<profileTunnelDir>/.applied-signature.json`. Records the signature
6
+ * the server handed us with the last bundle we successfully applied.
7
+ *
8
+ * The manifest is the *only* piece of state the agent has to remember
9
+ * across process restarts about credential bundles — everything else
10
+ * (creds JSON, config.yml) is reconstructable from a fresh server
11
+ * delivery. The signature is opaque to us; we just echo it back on the
12
+ * next heartbeat so the server can decide whether to re-ship the body.
13
+ *
14
+ * Self-healing properties (intentional):
15
+ * - Manifest missing on disk → no signature sent → server sends
16
+ * bundle → we re-apply and rewrite the manifest. Recovers any
17
+ * install where the manifest was deleted but credentials weren't,
18
+ * or vice versa.
19
+ * - Manifest present but probe says no live tunnel files → we treat
20
+ * the manifest as unusable (return null from `loadIfValid`), the
21
+ * next heartbeat goes signature-free, the server re-ships the
22
+ * bundle, and we land back in a coherent state.
23
+ * - Process restart with everything intact → manifest signature is
24
+ * sent on the startup heartbeat, server replies with no
25
+ * `credentialBundle`, no disk writes, no tunnel restart.
26
+ */
27
+ /**
28
+ * Read the persisted signature, if any. Returns `null` when the file
29
+ * does not exist, fails to parse, has the wrong shape, or refers to a
30
+ * tunnel state that no longer matches what's on disk.
31
+ *
32
+ * The on-disk-coherence check (`probeLocalTunnelCredential()`) is what
33
+ * gives us self-healing: a stranded manifest from a wiped tunnel dir
34
+ * gets ignored, forcing a fresh bundle on the next heartbeat.
35
+ */
36
+ export declare function loadAppliedSignatureIfValid(): string | null;
37
+ /**
38
+ * Persist the signature for the most recently applied bundle. Best-
39
+ * effort: a write failure is logged but does not throw, since the
40
+ * worst case is just an extra full-bundle delivery on the next
41
+ * heartbeat.
42
+ *
43
+ * The file is written with 0o600 to match the credentials sitting next
44
+ * to it; the directory itself is already 0o700 from
45
+ * `runtime-credentials.ts`.
46
+ */
47
+ export declare function writeAppliedSignature(signature: string): void;
48
+ /**
49
+ * Forget the persisted signature. Used by tests; production code never
50
+ * needs to delete it explicitly because writes overwrite in place.
51
+ */
52
+ export declare function __clearAppliedSignatureForTests(): void;
53
+ //# sourceMappingURL=applied-credential-signature.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"applied-credential-signature.d.ts","sourceRoot":"","sources":["../../src/agent/applied-credential-signature.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAwBH;;;;;;;;GAQG;AACH,wBAAgB,2BAA2B,IAAI,MAAM,GAAG,IAAI,CA2C3D;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAgC7D;AAED;;;GAGG;AACH,wBAAgB,+BAA+B,IAAI,IAAI,CAMtD"}
@@ -0,0 +1,137 @@
1
+ /**
2
+ * Applied-credential signature manifest.
3
+ *
4
+ * Persisted alongside materialised tunnel credentials at
5
+ * `<profileTunnelDir>/.applied-signature.json`. Records the signature
6
+ * the server handed us with the last bundle we successfully applied.
7
+ *
8
+ * The manifest is the *only* piece of state the agent has to remember
9
+ * across process restarts about credential bundles — everything else
10
+ * (creds JSON, config.yml) is reconstructable from a fresh server
11
+ * delivery. The signature is opaque to us; we just echo it back on the
12
+ * next heartbeat so the server can decide whether to re-ship the body.
13
+ *
14
+ * Self-healing properties (intentional):
15
+ * - Manifest missing on disk → no signature sent → server sends
16
+ * bundle → we re-apply and rewrite the manifest. Recovers any
17
+ * install where the manifest was deleted but credentials weren't,
18
+ * or vice versa.
19
+ * - Manifest present but probe says no live tunnel files → we treat
20
+ * the manifest as unusable (return null from `loadIfValid`), the
21
+ * next heartbeat goes signature-free, the server re-ships the
22
+ * bundle, and we land back in a coherent state.
23
+ * - Process restart with everything intact → manifest signature is
24
+ * sent on the startup heartbeat, server replies with no
25
+ * `credentialBundle`, no disk writes, no tunnel restart.
26
+ */
27
+ import fs from "node:fs";
28
+ import path from "node:path";
29
+ import { getProfileTunnelDir } from "../config/index.js";
30
+ import { probeLocalTunnelCredential } from "./runtime-credentials.js";
31
+ import { logger } from "../logger.js";
32
+ const MANIFEST_FILENAME = ".applied-signature.json";
33
+ const MANIFEST_VERSION = 1;
34
+ function getManifestPath() {
35
+ return path.join(getProfileTunnelDir(), MANIFEST_FILENAME);
36
+ }
37
+ /**
38
+ * Read the persisted signature, if any. Returns `null` when the file
39
+ * does not exist, fails to parse, has the wrong shape, or refers to a
40
+ * tunnel state that no longer matches what's on disk.
41
+ *
42
+ * The on-disk-coherence check (`probeLocalTunnelCredential()`) is what
43
+ * gives us self-healing: a stranded manifest from a wiped tunnel dir
44
+ * gets ignored, forcing a fresh bundle on the next heartbeat.
45
+ */
46
+ export function loadAppliedSignatureIfValid() {
47
+ const manifestPath = getManifestPath();
48
+ if (!fs.existsSync(manifestPath))
49
+ return null;
50
+ let raw;
51
+ try {
52
+ raw = fs.readFileSync(manifestPath, "utf-8");
53
+ }
54
+ catch (err) {
55
+ logger.warn(`Applied-signature manifest unreadable: ${err instanceof Error ? err.message : String(err)}`);
56
+ return null;
57
+ }
58
+ let parsed;
59
+ try {
60
+ parsed = JSON.parse(raw);
61
+ }
62
+ catch {
63
+ logger.warn(`Applied-signature manifest malformed; ignoring`);
64
+ return null;
65
+ }
66
+ if (!parsed ||
67
+ typeof parsed !== "object" ||
68
+ !("signature" in parsed) ||
69
+ typeof parsed.signature !== "string" ||
70
+ parsed.signature.trim() === "") {
71
+ return null;
72
+ }
73
+ const signature = parsed.signature.trim();
74
+ // Coherence: a manifest is only meaningful when the credentials it
75
+ // refers to actually still exist on disk. If the tunnel files were
76
+ // wiped (e.g. operator deleted `~/.visionclaw/profiles/default/tunnel`)
77
+ // the stored signature lies about our state, so pretend we have none
78
+ // and let the server reissue the bundle.
79
+ if (probeLocalTunnelCredential() === null) {
80
+ return null;
81
+ }
82
+ return signature;
83
+ }
84
+ /**
85
+ * Persist the signature for the most recently applied bundle. Best-
86
+ * effort: a write failure is logged but does not throw, since the
87
+ * worst case is just an extra full-bundle delivery on the next
88
+ * heartbeat.
89
+ *
90
+ * The file is written with 0o600 to match the credentials sitting next
91
+ * to it; the directory itself is already 0o700 from
92
+ * `runtime-credentials.ts`.
93
+ */
94
+ export function writeAppliedSignature(signature) {
95
+ if (typeof signature !== "string" || signature.trim() === "")
96
+ return;
97
+ const manifestPath = getManifestPath();
98
+ const dir = path.dirname(manifestPath);
99
+ try {
100
+ fs.mkdirSync(dir, { recursive: true });
101
+ }
102
+ catch {
103
+ // best-effort; the credential apply path will have created it
104
+ }
105
+ const payload = {
106
+ version: MANIFEST_VERSION,
107
+ signature: signature.trim(),
108
+ appliedAt: new Date().toISOString(),
109
+ };
110
+ try {
111
+ fs.writeFileSync(manifestPath, JSON.stringify(payload, null, 2), "utf-8");
112
+ if (process.platform !== "win32") {
113
+ try {
114
+ fs.chmodSync(manifestPath, 0o600);
115
+ }
116
+ catch {
117
+ // best-effort; directory perms still protect
118
+ }
119
+ }
120
+ }
121
+ catch (err) {
122
+ logger.warn(`Failed to persist applied-signature manifest: ${err instanceof Error ? err.message : String(err)}`);
123
+ }
124
+ }
125
+ /**
126
+ * Forget the persisted signature. Used by tests; production code never
127
+ * needs to delete it explicitly because writes overwrite in place.
128
+ */
129
+ export function __clearAppliedSignatureForTests() {
130
+ try {
131
+ fs.rmSync(getManifestPath(), { force: true });
132
+ }
133
+ catch {
134
+ // ignore
135
+ }
136
+ }
137
+ //# sourceMappingURL=applied-credential-signature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"applied-credential-signature.js","sourceRoot":"","sources":["../../src/agent/applied-credential-signature.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"command-handlers.d.ts","sourceRoot":"","sources":["../../src/agent/command-handlers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AA2BxE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,KAAK,UAAU,EAAuB,MAAM,YAAY,CAAC;AAkBlE,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,UAAU,CAAC;IACvB,cAAc,EAAE,cAAc,CAAC;IAC/B,YAAY,EAAE,YAAY,CAAC;IAC3B,OAAO,EAAE,cAAc,CAAC;IACxB,MAAM,EAAE,gBAAgB,CAAC;IACzB,WAAW,EAAE,WAAW,CAAC;IACzB,SAAS,EAAE,gBAAgB,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAChC;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,kBAAkB,GAAG,IAAI,CAi3BtE"}
1
+ {"version":3,"file":"command-handlers.d.ts","sourceRoot":"","sources":["../../src/agent/command-handlers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AA2BxE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,KAAK,UAAU,EAAuB,MAAM,YAAY,CAAC;AAkBlE,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,UAAU,CAAC;IACvB,cAAc,EAAE,cAAc,CAAC;IAC/B,YAAY,EAAE,YAAY,CAAC;IAC3B,OAAO,EAAE,cAAc,CAAC;IACxB,MAAM,EAAE,gBAAgB,CAAC;IACzB,WAAW,EAAE,WAAW,CAAC;IACzB,SAAS,EAAE,gBAAgB,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAChC;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,kBAAkB,GAAG,IAAI,CA83BtE"}
@@ -386,9 +386,6 @@ export function registerCommandHandlers(deps) {
386
386
  const doRefresh = async () => {
387
387
  // Claim the `compacting` mutex upfront so the main loop's wake gate
388
388
  // won't start a new turn on the same session while we compact it.
389
- // Claude's requestCompaction() also manages this flag internally; our
390
- // early claim covers the window between requestStop() and the compact
391
- // call, and the OpenAI provider (which doesn't touch the flag).
392
389
  agentState.compacting = true;
393
390
  try {
394
391
  if (agentState.busy) {
@@ -421,14 +418,28 @@ export function registerCommandHandlers(deps) {
421
418
  return;
422
419
  }
423
420
  await channelManager.sendMessage(req.channel, req.sender, t("cmd.refresh.refreshing", getLocale()));
424
- await activeSession.requestCompaction();
425
- // Enqueue a system message so the agent re-orients after compaction
426
- // (task details may be lost in the summary).
421
+ // Summarize the current transcript before resetting
422
+ const transcriptPath = activeSession.getTranscriptPath();
423
+ let summary = null;
424
+ if (transcriptPath) {
425
+ const { summarizeTranscript } = await import("./transcript-summarizer.js");
426
+ summary = await summarizeTranscript(transcriptPath, config);
427
+ }
428
+ // If LLM summary failed, use a fallback instruction
429
+ const finalSummary = summary ??
430
+ "The previous session transcript could not be summarized automatically. " +
431
+ "Use the `memory_transcript_search` tool to look up your recent activity " +
432
+ "and rebuild context. Also check your memory directory and todo list.";
433
+ // Perform the full session reset
434
+ session.resetActiveSession(finalSummary);
435
+ // Re-enqueue pending messages so they're delivered to the new session
427
436
  messageQueue.enqueue({
428
437
  id: `refresh_cmd_${Date.now()}`,
429
438
  channel: "system",
430
439
  sender: "system",
431
- text: "The owner manually triggered a context refresh (compaction). Review your current task and todo list to make sure you haven't lost track of what you were working on.",
440
+ text: "The owner manually triggered a full context refresh. A new session has been created. " +
441
+ "The summary of your previous session has been injected as context above. " +
442
+ "Review it, check your memory and todo list, and continue where you left off.",
432
443
  attachments: [],
433
444
  timestamp: new Date().toISOString(),
434
445
  });