fix: expose native session title summaries

This commit is contained in:
root
2026-07-20 10:45:09 +02:00
parent 9a1963bc94
commit 54e823e140
2 changed files with 42 additions and 1 deletions
+14 -1
View File
@@ -76,7 +76,10 @@ function requireAuthorization(request: Request, options: { snapshot?: unknown; a
async function nativeSessionList(options: { snapshot?: () => Promise<any>; mode?: WorkbenchMode }, url: URL) {
const state = await requiredSnapshot(options);
const owner = text(url.searchParams.get("ownerUserId"));
const sessions = Object.values(state.sessions).filter((session: any) => !owner || session.ownerUserId === owner).sort((left: any, right: any) => String(right.updatedAt).localeCompare(String(left.updatedAt)));
const sessions = Object.values(state.sessions)
.filter((session: any) => !owner || session.ownerUserId === owner)
.map((session: any) => ({ ...session, firstUserMessagePreview: firstUserMessagePreview(session.messages) ?? (text(session.firstUserMessagePreview) || null) }))
.sort((left: any, right: any) => String(right.updatedAt).localeCompare(String(left.updatedAt)));
return json(200, { ok: true, status: "ready", sessions, count: sessions.length, mode: options.mode ?? "native-test" });
}
async function nativeSessionDetail(options: { snapshot?: () => Promise<any>; mode?: WorkbenchMode }, sessionId: string, messagesOnly: boolean) {
@@ -244,6 +247,16 @@ function nativeEnvelopeMatches(envelope: any, sessionId: string, traceId: string
return (!sessionId || envelopeSessionId === sessionId) && (!traceId || envelopeTraceId === traceId);
}
function firstUserMessagePreview(messages: unknown): string | null {
if (!Array.isArray(messages)) return null;
for (const message of messages) {
if (!message || typeof message !== "object" || text((message as any).role) !== "user") continue;
const preview = text((message as any).text ?? (message as any).content ?? (message as any).message);
if (preview) return preview.slice(0, 240);
}
return null;
}
function actorFrom(request: Request, nativeTest: boolean) {
const id = text(request.headers.get("x-hwlab-actor-id"));
if (!id && nativeTest) return { id: "usr_native", role: "user" };
+28
View File
@@ -75,6 +75,34 @@ describe("Workbench Cloud application adapter", () => {
});
describe("Workbench native HTTP adapter", () => {
test("native session list exposes the first user preview for summary-only rail loading", async () => {
const app = createWorkbenchHttpApp({
async dispatch() { return { ok: true }; },
async snapshot() {
return {
sessions: {
ses_title: {
sessionId: "ses_title",
updatedAt: "2026-07-20T01:00:00.000Z",
messages: [{ role: "user", content: "persisted native title", createdAt: "2026-07-20T00:59:00.000Z" }]
},
ses_empty: { sessionId: "ses_empty", updatedAt: "2026-07-20T00:00:00.000Z", messages: [] }
},
turns: {}
};
}
});
const response = await app.fetch(new Request("http://native.test/v1/workbench/sessions"));
expect(response.status).toBe(200);
expect(await response.json()).toMatchObject({
sessions: [
{ sessionId: "ses_title", firstUserMessagePreview: "persisted native title" },
{ sessionId: "ses_empty", firstUserMessagePreview: null }
]
});
});
test("authorizes only the Workbench navigation entry", async () => {
const app = createWorkbenchHttpApp({
async dispatch() { return { ok: true }; },