chore: generate

This commit is contained in:
opencode-agent[bot]
2026-06-04 03:03:39 +00:00
parent 76ee87ead8
commit b0a929440b
87 changed files with 2360 additions and 1658 deletions
+5 -1
View File
@@ -117,7 +117,11 @@ const appendText = (
) => {
const last = content.at(-1)
if (last?.type === type) {
content[content.length - 1] = { ...last, text: `${last.text}${text}`, providerMetadata: providerMetadata ?? last.providerMetadata }
content[content.length - 1] = {
...last,
text: `${last.text}${text}`,
providerMetadata: providerMetadata ?? last.providerMetadata,
}
return
}
content.push({ type, text, providerMetadata })
+3 -1
View File
@@ -136,7 +136,9 @@ describe("llm constructors", () => {
})
test("builds chronological text-only system updates separately from the initial system prompt", () => {
const update = Message.system([{ type: "text", text: "Use parameterized SQL.", cache: new CacheHint({ type: "ephemeral" }) }])
const update = Message.system([
{ type: "text", text: "Use parameterized SQL.", cache: new CacheHint({ type: "ephemeral" }) },
])
const request = LLM.request({
model: Model.make({ id: "fake-model", provider: "fake", route: chatRoute }),
system: "Initial operator prompt.",
@@ -87,7 +87,11 @@ describe("Anthropic Messages route", () => {
const prepared = yield* LLMClient.prepare<AnthropicMessages.AnthropicMessagesBody>(
LLM.request({
model,
messages: [Message.user("Before."), Message.system("Treat </system-update> literally."), Message.assistant("After.")],
messages: [
Message.user("Before."),
Message.system("Treat </system-update> literally."),
Message.assistant("After."),
],
cache: "none",
}),
)
@@ -127,19 +131,19 @@ describe("Anthropic Messages route", () => {
LLMClient.prepare(LLM.request({ model: opus48, messages, cache: "none" })).pipe(Effect.flip)
expect((yield* placementError([Message.system("First.")])).message).toContain("cannot be the first message")
expect((yield* placementError([Message.user("Before."), Message.system("One."), Message.system("Two.")])).message)
.toContain("cannot be consecutive")
expect((yield* placementError([Message.assistant("Plain."), Message.system("After plain assistant.")])).message)
.toContain("must follow a user message, tool result, or assistant server tool use")
expect(
(
yield* placementError([
Message.user("Use the tool."),
Message.assistant([ToolCallPart.make({ id: "call_1", name: "lookup", input: {} })]),
Message.system("Too early."),
Message.tool({ id: "call_1", name: "lookup", result: "Done." }),
])
).message,
(yield* placementError([Message.user("Before."), Message.system("One."), Message.system("Two.")])).message,
).toContain("cannot be consecutive")
expect(
(yield* placementError([Message.assistant("Plain."), Message.system("After plain assistant.")])).message,
).toContain("must follow a user message, tool result, or assistant server tool use")
expect(
(yield* placementError([
Message.user("Use the tool."),
Message.assistant([ToolCallPart.make({ id: "call_1", name: "lookup", input: {} })]),
Message.system("Too early."),
Message.tool({ id: "call_1", name: "lookup", result: "Done." }),
])).message,
).toContain("cannot appear between a local tool call and its tool result")
}),
)
@@ -327,7 +327,10 @@ describe("Bedrock Converse route", () => {
}),
)
expect(prepared.body.messages).toEqual([
{ role: "assistant", content: [{ reasoningContent: { reasoningText: { text: "Let me think.", signature: "sig_1" } } }] },
{
role: "assistant",
content: [{ reasoningContent: { reasoningText: { text: "Let me think.", signature: "sig_1" } } }],
},
])
}),
)
+15 -3
View File
@@ -55,12 +55,19 @@ describe("OpenAI Chat route", () => {
const prepared = yield* LLMClient.prepare<OpenAIChat.OpenAIChatBody>(
LLM.request({
model,
messages: [Message.user("Before."), Message.system("Treat <admin> & data literally."), Message.assistant("After.")],
messages: [
Message.user("Before."),
Message.system("Treat <admin> & data literally."),
Message.assistant("After."),
],
}),
)
expect(prepared.body.messages).toEqual([
{ role: "user", content: "Before.\n<system-update>\nTreat &lt;admin&gt; &amp; data literally.\n</system-update>" },
{
role: "user",
content: "Before.\n<system-update>\nTreat &lt;admin&gt; &amp; data literally.\n</system-update>",
},
{ role: "assistant", content: "After." },
])
}),
@@ -71,7 +78,12 @@ describe("OpenAI Chat route", () => {
const prepared = yield* LLMClient.prepare<OpenAIChat.OpenAIChatBody>(
LLM.request({
model,
messages: [Message.assistant([{ type: "reasoning", text: "thinking" }, { type: "text", text: "Hello" }])],
messages: [
Message.assistant([
{ type: "reasoning", text: "thinking" },
{ type: "text", text: "Hello" },
]),
],
}),
)
@@ -62,7 +62,11 @@ describe("OpenAI Responses route", () => {
const prepared = yield* LLMClient.prepare<OpenAIResponses.OpenAIResponsesBody>(
LLM.request({
model,
messages: [Message.user("Before."), Message.system("Treat </system-update> literally."), Message.assistant("After.")],
messages: [
Message.user("Before."),
Message.system("Treat </system-update> literally."),
Message.assistant("After."),
],
}),
)
+42 -12
View File
@@ -1,6 +1,17 @@
import { describe, expect } from "bun:test"
import { Effect, Schema, Stream } from "effect"
import { GenerationOptions, LLM, LLMEvent, LLMRequest, LLMResponse, ToolChoice, ToolContent, ToolOutput, toolFileSourceFromUri, toDefinitions } from "../src"
import {
GenerationOptions,
LLM,
LLMEvent,
LLMRequest,
LLMResponse,
ToolChoice,
ToolContent,
ToolOutput,
toolFileSourceFromUri,
toDefinitions,
} from "../src"
import { Auth, LLMClient } from "../src/route"
import * as AnthropicMessages from "../src/protocols/anthropic-messages"
import * as OpenAIChat from "../src/protocols/openai-chat"
@@ -188,10 +199,12 @@ describe("LLMClient tools", () => {
execute: () => Effect.succeed({ ok: true }),
})
expect((yield* ToolRuntime.dispatch({ text }, LLMEvent.toolCall({ id: "call_text", name: "text", input: {} }))).output)
.toEqual({ structured: "hello", content: [{ type: "text", text: "hello" }] })
expect((yield* ToolRuntime.dispatch({ json }, LLMEvent.toolCall({ id: "call_json", name: "json", input: {} }))).output)
.toEqual({ structured: { ok: true }, content: [] })
expect(
(yield* ToolRuntime.dispatch({ text }, LLMEvent.toolCall({ id: "call_text", name: "text", input: {} }))).output,
).toEqual({ structured: "hello", content: [{ type: "text", text: "hello" }] })
expect(
(yield* ToolRuntime.dispatch({ json }, LLMEvent.toolCall({ id: "call_json", name: "json", input: {} }))).output,
).toEqual({ structured: { ok: true }, content: [] })
}),
)
@@ -204,12 +217,16 @@ describe("LLMClient tools", () => {
source: { type: "data", data: "AAAA" },
mime: "image/png",
})
expect(decode({ type: "file", source: { type: "url", url: "https://example.test/image.png" }, mime: "image/png" })).toEqual({
expect(
decode({ type: "file", source: { type: "url", url: "https://example.test/image.png" }, mime: "image/png" }),
).toEqual({
type: "file",
source: { type: "url", url: "https://example.test/image.png" },
mime: "image/png",
})
expect(decode({ type: "file", source: { type: "file", uri: "file:///tmp/image.png" }, mime: "image/png" })).toEqual({
expect(
decode({ type: "file", source: { type: "file", uri: "file:///tmp/image.png" }, mime: "image/png" }),
).toEqual({
type: "file",
source: { type: "file", uri: "file:///tmp/image.png" },
mime: "image/png",
@@ -226,16 +243,29 @@ describe("LLMClient tools", () => {
).toEqual({ type: "content", value: [{ type: "media", mediaType: "image/png", data: "AAAA" }] })
expect(
ToolOutput.toResultValue(
ToolOutput.make({}, [{ type: "file", source: { type: "url", url: "https://example.test/image.png" }, mime: "image/png" }]),
ToolOutput.make({}, [
{ type: "file", source: { type: "url", url: "https://example.test/image.png" }, mime: "image/png" },
]),
),
).toEqual({ type: "error", value: 'Tool file source "url" must be materialized to inline data before provider conversion' })
).toEqual({
type: "error",
value: 'Tool file source "url" must be materialized to inline data before provider conversion',
})
expect(
ToolOutput.toResultValue(
ToolOutput.make({}, [{ type: "file", source: { type: "file", uri: "file:///tmp/image.png" }, mime: "image/png" }]),
ToolOutput.make({}, [
{ type: "file", source: { type: "file", uri: "file:///tmp/image.png" }, mime: "image/png" },
]),
),
).toEqual({ type: "error", value: 'Tool file source "file" must be materialized to inline data before provider conversion' })
).toEqual({
type: "error",
value: 'Tool file source "file" must be materialized to inline data before provider conversion',
})
expect(toolFileSourceFromUri("data:image/png;base64,AAAA")).toEqual({ type: "data", data: "AAAA" })
expect(toolFileSourceFromUri("https://example.test/image.png")).toEqual({ type: "url", url: "https://example.test/image.png" })
expect(toolFileSourceFromUri("https://example.test/image.png")).toEqual({
type: "url",
url: "https://example.test/image.png",
})
expect(toolFileSourceFromUri("file:///tmp/image.png")).toEqual({ type: "file", uri: "file:///tmp/image.png" })
expect(() => toolFileSourceFromUri("opaque-value")).toThrow("Unsupported tool file URI")
expect(() =>
+3 -1
View File
@@ -27,7 +27,9 @@ Tool.make({
parameters: Schema.Struct({ city: Schema.String }),
success: Schema.Struct({ forecast: Schema.NumberFromString }),
execute: () => Effect.succeed({ forecast: 1 }),
toModelOutput: ({ callID, parameters, output }) => [{ type: "text", text: `${callID}:${parameters.city}:${output.forecast}` }],
toModelOutput: ({ callID, parameters, output }) => [
{ type: "text", text: `${callID}:${parameters.city}:${output.forecast}` },
],
})
LLM.stream(request)