feat(ai,agent,coding-agent): add sessionId for provider session-based caching

- Add sessionId to StreamOptions for providers that support session-based caching
- OpenAI Codex provider uses sessionId for prompt_cache_key and routing headers
- Agent class now accepts and forwards sessionId to stream functions
- coding-agent passes session ID from SessionManager and updates on session changes
- Update ai package README with table of contents, OpenAI Codex OAuth docs, and env vars table
- Increase Codex instructions cache TTL from 15 minutes to 24 hours
- Add tests for sessionId forwarding in ai and agent packages
This commit is contained in:
Mario Zechner 2026-01-06 11:08:42 +01:00
parent 858c6bae8a
commit edb0da9611
14 changed files with 335 additions and 56 deletions

View file

@ -96,6 +96,7 @@ export const streamOpenAICodexResponses: StreamFunction<"openai-codex-responses"
model: model.id,
input: messages,
stream: true,
prompt_cache_key: options?.sessionId,
};
if (options?.maxTokens) {
@ -132,7 +133,7 @@ export const streamOpenAICodexResponses: StreamFunction<"openai-codex-responses"
const transformedBody = await transformRequestBody(params, codexOptions, systemPrompt);
const reasoningEffort = transformedBody.reasoning?.effort ?? null;
const headers = createCodexHeaders(model.headers, accountId, apiKey, transformedBody.prompt_cache_key);
const headers = createCodexHeaders(model.headers, accountId, apiKey, options?.sessionId);
logCodexDebug("codex request", {
url,
model: params.model,

View file

@ -115,7 +115,7 @@ export async function getCodexInstructions(normalizedModel = "gpt-5.1-codex"): P
cachedTimestamp = metadata.lastChecked;
}
const CACHE_TTL_MS = 15 * 60 * 1000;
const CACHE_TTL_MS = 24 * 60 * 60 * 1000;
if (cachedTimestamp && Date.now() - cachedTimestamp < CACHE_TTL_MS && existsSync(cacheFile)) {
return readFileSync(cacheFile, "utf8");
}
@ -183,45 +183,3 @@ export async function getCodexInstructions(normalizedModel = "gpt-5.1-codex"): P
throw new Error(`No cached Codex instructions available for ${modelFamily}`);
}
}
export const TOOL_REMAP_MESSAGE = `<user_instructions priority="0">
<environment_override priority="0">
YOU ARE IN A DIFFERENT ENVIRONMENT. These instructions override ALL previous tool references.
</environment_override>
<tool_replacements priority="0">
<critical_rule priority="0">
APPLY_PATCH DOES NOT EXIST USE "edit" INSTEAD
- NEVER use: apply_patch, applyPatch
- ALWAYS use: edit tool for ALL file modifications
</critical_rule>
<critical_rule priority="0">
UPDATE_PLAN DOES NOT EXIST
- NEVER use: update_plan, updatePlan, read_plan, readPlan, todowrite, todoread
- There is no plan tool in this environment
</critical_rule>
</tool_replacements>
<available_tools priority="0">
File Operations:
read - Read file contents
edit - Modify files with exact find/replace
write - Create or overwrite files
Search/Discovery:
grep - Search file contents for patterns (read-only)
find - Find files by glob pattern (read-only)
ls - List directory contents (read-only)
Execution:
bash - Run shell commands
</available_tools>
<verification_checklist priority="0">
Before file modifications:
1. Am I using "edit" NOT "apply_patch"?
2. Am I avoiding plan tools entirely?
3. Am I using only the tools listed above?
</verification_checklist>
</user_instructions>`;

View file

@ -35,6 +35,7 @@ export interface RequestBody {
};
include?: string[];
prompt_cache_key?: string;
prompt_cache_retention?: "in_memory" | "24h";
max_output_tokens?: number;
max_completion_tokens?: number;
[key: string]: unknown;

View file

@ -177,6 +177,7 @@ function mapOptionsForApi<TApi extends Api>(
maxTokens: options?.maxTokens || Math.min(model.maxTokens, 32000),
signal: options?.signal,
apiKey: apiKey || options?.apiKey,
sessionId: options?.sessionId,
};
// Helper to clamp xhigh to high for providers that don't support it

View file

@ -64,6 +64,12 @@ export interface StreamOptions {
maxTokens?: number;
signal?: AbortSignal;
apiKey?: string;
/**
* Optional session identifier for providers that support session-based caching.
* Providers can use this to enable prompt caching, request routing, or other
* session-aware features. Ignored by providers that don't support it.
*/
sessionId?: string;
}
// Unified options with reasoning passed to streamSimple() and completeSimple()