Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions apps/open-swe/src/__tests__/tokens.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,17 @@ describe("calculateConversationHistoryTokenCount", () => {

expect(result).toBe(expectedResult);
});

it("should handle 1M token limit", async () => {
const messages = [
new HumanMessage({
content: "A".repeat(4 * 1_000_000), // 1M tokens worth of content
}),
];

const result = calculateConversationHistoryTokenCount(messages);
expect(result).toBe(1_000_000);
});
});

describe("getMessagesSinceLastSummary", () => {
Expand Down
4 changes: 2 additions & 2 deletions apps/open-swe/src/utils/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import {
import { getMessageContentString } from "@openswe/shared/messages";
import { traceable } from "langsmith/traceable";

// After 80k tokens, summarize the conversation history.
export const MAX_INTERNAL_TOKENS = 80_000;
// After 1M tokens, summarize the conversation history.
export const MAX_INTERNAL_TOKENS = 1_000_000; // Updated to support 1M tokens

export function calculateConversationHistoryTokenCount(
messages: BaseMessage[],
Expand Down
5 changes: 5 additions & 0 deletions packages/shared/src/open-swe/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ export const MODEL_OPTIONS = [
// label: "Claude Opus 4 (Extended Thinking)",
// value: "anthropic:extended-thinking:claude-opus-4-0",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#833 specifically creating the new model to do a function lookup instead of reliance on the static implementation

// Canonical metadata for all supported models

export type ModelFamily = "Anthropic Claude" | "OpenAI GPT" | "Google Gemini" | "DeepSeek" | "Qwen" | "Meta Llama" | "Grok" | "Other";

export interface ModelMetadata {
 label: string;
 modelName: string;
 modelFamily: ModelFamily;
 maxInternalTokens: number | undefined;
 contextWindow: number;
 notableFeatures?: string[];
 costPerMillionTokens?: {
   input: number;
   output: number;
 };
}

export const MODEL_METADATA: Record<string, ModelMetadata> = {
 "anthropic:claude-sonnet-4-1m": {
   label: "Claude Sonnet 4 (1M Context)",
   modelName: "anthropic:claude-sonnet-4-1m",
   modelFamily: "Anthropic Claude",
   maxInternalTokens: 1_000_000,
   contextWindow: 1_000_000,
   notableFeatures: ["1M token context", "Best for long conversations"],
   costPerMillionTokens: { input: 3.0, output: 15.0 },
 },
 "anthropic:claude-opus-4-1": {
   label: "Claude Opus 4.1",
   modelName: "anthropic:claude-opus-4-1",
   modelFamily: "Anthropic Claude",
   maxInternalTokens: 200_000,
   contextWindow: 200_000,
   notableFeatures: ["High accuracy", "Fast output"],
   costPerMillionTokens: { input: 15.0, output: 75.0 },
 },
 "openai:gpt-4o": {
   label: "GPT-4o",
   modelName: "openai:gpt-4o",
   modelFamily: "OpenAI GPT",
   maxInternalTokens: 128_000,
   contextWindow: 128_000,
   notableFeatures: ["Multimodal", "Fast inference"],
   costPerMillionTokens: { input: 2.5, output: 10.0 },
 },
 "google-genai:gemini-2.5-pro": {
   label: "Gemini 2.5 Pro",
   modelName: "google-genai:gemini-2.5-pro",
   modelFamily: "Google Gemini",
   maxInternalTokens: undefined,
   contextWindow: 1_048_576,
   notableFeatures: ["Multimodal", "1M token context window", "Integrated with Google products"],
   costPerMillionTokens: { input: 2.5, output: 15.0 },
 },
 "deepseek:v3.1": {
   label: "DeepSeek V3.1",
   modelName: "deepseek:v3.1",
   modelFamily: "DeepSeek",
   maxInternalTokens: 671_000_000,
   contextWindow: 128_000,
   notableFeatures: ["High-performance MoE", "Specialized in coding and reasoning"],
   costPerMillionTokens: { input: 0.14, output: 0.28 },
 },
 "qwen:3-1m": {
   label: "Qwen 3 (1M Context)",
   modelName: "qwen:3-1m",
   modelFamily: "Qwen",
   maxInternalTokens: 1_000_000,
   contextWindow: 1_000_000,
   notableFeatures: ["Ultra-long context", "Multilingual", "MoE architecture"],
   costPerMillionTokens: { input: 0.20, output: 0.60 },
 },
 "meta:llama-4-scout": {
   label: "Llama 4 Scout",
   modelName: "meta:llama-4-scout",
   modelFamily: "Meta Llama",
   maxInternalTokens: 109_000_000_000,
   contextWindow: 10_000_000,
   notableFeatures: ["10M context window", "Multimodal (text, image, video)", "Open-weight"],
   costPerMillionTokens: { input: 0.11, output: 0.34 },
 },
 "grok:4": {
   label: "Grok 4",
   modelName: "grok:4",
   modelFamily: "Grok",
   maxInternalTokens: undefined,
   contextWindow: 256_000,
   notableFeatures: ["Multimodal", "Real-time web searches", "Advanced reasoning"],
   costPerMillionTokens: { input: 3.0, output: 15.0 },
 },
 // Add other models here
};

// Utility to get model attributes
export function getMaxInternalTokensForModel(modelName: string): number {
 const model = MODEL_METADATA[modelName];
 if (!model) {
   throw new Error(`Unknown model: ${modelName}`);
 }
 return model.maxInternalTokens ?? model.contextWindow;
}

export function getModelMetadata(modelName: string): ModelMetadata {
 const model = MODEL_METADATA[modelName];
 if (!model) {
   throw new Error(`Unknown model: ${modelName}`);
 }
 return model;
}

// },
{
label: "Claude Sonnet 4 (1M Context)",
value: "anthropic:claude-sonnet-4",
betaHeader: "context-1m-2025-08-07", // Add the beta header here
},
{
label: "Claude Sonnet 4",
value: "anthropic:claude-sonnet-4-0",
Expand Down