happy-imou-cloud 2.0.10 → 2.0.11

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 (34) hide show
  1. package/dist/BaseReasoningProcessor-5ACv9gKu.mjs +320 -0
  2. package/dist/BaseReasoningProcessor-COrRWyn0.cjs +323 -0
  3. package/dist/ProviderSelectionHandler-BljOLMQn.mjs +261 -0
  4. package/dist/ProviderSelectionHandler-DBGobhGZ.cjs +265 -0
  5. package/dist/{api-BjxmW-0W.mjs → api-BcWf5v4i.mjs} +174 -46
  6. package/dist/{api-DUE5TJBE.cjs → api-Ye-rPX6s.cjs} +174 -46
  7. package/dist/{command-Df7u5eAT.cjs → command-BK93nizl.cjs} +6 -6
  8. package/dist/{command-ComOeFLY.mjs → command-nOI80Mnm.mjs} +6 -6
  9. package/dist/{index-CzvgPwr1.mjs → index-DnsqY6I_.mjs} +189 -60
  10. package/dist/{index-Cuvfa15L.cjs → index-J7QKJ8lc.cjs} +194 -61
  11. package/dist/index.cjs +8 -8
  12. package/dist/index.mjs +8 -8
  13. package/dist/lib.cjs +2 -3
  14. package/dist/lib.d.cts +2 -0
  15. package/dist/lib.d.mts +2 -0
  16. package/dist/lib.mjs +2 -3
  17. package/dist/{persistence-BxP6Jw1f.mjs → persistence-BMa6cyw9.mjs} +2 -3
  18. package/dist/{persistence-D7JtnrYA.cjs → persistence-xK5CKhbn.cjs} +2 -3
  19. package/dist/registerKillSessionHandler-CH6yN0eG.cjs +1198 -0
  20. package/dist/registerKillSessionHandler-Dxwg4L4J.mjs +1179 -0
  21. package/dist/{runClaude-C1W_Nw0C.cjs → runClaude-BMHlBny_.cjs} +884 -398
  22. package/dist/{runClaude-B_fTMxc4.mjs → runClaude-cQ-UT0Ke.mjs} +882 -396
  23. package/dist/{runCodex-CUgOiIEz.mjs → runCodex-AnJUPIhX.mjs} +155 -578
  24. package/dist/{runCodex-D2VCWVEK.cjs → runCodex-roOSOWWL.cjs} +158 -583
  25. package/dist/{runGemini-2_FEtJYa.mjs → runGemini-BGo_0mzA.mjs} +142 -387
  26. package/dist/{runGemini-CiGnjflq.cjs → runGemini-Cg6Zbqlz.cjs} +145 -390
  27. package/package.json +9 -8
  28. package/scripts/e2e/fake-codex-acp-agent.mjs +139 -0
  29. package/scripts/e2e/local-server-session-roundtrip.mjs +1063 -0
  30. package/scripts/release-smoke.mjs +23 -6
  31. package/dist/names-CicSgRNg.mjs +0 -625
  32. package/dist/names-yJNZoTv_.cjs +0 -636
  33. package/dist/registerKillSessionHandler-ARQrPvnT.mjs +0 -454
  34. package/dist/registerKillSessionHandler-DCMFiXyA.cjs +0 -459
@@ -165,6 +165,8 @@ function main() {
165
165
  runToolStep('typecheck', tsc, ['--noEmit']);
166
166
  runToolStep('unit runtime suite', vitest, [
167
167
  'run',
168
+ '--testTimeout',
169
+ '20000',
168
170
  'src/agent/acp/AcpBackend.test.ts',
169
171
  'src/agent/acp/AcpBackend.startup.test.ts',
170
172
  'src/agent/acp/AcpBackend.waitForResponseComplete.test.ts',
@@ -172,12 +174,27 @@ function main() {
172
174
  'src/agent/acp/acpSpawn.test.ts',
173
175
  'src/agent/acp/createAcpFilteredStdoutReadable.multiline.test.ts',
174
176
  'src/agent/acp/killProcessTree.test.ts',
175
- 'src/runtime/executeProvider.test.ts',
176
- 'src/runtime/command.test.ts',
177
- 'src/runtime/launch.test.ts',
178
- 'src/runtime/RuntimeShell.test.ts',
179
- 'src/runtime/createDefaultRuntimeShell.test.ts',
180
- 'src/security/signedTransport.test.ts',
177
+ 'src/runtime/executeProvider.test.ts',
178
+ 'src/runtime/ensureManagedProviderMachine.test.ts',
179
+ 'src/runtime/bootstrapManagedProviderSession.test.ts',
180
+ 'src/runtime/command.test.ts',
181
+ 'src/runtime/launch.test.ts',
182
+ 'src/runtime/launchWithFactoryResult.test.ts',
183
+ 'src/runtime/providerMessageBridge.test.ts',
184
+ 'src/runtime/runModeLoop.test.ts',
185
+ 'src/runtime/createKeepAliveController.test.ts',
186
+ 'src/runtime/sessionControl.test.ts',
187
+ 'src/runtime/closeProviderSession.test.ts',
188
+ 'src/runtime/waitForResponseCompleteWithAbort.test.ts',
189
+ 'src/utils/ConversationHistory.test.ts',
190
+ 'src/runtime/RuntimeShell.test.ts',
191
+ 'src/runtime/createDefaultRuntimeShell.test.ts',
192
+ 'src/claude/loop.test.ts',
193
+ 'src/claude/claudeAcpRemoteLauncher.test.ts',
194
+ 'src/claude/utils/acpPermissionHandler.test.ts',
195
+ 'src/codex/__tests__/runCodex.lifecycle.test.ts',
196
+ 'src/codex/__tests__/selectionHandler.test.ts',
197
+ 'src/security/signedTransport.test.ts',
181
198
  'src/agent/initializeAgents.test.ts',
182
199
  'src/agent/factories/factories.test.ts',
183
200
  'src/packageContract.test.ts',
@@ -1,625 +0,0 @@
1
- import os from 'node:os';
2
- import { resolve } from 'node:path';
3
- import { c as configuration, p as packageJson, s as startOfflineReconnection, l as logger } from './api-BjxmW-0W.mjs';
4
- import { d as projectPath } from './index-CzvgPwr1.mjs';
5
- import { EventEmitter } from 'node:events';
6
- import { randomUUID } from 'node:crypto';
7
-
8
- function createSessionMetadata(opts) {
9
- const state = {
10
- controlledByUser: false
11
- };
12
- const metadata = {
13
- path: process.cwd(),
14
- host: os.hostname(),
15
- version: packageJson.version,
16
- os: os.platform(),
17
- machineId: opts.machineId,
18
- homeDir: os.homedir(),
19
- happyHomeDir: configuration.happyCloudHomeDir,
20
- happyLibDir: projectPath(),
21
- happyToolsDir: resolve(projectPath(), "tools", "unpacked"),
22
- startedFromDaemon: opts.startedBy === "daemon",
23
- hostPid: process.pid,
24
- startedBy: opts.startedBy || "terminal",
25
- lifecycleState: "running",
26
- lifecycleStateSince: Date.now(),
27
- flavor: opts.flavor
28
- };
29
- return { state, metadata };
30
- }
31
-
32
- function createOfflineSessionStub(sessionTag) {
33
- const emitter = new EventEmitter();
34
- let metadata = null;
35
- let agentState = null;
36
- const stub = {
37
- sessionId: `offline-${sessionTag}`,
38
- sendCodexMessage: () => {
39
- },
40
- sendAgentMessage: () => {
41
- },
42
- sendClaudeSessionMessage: () => {
43
- },
44
- keepAlive: () => {
45
- },
46
- sendSessionEvent: () => {
47
- },
48
- sendSessionDeath: () => {
49
- },
50
- updateLifecycleState: () => {
51
- },
52
- requestControlTransfer: async () => {
53
- },
54
- flush: async () => {
55
- },
56
- close: async () => {
57
- },
58
- updateMetadata: (handler) => {
59
- metadata = handler(metadata || {});
60
- emitter.emit("metadata-updated", metadata);
61
- },
62
- updateAgentState: (handler) => {
63
- agentState = handler(agentState || {});
64
- emitter.emit("agent-state-updated", agentState);
65
- },
66
- getMetadataSnapshot: () => metadata,
67
- getAgentStateSnapshot: () => agentState,
68
- waitForMetadataUpdate: async () => metadata,
69
- onUserMessage: () => {
70
- },
71
- rpcHandlerManager: {
72
- registerHandler: () => {
73
- }
74
- },
75
- on: emitter.on.bind(emitter),
76
- once: emitter.once.bind(emitter),
77
- off: emitter.off.bind(emitter),
78
- emit: emitter.emit.bind(emitter)
79
- };
80
- return stub;
81
- }
82
-
83
- function setupOfflineReconnection(opts) {
84
- const { api, sessionTag, metadata, state, response, onSessionSwap } = opts;
85
- let session;
86
- let reconnectionHandle = null;
87
- if (!response) {
88
- session = createOfflineSessionStub(sessionTag);
89
- reconnectionHandle = startOfflineReconnection({
90
- serverUrl: configuration.serverUrl,
91
- onReconnected: async () => {
92
- const resp = await api.getOrCreateSession({ tag: sessionTag, metadata, state });
93
- if (!resp) throw new Error("Server unavailable");
94
- const realSession = api.sessionSyncClient(resp);
95
- onSessionSwap(realSession);
96
- return realSession;
97
- },
98
- onNotify: (msg) => {
99
- console.log(msg);
100
- }
101
- });
102
- return { session, reconnectionHandle, isOffline: true };
103
- } else {
104
- session = api.sessionSyncClient(response);
105
- return { session, reconnectionHandle: null, isOffline: false };
106
- }
107
- }
108
-
109
- const INTERACTION_SUPERSEDED_ERROR = "Interaction superseded by new user message";
110
- const INTERACTION_TIMED_OUT_ERROR = "Interaction timed out waiting for user response";
111
- const DEFAULT_INTERACTION_TIMEOUT_MS = 2 * 60 * 1e3;
112
- function getPendingInteractionTimeoutMs() {
113
- const raw = Number(process.env.HAPPY_INTERACTION_TIMEOUT_MS);
114
- if (Number.isFinite(raw) && raw > 0) {
115
- return raw;
116
- }
117
- return DEFAULT_INTERACTION_TIMEOUT_MS;
118
- }
119
- class BasePermissionHandler {
120
- pendingRequests = /* @__PURE__ */ new Map();
121
- session;
122
- isResetting = false;
123
- constructor(session) {
124
- this.session = session;
125
- this.setupRpcHandler();
126
- }
127
- /**
128
- * Update the session reference (used after offline reconnection swaps sessions).
129
- * This is critical for avoiding stale session references after onSessionSwap.
130
- */
131
- updateSession(newSession) {
132
- logger.debug(`${this.getLogPrefix()} Session reference updated`);
133
- this.session = newSession;
134
- this.setupRpcHandler();
135
- }
136
- /**
137
- * Setup RPC handler for permission responses.
138
- */
139
- setupRpcHandler() {
140
- this.session.rpcHandlerManager.registerHandler(
141
- "permission",
142
- async (response) => {
143
- const pending = this.pendingRequests.get(response.id);
144
- if (!pending) {
145
- logger.debug(`${this.getLogPrefix()} Permission request not found or already resolved`);
146
- return;
147
- }
148
- this.pendingRequests.delete(response.id);
149
- this.clearPendingRequestTimeout(pending);
150
- const result = response.approved ? { decision: response.decision === "approved_for_session" ? "approved_for_session" : "approved" } : { decision: response.decision === "denied" ? "denied" : "abort" };
151
- pending.resolve(result);
152
- this.session.updateAgentState((currentState) => {
153
- const request = currentState.requests?.[response.id];
154
- if (!request) return currentState;
155
- const { [response.id]: _, ...remainingRequests } = currentState.requests || {};
156
- let res = {
157
- ...currentState,
158
- requests: remainingRequests,
159
- completedRequests: {
160
- ...currentState.completedRequests,
161
- [response.id]: {
162
- ...request,
163
- completedAt: Date.now(),
164
- status: response.approved ? "approved" : "denied",
165
- decision: result.decision
166
- }
167
- }
168
- };
169
- return res;
170
- });
171
- logger.debug(`${this.getLogPrefix()} Permission ${response.approved ? "approved" : "denied"} for ${pending.toolName}`);
172
- }
173
- );
174
- }
175
- /**
176
- * Add a pending request to the agent state.
177
- */
178
- addPendingRequestToState(toolCallId, toolName, input) {
179
- this.session.updateAgentState((currentState) => ({
180
- ...currentState,
181
- requests: {
182
- ...currentState.requests,
183
- [toolCallId]: {
184
- tool: toolName,
185
- arguments: input,
186
- createdAt: Date.now()
187
- }
188
- }
189
- }));
190
- }
191
- registerPendingRequest(toolCallId, toolName, input, logSuffix = "") {
192
- return new Promise((resolve, reject) => {
193
- const pending = {
194
- resolve,
195
- reject,
196
- toolName,
197
- input
198
- };
199
- pending.timeoutHandle = setTimeout(() => {
200
- this.handlePendingRequestTimeout(toolCallId, pending);
201
- }, getPendingInteractionTimeoutMs());
202
- this.pendingRequests.set(toolCallId, pending);
203
- this.addPendingRequestToState(toolCallId, toolName, input);
204
- logger.debug(`${this.getLogPrefix()} Permission request sent for tool: ${toolName} (${toolCallId})${logSuffix}`);
205
- });
206
- }
207
- hasPendingRequests() {
208
- return this.pendingRequests.size > 0;
209
- }
210
- supersedePendingRequests(reason = INTERACTION_SUPERSEDED_ERROR) {
211
- const pendingSnapshot = Array.from(this.pendingRequests.entries());
212
- if (pendingSnapshot.length === 0) {
213
- return 0;
214
- }
215
- this.pendingRequests.clear();
216
- const completedAt = Date.now();
217
- for (const [, pending] of pendingSnapshot) {
218
- this.clearPendingRequestTimeout(pending);
219
- pending.resolve({ decision: "abort" });
220
- }
221
- this.session.updateAgentState((currentState) => {
222
- const requests = { ...currentState.requests || {} };
223
- const completedRequests = { ...currentState.completedRequests || {} };
224
- for (const [id, request] of Object.entries(requests)) {
225
- if (request.requestKind === "selection") {
226
- continue;
227
- }
228
- completedRequests[id] = {
229
- ...request,
230
- completedAt,
231
- status: "denied",
232
- reason,
233
- decision: "abort",
234
- requestKind: request.requestKind || "permission"
235
- };
236
- delete requests[id];
237
- }
238
- return {
239
- ...currentState,
240
- requests,
241
- completedRequests
242
- };
243
- });
244
- logger.debug(`${this.getLogPrefix()} Superseded ${pendingSnapshot.length} pending permission request(s)`);
245
- return pendingSnapshot.length;
246
- }
247
- /**
248
- * Reset state for new sessions.
249
- * This method is idempotent - safe to call multiple times.
250
- */
251
- reset() {
252
- if (this.isResetting) {
253
- logger.debug(`${this.getLogPrefix()} Reset already in progress, skipping`);
254
- return;
255
- }
256
- this.isResetting = true;
257
- try {
258
- const pendingSnapshot = Array.from(this.pendingRequests.entries());
259
- this.pendingRequests.clear();
260
- for (const [id, pending] of pendingSnapshot) {
261
- try {
262
- this.clearPendingRequestTimeout(pending);
263
- pending.reject(new Error("Session reset"));
264
- } catch (err) {
265
- logger.debug(`${this.getLogPrefix()} Error rejecting pending request ${id}:`, err);
266
- }
267
- }
268
- this.session.updateAgentState((currentState) => {
269
- const pendingRequests = currentState.requests || {};
270
- const completedRequests = { ...currentState.completedRequests };
271
- for (const [id, request] of Object.entries(pendingRequests)) {
272
- completedRequests[id] = {
273
- ...request,
274
- completedAt: Date.now(),
275
- status: "canceled",
276
- reason: "Session reset"
277
- };
278
- }
279
- return {
280
- ...currentState,
281
- requests: {},
282
- completedRequests
283
- };
284
- });
285
- logger.debug(`${this.getLogPrefix()} Permission handler reset`);
286
- } finally {
287
- this.isResetting = false;
288
- }
289
- }
290
- clearPendingRequestTimeout(pending) {
291
- if (pending?.timeoutHandle) {
292
- clearTimeout(pending.timeoutHandle);
293
- pending.timeoutHandle = void 0;
294
- }
295
- }
296
- handlePendingRequestTimeout(toolCallId, pending) {
297
- const active = this.pendingRequests.get(toolCallId);
298
- if (!active || active !== pending) {
299
- return;
300
- }
301
- this.pendingRequests.delete(toolCallId);
302
- this.clearPendingRequestTimeout(active);
303
- active.resolve({ decision: "abort" });
304
- this.session.updateAgentState((currentState) => {
305
- const request = currentState.requests?.[toolCallId] || {
306
- tool: active.toolName,
307
- arguments: active.input,
308
- createdAt: Date.now(),
309
- requestKind: "permission"
310
- };
311
- const { [toolCallId]: _, ...remainingRequests } = currentState.requests || {};
312
- return {
313
- ...currentState,
314
- requests: remainingRequests,
315
- completedRequests: {
316
- ...currentState.completedRequests,
317
- [toolCallId]: {
318
- ...request,
319
- completedAt: Date.now(),
320
- status: "canceled",
321
- reason: INTERACTION_TIMED_OUT_ERROR,
322
- decision: "abort",
323
- requestKind: request.requestKind || "permission"
324
- }
325
- }
326
- };
327
- });
328
- this.session.sendSessionEvent({
329
- type: "message",
330
- message: "Pending interaction timed out waiting for a response. Send a new message to continue."
331
- });
332
- logger.debug(`${this.getLogPrefix()} Permission request timed out for ${active.toolName} (${toolCallId})`);
333
- }
334
- }
335
-
336
- class BaseReasoningProcessor {
337
- accumulator = "";
338
- inTitleCapture = false;
339
- titleBuffer = "";
340
- contentBuffer = "";
341
- hasTitle = false;
342
- currentCallId = null;
343
- toolCallStarted = false;
344
- currentTitle = null;
345
- onMessage = null;
346
- constructor(onMessage) {
347
- this.onMessage = onMessage || null;
348
- this.reset();
349
- }
350
- /**
351
- * Set the message callback for sending messages directly.
352
- */
353
- setMessageCallback(callback) {
354
- this.onMessage = callback;
355
- }
356
- /**
357
- * Process a reasoning section break - indicates a new reasoning section is starting.
358
- */
359
- handleSectionBreak() {
360
- this.finishCurrentToolCall("canceled");
361
- this.resetState();
362
- logger.debug(`${this.getLogPrefix()} Section break - reset state`);
363
- }
364
- /**
365
- * Process a reasoning delta/chunk and accumulate content.
366
- */
367
- processInput(input) {
368
- this.accumulator += input;
369
- if (!this.inTitleCapture && !this.hasTitle && !this.contentBuffer) {
370
- if (this.accumulator.startsWith("**")) {
371
- this.inTitleCapture = true;
372
- this.titleBuffer = this.accumulator.substring(2);
373
- logger.debug(`${this.getLogPrefix()} Started title capture`);
374
- } else if (this.accumulator.length > 0) {
375
- this.contentBuffer = this.accumulator;
376
- }
377
- } else if (this.inTitleCapture) {
378
- this.titleBuffer = this.accumulator.substring(2);
379
- const titleEndIndex = this.titleBuffer.indexOf("**");
380
- if (titleEndIndex !== -1) {
381
- const title = this.titleBuffer.substring(0, titleEndIndex);
382
- const afterTitle = this.titleBuffer.substring(titleEndIndex + 2);
383
- this.hasTitle = true;
384
- this.inTitleCapture = false;
385
- this.currentTitle = title;
386
- this.contentBuffer = afterTitle;
387
- this.currentCallId = randomUUID();
388
- logger.debug(`${this.getLogPrefix()} Title captured: "${title}"`);
389
- this.sendToolCallStart(title);
390
- }
391
- } else if (this.hasTitle) {
392
- const titleStartIndex = this.accumulator.indexOf("**");
393
- if (titleStartIndex !== -1) {
394
- this.contentBuffer = this.accumulator.substring(
395
- titleStartIndex + 2 + this.currentTitle.length + 2
396
- );
397
- }
398
- } else {
399
- this.contentBuffer = this.accumulator;
400
- }
401
- }
402
- /**
403
- * Send the tool call start message.
404
- */
405
- sendToolCallStart(title) {
406
- if (!this.currentCallId || this.toolCallStarted) {
407
- return;
408
- }
409
- const toolCall = {
410
- type: "tool-call",
411
- name: this.getToolName(),
412
- callId: this.currentCallId,
413
- input: {
414
- title
415
- },
416
- id: randomUUID()
417
- };
418
- logger.debug(`${this.getLogPrefix()} Sending tool call start for: "${title}"`);
419
- this.onMessage?.(toolCall);
420
- this.toolCallStarted = true;
421
- }
422
- /**
423
- * Complete the reasoning section.
424
- * Returns true if reasoning was completed, false if there was nothing to complete.
425
- */
426
- completeReasoning(fullText) {
427
- const text = fullText ?? this.accumulator;
428
- if (!text.trim() && !this.toolCallStarted) {
429
- logger.debug(`${this.getLogPrefix()} Complete called but no content accumulated, skipping`);
430
- return false;
431
- }
432
- let title;
433
- let content = text;
434
- if (text.startsWith("**")) {
435
- const titleEndIndex = text.indexOf("**", 2);
436
- if (titleEndIndex !== -1) {
437
- title = text.substring(2, titleEndIndex);
438
- content = text.substring(titleEndIndex + 2).trim();
439
- }
440
- }
441
- logger.debug(`${this.getLogPrefix()} Complete reasoning - Title: "${title}", Has content: ${content.length > 0}`);
442
- if (title && !this.toolCallStarted) {
443
- this.currentCallId = this.currentCallId || randomUUID();
444
- this.sendToolCallStart(title);
445
- }
446
- if (this.toolCallStarted && this.currentCallId) {
447
- const toolResult = {
448
- type: "tool-call-result",
449
- callId: this.currentCallId,
450
- output: {
451
- content,
452
- status: "completed"
453
- },
454
- id: randomUUID()
455
- };
456
- logger.debug(`${this.getLogPrefix()} Sending tool call result`);
457
- this.onMessage?.(toolResult);
458
- } else if (content.trim()) {
459
- const reasoningMessage = {
460
- type: "reasoning",
461
- message: content,
462
- id: randomUUID()
463
- };
464
- logger.debug(`${this.getLogPrefix()} Sending reasoning message`);
465
- this.onMessage?.(reasoningMessage);
466
- }
467
- this.resetState();
468
- return true;
469
- }
470
- /**
471
- * Abort the current reasoning section.
472
- */
473
- abort() {
474
- logger.debug(`${this.getLogPrefix()} Abort called`);
475
- this.finishCurrentToolCall("canceled");
476
- this.resetState();
477
- }
478
- /**
479
- * Reset the processor state.
480
- */
481
- reset() {
482
- this.finishCurrentToolCall("canceled");
483
- this.resetState();
484
- }
485
- /**
486
- * Finish current tool call if one is in progress.
487
- */
488
- finishCurrentToolCall(status) {
489
- if (this.toolCallStarted && this.currentCallId) {
490
- const toolResult = {
491
- type: "tool-call-result",
492
- callId: this.currentCallId,
493
- output: {
494
- content: this.contentBuffer || "",
495
- status
496
- },
497
- id: randomUUID()
498
- };
499
- logger.debug(`${this.getLogPrefix()} Sending tool call result with status: ${status}`);
500
- this.onMessage?.(toolResult);
501
- }
502
- }
503
- /**
504
- * Reset internal state.
505
- */
506
- resetState() {
507
- this.accumulator = "";
508
- this.inTitleCapture = false;
509
- this.titleBuffer = "";
510
- this.contentBuffer = "";
511
- this.hasTitle = false;
512
- this.currentCallId = null;
513
- this.toolCallStarted = false;
514
- this.currentTitle = null;
515
- }
516
- /**
517
- * Get the current call ID for tool result matching.
518
- */
519
- getCurrentCallId() {
520
- return this.currentCallId;
521
- }
522
- /**
523
- * Check if a tool call has been started.
524
- */
525
- hasStartedToolCall() {
526
- return this.toolCallStarted;
527
- }
528
- }
529
-
530
- function inferToolResultError(result) {
531
- if (!result || typeof result !== "object") {
532
- return false;
533
- }
534
- const record = result;
535
- if (record.isError === true || record.is_error === true) {
536
- return true;
537
- }
538
- if (typeof record.error === "string" && record.error.trim().length > 0) {
539
- return true;
540
- }
541
- if (record.success === false) {
542
- return true;
543
- }
544
- const status = typeof record.status === "string" ? record.status.toLowerCase() : "";
545
- return status === "failed" || status === "cancelled" || status === "error" || status === "denied" || status === "aborted";
546
- }
547
-
548
- function buildToolHappierMetaV2(input) {
549
- return {
550
- ...input,
551
- v: 2
552
- };
553
- }
554
- function attachToolHappierMetaV2(value, meta) {
555
- if (!value || typeof value !== "object" || Array.isArray(value)) {
556
- return value;
557
- }
558
- return {
559
- ...value,
560
- _happier: buildToolHappierMetaV2(meta)
561
- };
562
- }
563
-
564
- const KNOWN_CANONICAL_TOOL_NAMES_V2 = [
565
- "Bash",
566
- "Read",
567
- "Write",
568
- "Edit",
569
- "MultiEdit",
570
- "Delete",
571
- "Patch",
572
- "Diff",
573
- "Glob",
574
- "Grep",
575
- "LS",
576
- "CodeSearch",
577
- "WebFetch",
578
- "WebSearch",
579
- "TodoWrite",
580
- "TodoRead",
581
- "Task",
582
- "Reasoning",
583
- "EnterPlanMode",
584
- "ExitPlanMode",
585
- "AskUserQuestion",
586
- "AcpHistoryImport",
587
- "WorkspaceIndexingPermission",
588
- "SubAgentRun",
589
- "AgentTeamCreate",
590
- "AgentTeamDelete",
591
- "AgentTeamSendMessage"
592
- ];
593
- const CANONICAL_TOOL_NAME_LOOKUP = new Map(
594
- KNOWN_CANONICAL_TOOL_NAMES_V2.map((name) => [name.toLowerCase(), name])
595
- );
596
- const RAW_TO_CANONICAL_TOOL_NAME_LOOKUP = {
597
- bash: "Bash",
598
- shell: "Bash",
599
- execute: "Bash",
600
- codexbash: "Bash",
601
- geminibash: "Bash",
602
- codexpatch: "Patch",
603
- geminipatch: "Patch"
604
- };
605
- function resolveCanonicalToolNameV2(rawToolName) {
606
- const normalized = typeof rawToolName === "string" ? rawToolName.trim() : "";
607
- if (!normalized) {
608
- return "Bash";
609
- }
610
- if (normalized.startsWith("mcp__")) {
611
- return normalized;
612
- }
613
- const lower = normalized.toLowerCase();
614
- const known = CANONICAL_TOOL_NAME_LOOKUP.get(lower);
615
- if (known) {
616
- return known;
617
- }
618
- const mapped = RAW_TO_CANONICAL_TOOL_NAME_LOOKUP[lower];
619
- if (mapped) {
620
- return mapped;
621
- }
622
- return normalized;
623
- }
624
-
625
- export { BasePermissionHandler as B, INTERACTION_SUPERSEDED_ERROR as I, BaseReasoningProcessor as a, attachToolHappierMetaV2 as b, createSessionMetadata as c, INTERACTION_TIMED_OUT_ERROR as d, getPendingInteractionTimeoutMs as g, inferToolResultError as i, resolveCanonicalToolNameV2 as r, setupOfflineReconnection as s };