kimi-code / packages /node-sdk /src /replay.ts
SaylorTwift's picture
SaylorTwift HF Staff
Add files using upload-large-folder tool
4e23b01 verified
Raw History Blame Contribute Delete
4.33 kB
import type { SessionSummary as V2SessionSummary } from '@moonshot-ai/agent-core-v2';
import type { GoalChange, GoalSnapshot } from '@moonshot-ai/agent-core-v2/features/goal/types';
import type { PlanData } from '@moonshot-ai/agent-core-v2/features/plan/plan';
import type { ModelCapability, ProviderConfig } from '@moonshot-ai/kosong';
import type { CompactionResult } from '@moonshot-ai/agent-core-v2/agent/fullCompaction/types';
import type { UsageStatus } from '@moonshot-ai/agent-core-v2/agent/usage/usage';
import type { AgentContextData, ContextMessage } from '#/context';
import type { PermissionApprovalResultRecord, PermissionData, PermissionMode } from '#/permission';
import type { BackgroundTaskInfo } from '#/task';
import type { ToolInfo } from '#/tool';
export type AgentType = 'main' | 'sub' | 'independent';
export interface AgentConfigData {
cwd: string;
provider?: ProviderConfig;
modelAlias?: string;
modelCapabilities: ModelCapability;
profileName?: string;
subagentNames?: readonly string[];
thinkingEffort: string;
systemPrompt: string;
}
export type AgentConfigUpdateData = Partial<{
cwd: string;
modelAlias: string;
profileName: string;
subagentNames: readonly string[];
thinkingEffort: string;
systemPrompt: string;
}>;
export interface AgentMeta {
readonly homedir?: string;
readonly type: AgentType;
readonly parentAgentId?: string | null;
readonly swarmItem?: string;
}
export interface SessionMeta {
createdAt: string;
updatedAt: string;
title: string;
isCustomTitle: boolean;
lastPrompt?: string;
forkedFrom?: string;
workDir?: string;
additionalDirs?: string[];
agents: Record<string, AgentMeta>;
custom: Record<string, any>;
}
export type AgentReplayRecordPayload =
| { type: 'message'; message: ContextMessage }
| { type: 'compaction'; result?: CompactionResult | 'cancelled'; instruction?: string }
| {
type: 'goal_updated';
snapshot: GoalSnapshot;
change: GoalChange | { readonly kind: 'created' };
}
| { type: 'plan_updated'; enabled: boolean }
| { type: 'config_updated'; config: AgentConfigUpdateData }
| { type: 'permission_updated'; mode: PermissionMode }
| { type: 'approval_result'; record: PermissionApprovalResultRecord };
export type AgentReplayRecord = { readonly time: number } & AgentReplayRecordPayload;
export interface ResumedAgentState {
readonly type: AgentType;
readonly config: AgentConfigData;
readonly context: AgentContextData;
readonly replay: readonly AgentReplayRecord[];
readonly permission: PermissionData;
readonly plan: PlanData;
readonly swarmMode?: boolean | undefined;
readonly usage: UsageStatus;
readonly tools: readonly ToolInfo[];
readonly toolStore?: Readonly<Record<string, unknown>>;
readonly background: readonly BackgroundTaskInfo[];
}
export interface ResumeSessionResult extends V2SessionSummary {
readonly sessionMetadata: SessionMeta;
readonly agents: Readonly<Record<string, ResumedAgentState>>;
readonly warning?: string | undefined;
}
export function limitAgentReplayByTurns(
records: readonly AgentReplayRecord[],
maxTurns?: number,
): readonly AgentReplayRecord[] {
if (maxTurns === undefined) return records;
if (maxTurns <= 0) return [];
const turnStarts = records.flatMap((record, index) =>
isAgentReplayUserTurnRecord(record) ? [index] : [],
);
if (turnStarts.length <= maxTurns) return records;
return records.slice(turnStarts[turnStarts.length - maxTurns]);
}
function isAgentReplayUserTurnRecord(record: AgentReplayRecord): boolean {
if (record.type !== 'message') return false;
const { message } = record;
if (message.role !== 'user') return false;
switch (message.origin?.kind) {
case undefined:
case 'user':
return true;
case 'skill_activation':
return message.origin.trigger === 'user-slash';
case 'plugin_command':
return message.origin.trigger === 'user-slash';
case 'shell_command':
return message.origin.phase === 'input';
case 'cron_job':
case 'cron_missed':
return true;
case 'background_task':
case 'compaction_summary':
case 'hook_result':
case 'injection':
case 'retry':
return false;
case 'system_trigger':
return message.origin.name === 'goal_continuation';
}
}