very-happy-cli 0.2.128 → 0.2.129
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/dist/{AcpBackend-D7987ody.mjs → AcpBackend-MAU4POiE.mjs} +16 -4
- package/dist/{AcpBackend-BYU6J2n0.cjs → AcpBackend-kU2VqiYx.cjs} +16 -4
- package/dist/{AcpSessionManager-artXJgqb.cjs → AcpSessionManager-BWasT5jq.cjs} +1 -1
- package/dist/{AcpSessionManager-BwrjVZyn.mjs → AcpSessionManager-uSGDDRqF.mjs} +1 -1
- package/dist/{agentGuidance-B1xYgHx6.cjs → agentGuidance-B1PsijGg.cjs} +1 -1
- package/dist/{agentGuidance-BPGPaNlo.mjs → agentGuidance-DlZ5s0Om.mjs} +1 -1
- package/dist/codex/happyMcpStdioBridge.cjs +2 -2
- package/dist/codex/happyMcpStdioBridge.mjs +2 -2
- package/dist/{config-Dmkzs3o4.cjs → config-DswZvA8V.cjs} +4 -4
- package/dist/{config-DSBE0Az0.mjs → config-_DKtp9qs.mjs} +4 -4
- package/dist/{index-35FahgEU.mjs → index-1QwKRLYG.mjs} +4 -4
- package/dist/{index-D_YVlpsW.cjs → index-BdZ7Dlg0.cjs} +184 -86
- package/dist/{index-m0Dnccc_.mjs → index-FMMrmSa2.mjs} +115 -32
- package/dist/{index-vyTJsT_R.cjs → index-dqKLs4dZ.cjs} +114 -31
- package/dist/{index-CJmXLSQc.cjs → index-lwOIU7K9.cjs} +4 -4
- package/dist/{index-CfM6ewd8.mjs → index-tr2Fqhby.mjs} +177 -83
- package/dist/index.cjs +4 -4
- package/dist/index.mjs +4 -4
- package/dist/{installTerminalHooks-ClrFe2fA.mjs → installTerminalHooks-B3a0ugvz.mjs} +4 -4
- package/dist/{installTerminalHooks-C1zwiJJ2.cjs → installTerminalHooks-CV2LAKXO.cjs} +4 -4
- package/dist/lib.cjs +2 -2
- package/dist/lib.d.cts +5 -0
- package/dist/lib.d.mts +5 -0
- package/dist/lib.mjs +2 -2
- package/dist/{limits-CrwtFbi8.cjs → limits-B5wJ5Slz.cjs} +7 -7
- package/dist/{limits-BNTLh2lw.mjs → limits-C41sn_OJ.mjs} +7 -7
- package/dist/{mcp-Bc_mmJt8.cjs → mcp-B7lwVQT8.cjs} +4 -4
- package/dist/{mcp-BsohER5A.mjs → mcp-BHNVwrwS.mjs} +4 -4
- package/dist/{runGemini-B9S85Vms.mjs → runGemini-FNZrH8yX.mjs} +6 -6
- package/dist/{runGemini-B2GesRWm.cjs → runGemini-gbflWQ3_.cjs} +6 -6
- package/dist/{runOpenClaw-Byhq-B1y.mjs → runOpenClaw-3EF_Rqv_.mjs} +5 -5
- package/dist/{runOpenClaw-DCK-R8qe.cjs → runOpenClaw-CmhYI7OB.cjs} +5 -5
- package/dist/{send-DQS1zNWp.mjs → send-DV7IeBAv.mjs} +4 -4
- package/dist/{send-CPdT1nOg.cjs → send-DqedYZtc.cjs} +4 -4
- package/dist/{sessions-DC0IKaD9.cjs → sessions-Bz243hZ9.cjs} +4 -4
- package/dist/{sessions-DIOdWnPe.mjs → sessions-ieB0bLb5.mjs} +4 -4
- package/dist/{spawn-DrnCW2QK.cjs → spawn-BXwwueEs.cjs} +4 -4
- package/dist/{spawn-DV4pIAHZ.mjs → spawn-CcqzmjhT.mjs} +4 -4
- package/dist/{teams-CwXEJs9I.cjs → teams-BtI6h4Dw.cjs} +4 -4
- package/dist/{teams-DlTHOiCk.mjs → teams-Bx79Wr9-.mjs} +4 -4
- package/dist/{todo-DrME15xq.cjs → todo-B-Kj9lXl.cjs} +3 -3
- package/dist/{todo-BwXURAbQ.mjs → todo-CGRuBaiH.mjs} +3 -3
- package/dist/{types-DfatCoQL.cjs → types-Ba9u0uZL.cjs} +19 -5
- package/dist/{types-CFs8FmiY.mjs → types-BvYEAHds.mjs} +19 -5
- package/package.json +7 -7
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { D as DefaultTransport, A as AcpBackend } from './AcpBackend-
|
|
2
|
-
export { a as DEFAULT_IDLE_TIMEOUT_MS, b as DEFAULT_TOOL_CALL_TIMEOUT_MS, e as extractErrorDetail, f as formatDuration, c as formatDurationMinutes, h as handleAgentMessageChunk, d as handleAgentThoughtChunk, g as handleLegacyMessageChunk, i as handlePlanUpdate, j as handleThinkingUpdate, k as handleToolCall, l as handleToolCallUpdate, p as parseArgsFromContent } from './AcpBackend-
|
|
3
|
-
import { c as configuration, g as readSettings, i as encodeBase64, l as logger } from './limits-
|
|
4
|
-
import { A as AcpSessionManager } from './AcpSessionManager-
|
|
5
|
-
import {
|
|
1
|
+
import { D as DefaultTransport, A as AcpBackend } from './AcpBackend-MAU4POiE.mjs';
|
|
2
|
+
export { a as DEFAULT_IDLE_TIMEOUT_MS, b as DEFAULT_TOOL_CALL_TIMEOUT_MS, e as extractErrorDetail, f as formatDuration, c as formatDurationMinutes, h as handleAgentMessageChunk, d as handleAgentThoughtChunk, g as handleLegacyMessageChunk, i as handlePlanUpdate, j as handleThinkingUpdate, k as handleToolCall, l as handleToolCallUpdate, p as parseArgsFromContent } from './AcpBackend-MAU4POiE.mjs';
|
|
3
|
+
import { c as configuration, g as readSettings, i as encodeBase64, l as logger } from './limits-C41sn_OJ.mjs';
|
|
4
|
+
import { A as AcpSessionManager } from './AcpSessionManager-uSGDDRqF.mjs';
|
|
5
|
+
import { f as connectionState, A as ApiClient, p as projectPath, g as BUILTIN_TODO_DISCOVERY } from './types-BvYEAHds.mjs';
|
|
6
|
+
import { P as PI_TEAMS_EXTENSION, n as initialMachineMetadata, o as createSessionMetadata, u as setupOfflineReconnection, v as notifyDaemonSessionStarted, z as StreamRelay, x as MessageQueue2, B as hashObject, C as startHappyServer, E as registerAgentAttachmentDownloads, F as TitleGenerator, y as registerKillSessionHandler, H as CLAUDE_ATTACHMENT_KINDS, I as stageClaudeAttachments, J as appendStagedAttachmentsToPrompt, K as BasePermissionHandler, L as writeSessionModeFile, N as normalizeAcpPermissionMode, O as removeSessionModeFile } from './index-tr2Fqhby.mjs';
|
|
6
7
|
import { mkdir, chmod, writeFile, rename } from 'node:fs/promises';
|
|
7
8
|
import { randomUUID } from 'node:crypto';
|
|
8
9
|
import { join } from 'node:path';
|
|
9
|
-
import { P as PI_TEAMS_EXTENSION, n as initialMachineMetadata, o as createSessionMetadata, u as setupOfflineReconnection, v as notifyDaemonSessionStarted, z as StreamRelay, x as MessageQueue2, B as hashObject, C as startHappyServer, E as TitleGenerator, y as registerKillSessionHandler, F as BasePermissionHandler, H as writeSessionModeFile, I as normalizeAcpPermissionMode, J as removeSessionModeFile } from './index-CfM6ewd8.mjs';
|
|
10
10
|
import 'node:child_process';
|
|
11
11
|
import '@agentclientprotocol/sdk';
|
|
12
12
|
import 'node:fs';
|
|
@@ -32,7 +32,7 @@ import 'fs';
|
|
|
32
32
|
import 'node:readline';
|
|
33
33
|
import '@anthropic-ai/sandbox-runtime';
|
|
34
34
|
import 'expo-server-sdk';
|
|
35
|
-
import './agentGuidance-
|
|
35
|
+
import './agentGuidance-DlZ5s0Om.mjs';
|
|
36
36
|
import 'ink';
|
|
37
37
|
import 'react';
|
|
38
38
|
import '@anthropic-ai/claude-agent-sdk';
|
|
@@ -518,6 +518,7 @@ function extractConfigSelector(configOptions, category) {
|
|
|
518
518
|
}
|
|
519
519
|
const id = normalizeComparable(option.id);
|
|
520
520
|
const name = normalizeComparable(option.name);
|
|
521
|
+
if (category === "thought_level") return id.includes("thinking") || id.includes("thought") || name.includes("thinking");
|
|
521
522
|
if (category === "model") {
|
|
522
523
|
return id.includes("model") || name.includes("model");
|
|
523
524
|
}
|
|
@@ -632,6 +633,7 @@ async function runAcp(opts) {
|
|
|
632
633
|
startedBy: opts.startedBy,
|
|
633
634
|
sandbox: settings.sandboxConfig
|
|
634
635
|
});
|
|
636
|
+
metadata.attachmentKinds = [];
|
|
635
637
|
const response = await api.getOrCreateSession({ tag: sessionTag, metadata, state });
|
|
636
638
|
if (response) {
|
|
637
639
|
logAcp("muted", `Happy Session ID: ${response.id}`);
|
|
@@ -677,6 +679,8 @@ async function runAcp(opts) {
|
|
|
677
679
|
let currentModel;
|
|
678
680
|
let modeSelector = null;
|
|
679
681
|
let modelSelector = null;
|
|
682
|
+
let thoughtSelector = null;
|
|
683
|
+
let currentEffort;
|
|
680
684
|
let legacyModes = null;
|
|
681
685
|
let legacyModels = null;
|
|
682
686
|
let sawSlashCommands = false;
|
|
@@ -824,35 +828,78 @@ async function runAcp(opts) {
|
|
|
824
828
|
};
|
|
825
829
|
}
|
|
826
830
|
};
|
|
831
|
+
const switchEffortIfRequested = async (requested, modelChanged) => {
|
|
832
|
+
const discardStaleEffort = () => {
|
|
833
|
+
if (currentEffort === requested) currentEffort = null;
|
|
834
|
+
session.sendSessionEvent({ type: "message", message: `The new model does not support thinking level "${requested}"; using its current thinking level.` });
|
|
835
|
+
};
|
|
836
|
+
if (thoughtSelector) {
|
|
837
|
+
const resolved = thoughtSelector.options.find((option) => option.code === requested)?.code;
|
|
838
|
+
if (!resolved) {
|
|
839
|
+
if (modelChanged) {
|
|
840
|
+
discardStaleEffort();
|
|
841
|
+
return;
|
|
842
|
+
}
|
|
843
|
+
throw new Error(`Unsupported thinking level: ${requested}`);
|
|
844
|
+
}
|
|
845
|
+
if (resolved === thoughtSelector.currentCode) return;
|
|
846
|
+
if (!await backend.setSessionConfigOption(thoughtSelector.configId, resolved)) {
|
|
847
|
+
throw new Error(`Failed to switch thinking level to ${resolved}`);
|
|
848
|
+
}
|
|
849
|
+
thoughtSelector.currentCode = resolved;
|
|
850
|
+
session.updateMetadata((metadata2) => ({ ...metadata2, currentThoughtLevelCode: resolved }));
|
|
851
|
+
return;
|
|
852
|
+
}
|
|
853
|
+
if (permissionModeIsFileBacked() && legacyModes) {
|
|
854
|
+
const resolved = legacyModes.availableModes.find((mode) => mode.id === requested)?.id;
|
|
855
|
+
if (!resolved) {
|
|
856
|
+
if (modelChanged) {
|
|
857
|
+
discardStaleEffort();
|
|
858
|
+
return;
|
|
859
|
+
}
|
|
860
|
+
throw new Error(`Unsupported thinking level: ${requested}`);
|
|
861
|
+
}
|
|
862
|
+
if (resolved === legacyModes.currentModeId) return;
|
|
863
|
+
if (!await backend.setSessionMode(resolved)) throw new Error(`Failed to switch thinking level to ${resolved}`);
|
|
864
|
+
legacyModes = { ...legacyModes, currentModeId: resolved };
|
|
865
|
+
session.updateMetadata((metadata2) => ({ ...metadata2, currentOperatingModeCode: resolved, currentThoughtLevelCode: resolved }));
|
|
866
|
+
return;
|
|
867
|
+
}
|
|
868
|
+
if (modelChanged) {
|
|
869
|
+
discardStaleEffort();
|
|
870
|
+
return;
|
|
871
|
+
}
|
|
872
|
+
throw new Error(`This agent does not advertise thinking levels`);
|
|
873
|
+
};
|
|
827
874
|
const switchModelIfRequested = async (requestedModel) => {
|
|
828
875
|
if (!requestedModel) {
|
|
829
|
-
return;
|
|
876
|
+
return false;
|
|
830
877
|
}
|
|
831
878
|
if (modelSelector) {
|
|
832
879
|
const resolved = resolveRequestedCode(modelSelector.options, requestedModel);
|
|
833
880
|
if (!resolved) {
|
|
834
881
|
logger.debug(`[${opts.agentName}] Ignoring unknown ACP model request: ${requestedModel}`);
|
|
835
|
-
return;
|
|
882
|
+
return false;
|
|
836
883
|
}
|
|
837
884
|
if (resolved === modelSelector.currentCode) {
|
|
838
|
-
return;
|
|
885
|
+
return false;
|
|
839
886
|
}
|
|
840
887
|
const switched2 = await backend.setSessionConfigOption(modelSelector.configId, resolved);
|
|
841
888
|
if (switched2) {
|
|
842
889
|
modelSelector.currentCode = resolved;
|
|
843
|
-
return;
|
|
890
|
+
return true;
|
|
844
891
|
}
|
|
845
892
|
}
|
|
846
893
|
if (!legacyModels) {
|
|
847
|
-
return;
|
|
894
|
+
return false;
|
|
848
895
|
}
|
|
849
896
|
const resolvedLegacyModel = resolveRequestedLegacyModelCode(legacyModels, requestedModel);
|
|
850
897
|
if (!resolvedLegacyModel) {
|
|
851
898
|
logger.debug(`[${opts.agentName}] Ignoring unknown ACP legacy model request: ${requestedModel}`);
|
|
852
|
-
return;
|
|
899
|
+
return false;
|
|
853
900
|
}
|
|
854
901
|
if (resolvedLegacyModel === legacyModels.currentModelId) {
|
|
855
|
-
return;
|
|
902
|
+
return false;
|
|
856
903
|
}
|
|
857
904
|
const switched = await backend.setSessionModel(resolvedLegacyModel);
|
|
858
905
|
if (switched) {
|
|
@@ -860,7 +907,13 @@ async function runAcp(opts) {
|
|
|
860
907
|
...legacyModels,
|
|
861
908
|
currentModelId: resolvedLegacyModel
|
|
862
909
|
};
|
|
910
|
+
return true;
|
|
863
911
|
}
|
|
912
|
+
return false;
|
|
913
|
+
};
|
|
914
|
+
const isCurrentRequestedModel = (requested) => {
|
|
915
|
+
if (modelSelector) return resolveRequestedCode(modelSelector.options, requested) === modelSelector.currentCode;
|
|
916
|
+
return !!legacyModels && resolveRequestedLegacyModelCode(legacyModels, requested) === legacyModels.currentModelId;
|
|
864
917
|
};
|
|
865
918
|
const onBackendMessage = (msg) => {
|
|
866
919
|
if (verbose) {
|
|
@@ -897,6 +950,7 @@ async function runAcp(opts) {
|
|
|
897
950
|
}
|
|
898
951
|
modeSelector = extractConfigSelector(configOptions, "mode");
|
|
899
952
|
modelSelector = extractConfigSelector(configOptions, "model");
|
|
953
|
+
thoughtSelector = extractConfigSelector(configOptions, "thought_level");
|
|
900
954
|
if (verbose) {
|
|
901
955
|
if (modeSelector) {
|
|
902
956
|
sawModes = true;
|
|
@@ -997,22 +1051,35 @@ async function runAcp(opts) {
|
|
|
997
1051
|
};
|
|
998
1052
|
backend.onMessage(onBackendMessage);
|
|
999
1053
|
const titleGenerator = new TitleGenerator(session);
|
|
1054
|
+
registerAgentAttachmentDownloads(session);
|
|
1055
|
+
let userMessageDelivery = Promise.resolve();
|
|
1000
1056
|
session.onUserMessage((message) => {
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1057
|
+
const downloads = session.drainAttachmentsForUserMessage();
|
|
1058
|
+
userMessageDelivery = userMessageDelivery.then(async () => {
|
|
1059
|
+
const attachments = await downloads;
|
|
1060
|
+
if (!message.content.text && !attachments?.length) {
|
|
1061
|
+
return;
|
|
1062
|
+
}
|
|
1063
|
+
titleGenerator.maybeGenerate(message.content.text);
|
|
1064
|
+
if (typeof message.meta?.permissionMode === "string") {
|
|
1065
|
+
currentPermissionMode = message.meta.permissionMode;
|
|
1066
|
+
logger.debug(`[${opts.agentName}] Requested ACP permission mode: ${currentPermissionMode}`);
|
|
1067
|
+
}
|
|
1068
|
+
if (message.meta && Object.prototype.hasOwnProperty.call(message.meta, "model")) {
|
|
1069
|
+
currentModel = message.meta.model ?? null;
|
|
1070
|
+
logger.debug(`[${opts.agentName}] Requested ACP model: ${currentModel ?? "null"}`);
|
|
1071
|
+
}
|
|
1072
|
+
if (message.meta && Object.prototype.hasOwnProperty.call(message.meta, "effort")) {
|
|
1073
|
+
currentEffort = message.meta.effort ?? null;
|
|
1074
|
+
}
|
|
1075
|
+
messageQueue.push(message.content.text, {
|
|
1076
|
+
permissionMode: currentPermissionMode,
|
|
1077
|
+
model: currentModel,
|
|
1078
|
+
effort: currentEffort
|
|
1079
|
+
}, attachments, message.localKey);
|
|
1080
|
+
}).catch(() => {
|
|
1081
|
+
logger.warn("[ACP] Failed to prepare user attachments");
|
|
1082
|
+
session.sendSessionEvent({ type: "message", message: "Could not prepare this message. Please send it again." });
|
|
1016
1083
|
});
|
|
1017
1084
|
});
|
|
1018
1085
|
session.keepAlive(thinking, "remote");
|
|
@@ -1058,6 +1125,15 @@ async function runAcp(opts) {
|
|
|
1058
1125
|
try {
|
|
1059
1126
|
const started = await backend.startSession();
|
|
1060
1127
|
acpSessionId = started.sessionId;
|
|
1128
|
+
if (opts.model) {
|
|
1129
|
+
await switchModelIfRequested(opts.model);
|
|
1130
|
+
const applied = isCurrentRequestedModel(opts.model);
|
|
1131
|
+
if (!applied) session.sendSessionEvent({ type: "message", message: "The saved model is unavailable for this agent; using its current model." });
|
|
1132
|
+
}
|
|
1133
|
+
session.updateMetadata((current) => ({
|
|
1134
|
+
...current,
|
|
1135
|
+
attachmentKinds: opts.agentName === "pi" && backend.supportsImageAttachments ? [...CLAUDE_ATTACHMENT_KINDS] : []
|
|
1136
|
+
}));
|
|
1061
1137
|
if (permissionModeIsFileBacked()) {
|
|
1062
1138
|
fileBackedModeActive = true;
|
|
1063
1139
|
publishFileBackedPermissionMode(initialPermissionMode);
|
|
@@ -1097,13 +1173,19 @@ async function runAcp(opts) {
|
|
|
1097
1173
|
if (typeof batch.mode.permissionMode === "string" && batch.mode.permissionMode.length > 0) {
|
|
1098
1174
|
await switchPermissionModeIfRequested(batch.mode.permissionMode);
|
|
1099
1175
|
}
|
|
1100
|
-
|
|
1101
|
-
|
|
1176
|
+
const modelChanged = typeof batch.mode.model === "string" && batch.mode.model.length > 0 ? await switchModelIfRequested(batch.mode.model) : false;
|
|
1177
|
+
if (typeof batch.mode.effort === "string") {
|
|
1178
|
+
await switchEffortIfRequested(batch.mode.effort, modelChanged);
|
|
1102
1179
|
}
|
|
1103
1180
|
const prompt = todoDiscoverySent ? batch.message : `${batch.message}
|
|
1104
1181
|
|
|
1105
1182
|
${BUILTIN_TODO_DISCOVERY}`;
|
|
1106
|
-
|
|
1183
|
+
const attachments = batch.attachments ?? [];
|
|
1184
|
+
const staged = attachments.length ? await stageClaudeAttachments(attachments, {
|
|
1185
|
+
happyHomeDir: configuration.happyHomeDir,
|
|
1186
|
+
sessionId: session.sessionId
|
|
1187
|
+
}) : [];
|
|
1188
|
+
await backend.sendPrompt(acpSessionId, appendStagedAttachmentsToPrompt(prompt, staged), attachments);
|
|
1107
1189
|
todoDiscoverySent = true;
|
|
1108
1190
|
await turnEnded;
|
|
1109
1191
|
sendEnvelopes(sessionManager.endTurn("completed"));
|
|
@@ -1114,6 +1196,7 @@ ${BUILTIN_TODO_DISCOVERY}`;
|
|
|
1114
1196
|
logAcp("muted", `Outgoing prompt completion from ${opts.agentName}`);
|
|
1115
1197
|
}
|
|
1116
1198
|
} catch (error) {
|
|
1199
|
+
session.sendSessionEvent({ type: "message", message: "The agent could not process this message or its attachments. Please check the agent and try again." });
|
|
1117
1200
|
sendEnvelopes(sessionManager.endTurn("failed"));
|
|
1118
1201
|
streamRelay.endTurn();
|
|
1119
1202
|
setThinking(false);
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var AcpBackend = require('./AcpBackend-
|
|
4
|
-
var persistence = require('./limits-
|
|
5
|
-
var AcpSessionManager = require('./AcpSessionManager-
|
|
6
|
-
var api = require('./types-
|
|
3
|
+
var AcpBackend = require('./AcpBackend-kU2VqiYx.cjs');
|
|
4
|
+
var persistence = require('./limits-B5wJ5Slz.cjs');
|
|
5
|
+
var AcpSessionManager = require('./AcpSessionManager-BWasT5jq.cjs');
|
|
6
|
+
var api = require('./types-Ba9u0uZL.cjs');
|
|
7
|
+
var index = require('./index-BdZ7Dlg0.cjs');
|
|
7
8
|
var promises = require('node:fs/promises');
|
|
8
9
|
var node_crypto = require('node:crypto');
|
|
9
10
|
var path = require('node:path');
|
|
10
|
-
var index = require('./index-D_YVlpsW.cjs');
|
|
11
11
|
require('node:child_process');
|
|
12
12
|
require('@agentclientprotocol/sdk');
|
|
13
13
|
require('node:fs');
|
|
@@ -33,7 +33,7 @@ require('fs');
|
|
|
33
33
|
require('node:readline');
|
|
34
34
|
require('@anthropic-ai/sandbox-runtime');
|
|
35
35
|
require('expo-server-sdk');
|
|
36
|
-
require('./agentGuidance-
|
|
36
|
+
require('./agentGuidance-B1PsijGg.cjs');
|
|
37
37
|
require('ink');
|
|
38
38
|
require('react');
|
|
39
39
|
require('@anthropic-ai/claude-agent-sdk');
|
|
@@ -519,6 +519,7 @@ function extractConfigSelector(configOptions, category) {
|
|
|
519
519
|
}
|
|
520
520
|
const id = normalizeComparable(option.id);
|
|
521
521
|
const name = normalizeComparable(option.name);
|
|
522
|
+
if (category === "thought_level") return id.includes("thinking") || id.includes("thought") || name.includes("thinking");
|
|
522
523
|
if (category === "model") {
|
|
523
524
|
return id.includes("model") || name.includes("model");
|
|
524
525
|
}
|
|
@@ -633,6 +634,7 @@ async function runAcp(opts) {
|
|
|
633
634
|
startedBy: opts.startedBy,
|
|
634
635
|
sandbox: settings.sandboxConfig
|
|
635
636
|
});
|
|
637
|
+
metadata.attachmentKinds = [];
|
|
636
638
|
const response = await api$1.getOrCreateSession({ tag: sessionTag, metadata, state });
|
|
637
639
|
if (response) {
|
|
638
640
|
logAcp("muted", `Happy Session ID: ${response.id}`);
|
|
@@ -678,6 +680,8 @@ async function runAcp(opts) {
|
|
|
678
680
|
let currentModel;
|
|
679
681
|
let modeSelector = null;
|
|
680
682
|
let modelSelector = null;
|
|
683
|
+
let thoughtSelector = null;
|
|
684
|
+
let currentEffort;
|
|
681
685
|
let legacyModes = null;
|
|
682
686
|
let legacyModels = null;
|
|
683
687
|
let sawSlashCommands = false;
|
|
@@ -825,35 +829,78 @@ async function runAcp(opts) {
|
|
|
825
829
|
};
|
|
826
830
|
}
|
|
827
831
|
};
|
|
832
|
+
const switchEffortIfRequested = async (requested, modelChanged) => {
|
|
833
|
+
const discardStaleEffort = () => {
|
|
834
|
+
if (currentEffort === requested) currentEffort = null;
|
|
835
|
+
session.sendSessionEvent({ type: "message", message: `The new model does not support thinking level "${requested}"; using its current thinking level.` });
|
|
836
|
+
};
|
|
837
|
+
if (thoughtSelector) {
|
|
838
|
+
const resolved = thoughtSelector.options.find((option) => option.code === requested)?.code;
|
|
839
|
+
if (!resolved) {
|
|
840
|
+
if (modelChanged) {
|
|
841
|
+
discardStaleEffort();
|
|
842
|
+
return;
|
|
843
|
+
}
|
|
844
|
+
throw new Error(`Unsupported thinking level: ${requested}`);
|
|
845
|
+
}
|
|
846
|
+
if (resolved === thoughtSelector.currentCode) return;
|
|
847
|
+
if (!await backend.setSessionConfigOption(thoughtSelector.configId, resolved)) {
|
|
848
|
+
throw new Error(`Failed to switch thinking level to ${resolved}`);
|
|
849
|
+
}
|
|
850
|
+
thoughtSelector.currentCode = resolved;
|
|
851
|
+
session.updateMetadata((metadata2) => ({ ...metadata2, currentThoughtLevelCode: resolved }));
|
|
852
|
+
return;
|
|
853
|
+
}
|
|
854
|
+
if (permissionModeIsFileBacked() && legacyModes) {
|
|
855
|
+
const resolved = legacyModes.availableModes.find((mode) => mode.id === requested)?.id;
|
|
856
|
+
if (!resolved) {
|
|
857
|
+
if (modelChanged) {
|
|
858
|
+
discardStaleEffort();
|
|
859
|
+
return;
|
|
860
|
+
}
|
|
861
|
+
throw new Error(`Unsupported thinking level: ${requested}`);
|
|
862
|
+
}
|
|
863
|
+
if (resolved === legacyModes.currentModeId) return;
|
|
864
|
+
if (!await backend.setSessionMode(resolved)) throw new Error(`Failed to switch thinking level to ${resolved}`);
|
|
865
|
+
legacyModes = { ...legacyModes, currentModeId: resolved };
|
|
866
|
+
session.updateMetadata((metadata2) => ({ ...metadata2, currentOperatingModeCode: resolved, currentThoughtLevelCode: resolved }));
|
|
867
|
+
return;
|
|
868
|
+
}
|
|
869
|
+
if (modelChanged) {
|
|
870
|
+
discardStaleEffort();
|
|
871
|
+
return;
|
|
872
|
+
}
|
|
873
|
+
throw new Error(`This agent does not advertise thinking levels`);
|
|
874
|
+
};
|
|
828
875
|
const switchModelIfRequested = async (requestedModel) => {
|
|
829
876
|
if (!requestedModel) {
|
|
830
|
-
return;
|
|
877
|
+
return false;
|
|
831
878
|
}
|
|
832
879
|
if (modelSelector) {
|
|
833
880
|
const resolved = resolveRequestedCode(modelSelector.options, requestedModel);
|
|
834
881
|
if (!resolved) {
|
|
835
882
|
persistence.logger.debug(`[${opts.agentName}] Ignoring unknown ACP model request: ${requestedModel}`);
|
|
836
|
-
return;
|
|
883
|
+
return false;
|
|
837
884
|
}
|
|
838
885
|
if (resolved === modelSelector.currentCode) {
|
|
839
|
-
return;
|
|
886
|
+
return false;
|
|
840
887
|
}
|
|
841
888
|
const switched2 = await backend.setSessionConfigOption(modelSelector.configId, resolved);
|
|
842
889
|
if (switched2) {
|
|
843
890
|
modelSelector.currentCode = resolved;
|
|
844
|
-
return;
|
|
891
|
+
return true;
|
|
845
892
|
}
|
|
846
893
|
}
|
|
847
894
|
if (!legacyModels) {
|
|
848
|
-
return;
|
|
895
|
+
return false;
|
|
849
896
|
}
|
|
850
897
|
const resolvedLegacyModel = resolveRequestedLegacyModelCode(legacyModels, requestedModel);
|
|
851
898
|
if (!resolvedLegacyModel) {
|
|
852
899
|
persistence.logger.debug(`[${opts.agentName}] Ignoring unknown ACP legacy model request: ${requestedModel}`);
|
|
853
|
-
return;
|
|
900
|
+
return false;
|
|
854
901
|
}
|
|
855
902
|
if (resolvedLegacyModel === legacyModels.currentModelId) {
|
|
856
|
-
return;
|
|
903
|
+
return false;
|
|
857
904
|
}
|
|
858
905
|
const switched = await backend.setSessionModel(resolvedLegacyModel);
|
|
859
906
|
if (switched) {
|
|
@@ -861,7 +908,13 @@ async function runAcp(opts) {
|
|
|
861
908
|
...legacyModels,
|
|
862
909
|
currentModelId: resolvedLegacyModel
|
|
863
910
|
};
|
|
911
|
+
return true;
|
|
864
912
|
}
|
|
913
|
+
return false;
|
|
914
|
+
};
|
|
915
|
+
const isCurrentRequestedModel = (requested) => {
|
|
916
|
+
if (modelSelector) return resolveRequestedCode(modelSelector.options, requested) === modelSelector.currentCode;
|
|
917
|
+
return !!legacyModels && resolveRequestedLegacyModelCode(legacyModels, requested) === legacyModels.currentModelId;
|
|
865
918
|
};
|
|
866
919
|
const onBackendMessage = (msg) => {
|
|
867
920
|
if (verbose) {
|
|
@@ -898,6 +951,7 @@ async function runAcp(opts) {
|
|
|
898
951
|
}
|
|
899
952
|
modeSelector = extractConfigSelector(configOptions, "mode");
|
|
900
953
|
modelSelector = extractConfigSelector(configOptions, "model");
|
|
954
|
+
thoughtSelector = extractConfigSelector(configOptions, "thought_level");
|
|
901
955
|
if (verbose) {
|
|
902
956
|
if (modeSelector) {
|
|
903
957
|
sawModes = true;
|
|
@@ -998,22 +1052,35 @@ async function runAcp(opts) {
|
|
|
998
1052
|
};
|
|
999
1053
|
backend.onMessage(onBackendMessage);
|
|
1000
1054
|
const titleGenerator = new index.TitleGenerator(session);
|
|
1055
|
+
index.registerAgentAttachmentDownloads(session);
|
|
1056
|
+
let userMessageDelivery = Promise.resolve();
|
|
1001
1057
|
session.onUserMessage((message) => {
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1058
|
+
const downloads = session.drainAttachmentsForUserMessage();
|
|
1059
|
+
userMessageDelivery = userMessageDelivery.then(async () => {
|
|
1060
|
+
const attachments = await downloads;
|
|
1061
|
+
if (!message.content.text && !attachments?.length) {
|
|
1062
|
+
return;
|
|
1063
|
+
}
|
|
1064
|
+
titleGenerator.maybeGenerate(message.content.text);
|
|
1065
|
+
if (typeof message.meta?.permissionMode === "string") {
|
|
1066
|
+
currentPermissionMode = message.meta.permissionMode;
|
|
1067
|
+
persistence.logger.debug(`[${opts.agentName}] Requested ACP permission mode: ${currentPermissionMode}`);
|
|
1068
|
+
}
|
|
1069
|
+
if (message.meta && Object.prototype.hasOwnProperty.call(message.meta, "model")) {
|
|
1070
|
+
currentModel = message.meta.model ?? null;
|
|
1071
|
+
persistence.logger.debug(`[${opts.agentName}] Requested ACP model: ${currentModel ?? "null"}`);
|
|
1072
|
+
}
|
|
1073
|
+
if (message.meta && Object.prototype.hasOwnProperty.call(message.meta, "effort")) {
|
|
1074
|
+
currentEffort = message.meta.effort ?? null;
|
|
1075
|
+
}
|
|
1076
|
+
messageQueue.push(message.content.text, {
|
|
1077
|
+
permissionMode: currentPermissionMode,
|
|
1078
|
+
model: currentModel,
|
|
1079
|
+
effort: currentEffort
|
|
1080
|
+
}, attachments, message.localKey);
|
|
1081
|
+
}).catch(() => {
|
|
1082
|
+
persistence.logger.warn("[ACP] Failed to prepare user attachments");
|
|
1083
|
+
session.sendSessionEvent({ type: "message", message: "Could not prepare this message. Please send it again." });
|
|
1017
1084
|
});
|
|
1018
1085
|
});
|
|
1019
1086
|
session.keepAlive(thinking, "remote");
|
|
@@ -1059,6 +1126,15 @@ async function runAcp(opts) {
|
|
|
1059
1126
|
try {
|
|
1060
1127
|
const started = await backend.startSession();
|
|
1061
1128
|
acpSessionId = started.sessionId;
|
|
1129
|
+
if (opts.model) {
|
|
1130
|
+
await switchModelIfRequested(opts.model);
|
|
1131
|
+
const applied = isCurrentRequestedModel(opts.model);
|
|
1132
|
+
if (!applied) session.sendSessionEvent({ type: "message", message: "The saved model is unavailable for this agent; using its current model." });
|
|
1133
|
+
}
|
|
1134
|
+
session.updateMetadata((current) => ({
|
|
1135
|
+
...current,
|
|
1136
|
+
attachmentKinds: opts.agentName === "pi" && backend.supportsImageAttachments ? [...index.CLAUDE_ATTACHMENT_KINDS] : []
|
|
1137
|
+
}));
|
|
1062
1138
|
if (permissionModeIsFileBacked()) {
|
|
1063
1139
|
fileBackedModeActive = true;
|
|
1064
1140
|
publishFileBackedPermissionMode(initialPermissionMode);
|
|
@@ -1098,13 +1174,19 @@ async function runAcp(opts) {
|
|
|
1098
1174
|
if (typeof batch.mode.permissionMode === "string" && batch.mode.permissionMode.length > 0) {
|
|
1099
1175
|
await switchPermissionModeIfRequested(batch.mode.permissionMode);
|
|
1100
1176
|
}
|
|
1101
|
-
|
|
1102
|
-
|
|
1177
|
+
const modelChanged = typeof batch.mode.model === "string" && batch.mode.model.length > 0 ? await switchModelIfRequested(batch.mode.model) : false;
|
|
1178
|
+
if (typeof batch.mode.effort === "string") {
|
|
1179
|
+
await switchEffortIfRequested(batch.mode.effort, modelChanged);
|
|
1103
1180
|
}
|
|
1104
1181
|
const prompt = todoDiscoverySent ? batch.message : `${batch.message}
|
|
1105
1182
|
|
|
1106
1183
|
${api.BUILTIN_TODO_DISCOVERY}`;
|
|
1107
|
-
|
|
1184
|
+
const attachments = batch.attachments ?? [];
|
|
1185
|
+
const staged = attachments.length ? await index.stageClaudeAttachments(attachments, {
|
|
1186
|
+
happyHomeDir: persistence.configuration.happyHomeDir,
|
|
1187
|
+
sessionId: session.sessionId
|
|
1188
|
+
}) : [];
|
|
1189
|
+
await backend.sendPrompt(acpSessionId, index.appendStagedAttachmentsToPrompt(prompt, staged), attachments);
|
|
1108
1190
|
todoDiscoverySent = true;
|
|
1109
1191
|
await turnEnded;
|
|
1110
1192
|
sendEnvelopes(sessionManager.endTurn("completed"));
|
|
@@ -1115,6 +1197,7 @@ ${api.BUILTIN_TODO_DISCOVERY}`;
|
|
|
1115
1197
|
logAcp("muted", `Outgoing prompt completion from ${opts.agentName}`);
|
|
1116
1198
|
}
|
|
1117
1199
|
} catch (error) {
|
|
1200
|
+
session.sendSessionEvent({ type: "message", message: "The agent could not process this message or its attachments. Please check the agent and try again." });
|
|
1118
1201
|
sendEnvelopes(sessionManager.endTurn("failed"));
|
|
1119
1202
|
streamRelay.endTurn();
|
|
1120
1203
|
setThinking(false);
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var index = require('./index-
|
|
3
|
+
var index = require('./index-BdZ7Dlg0.cjs');
|
|
4
4
|
var claudeAgentSdk = require('@anthropic-ai/claude-agent-sdk');
|
|
5
5
|
require('chalk');
|
|
6
6
|
require('node:os');
|
|
7
7
|
require('node:crypto');
|
|
8
|
-
require('./types-
|
|
8
|
+
require('./types-Ba9u0uZL.cjs');
|
|
9
9
|
require('axios');
|
|
10
|
-
require('./limits-
|
|
10
|
+
require('./limits-B5wJ5Slz.cjs');
|
|
11
11
|
require('node:fs/promises');
|
|
12
12
|
require('node:fs');
|
|
13
13
|
require('node:path');
|
|
@@ -31,7 +31,7 @@ require('fs');
|
|
|
31
31
|
require('node:readline');
|
|
32
32
|
require('@anthropic-ai/sandbox-runtime');
|
|
33
33
|
require('expo-server-sdk');
|
|
34
|
-
require('./agentGuidance-
|
|
34
|
+
require('./agentGuidance-B1PsijGg.cjs');
|
|
35
35
|
require('ink');
|
|
36
36
|
require('react');
|
|
37
37
|
require('ps-list');
|