happy-imou-cloud 2.0.22 → 2.1.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.
- package/bin/happy-cloud.mjs +1 -1
- package/dist/{BaseReasoningProcessor-CJVv1aNR.cjs → BaseReasoningProcessor-C9mH8EVn.cjs} +3 -3
- package/dist/{BaseReasoningProcessor-mIqqngd3.mjs → BaseReasoningProcessor-DQkzwRuf.mjs} +3 -3
- package/dist/ProviderSelectionHandler-5Dedbm8j.cjs +265 -0
- package/dist/ProviderSelectionHandler-BlrrLPlo.mjs +261 -0
- package/dist/{api-DP-RQUao.cjs → api-Bd-MnOS4.cjs} +24 -2
- package/dist/{api-DrijKeDb.mjs → api-w_CUxb9Q.mjs} +25 -3
- package/dist/{command-BZphfJrt.cjs → command-DoDmHNxR.cjs} +3 -3
- package/dist/{command--vV6BSsL.mjs → command-mTWwCqTY.mjs} +3 -3
- package/dist/{index-CqCEZDFi.cjs → index-BQmJ4NAa.cjs} +199 -79
- package/dist/{index-BIki80pQ.mjs → index-GuXV-pxB.mjs} +196 -76
- package/dist/index.cjs +3 -3
- package/dist/index.mjs +3 -3
- package/dist/lib.cjs +1 -1
- package/dist/lib.d.cts +95 -92
- package/dist/lib.d.mts +95 -92
- package/dist/lib.mjs +1 -1
- package/dist/{persistence-yVTbf_Ng.cjs → persistence-BL06LLVz.cjs} +1 -1
- package/dist/{persistence-C3NBdZdz.mjs → persistence-MSy70is3.mjs} +1 -1
- package/dist/{registerKillSessionHandler-CHEj7UjN.mjs → registerKillSessionHandler-CjWfUfc3.mjs} +428 -13
- package/dist/{registerKillSessionHandler-QmBN446A.cjs → registerKillSessionHandler-D9kwxy6B.cjs} +430 -12
- package/dist/{runClaude-BuI6OOEv.cjs → runClaude-D2ZEXue8.cjs} +11 -9
- package/dist/{runClaude-D0DD_Ya5.mjs → runClaude-DpZ95Twb.mjs} +8 -6
- package/dist/{runCodex-BzZ0jODI.mjs → runCodex-CJwaep2R.mjs} +9 -7
- package/dist/{runCodex-1jTTmCvq.cjs → runCodex-Dz_1ho8d.cjs} +12 -10
- package/dist/{runGemini-Bx2SYAyG.mjs → runGemini-BehqjM73.mjs} +192 -71
- package/dist/{runGemini-1gJRE8oT.cjs → runGemini-Dfu6LltX.cjs} +192 -71
- package/package.json +1 -1
- 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 +3 -0
- package/dist/ProviderSelectionHandler-BjLyIfSR.mjs +0 -673
- package/dist/ProviderSelectionHandler-e4zL4Y5_.cjs +0 -680
|
@@ -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-Bd-MnOS4.cjs');
|
|
5
|
+
var registerKillSessionHandler = require('./registerKillSessionHandler-D9kwxy6B.cjs');
|
|
6
|
+
var index = require('./index-BQmJ4NAa.cjs');
|
|
7
7
|
require('cross-spawn');
|
|
8
8
|
require('@agentclientprotocol/sdk');
|
|
9
9
|
require('ps-list');
|
|
@@ -16,7 +16,7 @@ require('node:path');
|
|
|
16
16
|
require('node:os');
|
|
17
17
|
require('node:child_process');
|
|
18
18
|
require('node:readline');
|
|
19
|
-
require('./persistence-
|
|
19
|
+
require('./persistence-BL06LLVz.cjs');
|
|
20
20
|
require('node:fs/promises');
|
|
21
21
|
require('fs/promises');
|
|
22
22
|
require('crypto');
|
|
@@ -27,8 +27,8 @@ require('tweetnacl');
|
|
|
27
27
|
require('open');
|
|
28
28
|
var React = require('react');
|
|
29
29
|
var ink = require('ink');
|
|
30
|
-
var ProviderSelectionHandler = require('./ProviderSelectionHandler-
|
|
31
|
-
var BaseReasoningProcessor = require('./BaseReasoningProcessor-
|
|
30
|
+
var ProviderSelectionHandler = require('./ProviderSelectionHandler-5Dedbm8j.cjs');
|
|
31
|
+
var BaseReasoningProcessor = require('./BaseReasoningProcessor-C9mH8EVn.cjs');
|
|
32
32
|
require('zod');
|
|
33
33
|
require('socket.io-client');
|
|
34
34
|
require('expo-server-sdk');
|
|
@@ -1021,7 +1021,7 @@ async function codexRemoteLauncher(session) {
|
|
|
1021
1021
|
api.logger.debug(`[Codex] Injected conversation history context (${historyContext.length} chars)`);
|
|
1022
1022
|
}
|
|
1023
1023
|
if (message.mode.happyOrg) {
|
|
1024
|
-
promptToSend =
|
|
1024
|
+
promptToSend = registerKillSessionHandler.buildHappyOrgTurnPrompt(promptToSend, message.mode.happyOrg);
|
|
1025
1025
|
}
|
|
1026
1026
|
conversationHistory.addUserMessage(message.message);
|
|
1027
1027
|
await activeRuntimeHandle.sendPrompt(promptToSend);
|
|
@@ -1051,7 +1051,7 @@ async function codexRemoteLauncher(session) {
|
|
|
1051
1051
|
}
|
|
1052
1052
|
} finally {
|
|
1053
1053
|
turnInFlight = false;
|
|
1054
|
-
const finalizedTurn =
|
|
1054
|
+
const finalizedTurn = registerKillSessionHandler.finalizeHappyOrgTurn({
|
|
1055
1055
|
metadata: session.runtimeSession.getMetadataSnapshot?.() ?? null,
|
|
1056
1056
|
queuedTurn: message.mode.happyOrg,
|
|
1057
1057
|
responseText: accumulatedResponse,
|
|
@@ -1233,7 +1233,7 @@ async function runCodex(opts) {
|
|
|
1233
1233
|
let currentPermissionMode = initialPermissionMode;
|
|
1234
1234
|
let currentModel;
|
|
1235
1235
|
sessionClient.onUserMessage((message) => {
|
|
1236
|
-
const happyOrgResult =
|
|
1236
|
+
const happyOrgResult = registerKillSessionHandler.resolveHappyOrgQueuedTurn({
|
|
1237
1237
|
metadata: sessionClient.getMetadataSnapshot?.() ?? metadata,
|
|
1238
1238
|
message
|
|
1239
1239
|
});
|
|
@@ -1299,7 +1299,9 @@ async function runCodex(opts) {
|
|
|
1299
1299
|
loopError = error;
|
|
1300
1300
|
} finally {
|
|
1301
1301
|
try {
|
|
1302
|
-
await registerKillSessionHandler.closeProviderSession(sessionClient
|
|
1302
|
+
await registerKillSessionHandler.closeProviderSession(sessionClient, {
|
|
1303
|
+
archiveOnClose: true
|
|
1304
|
+
});
|
|
1303
1305
|
} catch (error) {
|
|
1304
1306
|
closeError = error;
|
|
1305
1307
|
}
|
|
@@ -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,
|
|
5
|
-
import { B as BasePermissionHandler, C as ConversationHistory$1, e as ensureManagedProviderMachine, M as MissingMachineIdError, s as syncControlledByUserState, b as MessageQueue2, h as hashObject, d as MessageBuffer,
|
|
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 './BaseReasoningProcessor-
|
|
4
|
+
import { l as logger, b as connectionState, A as ApiClient } from './api-w_CUxb9Q.mjs';
|
|
5
|
+
import { B as BasePermissionHandler, C as ConversationHistory$1, r as resolveHappyOrgQueuedTurn, e as ensureManagedProviderMachine, M as MissingMachineIdError, s as syncControlledByUserState, b as MessageQueue2, h as hashObject, d as registerKillSessionHandler, f as MessageBuffer, i as buildHappyOrgTurnPrompt, w as waitForResponseCompleteWithAbort, j as finalizeHappyOrgTurn, k as closeProviderSession, l as launchRuntimeHandleWithFactoryResult, m as inferToolResultError, n as forwardAgentMessageToProviderSession } from './registerKillSessionHandler-CjWfUfc3.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-GuXV-pxB.mjs';
|
|
7
|
+
import { B as BaseReasoningProcessor, b as bootstrapManagedProviderSession } from './BaseReasoningProcessor-DQkzwRuf.mjs';
|
|
8
8
|
import 'cross-spawn';
|
|
9
9
|
import '@agentclientprotocol/sdk';
|
|
10
10
|
import 'ps-list';
|
|
@@ -15,7 +15,7 @@ import 'node:child_process';
|
|
|
15
15
|
import 'node:readline';
|
|
16
16
|
import 'tweetnacl';
|
|
17
17
|
import 'axios';
|
|
18
|
-
import './persistence-
|
|
18
|
+
import './persistence-MSy70is3.mjs';
|
|
19
19
|
import 'open';
|
|
20
20
|
import 'chalk';
|
|
21
21
|
import 'fs';
|
|
@@ -430,6 +430,93 @@ class ConversationHistory extends ConversationHistory$1 {
|
|
|
430
430
|
}
|
|
431
431
|
}
|
|
432
432
|
|
|
433
|
+
const GEMINI_PERMISSION_MODES = [
|
|
434
|
+
"default",
|
|
435
|
+
"read-only",
|
|
436
|
+
"safe-yolo",
|
|
437
|
+
"yolo"
|
|
438
|
+
];
|
|
439
|
+
function isGeminiPermissionMode(value) {
|
|
440
|
+
return typeof value === "string" && GEMINI_PERMISSION_MODES.includes(value);
|
|
441
|
+
}
|
|
442
|
+
function hasMetaOverride(message, key) {
|
|
443
|
+
return Object.prototype.hasOwnProperty.call(message.meta ?? {}, key);
|
|
444
|
+
}
|
|
445
|
+
function resolveGeminiQueuedMessage(message, currentState) {
|
|
446
|
+
const previousState = { ...currentState };
|
|
447
|
+
const currentPermissionMode = isGeminiPermissionMode(currentState.permissionMode) ? currentState.permissionMode : void 0;
|
|
448
|
+
let permissionMode = currentPermissionMode;
|
|
449
|
+
let invalidPermissionMode = null;
|
|
450
|
+
if (hasMetaOverride(message, "permissionMode")) {
|
|
451
|
+
if (isGeminiPermissionMode(message.meta?.permissionMode)) {
|
|
452
|
+
permissionMode = message.meta.permissionMode;
|
|
453
|
+
} else if (message.meta?.permissionMode) {
|
|
454
|
+
invalidPermissionMode = String(message.meta.permissionMode);
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
const hasModelOverride = hasMetaOverride(message, "model");
|
|
458
|
+
const model = hasModelOverride ? message.meta?.model || void 0 : currentState.model;
|
|
459
|
+
const originalUserMessage = message.content.text;
|
|
460
|
+
let queuedText = originalUserMessage;
|
|
461
|
+
const isFirstMessage = currentState.isFirstMessage ?? true;
|
|
462
|
+
let nextIsFirstMessage = isFirstMessage;
|
|
463
|
+
if (isFirstMessage && message.meta?.appendSystemPrompt) {
|
|
464
|
+
queuedText = `${message.meta.appendSystemPrompt}
|
|
465
|
+
|
|
466
|
+
${originalUserMessage}`;
|
|
467
|
+
nextIsFirstMessage = false;
|
|
468
|
+
}
|
|
469
|
+
const nextState = {
|
|
470
|
+
permissionMode: permissionMode ?? "default",
|
|
471
|
+
model,
|
|
472
|
+
isFirstMessage: nextIsFirstMessage
|
|
473
|
+
};
|
|
474
|
+
return {
|
|
475
|
+
previousState,
|
|
476
|
+
nextState,
|
|
477
|
+
invalidPermissionMode,
|
|
478
|
+
hasModelOverride,
|
|
479
|
+
queuedMessage: {
|
|
480
|
+
text: queuedText,
|
|
481
|
+
mode: {
|
|
482
|
+
permissionMode: nextState.permissionMode ?? "default",
|
|
483
|
+
model,
|
|
484
|
+
originalUserMessage
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
function bindGeminiUserMessageQueue(opts) {
|
|
490
|
+
let currentState = { ...opts.initialState };
|
|
491
|
+
opts.session.onUserMessage((message) => {
|
|
492
|
+
const happyOrgResult = opts.happyOrg ? resolveHappyOrgQueuedTurn({
|
|
493
|
+
metadata: opts.happyOrg.getMetadata(),
|
|
494
|
+
message
|
|
495
|
+
}) : {
|
|
496
|
+
nextMetadata: null,
|
|
497
|
+
queuedTurn: null,
|
|
498
|
+
blocked: false,
|
|
499
|
+
statusMessage: void 0
|
|
500
|
+
};
|
|
501
|
+
if (opts.happyOrg && happyOrgResult.nextMetadata) {
|
|
502
|
+
opts.happyOrg.updateMetadata(() => happyOrgResult.nextMetadata);
|
|
503
|
+
}
|
|
504
|
+
if (happyOrgResult.blocked) {
|
|
505
|
+
if (happyOrgResult.statusMessage) {
|
|
506
|
+
opts.happyOrg?.emitStatusMessage(happyOrgResult.statusMessage);
|
|
507
|
+
}
|
|
508
|
+
logger.debugLargeJson("[gemini] User message blocked by Happy Org runtime:", message);
|
|
509
|
+
return;
|
|
510
|
+
}
|
|
511
|
+
const resolution = resolveGeminiQueuedMessage(message, currentState);
|
|
512
|
+
currentState = resolution.nextState;
|
|
513
|
+
resolution.queuedMessage.mode.happyOrg = happyOrgResult.queuedTurn;
|
|
514
|
+
opts.onResolvedMessage?.(resolution);
|
|
515
|
+
opts.messageQueue.push(resolution.queuedMessage.text, resolution.queuedMessage.mode);
|
|
516
|
+
logger.debugLargeJson("[gemini] User message queued:", message);
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
|
|
433
520
|
async function runGemini(opts) {
|
|
434
521
|
const sessionTag = randomUUID();
|
|
435
522
|
connectionState.setBackend("Gemini");
|
|
@@ -511,67 +598,21 @@ async function runGemini(opts) {
|
|
|
511
598
|
await syncControlledByUserState(session, false);
|
|
512
599
|
const messageQueue = new MessageQueue2((mode) => hashObject({
|
|
513
600
|
permissionMode: mode.permissionMode,
|
|
514
|
-
model: mode.model
|
|
601
|
+
model: mode.model,
|
|
602
|
+
happyOrg: mode.happyOrg ? {
|
|
603
|
+
taskId: mode.happyOrg.context.taskId,
|
|
604
|
+
organizationId: mode.happyOrg.context.organizationId,
|
|
605
|
+
memberAgentId: mode.happyOrg.context.memberAgentId,
|
|
606
|
+
supervisorAgentId: mode.happyOrg.context.supervisorAgentId,
|
|
607
|
+
reopenContext: mode.happyOrg.reopenContext ?? null
|
|
608
|
+
} : null
|
|
515
609
|
}));
|
|
516
610
|
const conversationHistory = new ConversationHistory({ maxMessages: 20, maxCharacters: 5e4 });
|
|
517
|
-
let currentPermissionMode = void 0;
|
|
518
|
-
let currentModel = void 0;
|
|
519
|
-
session.onUserMessage((message) => {
|
|
520
|
-
let messagePermissionMode = currentPermissionMode;
|
|
521
|
-
if (message.meta?.permissionMode) {
|
|
522
|
-
const validModes = ["default", "read-only", "safe-yolo", "yolo"];
|
|
523
|
-
if (validModes.includes(message.meta.permissionMode)) {
|
|
524
|
-
messagePermissionMode = message.meta.permissionMode;
|
|
525
|
-
currentPermissionMode = messagePermissionMode;
|
|
526
|
-
updatePermissionMode(messagePermissionMode);
|
|
527
|
-
logger.debug(`[Gemini] Permission mode updated from user message to: ${currentPermissionMode}`);
|
|
528
|
-
} else {
|
|
529
|
-
logger.debug(`[Gemini] Invalid permission mode received: ${message.meta.permissionMode}`);
|
|
530
|
-
}
|
|
531
|
-
} else {
|
|
532
|
-
logger.debug(`[Gemini] User message received with no permission mode override, using current: ${currentPermissionMode ?? "default (effective)"}`);
|
|
533
|
-
}
|
|
534
|
-
if (currentPermissionMode === void 0) {
|
|
535
|
-
currentPermissionMode = "default";
|
|
536
|
-
updatePermissionMode("default");
|
|
537
|
-
}
|
|
538
|
-
let messageModel = currentModel;
|
|
539
|
-
if (message.meta?.hasOwnProperty("model")) {
|
|
540
|
-
if (message.meta.model === null) {
|
|
541
|
-
messageModel = void 0;
|
|
542
|
-
currentModel = void 0;
|
|
543
|
-
} else if (message.meta.model) {
|
|
544
|
-
const previousModel = currentModel;
|
|
545
|
-
messageModel = message.meta.model;
|
|
546
|
-
currentModel = messageModel;
|
|
547
|
-
if (previousModel !== messageModel) {
|
|
548
|
-
updateDisplayedModel(messageModel, true);
|
|
549
|
-
messageBuffer.addMessage(`Model changed to: ${messageModel}`, "system");
|
|
550
|
-
logger.debug(`[Gemini] Model changed from ${previousModel} to ${messageModel}`);
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
}
|
|
554
|
-
const originalUserMessage = message.content.text;
|
|
555
|
-
let fullPrompt = originalUserMessage;
|
|
556
|
-
if (isFirstMessage && message.meta?.appendSystemPrompt) {
|
|
557
|
-
fullPrompt = message.meta.appendSystemPrompt + "\n\n" + originalUserMessage;
|
|
558
|
-
isFirstMessage = false;
|
|
559
|
-
}
|
|
560
|
-
const mode = {
|
|
561
|
-
permissionMode: messagePermissionMode || "default",
|
|
562
|
-
model: messageModel,
|
|
563
|
-
originalUserMessage
|
|
564
|
-
// Store original message separately
|
|
565
|
-
};
|
|
566
|
-
messageQueue.push(fullPrompt, mode);
|
|
567
|
-
conversationHistory.addUserMessage(originalUserMessage);
|
|
568
|
-
});
|
|
569
611
|
let thinking = false;
|
|
570
612
|
session.keepAlive(thinking, "remote");
|
|
571
613
|
const keepAliveInterval = setInterval(() => {
|
|
572
614
|
session.keepAlive(thinking, "remote");
|
|
573
615
|
}, 2e3);
|
|
574
|
-
let isFirstMessage = true;
|
|
575
616
|
const sendReady = () => {
|
|
576
617
|
session.sendSessionEvent({ type: "ready" });
|
|
577
618
|
try {
|
|
@@ -604,12 +645,18 @@ async function runGemini(opts) {
|
|
|
604
645
|
let shouldExit = false;
|
|
605
646
|
let runtimeHandle = null;
|
|
606
647
|
let unsubscribeRuntimeMessages = null;
|
|
648
|
+
let handleQueuedUserMessage = null;
|
|
649
|
+
let emitGeminiStatusMessage = null;
|
|
650
|
+
let turnAbortedSent = false;
|
|
607
651
|
async function handleAbort() {
|
|
608
652
|
logger.debug("[Gemini] Abort requested - stopping current task");
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
653
|
+
if (!turnAbortedSent) {
|
|
654
|
+
session.sendAgentMessage("gemini", {
|
|
655
|
+
type: "turn_aborted",
|
|
656
|
+
id: randomUUID()
|
|
657
|
+
});
|
|
658
|
+
turnAbortedSent = true;
|
|
659
|
+
}
|
|
613
660
|
reasoningProcessor.abort();
|
|
614
661
|
diffProcessor.reset();
|
|
615
662
|
try {
|
|
@@ -670,6 +717,10 @@ async function runGemini(opts) {
|
|
|
670
717
|
logger.debug(`[gemini] Model unchanged, skipping update message`);
|
|
671
718
|
}
|
|
672
719
|
};
|
|
720
|
+
emitGeminiStatusMessage = (message) => {
|
|
721
|
+
messageBuffer.addMessage(message, "status");
|
|
722
|
+
session.sendSessionEvent({ type: "message", message });
|
|
723
|
+
};
|
|
673
724
|
if (hasTTY) {
|
|
674
725
|
console.clear();
|
|
675
726
|
const DisplayComponent = () => {
|
|
@@ -710,6 +761,41 @@ async function runGemini(opts) {
|
|
|
710
761
|
const updatePermissionMode = (mode) => {
|
|
711
762
|
permissionHandler.setPermissionMode(mode);
|
|
712
763
|
};
|
|
764
|
+
handleQueuedUserMessage = ({ previousState, nextState, invalidPermissionMode, hasModelOverride }) => {
|
|
765
|
+
if (invalidPermissionMode) {
|
|
766
|
+
logger.debug(`[Gemini] Invalid permission mode received: ${invalidPermissionMode}`);
|
|
767
|
+
} else if (nextState.permissionMode) {
|
|
768
|
+
logger.debug(`[Gemini] Permission mode resolved to: ${nextState.permissionMode}`);
|
|
769
|
+
}
|
|
770
|
+
updatePermissionMode(nextState.permissionMode ?? "default");
|
|
771
|
+
if (hasModelOverride && nextState.model && previousState.model !== nextState.model) {
|
|
772
|
+
updateDisplayedModel(nextState.model, true);
|
|
773
|
+
messageBuffer.addMessage(`Model changed to: ${nextState.model}`, "system");
|
|
774
|
+
logger.debug(`[Gemini] Model changed from ${previousState.model} to ${nextState.model}`);
|
|
775
|
+
}
|
|
776
|
+
};
|
|
777
|
+
bindGeminiUserMessageQueue({
|
|
778
|
+
session,
|
|
779
|
+
messageQueue,
|
|
780
|
+
initialState: {},
|
|
781
|
+
happyOrg: {
|
|
782
|
+
getMetadata: () => session.getMetadataSnapshot?.() ?? metadata,
|
|
783
|
+
updateMetadata: (handler) => session.updateMetadata(handler),
|
|
784
|
+
emitStatusMessage: (message) => {
|
|
785
|
+
emitGeminiStatusMessage?.(message);
|
|
786
|
+
}
|
|
787
|
+
},
|
|
788
|
+
onResolvedMessage: (resolution) => {
|
|
789
|
+
handleQueuedUserMessage?.(resolution);
|
|
790
|
+
}
|
|
791
|
+
});
|
|
792
|
+
const emitTurnReport = (report) => {
|
|
793
|
+
session.sendAgentMessage("gemini", {
|
|
794
|
+
type: "turn-report",
|
|
795
|
+
id: randomUUID(),
|
|
796
|
+
report
|
|
797
|
+
});
|
|
798
|
+
};
|
|
713
799
|
let accumulatedResponse = "";
|
|
714
800
|
let isResponseInProgress = false;
|
|
715
801
|
let hadToolCallInTurn = false;
|
|
@@ -757,10 +843,13 @@ async function runGemini(opts) {
|
|
|
757
843
|
logger.debug(`[gemini] Status changed: ${msg.status}${statusDetail ? ` - ${statusDetail}` : ""}`);
|
|
758
844
|
if (msg.status === "error") {
|
|
759
845
|
logger.debug(`[gemini] \u26A0\uFE0F Error status received: ${statusDetail || "Unknown error"}`);
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
846
|
+
if (!turnAbortedSent) {
|
|
847
|
+
session.sendAgentMessage("gemini", {
|
|
848
|
+
type: "turn_aborted",
|
|
849
|
+
id: randomUUID()
|
|
850
|
+
});
|
|
851
|
+
turnAbortedSent = true;
|
|
852
|
+
}
|
|
764
853
|
}
|
|
765
854
|
if (msg.status === "running") {
|
|
766
855
|
thinking = true;
|
|
@@ -985,6 +1074,7 @@ Guide: https://goo.gle/gemini-cli-auth-docs#workspace-gca`;
|
|
|
985
1074
|
const userMessageToShow = message.mode?.originalUserMessage || message.message;
|
|
986
1075
|
messageBuffer.addMessage(userMessageToShow, "user");
|
|
987
1076
|
isProcessingMessage = true;
|
|
1077
|
+
let turnStatus = "task_complete";
|
|
988
1078
|
try {
|
|
989
1079
|
let activeHandle = runtimeHandle;
|
|
990
1080
|
if (!activeHandle) {
|
|
@@ -1005,12 +1095,17 @@ Guide: https://goo.gle/gemini-cli-auth-docs#workspace-gca`;
|
|
|
1005
1095
|
isResponseInProgress = false;
|
|
1006
1096
|
hadToolCallInTurn = false;
|
|
1007
1097
|
taskStartedSent = false;
|
|
1098
|
+
turnAbortedSent = false;
|
|
1008
1099
|
let promptToSend = message.message;
|
|
1009
1100
|
if (injectHistoryContext && conversationHistory.hasHistory()) {
|
|
1010
1101
|
const historyContext = conversationHistory.getContextForNewSession();
|
|
1011
1102
|
promptToSend = historyContext + promptToSend;
|
|
1012
1103
|
logger.debug(`[gemini] Injected conversation history context (${historyContext.length} chars)`);
|
|
1013
1104
|
}
|
|
1105
|
+
if (message.mode.happyOrg) {
|
|
1106
|
+
promptToSend = buildHappyOrgTurnPrompt(promptToSend, message.mode.happyOrg);
|
|
1107
|
+
}
|
|
1108
|
+
conversationHistory.addUserMessage(userMessageToShow);
|
|
1014
1109
|
logger.debug(`[gemini] Sending prompt to Gemini (length: ${promptToSend.length}): ${promptToSend.substring(0, 100)}...`);
|
|
1015
1110
|
logger.debug(`[gemini] Full prompt: ${promptToSend}`);
|
|
1016
1111
|
const MAX_RETRIES = 3;
|
|
@@ -1020,7 +1115,7 @@ Guide: https://goo.gle/gemini-cli-auth-docs#workspace-gca`;
|
|
|
1020
1115
|
try {
|
|
1021
1116
|
await activeHandle.sendPrompt(promptToSend);
|
|
1022
1117
|
logger.debug("[gemini] Prompt sent successfully");
|
|
1023
|
-
await waitForResponseCompleteWithAbort(activeHandle.backend, abortController.signal,
|
|
1118
|
+
await waitForResponseCompleteWithAbort(activeHandle.backend, abortController.signal, 10 * 6e4);
|
|
1024
1119
|
logger.debug("[gemini] Response complete");
|
|
1025
1120
|
break;
|
|
1026
1121
|
} catch (promptError) {
|
|
@@ -1059,6 +1154,14 @@ Guide: https://goo.gle/gemini-cli-auth-docs#workspace-gca`;
|
|
|
1059
1154
|
} catch (error) {
|
|
1060
1155
|
logger.debug("[gemini] Error in gemini session:", error);
|
|
1061
1156
|
const isAbortError = error instanceof Error && error.name === "AbortError";
|
|
1157
|
+
turnStatus = "turn_aborted";
|
|
1158
|
+
if (!turnAbortedSent) {
|
|
1159
|
+
session.sendAgentMessage("gemini", {
|
|
1160
|
+
type: "turn_aborted",
|
|
1161
|
+
id: randomUUID()
|
|
1162
|
+
});
|
|
1163
|
+
turnAbortedSent = true;
|
|
1164
|
+
}
|
|
1062
1165
|
if (isAbortError) {
|
|
1063
1166
|
messageBuffer.addMessage("Aborted by user", "status");
|
|
1064
1167
|
session.sendSessionEvent({ type: "message", message: "Aborted by user" });
|
|
@@ -1071,8 +1174,8 @@ Guide: https://goo.gle/gemini-cli-auth-docs#workspace-gca`;
|
|
|
1071
1174
|
const errorMessage = errObj.message || errObj.error?.message || "";
|
|
1072
1175
|
const errorString = String(error);
|
|
1073
1176
|
if (errorCode === 404 || errorDetails.includes("notFound") || errorDetails.includes("404") || errorMessage.includes("not found") || errorMessage.includes("404")) {
|
|
1074
|
-
const
|
|
1075
|
-
errorMsg = `Model "${
|
|
1177
|
+
const currentModel = displayedModel || "gemini-2.5-pro";
|
|
1178
|
+
errorMsg = `Model "${currentModel}" not found. Available models: gemini-2.5-pro, gemini-2.5-flash, gemini-2.5-flash-lite`;
|
|
1076
1179
|
} else if (errorCode === -32603 || errorDetails.includes("empty response") || errorDetails.includes("Model stream ended")) {
|
|
1077
1180
|
errorMsg = "Gemini API returned empty response after retries. This is a temporary issue - please try again.";
|
|
1078
1181
|
} else if (errorCode === 429 || errorDetails.includes("429") || errorMessage.includes("429") || errorString.includes("429") || errorDetails.includes("rateLimitExceeded") || errorDetails.includes("RESOURCE_EXHAUSTED") || errorMessage.includes("Rate limit exceeded") || errorMessage.includes("Resource exhausted") || errorString.includes("rateLimitExceeded") || errorString.includes("RESOURCE_EXHAUSTED")) {
|
|
@@ -1108,6 +1211,22 @@ Guide: https://goo.gle/gemini-cli-auth-docs#workspace-gca`;
|
|
|
1108
1211
|
permissionHandler.reset();
|
|
1109
1212
|
reasoningProcessor.abort();
|
|
1110
1213
|
diffProcessor.reset();
|
|
1214
|
+
const finalizedTurn = finalizeHappyOrgTurn({
|
|
1215
|
+
metadata: session.getMetadataSnapshot?.() ?? null,
|
|
1216
|
+
queuedTurn: message.mode.happyOrg,
|
|
1217
|
+
responseText: accumulatedResponse,
|
|
1218
|
+
turnStatus
|
|
1219
|
+
});
|
|
1220
|
+
if (finalizedTurn.nextMetadata && typeof session.updateMetadata === "function") {
|
|
1221
|
+
session.updateMetadata(() => finalizedTurn.nextMetadata);
|
|
1222
|
+
}
|
|
1223
|
+
if (finalizedTurn.report) {
|
|
1224
|
+
emitTurnReport(finalizedTurn.report);
|
|
1225
|
+
}
|
|
1226
|
+
if (finalizedTurn.terminateMessage) {
|
|
1227
|
+
emitGeminiStatusMessage?.(finalizedTurn.terminateMessage);
|
|
1228
|
+
}
|
|
1229
|
+
accumulatedResponse = finalizedTurn.cleanedText;
|
|
1111
1230
|
if (accumulatedResponse.trim()) {
|
|
1112
1231
|
const { text: messageText, options } = parseOptionsFromText(accumulatedResponse);
|
|
1113
1232
|
conversationHistory.addAssistantMessage(messageText);
|
|
@@ -1151,7 +1270,9 @@ Guide: https://goo.gle/gemini-cli-auth-docs#workspace-gca`;
|
|
|
1151
1270
|
reconnectionHandle.cancel();
|
|
1152
1271
|
}
|
|
1153
1272
|
try {
|
|
1154
|
-
await closeProviderSession(session
|
|
1273
|
+
await closeProviderSession(session, {
|
|
1274
|
+
archiveOnClose: true
|
|
1275
|
+
});
|
|
1155
1276
|
} catch (e) {
|
|
1156
1277
|
logger.debug("[gemini]: Error while closing session", e);
|
|
1157
1278
|
}
|