feat: [AI-6949] add session transcript REST endpoint for datamates extension#941
Conversation
|
This PR doesn't fully meet our contributing guidelines and PR template. What needs to be fixed:
Please edit this PR description to address the above within 2 hours, or it will be automatically closed. If you believe this was flagged incorrectly, please let a maintainer know. |
ralphstodomingo
left a comment
There was a problem hiding this comment.
Reviewed the session-transcript endpoint. Mirrors the existing Session.get/messages pattern well. One boolean-parsing footgun plus the test gap that hides it.
| validator( | ||
| "query", | ||
| z.object({ | ||
| thinking: z.coerce.boolean().optional().default(false).meta({ description: "Include reasoning/thinking parts" }), |
There was a problem hiding this comment.
Bug (latent): z.coerce.boolean() uses JS Boolean() semantics, so ?thinking=false, =0, =off all coerce to true — only absent/empty yields false. For flags presented as real toggles defaulting to false, the only way to get false is to omit the param. Latent because the current consumer (#366) only ever sends =true or omits, but it'll bite any client passing explicit =false. Suggest z.enum(["true","false"]).optional().default("false").transform(v => v === "true") (or a stringbool helper) for all three flags.
There was a problem hiding this comment.
Fixed in b7c1757 using z.preprocess(v => v === "false" ? false : v, z.coerce.boolean()) — handles the "false" string explicitly before coerce runs. Preserves the z.boolean() output type so the rest of the route chain stays unchanged.
| fn: async () => { | ||
| const session = await Session.create({ title: "Options Session" }) | ||
| await addUserMessage(session.id, "test message") | ||
| const app = Server.Default() |
There was a problem hiding this comment.
Concern: this flag test only sends =true and asserts status 200 + # prefix, so it can't catch the coercion bug above and doesn't prove the flags change output. formatTranscript emits _Thinking:_ / **Input:** / **Output:** — build a session with reasoning + tool parts and assert =true includes those markers while =false/default exclude them. That also closes the PR's own unchecked "verify flags work" item.
There was a problem hiding this comment.
Fixed in b7c1757. Replaced the smoke test with a session that has a real reasoning part. Now asserts ?thinking=true includes _Thinking:_, ?thinking=false excludes it (catches the coerce bug), and default also excludes it. 17 assertions, all pass.
| @@ -1,4 +1,5 @@ | |||
| import { Hono } from "hono" | |||
| import { formatTranscript } from "../../cli/cmd/tui/util/transcript" | |||
There was a problem hiding this comment.
Nit: this imports formatTranscript via deep relative path ../../cli/cmd/tui/util/transcript, but the only other server→cli import (routes/tui.ts) uses the @/cli/… alias, and this file already uses @/ elsewhere. Use @/cli/cmd/tui/util/transcript (or @tui/util/transcript). Server importing from cli/ is a layering smell, but there's precedent.
There was a problem hiding this comment.
Fixed in b7c1757 — changed to @/cli/cmd/tui/util/transcript.
…trengthen flag tests
- Use z.preprocess to handle explicit "false" string correctly: z.coerce.boolean()
coerces Boolean("false") = true, so ?thinking=false was silently treated as true
- Fix import to use @/cli alias consistent with other server routes
- Update flag test to build a session with real reasoning parts and assert
both ?thinking=true includes _Thinking:_ and ?thinking=false excludes it
❌ Tests — Failures DetectedTypeScript — 15 failure(s)
Next StepPlease address the failing cases above and re-run verification. cc @app/altimate-harness-bot |
Summary
GET /session/:sessionID/transcriptREST endpoint toaltimate-codeservertext/plain; charset=utf-8)formatTranscriptfromcli/cmd/tui/util/transcript.ts(same function powering the TUI/exportcommand)thinking(bool),toolDetails(bool),assistantMetadata(bool) — all defaultfalseEndpoint
Response:
text/plain; charset=utf-8— markdown string starting with# <session title>Example response:
Test plan
POST /session, calledGET /session/:id/transcript200 OK,Content-Type: text/plain; charset=UTF-8#(markdown session title)thinking,toolDetails,assistantMetadata) accepted without errorFiles changed
packages/opencode/src/server/routes/session.ts— added import + route handlerRequested by @saravmajestic via harness
Summary by cubic
Adds a new REST endpoint to export a session’s conversation as a markdown transcript for easy sharing and offline viewing. Implements Linear AI-6949.
New Features
text/plain; charset=utf-8); reusesformatTranscriptto match the TUI/export; supportsthinking,toolDetails, andassistantMetadataflags (defaultfalse); includes tests for 200/404, empty sessions, and flag behavior.Bug Fixes
z.preprocessso?thinking=falseis respected; aligns import to@/cli/...; strengthens tests to assert reasoning is included/excluded.Written for commit b7c1757. Summary will update on new commits.