@asm-agent/coding-agent 0.8.7 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (195) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +2 -7
  3. package/dist/asm-agent-runtime/src/__pycache__/asm_cm_driver.cpython-313.pyc +0 -0
  4. package/dist/asm-agent-runtime/src/__pycache__/phase76_address_head.cpython-313.pyc +0 -0
  5. package/dist/asm-agent-runtime/src/rlm/__init__.py +1 -1
  6. package/dist/asm-agent-runtime/src/rlm/__pycache__/__init__.cpython-312.pyc +0 -0
  7. package/dist/asm-agent-runtime/src/rlm/__pycache__/__init__.cpython-313.pyc +0 -0
  8. package/dist/asm-agent-runtime/src/rlm/__pycache__/_winjob.cpython-313.pyc +0 -0
  9. package/dist/asm-agent-runtime/src/rlm/__pycache__/bash.cpython-312.pyc +0 -0
  10. package/dist/asm-agent-runtime/src/rlm/__pycache__/bash.cpython-313.pyc +0 -0
  11. package/dist/asm-agent-runtime/src/rlm/__pycache__/harness.cpython-313.pyc +0 -0
  12. package/dist/asm-agent-runtime/src/rlm/__pycache__/mcp.cpython-312.pyc +0 -0
  13. package/dist/asm-agent-runtime/src/rlm/__pycache__/mcp.cpython-313.pyc +0 -0
  14. package/dist/asm-agent-runtime/src/rlm/__pycache__/mcp_base.cpython-312.pyc +0 -0
  15. package/dist/asm-agent-runtime/src/rlm/__pycache__/mcp_base.cpython-313.pyc +0 -0
  16. package/dist/asm-agent-runtime/src/rlm/__pycache__/repl.cpython-312.pyc +0 -0
  17. package/dist/asm-agent-runtime/src/rlm/__pycache__/repl.cpython-313.pyc +0 -0
  18. package/dist/asm-agent-runtime/src/rlm/__pycache__/skill.cpython-313.pyc +0 -0
  19. package/dist/asm-agent-runtime/src/rlm/bash.py +94 -31
  20. package/dist/asm-agent-runtime/src/rlm/repl.md +3 -3
  21. package/dist/asm-agent-runtime/src/rlm/repl.py +46 -45
  22. package/dist/asm-agent-runtime/test/__pycache__/test_agent_message_skill.cpython-313.pyc +0 -0
  23. package/dist/asm-agent-runtime/test/__pycache__/test_bash.cpython-313.pyc +0 -0
  24. package/dist/asm-agent-runtime/test/__pycache__/test_harness.cpython-313.pyc +0 -0
  25. package/dist/asm-agent-runtime/test/__pycache__/test_mcp.cpython-313.pyc +0 -0
  26. package/dist/asm-agent-runtime/test/__pycache__/test_mcp_base.cpython-313.pyc +0 -0
  27. package/dist/asm-agent-runtime/test/__pycache__/test_repl.cpython-313.pyc +0 -0
  28. package/dist/asm-agent-runtime/test/__pycache__/test_subagent_registry.cpython-313.pyc +0 -0
  29. package/dist/asm-agent-runtime/test/__pycache__/test_winjob.cpython-313.pyc +0 -0
  30. package/dist/asm-agent-runtime/test/test_bash.py +74 -19
  31. package/dist/asm-agent-runtime/test/test_repl.py +67 -3
  32. package/dist/asm-agent-runtime/uv.lock +446 -155
  33. package/dist/bundle/{anthropic-XSMQHGYB.js → anthropic-ZOZNPFXS.js} +2 -2
  34. package/dist/bundle/{azure-openai-responses-XLQAIKKH.js → azure-openai-responses-TDHCU647.js} +2 -2
  35. package/dist/bundle/{bundled-modules-5OCN73BM.js → bundled-modules-Q2YODC4B.js} +3 -3
  36. package/dist/bundle/{chunk-IAQLPSMN.js → chunk-AMKLNEAK.js} +47 -47
  37. package/dist/bundle/{chunk-2LPSALBF.js → chunk-FPY7FFJS.js} +978 -1821
  38. package/dist/bundle/{chunk-E3YE2Q7A.js → chunk-G6SC4YYW.js} +4973 -1926
  39. package/dist/bundle/{chunk-YPNK4MRU.js → chunk-QLHAP3FT.js} +1 -1
  40. package/dist/bundle/{cli-main-QYX5R3LF.js → cli-main-277AG2BR.js} +3 -3
  41. package/dist/bundle/cli.js +1 -1
  42. package/dist/bundle/{google-ZXJEPWJA.js → google-Q3AJWUOY.js} +1 -1
  43. package/dist/bundle/{google-vertex-WAF3RIJ6.js → google-vertex-2CSNOUBS.js} +1 -1
  44. package/dist/bundle/{main-EOUAQCJH.js → main-TNXWJXIU.js} +3 -3
  45. package/dist/bundle/{mistral-GDZXSXRS.js → mistral-XRYJGLLG.js} +1 -1
  46. package/dist/bundle/{openai-codex-responses-7XMPW4LG.js → openai-codex-responses-C6BRO2BN.js} +2 -2
  47. package/dist/bundle/{openai-completions-LNSVGDMF.js → openai-completions-DNXCK2JW.js} +4 -4
  48. package/dist/bundle/{openai-responses-MFZOBMIT.js → openai-responses-BEMWVIXE.js} +2 -2
  49. package/dist/config.d.ts +0 -1
  50. package/dist/config.d.ts.map +1 -1
  51. package/dist/config.js +0 -3
  52. package/dist/config.js.map +1 -1
  53. package/dist/core/agent-session-config.d.ts +1 -2
  54. package/dist/core/agent-session-config.d.ts.map +1 -1
  55. package/dist/core/agent-session-config.js +0 -3
  56. package/dist/core/agent-session-config.js.map +1 -1
  57. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  58. package/dist/core/agent-session-runtime.js +0 -8
  59. package/dist/core/agent-session-runtime.js.map +1 -1
  60. package/dist/core/agent-session-services.d.ts +0 -2
  61. package/dist/core/agent-session-services.d.ts.map +1 -1
  62. package/dist/core/agent-session-services.js +0 -22
  63. package/dist/core/agent-session-services.js.map +1 -1
  64. package/dist/core/agent-session.d.ts +8 -1
  65. package/dist/core/agent-session.d.ts.map +1 -1
  66. package/dist/core/agent-session.js +100 -22
  67. package/dist/core/agent-session.js.map +1 -1
  68. package/dist/core/kernel/bootstrap.d.ts.map +1 -1
  69. package/dist/core/kernel/bootstrap.js +1 -1
  70. package/dist/core/kernel/bootstrap.js.map +1 -1
  71. package/dist/core/kernel/repl-manager.d.ts +32 -8
  72. package/dist/core/kernel/repl-manager.d.ts.map +1 -1
  73. package/dist/core/kernel/repl-manager.js +401 -102
  74. package/dist/core/kernel/repl-manager.js.map +1 -1
  75. package/dist/core/kernel/shared.d.ts +11 -7
  76. package/dist/core/kernel/shared.d.ts.map +1 -1
  77. package/dist/core/kernel/shared.js +2 -5
  78. package/dist/core/kernel/shared.js.map +1 -1
  79. package/dist/core/mcp/mcp-manager.d.ts +4 -2
  80. package/dist/core/mcp/mcp-manager.d.ts.map +1 -1
  81. package/dist/core/mcp/mcp-manager.js +9 -7
  82. package/dist/core/mcp/mcp-manager.js.map +1 -1
  83. package/dist/core/model-registry.d.ts.map +1 -1
  84. package/dist/core/model-registry.js +1 -1
  85. package/dist/core/model-registry.js.map +1 -1
  86. package/dist/core/ollama-models.d.ts +3 -1
  87. package/dist/core/ollama-models.d.ts.map +1 -1
  88. package/dist/core/ollama-models.js +31 -10
  89. package/dist/core/ollama-models.js.map +1 -1
  90. package/dist/core/prime-inference-auth.d.ts +0 -9
  91. package/dist/core/prime-inference-auth.d.ts.map +1 -1
  92. package/dist/core/prime-inference-auth.js +0 -50
  93. package/dist/core/prime-inference-auth.js.map +1 -1
  94. package/dist/core/provider-display-names.d.ts.map +1 -1
  95. package/dist/core/provider-display-names.js +0 -1
  96. package/dist/core/provider-display-names.js.map +1 -1
  97. package/dist/core/session-manager.d.ts +0 -4
  98. package/dist/core/session-manager.d.ts.map +1 -1
  99. package/dist/core/session-manager.js +0 -22
  100. package/dist/core/session-manager.js.map +1 -1
  101. package/dist/core/settings-manager.d.ts +4 -16
  102. package/dist/core/settings-manager.d.ts.map +1 -1
  103. package/dist/core/settings-manager.js +13 -43
  104. package/dist/core/settings-manager.js.map +1 -1
  105. package/dist/core/slash-commands.d.ts.map +1 -1
  106. package/dist/core/slash-commands.js +0 -5
  107. package/dist/core/slash-commands.js.map +1 -1
  108. package/dist/core/tools/acp-mcp.d.ts +6 -0
  109. package/dist/core/tools/acp-mcp.d.ts.map +1 -0
  110. package/dist/core/tools/acp-mcp.js +86 -0
  111. package/dist/core/tools/acp-mcp.js.map +1 -0
  112. package/dist/core/tools/index.d.ts +1 -0
  113. package/dist/core/tools/index.d.ts.map +1 -1
  114. package/dist/core/tools/index.js +1 -0
  115. package/dist/core/tools/index.js.map +1 -1
  116. package/dist/core/tools/ipython.d.ts.map +1 -1
  117. package/dist/core/tools/ipython.js +9 -4
  118. package/dist/core/tools/ipython.js.map +1 -1
  119. package/dist/main.d.ts.map +1 -1
  120. package/dist/main.js +2 -11
  121. package/dist/main.js.map +1 -1
  122. package/dist/modes/acp/acp-mode.d.ts.map +1 -1
  123. package/dist/modes/acp/acp-mode.js +1 -1
  124. package/dist/modes/acp/acp-mode.js.map +1 -1
  125. package/dist/modes/agent-connection/daemon-agent-connection.d.ts +0 -2
  126. package/dist/modes/agent-connection/daemon-agent-connection.d.ts.map +1 -1
  127. package/dist/modes/agent-connection/daemon-agent-connection.js +0 -2
  128. package/dist/modes/agent-connection/daemon-agent-connection.js.map +1 -1
  129. package/dist/modes/agents-view/agents-view-mode.d.ts.map +1 -1
  130. package/dist/modes/agents-view/agents-view-mode.js +0 -19
  131. package/dist/modes/agents-view/agents-view-mode.js.map +1 -1
  132. package/dist/modes/daemon/daemon-mode.d.ts +1 -10
  133. package/dist/modes/daemon/daemon-mode.d.ts.map +1 -1
  134. package/dist/modes/daemon/daemon-mode.js +134 -274
  135. package/dist/modes/daemon/daemon-mode.js.map +1 -1
  136. package/dist/modes/daemon/daemon-protocol.d.ts +11 -5
  137. package/dist/modes/daemon/daemon-protocol.d.ts.map +1 -1
  138. package/dist/modes/daemon/daemon-protocol.js +6 -8
  139. package/dist/modes/daemon/daemon-protocol.js.map +1 -1
  140. package/dist/modes/daemon/daemon-supervisor.d.ts +0 -3
  141. package/dist/modes/daemon/daemon-supervisor.d.ts.map +1 -1
  142. package/dist/modes/daemon/daemon-supervisor.js +18 -52
  143. package/dist/modes/daemon/daemon-supervisor.js.map +1 -1
  144. package/dist/modes/daemon/daemon-worker-protocol.d.ts +1 -6
  145. package/dist/modes/daemon/daemon-worker-protocol.d.ts.map +1 -1
  146. package/dist/modes/daemon/daemon-worker-protocol.js +0 -2
  147. package/dist/modes/daemon/daemon-worker-protocol.js.map +1 -1
  148. package/dist/modes/interactive/auth-flows.d.ts +0 -2
  149. package/dist/modes/interactive/auth-flows.d.ts.map +1 -1
  150. package/dist/modes/interactive/auth-flows.js +1 -101
  151. package/dist/modes/interactive/auth-flows.js.map +1 -1
  152. package/dist/modes/interactive/components/assistant-message.d.ts +6 -1
  153. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  154. package/dist/modes/interactive/components/assistant-message.js +13 -3
  155. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  156. package/dist/modes/interactive/components/footer.d.ts +1 -1
  157. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  158. package/dist/modes/interactive/components/footer.js +2 -2
  159. package/dist/modes/interactive/components/footer.js.map +1 -1
  160. package/dist/modes/interactive/components/mermaid.d.ts +12 -0
  161. package/dist/modes/interactive/components/mermaid.d.ts.map +1 -0
  162. package/dist/modes/interactive/components/mermaid.js +63 -0
  163. package/dist/modes/interactive/components/mermaid.js.map +1 -0
  164. package/dist/modes/interactive/components/settings-selector.d.ts +3 -1
  165. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  166. package/dist/modes/interactive/components/settings-selector.js +10 -0
  167. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  168. package/dist/modes/interactive/feature-hints.d.ts.map +1 -1
  169. package/dist/modes/interactive/feature-hints.js +0 -4
  170. package/dist/modes/interactive/feature-hints.js.map +1 -1
  171. package/dist/modes/interactive/interactive-mode.d.ts +1 -7
  172. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  173. package/dist/modes/interactive/interactive-mode.js +23 -279
  174. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  175. package/dist/utils/version-check.d.ts.map +1 -1
  176. package/dist/utils/version-check.js +1 -1
  177. package/dist/utils/version-check.js.map +1 -1
  178. package/docs/settings.md +1 -31
  179. package/docs/usage.md +1 -4
  180. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  181. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  182. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  183. package/examples/extensions/sandbox/package-lock.json +2 -2
  184. package/examples/extensions/sandbox/package.json +1 -1
  185. package/examples/extensions/with-deps/package-lock.json +2 -2
  186. package/examples/extensions/with-deps/package.json +1 -1
  187. package/package.json +6 -5
  188. package/dist/core/agent-traces.d.ts +0 -130
  189. package/dist/core/agent-traces.d.ts.map +0 -1
  190. package/dist/core/agent-traces.js +0 -746
  191. package/dist/core/agent-traces.js.map +0 -1
  192. package/dist/core/telemetry.d.ts +0 -92
  193. package/dist/core/telemetry.d.ts.map +0 -1
  194. package/dist/core/telemetry.js +0 -633
  195. package/dist/core/telemetry.js.map +0 -1
