fix: refresh model preset settings on resume (#1052)
Co-authored-by: Letta <noreply@letta.com> Co-authored-by: letta-code <248085862+letta-code@users.noreply.github.com> Co-authored-by: jnjpng <jnjpng@users.noreply.github.com>
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
* Model resolution and handling utilities
|
* Model resolution and handling utilities
|
||||||
*/
|
*/
|
||||||
import modelsData from "../models.json";
|
import modelsData from "../models.json";
|
||||||
|
import { OPENAI_CODEX_PROVIDER_NAME } from "../providers/openai-codex-provider";
|
||||||
|
|
||||||
export const models = modelsData;
|
export const models = modelsData;
|
||||||
|
|
||||||
@@ -186,6 +187,68 @@ export function getModelUpdateArgs(
|
|||||||
return modelInfo?.updateArgs;
|
return modelInfo?.updateArgs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AgentModelSnapshot = {
|
||||||
|
model?: string | null;
|
||||||
|
llm_config?: {
|
||||||
|
model?: string | null;
|
||||||
|
model_endpoint_type?: string | null;
|
||||||
|
reasoning_effort?: string | null;
|
||||||
|
enable_reasoner?: boolean | null;
|
||||||
|
} | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve the current model preset + updateArgs for an existing agent.
|
||||||
|
*
|
||||||
|
* Used during startup/resume refresh to re-apply only preset-defined fields
|
||||||
|
* (without requiring an explicit --model flag).
|
||||||
|
*/
|
||||||
|
export function getModelPresetUpdateForAgent(
|
||||||
|
agent: AgentModelSnapshot,
|
||||||
|
): { modelHandle: string; updateArgs: Record<string, unknown> } | null {
|
||||||
|
const directHandle =
|
||||||
|
typeof agent.model === "string" && agent.model.length > 0
|
||||||
|
? agent.model
|
||||||
|
: null;
|
||||||
|
|
||||||
|
const endpointType = agent.llm_config?.model_endpoint_type;
|
||||||
|
const llmModel = agent.llm_config?.model;
|
||||||
|
const llmDerivedHandle =
|
||||||
|
typeof endpointType === "string" &&
|
||||||
|
endpointType.length > 0 &&
|
||||||
|
typeof llmModel === "string" &&
|
||||||
|
llmModel.length > 0
|
||||||
|
? `${
|
||||||
|
endpointType === "chatgpt_oauth"
|
||||||
|
? OPENAI_CODEX_PROVIDER_NAME
|
||||||
|
: endpointType
|
||||||
|
}/${llmModel}`
|
||||||
|
: typeof llmModel === "string" && llmModel.includes("/")
|
||||||
|
? llmModel
|
||||||
|
: null;
|
||||||
|
|
||||||
|
const modelHandle = directHandle ?? llmDerivedHandle;
|
||||||
|
if (!modelHandle) return null;
|
||||||
|
|
||||||
|
const modelInfo = getModelInfoForLlmConfig(modelHandle, {
|
||||||
|
reasoning_effort: agent.llm_config?.reasoning_effort ?? null,
|
||||||
|
enable_reasoner: agent.llm_config?.enable_reasoner ?? null,
|
||||||
|
});
|
||||||
|
|
||||||
|
const updateArgs =
|
||||||
|
(modelInfo?.updateArgs as Record<string, unknown> | undefined) ??
|
||||||
|
getModelUpdateArgs(modelHandle);
|
||||||
|
|
||||||
|
if (!updateArgs || Object.keys(updateArgs).length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
modelHandle: modelInfo?.handle ?? modelHandle,
|
||||||
|
updateArgs,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find a model entry by handle with fuzzy matching support
|
* Find a model entry by handle with fuzzy matching support
|
||||||
* @param handle - The full model handle
|
* @param handle - The full model handle
|
||||||
|
|||||||
@@ -878,23 +878,56 @@ export async function handleHeadlessCommand(
|
|||||||
(!forceNew && !fromAfFile)
|
(!forceNew && !fromAfFile)
|
||||||
);
|
);
|
||||||
|
|
||||||
// If resuming and a model or system prompt was specified, apply those changes
|
// If resuming, always refresh model settings from presets to keep
|
||||||
if (isResumingAgent && (model || systemPromptPreset)) {
|
// preset-derived fields in sync, then apply optional command-line
|
||||||
|
// overrides (model/system prompt).
|
||||||
|
if (isResumingAgent) {
|
||||||
|
const { updateAgentLLMConfig } = await import("./agent/modify");
|
||||||
|
|
||||||
if (model) {
|
if (model) {
|
||||||
const { resolveModel } = await import("./agent/model");
|
const { resolveModel } = await import("./agent/model");
|
||||||
const modelHandle = resolveModel(model);
|
const modelHandle = resolveModel(model);
|
||||||
if (!modelHandle) {
|
if (typeof modelHandle !== "string") {
|
||||||
console.error(`Error: Invalid model "${model}"`);
|
console.error(`Error: Invalid model "${model}"`);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always apply model update - different model IDs can share the same
|
// Always apply model update - different model IDs can share the same
|
||||||
// handle but have different settings (e.g., gpt-5.2-medium vs gpt-5.2-xhigh)
|
// handle but have different settings (e.g., gpt-5.2-medium vs gpt-5.2-xhigh)
|
||||||
const { updateAgentLLMConfig } = await import("./agent/modify");
|
|
||||||
const updateArgs = getModelUpdateArgs(model);
|
const updateArgs = getModelUpdateArgs(model);
|
||||||
await updateAgentLLMConfig(agent.id, modelHandle, updateArgs);
|
await updateAgentLLMConfig(agent.id, modelHandle, updateArgs);
|
||||||
// Refresh agent state after model update
|
// Refresh agent state after model update
|
||||||
agent = await client.agents.retrieve(agent.id);
|
agent = await client.agents.retrieve(agent.id);
|
||||||
|
} else {
|
||||||
|
const { getModelPresetUpdateForAgent } = await import("./agent/model");
|
||||||
|
const presetRefresh = getModelPresetUpdateForAgent(agent);
|
||||||
|
if (presetRefresh) {
|
||||||
|
// Resume preset refresh is intentionally scoped for now.
|
||||||
|
// We only force-refresh max_output_tokens + parallel_tool_calls.
|
||||||
|
// Other preset fields available in models.json (for example:
|
||||||
|
// context_window, reasoning_effort, enable_reasoner,
|
||||||
|
// max_reasoning_tokens, verbosity, temperature,
|
||||||
|
// thinking_budget) are intentionally not auto-applied yet.
|
||||||
|
const resumeRefreshUpdateArgs: Record<string, unknown> = {};
|
||||||
|
if (typeof presetRefresh.updateArgs.max_output_tokens === "number") {
|
||||||
|
resumeRefreshUpdateArgs.max_output_tokens =
|
||||||
|
presetRefresh.updateArgs.max_output_tokens;
|
||||||
|
}
|
||||||
|
if (typeof presetRefresh.updateArgs.parallel_tool_calls === "boolean") {
|
||||||
|
resumeRefreshUpdateArgs.parallel_tool_calls =
|
||||||
|
presetRefresh.updateArgs.parallel_tool_calls;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Object.keys(resumeRefreshUpdateArgs).length > 0) {
|
||||||
|
await updateAgentLLMConfig(
|
||||||
|
agent.id,
|
||||||
|
presetRefresh.modelHandle,
|
||||||
|
resumeRefreshUpdateArgs,
|
||||||
|
);
|
||||||
|
// Refresh agent state after model update
|
||||||
|
agent = await client.agents.retrieve(agent.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (systemPromptPreset) {
|
if (systemPromptPreset) {
|
||||||
|
|||||||
46
src/index.ts
46
src/index.ts
@@ -1789,8 +1789,12 @@ async function main(): Promise<void> {
|
|||||||
);
|
);
|
||||||
setIsResumingSession(resuming);
|
setIsResumingSession(resuming);
|
||||||
|
|
||||||
// If resuming and a model or system prompt was specified, apply those changes
|
// If resuming, always refresh model settings from presets to keep
|
||||||
if (resuming && (model || systemPromptPreset)) {
|
// preset-derived fields in sync, then apply optional command-line
|
||||||
|
// overrides (model/system prompt).
|
||||||
|
if (resuming) {
|
||||||
|
const { updateAgentLLMConfig } = await import("./agent/modify");
|
||||||
|
|
||||||
if (model) {
|
if (model) {
|
||||||
const { resolveModel, getModelUpdateArgs } = await import(
|
const { resolveModel, getModelUpdateArgs } = await import(
|
||||||
"./agent/model"
|
"./agent/model"
|
||||||
@@ -1803,11 +1807,47 @@ async function main(): Promise<void> {
|
|||||||
|
|
||||||
// Always apply model update - different model IDs can share the same
|
// Always apply model update - different model IDs can share the same
|
||||||
// handle but have different settings (e.g., gpt-5.2-medium vs gpt-5.2-xhigh)
|
// handle but have different settings (e.g., gpt-5.2-medium vs gpt-5.2-xhigh)
|
||||||
const { updateAgentLLMConfig } = await import("./agent/modify");
|
|
||||||
const updateArgs = getModelUpdateArgs(model);
|
const updateArgs = getModelUpdateArgs(model);
|
||||||
await updateAgentLLMConfig(agent.id, modelHandle, updateArgs);
|
await updateAgentLLMConfig(agent.id, modelHandle, updateArgs);
|
||||||
// Refresh agent state after model update
|
// Refresh agent state after model update
|
||||||
agent = await client.agents.retrieve(agent.id);
|
agent = await client.agents.retrieve(agent.id);
|
||||||
|
} else {
|
||||||
|
const { getModelPresetUpdateForAgent } = await import(
|
||||||
|
"./agent/model"
|
||||||
|
);
|
||||||
|
const presetRefresh = getModelPresetUpdateForAgent(agent);
|
||||||
|
if (presetRefresh) {
|
||||||
|
// Resume preset refresh is intentionally scoped for now.
|
||||||
|
// We only force-refresh max_output_tokens + parallel_tool_calls.
|
||||||
|
// Other preset fields available in models.json (for example:
|
||||||
|
// context_window, reasoning_effort, enable_reasoner,
|
||||||
|
// max_reasoning_tokens, verbosity, temperature,
|
||||||
|
// thinking_budget) are intentionally not auto-applied yet.
|
||||||
|
const resumeRefreshUpdateArgs: Record<string, unknown> = {};
|
||||||
|
if (
|
||||||
|
typeof presetRefresh.updateArgs.max_output_tokens === "number"
|
||||||
|
) {
|
||||||
|
resumeRefreshUpdateArgs.max_output_tokens =
|
||||||
|
presetRefresh.updateArgs.max_output_tokens;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
typeof presetRefresh.updateArgs.parallel_tool_calls ===
|
||||||
|
"boolean"
|
||||||
|
) {
|
||||||
|
resumeRefreshUpdateArgs.parallel_tool_calls =
|
||||||
|
presetRefresh.updateArgs.parallel_tool_calls;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Object.keys(resumeRefreshUpdateArgs).length > 0) {
|
||||||
|
await updateAgentLLMConfig(
|
||||||
|
agent.id,
|
||||||
|
presetRefresh.modelHandle,
|
||||||
|
resumeRefreshUpdateArgs,
|
||||||
|
);
|
||||||
|
// Refresh agent state after model update
|
||||||
|
agent = await client.agents.retrieve(agent.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (systemPromptPreset) {
|
if (systemPromptPreset) {
|
||||||
|
|||||||
234
src/models.json
234
src/models.json
@@ -10,7 +10,8 @@
|
|||||||
"context_window": 200000,
|
"context_window": 200000,
|
||||||
"max_output_tokens": 128000,
|
"max_output_tokens": 128000,
|
||||||
"reasoning_effort": "high",
|
"reasoning_effort": "high",
|
||||||
"enable_reasoner": true
|
"enable_reasoner": true,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -22,7 +23,8 @@
|
|||||||
"context_window": 1000000,
|
"context_window": 1000000,
|
||||||
"max_output_tokens": 128000,
|
"max_output_tokens": 128000,
|
||||||
"reasoning_effort": "high",
|
"reasoning_effort": "high",
|
||||||
"enable_reasoner": true
|
"enable_reasoner": true,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -34,7 +36,8 @@
|
|||||||
"context_window": 200000,
|
"context_window": 200000,
|
||||||
"max_output_tokens": 128000,
|
"max_output_tokens": 128000,
|
||||||
"reasoning_effort": "none",
|
"reasoning_effort": "none",
|
||||||
"enable_reasoner": false
|
"enable_reasoner": false,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -47,7 +50,8 @@
|
|||||||
"max_output_tokens": 128000,
|
"max_output_tokens": 128000,
|
||||||
"reasoning_effort": "low",
|
"reasoning_effort": "low",
|
||||||
"enable_reasoner": true,
|
"enable_reasoner": true,
|
||||||
"max_reasoning_tokens": 4000
|
"max_reasoning_tokens": 4000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -60,7 +64,8 @@
|
|||||||
"max_output_tokens": 128000,
|
"max_output_tokens": 128000,
|
||||||
"reasoning_effort": "medium",
|
"reasoning_effort": "medium",
|
||||||
"enable_reasoner": true,
|
"enable_reasoner": true,
|
||||||
"max_reasoning_tokens": 12000
|
"max_reasoning_tokens": 12000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -73,7 +78,8 @@
|
|||||||
"max_output_tokens": 128000,
|
"max_output_tokens": 128000,
|
||||||
"reasoning_effort": "xhigh",
|
"reasoning_effort": "xhigh",
|
||||||
"enable_reasoner": true,
|
"enable_reasoner": true,
|
||||||
"max_reasoning_tokens": 31999
|
"max_reasoning_tokens": 31999,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -84,7 +90,8 @@
|
|||||||
"updateArgs": {
|
"updateArgs": {
|
||||||
"context_window": 180000,
|
"context_window": 180000,
|
||||||
"max_output_tokens": 64000,
|
"max_output_tokens": 64000,
|
||||||
"max_reasoning_tokens": 31999
|
"max_reasoning_tokens": 31999,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -95,7 +102,8 @@
|
|||||||
"updateArgs": {
|
"updateArgs": {
|
||||||
"enable_reasoner": false,
|
"enable_reasoner": false,
|
||||||
"context_window": 180000,
|
"context_window": 180000,
|
||||||
"max_output_tokens": 64000
|
"max_output_tokens": 64000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -108,7 +116,8 @@
|
|||||||
"context_window": 200000,
|
"context_window": 200000,
|
||||||
"max_output_tokens": 128000,
|
"max_output_tokens": 128000,
|
||||||
"reasoning_effort": "high",
|
"reasoning_effort": "high",
|
||||||
"enable_reasoner": true
|
"enable_reasoner": true,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -120,7 +129,8 @@
|
|||||||
"context_window": 200000,
|
"context_window": 200000,
|
||||||
"max_output_tokens": 128000,
|
"max_output_tokens": 128000,
|
||||||
"reasoning_effort": "none",
|
"reasoning_effort": "none",
|
||||||
"enable_reasoner": false
|
"enable_reasoner": false,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -133,7 +143,8 @@
|
|||||||
"max_output_tokens": 128000,
|
"max_output_tokens": 128000,
|
||||||
"reasoning_effort": "low",
|
"reasoning_effort": "low",
|
||||||
"enable_reasoner": true,
|
"enable_reasoner": true,
|
||||||
"max_reasoning_tokens": 4000
|
"max_reasoning_tokens": 4000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -146,7 +157,8 @@
|
|||||||
"max_output_tokens": 128000,
|
"max_output_tokens": 128000,
|
||||||
"reasoning_effort": "medium",
|
"reasoning_effort": "medium",
|
||||||
"enable_reasoner": true,
|
"enable_reasoner": true,
|
||||||
"max_reasoning_tokens": 12000
|
"max_reasoning_tokens": 12000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -159,7 +171,8 @@
|
|||||||
"max_output_tokens": 128000,
|
"max_output_tokens": 128000,
|
||||||
"reasoning_effort": "xhigh",
|
"reasoning_effort": "xhigh",
|
||||||
"enable_reasoner": true,
|
"enable_reasoner": true,
|
||||||
"max_reasoning_tokens": 31999
|
"max_reasoning_tokens": 31999,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -170,7 +183,8 @@
|
|||||||
"updateArgs": {
|
"updateArgs": {
|
||||||
"context_window": 180000,
|
"context_window": 180000,
|
||||||
"max_output_tokens": 64000,
|
"max_output_tokens": 64000,
|
||||||
"max_reasoning_tokens": 31999
|
"max_reasoning_tokens": 31999,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -183,7 +197,8 @@
|
|||||||
"updateArgs": {
|
"updateArgs": {
|
||||||
"context_window": 180000,
|
"context_window": 180000,
|
||||||
"max_output_tokens": 64000,
|
"max_output_tokens": 64000,
|
||||||
"max_reasoning_tokens": 31999
|
"max_reasoning_tokens": 31999,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -194,7 +209,8 @@
|
|||||||
"isFeatured": true,
|
"isFeatured": true,
|
||||||
"updateArgs": {
|
"updateArgs": {
|
||||||
"context_window": 180000,
|
"context_window": 180000,
|
||||||
"max_output_tokens": 64000
|
"max_output_tokens": 64000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -206,7 +222,8 @@
|
|||||||
"reasoning_effort": "none",
|
"reasoning_effort": "none",
|
||||||
"verbosity": "low",
|
"verbosity": "low",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -218,7 +235,8 @@
|
|||||||
"reasoning_effort": "low",
|
"reasoning_effort": "low",
|
||||||
"verbosity": "low",
|
"verbosity": "low",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -230,7 +248,8 @@
|
|||||||
"reasoning_effort": "medium",
|
"reasoning_effort": "medium",
|
||||||
"verbosity": "low",
|
"verbosity": "low",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -243,7 +262,8 @@
|
|||||||
"reasoning_effort": "high",
|
"reasoning_effort": "high",
|
||||||
"verbosity": "low",
|
"verbosity": "low",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -255,7 +275,8 @@
|
|||||||
"reasoning_effort": "xhigh",
|
"reasoning_effort": "xhigh",
|
||||||
"verbosity": "low",
|
"verbosity": "low",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -267,7 +288,8 @@
|
|||||||
"reasoning_effort": "medium",
|
"reasoning_effort": "medium",
|
||||||
"verbosity": "medium",
|
"verbosity": "medium",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -279,7 +301,8 @@
|
|||||||
"reasoning_effort": "high",
|
"reasoning_effort": "high",
|
||||||
"verbosity": "medium",
|
"verbosity": "medium",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -291,7 +314,8 @@
|
|||||||
"reasoning_effort": "medium",
|
"reasoning_effort": "medium",
|
||||||
"verbosity": "medium",
|
"verbosity": "medium",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -303,7 +327,8 @@
|
|||||||
"reasoning_effort": "high",
|
"reasoning_effort": "high",
|
||||||
"verbosity": "medium",
|
"verbosity": "medium",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -315,7 +340,8 @@
|
|||||||
"reasoning_effort": "medium",
|
"reasoning_effort": "medium",
|
||||||
"verbosity": "medium",
|
"verbosity": "medium",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -327,7 +353,8 @@
|
|||||||
"reasoning_effort": "high",
|
"reasoning_effort": "high",
|
||||||
"verbosity": "medium",
|
"verbosity": "medium",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -339,7 +366,8 @@
|
|||||||
"reasoning_effort": "medium",
|
"reasoning_effort": "medium",
|
||||||
"verbosity": "medium",
|
"verbosity": "medium",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -351,7 +379,8 @@
|
|||||||
"reasoning_effort": "high",
|
"reasoning_effort": "high",
|
||||||
"verbosity": "medium",
|
"verbosity": "medium",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -363,7 +392,8 @@
|
|||||||
"reasoning_effort": "xhigh",
|
"reasoning_effort": "xhigh",
|
||||||
"verbosity": "medium",
|
"verbosity": "medium",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -375,7 +405,8 @@
|
|||||||
"reasoning_effort": "medium",
|
"reasoning_effort": "medium",
|
||||||
"verbosity": "medium",
|
"verbosity": "medium",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -387,7 +418,8 @@
|
|||||||
"reasoning_effort": "none",
|
"reasoning_effort": "none",
|
||||||
"verbosity": "medium",
|
"verbosity": "medium",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -399,7 +431,8 @@
|
|||||||
"reasoning_effort": "low",
|
"reasoning_effort": "low",
|
||||||
"verbosity": "medium",
|
"verbosity": "medium",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -412,7 +445,8 @@
|
|||||||
"reasoning_effort": "medium",
|
"reasoning_effort": "medium",
|
||||||
"verbosity": "medium",
|
"verbosity": "medium",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -424,7 +458,8 @@
|
|||||||
"reasoning_effort": "high",
|
"reasoning_effort": "high",
|
||||||
"verbosity": "medium",
|
"verbosity": "medium",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -436,7 +471,8 @@
|
|||||||
"reasoning_effort": "xhigh",
|
"reasoning_effort": "xhigh",
|
||||||
"verbosity": "medium",
|
"verbosity": "medium",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -448,7 +484,8 @@
|
|||||||
"reasoning_effort": "none",
|
"reasoning_effort": "none",
|
||||||
"verbosity": "medium",
|
"verbosity": "medium",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -460,7 +497,8 @@
|
|||||||
"reasoning_effort": "low",
|
"reasoning_effort": "low",
|
||||||
"verbosity": "medium",
|
"verbosity": "medium",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -473,7 +511,8 @@
|
|||||||
"reasoning_effort": "medium",
|
"reasoning_effort": "medium",
|
||||||
"verbosity": "medium",
|
"verbosity": "medium",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -485,7 +524,8 @@
|
|||||||
"reasoning_effort": "high",
|
"reasoning_effort": "high",
|
||||||
"verbosity": "medium",
|
"verbosity": "medium",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -497,7 +537,8 @@
|
|||||||
"reasoning_effort": "xhigh",
|
"reasoning_effort": "xhigh",
|
||||||
"verbosity": "medium",
|
"verbosity": "medium",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -509,7 +550,8 @@
|
|||||||
"reasoning_effort": "none",
|
"reasoning_effort": "none",
|
||||||
"verbosity": "medium",
|
"verbosity": "medium",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -521,7 +563,8 @@
|
|||||||
"reasoning_effort": "low",
|
"reasoning_effort": "low",
|
||||||
"verbosity": "medium",
|
"verbosity": "medium",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -533,7 +576,8 @@
|
|||||||
"reasoning_effort": "medium",
|
"reasoning_effort": "medium",
|
||||||
"verbosity": "medium",
|
"verbosity": "medium",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -545,7 +589,8 @@
|
|||||||
"reasoning_effort": "high",
|
"reasoning_effort": "high",
|
||||||
"verbosity": "medium",
|
"verbosity": "medium",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -557,7 +602,8 @@
|
|||||||
"reasoning_effort": "none",
|
"reasoning_effort": "none",
|
||||||
"verbosity": "medium",
|
"verbosity": "medium",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -570,7 +616,8 @@
|
|||||||
"reasoning_effort": "medium",
|
"reasoning_effort": "medium",
|
||||||
"verbosity": "medium",
|
"verbosity": "medium",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -582,7 +629,8 @@
|
|||||||
"reasoning_effort": "high",
|
"reasoning_effort": "high",
|
||||||
"verbosity": "medium",
|
"verbosity": "medium",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -594,7 +642,8 @@
|
|||||||
"reasoning_effort": "medium",
|
"reasoning_effort": "medium",
|
||||||
"verbosity": "medium",
|
"verbosity": "medium",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -606,7 +655,8 @@
|
|||||||
"reasoning_effort": "high",
|
"reasoning_effort": "high",
|
||||||
"verbosity": "medium",
|
"verbosity": "medium",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -618,7 +668,8 @@
|
|||||||
"reasoning_effort": "xhigh",
|
"reasoning_effort": "xhigh",
|
||||||
"verbosity": "medium",
|
"verbosity": "medium",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -630,7 +681,8 @@
|
|||||||
"reasoning_effort": "minimal",
|
"reasoning_effort": "minimal",
|
||||||
"verbosity": "medium",
|
"verbosity": "medium",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -642,7 +694,8 @@
|
|||||||
"reasoning_effort": "low",
|
"reasoning_effort": "low",
|
||||||
"verbosity": "medium",
|
"verbosity": "medium",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -654,7 +707,8 @@
|
|||||||
"reasoning_effort": "medium",
|
"reasoning_effort": "medium",
|
||||||
"verbosity": "medium",
|
"verbosity": "medium",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -666,7 +720,8 @@
|
|||||||
"reasoning_effort": "high",
|
"reasoning_effort": "high",
|
||||||
"verbosity": "medium",
|
"verbosity": "medium",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -678,7 +733,8 @@
|
|||||||
"reasoning_effort": "medium",
|
"reasoning_effort": "medium",
|
||||||
"verbosity": "medium",
|
"verbosity": "medium",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -690,7 +746,8 @@
|
|||||||
"reasoning_effort": "medium",
|
"reasoning_effort": "medium",
|
||||||
"verbosity": "medium",
|
"verbosity": "medium",
|
||||||
"context_window": 272000,
|
"context_window": 272000,
|
||||||
"max_output_tokens": 128000
|
"max_output_tokens": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -701,7 +758,8 @@
|
|||||||
"isFeatured": true,
|
"isFeatured": true,
|
||||||
"free": true,
|
"free": true,
|
||||||
"updateArgs": {
|
"updateArgs": {
|
||||||
"context_window": 200000
|
"context_window": 200000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -712,7 +770,8 @@
|
|||||||
"isFeatured": true,
|
"isFeatured": true,
|
||||||
"free": true,
|
"free": true,
|
||||||
"updateArgs": {
|
"updateArgs": {
|
||||||
"context_window": 200000
|
"context_window": 200000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -724,7 +783,8 @@
|
|||||||
"free": true,
|
"free": true,
|
||||||
"updateArgs": {
|
"updateArgs": {
|
||||||
"context_window": 160000,
|
"context_window": 160000,
|
||||||
"max_output_tokens": 64000
|
"max_output_tokens": 64000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -736,7 +796,8 @@
|
|||||||
"free": true,
|
"free": true,
|
||||||
"updateArgs": {
|
"updateArgs": {
|
||||||
"context_window": 160000,
|
"context_window": 160000,
|
||||||
"max_output_tokens": 64000
|
"max_output_tokens": 64000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -746,7 +807,8 @@
|
|||||||
"description": "Minimax's latest model",
|
"description": "Minimax's latest model",
|
||||||
"updateArgs": {
|
"updateArgs": {
|
||||||
"context_window": 160000,
|
"context_window": 160000,
|
||||||
"max_output_tokens": 64000
|
"max_output_tokens": 64000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -755,7 +817,8 @@
|
|||||||
"label": "Kimi K2",
|
"label": "Kimi K2",
|
||||||
"description": "Kimi's K2 model",
|
"description": "Kimi's K2 model",
|
||||||
"updateArgs": {
|
"updateArgs": {
|
||||||
"context_window": 262144
|
"context_window": 262144,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -766,7 +829,8 @@
|
|||||||
"updateArgs": {
|
"updateArgs": {
|
||||||
"context_window": 256000,
|
"context_window": 256000,
|
||||||
"max_output_tokens": 16000,
|
"max_output_tokens": 16000,
|
||||||
"temperature": 1.0
|
"temperature": 1.0,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -776,7 +840,8 @@
|
|||||||
"description": "Kimi's latest coding model",
|
"description": "Kimi's latest coding model",
|
||||||
"isFeatured": true,
|
"isFeatured": true,
|
||||||
"updateArgs": {
|
"updateArgs": {
|
||||||
"context_window": 262144
|
"context_window": 262144,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -785,7 +850,8 @@
|
|||||||
"label": "DeepSeek Chat V3.1",
|
"label": "DeepSeek Chat V3.1",
|
||||||
"description": "DeepSeek V3.1 model",
|
"description": "DeepSeek V3.1 model",
|
||||||
"updateArgs": {
|
"updateArgs": {
|
||||||
"context_window": 128000
|
"context_window": 128000,
|
||||||
|
"parallel_tool_calls": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -794,7 +860,11 @@
|
|||||||
"label": "Gemini 3.1 Pro",
|
"label": "Gemini 3.1 Pro",
|
||||||
"description": "Google's latest and smartest model",
|
"description": "Google's latest and smartest model",
|
||||||
"isFeatured": true,
|
"isFeatured": true,
|
||||||
"updateArgs": { "context_window": 180000, "temperature": 1.0 }
|
"updateArgs": {
|
||||||
|
"context_window": 180000,
|
||||||
|
"temperature": 1.0,
|
||||||
|
"parallel_tool_calls": true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "gemini-3",
|
"id": "gemini-3",
|
||||||
@@ -802,7 +872,11 @@
|
|||||||
"label": "Gemini 3 Pro",
|
"label": "Gemini 3 Pro",
|
||||||
"description": "Google's smartest model",
|
"description": "Google's smartest model",
|
||||||
"isFeatured": true,
|
"isFeatured": true,
|
||||||
"updateArgs": { "context_window": 180000, "temperature": 1.0 }
|
"updateArgs": {
|
||||||
|
"context_window": 180000,
|
||||||
|
"temperature": 1.0,
|
||||||
|
"parallel_tool_calls": true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "gemini-3-flash",
|
"id": "gemini-3-flash",
|
||||||
@@ -810,55 +884,63 @@
|
|||||||
"label": "Gemini 3 Flash",
|
"label": "Gemini 3 Flash",
|
||||||
"description": "Google's fastest Gemini 3 model",
|
"description": "Google's fastest Gemini 3 model",
|
||||||
"isFeatured": true,
|
"isFeatured": true,
|
||||||
"updateArgs": { "context_window": 180000, "temperature": 1.0 }
|
"updateArgs": {
|
||||||
|
"context_window": 180000,
|
||||||
|
"temperature": 1.0,
|
||||||
|
"parallel_tool_calls": true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "gemini-flash",
|
"id": "gemini-flash",
|
||||||
"handle": "google_ai/gemini-2.5-flash",
|
"handle": "google_ai/gemini-2.5-flash",
|
||||||
"label": "Gemini 2.5 Flash",
|
"label": "Gemini 2.5 Flash",
|
||||||
"description": "Google's fastest model",
|
"description": "Google's fastest model",
|
||||||
"updateArgs": { "context_window": 180000 }
|
"updateArgs": { "context_window": 180000, "parallel_tool_calls": true }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "gemini-pro",
|
"id": "gemini-pro",
|
||||||
"handle": "google_ai/gemini-2.5-pro",
|
"handle": "google_ai/gemini-2.5-pro",
|
||||||
"label": "Gemini 2.5 Pro",
|
"label": "Gemini 2.5 Pro",
|
||||||
"description": "Google's last generation flagship model",
|
"description": "Google's last generation flagship model",
|
||||||
"updateArgs": { "context_window": 180000 }
|
"updateArgs": { "context_window": 180000, "parallel_tool_calls": true }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "gpt-4.1",
|
"id": "gpt-4.1",
|
||||||
"handle": "openai/gpt-4.1",
|
"handle": "openai/gpt-4.1",
|
||||||
"label": "GPT-4.1",
|
"label": "GPT-4.1",
|
||||||
"description": "OpenAI's most recent non-reasoner model",
|
"description": "OpenAI's most recent non-reasoner model",
|
||||||
"updateArgs": { "context_window": 1047576 }
|
"updateArgs": { "context_window": 1047576, "parallel_tool_calls": true }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "gpt-4.1-mini",
|
"id": "gpt-4.1-mini",
|
||||||
"handle": "openai/gpt-4.1-mini-2025-04-14",
|
"handle": "openai/gpt-4.1-mini-2025-04-14",
|
||||||
"label": "GPT-4.1-Mini",
|
"label": "GPT-4.1-Mini",
|
||||||
"description": "OpenAI's most recent non-reasoner model (mini version)",
|
"description": "OpenAI's most recent non-reasoner model (mini version)",
|
||||||
"updateArgs": { "context_window": 1047576 }
|
"updateArgs": { "context_window": 1047576, "parallel_tool_calls": true }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "gpt-4.1-nano",
|
"id": "gpt-4.1-nano",
|
||||||
"handle": "openai/gpt-4.1-nano-2025-04-14",
|
"handle": "openai/gpt-4.1-nano-2025-04-14",
|
||||||
"label": "GPT-4.1-Nano",
|
"label": "GPT-4.1-Nano",
|
||||||
"description": "OpenAI's most recent non-reasoner model (nano version)",
|
"description": "OpenAI's most recent non-reasoner model (nano version)",
|
||||||
"updateArgs": { "context_window": 1047576 }
|
"updateArgs": { "context_window": 1047576, "parallel_tool_calls": true }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "o4-mini",
|
"id": "o4-mini",
|
||||||
"handle": "openai/o4-mini",
|
"handle": "openai/o4-mini",
|
||||||
"label": "o4-mini",
|
"label": "o4-mini",
|
||||||
"description": "OpenAI's latest o-series reasoning model",
|
"description": "OpenAI's latest o-series reasoning model",
|
||||||
"updateArgs": { "context_window": 180000 }
|
"updateArgs": { "context_window": 180000, "parallel_tool_calls": true }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "gemini-3-vertex",
|
"id": "gemini-3-vertex",
|
||||||
"handle": "google_vertex/gemini-3-pro-preview",
|
"handle": "google_vertex/gemini-3-pro-preview",
|
||||||
"label": "Gemini 3 Pro",
|
"label": "Gemini 3 Pro",
|
||||||
"description": "Google's smartest Gemini 3 Pro model (via Vertex AI)",
|
"description": "Google's smartest Gemini 3 Pro model (via Vertex AI)",
|
||||||
"updateArgs": { "context_window": 180000, "temperature": 1.0 }
|
"updateArgs": {
|
||||||
|
"context_window": 180000,
|
||||||
|
"temperature": 1.0,
|
||||||
|
"parallel_tool_calls": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
81
src/tests/agent/model-preset-refresh.wiring.test.ts
Normal file
81
src/tests/agent/model-preset-refresh.wiring.test.ts
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
import { describe, expect, test } from "bun:test";
|
||||||
|
import { readFileSync } from "node:fs";
|
||||||
|
import { fileURLToPath } from "node:url";
|
||||||
|
|
||||||
|
describe("model preset refresh wiring", () => {
|
||||||
|
test("model.ts exports preset refresh helper", () => {
|
||||||
|
const path = fileURLToPath(
|
||||||
|
new URL("../../agent/model.ts", import.meta.url),
|
||||||
|
);
|
||||||
|
const source = readFileSync(path, "utf-8");
|
||||||
|
|
||||||
|
expect(source).toContain("export function getModelPresetUpdateForAgent(");
|
||||||
|
expect(source).toContain("OPENAI_CODEX_PROVIDER_NAME");
|
||||||
|
expect(source).toContain("getModelInfoForLlmConfig(modelHandle");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("modify.ts keeps direct updateArgs-driven model update flow", () => {
|
||||||
|
const path = fileURLToPath(
|
||||||
|
new URL("../../agent/modify.ts", import.meta.url),
|
||||||
|
);
|
||||||
|
const source = readFileSync(path, "utf-8");
|
||||||
|
|
||||||
|
const start = source.indexOf("export async function updateAgentLLMConfig(");
|
||||||
|
const end = source.indexOf(
|
||||||
|
"export interface SystemPromptUpdateResult",
|
||||||
|
start,
|
||||||
|
);
|
||||||
|
expect(start).toBeGreaterThanOrEqual(0);
|
||||||
|
expect(end).toBeGreaterThan(start);
|
||||||
|
const updateSegment = source.slice(start, end);
|
||||||
|
|
||||||
|
expect(updateSegment).toContain(
|
||||||
|
"buildModelSettings(modelHandle, updateArgs)",
|
||||||
|
);
|
||||||
|
expect(updateSegment).toContain("getModelContextWindow(modelHandle)");
|
||||||
|
expect(updateSegment).not.toContain(
|
||||||
|
"const currentAgent = await client.agents.retrieve(",
|
||||||
|
);
|
||||||
|
expect(source).not.toContain(
|
||||||
|
'hasUpdateArg(updateArgs, "parallel_tool_calls")',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("interactive resume flow refreshes model preset without explicit --model", () => {
|
||||||
|
const path = fileURLToPath(new URL("../../index.ts", import.meta.url));
|
||||||
|
const source = readFileSync(path, "utf-8");
|
||||||
|
|
||||||
|
expect(source).toContain("if (resuming)");
|
||||||
|
expect(source).toContain("getModelPresetUpdateForAgent");
|
||||||
|
expect(source).toContain(
|
||||||
|
"const presetRefresh = getModelPresetUpdateForAgent(agent)",
|
||||||
|
);
|
||||||
|
expect(source).toContain("resumeRefreshUpdateArgs");
|
||||||
|
expect(source).toContain("presetRefresh.updateArgs.max_output_tokens");
|
||||||
|
expect(source).toContain("presetRefresh.updateArgs.parallel_tool_calls");
|
||||||
|
expect(source).toContain("await updateAgentLLMConfig(");
|
||||||
|
expect(source).toContain("presetRefresh.modelHandle");
|
||||||
|
expect(source).not.toContain(
|
||||||
|
"await updateAgentLLMConfig(\n agent.id,\n presetRefresh.modelHandle,\n presetRefresh.updateArgs,",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("headless resume flow refreshes model preset without explicit --model", () => {
|
||||||
|
const path = fileURLToPath(new URL("../../headless.ts", import.meta.url));
|
||||||
|
const source = readFileSync(path, "utf-8");
|
||||||
|
|
||||||
|
expect(source).toContain("if (isResumingAgent)");
|
||||||
|
expect(source).toContain("getModelPresetUpdateForAgent");
|
||||||
|
expect(source).toContain(
|
||||||
|
"const presetRefresh = getModelPresetUpdateForAgent(agent)",
|
||||||
|
);
|
||||||
|
expect(source).toContain("resumeRefreshUpdateArgs");
|
||||||
|
expect(source).toContain("presetRefresh.updateArgs.max_output_tokens");
|
||||||
|
expect(source).toContain("presetRefresh.updateArgs.parallel_tool_calls");
|
||||||
|
expect(source).toContain("await updateAgentLLMConfig(");
|
||||||
|
expect(source).toContain("presetRefresh.modelHandle");
|
||||||
|
expect(source).not.toContain(
|
||||||
|
"await updateAgentLLMConfig(\n agent.id,\n presetRefresh.modelHandle,\n presetRefresh.updateArgs,",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user