happy-imou-cloud 2.0.12 → 2.0.13
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.
- package/bin/happy-cloud.mjs +1 -1
- package/dist/ConversationHistory-V3VLmjJf.cjs +868 -0
- package/dist/ConversationHistory-_ciJNIgH.mjs +856 -0
- package/dist/{api-BxXBKBUy.mjs → api-D1meoL-9.mjs} +2 -2
- package/dist/{api-B4g8VLUn.cjs → api-DH5-IqeM.cjs} +2 -2
- package/dist/{command-CHiLfBa4.mjs → command-CMvWClny.mjs} +3 -3
- package/dist/{command-DVt_YmE6.cjs → command-Ch8Dgidj.cjs} +3 -3
- package/dist/createKeepAliveController-C5cQlDRr.mjs +51 -0
- package/dist/createKeepAliveController-DO8H6d5E.cjs +54 -0
- package/dist/{index-CWom7mSf.cjs → index-CryJfCh5.cjs} +10 -11
- package/dist/{index-DaAkW0VN.mjs → index-Cxrx9m5D.mjs} +9 -9
- package/dist/index.cjs +3 -3
- package/dist/index.mjs +3 -3
- package/dist/lib.cjs +1 -1
- package/dist/lib.mjs +1 -1
- package/dist/{persistence-8pNEvzaq.mjs → persistence-9Iu0wGNM.mjs} +1 -1
- package/dist/{persistence-DScOANDE.cjs → persistence-Bl3FYvwd.cjs} +1 -1
- package/dist/{registerKillSessionHandler-CNNguWyD.mjs → registerKillSessionHandler-BElGmD1E.mjs} +5 -541
- package/dist/{registerKillSessionHandler-Dr1inhTc.cjs → registerKillSessionHandler-BjkY-oUn.cjs} +4 -549
- package/dist/{runClaude-h-8llTrI.cjs → runClaude-CDZxAF3l.cjs} +129 -630
- package/dist/{runClaude-BcvOkIwh.mjs → runClaude-D7dF4RDM.mjs} +126 -627
- package/dist/{runCodex-CA58KUHf.cjs → runCodex-Cik8VzFs.cjs} +224 -17
- package/dist/{runCodex-ClJUgipy.mjs → runCodex-DnGz1XES.mjs} +213 -6
- package/dist/{runGemini-dAr7Gcn8.mjs → runGemini-B8tXMHeL.mjs} +5 -5
- package/dist/{runGemini-IFHhFMSU.cjs → runGemini-BM2BQ4I7.cjs} +13 -13
- package/package.json +9 -9
- package/scripts/build.mjs +66 -66
- package/scripts/devtools/README.md +9 -9
- package/scripts/e2e/fake-codex-acp-agent.mjs +139 -139
- package/scripts/e2e/local-server-session-roundtrip.mjs +1063 -1063
- package/scripts/release-smoke.mjs +202 -202
- package/dist/BaseReasoningProcessor-BrKUKAOr.cjs +0 -323
- package/dist/BaseReasoningProcessor-DrHf5B98.mjs +0 -320
- package/dist/ProviderSelectionHandler-BCDvmifJ.cjs +0 -265
- package/dist/ProviderSelectionHandler-BuZarTDc.mjs +0 -261
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var node_crypto = require('node:crypto');
|
|
4
|
-
var api = require('./api-
|
|
5
|
-
var registerKillSessionHandler = require('./registerKillSessionHandler-
|
|
6
|
-
var index = require('./index-
|
|
4
|
+
var api = require('./api-DH5-IqeM.cjs');
|
|
5
|
+
var registerKillSessionHandler = require('./registerKillSessionHandler-BjkY-oUn.cjs');
|
|
6
|
+
var index = require('./index-CryJfCh5.cjs');
|
|
7
7
|
require('cross-spawn');
|
|
8
8
|
require('@agentclientprotocol/sdk');
|
|
9
9
|
require('ps-list');
|
|
@@ -14,7 +14,7 @@ require('child_process');
|
|
|
14
14
|
require('node:fs');
|
|
15
15
|
require('node:path');
|
|
16
16
|
require('node:os');
|
|
17
|
-
require('./persistence-
|
|
17
|
+
require('./persistence-Bl3FYvwd.cjs');
|
|
18
18
|
require('node:fs/promises');
|
|
19
19
|
require('fs/promises');
|
|
20
20
|
require('crypto');
|
|
@@ -26,8 +26,8 @@ require('tweetnacl');
|
|
|
26
26
|
require('open');
|
|
27
27
|
var React = require('react');
|
|
28
28
|
var ink = require('ink');
|
|
29
|
-
var
|
|
30
|
-
var
|
|
29
|
+
var createKeepAliveController = require('./createKeepAliveController-DO8H6d5E.cjs');
|
|
30
|
+
var ConversationHistory = require('./ConversationHistory-V3VLmjJf.cjs');
|
|
31
31
|
require('socket.io-client');
|
|
32
32
|
require('zod');
|
|
33
33
|
require('expo-server-sdk');
|
|
@@ -146,7 +146,7 @@ class CodexSession {
|
|
|
146
146
|
this.queue = opts.messageQueue;
|
|
147
147
|
this.codexArgs = opts.codexArgs;
|
|
148
148
|
this.onModeChangeCallback = opts.onModeChange;
|
|
149
|
-
this.keepAliveController =
|
|
149
|
+
this.keepAliveController = createKeepAliveController.createKeepAliveController({
|
|
150
150
|
initialMode: this.mode,
|
|
151
151
|
initialThinking: this.thinking,
|
|
152
152
|
send: (thinking, mode) => {
|
|
@@ -316,7 +316,7 @@ const CodexDisplay = ({ messageBuffer, logPath, onExit, title }) => {
|
|
|
316
316
|
));
|
|
317
317
|
};
|
|
318
318
|
|
|
319
|
-
class CodexPermissionHandler extends
|
|
319
|
+
class CodexPermissionHandler extends ConversationHistory.BasePermissionHandler {
|
|
320
320
|
constructor(session) {
|
|
321
321
|
super(session);
|
|
322
322
|
}
|
|
@@ -335,13 +335,220 @@ class CodexPermissionHandler extends registerKillSessionHandler.BasePermissionHa
|
|
|
335
335
|
}
|
|
336
336
|
}
|
|
337
337
|
|
|
338
|
-
class
|
|
338
|
+
class ProviderSelectionHandler {
|
|
339
|
+
pendingRequests = /* @__PURE__ */ new Map();
|
|
340
|
+
session;
|
|
341
|
+
providerLabel;
|
|
342
|
+
constructor(session, providerLabel) {
|
|
343
|
+
this.session = session;
|
|
344
|
+
this.providerLabel = providerLabel;
|
|
345
|
+
this.setupRpcHandler();
|
|
346
|
+
}
|
|
347
|
+
updateSession(newSession) {
|
|
348
|
+
this.session = newSession;
|
|
349
|
+
this.setupRpcHandler();
|
|
350
|
+
}
|
|
351
|
+
async requestSelection(request) {
|
|
352
|
+
return new Promise((resolve, reject) => {
|
|
353
|
+
const pending = {
|
|
354
|
+
resolve,
|
|
355
|
+
reject,
|
|
356
|
+
request
|
|
357
|
+
};
|
|
358
|
+
pending.timeoutHandle = setTimeout(() => {
|
|
359
|
+
this.handleSelectionTimeout(request.id, pending);
|
|
360
|
+
}, ConversationHistory.getPendingInteractionTimeoutMs());
|
|
361
|
+
this.pendingRequests.set(request.id, pending);
|
|
362
|
+
this.session.updateAgentState((currentState) => ({
|
|
363
|
+
...currentState,
|
|
364
|
+
requests: {
|
|
365
|
+
...currentState.requests,
|
|
366
|
+
[request.id]: {
|
|
367
|
+
tool: "AskUserQuestion",
|
|
368
|
+
arguments: {
|
|
369
|
+
requestKind: "selection",
|
|
370
|
+
questions: [
|
|
371
|
+
{
|
|
372
|
+
header: this.providerLabel,
|
|
373
|
+
question: request.message,
|
|
374
|
+
multiSelect: false,
|
|
375
|
+
options: request.options.map((option) => ({
|
|
376
|
+
label: option.label,
|
|
377
|
+
description: option.description || option.optionId,
|
|
378
|
+
optionId: option.optionId
|
|
379
|
+
}))
|
|
380
|
+
}
|
|
381
|
+
]
|
|
382
|
+
},
|
|
383
|
+
createdAt: Date.now(),
|
|
384
|
+
requestKind: "selection",
|
|
385
|
+
options: request.options,
|
|
386
|
+
defaultOptionId: request.defaultOptionId
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
}));
|
|
390
|
+
api.logger.debug(`[${this.providerLabel}] Selection request sent (${request.id}) with ${request.options.length} options`);
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
hasPendingRequests() {
|
|
394
|
+
return this.pendingRequests.size > 0;
|
|
395
|
+
}
|
|
396
|
+
supersedePendingRequests(reason = ConversationHistory.INTERACTION_SUPERSEDED_ERROR) {
|
|
397
|
+
const pendingSnapshot = Array.from(this.pendingRequests.entries());
|
|
398
|
+
if (pendingSnapshot.length === 0) {
|
|
399
|
+
return 0;
|
|
400
|
+
}
|
|
401
|
+
this.pendingRequests.clear();
|
|
402
|
+
const completedAt = Date.now();
|
|
403
|
+
for (const [, pending] of pendingSnapshot) {
|
|
404
|
+
this.clearPendingRequestTimeout(pending);
|
|
405
|
+
pending.reject(new Error(reason));
|
|
406
|
+
}
|
|
407
|
+
this.session.updateAgentState((currentState) => {
|
|
408
|
+
const requests = { ...currentState.requests || {} };
|
|
409
|
+
const completedRequests = { ...currentState.completedRequests || {} };
|
|
410
|
+
for (const [id, request] of Object.entries(requests)) {
|
|
411
|
+
if (request.requestKind !== "selection") {
|
|
412
|
+
continue;
|
|
413
|
+
}
|
|
414
|
+
completedRequests[id] = {
|
|
415
|
+
...request,
|
|
416
|
+
completedAt,
|
|
417
|
+
status: "canceled",
|
|
418
|
+
reason,
|
|
419
|
+
requestKind: "selection"
|
|
420
|
+
};
|
|
421
|
+
delete requests[id];
|
|
422
|
+
}
|
|
423
|
+
return {
|
|
424
|
+
...currentState,
|
|
425
|
+
requests,
|
|
426
|
+
completedRequests
|
|
427
|
+
};
|
|
428
|
+
});
|
|
429
|
+
api.logger.debug(`[${this.providerLabel}] Superseded ${pendingSnapshot.length} pending selection request(s)`);
|
|
430
|
+
return pendingSnapshot.length;
|
|
431
|
+
}
|
|
432
|
+
reset(reason = "Session reset") {
|
|
433
|
+
const pendingSnapshot = Array.from(this.pendingRequests.entries());
|
|
434
|
+
this.pendingRequests.clear();
|
|
435
|
+
for (const [, pending] of pendingSnapshot) {
|
|
436
|
+
this.clearPendingRequestTimeout(pending);
|
|
437
|
+
pending.reject(new Error(reason));
|
|
438
|
+
}
|
|
439
|
+
this.session.updateAgentState((currentState) => {
|
|
440
|
+
const requests = { ...currentState.requests || {} };
|
|
441
|
+
const completedRequests = { ...currentState.completedRequests || {} };
|
|
442
|
+
for (const [id, request] of Object.entries(requests)) {
|
|
443
|
+
if (request.requestKind !== "selection") {
|
|
444
|
+
continue;
|
|
445
|
+
}
|
|
446
|
+
completedRequests[id] = {
|
|
447
|
+
...request,
|
|
448
|
+
completedAt: Date.now(),
|
|
449
|
+
status: "canceled",
|
|
450
|
+
reason,
|
|
451
|
+
requestKind: "selection"
|
|
452
|
+
};
|
|
453
|
+
delete requests[id];
|
|
454
|
+
}
|
|
455
|
+
return {
|
|
456
|
+
...currentState,
|
|
457
|
+
requests,
|
|
458
|
+
completedRequests
|
|
459
|
+
};
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
setupRpcHandler() {
|
|
463
|
+
this.session.rpcHandlerManager.registerHandler("selection", async (response) => {
|
|
464
|
+
const pending = this.pendingRequests.get(response.id);
|
|
465
|
+
if (!pending) {
|
|
466
|
+
api.logger.debug(`[${this.providerLabel}] Selection request not found or already resolved`);
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
this.pendingRequests.delete(response.id);
|
|
470
|
+
this.clearPendingRequestTimeout(pending);
|
|
471
|
+
pending.resolve(response);
|
|
472
|
+
this.session.updateAgentState((currentState) => {
|
|
473
|
+
const request = currentState.requests?.[response.id];
|
|
474
|
+
if (!request) {
|
|
475
|
+
return currentState;
|
|
476
|
+
}
|
|
477
|
+
const { [response.id]: _, ...remainingRequests } = currentState.requests || {};
|
|
478
|
+
return {
|
|
479
|
+
...currentState,
|
|
480
|
+
requests: remainingRequests,
|
|
481
|
+
completedRequests: {
|
|
482
|
+
...currentState.completedRequests,
|
|
483
|
+
[response.id]: {
|
|
484
|
+
...request,
|
|
485
|
+
completedAt: Date.now(),
|
|
486
|
+
status: "approved",
|
|
487
|
+
requestKind: "selection",
|
|
488
|
+
selectedOptionId: response.optionId
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
};
|
|
492
|
+
});
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
clearPendingRequestTimeout(pending) {
|
|
496
|
+
if (pending?.timeoutHandle) {
|
|
497
|
+
clearTimeout(pending.timeoutHandle);
|
|
498
|
+
pending.timeoutHandle = void 0;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
handleSelectionTimeout(requestId, pending) {
|
|
502
|
+
const active = this.pendingRequests.get(requestId);
|
|
503
|
+
if (!active || active !== pending) {
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
506
|
+
this.pendingRequests.delete(requestId);
|
|
507
|
+
this.clearPendingRequestTimeout(active);
|
|
508
|
+
active.reject(new Error(ConversationHistory.INTERACTION_TIMED_OUT_ERROR));
|
|
509
|
+
this.session.updateAgentState((currentState) => {
|
|
510
|
+
const request = currentState.requests?.[requestId] || {
|
|
511
|
+
tool: "AskUserQuestion",
|
|
512
|
+
arguments: {
|
|
513
|
+
requestKind: "selection",
|
|
514
|
+
questions: []
|
|
515
|
+
},
|
|
516
|
+
createdAt: Date.now(),
|
|
517
|
+
requestKind: "selection",
|
|
518
|
+
options: active.request.options,
|
|
519
|
+
defaultOptionId: active.request.defaultOptionId
|
|
520
|
+
};
|
|
521
|
+
const { [requestId]: _, ...remainingRequests } = currentState.requests || {};
|
|
522
|
+
return {
|
|
523
|
+
...currentState,
|
|
524
|
+
requests: remainingRequests,
|
|
525
|
+
completedRequests: {
|
|
526
|
+
...currentState.completedRequests,
|
|
527
|
+
[requestId]: {
|
|
528
|
+
...request,
|
|
529
|
+
completedAt: Date.now(),
|
|
530
|
+
status: "canceled",
|
|
531
|
+
reason: ConversationHistory.INTERACTION_TIMED_OUT_ERROR,
|
|
532
|
+
requestKind: "selection"
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
};
|
|
536
|
+
});
|
|
537
|
+
this.session.sendSessionEvent({
|
|
538
|
+
type: "message",
|
|
539
|
+
message: "Pending interaction timed out waiting for a response. Send a new message to continue."
|
|
540
|
+
});
|
|
541
|
+
api.logger.debug(`[${this.providerLabel}] Selection request timed out (${requestId})`);
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
class CodexSelectionHandler extends ProviderSelectionHandler {
|
|
339
546
|
constructor(session) {
|
|
340
547
|
super(session, "Codex");
|
|
341
548
|
}
|
|
342
549
|
}
|
|
343
550
|
|
|
344
|
-
class ReasoningProcessor extends
|
|
551
|
+
class ReasoningProcessor extends ConversationHistory.BaseReasoningProcessor {
|
|
345
552
|
getToolName() {
|
|
346
553
|
return "CodexReasoning";
|
|
347
554
|
}
|
|
@@ -492,7 +699,7 @@ async function codexRemoteLauncher(session) {
|
|
|
492
699
|
let currentThinkingMessageId = null;
|
|
493
700
|
const permissionHandler = new CodexPermissionHandler(session.client);
|
|
494
701
|
const selectionHandler = new CodexSelectionHandler(session.client);
|
|
495
|
-
const conversationHistory = new
|
|
702
|
+
const conversationHistory = new ConversationHistory.ConversationHistory({ maxMessages: 20, maxCharacters: 5e4 });
|
|
496
703
|
const reasoningProcessor = new ReasoningProcessor((message) => {
|
|
497
704
|
session.runtimeSession.sendCodexMessage(message);
|
|
498
705
|
});
|
|
@@ -586,7 +793,7 @@ async function codexRemoteLauncher(session) {
|
|
|
586
793
|
};
|
|
587
794
|
const setupRuntimeMessageHandler = (activeRuntimeHandle) => {
|
|
588
795
|
const forwardAgentMessage = (agentMessage) => {
|
|
589
|
-
|
|
796
|
+
ConversationHistory.forwardAgentMessageToProviderSession(agentMessage, {
|
|
590
797
|
provider: "codex",
|
|
591
798
|
send: (body) => session.runtimeSession.sendCodexMessage(body),
|
|
592
799
|
toolResultType: "tool-call-result"
|
|
@@ -652,7 +859,7 @@ async function codexRemoteLauncher(session) {
|
|
|
652
859
|
return;
|
|
653
860
|
}
|
|
654
861
|
case "tool-result": {
|
|
655
|
-
const isError =
|
|
862
|
+
const isError = ConversationHistory.inferToolResultError(msg.result);
|
|
656
863
|
const resultText = index.truncateDisplayMessage(msg.result, 200) || (isError ? "Unknown error" : "");
|
|
657
864
|
messageBuffer.addMessage(
|
|
658
865
|
`${isError ? "Error:" : "Result:"} ${resultText}`.trim(),
|
|
@@ -739,7 +946,7 @@ async function codexRemoteLauncher(session) {
|
|
|
739
946
|
if (!validation.ok) {
|
|
740
947
|
throw new Error(validation.errorMessage);
|
|
741
948
|
}
|
|
742
|
-
const { session: nextRuntimeHandle } = await
|
|
949
|
+
const { session: nextRuntimeHandle } = await ConversationHistory.launchRuntimeHandleWithFactoryResult({
|
|
743
950
|
provider: "codex",
|
|
744
951
|
cwd: session.path,
|
|
745
952
|
createBackendResult: (opts) => index.createCodexBackend({
|
|
@@ -874,7 +1081,7 @@ async function codexRemoteLauncher(session) {
|
|
|
874
1081
|
}
|
|
875
1082
|
conversationHistory.addUserMessage(message.message);
|
|
876
1083
|
await activeRuntimeHandle.sendPrompt(promptToSend);
|
|
877
|
-
await
|
|
1084
|
+
await ConversationHistory.waitForResponseCompleteWithAbort(activeRuntimeHandle.backend, turnSignal);
|
|
878
1085
|
reasoningProcessor.completeCurrent();
|
|
879
1086
|
shouldCommitAccumulatedResponse = true;
|
|
880
1087
|
shouldInjectHistoryOnNextSession = false;
|
|
@@ -959,7 +1166,7 @@ async function codexLoop(opts) {
|
|
|
959
1166
|
await codexRemoteLauncher(opts.session);
|
|
960
1167
|
return { type: "exit", value: 0 };
|
|
961
1168
|
};
|
|
962
|
-
return await
|
|
1169
|
+
return await createKeepAliveController.runModeLoop({
|
|
963
1170
|
startingMode: displayMode,
|
|
964
1171
|
notifyInitialMode: true,
|
|
965
1172
|
onModeChange: async (mode) => {
|
|
@@ -1025,7 +1232,7 @@ async function runCodex(opts) {
|
|
|
1025
1232
|
}
|
|
1026
1233
|
let sessionClient;
|
|
1027
1234
|
let codexSession = null;
|
|
1028
|
-
const { metadata, session: initialSession, reconnectionHandle } = await
|
|
1235
|
+
const { metadata, session: initialSession, reconnectionHandle } = await ConversationHistory.bootstrapManagedProviderSession({
|
|
1029
1236
|
api: api$1,
|
|
1030
1237
|
sessionTag,
|
|
1031
1238
|
flavor: "codex",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
|
-
import { l as logger, b as connectionState, A as ApiClient } from './api-
|
|
3
|
-
import {
|
|
4
|
-
import { f as formatDisplayMessage, v as validateCodexAcpSpawn, d as createCodexBackend, t as truncateDisplayMessage, b as stopCaffeinate } from './index-
|
|
2
|
+
import { l as logger, b as connectionState, A as ApiClient } from './api-D1meoL-9.mjs';
|
|
3
|
+
import { h as hashObject, b as MessageBuffer, r as registerKillSessionHandler, c as closeProviderSession, e as ensureManagedProviderMachine, M as MissingMachineIdError, a as MessageQueue2, s as syncControlledByUserState } from './registerKillSessionHandler-BElGmD1E.mjs';
|
|
4
|
+
import { f as formatDisplayMessage, v as validateCodexAcpSpawn, d as createCodexBackend, t as truncateDisplayMessage, b as stopCaffeinate } from './index-Cxrx9m5D.mjs';
|
|
5
5
|
import 'cross-spawn';
|
|
6
6
|
import '@agentclientprotocol/sdk';
|
|
7
7
|
import 'ps-list';
|
|
@@ -12,7 +12,7 @@ import 'child_process';
|
|
|
12
12
|
import 'node:fs';
|
|
13
13
|
import 'node:path';
|
|
14
14
|
import 'node:os';
|
|
15
|
-
import './persistence-
|
|
15
|
+
import './persistence-9Iu0wGNM.mjs';
|
|
16
16
|
import 'node:fs/promises';
|
|
17
17
|
import 'fs/promises';
|
|
18
18
|
import 'crypto';
|
|
@@ -24,8 +24,8 @@ import 'tweetnacl';
|
|
|
24
24
|
import 'open';
|
|
25
25
|
import React, { useState, useRef, useEffect, useCallback } from 'react';
|
|
26
26
|
import { useStdout, useInput, Box, Text, render } from 'ink';
|
|
27
|
-
import { c as createKeepAliveController,
|
|
28
|
-
import { B as BaseReasoningProcessor, b as bootstrapManagedProviderSession } from './
|
|
27
|
+
import { c as createKeepAliveController, r as runModeLoop } from './createKeepAliveController-C5cQlDRr.mjs';
|
|
28
|
+
import { B as BasePermissionHandler, g as getPendingInteractionTimeoutMs, I as INTERACTION_SUPERSEDED_ERROR, c as INTERACTION_TIMED_OUT_ERROR, a as BaseReasoningProcessor, C as ConversationHistory$1, w as waitForResponseCompleteWithAbort, l as launchRuntimeHandleWithFactoryResult, i as inferToolResultError, f as forwardAgentMessageToProviderSession, b as bootstrapManagedProviderSession } from './ConversationHistory-_ciJNIgH.mjs';
|
|
29
29
|
import 'socket.io-client';
|
|
30
30
|
import 'zod';
|
|
31
31
|
import 'expo-server-sdk';
|
|
@@ -333,6 +333,213 @@ class CodexPermissionHandler extends BasePermissionHandler {
|
|
|
333
333
|
}
|
|
334
334
|
}
|
|
335
335
|
|
|
336
|
+
class ProviderSelectionHandler {
|
|
337
|
+
pendingRequests = /* @__PURE__ */ new Map();
|
|
338
|
+
session;
|
|
339
|
+
providerLabel;
|
|
340
|
+
constructor(session, providerLabel) {
|
|
341
|
+
this.session = session;
|
|
342
|
+
this.providerLabel = providerLabel;
|
|
343
|
+
this.setupRpcHandler();
|
|
344
|
+
}
|
|
345
|
+
updateSession(newSession) {
|
|
346
|
+
this.session = newSession;
|
|
347
|
+
this.setupRpcHandler();
|
|
348
|
+
}
|
|
349
|
+
async requestSelection(request) {
|
|
350
|
+
return new Promise((resolve, reject) => {
|
|
351
|
+
const pending = {
|
|
352
|
+
resolve,
|
|
353
|
+
reject,
|
|
354
|
+
request
|
|
355
|
+
};
|
|
356
|
+
pending.timeoutHandle = setTimeout(() => {
|
|
357
|
+
this.handleSelectionTimeout(request.id, pending);
|
|
358
|
+
}, getPendingInteractionTimeoutMs());
|
|
359
|
+
this.pendingRequests.set(request.id, pending);
|
|
360
|
+
this.session.updateAgentState((currentState) => ({
|
|
361
|
+
...currentState,
|
|
362
|
+
requests: {
|
|
363
|
+
...currentState.requests,
|
|
364
|
+
[request.id]: {
|
|
365
|
+
tool: "AskUserQuestion",
|
|
366
|
+
arguments: {
|
|
367
|
+
requestKind: "selection",
|
|
368
|
+
questions: [
|
|
369
|
+
{
|
|
370
|
+
header: this.providerLabel,
|
|
371
|
+
question: request.message,
|
|
372
|
+
multiSelect: false,
|
|
373
|
+
options: request.options.map((option) => ({
|
|
374
|
+
label: option.label,
|
|
375
|
+
description: option.description || option.optionId,
|
|
376
|
+
optionId: option.optionId
|
|
377
|
+
}))
|
|
378
|
+
}
|
|
379
|
+
]
|
|
380
|
+
},
|
|
381
|
+
createdAt: Date.now(),
|
|
382
|
+
requestKind: "selection",
|
|
383
|
+
options: request.options,
|
|
384
|
+
defaultOptionId: request.defaultOptionId
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}));
|
|
388
|
+
logger.debug(`[${this.providerLabel}] Selection request sent (${request.id}) with ${request.options.length} options`);
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
hasPendingRequests() {
|
|
392
|
+
return this.pendingRequests.size > 0;
|
|
393
|
+
}
|
|
394
|
+
supersedePendingRequests(reason = INTERACTION_SUPERSEDED_ERROR) {
|
|
395
|
+
const pendingSnapshot = Array.from(this.pendingRequests.entries());
|
|
396
|
+
if (pendingSnapshot.length === 0) {
|
|
397
|
+
return 0;
|
|
398
|
+
}
|
|
399
|
+
this.pendingRequests.clear();
|
|
400
|
+
const completedAt = Date.now();
|
|
401
|
+
for (const [, pending] of pendingSnapshot) {
|
|
402
|
+
this.clearPendingRequestTimeout(pending);
|
|
403
|
+
pending.reject(new Error(reason));
|
|
404
|
+
}
|
|
405
|
+
this.session.updateAgentState((currentState) => {
|
|
406
|
+
const requests = { ...currentState.requests || {} };
|
|
407
|
+
const completedRequests = { ...currentState.completedRequests || {} };
|
|
408
|
+
for (const [id, request] of Object.entries(requests)) {
|
|
409
|
+
if (request.requestKind !== "selection") {
|
|
410
|
+
continue;
|
|
411
|
+
}
|
|
412
|
+
completedRequests[id] = {
|
|
413
|
+
...request,
|
|
414
|
+
completedAt,
|
|
415
|
+
status: "canceled",
|
|
416
|
+
reason,
|
|
417
|
+
requestKind: "selection"
|
|
418
|
+
};
|
|
419
|
+
delete requests[id];
|
|
420
|
+
}
|
|
421
|
+
return {
|
|
422
|
+
...currentState,
|
|
423
|
+
requests,
|
|
424
|
+
completedRequests
|
|
425
|
+
};
|
|
426
|
+
});
|
|
427
|
+
logger.debug(`[${this.providerLabel}] Superseded ${pendingSnapshot.length} pending selection request(s)`);
|
|
428
|
+
return pendingSnapshot.length;
|
|
429
|
+
}
|
|
430
|
+
reset(reason = "Session reset") {
|
|
431
|
+
const pendingSnapshot = Array.from(this.pendingRequests.entries());
|
|
432
|
+
this.pendingRequests.clear();
|
|
433
|
+
for (const [, pending] of pendingSnapshot) {
|
|
434
|
+
this.clearPendingRequestTimeout(pending);
|
|
435
|
+
pending.reject(new Error(reason));
|
|
436
|
+
}
|
|
437
|
+
this.session.updateAgentState((currentState) => {
|
|
438
|
+
const requests = { ...currentState.requests || {} };
|
|
439
|
+
const completedRequests = { ...currentState.completedRequests || {} };
|
|
440
|
+
for (const [id, request] of Object.entries(requests)) {
|
|
441
|
+
if (request.requestKind !== "selection") {
|
|
442
|
+
continue;
|
|
443
|
+
}
|
|
444
|
+
completedRequests[id] = {
|
|
445
|
+
...request,
|
|
446
|
+
completedAt: Date.now(),
|
|
447
|
+
status: "canceled",
|
|
448
|
+
reason,
|
|
449
|
+
requestKind: "selection"
|
|
450
|
+
};
|
|
451
|
+
delete requests[id];
|
|
452
|
+
}
|
|
453
|
+
return {
|
|
454
|
+
...currentState,
|
|
455
|
+
requests,
|
|
456
|
+
completedRequests
|
|
457
|
+
};
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
setupRpcHandler() {
|
|
461
|
+
this.session.rpcHandlerManager.registerHandler("selection", async (response) => {
|
|
462
|
+
const pending = this.pendingRequests.get(response.id);
|
|
463
|
+
if (!pending) {
|
|
464
|
+
logger.debug(`[${this.providerLabel}] Selection request not found or already resolved`);
|
|
465
|
+
return;
|
|
466
|
+
}
|
|
467
|
+
this.pendingRequests.delete(response.id);
|
|
468
|
+
this.clearPendingRequestTimeout(pending);
|
|
469
|
+
pending.resolve(response);
|
|
470
|
+
this.session.updateAgentState((currentState) => {
|
|
471
|
+
const request = currentState.requests?.[response.id];
|
|
472
|
+
if (!request) {
|
|
473
|
+
return currentState;
|
|
474
|
+
}
|
|
475
|
+
const { [response.id]: _, ...remainingRequests } = currentState.requests || {};
|
|
476
|
+
return {
|
|
477
|
+
...currentState,
|
|
478
|
+
requests: remainingRequests,
|
|
479
|
+
completedRequests: {
|
|
480
|
+
...currentState.completedRequests,
|
|
481
|
+
[response.id]: {
|
|
482
|
+
...request,
|
|
483
|
+
completedAt: Date.now(),
|
|
484
|
+
status: "approved",
|
|
485
|
+
requestKind: "selection",
|
|
486
|
+
selectedOptionId: response.optionId
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
};
|
|
490
|
+
});
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
clearPendingRequestTimeout(pending) {
|
|
494
|
+
if (pending?.timeoutHandle) {
|
|
495
|
+
clearTimeout(pending.timeoutHandle);
|
|
496
|
+
pending.timeoutHandle = void 0;
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
handleSelectionTimeout(requestId, pending) {
|
|
500
|
+
const active = this.pendingRequests.get(requestId);
|
|
501
|
+
if (!active || active !== pending) {
|
|
502
|
+
return;
|
|
503
|
+
}
|
|
504
|
+
this.pendingRequests.delete(requestId);
|
|
505
|
+
this.clearPendingRequestTimeout(active);
|
|
506
|
+
active.reject(new Error(INTERACTION_TIMED_OUT_ERROR));
|
|
507
|
+
this.session.updateAgentState((currentState) => {
|
|
508
|
+
const request = currentState.requests?.[requestId] || {
|
|
509
|
+
tool: "AskUserQuestion",
|
|
510
|
+
arguments: {
|
|
511
|
+
requestKind: "selection",
|
|
512
|
+
questions: []
|
|
513
|
+
},
|
|
514
|
+
createdAt: Date.now(),
|
|
515
|
+
requestKind: "selection",
|
|
516
|
+
options: active.request.options,
|
|
517
|
+
defaultOptionId: active.request.defaultOptionId
|
|
518
|
+
};
|
|
519
|
+
const { [requestId]: _, ...remainingRequests } = currentState.requests || {};
|
|
520
|
+
return {
|
|
521
|
+
...currentState,
|
|
522
|
+
requests: remainingRequests,
|
|
523
|
+
completedRequests: {
|
|
524
|
+
...currentState.completedRequests,
|
|
525
|
+
[requestId]: {
|
|
526
|
+
...request,
|
|
527
|
+
completedAt: Date.now(),
|
|
528
|
+
status: "canceled",
|
|
529
|
+
reason: INTERACTION_TIMED_OUT_ERROR,
|
|
530
|
+
requestKind: "selection"
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
};
|
|
534
|
+
});
|
|
535
|
+
this.session.sendSessionEvent({
|
|
536
|
+
type: "message",
|
|
537
|
+
message: "Pending interaction timed out waiting for a response. Send a new message to continue."
|
|
538
|
+
});
|
|
539
|
+
logger.debug(`[${this.providerLabel}] Selection request timed out (${requestId})`);
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
|
|
336
543
|
class CodexSelectionHandler extends ProviderSelectionHandler {
|
|
337
544
|
constructor(session) {
|
|
338
545
|
super(session, "Codex");
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { useStdout, useInput, Box, Text, render } from 'ink';
|
|
2
2
|
import React, { useState, useRef, useEffect, useCallback } from 'react';
|
|
3
3
|
import { randomUUID } from 'node:crypto';
|
|
4
|
-
import { l as logger, b as connectionState, A as ApiClient } from './api-
|
|
5
|
-
import {
|
|
6
|
-
import { g as getInitialGeminiModel, r as readGeminiLocalConfig, G as GEMINI_MODEL_ENV, s as saveGeminiModelToConfig, a as createGeminiBackend, b as stopCaffeinate } from './index-
|
|
7
|
-
import { B as BaseReasoningProcessor, b as bootstrapManagedProviderSession } from './
|
|
4
|
+
import { l as logger, b as connectionState, A as ApiClient } from './api-D1meoL-9.mjs';
|
|
5
|
+
import { e as ensureManagedProviderMachine, M as MissingMachineIdError, s as syncControlledByUserState, a as MessageQueue2, h as hashObject, b as MessageBuffer, r as registerKillSessionHandler, c as closeProviderSession } from './registerKillSessionHandler-BElGmD1E.mjs';
|
|
6
|
+
import { g as getInitialGeminiModel, r as readGeminiLocalConfig, G as GEMINI_MODEL_ENV, s as saveGeminiModelToConfig, a as createGeminiBackend, b as stopCaffeinate } from './index-Cxrx9m5D.mjs';
|
|
7
|
+
import { B as BasePermissionHandler, a as BaseReasoningProcessor, C as ConversationHistory$1, b as bootstrapManagedProviderSession, w as waitForResponseCompleteWithAbort, l as launchRuntimeHandleWithFactoryResult, i as inferToolResultError, f as forwardAgentMessageToProviderSession } from './ConversationHistory-_ciJNIgH.mjs';
|
|
8
8
|
import 'cross-spawn';
|
|
9
9
|
import '@agentclientprotocol/sdk';
|
|
10
10
|
import 'ps-list';
|
|
@@ -13,7 +13,7 @@ import 'node:path';
|
|
|
13
13
|
import 'node:os';
|
|
14
14
|
import 'tweetnacl';
|
|
15
15
|
import 'axios';
|
|
16
|
-
import './persistence-
|
|
16
|
+
import './persistence-9Iu0wGNM.mjs';
|
|
17
17
|
import 'open';
|
|
18
18
|
import 'chalk';
|
|
19
19
|
import 'fs';
|