From 32affaee02c07b36f75e4589ec32aca009aaa964 Mon Sep 17 00:00:00 2001 From: Peter Siska <63866+peschee@users.noreply.github.com> Date: Sun, 11 Jan 2026 15:56:43 +0000 Subject: [PATCH] feat: wire up model extraParams (temperature, maxTokens) to pi agent - Use resolveExtraParams() which was defined but unused - Create streamFn wrapper that injects config-driven params - Apply to both compaction and run sessions Config path: agents.defaults.models["provider/model"].params.temperature Example: agents.defaults.models["anthropic/claude-sonnet-4"].params.temperature = 0.7 agents.defaults.models["openai/gpt-4"].params.maxTokens = 8192 --- src/agents/pi-embedded-runner.ts | 88 ++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/src/agents/pi-embedded-runner.ts b/src/agents/pi-embedded-runner.ts index 3932f49fd..0315ceb4f 100644 --- a/src/agents/pi-embedded-runner.ts +++ b/src/agents/pi-embedded-runner.ts @@ -6,6 +6,7 @@ import { fileURLToPath } from "node:url"; import type { AgentMessage, AgentTool, + StreamFn, ThinkingLevel, } from "@mariozechner/pi-agent-core"; import type { @@ -13,7 +14,9 @@ import type { AssistantMessage, ImageContent, Model, + SimpleStreamOptions, } from "@mariozechner/pi-ai"; +import { streamSimple } from "@mariozechner/pi-ai"; import { createAgentSession, discoverAuthStorage, @@ -189,6 +192,73 @@ export function resolveExtraParams(params: { return extraParams; } +/** + * Create a wrapped streamFn that injects extra params (like temperature) from config. + * + * This wraps the default streamSimple with config-driven params for each model. + * Example config: + * agents.defaults.models["anthropic/claude-sonnet-4"].params.temperature = 0.7 + * + * @internal + */ +function createStreamFnWithExtraParams( + extraParams: Record | undefined, +): StreamFn | undefined { + if (!extraParams || Object.keys(extraParams).length === 0) { + return undefined; // No wrapper needed + } + + // Extract stream-related params (temperature, maxTokens, etc.) + const streamParams: Partial = {}; + if (typeof extraParams.temperature === "number") { + streamParams.temperature = extraParams.temperature; + } + if (typeof extraParams.maxTokens === "number") { + streamParams.maxTokens = extraParams.maxTokens; + } + + // If no stream params to inject, no wrapper needed + if (Object.keys(streamParams).length === 0) { + return undefined; + } + + log.debug(`creating streamFn wrapper with params: ${JSON.stringify(streamParams)}`); + + // Return a wrapper that merges our params with any passed options + const wrappedStreamFn: StreamFn = (model, context, options) => { + const mergedOptions: SimpleStreamOptions = { + ...streamParams, + ...options, // Caller options take precedence + }; + return streamSimple(model, context, mergedOptions); + }; + + return wrappedStreamFn; +} + +/** + * Apply extra params (like temperature) to an agent's streamFn. + * + * Call this after createAgentSession to wire up config-driven model params. + */ +function applyExtraParamsToAgent( + agent: { streamFn: StreamFn }, + cfg: ClawdbotConfig | undefined, + provider: string, + modelId: string, + thinkLevel?: string, +): void { + const extraParams = resolveExtraParams({ cfg, provider, modelId, thinkLevel }); + const wrappedStreamFn = createStreamFnWithExtraParams(extraParams); + + if (wrappedStreamFn) { + log.debug( + `applying extraParams to agent streamFn for ${provider}/${modelId}`, + ); + agent.streamFn = wrappedStreamFn; + } +} + // We configure context pruning per-session via a WeakMap registry keyed by the SessionManager instance. function resolvePiExtensionPath(id: string): string { @@ -1125,6 +1195,15 @@ export async function compactEmbeddedPiSession(params: { additionalExtensionPaths, })); + // Wire up config-driven model params (e.g., temperature) + applyExtraParamsToAgent( + session.agent, + params.config, + provider, + modelId, + params.thinkLevel, + ); + try { const prior = await sanitizeSessionHistory({ messages: session.messages, @@ -1520,6 +1599,15 @@ export async function runEmbeddedPiAgent(params: { additionalExtensionPaths, })); + // Wire up config-driven model params (e.g., temperature) + applyExtraParamsToAgent( + session.agent, + params.config, + provider, + modelId, + params.thinkLevel, + ); + try { const prior = await sanitizeSessionHistory({ messages: session.messages,