37 lines
1.4 KiB
TypeScript
37 lines
1.4 KiB
TypeScript
import type { Session } from '@opencode-ai/sdk/v2';
|
|||
|
|
|
||
|
|
// Recap + suggested follow-up generated by the server's session-assist
|
||
|
|
// watcher, stored under session.metadata.openchamber.assist. Freshness is
|
||
|
|
// encoded in forMessageID: the payload is only valid while that message is
|
||
|
|
// still the session's last assistant message.
|
||
|
|
export interface SessionAssistPayload {
|
||
|
|
recap: string;
|
||
|
|
suggestion: string;
|
||
|
|
forMessageID: string;
|
||
|
|
generatedAt: number;
|
||
|
|
}
|
||
|
|
|
||
|
|
const isRecord = (value: unknown): value is Record<string, unknown> =>
|
||
|
|
Boolean(value) && typeof value === 'object' && !Array.isArray(value);
|
||
|
|
|
||
|
|
export function getSessionAssist(session: Session | null | undefined): SessionAssistPayload | null {
|
||
|
|
const metadata = (session as { metadata?: unknown } | null | undefined)?.metadata;
|
||
|
|
if (!isRecord(metadata)) return null;
|
||
|
|
const namespace = metadata.openchamber;
|
||
|
|
if (!isRecord(namespace)) return null;
|
||
|
|
const assist = namespace.assist;
|
||
|
|
if (!isRecord(assist)) return null;
|
||
|
|
|
||
|
|
const recap = typeof assist.recap === 'string' ? assist.recap.trim() : '';
|
||
|
|
const suggestion = typeof assist.suggestion === 'string' ? assist.suggestion.trim() : '';
|
||
|
|
const forMessageID = typeof assist.forMessageID === 'string' ? assist.forMessageID : '';
|
||
|
|
if (!forMessageID || (!recap && !suggestion)) return null;
|
||
|
|
|
||
|
|
return {
|
||
|
|
recap,
|
||
|
|
suggestion,
|
||
|
|
forMessageID,
|
||
|
|
generatedAt: typeof assist.generatedAt === 'number' ? assist.generatedAt : 0,
|
||
|
|
};
|
||
|
|
}
|