@@ -1,633 +0,0 @@
1
- import { randomUUID } from "node:crypto";
2
- import { lstatSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
3
- import { arch, platform } from "node:os";
4
- import { join } from "node:path";
5
- import { detectInstallMethod, VERSION } from "../config.js";
6
- import { isBuiltinSlashCommandName, resolveBuiltinSlashCommandName } from "./slash-commands.js";
7
- const DEFAULT_TELEMETRY_ENDPOINT = "https://api.primeintellect.ai/api/v1/agent-analytics/events";
8
- const TELEMETRY_STATE_FILE = "telemetry.json";
9
- const TELEMETRY_STATE_VERSION = 1;
10
- const DEFAULT_BATCH_SIZE = 10;
11
- const DEFAULT_FLUSH_INTERVAL_MS = 10_000;
12
- const DEFAULT_REQUEST_TIMEOUT_MS = 1_500;
13
- const EMPTY_USAGE_TOTALS = {
14
- input: 0,
15
- output: 0,
16
- cacheRead: 0,
17
- cacheWrite: 0,
18
- totalTokens: 0,
19
- cost: {
20
- input: 0,
21
- output: 0,
22
- cacheRead: 0,
23
- cacheWrite: 0,
24
- total: 0,
25
- },
26
- modelCallCount: 0,
27
- };
28
- function newUsageTotals() {
29
- return structuredClone(EMPTY_USAGE_TOTALS);
30
- }
31
- function addUsage(target, usage) {
32
- target.input += usage.input;
33
- target.output += usage.output;
34
- target.cacheRead += usage.cacheRead;
35
- target.cacheWrite += usage.cacheWrite;
36
- target.totalTokens += usage.totalTokens;
37
- target.cost.input += usage.cost.input;
38
- target.cost.output += usage.cost.output;
39
- target.cost.cacheRead += usage.cost.cacheRead;
40
- target.cost.cacheWrite += usage.cost.cacheWrite;
41
- target.cost.total += usage.cost.total;
42
- target.modelCallCount++;
43
- }
44
- function mergeUsage(target, usage) {
45
- target.input += usage.input;
46
- target.output += usage.output;
47
- target.cacheRead += usage.cacheRead;
48
- target.cacheWrite += usage.cacheWrite;
49
- target.totalTokens += usage.totalTokens;
50
- target.cost.input += usage.cost.input;
51
- target.cost.output += usage.cost.output;
52
- target.cost.cacheRead += usage.cost.cacheRead;
53
- target.cost.cacheWrite += usage.cost.cacheWrite;
54
- target.cost.total += usage.cost.total;
55
- target.modelCallCount += usage.modelCallCount;
56
- }
57
- function parseBooleanOverride(value) {
58
- if (value === undefined) {
59
- return undefined;
60
- }
61
- const normalized = value.trim().toLowerCase();
62
- if (["1", "true", "yes", "on"].includes(normalized)) {
63
- return true;
64
- }
65
- if (["0", "false", "no", "off"].includes(normalized)) {
66
- return false;
67
- }
68
- return undefined;
69
- }
70
- export function isTelemetryEnabled(settingsManager) {
71
- if (parseBooleanOverride(process.env.PI_OFFLINE) === true) {
72
- return false;
73
- }
74
- if (parseBooleanOverride(process.env.DO_NOT_TRACK) === true) {
75
- return false;
76
- }
77
- const override = parseBooleanOverride(process.env.ASM_AGENT_TELEMETRY);
78
- if (override !== undefined) {
79
- return override;
80
- }
81
- if (process.env.NODE_ENV === "test") {
82
- return false;
83
- }
84
- return settingsManager.getTelemetryEnabled();
85
- }
86
- function isInstallationId(value) {
87
- return (typeof value === "string" &&
88
- /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value));
89
- }
90
- function readInstallationId(path) {
91
- try {
92
- const parsed = JSON.parse(readFileSync(path, "utf8"));
93
- return parsed.version === TELEMETRY_STATE_VERSION && isInstallationId(parsed.installationId)
94
- ? parsed.installationId
95
- : undefined;
96
- }
97
- catch {
98
- return undefined;
99
- }
100
- }
101
- function writeTelemetryStateAtomically(path, state) {
102
- const temporaryPath = `${path}.${process.pid}.${randomUUID()}.tmp`;
103
- try {
104
- writeFileSync(temporaryPath, JSON.stringify(state, null, 2), {
105
- encoding: "utf8",
106
- flag: "wx",
107
- mode: 0o600,
108
- });
109
- renameSync(temporaryPath, path);
110
- }
111
- finally {
112
- try {
113
- unlinkSync(temporaryPath);
114
- }
115
- catch {
116
- // The rename succeeded or the temporary file was never created.
117
- }
118
- }
119
- }
120
- export function getOrCreateTelemetryInstallationId(agentDir, randomId = randomUUID) {
121
- const path = join(agentDir, TELEMETRY_STATE_FILE);
122
- let replaceInvalidState = false;
123
- try {
124
- const stats = lstatSync(path);
125
- if (!stats.isFile()) {
126
- throw new Error("Telemetry state path must be a regular file");
127
- }
128
- const existing = readInstallationId(path);
129
- if (existing) {
130
- return existing;
131
- }
132
- replaceInvalidState = true;
133
- }
134
- catch (error) {
135
- const code = typeof error === "object" && error !== null && "code" in error
136
- ? String(error.code)
137
- : undefined;
138
- if (code !== "ENOENT") {
139
- throw error;
140
- }
141
- }
142
- const installationId = randomId();
143
- if (!isInstallationId(installationId)) {
144
- throw new Error("Telemetry installation ID generator returned an invalid UUID");
145
- }
146
- mkdirSync(agentDir, { recursive: true });
147
- const state = {
148
- version: TELEMETRY_STATE_VERSION,
149
- installationId,
150
- };
151
- try {
152
- if (replaceInvalidState) {
153
- writeTelemetryStateAtomically(path, state);
154
- }
155
- else {
156
- writeFileSync(path, JSON.stringify(state, null, 2), {
157
- encoding: "utf8",
158
- flag: "wx",
159
- mode: 0o600,
160
- });
161
- }
162
- return installationId;
163
- }
164
- catch (error) {
165
- const code = typeof error === "object" && error !== null && "code" in error
166
- ? String(error.code)
167
- : undefined;
168
- if (code !== "EEXIST") {
169
- throw error;
170
- }
171
- return readInstallationId(path) ?? installationId;
172
- }
173
- }
174
- export class TelemetryClient {
175
- options;
176
- endpoint;
177
- fetchImpl;
178
- now;
179
- randomId;
180
- batchSize;
181
- flushIntervalMs;
182
- requestTimeoutMs;
183
- installationId;
184
- queue = [];
185
- flushTimer;
186
- flushInFlight;
187
- disabled = false;
188
- constructor(options) {
189
- this.options = options;
190
- this.endpoint = options.endpoint ?? process.env.ASM_AGENT_TELEMETRY_ENDPOINT ?? DEFAULT_TELEMETRY_ENDPOINT;
191
- this.fetchImpl = options.fetch ?? fetch;
192
- this.now = options.now ?? Date.now;
193
- this.randomId = options.randomId ?? randomUUID;
194
- this.batchSize = options.batchSize ?? DEFAULT_BATCH_SIZE;
195
- this.flushIntervalMs = options.flushIntervalMs ?? DEFAULT_FLUSH_INTERVAL_MS;
196
- this.requestTimeoutMs = options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
197
- }
198
- capture(name, properties) {
199
- if (this.disabled) {
200
- return;
201
- }
202
- try {
203
- this.installationId ??= getOrCreateTelemetryInstallationId(this.options.agentDir, this.randomId);
204
- this.queue.push({
205
- id: this.randomId(),
206
- name,
207
- timestamp: new Date(this.now()).toISOString(),
208
- properties,
209
- });
210
- }
211
- catch {
212
- this.disabled = true;
213
- this.queue = [];
214
- return;
215
- }
216
- if (this.queue.length >= this.batchSize) {
217
- void this.flush();
218
- return;
219
- }
220
- this.scheduleFlush();
221
- }
222
- scheduleFlush() {
223
- if (this.flushTimer) {
224
- return;
225
- }
226
- this.flushTimer = setTimeout(() => {
227
- this.flushTimer = undefined;
228
- void this.flush();
229
- }, this.flushIntervalMs);
230
- this.flushTimer.unref?.();
231
- }
232
- async flush() {
233
- if (this.flushTimer) {
234
- clearTimeout(this.flushTimer);
235
- this.flushTimer = undefined;
236
- }
237
- if (this.flushInFlight) {
238
- await this.flushInFlight;
239
- if (this.queue.length > 0) {
240
- await this.flush();
241
- }
242
- return;
243
- }
244
- if (this.queue.length === 0 || !this.installationId) {
245
- return;
246
- }
247
- const drain = this.drainQueue();
248
- this.flushInFlight = drain;
249
- try {
250
- await drain;
251
- }
252
- finally {
253
- if (this.flushInFlight === drain) {
254
- this.flushInFlight = undefined;
255
- }
256
- }
257
- if (this.queue.length > 0) {
258
- await this.flush();
259
- }
260
- }
261
- async drainQueue() {
262
- while (this.queue.length > 0 && this.installationId) {
263
- const events = this.queue.splice(0, this.batchSize);
264
- const batch = {
265
- installation_id: this.installationId,
266
- events,
267
- };
268
- await this.send(batch);
269
- }
270
- }
271
- async send(batch) {
272
- try {
273
- await this.fetchImpl(this.endpoint, {
274
- method: "POST",
275
- headers: {
276
- "content-type": "application/json",
277
- "user-agent": `asm-agent/${VERSION}`,
278
- },
279
- body: JSON.stringify(batch),
280
- signal: AbortSignal.timeout(this.requestTimeoutMs),
281
- });
282
- }
283
- catch {
284
- // Product analytics is best-effort and must never affect the agent.
285
- }
286
- }
287
- }
288
- function modelCategory(model) {
289
- const normalized = model.toLowerCase();
290
- const categories = [
291
- "claude",
292
- "gpt",
293
- "o1",
294
- "o3",
295
- "o4",
296
- "gemini",
297
- "glm",
298
- "kimi",
299
- "qwen",
300
- "deepseek",
301
- "llama",
302
- "mistral",
303
- ];
304
- return categories.find((category) => normalized.includes(category)) ?? "custom";
305
- }
306
- export function telemetryProviderCategory(provider) {
307
- if (!provider) {
308
- return "unknown";
309
- }
310
- const normalized = provider.toLowerCase();
311
- const categories = [
312
- "anthropic",
313
- "openai",
314
- "google",
315
- "asm",
316
- "openrouter",
317
- "bedrock",
318
- "vertex",
319
- "mistral",
320
- "groq",
321
- "xai",
322
- ];
323
- return categories.find((category) => normalized.includes(category)) ?? "custom";
324
- }
325
- export function telemetryAuthCategory(source, storedCredentialType) {
326
- switch (source) {
327
- case "stored":
328
- return storedCredentialType ?? "stored";
329
- case "runtime":
330
- return "runtime_api_key";
331
- case "environment":
332
- return "environment";
333
- case "prime_cli":
334
- return "prime_cli";
335
- case "models_json_key":
336
- case "models_json_command":
337
- return "models_json";
338
- case "fallback":
339
- return "fallback";
340
- case "stale":
341
- return "stale";
342
- default:
343
- return "none";
344
- }
345
- }
346
- function baseProperties(executionMode) {
347
- return {
348
- version: VERSION,
349
- os_family: platform(),
350
- architecture: arch(),
351
- install_method: detectInstallMethod(),
352
- execution_mode: executionMode,
353
- };
354
- }
355
- export async function captureOnboardingCompleted(options) {
356
- if (!isTelemetryEnabled(options.settingsManager)) {
357
- return;
358
- }
359
- const now = options.now ?? Date.now;
360
- const randomId = options.randomId ?? randomUUID;
361
- const sink = options.sink ??
362
- new TelemetryClient({
363
- agentDir: options.agentDir,
364
- now,
365
- randomId,
366
- });
367
- sink.capture("onboarding completed", {
368
- ...baseProperties("interactive"),
369
- duration_ms: Math.max(0, options.durationMs),
370
- outcome: options.outcome,
371
- auth_category: telemetryAuthCategory(options.authSource, options.storedCredentialType),
372
- provider_category: telemetryProviderCategory(options.provider),
373
- });
374
- await sink.flush();
375
- }
376
- export async function captureAgentCommandUsed(options) {
377
- if (!isBuiltinSlashCommandName(options.commandName) || !isTelemetryEnabled(options.settingsManager)) {
378
- return;
379
- }
380
- const commandName = resolveBuiltinSlashCommandName(options.commandName);
381
- const now = options.now ?? Date.now;
382
- const randomId = options.randomId ?? randomUUID;
383
- const sink = options.sink ??
384
- new TelemetryClient({
385
- agentDir: options.agentDir,
386
- now,
387
- randomId,
388
- });
389
- sink.capture("agent command used", {
390
- ...baseProperties("interactive"),
391
- command_name: commandName,
392
- });
393
- await sink.flush();
394
- }
395
- function errorCategory(message) {
396
- if (!message || message.stopReason !== "error") {
397
- return null;
398
- }
399
- const error = message.errorMessage?.toLowerCase() ?? "";
400
- if (/\b401\b|\b403\b|auth|api.?key|credential|unauthori[sz]ed|forbidden/.test(error)) {
401
- return "authentication";
402
- }
403
- if (/\b429\b|rate.?limit|quota/.test(error)) {
404
- return "rate_limit";
405
- }
406
- if (/timeout|timed out/.test(error)) {
407
- return "timeout";
408
- }
409
- if (/context|token.*limit|too long|maximum.*length/.test(error)) {
410
- return "context_limit";
411
- }
412
- if (/network|socket|connection|fetch/.test(error)) {
413
- return "network";
414
- }
415
- if (/\b5\d\d\b|overload|unavailable/.test(error)) {
416
- return "provider_unavailable";
417
- }
418
- return "other";
419
- }
420
- function runOutcome(message) {
421
- if (message?.stopReason === "aborted") {
422
- return "aborted";
423
- }
424
- if (!message || message.stopReason === "error") {
425
- return "error";
426
- }
427
- return "success";
428
- }
429
- function assistantMessage(event) {
430
- if (event.type !== "message_end" || event.message.role !== "assistant") {
431
- return undefined;
432
- }
433
- return event.message;
434
- }
435
- function createActiveRun(now) {
436
- return {
437
- startedAt: now(),
438
- agentEnded: false,
439
- modelLatencyMs: 0,
440
- maxModelLatencyMs: 0,
441
- turnCount: 0,
442
- toolCallCount: 0,
443
- toolErrorCount: 0,
444
- compactionCount: 0,
445
- retryCount: 0,
446
- usage: newUsageTotals(),
447
- };
448
- }
449
- export function installAgentTelemetry(session, options) {
450
- if (!isTelemetryEnabled(options.settingsManager)) {
451
- return;
452
- }
453
- const now = options.now ?? Date.now;
454
- const randomId = options.randomId ?? randomUUID;
455
- const sink = options.sink ??
456
- new TelemetryClient({
457
- agentDir: options.agentDir,
458
- now,
459
- randomId,
460
- });
461
- const sessionId = randomId();
462
- const sessionTotals = {
463
- startedAt: now(),
464
- runCount: 0,
465
- successfulRunCount: 0,
466
- failedRunCount: 0,
467
- abortedRunCount: 0,
468
- promptCount: 0,
469
- toolCallCount: 0,
470
- compactionCount: 0,
471
- usage: newUsageTotals(),
472
- };
473
- let activeRun;
474
- let turnActionActive = false;
475
- const commonProperties = () => ({
476
- ...baseProperties(options.executionMode ?? "unknown"),
477
- session_id: sessionId,
478
- });
479
- const finalizeRun = () => {
480
- const run = activeRun;
481
- if (!run) {
482
- return;
483
- }
484
- activeRun = undefined;
485
- const outcome = runOutcome(run.lastAssistant);
486
- sessionTotals.runCount++;
487
- sessionTotals.toolCallCount += run.toolCallCount;
488
- sessionTotals.compactionCount += run.compactionCount;
489
- if (outcome === "success") {
490
- sessionTotals.successfulRunCount++;
491
- }
492
- else if (outcome === "aborted") {
493
- sessionTotals.abortedRunCount++;
494
- }
495
- else {
496
- sessionTotals.failedRunCount++;
497
- }
498
- mergeUsage(sessionTotals.usage, run.usage);
499
- const lastAssistant = run.lastAssistant;
500
- sink.capture("agent run completed", {
501
- ...commonProperties(),
502
- outcome,
503
- duration_ms: Math.max(0, now() - run.startedAt),
504
- visible_ttft_ms: run.visibleTtftMs ?? null,
505
- first_model_event_ms: run.firstModelEventMs ?? null,
506
- model_latency_ms: run.modelLatencyMs,
507
- max_model_latency_ms: run.maxModelLatencyMs,
508
- model_call_count: run.usage.modelCallCount,
509
- turn_count: run.turnCount,
510
- tool_call_count: run.toolCallCount,
511
- tool_error_count: run.toolErrorCount,
512
- input_tokens: run.usage.input,
513
- output_tokens: run.usage.output,
514
- cache_read_tokens: run.usage.cacheRead,
515
- cache_write_tokens: run.usage.cacheWrite,
516
- total_tokens: run.usage.totalTokens,
517
- compaction_count: run.compactionCount,
518
- retry_count: run.retryCount,
519
- provider_category: telemetryProviderCategory(lastAssistant?.provider),
520
- model_category: lastAssistant ? modelCategory(lastAssistant.model) : "unknown",
521
- error_category: errorCategory(lastAssistant),
522
- });
523
- };
524
- sink.capture("agent started", commonProperties());
525
- const unsubscribe = session.subscribe((event) => {
526
- switch (event.type) {
527
- case "session_action_update":
528
- turnActionActive = event.actions.active?.kind === "turn";
529
- if (!turnActionActive && activeRun?.agentEnded) {
530
- finalizeRun();
531
- }
532
- break;
533
- case "agent_start":
534
- if (activeRun?.agentEnded && !turnActionActive) {
535
- finalizeRun();
536
- }
537
- activeRun ??= createActiveRun(now);
538
- activeRun.agentEnded = false;
539
- break;
540
- case "message_start":
541
- if (event.message.role === "user") {
542
- sessionTotals.promptCount++;
543
- }
544
- break;
545
- case "turn_start":
546
- if (activeRun) {
547
- activeRun.currentTurnStartedAt = now();
548
- activeRun.firstTurnStartedAt ??= activeRun.currentTurnStartedAt;
549
- activeRun.turnCount++;
550
- }
551
- break;
552
- case "message_update":
553
- if (!activeRun) {
554
- break;
555
- }
556
- if (activeRun.firstModelEventMs === undefined && activeRun.firstTurnStartedAt !== undefined) {
557
- activeRun.firstModelEventMs = Math.max(0, now() - activeRun.firstTurnStartedAt);
558
- }
559
- if (activeRun.visibleTtftMs === undefined &&
560
- activeRun.firstTurnStartedAt !== undefined &&
561
- event.assistantMessageEvent.type === "text_delta" &&
562
- event.assistantMessageEvent.delta.length > 0) {
563
- activeRun.visibleTtftMs = Math.max(0, now() - activeRun.firstTurnStartedAt);
564
- }
565
- break;
566
- case "message_end": {
567
- const message = assistantMessage(event);
568
- if (!activeRun || !message) {
569
- break;
570
- }
571
- activeRun.lastAssistant = message;
572
- addUsage(activeRun.usage, message.usage);
573
- if (activeRun.currentTurnStartedAt !== undefined) {
574
- const latency = Math.max(0, now() - activeRun.currentTurnStartedAt);
575
- activeRun.modelLatencyMs += latency;
576
- activeRun.maxModelLatencyMs = Math.max(activeRun.maxModelLatencyMs, latency);
577
- activeRun.currentTurnStartedAt = undefined;
578
- }
579
- break;
580
- }
581
- case "tool_execution_end":
582
- if (activeRun) {
583
- activeRun.toolCallCount++;
584
- if (event.isError) {
585
- activeRun.toolErrorCount++;
586
- }
587
- }
588
- break;
589
- case "compaction_end":
590
- if (activeRun && event.result && !event.aborted) {
591
- activeRun.compactionCount++;
592
- }
593
- break;
594
- case "auto_retry_start":
595
- if (activeRun) {
596
- activeRun.retryCount++;
597
- }
598
- break;
599
- case "agent_end":
600
- if (!activeRun) {
601
- break;
602
- }
603
- activeRun.agentEnded = true;
604
- if (!turnActionActive) {
605
- finalizeRun();
606
- }
607
- break;
608
- }
609
- });
610
- session.registerDisposeCallback(async () => {
611
- unsubscribe();
612
- finalizeRun();
613
- sink.capture("agent session ended", {
614
- ...commonProperties(),
615
- duration_ms: Math.max(0, now() - sessionTotals.startedAt),
616
- prompt_count: sessionTotals.promptCount,
617
- run_count: sessionTotals.runCount,
618
- successful_run_count: sessionTotals.successfulRunCount,
619
- failed_run_count: sessionTotals.failedRunCount,
620
- aborted_run_count: sessionTotals.abortedRunCount,
621
- tool_call_count: sessionTotals.toolCallCount,
622
- compaction_count: sessionTotals.compactionCount,
623
- model_call_count: sessionTotals.usage.modelCallCount,
624
- input_tokens: sessionTotals.usage.input,
625
- output_tokens: sessionTotals.usage.output,
626
- cache_read_tokens: sessionTotals.usage.cacheRead,
627
- cache_write_tokens: sessionTotals.usage.cacheWrite,
628
- total_tokens: sessionTotals.usage.totalTokens,
629
- });
630
- await sink.flush();
631
- });
632
- }
633
- //# sourceMappingURL=telemetry.js.map