createAgentSession Zusammenbau
createAgentSession ist der Kern-Eingang des SDK. Es setzt aus AuthStorage, ModelRegistry, SettingsManager, SessionManager, ResourceLoader als externen Services, plus Werkzeugdefinitionen und Extension-Runner, ein verwendbares AgentSession zusammen. main.ts ruft es nicht direkt auf, sondern geht über createAgentSessionRuntime zu createAgentSessionServices, aber ein SDK-Aufrufer (der pi in ein anderes Programm einbettet) nutzt diese Funktion direkt.
Verantwortung
- Service-Auflösung: Jeder externe Service kann übergeben oder automatisch erzeugt werden, der default-Pfad basiert auf
agentDir(~/.pi/agent). Siehepackages/coding-agent/src/core/sdk.ts:193-211. - Modell-Wiederherstellung: Wenn Session-Daten vorhanden sind, wird
modelaus dem session-Header geholt, sonst aus den settings als default; wenn das Modell nicht wiederherstellbar ist, wirdmodelFallbackMessagegesetzt. Siehepackages/coding-agent/src/core/sdk.ts:214-248. - thinking-Level-Klammerung: thinking level wird aus session oder settings geholt, dann von
clampThinkingLevelauf den Modell-Fähigkeitsbereich begrenzt. Siehepackages/coding-agent/src/core/sdk.ts:250-269. - stream-Funktion-Injektion:
streamFndesAgentruft nicht direktstreamSimpleauf, sondern holt zuerst übermodelRegistry.getApiKeyAndHeadersdie Auth und fügt die Telemetrie-Header vongetAttributionHeadershinzu. Siehepackages/coding-agent/src/core/sdk.ts:328-346. - convertToLlm-Wrapper: Wenn
blockImagesaktiv ist, wird der gesamte ImageContent durch Platzhaltertext ersetzt, dabei wird settings dynamisch gelesen, damit Änderungen während der Session greifen. Siehepackages/coding-agent/src/core/sdk.ts:282-316. - Attribution-Header: OpenRouter und Cloudflare bekommen proprietäre HTTP-Header für die Zuordnung. Siehe
packages/coding-agent/src/core/sdk.ts:128-156.
Entwurfsmotivation
Warum nicht den Aufrufer selbst new Agent und dann new AgentSession machen lassen? Weil die Zusammenbau-Schritte mehr als zehn Services mit gegenseitigen Abhängigkeiten berühren: auth entscheidet, ob model verfügbar ist; model entscheidet den Bereich des thinking level; settings entscheiden retry/transport/steering; der resource loader lädt Extensions und injiziert sie in extensionRunnerRef. Das dem Aufrufer aufzubürden hieße, jeder müsste die gleichen Fehler nochmal machen. createAgentSession konzentriert die Zusammenbau-Regeln in einer Funktion, der SDK-Aufrufer muss nur cwd und (optional) model übergeben.
getAttributionHeaders ist deshalb separat herausgezogen, weil verschiedene Provider unterschiedliche Header wollen: OpenRouter will HTTP-Referer + X-OpenRouter-*, Cloudflare will User-Agent. Zentral an einer Stelle zu sammeln vermeidet, dass es sich über den stream-Pfad verstreut.
Wichtige Dateien
packages/coding-agent/src/core/sdk.ts:33-80—CreateAgentSessionOptions, alle Zusammenbau-Parameter (cwd, authStorage, modelRegistry, model, tools, scopedModels, customTools, resourceLoader, sessionManager, settingsManager).packages/coding-agent/src/core/sdk.ts:82-90—CreateAgentSessionResult:session+extensionsResult+ optionalesmodelFallbackMessage.packages/coding-agent/src/core/sdk.ts:124-126—getDefaultAgentDir, default globales Konfigurationsverzeichnis.packages/coding-agent/src/core/sdk.ts:128-156—getAttributionHeaders, provider-proprietäre Telemetrie-Header.packages/coding-agent/src/core/sdk.ts:193-211— Anfang voncreateAgentSession: Service-Auflösung und Defaults.packages/coding-agent/src/core/sdk.ts:320-376—new Agent({...})-Konstruktion, injiziertstreamFn,onPayload,onResponse,transformContext,steeringMode,transportund alle anderen Runtime-Parameter.packages/coding-agent/src/core/sdk.ts:392-413— Am Endenew AgentSession({...})und Rückgabe vonCreateAgentSessionResult.packages/coding-agent/src/core/sdk.ts:108-120— Re-export der Werkzeugfabriken, SDK-Aufrufer können direktcreateCodingToolsusw. holen.
An der streamFn-Injektion sieht man, wie Auth-Versagen kurzschließt und Attribution-Header zusammengeführt werden:
// packages/coding-agent/src/core/sdk.ts:328-346
streamFn: async (model, context, options) => {
const auth = await modelRegistry.getApiKeyAndHeaders(model);
if (!auth.ok) {
throw new Error(auth.error);
}
const providerRetrySettings = settingsManager.getProviderRetrySettings();
const attributionHeaders = getAttributionHeaders(model, settingsManager);
return streamSimple(model, context, {
...options,
apiKey: auth.apiKey,
timeoutMs: options?.timeoutMs ?? providerRetrySettings.timeoutMs,
// ...
headers:
attributionHeaders || auth.headers || options?.headers
? { ...attributionHeaders, ...auth.headers, ...options?.headers }
: undefined,
});
},Die convertToLlm-Wrapper-Schicht ersetzt bei aktivem blockImages Bilder durch Textplatzhalter und dedupliziert aufeinanderfolgende Platzhalter:
// packages/coding-agent/src/core/sdk.ts:282-298
const convertToLlmWithBlockImages = (messages: AgentMessage[]): Message[] => {
const converted = convertToLlm(messages);
if (!settingsManager.getBlockImages()) {
return converted;
}
return converted.map((msg) => {
if (msg.role === "user" || msg.role === "toolResult") {
const content = msg.content;
if (Array.isArray(content)) {
const hasImages = content.some((c) => c.type === "image");
if (hasImages) {
const filteredContent = content
.map((c) =>
c.type === "image" ? { type: "text" as const, text: "Image reading is disabled." } : c,
)
// ... dedup ...Datenfluss
Reihenfolge des Zusammenbaus:
Grenzen und Fehler
- Modell nicht wiederherstellbar:
modelFallbackMessagesagt sowohl "Modell konnte nicht wiederhergestellt werden" als auch "keine Modelle konfiguriert", beides wird zurückgegeben, die UI entscheidet, wie es angezeigt wird, siehepackages/coding-agent/src/core/sdk.ts:243-247. - Ohne model thinking off:
if (!model) thinkingLevel = "off", um thinking-Parameter an ein leeres Modell zu vermeiden. - Session vorhanden aber ohne thinking-Eintrag: Beim Wiederherstellen wird ein
appendThinkingLevelChangeergänzt, damit ein späteres fork/resume den Zustand bekommt, siehepackages/coding-agent/src/core/sdk.ts:378-390. - Extension transformContext: Wenn
extensionRunnerRef.currentnicht existiert, wird direkt das Original messages zurückgegeben, ohne zu werfen, damit es ohne gebundene Extension weiterläuft.
Zusammenfassung
createAgentSession konzentriert die Zusammenbau-Regeln von mehr als zehn Services in einer Funktion, der SDK-Aufrufer muss nur cwd und optionales model übergeben. Zusammenbau-Details nach unten siehe AgentSession Orchestrierungsschicht; die Werkzeugfabriken siehe Werkzeugset read/bash/edit/write/grep/find/ls; die Nachrichtenkonvertierung siehe Nachrichtentypen und convertToLlm.