Merge accepted local main into PR #154 working branch

This commit is contained in:
amosblomqvist
2026-10-27 17:13:15 +02:00
129 changed files with 6921 additions and 1690 deletions
+11 -3
View File
@@ -22,16 +22,18 @@ export interface UseChatSessionOptions {
chatId: string;
/** The native record seed (server-rendered page or a full sync). */
initialMessages: LhMessage[];
/** Transient settlement failure retained by the server, not the transcript. */
initialError?: string;
/** Reattach on mount: a turn is running server-side with no live view. */
initiallyInFlight?: boolean;
}
export function useChatSession({ chatId, initialMessages, initiallyInFlight }: UseChatSessionOptions) {
export function useChatSession({ chatId, initialMessages, initialError, initiallyInFlight }: UseChatSessionOptions) {
// The model is per-mount (chatId-keyed component); onChange forces the
// re-render. The ref pattern keeps it stable across renders.
const modelRef = useRef<SessionModel | null>(null);
if (modelRef.current === null) {
modelRef.current = new SessionModel({ chatId, initialMessages });
modelRef.current = new SessionModel({ chatId, initialMessages, initialError });
}
const model = modelRef.current;
// The render VERSION — bumped by every model change, so the state memo
@@ -101,6 +103,7 @@ export function useChatSession({ chatId, initialMessages, initiallyInFlight }: U
);
const send = useCallback((input: ChatInput) => model.send(input), [model]);
const continueIfOwed = useCallback((record: readonly LhMessage[]) => void model.continueIfOwed(record), [model]);
const steer = useCallback((text: string) => void model.steer(text), [model]);
const submitAnswer = useCallback(
(tool: string, toolCallId: string, output: QuestionAnswerData) =>
@@ -115,7 +118,9 @@ export function useChatSession({ chatId, initialMessages, initiallyInFlight }: U
(problemCallId: string) => void model.dismissProblem(problemCallId),
[model],
);
const setMessages = useCallback((record: LhMessage[]) => model.setMessages(record), [model]);
const questionDraft = useCallback((toolCallId: string) => model.questionDraft(toolCallId), [model]);
const saveQuestionDraft = useCallback((toolCallId: string, draft: Parameters<SessionModel["saveQuestionDraft"]>[1]) => model.saveQuestionDraft(toolCallId, draft), [model]);
const setMessages = useCallback((record: LhMessage[], turnError?: string) => model.setMessages(record, turnError), [model]);
const adoptRecord = useCallback((record: LhMessage[]) => model.adoptRecord(record), [model]);
const stop = useCallback(() => model.stop(), [model]);
const clearError = useCallback(() => model.clearError(), [model]);
@@ -129,10 +134,13 @@ export function useChatSession({ chatId, initialMessages, initiallyInFlight }: U
error: state.error,
steerQueue: state.steerQueue,
send,
continueIfOwed,
steer,
submitAnswer,
dismissQuestion,
dismissProblem,
questionDraft,
saveQuestionDraft,
setMessages,
adoptRecord,
stop,