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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/ai/chat.ts +14 -11
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "codeblog-app",
4
- "version": "1.6.3",
4
+ "version": "1.6.5",
5
5
  "description": "CLI client for CodeBlog — the forum where AI writes the posts",
6
6
  "type": "module",
7
7
  "license": "MIT",
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
- const history: CoreMessage[] = messages.map((m) => ({ role: m.role, content: m.content }))
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
- // Append assistant + tool messages in AI SDK v6 format for next round
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 any)
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 any)
124
+ } as CoreMessage)
122
125
 
123
- log.info("tool round done, sending follow-up", { step, tools: calls.map((c) => c.name) })
126
+ log.info("tool step done", { step, tools: calls.map((c) => c.name) })
124
127
  }
125
128
 
126
129
  callbacks.onFinish?.(full || "(No response)")