import { cloneMessages, type CanonicalMessage, type CanonicalUsage } from "../../model/index.js";
import type { AgentPermissionDenial } from "../protocol/result.js";
import type { AgentSessionState as AgentSessionStateShape } from "../protocol/state.js";
export function createInitialAgentSessionState(sessionId: string): AgentSessionStateShape {
return {
sessionId,
messages: [],
usage: {},
permissionDenials: [],
status: "idle",
abortController: new AbortController(),
};
}
export function snapshotAgentSessionState(state: AgentSessionStateShape): AgentSessionStateShape {
return {
...state,
messages: cloneMessages(state.messages),
usage: { ...state.usage },
permissionDenials: state.permissionDenials.map((denial) => ({ ...denial })),
};
}
export function cloneSessionStateForRuntimeReload(state: AgentSessionStateShape): AgentSessionStateShape {
return {
...snapshotAgentSessionState(state),
status: "idle",
currentTurnId: undefined,
abortController: new AbortController(),
};
}
export function mergeSessionUsage(first: CanonicalUsage, second: CanonicalUsage): CanonicalUsage {
return {
inputTokens: add(first.inputTokens, second.inputTokens),
outputTokens: add(first.outputTokens, second.outputTokens),
cacheReadTokens: add(first.cacheReadTokens, second.cacheReadTokens),
cacheWriteTokens: add(first.cacheWriteTokens, second.cacheWriteTokens),
totalTokens: add(first.totalTokens, second.totalTokens),
};
}
export function appendPermissionDenials(
first: AgentPermissionDenial[],
second: AgentPermissionDenial[],
): AgentPermissionDenial[] {
return [...first, ...second.map((denial) => ({ ...denial }))];
}
function add(first: number | undefined, second: number | undefined): number | undefined {
if (first === undefined && second === undefined) {
return undefined;
}
return (first ?? 0) + (second ?? 0);
}