mirror of
https://github.com/MoonshotAI/kimi-code.git
synced 2026-08-22 23:26:12 +00:00
refactor(agent-core-v2): rename loop context interfaces
This commit is contained in:
parent
cf9bca54e4
commit
2a9e2194e4
9 changed files with 42 additions and 42 deletions
|
|
@ -26,7 +26,7 @@ import {
|
|||
type FullCompactionTask,
|
||||
} from '#/agent/fullCompaction';
|
||||
import type { CompactionResult, CompactionSource } from '#/agent/fullCompaction/types';
|
||||
import { IAgentLoopService, type TurnAfterStepContext } from '#/agent/loop';
|
||||
import { IAgentLoopService, type AfterStepContext } from '#/agent/loop';
|
||||
import {
|
||||
IAgentPermissionGate,
|
||||
} from '#/agent/permissionGate';
|
||||
|
|
@ -188,8 +188,8 @@ export class AgentExternalHooksService extends Disposable implements IAgentExter
|
|||
loop.hooks.afterStep.register('externalHooks', async (ctx, next) => {
|
||||
await next();
|
||||
if (
|
||||
ctx.stopReason === 'tool_calls' ||
|
||||
ctx.stopReason === 'filtered' ||
|
||||
ctx.finishReason === 'tool_calls' ||
|
||||
ctx.finishReason === 'filtered' ||
|
||||
ctx.continue
|
||||
) {
|
||||
return;
|
||||
|
|
@ -355,7 +355,7 @@ export class AgentExternalHooksService extends Disposable implements IAgentExter
|
|||
);
|
||||
}
|
||||
|
||||
private async runStop(ctx: TurnAfterStepContext): Promise<string | undefined> {
|
||||
private async runStop(ctx: AfterStepContext): Promise<string | undefined> {
|
||||
ctx.signal.throwIfAborted();
|
||||
if (this.stopHookContinuationUsed) return undefined;
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import {
|
|||
sleepForRetry,
|
||||
type LLMRequestFinish,
|
||||
} from '#/agent/llmRequester';
|
||||
import { IAgentLoopService, type TurnErrorContext } from '#/agent/loop';
|
||||
import { IAgentLoopService, type LoopErrorContext } from '#/agent/loop';
|
||||
import { isAbortError, isContextOverflowError } from '#/agent/loop/errors';
|
||||
import { IAgentProfileService } from '#/agent/profile';
|
||||
import { IAgentTurnService } from '#/agent/turn';
|
||||
|
|
@ -225,7 +225,7 @@ export class AgentFullCompactionService extends Disposable implements IAgentFull
|
|||
}
|
||||
|
||||
private async onLoopError(
|
||||
context: TurnErrorContext,
|
||||
context: LoopErrorContext,
|
||||
next: () => Promise<void>,
|
||||
): Promise<void> {
|
||||
if (!isContextOverflowError(context.error)) {
|
||||
|
|
|
|||
|
|
@ -38,8 +38,8 @@ import {
|
|||
} from '#/agent/goal/tools/outcome-prompts';
|
||||
import {
|
||||
IAgentLoopService,
|
||||
type TurnAfterStepContext,
|
||||
type TurnBeforeStepContext,
|
||||
type AfterStepContext,
|
||||
type BeforeStepContext,
|
||||
} from '#/agent/loop';
|
||||
import { IAgentSystemReminderService } from '#/agent/systemReminder';
|
||||
import { IAgentTurnService, type TurnResult } from '#/agent/turn';
|
||||
|
|
@ -370,14 +370,14 @@ export class AgentGoalService extends Disposable implements IAgentGoalService {
|
|||
this.goalOutcomeContinuationTurns.delete(turnId);
|
||||
}
|
||||
|
||||
private async handleBeforeStep(ctx: TurnBeforeStepContext): Promise<void> {
|
||||
private async handleBeforeStep(ctx: BeforeStepContext): Promise<void> {
|
||||
if (!this.goalDrivenTurns.has(ctx.turnId)) return;
|
||||
if (this.countedGoalTurns.has(ctx.turnId)) return;
|
||||
this.countedGoalTurns.add(ctx.turnId);
|
||||
await this.incrementTurn();
|
||||
}
|
||||
|
||||
private handleAfterStep(ctx: TurnAfterStepContext): void {
|
||||
private handleAfterStep(ctx: AfterStepContext): void {
|
||||
if (this.goalDrivenTurns.has(ctx.turnId)) {
|
||||
const snapshot = this.accountTokenUsage(tokenUsageTotal(ctx.usage));
|
||||
if (snapshot?.budget.overBudget === true) {
|
||||
|
|
|
|||
|
|
@ -4,19 +4,19 @@ import type { TokenUsage } from '#/app/llmProtocol/usage';
|
|||
import type { Hooks } from '#/hooks';
|
||||
import type { TurnEndReason } from '@moonshot-ai/protocol';
|
||||
|
||||
export interface TurnBeforeStepContext {
|
||||
export interface BeforeStepContext {
|
||||
readonly turnId: number;
|
||||
readonly step: number;
|
||||
readonly signal: AbortSignal;
|
||||
}
|
||||
|
||||
export interface TurnAfterStepContext extends TurnBeforeStepContext {
|
||||
export interface AfterStepContext extends BeforeStepContext {
|
||||
readonly usage: TokenUsage;
|
||||
readonly stopReason: FinishReason;
|
||||
readonly finishReason: FinishReason;
|
||||
continue: boolean;
|
||||
}
|
||||
|
||||
export interface TurnErrorContext {
|
||||
export interface LoopErrorContext {
|
||||
readonly turnId: number;
|
||||
/** The currently executing step, or undefined for turn-level failures. */
|
||||
readonly step?: number;
|
||||
|
|
@ -29,14 +29,14 @@ export interface TurnErrorContext {
|
|||
retry: boolean;
|
||||
}
|
||||
|
||||
export interface RunOptions {
|
||||
export interface LoopRunOptions {
|
||||
readonly turnId: number;
|
||||
readonly signal?: AbortSignal;
|
||||
/** Fires on the first model response event for a step, or at step completion. */
|
||||
readonly onStarted?: (step: number) => void;
|
||||
}
|
||||
|
||||
export interface TurnResult {
|
||||
export interface LoopRunResult {
|
||||
readonly reason: TurnEndReason;
|
||||
readonly error?: unknown;
|
||||
readonly steps?: number;
|
||||
|
|
@ -45,12 +45,12 @@ export interface TurnResult {
|
|||
export interface IAgentLoopService {
|
||||
readonly _serviceBrand: undefined;
|
||||
|
||||
run(options: RunOptions): Promise<TurnResult>;
|
||||
run(options: LoopRunOptions): Promise<LoopRunResult>;
|
||||
|
||||
readonly hooks: Hooks<{
|
||||
beforeStep: TurnBeforeStepContext;
|
||||
afterStep: TurnAfterStepContext;
|
||||
onError: TurnErrorContext;
|
||||
beforeStep: BeforeStepContext;
|
||||
afterStep: AfterStepContext;
|
||||
onError: LoopErrorContext;
|
||||
}>;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,9 +32,9 @@ import {
|
|||
} from './errors';
|
||||
import {
|
||||
IAgentLoopService,
|
||||
type RunOptions,
|
||||
type TurnAfterStepContext,
|
||||
type TurnResult,
|
||||
type LoopRunOptions,
|
||||
type AfterStepContext,
|
||||
type LoopRunResult,
|
||||
} from './loop';
|
||||
|
||||
declare module '#/app/event/eventBus' {
|
||||
|
|
@ -74,7 +74,7 @@ export class AgentLoopService implements IAgentLoopService {
|
|||
@IConfigService private readonly config: IConfigService,
|
||||
) { }
|
||||
|
||||
async run(options: RunOptions): Promise<TurnResult> {
|
||||
async run(options: LoopRunOptions): Promise<LoopRunResult> {
|
||||
const { turnId } = options;
|
||||
const signal = options.signal ?? new AbortController().signal;
|
||||
|
||||
|
|
@ -233,12 +233,12 @@ export class AgentLoopService implements IAgentLoopService {
|
|||
markStepStarted();
|
||||
this.emitStepCompleted(turnId, currentStep, stepUuid, usage, finishReason, response);
|
||||
|
||||
const afterStepContext: TurnAfterStepContext = {
|
||||
const afterStepContext: AfterStepContext = {
|
||||
turnId,
|
||||
step: currentStep,
|
||||
signal,
|
||||
usage,
|
||||
stopReason: finishReason,
|
||||
finishReason,
|
||||
continue: false,
|
||||
};
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { createDecorator } from "#/_base/di/instantiation";
|
||||
import type { TurnResult } from '#/agent/loop';
|
||||
import type { LoopRunResult } from '#/agent/loop';
|
||||
|
||||
export type { TurnResult } from '#/agent/loop';
|
||||
export type { LoopRunResult as TurnResult } from '#/agent/loop';
|
||||
|
||||
export interface Turn {
|
||||
readonly id: number;
|
||||
|
|
@ -11,7 +11,7 @@ export interface Turn {
|
|||
* step completion; rejects if the turn ends earlier.
|
||||
*/
|
||||
readonly ready: Promise<void>;
|
||||
readonly result: Promise<TurnResult>;
|
||||
readonly result: Promise<LoopRunResult>;
|
||||
}
|
||||
|
||||
export interface IAgentTurnService {
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ import {
|
|||
import { HookDefSchema, HOOKS_SECTION, hooksFromToml, hooksToToml } from '#/agent/externalHooks/configSection';
|
||||
import { makeHookRunner } from './runner-stub';
|
||||
import { IAgentFullCompactionService } from '#/agent/fullCompaction';
|
||||
import { IAgentLoopService, type TurnAfterStepContext } from '#/agent/loop';
|
||||
import { IAgentLoopService, type AfterStepContext } from '#/agent/loop';
|
||||
import { IAgentPermissionGate } from '#/agent/permissionGate';
|
||||
import { IAgentPromptService } from '#/agent/prompt';
|
||||
import { IAgentToolExecutorService } from '#/agent/toolExecutor';
|
||||
|
|
@ -78,13 +78,13 @@ function stdinScript(body: string): string {
|
|||
].join('\n'));
|
||||
}
|
||||
|
||||
function makeAfterStep(signal: AbortSignal): TurnAfterStepContext {
|
||||
function makeAfterStep(signal: AbortSignal): AfterStepContext {
|
||||
return {
|
||||
turnId: 0,
|
||||
step: 1,
|
||||
signal,
|
||||
usage: emptyUsage(),
|
||||
stopReason: 'completed',
|
||||
finishReason: 'completed',
|
||||
continue: false,
|
||||
};
|
||||
}
|
||||
|
|
@ -290,9 +290,9 @@ describe('IExternalHooksRunnerService integration', () => {
|
|||
const eventBus = ix.get(IEventBus);
|
||||
|
||||
const signal = new AbortController().signal;
|
||||
const filtered: TurnAfterStepContext = {
|
||||
const filtered: AfterStepContext = {
|
||||
...makeAfterStep(signal),
|
||||
stopReason: 'filtered',
|
||||
finishReason: 'filtered',
|
||||
};
|
||||
await loop.hooks.afterStep.run(filtered);
|
||||
expect(filtered.continue).toBe(false);
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|||
import { IAgentContextMemoryService } from '#/agent/contextMemory';
|
||||
import { IAgentEventSinkService } from '#/agent/eventSink';
|
||||
import { IAgentGoalService, type AgentGoalService } from '#/agent/goal';
|
||||
import { IAgentLoopService, type TurnAfterStepContext } from '#/agent/loop';
|
||||
import { IAgentLoopService, type AfterStepContext } from '#/agent/loop';
|
||||
import { IAgentTurnService, type Turn, type TurnResult } from '#/agent/turn';
|
||||
import type { PersistedWireRecord, WireRecord } from '#/agent/wireRecord';
|
||||
import type { TokenUsage } from '#/app/llmProtocol/usage';
|
||||
|
|
@ -62,12 +62,12 @@ async function runGoalStep(loopService: IAgentLoopService, turn: Turn): Promise<
|
|||
step: 1,
|
||||
signal: turn.abortController.signal,
|
||||
};
|
||||
const afterStep: TurnAfterStepContext = {
|
||||
const afterStep: AfterStepContext = {
|
||||
turnId: turn.id,
|
||||
step: 1,
|
||||
signal: turn.abortController.signal,
|
||||
usage: zeroUsage,
|
||||
stopReason: 'completed' as const,
|
||||
finishReason: 'completed' as const,
|
||||
continue: false,
|
||||
};
|
||||
await loopService.hooks.beforeStep.run(step);
|
||||
|
|
@ -81,12 +81,12 @@ async function runStepUsageHooks(
|
|||
turn: Turn,
|
||||
usage: TokenUsage,
|
||||
): Promise<boolean> {
|
||||
const afterStep: TurnAfterStepContext = {
|
||||
const afterStep: AfterStepContext = {
|
||||
turnId: turn.id,
|
||||
step: 1,
|
||||
signal: turn.abortController.signal,
|
||||
usage,
|
||||
stopReason: 'completed' as const,
|
||||
finishReason: 'completed' as const,
|
||||
continue: false,
|
||||
};
|
||||
await loopService.hooks.afterStep.run(afterStep);
|
||||
|
|
@ -665,12 +665,12 @@ describe('AgentGoalService core workflow hooks', () => {
|
|||
step: 1,
|
||||
signal: turn.abortController.signal,
|
||||
};
|
||||
const afterStep: TurnAfterStepContext = {
|
||||
const afterStep: AfterStepContext = {
|
||||
turnId: turn.id,
|
||||
step: 1,
|
||||
signal: turn.abortController.signal,
|
||||
usage: zeroUsage,
|
||||
stopReason: 'completed' as const,
|
||||
finishReason: 'completed' as const,
|
||||
continue: false,
|
||||
};
|
||||
await loopService.hooks.beforeStep.run(step);
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ function afterStep(
|
|||
step,
|
||||
signal,
|
||||
usage: ZERO_USAGE,
|
||||
stopReason: 'completed',
|
||||
finishReason: 'completed',
|
||||
continue: false,
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue