@getpaseo/server 0.1.97 → 0.1.99
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/server/server/agent/agent-manager.d.ts +11 -3
- package/dist/server/server/agent/agent-manager.js +96 -24
- package/dist/server/server/agent/agent-prompt.d.ts +1 -1
- package/dist/server/server/agent/agent-prompt.js +3 -10
- package/dist/server/server/agent/agent-sdk-types.d.ts +20 -9
- package/dist/server/server/agent/create-agent/create.d.ts +2 -0
- package/dist/server/server/agent/create-agent/create.js +8 -7
- package/dist/server/server/agent/lifecycle-command.d.ts +15 -1
- package/dist/server/server/agent/lifecycle-command.js +9 -2
- package/dist/server/server/agent/mcp-server.js +254 -115
- package/dist/server/server/agent/provider-notices.d.ts +3 -0
- package/dist/server/server/agent/provider-notices.js +5 -0
- package/dist/server/server/agent/provider-registry.d.ts +8 -3
- package/dist/server/server/agent/provider-registry.js +58 -25
- package/dist/server/server/agent/provider-snapshot-manager.d.ts +3 -0
- package/dist/server/server/agent/provider-snapshot-manager.js +37 -16
- package/dist/server/server/agent/providers/acp-agent.d.ts +5 -3
- package/dist/server/server/agent/providers/acp-agent.js +32 -19
- package/dist/server/server/agent/providers/claude/agent.d.ts +2 -2
- package/dist/server/server/agent/providers/claude/agent.js +261 -167
- package/dist/server/server/agent/providers/claude/models.js +7 -3
- package/dist/server/server/agent/providers/codex-app-server-agent.d.ts +6 -4
- package/dist/server/server/agent/providers/codex-app-server-agent.js +48 -25
- package/dist/server/server/agent/providers/copilot-acp-agent.js +4 -31
- package/dist/server/server/agent/providers/diagnostic-utils.d.ts +9 -0
- package/dist/server/server/agent/providers/diagnostic-utils.js +188 -0
- package/dist/server/server/agent/providers/generic-acp-agent.d.ts +0 -1
- package/dist/server/server/agent/providers/generic-acp-agent.js +2 -108
- package/dist/server/server/agent/providers/mock-load-test-agent.d.ts +2 -3
- package/dist/server/server/agent/providers/mock-load-test-agent.js +5 -5
- package/dist/server/server/agent/providers/mock-slow-provider.d.ts +2 -3
- package/dist/server/server/agent/providers/mock-slow-provider.js +3 -6
- package/dist/server/server/agent/providers/opencode/server-manager.d.ts +29 -2
- package/dist/server/server/agent/providers/opencode/server-manager.js +83 -17
- package/dist/server/server/agent/providers/opencode-agent.d.ts +6 -3
- package/dist/server/server/agent/providers/opencode-agent.js +61 -107
- package/dist/server/server/agent/providers/pi/agent.d.ts +2 -3
- package/dist/server/server/agent/providers/pi/agent.js +11 -63
- package/dist/server/server/agent/providers/pi/cli-runtime.js +2 -2
- package/dist/server/server/agent/providers/pi/runtime.d.ts +1 -1
- package/dist/server/server/agent/providers/pi/test-utils/fake-pi.d.ts +1 -1
- package/dist/server/server/agent/providers/pi/test-utils/fake-pi.js +1 -1
- package/dist/server/server/bootstrap.d.ts +2 -0
- package/dist/server/server/bootstrap.js +32 -2
- package/dist/server/server/managed-processes/managed-processes.d.ts +76 -0
- package/dist/server/server/managed-processes/managed-processes.js +326 -0
- package/dist/server/server/resolve-worktree-creation-intent.d.ts +3 -0
- package/dist/server/server/resolve-worktree-creation-intent.js +3 -3
- package/dist/server/server/session/agent-config/agent-config-session.d.ts +50 -0
- package/dist/server/server/session/agent-config/agent-config-session.js +98 -0
- package/dist/server/server/session/chat/chat-schedule-loop-session.d.ts +120 -0
- package/dist/server/server/session/chat/chat-schedule-loop-session.js +489 -0
- package/dist/server/server/session/checkout/checkout-session.d.ts +142 -0
- package/dist/server/server/session/checkout/checkout-session.js +925 -0
- package/dist/server/server/session/daemon/daemon-session.d.ts +50 -0
- package/dist/server/server/session/daemon/daemon-session.js +98 -0
- package/dist/server/server/session/files/workspace-files-session.d.ts +43 -0
- package/dist/server/server/session/files/workspace-files-session.js +218 -0
- package/dist/server/server/session/project-config/project-config-session.d.ts +34 -0
- package/dist/server/server/session/project-config/project-config-session.js +125 -0
- package/dist/server/server/session/provider/provider-catalog-session.d.ts +74 -0
- package/dist/server/server/session/provider/provider-catalog-session.js +339 -0
- package/dist/server/server/session/voice/voice-session.d.ts +166 -0
- package/dist/server/server/session/voice/voice-session.js +893 -0
- package/dist/server/server/{voice → session/voice}/voice-turn-controller.d.ts +2 -2
- package/dist/server/server/{voice → session/voice}/voice-turn-controller.js +2 -2
- package/dist/server/server/session.d.ts +23 -207
- package/dist/server/server/session.js +2319 -5102
- package/dist/server/server/speech/providers/openai/runtime.js +3 -4
- package/dist/server/server/websocket-server.d.ts +1 -0
- package/dist/server/server/websocket-server.js +11 -0
- package/dist/server/server/workspace-archive-service.js +2 -3
- package/dist/server/server/workspace-directory.js +5 -5
- package/dist/server/server/workspace-reconciliation-service.js +2 -2
- package/dist/server/server/worktree-core.d.ts +1 -0
- package/dist/server/server/worktree-core.js +5 -1
- package/dist/server/services/quota-fetcher/manifest.d.ts +4 -0
- package/dist/server/services/quota-fetcher/manifest.js +47 -0
- package/dist/server/services/quota-fetcher/provider.d.ts +17 -0
- package/dist/server/services/quota-fetcher/provider.js +2 -0
- package/dist/server/services/quota-fetcher/providers/claude.d.ts +26 -0
- package/dist/server/services/quota-fetcher/providers/claude.js +217 -0
- package/dist/server/services/quota-fetcher/providers/codex.d.ts +23 -0
- package/dist/server/services/quota-fetcher/providers/codex.js +211 -0
- package/dist/server/services/quota-fetcher/providers/copilot.d.ts +17 -0
- package/dist/server/services/quota-fetcher/providers/copilot.js +75 -0
- package/dist/server/services/quota-fetcher/providers/cursor.d.ts +17 -0
- package/dist/server/services/quota-fetcher/providers/cursor.js +123 -0
- package/dist/server/services/quota-fetcher/providers/grok.d.ts +18 -0
- package/dist/server/services/quota-fetcher/providers/grok.js +89 -0
- package/dist/server/services/quota-fetcher/providers/kimi.d.ts +20 -0
- package/dist/server/services/quota-fetcher/providers/kimi.js +89 -0
- package/dist/server/services/quota-fetcher/providers/zai.d.ts +17 -0
- package/dist/server/services/quota-fetcher/providers/zai.js +58 -0
- package/dist/server/services/quota-fetcher/service.d.ts +28 -0
- package/dist/server/services/quota-fetcher/service.js +58 -0
- package/dist/server/services/quota-fetcher/usage.d.ts +22 -0
- package/dist/server/services/quota-fetcher/usage.js +49 -0
- package/dist/server/utils/checkout-git.d.ts +6 -0
- package/dist/server/utils/directory-suggestions.js +98 -2
- package/package.json +5 -5
|
@@ -9,13 +9,14 @@ import { getClaudeModelsWithSettings, normalizeClaudeRuntimeModelId } from "./mo
|
|
|
9
9
|
import { parsePartialJsonObject } from "./partial-json.js";
|
|
10
10
|
import { ClaudeSidechainTracker } from "./sidechain-tracker.js";
|
|
11
11
|
import { buildClaudeFeatures, claudeModelSupportsFastMode } from "./feature-definitions.js";
|
|
12
|
-
import { buildBinaryDiagnosticRows,
|
|
12
|
+
import { buildBinaryDiagnosticRows, buildCommandResolutionDiagnosticRows, formatProviderDiagnostic, formatProviderDiagnosticError, } from "../diagnostic-utils.js";
|
|
13
13
|
import { appendOrReplaceGrowingAssistantMessage, runProviderTurn } from "../provider-runner.js";
|
|
14
14
|
import { renderPromptAttachmentAsText } from "../../prompt-attachments.js";
|
|
15
15
|
import { claudeQuery } from "./query.js";
|
|
16
16
|
import { realClaudeRewindSdk, revertClaudeConversation, revertClaudeFiles } from "./rewind.js";
|
|
17
17
|
import { normalizeProviderReplayTimestamp } from "../../provider-history-timestamps.js";
|
|
18
18
|
import { claudeProjectDirSync } from "./project-dir.js";
|
|
19
|
+
import { SETTING_APPLIES_NEXT_TURN_NOTICE } from "../../provider-notices.js";
|
|
19
20
|
import { getAgentStreamEventTurnId, } from "../../agent-sdk-types.js";
|
|
20
21
|
import { importSessionFromPersistence } from "../../provider-session-import.js";
|
|
21
22
|
import { checkProviderLaunchAvailable, createProviderEnv, createProviderEnvSpec, resolveProviderLaunch, } from "../../provider-launch-config.js";
|
|
@@ -228,6 +229,9 @@ function isClaudeThinkingEffort(value) {
|
|
|
228
229
|
value === "xhigh" ||
|
|
229
230
|
value === "max");
|
|
230
231
|
}
|
|
232
|
+
function isClaudeThinkingOption(value) {
|
|
233
|
+
return value === "ultracode" || isClaudeThinkingEffort(value);
|
|
234
|
+
}
|
|
231
235
|
const MAX_RECENT_STDERR_CHARS = 4000;
|
|
232
236
|
const STDERR_FLUSH_WAIT_MS = 150;
|
|
233
237
|
const STDERR_FLUSH_POLL_INTERVAL_MS = 10;
|
|
@@ -1028,9 +1032,10 @@ export class ClaudeAgentClient {
|
|
|
1028
1032
|
resolveBinary: this.resolveBinary,
|
|
1029
1033
|
});
|
|
1030
1034
|
}
|
|
1031
|
-
async
|
|
1035
|
+
async fetchCatalog(_options) {
|
|
1032
1036
|
// Claude exposes a global catalog here; cwd/force are intentionally irrelevant.
|
|
1033
|
-
|
|
1037
|
+
const models = await getClaudeModelsWithSettings(this.logger, this.configDir);
|
|
1038
|
+
return { models, modes: DEFAULT_MODES };
|
|
1034
1039
|
}
|
|
1035
1040
|
async listFeatures(config) {
|
|
1036
1041
|
const claudeConfig = this.assertConfig(config);
|
|
@@ -1075,34 +1080,16 @@ export class ClaudeAgentClient {
|
|
|
1075
1080
|
defaultBinary: "claude",
|
|
1076
1081
|
});
|
|
1077
1082
|
const availability = await checkProviderLaunchAvailable(launch);
|
|
1078
|
-
const
|
|
1079
|
-
const auth = available
|
|
1083
|
+
const auth = availability.available
|
|
1080
1084
|
? await resolveClaudeAuth(launch, availability, this.runtimeSettings)
|
|
1081
1085
|
: null;
|
|
1082
|
-
let modelsValue = "Not checked";
|
|
1083
|
-
let status = formatDiagnosticStatus(available);
|
|
1084
|
-
if (available) {
|
|
1085
|
-
try {
|
|
1086
|
-
const models = await this.listModels({
|
|
1087
|
-
cwd: os.homedir(),
|
|
1088
|
-
force: false,
|
|
1089
|
-
});
|
|
1090
|
-
modelsValue = String(models.length);
|
|
1091
|
-
}
|
|
1092
|
-
catch (error) {
|
|
1093
|
-
modelsValue = `Error - ${toDiagnosticErrorMessage(error)}`;
|
|
1094
|
-
status = formatDiagnosticStatus(available, {
|
|
1095
|
-
source: "model fetch",
|
|
1096
|
-
cause: error,
|
|
1097
|
-
});
|
|
1098
|
-
}
|
|
1099
|
-
}
|
|
1100
1086
|
return {
|
|
1101
1087
|
diagnostic: formatProviderDiagnostic("Claude Code", [
|
|
1088
|
+
...(await buildCommandResolutionDiagnosticRows(launch, {
|
|
1089
|
+
knownBinaryNames: ["claude"],
|
|
1090
|
+
})),
|
|
1102
1091
|
...(await buildBinaryDiagnosticRows(launch, availability)),
|
|
1103
1092
|
...(auth ? [{ label: "Auth", value: auth }] : []),
|
|
1104
|
-
{ label: "Models", value: modelsValue },
|
|
1105
|
-
{ label: "Status", value: status },
|
|
1106
1093
|
]),
|
|
1107
1094
|
};
|
|
1108
1095
|
}
|
|
@@ -1180,21 +1167,21 @@ function extractContextWindowSize(modelUsage) {
|
|
|
1180
1167
|
}
|
|
1181
1168
|
return maxContextWindow;
|
|
1182
1169
|
}
|
|
1183
|
-
function
|
|
1184
|
-
|
|
1170
|
+
function resolveInitialContextWindowSize(modelId) {
|
|
1171
|
+
const normalized = typeof modelId === "string" ? modelId.trim().toLowerCase() : "";
|
|
1172
|
+
if (!normalized) {
|
|
1185
1173
|
return undefined;
|
|
1186
1174
|
}
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
return undefined;
|
|
1175
|
+
if (normalized.includes("[1m]") || normalized.includes("context-1m")) {
|
|
1176
|
+
return 1000000;
|
|
1190
1177
|
}
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
return
|
|
1178
|
+
if (normalized.includes("claude-fable-5")) {
|
|
1179
|
+
return 1000000;
|
|
1180
|
+
}
|
|
1181
|
+
if (/(?:^|[~/_-])(?:claude[-_ ]*)?(opus|sonnet|haiku)(?:$|[-_ ./])/.test(normalized)) {
|
|
1182
|
+
return 200000;
|
|
1183
|
+
}
|
|
1184
|
+
return undefined;
|
|
1198
1185
|
}
|
|
1199
1186
|
function readStreamRequestInputTokens(event) {
|
|
1200
1187
|
const messageUsage = toObjectRecord(toObjectRecord(event.message)?.usage);
|
|
@@ -1225,6 +1212,172 @@ function readStreamRequestOutputTokens(event) {
|
|
|
1225
1212
|
}
|
|
1226
1213
|
return outputTokens;
|
|
1227
1214
|
}
|
|
1215
|
+
function readLastUsageIteration(usage) {
|
|
1216
|
+
const iterations = toObjectRecord(usage)?.iterations;
|
|
1217
|
+
if (!Array.isArray(iterations)) {
|
|
1218
|
+
return undefined;
|
|
1219
|
+
}
|
|
1220
|
+
for (let index = iterations.length - 1; index >= 0; index -= 1) {
|
|
1221
|
+
const candidate = toObjectRecord(iterations[index]);
|
|
1222
|
+
if (candidate) {
|
|
1223
|
+
return candidate;
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1226
|
+
return undefined;
|
|
1227
|
+
}
|
|
1228
|
+
function readUsageTokenTotal(usage) {
|
|
1229
|
+
const usageWithCacheCreation = usage;
|
|
1230
|
+
const inputTokens = typeof usage.input_tokens === "number" && Number.isFinite(usage.input_tokens)
|
|
1231
|
+
? usage.input_tokens
|
|
1232
|
+
: 0;
|
|
1233
|
+
const cacheCreationInputTokens = typeof usageWithCacheCreation.cache_creation_input_tokens === "number" &&
|
|
1234
|
+
Number.isFinite(usageWithCacheCreation.cache_creation_input_tokens)
|
|
1235
|
+
? usageWithCacheCreation.cache_creation_input_tokens
|
|
1236
|
+
: 0;
|
|
1237
|
+
const cacheReadInputTokens = typeof usage.cache_read_input_tokens === "number" &&
|
|
1238
|
+
Number.isFinite(usage.cache_read_input_tokens)
|
|
1239
|
+
? usage.cache_read_input_tokens
|
|
1240
|
+
: 0;
|
|
1241
|
+
const outputTokens = typeof usage.output_tokens === "number" && Number.isFinite(usage.output_tokens)
|
|
1242
|
+
? usage.output_tokens
|
|
1243
|
+
: 0;
|
|
1244
|
+
const total = inputTokens + cacheCreationInputTokens + cacheReadInputTokens + outputTokens;
|
|
1245
|
+
return total > 0 ? total : undefined;
|
|
1246
|
+
}
|
|
1247
|
+
function readActiveUsageTokens(usage) {
|
|
1248
|
+
const activeUsage = readLastUsageIteration(usage);
|
|
1249
|
+
return activeUsage ? readUsageTokenTotal(activeUsage) : undefined;
|
|
1250
|
+
}
|
|
1251
|
+
function readLegacyResultUsageTokens(usage) {
|
|
1252
|
+
const usageRecord = toObjectRecord(usage);
|
|
1253
|
+
return usageRecord ? readUsageTokenTotal(usageRecord) : undefined;
|
|
1254
|
+
}
|
|
1255
|
+
function readCurrentContextUsage(value) {
|
|
1256
|
+
const record = toObjectRecord(value);
|
|
1257
|
+
if (!record) {
|
|
1258
|
+
return undefined;
|
|
1259
|
+
}
|
|
1260
|
+
const totalTokens = record.totalTokens;
|
|
1261
|
+
if (typeof totalTokens !== "number" || !Number.isFinite(totalTokens) || totalTokens < 0) {
|
|
1262
|
+
return undefined;
|
|
1263
|
+
}
|
|
1264
|
+
const maxTokens = record.maxTokens;
|
|
1265
|
+
return {
|
|
1266
|
+
totalTokens,
|
|
1267
|
+
...(typeof maxTokens === "number" && Number.isFinite(maxTokens) && maxTokens > 0
|
|
1268
|
+
? { maxTokens }
|
|
1269
|
+
: {}),
|
|
1270
|
+
};
|
|
1271
|
+
}
|
|
1272
|
+
function isClaudeSubagentToolName(name) {
|
|
1273
|
+
return name === "Task" || name === "Agent";
|
|
1274
|
+
}
|
|
1275
|
+
class ClaudeContextUsageState {
|
|
1276
|
+
constructor(initialContextWindowMaxTokens) {
|
|
1277
|
+
this.completedResultTurns = 0;
|
|
1278
|
+
this.contextWindowMaxTokens = initialContextWindowMaxTokens;
|
|
1279
|
+
}
|
|
1280
|
+
beginTurn() {
|
|
1281
|
+
this.streamRequestInputTokens = undefined;
|
|
1282
|
+
this.streamRequestOutputTokens = undefined;
|
|
1283
|
+
}
|
|
1284
|
+
setInitialContextWindowMaxTokens(contextWindowMaxTokens) {
|
|
1285
|
+
this.contextWindowMaxTokens = contextWindowMaxTokens;
|
|
1286
|
+
}
|
|
1287
|
+
recordModelUsage(modelUsage) {
|
|
1288
|
+
const contextWindowMaxTokens = extractContextWindowSize(modelUsage);
|
|
1289
|
+
if (contextWindowMaxTokens !== undefined) {
|
|
1290
|
+
this.contextWindowMaxTokens = contextWindowMaxTokens;
|
|
1291
|
+
}
|
|
1292
|
+
return this.contextWindowMaxTokens;
|
|
1293
|
+
}
|
|
1294
|
+
recordCurrentContextUsage(usage) {
|
|
1295
|
+
if (usage?.maxTokens !== undefined) {
|
|
1296
|
+
this.contextWindowMaxTokens = usage.maxTokens;
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1299
|
+
buildStreamUsageEvent(event) {
|
|
1300
|
+
const streamEvent = toObjectRecord(event);
|
|
1301
|
+
if (!streamEvent) {
|
|
1302
|
+
return null;
|
|
1303
|
+
}
|
|
1304
|
+
const eventType = readTrimmedString(streamEvent.type);
|
|
1305
|
+
if (eventType === "message_start") {
|
|
1306
|
+
const inputTokens = readStreamRequestInputTokens(streamEvent);
|
|
1307
|
+
if (typeof inputTokens !== "number") {
|
|
1308
|
+
return null;
|
|
1309
|
+
}
|
|
1310
|
+
this.streamRequestInputTokens = inputTokens;
|
|
1311
|
+
this.streamRequestOutputTokens = 0;
|
|
1312
|
+
}
|
|
1313
|
+
else if (eventType === "message_delta") {
|
|
1314
|
+
const outputTokens = readStreamRequestOutputTokens(streamEvent);
|
|
1315
|
+
if (typeof outputTokens !== "number") {
|
|
1316
|
+
return null;
|
|
1317
|
+
}
|
|
1318
|
+
this.streamRequestOutputTokens = outputTokens;
|
|
1319
|
+
}
|
|
1320
|
+
else {
|
|
1321
|
+
return null;
|
|
1322
|
+
}
|
|
1323
|
+
const usedTokens = this.streamUsedTokens();
|
|
1324
|
+
if (usedTokens === undefined) {
|
|
1325
|
+
return null;
|
|
1326
|
+
}
|
|
1327
|
+
return this.createUsageUpdatedEvent(usedTokens);
|
|
1328
|
+
}
|
|
1329
|
+
buildResultUsage(message, modelUsage, currentContextUsage) {
|
|
1330
|
+
try {
|
|
1331
|
+
if (!message.usage) {
|
|
1332
|
+
return undefined;
|
|
1333
|
+
}
|
|
1334
|
+
const usage = {
|
|
1335
|
+
inputTokens: message.usage.input_tokens,
|
|
1336
|
+
cachedInputTokens: message.usage.cache_read_input_tokens,
|
|
1337
|
+
outputTokens: message.usage.output_tokens,
|
|
1338
|
+
totalCostUsd: message.total_cost_usd,
|
|
1339
|
+
};
|
|
1340
|
+
const modelContextWindowMaxTokens = this.recordModelUsage(modelUsage ?? message.modelUsage);
|
|
1341
|
+
this.recordCurrentContextUsage(currentContextUsage);
|
|
1342
|
+
if (this.contextWindowMaxTokens !== undefined) {
|
|
1343
|
+
usage.contextWindowMaxTokens = this.contextWindowMaxTokens;
|
|
1344
|
+
}
|
|
1345
|
+
else if (modelContextWindowMaxTokens !== undefined) {
|
|
1346
|
+
usage.contextWindowMaxTokens = modelContextWindowMaxTokens;
|
|
1347
|
+
}
|
|
1348
|
+
const activeResultUsageTokens = readActiveUsageTokens(message.usage) ??
|
|
1349
|
+
(this.completedResultTurns === 0 ? readLegacyResultUsageTokens(message.usage) : undefined);
|
|
1350
|
+
const usedTokens = currentContextUsage?.totalTokens ?? this.streamUsedTokens() ?? activeResultUsageTokens;
|
|
1351
|
+
if (usedTokens !== undefined) {
|
|
1352
|
+
usage.contextWindowUsedTokens = usedTokens;
|
|
1353
|
+
}
|
|
1354
|
+
return usage;
|
|
1355
|
+
}
|
|
1356
|
+
finally {
|
|
1357
|
+
this.completedResultTurns += 1;
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1360
|
+
streamUsedTokens() {
|
|
1361
|
+
if (typeof this.streamRequestInputTokens !== "number" ||
|
|
1362
|
+
typeof this.streamRequestOutputTokens !== "number") {
|
|
1363
|
+
return undefined;
|
|
1364
|
+
}
|
|
1365
|
+
return this.streamRequestInputTokens + this.streamRequestOutputTokens;
|
|
1366
|
+
}
|
|
1367
|
+
createUsageUpdatedEvent(contextWindowUsedTokens) {
|
|
1368
|
+
const usage = {
|
|
1369
|
+
contextWindowUsedTokens,
|
|
1370
|
+
};
|
|
1371
|
+
if (this.contextWindowMaxTokens !== undefined) {
|
|
1372
|
+
usage.contextWindowMaxTokens = this.contextWindowMaxTokens;
|
|
1373
|
+
}
|
|
1374
|
+
return {
|
|
1375
|
+
type: "usage_updated",
|
|
1376
|
+
provider: "claude",
|
|
1377
|
+
usage,
|
|
1378
|
+
};
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1228
1381
|
class ClaudeAgentSession {
|
|
1229
1382
|
constructor(config, options) {
|
|
1230
1383
|
this.provider = "claude";
|
|
@@ -1344,6 +1497,7 @@ class ClaudeAgentSession {
|
|
|
1344
1497
|
this.logger = options.logger.child({ agentId: this.agentId });
|
|
1345
1498
|
this.queryFactory = options.queryFactory;
|
|
1346
1499
|
this.resolveBinary = options.resolveBinary;
|
|
1500
|
+
this.contextUsage = new ClaudeContextUsageState(resolveInitialContextWindowSize(this.config.model));
|
|
1347
1501
|
const handle = options.handle;
|
|
1348
1502
|
if (handle) {
|
|
1349
1503
|
if (!handle.sessionId) {
|
|
@@ -1441,6 +1595,7 @@ class ClaudeAgentSession {
|
|
|
1441
1595
|
this.activeForegroundTurnId = turnId;
|
|
1442
1596
|
this.foregroundHasVisibleActivity = false;
|
|
1443
1597
|
this.activeTurnHasAssistantText = false;
|
|
1598
|
+
this.contextUsage.beginTurn();
|
|
1444
1599
|
this.transitionTurnState("foreground", "foreground turn started");
|
|
1445
1600
|
this.clearRecentStderr();
|
|
1446
1601
|
let cancelIssued = false;
|
|
@@ -1550,6 +1705,7 @@ class ClaudeAgentSession {
|
|
|
1550
1705
|
if (!claudeModelSupportsFastMode(this.config.model) && this.config.featureValues?.fast_mode) {
|
|
1551
1706
|
await this.applyFastModeFeature(false, activeQuery);
|
|
1552
1707
|
}
|
|
1708
|
+
this.contextUsage.setInitialContextWindowMaxTokens(resolveInitialContextWindowSize(this.config.model));
|
|
1553
1709
|
this.lastOptionsModel = normalizedModelId ?? this.lastOptionsModel;
|
|
1554
1710
|
this.lastRuntimeModel = null;
|
|
1555
1711
|
this.cachedRuntimeInfo = null;
|
|
@@ -1563,13 +1719,16 @@ class ClaudeAgentSession {
|
|
|
1563
1719
|
if (!normalizedThinkingOptionId || normalizedThinkingOptionId === "default") {
|
|
1564
1720
|
this.config.thinkingOptionId = undefined;
|
|
1565
1721
|
}
|
|
1566
|
-
else if (
|
|
1722
|
+
else if (isClaudeThinkingOption(normalizedThinkingOptionId)) {
|
|
1567
1723
|
this.config.thinkingOptionId = normalizedThinkingOptionId;
|
|
1568
1724
|
}
|
|
1569
1725
|
else {
|
|
1570
1726
|
throw new Error(`Unknown thinking option: ${normalizedThinkingOptionId}`);
|
|
1571
1727
|
}
|
|
1572
1728
|
this.queryRestartNeeded = true;
|
|
1729
|
+
if (this.activeForegroundTurnId || this.autonomousTurn) {
|
|
1730
|
+
return SETTING_APPLIES_NEXT_TURN_NOTICE;
|
|
1731
|
+
}
|
|
1573
1732
|
}
|
|
1574
1733
|
async setFeature(featureId, value) {
|
|
1575
1734
|
if (featureId !== "fast_mode") {
|
|
@@ -2096,10 +2255,13 @@ class ClaudeAgentSession {
|
|
|
2096
2255
|
const thinkingOptionId = this.config.thinkingOptionId && this.config.thinkingOptionId !== "default"
|
|
2097
2256
|
? this.config.thinkingOptionId
|
|
2098
2257
|
: undefined;
|
|
2258
|
+
if (thinkingOptionId === "ultracode") {
|
|
2259
|
+
return { thinking: { type: "adaptive" }, effort: "xhigh", ultracode: true };
|
|
2260
|
+
}
|
|
2099
2261
|
if (thinkingOptionId && isClaudeThinkingEffort(thinkingOptionId)) {
|
|
2100
|
-
return { thinking: { type: "adaptive" }, effort: thinkingOptionId };
|
|
2262
|
+
return { thinking: { type: "adaptive" }, effort: thinkingOptionId, ultracode: false };
|
|
2101
2263
|
}
|
|
2102
|
-
return { thinking: undefined, effort: undefined };
|
|
2264
|
+
return { thinking: undefined, effort: undefined, ultracode: false };
|
|
2103
2265
|
}
|
|
2104
2266
|
buildAppendedSystemPrompt() {
|
|
2105
2267
|
return (composeSystemPromptParts(this.config.systemPrompt, this.config.daemonAppendSystemPrompt) ?? "");
|
|
@@ -2120,10 +2282,10 @@ class ClaudeAgentSession {
|
|
|
2120
2282
|
});
|
|
2121
2283
|
}
|
|
2122
2284
|
async buildOptions() {
|
|
2123
|
-
const { thinking, effort } = this.resolveThinkingConfig();
|
|
2285
|
+
const { thinking, effort, ultracode } = this.resolveThinkingConfig();
|
|
2124
2286
|
const appendedSystemPrompt = this.buildAppendedSystemPrompt();
|
|
2125
2287
|
const extraClaudeOptions = this.config.extra?.claude;
|
|
2126
|
-
const
|
|
2288
|
+
const settingsOptions = this.buildSettingsOptions(extraClaudeOptions, { ultracode });
|
|
2127
2289
|
const sdkEnv = this.buildSdkEnv(extraClaudeOptions);
|
|
2128
2290
|
assertClaudeAutoModeEligible(this.currentMode, sdkEnv);
|
|
2129
2291
|
const claudeBinary = await this.resolveBinary();
|
|
@@ -2172,7 +2334,7 @@ class ClaudeAgentSession {
|
|
|
2172
2334
|
...(thinking ? { thinking } : {}),
|
|
2173
2335
|
...(effort ? { effort } : {}),
|
|
2174
2336
|
...extraClaudeOptions,
|
|
2175
|
-
...
|
|
2337
|
+
...settingsOptions,
|
|
2176
2338
|
...(this.persistSession === undefined ? {} : { persistSession: this.persistSession }),
|
|
2177
2339
|
env: sdkEnv,
|
|
2178
2340
|
};
|
|
@@ -2194,12 +2356,17 @@ class ClaudeAgentSession {
|
|
|
2194
2356
|
}
|
|
2195
2357
|
return base;
|
|
2196
2358
|
}
|
|
2197
|
-
|
|
2359
|
+
buildSettingsOptions(extraClaudeOptions, input) {
|
|
2198
2360
|
const fastMode = this.resolveFastModeSetting();
|
|
2199
|
-
if (fastMode === null) {
|
|
2361
|
+
if (fastMode === null && !input.ultracode) {
|
|
2200
2362
|
return {};
|
|
2201
2363
|
}
|
|
2202
|
-
return {
|
|
2364
|
+
return {
|
|
2365
|
+
settings: mergeClaudeSettings(extraClaudeOptions?.settings, {
|
|
2366
|
+
...(fastMode === null ? {} : { fastMode }),
|
|
2367
|
+
...(input.ultracode ? { ultracode: true } : {}),
|
|
2368
|
+
}),
|
|
2369
|
+
};
|
|
2203
2370
|
}
|
|
2204
2371
|
resolveFastModeSetting() {
|
|
2205
2372
|
if (!claudeModelSupportsFastMode(this.config.model)) {
|
|
@@ -2413,6 +2580,7 @@ class ClaudeAgentSession {
|
|
|
2413
2580
|
id: this.createTurnId("autonomous"),
|
|
2414
2581
|
};
|
|
2415
2582
|
this.activeTurnHasAssistantText = false;
|
|
2583
|
+
this.contextUsage.beginTurn();
|
|
2416
2584
|
this.notifySubscribers({ type: "turn_started", provider: "claude" });
|
|
2417
2585
|
this.syncTurnState("autonomous turn started");
|
|
2418
2586
|
}
|
|
@@ -2491,7 +2659,7 @@ class ClaudeAgentSession {
|
|
|
2491
2659
|
if (await this.handleMissingResumedConversation(message, activeQuery)) {
|
|
2492
2660
|
return true;
|
|
2493
2661
|
}
|
|
2494
|
-
this.routeSdkMessageFromPump(message);
|
|
2662
|
+
await this.routeSdkMessageFromPump(message, activeQuery);
|
|
2495
2663
|
return false;
|
|
2496
2664
|
};
|
|
2497
2665
|
const drainActiveQuery = async () => {
|
|
@@ -2559,7 +2727,7 @@ class ClaudeAgentSession {
|
|
|
2559
2727
|
message.type === "tool_progress" ||
|
|
2560
2728
|
(message.type === "system" && message.subtype === "task_notification"));
|
|
2561
2729
|
}
|
|
2562
|
-
routeSdkMessageFromPump(message) {
|
|
2730
|
+
async routeSdkMessageFromPump(message, activeQuery) {
|
|
2563
2731
|
if (this.shouldSuppressStaleResult(message)) {
|
|
2564
2732
|
return;
|
|
2565
2733
|
}
|
|
@@ -2582,22 +2750,7 @@ class ClaudeAgentSession {
|
|
|
2582
2750
|
identifiers,
|
|
2583
2751
|
rawEvent: message,
|
|
2584
2752
|
}, "provider.claude.parsed_event");
|
|
2585
|
-
const
|
|
2586
|
-
suppressAssistantText: true,
|
|
2587
|
-
suppressReasoning: true,
|
|
2588
|
-
});
|
|
2589
|
-
const assistantTimelineEvents = this.timelineAssembler
|
|
2590
|
-
.consume({
|
|
2591
|
-
message,
|
|
2592
|
-
runId: turnId,
|
|
2593
|
-
messageIdHint: identifiers.messageId,
|
|
2594
|
-
})
|
|
2595
|
-
.map((item) => ({
|
|
2596
|
-
type: "timeline",
|
|
2597
|
-
item,
|
|
2598
|
-
provider: "claude",
|
|
2599
|
-
}));
|
|
2600
|
-
const events = [...messageEvents, ...assistantTimelineEvents];
|
|
2753
|
+
const events = await this.buildPumpedMessageEvents(message, activeQuery, identifiers.messageId, turnId);
|
|
2601
2754
|
if (events.length === 0) {
|
|
2602
2755
|
return;
|
|
2603
2756
|
}
|
|
@@ -2620,6 +2773,38 @@ class ClaudeAgentSession {
|
|
|
2620
2773
|
}
|
|
2621
2774
|
this.dispatchEvents(events);
|
|
2622
2775
|
}
|
|
2776
|
+
async buildPumpedMessageEvents(message, activeQuery, messageIdHint, turnId) {
|
|
2777
|
+
const currentContextUsage = message.type === "result" && message.subtype === "success"
|
|
2778
|
+
? await this.queryCurrentContextUsage(activeQuery)
|
|
2779
|
+
: undefined;
|
|
2780
|
+
const messageEvents = this.translateMessageToEvents(message, {
|
|
2781
|
+
suppressAssistantText: true,
|
|
2782
|
+
suppressReasoning: true,
|
|
2783
|
+
currentContextUsage,
|
|
2784
|
+
});
|
|
2785
|
+
const assistantTimelineEvents = this.timelineAssembler
|
|
2786
|
+
.consume({
|
|
2787
|
+
message,
|
|
2788
|
+
runId: turnId,
|
|
2789
|
+
messageIdHint,
|
|
2790
|
+
})
|
|
2791
|
+
.map((item) => ({
|
|
2792
|
+
type: "timeline",
|
|
2793
|
+
item,
|
|
2794
|
+
provider: "claude",
|
|
2795
|
+
}));
|
|
2796
|
+
return [...messageEvents, ...assistantTimelineEvents];
|
|
2797
|
+
}
|
|
2798
|
+
async queryCurrentContextUsage(activeQuery) {
|
|
2799
|
+
try {
|
|
2800
|
+
const usage = await withTimeout(activeQuery.getContextUsage(), 3000, "timeout");
|
|
2801
|
+
return readCurrentContextUsage(usage);
|
|
2802
|
+
}
|
|
2803
|
+
catch (error) {
|
|
2804
|
+
this.logger.debug({ err: error }, "Claude context usage query failed");
|
|
2805
|
+
return undefined;
|
|
2806
|
+
}
|
|
2807
|
+
}
|
|
2623
2808
|
async handleMissingResumedConversation(message, activeQuery) {
|
|
2624
2809
|
const staleResumeError = this.readMissingResumedConversationError(message);
|
|
2625
2810
|
if (!staleResumeError) {
|
|
@@ -2710,7 +2895,9 @@ class ClaudeAgentSession {
|
|
|
2710
2895
|
this.appendStreamEventEvents(message, events, options);
|
|
2711
2896
|
break;
|
|
2712
2897
|
case "result":
|
|
2713
|
-
this.appendResultEvents(message, events
|
|
2898
|
+
this.appendResultEvents(message, events, {
|
|
2899
|
+
currentContextUsage: options?.currentContextUsage,
|
|
2900
|
+
});
|
|
2714
2901
|
break;
|
|
2715
2902
|
default:
|
|
2716
2903
|
break;
|
|
@@ -2783,22 +2970,18 @@ class ClaudeAgentSession {
|
|
|
2783
2970
|
return;
|
|
2784
2971
|
}
|
|
2785
2972
|
if (message.subtype === "task_progress") {
|
|
2786
|
-
|
|
2787
|
-
readContextWindowUsedTokensFromTaskProgress(message) ?? this.lastContextWindowUsedTokens;
|
|
2788
|
-
if (typeof this.lastContextWindowUsedTokens === "number") {
|
|
2789
|
-
events.push(this.createUsageUpdatedEvent(this.lastContextWindowUsedTokens));
|
|
2790
|
-
}
|
|
2973
|
+
return;
|
|
2791
2974
|
}
|
|
2792
2975
|
}
|
|
2793
2976
|
appendTaskNotificationEvents(message, events) {
|
|
2794
2977
|
// TODO: subagent timelines are best-effort. Subagent task_notifications
|
|
2795
2978
|
// arrive without parent_tool_use_id but with tool_use_id pointing at the
|
|
2796
|
-
// parent's
|
|
2979
|
+
// the parent's subagent tool call, so they slip past the sidechain router and pollute
|
|
2797
2980
|
// the parent timeline. Drop them here; eventually thread them into the
|
|
2798
|
-
// parent
|
|
2981
|
+
// parent tool call's sub_agent log instead.
|
|
2799
2982
|
const taskUseId = message.tool_use_id;
|
|
2800
2983
|
const cachedTool = taskUseId ? this.toolUseCache.get(taskUseId) : undefined;
|
|
2801
|
-
if (cachedTool?.name
|
|
2984
|
+
if (isClaudeSubagentToolName(cachedTool?.name)) {
|
|
2802
2985
|
return;
|
|
2803
2986
|
}
|
|
2804
2987
|
const taskNotificationItem = mapTaskNotificationSystemRecordToToolCall(message);
|
|
@@ -2809,11 +2992,6 @@ class ClaudeAgentSession {
|
|
|
2809
2992
|
provider: "claude",
|
|
2810
2993
|
});
|
|
2811
2994
|
}
|
|
2812
|
-
const usage = readUsageFromTaskNotification(message);
|
|
2813
|
-
if (typeof usage === "number") {
|
|
2814
|
-
this.lastContextWindowUsedTokens = usage;
|
|
2815
|
-
events.push(this.createUsageUpdatedEvent(usage));
|
|
2816
|
-
}
|
|
2817
2995
|
}
|
|
2818
2996
|
appendUserMessageEvents(message, events) {
|
|
2819
2997
|
if (isSyntheticUserEntry(message)) {
|
|
@@ -2877,7 +3055,7 @@ class ClaudeAgentSession {
|
|
|
2877
3055
|
}
|
|
2878
3056
|
}
|
|
2879
3057
|
appendStreamEventEvents(message, events, options) {
|
|
2880
|
-
const usageUpdatedEvent = this.
|
|
3058
|
+
const usageUpdatedEvent = this.contextUsage.buildStreamUsageEvent(message.event);
|
|
2881
3059
|
if (usageUpdatedEvent) {
|
|
2882
3060
|
events.push(usageUpdatedEvent);
|
|
2883
3061
|
}
|
|
@@ -2889,8 +3067,8 @@ class ClaudeAgentSession {
|
|
|
2889
3067
|
events.push({ type: "timeline", item, provider: "claude" });
|
|
2890
3068
|
}
|
|
2891
3069
|
}
|
|
2892
|
-
appendResultEvents(message, events) {
|
|
2893
|
-
const usage = this.convertUsage(message, message.modelUsage);
|
|
3070
|
+
appendResultEvents(message, events, options) {
|
|
3071
|
+
const usage = this.convertUsage(message, message.modelUsage, options?.currentContextUsage);
|
|
2894
3072
|
if (message.subtype === "success") {
|
|
2895
3073
|
// Built-in slash commands (e.g. /voice, /usage, "Unknown command: …")
|
|
2896
3074
|
// run client-side in the Claude CLI with no model turn — output_tokens
|
|
@@ -3034,92 +3212,8 @@ class ClaudeAgentSession {
|
|
|
3034
3212
|
}
|
|
3035
3213
|
return null;
|
|
3036
3214
|
}
|
|
3037
|
-
convertUsage(message, modelUsage) {
|
|
3038
|
-
|
|
3039
|
-
return undefined;
|
|
3040
|
-
}
|
|
3041
|
-
const usage = {
|
|
3042
|
-
inputTokens: message.usage.input_tokens,
|
|
3043
|
-
cachedInputTokens: message.usage.cache_read_input_tokens,
|
|
3044
|
-
outputTokens: message.usage.output_tokens,
|
|
3045
|
-
totalCostUsd: message.total_cost_usd,
|
|
3046
|
-
};
|
|
3047
|
-
const contextWindowMaxTokens = extractContextWindowSize(modelUsage ?? message.modelUsage);
|
|
3048
|
-
if (contextWindowMaxTokens !== undefined) {
|
|
3049
|
-
this.lastContextWindowMaxTokens = contextWindowMaxTokens;
|
|
3050
|
-
usage.contextWindowMaxTokens = contextWindowMaxTokens;
|
|
3051
|
-
}
|
|
3052
|
-
else if (this.lastContextWindowMaxTokens !== undefined) {
|
|
3053
|
-
usage.contextWindowMaxTokens = this.lastContextWindowMaxTokens;
|
|
3054
|
-
}
|
|
3055
|
-
if (typeof this.lastContextWindowUsedTokens === "number") {
|
|
3056
|
-
// task_progress.total_tokens is the accurate context window fill level.
|
|
3057
|
-
// Prefer it over result.usage which contains accumulated session totals.
|
|
3058
|
-
usage.contextWindowUsedTokens = this.lastContextWindowUsedTokens;
|
|
3059
|
-
}
|
|
3060
|
-
else if (typeof this.lastStreamRequestInputTokens === "number" &&
|
|
3061
|
-
typeof this.lastStreamRequestOutputTokens === "number") {
|
|
3062
|
-
usage.contextWindowUsedTokens =
|
|
3063
|
-
this.lastStreamRequestInputTokens + this.lastStreamRequestOutputTokens;
|
|
3064
|
-
}
|
|
3065
|
-
else if (message.usage) {
|
|
3066
|
-
// Fallback: derive from result.usage when no task_progress has been
|
|
3067
|
-
// received yet. These values are accumulated across all API calls, but
|
|
3068
|
-
// for the first turn they equal the per-call values so the estimate is
|
|
3069
|
-
// reasonable. Once a task_progress arrives it takes over permanently.
|
|
3070
|
-
const usageWithCacheCreation = message.usage;
|
|
3071
|
-
const derived = (message.usage.input_tokens ?? 0) +
|
|
3072
|
-
(usageWithCacheCreation.cache_creation_input_tokens ?? 0) +
|
|
3073
|
-
(message.usage.cache_read_input_tokens ?? 0) +
|
|
3074
|
-
(message.usage.output_tokens ?? 0);
|
|
3075
|
-
if (Number.isFinite(derived) && derived > 0) {
|
|
3076
|
-
usage.contextWindowUsedTokens = derived;
|
|
3077
|
-
}
|
|
3078
|
-
}
|
|
3079
|
-
return usage;
|
|
3080
|
-
}
|
|
3081
|
-
createUsageUpdatedEvent(contextWindowUsedTokens) {
|
|
3082
|
-
const usage = {
|
|
3083
|
-
contextWindowUsedTokens,
|
|
3084
|
-
};
|
|
3085
|
-
if (this.lastContextWindowMaxTokens !== undefined) {
|
|
3086
|
-
usage.contextWindowMaxTokens = this.lastContextWindowMaxTokens;
|
|
3087
|
-
}
|
|
3088
|
-
return {
|
|
3089
|
-
type: "usage_updated",
|
|
3090
|
-
provider: "claude",
|
|
3091
|
-
usage,
|
|
3092
|
-
};
|
|
3093
|
-
}
|
|
3094
|
-
trackStreamEventUsage(event) {
|
|
3095
|
-
const streamEvent = toObjectRecord(event);
|
|
3096
|
-
if (!streamEvent) {
|
|
3097
|
-
return null;
|
|
3098
|
-
}
|
|
3099
|
-
const eventType = readTrimmedString(streamEvent.type);
|
|
3100
|
-
if (eventType === "message_start") {
|
|
3101
|
-
const inputTokens = readStreamRequestInputTokens(streamEvent);
|
|
3102
|
-
if (typeof inputTokens !== "number") {
|
|
3103
|
-
return null;
|
|
3104
|
-
}
|
|
3105
|
-
this.lastStreamRequestInputTokens = inputTokens;
|
|
3106
|
-
this.lastStreamRequestOutputTokens = 0;
|
|
3107
|
-
}
|
|
3108
|
-
else if (eventType === "message_delta") {
|
|
3109
|
-
const outputTokens = readStreamRequestOutputTokens(streamEvent);
|
|
3110
|
-
if (typeof outputTokens !== "number") {
|
|
3111
|
-
return null;
|
|
3112
|
-
}
|
|
3113
|
-
this.lastStreamRequestOutputTokens = outputTokens;
|
|
3114
|
-
}
|
|
3115
|
-
else {
|
|
3116
|
-
return null;
|
|
3117
|
-
}
|
|
3118
|
-
if (typeof this.lastStreamRequestInputTokens !== "number" ||
|
|
3119
|
-
typeof this.lastStreamRequestOutputTokens !== "number") {
|
|
3120
|
-
return null;
|
|
3121
|
-
}
|
|
3122
|
-
return this.createUsageUpdatedEvent(this.lastStreamRequestInputTokens + this.lastStreamRequestOutputTokens);
|
|
3215
|
+
convertUsage(message, modelUsage, currentContextUsage) {
|
|
3216
|
+
return this.contextUsage.buildResultUsage(message, modelUsage, currentContextUsage);
|
|
3123
3217
|
}
|
|
3124
3218
|
enqueueTimeline(item) {
|
|
3125
3219
|
this.pushEvent({ type: "timeline", item, provider: "claude" });
|
|
@@ -14,20 +14,24 @@ const CLAUDE_OPUS_EXTENDED_THINKING_OPTIONS = [
|
|
|
14
14
|
{ id: "xhigh", label: "Extra High" },
|
|
15
15
|
{ id: "max", label: "Max" },
|
|
16
16
|
];
|
|
17
|
+
const CLAUDE_ULTRACODE_THINKING_OPTIONS = [
|
|
18
|
+
...CLAUDE_OPUS_EXTENDED_THINKING_OPTIONS,
|
|
19
|
+
{ id: "ultracode", label: "Ultracode" },
|
|
20
|
+
];
|
|
17
21
|
const CLAUDE_MODELS = [
|
|
18
22
|
{
|
|
19
23
|
provider: "claude",
|
|
20
24
|
id: "claude-fable-5",
|
|
21
25
|
label: "Fable 5",
|
|
22
26
|
description: "Fable 5 · Most powerful model",
|
|
23
|
-
thinkingOptions: [...
|
|
27
|
+
thinkingOptions: [...CLAUDE_ULTRACODE_THINKING_OPTIONS],
|
|
24
28
|
},
|
|
25
29
|
{
|
|
26
30
|
provider: "claude",
|
|
27
31
|
id: "claude-opus-4-8[1m]",
|
|
28
32
|
label: "Opus 4.8 1M",
|
|
29
33
|
description: "Opus 4.8 with 1M context window",
|
|
30
|
-
thinkingOptions: [...
|
|
34
|
+
thinkingOptions: [...CLAUDE_ULTRACODE_THINKING_OPTIONS],
|
|
31
35
|
},
|
|
32
36
|
{
|
|
33
37
|
provider: "claude",
|
|
@@ -35,7 +39,7 @@ const CLAUDE_MODELS = [
|
|
|
35
39
|
label: "Opus 4.8",
|
|
36
40
|
description: "Opus 4.8 · Latest release",
|
|
37
41
|
isDefault: true,
|
|
38
|
-
thinkingOptions: [...
|
|
42
|
+
thinkingOptions: [...CLAUDE_ULTRACODE_THINKING_OPTIONS],
|
|
39
43
|
},
|
|
40
44
|
{
|
|
41
45
|
provider: "claude",
|