feat: thinking blocks rendered in tui and share page

This commit is contained in:
adamdotdevin
2025-08-10 19:24:16 -05:00
parent 20e818ad05
commit b8d2aebf09
17 changed files with 324 additions and 55 deletions

View File

@@ -87,7 +87,22 @@ export namespace ProviderTransform {
return {
reasoningEffort: "minimal",
textVerbosity: "low",
// reasoningSummary: "auto",
// include: ["reasoning.encrypted_content"],
}
}
// if (modelID.includes("claude")) {
// return {
// thinking: {
// type: "enabled",
// budgetTokens: 32000,
// },
// }
// }
// if (_providerID === "bedrock") {
// return {
// reasoningConfig: { type: "enabled", budgetTokens: 32000 },
// }
// }
}
}

View File

@@ -1006,6 +1006,7 @@ export namespace Session {
async process(stream: StreamTextResult<Record<string, AITool>, never>) {
try {
let currentText: MessageV2.TextPart | undefined
let reasoningMap: Record<string, MessageV2.ReasoningPart> = {}
for await (const value of stream.fullStream) {
log.info("part", {
@@ -1016,12 +1017,41 @@ export namespace Session {
break
case "reasoning-start":
if (value.id in reasoningMap) {
continue
}
reasoningMap[value.id] = {
id: Identifier.ascending("part"),
messageID: assistantMsg.id,
sessionID: assistantMsg.sessionID,
type: "reasoning",
text: "",
time: {
start: Date.now(),
},
}
break
case "reasoning-delta":
if (value.id in reasoningMap) {
const part = reasoningMap[value.id]
part.text += value.text
if (part.text) await updatePart(part)
}
break
case "reasoning-end":
if (value.id in reasoningMap) {
const part = reasoningMap[value.id]
part.text = part.text.trimEnd()
part.providerMetadata = value.providerMetadata
part.time = {
start: Date.now(),
end: Date.now(),
}
await updatePart(part)
delete reasoningMap[value.id]
}
break
case "tool-input-start":

View File

@@ -118,6 +118,21 @@ export namespace MessageV2 {
})
export type TextPart = z.infer<typeof TextPart>
export const ReasoningPart = PartBase.extend({
type: z.literal("reasoning"),
text: z.string(),
providerMetadata: z.record(z.any()).optional(),
time: z
.object({
start: z.number(),
end: z.number().optional(),
})
.optional(),
}).openapi({
ref: "ReasoningPart",
})
export type ReasoningPart = z.infer<typeof ReasoningPart>
export const ToolPart = PartBase.extend({
type: z.literal("tool"),
callID: z.string(),
@@ -229,6 +244,7 @@ export namespace MessageV2 {
export const Part = z
.discriminatedUnion("type", [
TextPart,
ReasoningPart,
FilePart,
ToolPart,
StepStartPart,