Skip to content
Closed
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
6 changes: 1 addition & 5 deletions scripts/generate-jawcode-metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,6 @@ const sourcePath = process.env.JAWCODE_MODELS_JSON
const outPath = process.env.JAWCODE_METADATA_OUT
? resolve(process.env.JAWCODE_METADATA_OUT)
: resolve(process.cwd(), "src/generated/jawcode-model-metadata.ts");
const CONTEXT_WINDOW_OVERRIDES: Record<string, number> = {
"anthropic/claude-sonnet-4-6": 200_000,
"anthropic/claude-sonnet-4-6[1m]": 200_000,
};

if (!existsSync(sourcePath)) {
throw new Error(`jawcode models.json not found: ${sourcePath}`);
Expand Down Expand Up @@ -91,7 +87,7 @@ for (const provider of allowedProviders) {
.sort(([a], [b]) => a.localeCompare(b))
.map(([id, model]) => compactRow([
id,
CONTEXT_WINDOW_OVERRIDES[`${provider}/${id}`] ?? model.contextWindow,
model.contextWindow,
model.maxTokens,
Array.isArray(model.input) ? model.input.join(",") : undefined,
model.reasoning === undefined ? undefined : (model.reasoning ? 1 : 0),
Expand Down
25 changes: 20 additions & 5 deletions src/claude/agents-inject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { lstatSync, mkdirSync, readdirSync, readFileSync, renameSync, unlinkSync
import { join } from "node:path";
import type { OcxConfig } from "../types";
import { claudeCodeAlias, claudeCodeNativeAlias } from "./alias";
import { resolveAutoContext, stripOneMillionMarker, withOneMillionMarker } from "./context-windows";
import { AUTO_CONTEXT_OFF, shouldMarkOneMillion, stripOneMillionMarker, withOneMillionMarker } from "./context-windows";
import { claudeConfigDir } from "./gateway-cache";
import { DEFAULT_SUBAGENT_MODELS, hasOwnProvider } from "../config";
import { effectiveBlockedSkillNames, resolveInboundModel } from "./inbound";
Expand Down Expand Up @@ -55,6 +55,23 @@ function pickerDefaultModel(configDir: string): string | null {
}
}

/**
* Generated subagents cannot rely on parent auto-context compaction before
* routed requests reach the real model limit.
*/
function withSubagentContextMarker(selector: string, windows: Record<string, number>): string {
const bare = stripOneMillionMarker(selector);
const wasMarked = selector !== bare;
const canonicalExact = wasMarked ? `${bare}[1m]` : selector;
const authoritativeWindow = windows[selector] ?? windows[canonicalExact] ?? windows[bare];
if (typeof authoritativeWindow === "number" && authoritativeWindow > 0) {
return shouldMarkOneMillion(authoritativeWindow, AUTO_CONTEXT_OFF)
? (withOneMillionMarker(selector, windows) ?? selector)
: bare;
}
return wasMarked ? selector : bare;
}

/** Roster entry -> alias + display parts. Entries are bare native slugs or "provider/id".
* Codex-facing encoded ids (`provider/vendor-model`) decode to the native slash id first
* so the alias joins the raw-native context-window map (context-windows.ts). */
Expand All @@ -72,7 +89,6 @@ function entryParts(entry: string, config: OcxConfig): { alias: string; id: stri
}

export function buildClaudeAgentDefs(config: OcxConfig, windows: Record<string, number>, configDir = claudeConfigDir()): ClaudeAgentDef[] {
const auto = resolveAutoContext(config.claudeCode);
const blockedSkills = effectiveBlockedSkillNames(config.claudeCode);
const blockedSkillsFor = (model: string): readonly string[] => {
const unmarked = stripOneMillionMarker(model);
Expand All @@ -87,8 +103,7 @@ export function buildClaudeAgentDefs(config: OcxConfig, windows: Record<string,
const coveredModels = new Set<string>();

const push = (name: string, alias: string, description: string) => {
// Effective model value: [1m] marking follows the same predicate as env slots.
const model = withOneMillionMarker(alias, windows, auto) ?? alias;
const model = withSubagentContextMarker(alias, windows);
const bare = alias.toLowerCase();
if (coveredModels.has(bare)) return;
coveredModels.add(bare);
Expand Down Expand Up @@ -120,7 +135,7 @@ export function buildClaudeAgentDefs(config: OcxConfig, windows: Record<string,
// the next launch sync — documented limit. No resolvable default -> no self def.
const selfModel = pickerDefaultModel(configDir) ?? (config.claudeCode?.model?.trim() || null);
if (selfModel) {
const marked = withOneMillionMarker(selfModel, windows, auto) ?? selfModel;
const marked = withSubagentContextMarker(selfModel, windows);
defs.push({
file: `${OWNED_PREFIX}self.md`,
name: `${OWNED_PREFIX}self`,
Expand Down
Loading
Loading