Skip to content
Closed
Show file tree
Hide file tree
Changes from 3 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
24 changes: 19 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,22 @@ 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 canonicalExact = selector === bare ? selector : `${bare}[1m]`;
const exactWindow = windows[selector] ?? windows[canonicalExact];
if (typeof exactWindow === "number" && exactWindow > 0) {
return shouldMarkOneMillion(exactWindow, AUTO_CONTEXT_OFF)
? (withOneMillionMarker(selector, windows) ?? selector)
: stripOneMillionMarker(selector);
}
return withOneMillionMarker(bare, windows) ?? bare;
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
}

/** 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 +88,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 +102,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 +134,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