@@ -426,7 +426,7 @@ export class AgentSession {
|
||||
headers?: Record<string, string>;
|
||||
env?: Record<string, string>;
|
||||
}> {
|
||||
if (this.agent.streamFn === streamSimple) {
|
||||
if (this.agent.streamFunction === streamSimple) {
|
||||
return this._getRequiredRequestAuth(model);
|
||||
}
|
||||
|
||||
@@ -1836,7 +1836,7 @@ export class AgentSession {
|
||||
customInstructions,
|
||||
this._compactionAbortController.signal,
|
||||
this.thinkingLevel,
|
||||
this.agent.streamFn,
|
||||
this.agent.streamFunction,
|
||||
env,
|
||||
);
|
||||
summary = result.summary;
|
||||
@@ -2037,7 +2037,7 @@ export class AgentSession {
|
||||
let apiKey: string | undefined;
|
||||
let headers: Record<string, string> | undefined;
|
||||
let env: Record<string, string> | undefined;
|
||||
if (this.agent.streamFn === streamSimple) {
|
||||
if (this.agent.streamFunction === streamSimple) {
|
||||
const authResult = await this._modelRuntime.getAuth(this.model);
|
||||
if (!authResult?.auth.apiKey) return false;
|
||||
apiKey = authResult.auth.apiKey;
|
||||
@@ -2112,7 +2112,7 @@ export class AgentSession {
|
||||
undefined,
|
||||
this._autoCompactionAbortController.signal,
|
||||
this.thinkingLevel,
|
||||
this.agent.streamFn,
|
||||
this.agent.streamFunction,
|
||||
env,
|
||||
);
|
||||
summary = compactResult.summary;
|
||||
@@ -2933,7 +2933,7 @@ export class AgentSession {
|
||||
customInstructions,
|
||||
replaceInstructions,
|
||||
reserveTokens: branchSummarySettings.reserveTokens,
|
||||
streamFn: this.agent.streamFn,
|
||||
streamFn: this.agent.streamFunction,
|
||||
});
|
||||
if (result.aborted) {
|
||||
return { cancelled: true, aborted: true };
|
||||
|
||||
@@ -294,7 +294,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
||||
tools: [],
|
||||
},
|
||||
convertToLlm: convertToLlmWithBlockImages,
|
||||
streamFn: async (model, context, options) => {
|
||||
streamFunction: async (model, context, options) => {
|
||||
const providerRetrySettings = settingsManager.getProviderRetrySettings();
|
||||
const httpIdleTimeoutMs = settingsManager.getHttpIdleTimeoutMs();
|
||||
// SDKs treat timeout=0 as 0ms (immediate timeout), not "no timeout".
|
||||
|
||||
@@ -3,7 +3,7 @@ import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { Agent } from "@earendil-works/pi-agent-core";
|
||||
import { type AssistantMessage, createAssistantMessageEventStream, fauxAssistantMessage } from "@earendil-works/pi-ai";
|
||||
import { getModel } from "@earendil-works/pi-ai/compat";
|
||||
import { getModel, streamSimple } from "@earendil-works/pi-ai/compat";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { AgentSession } from "../src/core/agent-session.ts";
|
||||
import { AuthStorage } from "../src/core/auth-storage.ts";
|
||||
@@ -21,10 +21,10 @@ describe("AgentSession auto-compaction queue resume", () => {
|
||||
beforeEach(async () => {
|
||||
tempDir = join(tmpdir(), `pi-auto-compaction-queue-${Date.now()}`);
|
||||
mkdirSync(tempDir, { recursive: true });
|
||||
vi.useFakeTimers();
|
||||
|
||||
const model = getModel("anthropic", "claude-sonnet-4-5")!;
|
||||
const agent = new Agent({
|
||||
streamFunction: streamSimple,
|
||||
initialState: {
|
||||
model,
|
||||
systemPrompt: "Test",
|
||||
@@ -50,7 +50,6 @@ describe("AgentSession auto-compaction queue resume", () => {
|
||||
|
||||
afterEach(() => {
|
||||
session.dispose();
|
||||
vi.useRealTimers();
|
||||
vi.restoreAllMocks();
|
||||
if (tempDir && existsSync(tempDir)) {
|
||||
rmSync(tempDir, { recursive: true });
|
||||
@@ -84,9 +83,9 @@ describe("AgentSession auto-compaction queue resume", () => {
|
||||
timestamp: now - 500,
|
||||
});
|
||||
session.agent.state.messages = sessionManager.buildSessionContext().messages;
|
||||
session.agent.streamFn = (summaryModel) => {
|
||||
session.agent.streamFunction = (summaryModel) => {
|
||||
const stream = createAssistantMessageEventStream();
|
||||
queueMicrotask(() => {
|
||||
void Promise.resolve().then(() => {
|
||||
stream.push({
|
||||
type: "done",
|
||||
reason: "stop",
|
||||
|
||||
@@ -12,7 +12,7 @@ import { existsSync, mkdirSync, rmSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { Agent } from "@earendil-works/pi-agent-core";
|
||||
import { getModel } from "@earendil-works/pi-ai/compat";
|
||||
import { getModel, streamSimple } from "@earendil-works/pi-ai/compat";
|
||||
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
||||
import { AgentSession, type AgentSessionEvent } from "../src/core/agent-session.ts";
|
||||
import { AuthStorage } from "../src/core/auth-storage.ts";
|
||||
@@ -49,6 +49,7 @@ describe.skipIf(!API_KEY)("AgentSession compaction e2e", () => {
|
||||
const model = getModel("anthropic", "claude-sonnet-4-5")!;
|
||||
const agent = new Agent({
|
||||
getApiKey: () => API_KEY,
|
||||
streamFunction: streamSimple,
|
||||
initialState: {
|
||||
model,
|
||||
systemPrompt: "You are a helpful assistant. Be concise.",
|
||||
|
||||
@@ -90,7 +90,7 @@ describe("AgentSession concurrent prompt guard", () => {
|
||||
systemPrompt: "Test",
|
||||
tools: [],
|
||||
},
|
||||
streamFn: (_model, _context, options) => {
|
||||
streamFunction: (_model, _context, options) => {
|
||||
abortSignal = options?.signal;
|
||||
const stream = new MockAssistantStream();
|
||||
queueMicrotask(() => {
|
||||
@@ -195,7 +195,7 @@ describe("AgentSession concurrent prompt guard", () => {
|
||||
systemPrompt: "Test",
|
||||
tools: [],
|
||||
},
|
||||
streamFn: (_model, context, options) => {
|
||||
streamFunction: (_model, context, options) => {
|
||||
abortSignal = options?.signal;
|
||||
const stream = new MockAssistantStream();
|
||||
queueMicrotask(() => {
|
||||
@@ -301,7 +301,7 @@ describe("AgentSession concurrent prompt guard", () => {
|
||||
systemPrompt: "Test",
|
||||
tools: [],
|
||||
},
|
||||
streamFn: () => {
|
||||
streamFunction: () => {
|
||||
const stream = new MockAssistantStream();
|
||||
queueMicrotask(() => {
|
||||
stream.push({ type: "start", partial: createAssistantMessage("") });
|
||||
@@ -362,7 +362,7 @@ describe("AgentSession concurrent prompt guard", () => {
|
||||
systemPrompt: "Test",
|
||||
tools: [tool],
|
||||
},
|
||||
streamFn: async (_model, context) => {
|
||||
streamFunction: async (_model, context) => {
|
||||
const stream = new MockAssistantStream();
|
||||
queueMicrotask(() => {
|
||||
const toolResultCount = context.messages.filter((message) => message.role === "toolResult").length;
|
||||
@@ -508,7 +508,7 @@ describe("AgentSession concurrent prompt guard", () => {
|
||||
systemPrompt: "Test",
|
||||
tools: [tool],
|
||||
},
|
||||
streamFn: async (_model, context) => {
|
||||
streamFunction: async (_model, context) => {
|
||||
const stream = new MockAssistantStream();
|
||||
queueMicrotask(() => {
|
||||
const hasToolResult = context.messages.some((message) => message.role === "toolResult");
|
||||
|
||||
@@ -84,7 +84,7 @@ describe("AgentSession dynamic provider registration", () => {
|
||||
session: Awaited<ReturnType<typeof createSession>>,
|
||||
): Promise<string | undefined> {
|
||||
let baseUrl: string | undefined;
|
||||
session.agent.streamFn = async (model) => {
|
||||
session.agent.streamFunction = async (model) => {
|
||||
baseUrl = model.baseUrl;
|
||||
throw new Error("stop");
|
||||
};
|
||||
|
||||
@@ -82,7 +82,7 @@ describe("AgentSession retry", () => {
|
||||
const agent = new Agent({
|
||||
getApiKey: () => "test-key",
|
||||
initialState: { model, systemPrompt: "Test", tools: [] },
|
||||
streamFn: () => {
|
||||
streamFunction: () => {
|
||||
callCount++;
|
||||
const stream = new MockAssistantStream();
|
||||
queueMicrotask(() => {
|
||||
@@ -203,7 +203,7 @@ describe("AgentSession retry", () => {
|
||||
const agent = new Agent({
|
||||
getApiKey: () => "test-key",
|
||||
initialState: { model, systemPrompt: "Test", tools: [] },
|
||||
streamFn,
|
||||
streamFunction: streamFn,
|
||||
});
|
||||
const sessionManager = SessionManager.inMemory();
|
||||
const settingsManager = SettingsManager.create(tempDir, tempDir);
|
||||
@@ -255,7 +255,7 @@ describe("AgentSession retry", () => {
|
||||
const agent = new Agent({
|
||||
getApiKey: () => "test-key",
|
||||
initialState: { model, systemPrompt: "Test", tools: [] },
|
||||
streamFn: () => {
|
||||
streamFunction: () => {
|
||||
callCount++;
|
||||
const stream = new MockAssistantStream();
|
||||
queueMicrotask(() => {
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
import { Agent } from "@earendil-works/pi-agent-core";
|
||||
import { type AssistantMessage, getModel, type ToolResultMessage, type Usage } from "@earendil-works/pi-ai/compat";
|
||||
import {
|
||||
type AssistantMessage,
|
||||
getModel,
|
||||
streamSimple,
|
||||
type ToolResultMessage,
|
||||
type Usage,
|
||||
} from "@earendil-works/pi-ai/compat";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { AgentSession } from "../src/core/agent-session.ts";
|
||||
import { AuthStorage } from "../src/core/auth-storage.ts";
|
||||
@@ -69,6 +75,7 @@ async function createSession() {
|
||||
const session = new AgentSession({
|
||||
agent: new Agent({
|
||||
getApiKey: () => "test-key",
|
||||
streamFunction: streamSimple,
|
||||
initialState: {
|
||||
model,
|
||||
systemPrompt: "You are a helpful assistant.",
|
||||
|
||||
@@ -7,7 +7,7 @@ import { existsSync, mkdirSync, rmSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { Agent } from "@earendil-works/pi-agent-core";
|
||||
import { getModel } from "@earendil-works/pi-ai/compat";
|
||||
import { getModel, streamSimple } from "@earendil-works/pi-ai/compat";
|
||||
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
||||
import { AgentSession } from "../src/core/agent-session.ts";
|
||||
import { AuthStorage } from "../src/core/auth-storage.ts";
|
||||
@@ -89,6 +89,7 @@ describe.skipIf(!API_KEY)("Compaction extensions", () => {
|
||||
const model = getModel("anthropic", "claude-sonnet-4-5")!;
|
||||
const agent = new Agent({
|
||||
getApiKey: () => API_KEY,
|
||||
streamFunction: streamSimple,
|
||||
initialState: {
|
||||
model,
|
||||
systemPrompt: "You are a helpful assistant. Be concise.",
|
||||
|
||||
@@ -114,7 +114,7 @@ async function createRuntimeHost(options: { withAuth: boolean; responseDelayMs:
|
||||
systemPrompt: "Test",
|
||||
tools: [],
|
||||
},
|
||||
streamFn: (_model, _context, _options) => {
|
||||
streamFunction: (_model, _context, _options) => {
|
||||
const stream = new MockAssistantStream();
|
||||
queueMicrotask(() => {
|
||||
stream.push({ type: "start", partial: createAssistantMessage("") });
|
||||
|
||||
@@ -126,7 +126,7 @@ describe("createAgentSession provider attribution headers", () => {
|
||||
});
|
||||
|
||||
try {
|
||||
const stream = await session.agent.streamFn(
|
||||
const stream = await session.agent.streamFunction(
|
||||
model,
|
||||
{ messages: [] },
|
||||
{
|
||||
|
||||
@@ -114,7 +114,7 @@ describe("createAgentSession stream options", () => {
|
||||
});
|
||||
|
||||
try {
|
||||
const stream = await session.agent.streamFn(model, { messages: [] }, requestOptions);
|
||||
const stream = await session.agent.streamFunction(model, { messages: [] }, requestOptions);
|
||||
await stream.result();
|
||||
return capturedOptions;
|
||||
} finally {
|
||||
|
||||
@@ -49,7 +49,7 @@ function createAssistant(
|
||||
|
||||
function useSummaryStreamFn(harness: Harness, summary: string): () => number {
|
||||
let callCount = 0;
|
||||
harness.session.agent.streamFn = (model) => {
|
||||
harness.session.agent.streamFunction = (model) => {
|
||||
callCount++;
|
||||
const stream = createAssistantMessageEventStream();
|
||||
queueMicrotask(() => {
|
||||
|
||||
@@ -14,7 +14,7 @@ import type {
|
||||
FauxResponseStep,
|
||||
Model,
|
||||
} from "@earendil-works/pi-ai/compat";
|
||||
import { registerFauxProvider } from "@earendil-works/pi-ai/compat";
|
||||
import { registerFauxProvider, streamSimple } from "@earendil-works/pi-ai/compat";
|
||||
import { AgentSession, type AgentSessionEvent } from "../../src/core/agent-session.ts";
|
||||
import { AuthStorage } from "../../src/core/auth-storage.ts";
|
||||
import type { ExtensionRunner } from "../../src/core/extensions/index.ts";
|
||||
@@ -137,6 +137,7 @@ export async function createHarness(options: HarnessOptions = {}): Promise<Harne
|
||||
|
||||
const agent = new Agent({
|
||||
getApiKey: () => (withConfiguredAuth ? "faux-key" : undefined),
|
||||
streamFunction: streamSimple,
|
||||
initialState: {
|
||||
model,
|
||||
systemPrompt: options.systemPrompt ?? "You are a test assistant.",
|
||||
|
||||
@@ -2,7 +2,7 @@ import { existsSync, mkdtempSync, rmSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { Agent } from "@earendil-works/pi-agent-core";
|
||||
import { fauxAssistantMessage, registerFauxProvider } from "@earendil-works/pi-ai/compat";
|
||||
import { fauxAssistantMessage, registerFauxProvider, streamSimple } from "@earendil-works/pi-ai/compat";
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { AgentSession } from "../../../src/core/agent-session.ts";
|
||||
import { AuthStorage } from "../../../src/core/auth-storage.ts";
|
||||
@@ -61,6 +61,7 @@ describe("regression #5596: missing configured theme export", () => {
|
||||
tools: [],
|
||||
},
|
||||
convertToLlm,
|
||||
streamFunction: streamSimple,
|
||||
});
|
||||
const session = new AgentSession({
|
||||
agent,
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ describe("issue #6324 branch summary ambient auth", () => {
|
||||
harnesses.push(harness);
|
||||
|
||||
let streamCallCount = 0;
|
||||
harness.session.agent.streamFn = (model, _context, options) => {
|
||||
harness.session.agent.streamFunction = (model, _context, options) => {
|
||||
streamCallCount++;
|
||||
expect(options?.apiKey).toBeUndefined();
|
||||
|
||||
|
||||
@@ -378,7 +378,7 @@ async function createHarnessWithResourceLoader(
|
||||
systemPrompt: options.systemPrompt ?? "You are a test assistant.",
|
||||
tools: options.tools ?? [],
|
||||
},
|
||||
streamFn,
|
||||
streamFunction: streamFn,
|
||||
});
|
||||
|
||||
const sessionManager = SessionManager.inMemory();
|
||||
|
||||
@@ -8,7 +8,7 @@ import { homedir, tmpdir } from "node:os";
|
||||
import { dirname, join } from "node:path";
|
||||
import { Agent } from "@earendil-works/pi-agent-core";
|
||||
import type { OAuthCredentials } from "@earendil-works/pi-ai";
|
||||
import { getModel } from "@earendil-works/pi-ai/compat";
|
||||
import { getModel, streamSimple } from "@earendil-works/pi-ai/compat";
|
||||
import { builtinProviders } from "@earendil-works/pi-ai/providers/all";
|
||||
import { AgentSession } from "../src/core/agent-session.ts";
|
||||
import { AuthStorage } from "../src/core/auth-storage.ts";
|
||||
@@ -246,6 +246,7 @@ export async function createTestSession(options: TestSessionOptions = {}): Promi
|
||||
systemPrompt: options.systemPrompt ?? "You are a helpful assistant. Be extremely concise.",
|
||||
tools: createCodingTools(process.cwd()),
|
||||
},
|
||||
streamFunction: streamSimple,
|
||||
});
|
||||
|
||||
const sessionManager = options.inMemory ? SessionManager.inMemory() : SessionManager.create(tempDir);
|
||||
|
||||
Reference in New Issue
Block a user