codeblog-app 1.6.3 → 1.6.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/ai/chat.ts +14 -11
package/package.json
CHANGED
package/src/ai/chat.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { streamText, type CoreMessage } from "ai"
|
|
1
|
+
import { streamText, type CoreMessage, type CoreToolMessage, type CoreAssistantMessage } from "ai"
|
|
2
2
|
import { AIProvider } from "./provider"
|
|
3
3
|
import { chatTools } from "./tools"
|
|
4
4
|
import { Log } from "../util/log"
|
|
@@ -39,11 +39,12 @@ export namespace AIChat {
|
|
|
39
39
|
const model = await AIProvider.getModel(modelID)
|
|
40
40
|
log.info("streaming", { model: modelID || AIProvider.DEFAULT_MODEL, messages: messages.length })
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
// Build history: only user/assistant text (tool context is added per-step below)
|
|
43
|
+
const history: CoreMessage[] = messages
|
|
44
|
+
.filter((m) => m.role === "user" || m.role === "assistant")
|
|
45
|
+
.map((m) => ({ role: m.role as "user" | "assistant", content: m.content }))
|
|
43
46
|
let full = ""
|
|
44
47
|
|
|
45
|
-
// Manual multi-step loop (maxSteps=1 per call, we handle tool follow-up ourselves)
|
|
46
|
-
// This is needed because openai-compatible providers don't support automatic multi-step
|
|
47
48
|
for (let step = 0; step < 5; step++) {
|
|
48
49
|
if (signal?.aborted) break
|
|
49
50
|
|
|
@@ -97,30 +98,32 @@ export namespace AIChat {
|
|
|
97
98
|
return full
|
|
98
99
|
}
|
|
99
100
|
|
|
100
|
-
// No tool calls this step → done
|
|
101
101
|
if (calls.length === 0) break
|
|
102
102
|
|
|
103
|
-
//
|
|
103
|
+
// AI SDK v6 ModelMessage format:
|
|
104
|
+
// AssistantModelMessage with ToolCallPart uses "input"
|
|
105
|
+
// ToolModelMessage with ToolResultPart uses "output: { type: 'json', value }"
|
|
104
106
|
history.push({
|
|
105
107
|
role: "assistant",
|
|
106
108
|
content: calls.map((c) => ({
|
|
107
109
|
type: "tool-call" as const,
|
|
108
110
|
toolCallId: c.id,
|
|
109
111
|
toolName: c.name,
|
|
110
|
-
input: c.input
|
|
112
|
+
input: c.input,
|
|
111
113
|
})),
|
|
112
|
-
} as
|
|
114
|
+
} as CoreMessage)
|
|
115
|
+
|
|
113
116
|
history.push({
|
|
114
117
|
role: "tool",
|
|
115
118
|
content: calls.map((c) => ({
|
|
116
119
|
type: "tool-result" as const,
|
|
117
120
|
toolCallId: c.id,
|
|
118
121
|
toolName: c.name,
|
|
119
|
-
output: { type: "json", value: c.output ?? {} },
|
|
122
|
+
output: { type: "json" as const, value: c.output ?? {} },
|
|
120
123
|
})),
|
|
121
|
-
} as
|
|
124
|
+
} as CoreMessage)
|
|
122
125
|
|
|
123
|
-
log.info("tool
|
|
126
|
+
log.info("tool step done", { step, tools: calls.map((c) => c.name) })
|
|
124
127
|
}
|
|
125
128
|
|
|
126
129
|
callbacks.onFinish?.(full || "(No response)")
|