Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
4 changes: 2 additions & 2 deletions packages/core/src/adapters/__tests__/session-runtime.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@
topologyContextProvider: provider,
});
await runtime.send('hi');
const [, opts] = session.send.mock.calls[0];
const [, opts] = session.send.mock.calls[0]!;
expect(opts).not.toHaveProperty('topologyContext');
});

Expand All @@ -240,7 +240,7 @@
topologyContextProvider: async () => '',
});
await runtime.send('hi');
const [, opts] = session.send.mock.calls[0];
const [, opts] = session.send.mock.calls[0]!;
expect(opts).not.toHaveProperty('topologyContext');
});

Expand All @@ -264,7 +264,7 @@
topologyContextProvider: provider,
});
const stream = runtime.stream!('hi');
for await (const _ of stream) {

Check failure on line 267 in packages/core/src/adapters/__tests__/session-runtime.test.ts

View workflow job for this annotation

GitHub Actions / Lint, Build & Test

'_' is assigned a value but never used

Check failure on line 267 in packages/core/src/adapters/__tests__/session-runtime.test.ts

View workflow job for this annotation

GitHub Actions / Lint, Build & Test

'_' is assigned a value but never used
// drain
}
await stream.result;
Expand Down
13 changes: 7 additions & 6 deletions packages/core/src/adapters/session-runtime.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ForkContextFn, LLMAdapter, LLMCompleteOptions } from '@stello-ai/session';
import type { ForkContextFn, LLMAdapter, LLMCompleteOptions, SessionInput } from '@stello-ai/session';
import type { EngineRuntimeSession } from '../engine/stello-engine';
import type { ToolCallParser } from '../engine/turn-runner';

Expand All @@ -24,6 +24,8 @@ export interface SessionCompatibleSendResult {
};
}

export type SessionCompatibleInput = string | SessionInput;

/** 结构兼容 @stello-ai/session 的 consolidate 函数签名 */
export type SessionCompatibleConsolidateFn = (
currentMemory: string | null,
Expand Down Expand Up @@ -67,11 +69,11 @@ export interface SessionCompatible {
status: 'active' | 'archived';
};
send(
content: string,
content: SessionCompatibleInput,
options?: SessionCompatibleSendOptions,
): Promise<SessionCompatibleSendResult>;
stream?(
content: string,
content: SessionCompatibleInput,
options?: SessionCompatibleSendOptions,
): AsyncIterable<string> & { result: Promise<SessionCompatibleSendResult> };
messages(): Promise<Array<{ role: string; content: string; timestamp?: string }>>;
Expand Down Expand Up @@ -170,7 +172,7 @@ export async function adaptSessionToEngineRuntime(
get turnCount() {
return turnCount;
},
async send(input: string, sendOptions?: SessionCompatibleSendOptions): Promise<string> {
async send(input: SessionCompatibleInput, sendOptions?: SessionCompatibleSendOptions): Promise<string> {
const sharedMemoryContext = await options.sharedMemoryContextProvider?.();
const topologyContext = await options.topologyContextProvider?.(session.meta.id);
const mergedOptions: SessionCompatibleSendOptions = {
Expand All @@ -193,7 +195,7 @@ export async function adaptSessionToEngineRuntime(
},
...(session.stream
? {
stream(input: string, sendOptions?: SessionCompatibleSendOptions) {
stream(input: SessionCompatibleInput, sendOptions?: SessionCompatibleSendOptions) {
const contextPromise = options.sharedMemoryContextProvider?.() ?? Promise.resolve(undefined);
const topologyPromise = options.topologyContextProvider?.(session.meta.id) ?? Promise.resolve(undefined);
const source = (async () => {
Expand Down Expand Up @@ -234,4 +236,3 @@ export async function adaptSessionToEngineRuntime(
: {}),
};
}

6 changes: 3 additions & 3 deletions packages/core/src/agent/stello-agent.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { BootstrapResult } from '../types/lifecycle';
import { TurnRunner, type ToolCallParser, type TurnRunnerOptions } from '../engine/turn-runner';
import { TurnRunner, type ToolCallParser, type TurnInput, type TurnRunnerOptions } from '../engine/turn-runner';
import type { EngineTurnResult } from '../engine/stello-engine';
import type { EngineStreamResult } from '../engine/stello-engine';
import {
Expand Down Expand Up @@ -447,7 +447,7 @@ export class StelloAgent {
/** 在指定 session 上运行一轮对话 */
turn(
sessionId: string,
input: string,
input: TurnInput,
options?: TurnRunnerOptions,
): Promise<EngineTurnResult> {
return this.orchestrator.turn(sessionId, input, options);
Expand All @@ -456,7 +456,7 @@ export class StelloAgent {
/** 在指定 session 上流式运行一轮对话 */
stream(
sessionId: string,
input: string,
input: TurnInput,
options?: TurnRunnerOptions,
): Promise<EngineStreamResult> {
return this.orchestrator.stream(sessionId, input, options);
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/engine/__tests__/topology-render.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { SessionTreeNode } from '../../types/session.js';
import { renderTopologyMarkdown } from '../topology-render.js';

function node(id: string, label: string, children: SessionTreeNode[] = [], status: 'active' | 'archived' = 'active'): SessionTreeNode {
return { id, label, parentId: null, status, children } as SessionTreeNode;
return { id, label, parentId: null, status, children, turnCount: 0 } as SessionTreeNode;
}

describe('renderTopologyMarkdown', () => {
Expand Down
32 changes: 20 additions & 12 deletions packages/core/src/engine/stello-engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,14 @@ import {
type TurnRunnerOptions,
type TurnRunnerResult,
type TurnRunnerStreamResult,
type TurnInput,
} from './turn-runner';


function turnInputText(input: TurnInput): string {
return typeof input === 'string' ? input : input.text;
}

/** Engine 调用 session.send/stream 时的运行时选项 */
export interface EngineRuntimeSessionCallOptions {
/** AbortSignal — 透传给底层 session.send/stream 与 LLM 调用 */
Expand All @@ -54,10 +60,10 @@ export interface EngineRuntimeSession {
/** 当前已完成轮次 */
turnCount: number;
/** 运行一次单条对话 */
send(input: string, options?: EngineRuntimeSessionCallOptions): Promise<string>;
send(input: TurnInput, options?: EngineRuntimeSessionCallOptions): Promise<string>;
/** 可选:流式运行一次单条对话 */
stream?(
input: string,
input: TurnInput,
options?: EngineRuntimeSessionCallOptions,
): AsyncIterable<string> & { result: Promise<string> };
/** fork 子 session,返回子 session 的 runtime */
Expand Down Expand Up @@ -216,9 +222,10 @@ export class StelloEngineImpl implements StelloEngine {
}

/** 处理一轮编排:当前 session send + tool loop + 调度 */
async turn(input: string, options?: TurnRunnerOptions): Promise<EngineTurnResult> {
this.fireHook('onMessageReceived', { sessionId: this.session.id, input });
this.fireHook('onRoundStart', { sessionId: this.session.id, input });
async turn(input: TurnInput, options?: TurnRunnerOptions): Promise<EngineTurnResult> {
const inputText = turnInputText(input);
this.fireHook('onMessageReceived', { sessionId: this.session.id, input: inputText });
this.fireHook('onRoundStart', { sessionId: this.session.id, input: inputText });
let turn: TurnRunnerResult;
try {
turn = await this.turnRunner.run(this.session, input, this, {
Expand All @@ -238,20 +245,21 @@ export class StelloEngineImpl implements StelloEngine {
}
this.fireHook('onAssistantReply', {
sessionId: this.session.id,
input,
input: inputText,
content: turn.finalContent,
rawResponse: turn.rawResponse,
});
this.fireHook('onRoundEnd', {
sessionId: this.session.id,
input,
input: inputText,
turn,
});
return { turn };
}

/** 流式处理一轮编排:先输出增量文本,完成后再返回完整 turn */
stream(input: string, options?: TurnRunnerOptions): EngineStreamResult {
stream(input: TurnInput, options?: TurnRunnerOptions): EngineStreamResult {
const inputText = turnInputText(input);
const source: TurnRunnerStreamResult = this.turnRunner.runStream(this.session, input, this, {
...options,
onToolCall: (toolCall) => {
Expand All @@ -265,8 +273,8 @@ export class StelloEngineImpl implements StelloEngine {
});

const result = (async () => {
this.fireHook('onMessageReceived', { sessionId: this.session.id, input });
this.fireHook('onRoundStart', { sessionId: this.session.id, input });
this.fireHook('onMessageReceived', { sessionId: this.session.id, input: inputText });
this.fireHook('onRoundStart', { sessionId: this.session.id, input: inputText });

let turn: TurnRunnerResult;
try {
Expand All @@ -278,13 +286,13 @@ export class StelloEngineImpl implements StelloEngine {

this.fireHook('onAssistantReply', {
sessionId: this.session.id,
input,
input: inputText,
content: turn.finalContent,
rawResponse: turn.rawResponse,
});
this.fireHook('onRoundEnd', {
sessionId: this.session.id,
input,
input: inputText,
turn,
});
return { turn };
Expand Down
13 changes: 8 additions & 5 deletions packages/core/src/engine/turn-runner.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import type { SessionInput } from '@stello-ai/session';
import type { ToolExecutionResult } from '../types/lifecycle';

export type TurnInput = string | SessionInput;

/**
* 在单轮内并行执行所有 tool call,按输入顺序整理结果并按序触发事件。
*
Expand Down Expand Up @@ -90,10 +93,10 @@ export interface TurnRunnerSession {
/** Session 标识 */
id: string;
/** 执行一次单条对话 */
send(input: string, options?: TurnRunnerSessionCallOptions): Promise<string>;
send(input: TurnInput, options?: TurnRunnerSessionCallOptions): Promise<string>;
/** 可选:流式执行一次单条对话 */
stream?(
input: string,
input: TurnInput,
options?: TurnRunnerSessionCallOptions,
): AsyncIterable<string> & { result: Promise<string> };
}
Expand Down Expand Up @@ -185,12 +188,12 @@ export class TurnRunner {
*/
async run(
session: TurnRunnerSession,
input: string,
input: TurnInput,
tools: TurnRunnerToolExecutor,
options: TurnRunnerOptions = {},
): Promise<TurnRunnerResult> {
const maxToolRounds = options.maxToolRounds ?? 5;
let currentInput = input;
let currentInput: TurnInput = input;
let toolRoundCount = 0;
let toolCallsExecuted = 0;
let lastRawResponse = '';
Expand Down Expand Up @@ -231,7 +234,7 @@ export class TurnRunner {
*/
runStream(
session: TurnRunnerSession,
input: string,
input: TurnInput,
tools: TurnRunnerToolExecutor,
options: TurnRunnerOptions = {},
): TurnRunnerStreamResult {
Expand Down
10 changes: 5 additions & 5 deletions packages/core/src/orchestrator/session-orchestrator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ import type { BootstrapResult } from '../types/lifecycle';
import type { StelloEngine, EngineForkOptions } from '../types/engine';
import type { EngineTurnResult } from '../engine/stello-engine';
import type { EngineStreamResult } from '../engine/stello-engine';
import type { TurnRunnerOptions } from '../engine/turn-runner';
import type { TurnInput, TurnRunnerOptions } from '../engine/turn-runner';
import type { EngineRuntimeManager } from './engine-runtime-manager';

/** Orchestrator 对 Engine 的最小依赖 */
export interface OrchestratorEngine extends StelloEngine {
/** 运行当前 session 的一轮对话 */
turn(input: string, options?: TurnRunnerOptions): Promise<EngineTurnResult>;
turn(input: TurnInput, options?: TurnRunnerOptions): Promise<EngineTurnResult>;
/** 流式运行当前 session 的一轮对话 */
stream(input: string, options?: TurnRunnerOptions): EngineStreamResult;
stream(input: TurnInput, options?: TurnRunnerOptions): EngineStreamResult;
/** 归档当前绑定 session */
archiveSession(): Promise<{ sessionId: string }>;
/** 从当前绑定 session 发起 fork */
Expand Down Expand Up @@ -59,7 +59,7 @@ export class SessionOrchestrator {
/** 在指定 session 上运行一轮对话 */
async turn(
sessionId: string,
input: string,
input: TurnInput,
options?: TurnRunnerOptions,
): Promise<EngineTurnResult> {
return this.runSerial(sessionId, async () => {
Expand All @@ -71,7 +71,7 @@ export class SessionOrchestrator {
/** 在指定 session 上流式运行一轮对话 */
async stream(
sessionId: string,
input: string,
input: TurnInput,
options?: TurnRunnerOptions,
): Promise<EngineStreamResult> {
await this.requireSession(sessionId)
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/types/engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import type {
ConfirmProtocol,
} from './lifecycle';
import type { EngineRuntimeSession, EngineStreamResult, EngineTurnResult } from '../engine/stello-engine';
import type { TurnRunnerOptions } from '../engine/turn-runner';
import type { TurnInput, TurnRunnerOptions } from '../engine/turn-runner';
import type { ForkContextFn } from '@stello-ai/session';
import type { SessionConfig } from './session-config';

Expand Down Expand Up @@ -85,9 +85,9 @@ export interface StelloEngine {
/** 离开当前绑定 Session 的整轮对话 */
leaveSession(): Promise<{ sessionId: string }>;
/** 流式处理当前绑定 Session 的一轮对话 */
stream(input: string, options?: TurnRunnerOptions): EngineStreamResult;
stream(input: TurnInput, options?: TurnRunnerOptions): EngineStreamResult;
/** 非流式处理当前绑定 Session 的一轮对话 */
turn?(input: string, options?: TurnRunnerOptions): Promise<EngineTurnResult>;
turn?(input: TurnInput, options?: TurnRunnerOptions): Promise<EngineTurnResult>;
/** 导出 Agent Tool 定义(兼容 OpenAI / Claude tool use) */
getToolDefinitions(): ToolDefinition[];
/** 执行 Agent Tool */
Expand Down
Loading
Loading