@opencode/ai 0.0.0-dev-20549 → 0.0.0-dev-20553
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.
|
@@ -675,9 +675,6 @@ const requireThinkingSignature = (request) => {
|
|
|
675
675
|
return false;
|
|
676
676
|
return true;
|
|
677
677
|
};
|
|
678
|
-
// Mid-conversation system messages became available with Opus 4.8 and version
|
|
679
|
-
// 5 of the other supported Claude families. Treat later family versions as
|
|
680
|
-
// compatible without assuming that every Anthropic Messages model is Claude.
|
|
681
678
|
// Opus 4.8 and every Claude 5 model accept mid-conversation system messages; later versions inherit support.
|
|
682
679
|
const supportsNativeSystemUpdates = (request) => {
|
|
683
680
|
const version = claudeVersion(String(request.model.id));
|
|
@@ -687,23 +684,8 @@ const supportsNativeSystemUpdates = (request) => {
|
|
|
687
684
|
return version.minor >= 8;
|
|
688
685
|
return version.major >= 5;
|
|
689
686
|
};
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
return message.role === "assistant" && last?.type === "tool-call" && last.providerExecuted === true;
|
|
693
|
-
};
|
|
694
|
-
const canUseNativeSystemUpdate = (request, index) => {
|
|
695
|
-
const previous = request.messages[index - 1];
|
|
696
|
-
const next = request.messages[index + 1];
|
|
697
|
-
// Vertex currently rejects/404s for a system message after local tool results,
|
|
698
|
-
// so fold it into the user tool-result turn across continuations and history.
|
|
699
|
-
if (request.model.route.id === "google-vertex-messages" && previous?.role === "tool")
|
|
700
|
-
return false;
|
|
701
|
-
return (previous !== undefined &&
|
|
702
|
-
previous.role !== "system" &&
|
|
703
|
-
(previous.role === "user" || previous.role === "tool" || endsInServerToolUse(previous)) &&
|
|
704
|
-
next?.role !== "system" &&
|
|
705
|
-
(next === undefined || next.role === "assistant"));
|
|
706
|
-
};
|
|
687
|
+
// Native system messages must follow a user turn (tool results count) or a paused server-tool turn.
|
|
688
|
+
const acceptsNativeSystemAfter = (message) => message?.role === "user" || (message?.role === "assistant" && message.content.at(-1)?.type === "server_tool_use");
|
|
707
689
|
const splitsLocalToolResults = (messages, index) => {
|
|
708
690
|
const pending = new Set();
|
|
709
691
|
for (const message of messages.slice(0, index)) {
|
|
@@ -727,9 +709,33 @@ const lowerNativeSystemUpdate = Effect.fnUntraced(function* (message, breakpoint
|
|
|
727
709
|
})),
|
|
728
710
|
};
|
|
729
711
|
});
|
|
712
|
+
const lowerWrappedSystemUpdate = Effect.fnUntraced(function* (message, breakpoints) {
|
|
713
|
+
const part = yield* ProviderShared.wrappedSystemUpdate("Anthropic Messages", message);
|
|
714
|
+
return { type: "text", text: part.text, cache_control: cacheControl(breakpoints, part.cache) };
|
|
715
|
+
});
|
|
716
|
+
const appendToUserTurn = (messages, block) => {
|
|
717
|
+
const last = messages.at(-1);
|
|
718
|
+
if (last?.role === "user")
|
|
719
|
+
messages[messages.length - 1] = { role: "user", content: [...last.content, block] };
|
|
720
|
+
else
|
|
721
|
+
messages.push({ role: "user", content: [block] });
|
|
722
|
+
};
|
|
730
723
|
const lowerMessages = Effect.fnUntraced(function* (request, breakpoints) {
|
|
731
724
|
const messages = [];
|
|
732
725
|
const providerMetadataKey = request.model.route.providerMetadataKey ?? String(request.model.provider);
|
|
726
|
+
// Text updates stay where they are unless a user turn follows them; then they move after the latest
|
|
727
|
+
// user turn, the nearest spot where Anthropic accepts a native system message.
|
|
728
|
+
const holdUpdates = supportsNativeSystemUpdates(request);
|
|
729
|
+
const held = [];
|
|
730
|
+
const releaseHeld = Effect.fnUntraced(function* () {
|
|
731
|
+
const native = acceptsNativeSystemAfter(messages.findLast((message) => message.role !== "system"));
|
|
732
|
+
for (const update of held.splice(0)) {
|
|
733
|
+
if (native)
|
|
734
|
+
messages.push(yield* lowerNativeSystemUpdate(update, breakpoints));
|
|
735
|
+
else
|
|
736
|
+
appendToUserTurn(messages, yield* lowerWrappedSystemUpdate(update, breakpoints));
|
|
737
|
+
}
|
|
738
|
+
});
|
|
733
739
|
for (const [index, message] of request.messages.entries()) {
|
|
734
740
|
if (message.role === "system") {
|
|
735
741
|
const update = effortUpdate(message);
|
|
@@ -740,17 +746,10 @@ const lowerMessages = Effect.fnUntraced(function* (request, breakpoints) {
|
|
|
740
746
|
}
|
|
741
747
|
if (splitsLocalToolResults(request.messages, index))
|
|
742
748
|
return yield* invalid("Anthropic Messages system updates cannot split a local tool call from its tool result");
|
|
743
|
-
if (
|
|
744
|
-
|
|
745
|
-
continue;
|
|
746
|
-
}
|
|
747
|
-
const part = yield* ProviderShared.wrappedSystemUpdate("Anthropic Messages", message);
|
|
748
|
-
const block = { type: "text", text: part.text, cache_control: cacheControl(breakpoints, part.cache) };
|
|
749
|
-
const previous = messages.at(-1);
|
|
750
|
-
if (previous?.role === "user")
|
|
751
|
-
messages[messages.length - 1] = { role: "user", content: [...previous.content, block] };
|
|
749
|
+
if (holdUpdates)
|
|
750
|
+
held.push(message);
|
|
752
751
|
else
|
|
753
|
-
messages
|
|
752
|
+
appendToUserTurn(messages, yield* lowerWrappedSystemUpdate(message, breakpoints));
|
|
754
753
|
continue;
|
|
755
754
|
}
|
|
756
755
|
if (message.role === "user") {
|
|
@@ -826,8 +825,10 @@ const lowerMessages = Effect.fnUntraced(function* (request, breakpoints) {
|
|
|
826
825
|
}
|
|
827
826
|
return yield* invalid(`Anthropic Messages assistant messages only support text, reasoning, and tool-call content for now`);
|
|
828
827
|
}
|
|
829
|
-
if (content.length
|
|
830
|
-
|
|
828
|
+
if (content.length === 0)
|
|
829
|
+
continue;
|
|
830
|
+
yield* releaseHeld();
|
|
831
|
+
messages.push({ role: "assistant", content });
|
|
831
832
|
continue;
|
|
832
833
|
}
|
|
833
834
|
const content = [];
|
|
@@ -848,6 +849,7 @@ const lowerMessages = Effect.fnUntraced(function* (request, breakpoints) {
|
|
|
848
849
|
else
|
|
849
850
|
messages.push({ role: "user", content });
|
|
850
851
|
}
|
|
852
|
+
yield* releaseHeld();
|
|
851
853
|
return messages;
|
|
852
854
|
});
|
|
853
855
|
// TODO: Move per-model capability heuristics (`supportsEffortUpdates`, `supportsNativeSystemUpdates`,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
|
-
"version": "0.0.0-dev-
|
|
3
|
+
"version": "0.0.0-dev-20553",
|
|
4
4
|
"name": "@opencode/ai",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@clack/prompts": "1.0.0-alpha.1",
|
|
36
36
|
"@effect/platform-node": "4.0.0-rc.112",
|
|
37
|
-
"@opencode/http-recorder": "0.0.0-dev-
|
|
37
|
+
"@opencode/http-recorder": "0.0.0-dev-20553",
|
|
38
38
|
"@tsconfig/bun": "1.0.9",
|
|
39
39
|
"@types/bun": "1.4.0",
|
|
40
40
|
"@typescript/native-preview": "7.0.0-dev.20251207.1",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"@aws-sdk/credential-providers": "3.1057.0",
|
|
45
45
|
"@smithy/eventstream-codec": "4.2.14",
|
|
46
46
|
"@smithy/util-utf8": "4.2.2",
|
|
47
|
-
"@opencode/schema": "0.0.0-dev-
|
|
47
|
+
"@opencode/schema": "0.0.0-dev-20553",
|
|
48
48
|
"aws4fetch": "1.0.20",
|
|
49
49
|
"effect": "4.0.0-rc.112",
|
|
50
50
|
"google-auth-library": "10.5.0"
|