@opencode-ai/ai 0.0.0-dev-17545 → 0.0.0-dev-17603
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/dist/protocols/anthropic-messages.js +22 -9
- package/dist/protocols/gemini.d.ts +11 -4
- package/dist/protocols/gemini.js +3 -2
- package/dist/protocols/shared.d.ts +2 -2
- package/dist/protocols/shared.js +3 -3
- package/dist/provider-error.js +1 -1
- package/dist/providers/google-vertex.d.ts +16 -9
- package/dist/providers/google-vertex.js +18 -1
- package/dist/providers/google.d.ts +4 -1
- package/dist/schema/errors.js +1 -1
- package/package.json +5 -5
|
@@ -329,10 +329,20 @@ const lowerToolResultContent = Effect.fnUntraced(function* (part) {
|
|
|
329
329
|
const content = part.result.value;
|
|
330
330
|
return yield* Effect.forEach(content, lowerToolResultContentItem);
|
|
331
331
|
});
|
|
332
|
-
// Mid-conversation system messages
|
|
333
|
-
//
|
|
334
|
-
//
|
|
335
|
-
const supportsNativeSystemUpdates = (request) =>
|
|
332
|
+
// Mid-conversation system messages became available with Opus 4.8 and version
|
|
333
|
+
// 5 of the other supported Claude families. Treat later family versions as
|
|
334
|
+
// compatible without assuming that every Anthropic Messages model is Claude.
|
|
335
|
+
const supportsNativeSystemUpdates = (request) => {
|
|
336
|
+
const match = /(?:^|[./])claude-(fable|haiku|mythos|opus|sonnet)-(\d+)(?:[.-](\d+))?/.exec(String(request.model.id).toLowerCase());
|
|
337
|
+
if (!match)
|
|
338
|
+
return false;
|
|
339
|
+
const major = Number(match[2]);
|
|
340
|
+
if (match[1] !== "opus")
|
|
341
|
+
return major >= 5;
|
|
342
|
+
if (major !== 4)
|
|
343
|
+
return major >= 5;
|
|
344
|
+
return match[3] !== undefined && match[3].length <= 2 && Number(match[3]) >= 8;
|
|
345
|
+
};
|
|
336
346
|
const endsInServerToolUse = (message) => {
|
|
337
347
|
const last = message.content.at(-1);
|
|
338
348
|
return message.role === "assistant" && last?.type === "tool-call" && last.providerExecuted === true;
|
|
@@ -781,9 +791,12 @@ const onMessageDelta = (state, event) => {
|
|
|
781
791
|
NO_EVENTS,
|
|
782
792
|
];
|
|
783
793
|
};
|
|
784
|
-
const onMessageStop = (state)
|
|
794
|
+
const onMessageStop = Effect.fn("AnthropicMessages.onMessageStop")(function* (state) {
|
|
795
|
+
const result = yield* ToolStream.finishAll(ADAPTER, state.tools);
|
|
785
796
|
const events = [];
|
|
786
|
-
const lifecycle = Lifecycle.
|
|
797
|
+
const lifecycle = result.events.length ? Lifecycle.stepStart(state.lifecycle, events) : state.lifecycle;
|
|
798
|
+
events.push(...result.events);
|
|
799
|
+
const finished = Lifecycle.finish(lifecycle, events, {
|
|
787
800
|
reason: state.pendingFinish?.reason ?? {
|
|
788
801
|
normalized: "unknown",
|
|
789
802
|
raw: undefined,
|
|
@@ -791,8 +804,8 @@ const onMessageStop = (state) => {
|
|
|
791
804
|
usage: state.usage,
|
|
792
805
|
providerMetadata: state.pendingFinish?.providerMetadata,
|
|
793
806
|
});
|
|
794
|
-
return [{ ...state, lifecycle }, events];
|
|
795
|
-
};
|
|
807
|
+
return [{ ...state, lifecycle: finished, tools: result.tools }, events];
|
|
808
|
+
});
|
|
796
809
|
// Prefix `error.type` so overloads, rate limits, and quota errors are visible
|
|
797
810
|
// even when the provider message is generic or empty.
|
|
798
811
|
const providerErrorMessage = (event) => {
|
|
@@ -819,7 +832,7 @@ const step = (state, event) => {
|
|
|
819
832
|
if (event.type === "message_delta")
|
|
820
833
|
return Effect.succeed(onMessageDelta(state, event));
|
|
821
834
|
if (event.type === "message_stop")
|
|
822
|
-
return
|
|
835
|
+
return onMessageStop(state);
|
|
823
836
|
if (event.type === "error")
|
|
824
837
|
return onError(event);
|
|
825
838
|
return Effect.succeed([state, NO_EVENTS]);
|
|
@@ -38,7 +38,7 @@ declare const GeminiBody: Schema.Struct<{
|
|
|
38
38
|
readonly functionCall: Schema.Struct<{
|
|
39
39
|
readonly id: Schema.optional<Schema.String>;
|
|
40
40
|
readonly name: Schema.String;
|
|
41
|
-
readonly args: Schema.Unknown
|
|
41
|
+
readonly args: Schema.optional<Schema.Unknown>;
|
|
42
42
|
}>;
|
|
43
43
|
readonly thoughtSignature: Schema.optional<Schema.String>;
|
|
44
44
|
}>, Schema.Struct<{
|
|
@@ -55,6 +55,7 @@ declare const GeminiBody: Schema.Struct<{
|
|
|
55
55
|
}>;
|
|
56
56
|
}>]>>;
|
|
57
57
|
}>>;
|
|
58
|
+
labels: Schema.optional<Schema.$Record<Schema.String, Schema.String>>;
|
|
58
59
|
safetySettings: Schema.optional<Schema.$Array<Schema.Struct<{
|
|
59
60
|
readonly category: Schema.String;
|
|
60
61
|
readonly threshold: Schema.String;
|
|
@@ -115,8 +116,8 @@ export declare const protocol: Protocol<{
|
|
|
115
116
|
} | {
|
|
116
117
|
readonly functionCall: {
|
|
117
118
|
readonly name: string;
|
|
118
|
-
readonly args: unknown;
|
|
119
119
|
readonly id?: string | undefined;
|
|
120
|
+
readonly args?: unknown;
|
|
120
121
|
};
|
|
121
122
|
readonly thoughtSignature?: string | undefined;
|
|
122
123
|
} | {
|
|
@@ -154,6 +155,9 @@ export declare const protocol: Protocol<{
|
|
|
154
155
|
readonly threshold: string;
|
|
155
156
|
}[] | undefined;
|
|
156
157
|
readonly serviceTier?: string | undefined;
|
|
158
|
+
readonly labels?: {
|
|
159
|
+
readonly [x: string]: string;
|
|
160
|
+
} | undefined;
|
|
157
161
|
readonly systemInstruction?: {
|
|
158
162
|
readonly parts: readonly {
|
|
159
163
|
readonly text: string;
|
|
@@ -190,8 +194,8 @@ export declare const protocol: Protocol<{
|
|
|
190
194
|
} | {
|
|
191
195
|
readonly functionCall: {
|
|
192
196
|
readonly name: string;
|
|
193
|
-
readonly args: unknown;
|
|
194
197
|
readonly id?: string | undefined;
|
|
198
|
+
readonly args?: unknown;
|
|
195
199
|
};
|
|
196
200
|
readonly thoughtSignature?: string | undefined;
|
|
197
201
|
} | {
|
|
@@ -243,8 +247,8 @@ export declare const route: Route<{
|
|
|
243
247
|
} | {
|
|
244
248
|
readonly functionCall: {
|
|
245
249
|
readonly name: string;
|
|
246
|
-
readonly args: unknown;
|
|
247
250
|
readonly id?: string | undefined;
|
|
251
|
+
readonly args?: unknown;
|
|
248
252
|
};
|
|
249
253
|
readonly thoughtSignature?: string | undefined;
|
|
250
254
|
} | {
|
|
@@ -282,6 +286,9 @@ export declare const route: Route<{
|
|
|
282
286
|
readonly threshold: string;
|
|
283
287
|
}[] | undefined;
|
|
284
288
|
readonly serviceTier?: string | undefined;
|
|
289
|
+
readonly labels?: {
|
|
290
|
+
readonly [x: string]: string;
|
|
291
|
+
} | undefined;
|
|
285
292
|
readonly systemInstruction?: {
|
|
286
293
|
readonly parts: readonly {
|
|
287
294
|
readonly text: string;
|
package/dist/protocols/gemini.js
CHANGED
|
@@ -44,7 +44,7 @@ const GeminiFunctionCallPart = Schema.Struct({
|
|
|
44
44
|
functionCall: Schema.Struct({
|
|
45
45
|
id: Schema.optional(Schema.String),
|
|
46
46
|
name: Schema.String,
|
|
47
|
-
args: Schema.Unknown,
|
|
47
|
+
args: Schema.optional(Schema.Unknown),
|
|
48
48
|
}),
|
|
49
49
|
thoughtSignature: Schema.optional(Schema.String),
|
|
50
50
|
});
|
|
@@ -106,6 +106,7 @@ const GeminiGenerationConfig = Schema.Struct({
|
|
|
106
106
|
const GeminiBodyFields = {
|
|
107
107
|
cachedContent: Schema.optional(Schema.String),
|
|
108
108
|
contents: Schema.Array(GeminiContent),
|
|
109
|
+
labels: Schema.optional(Schema.Record(Schema.String, Schema.String)),
|
|
109
110
|
safetySettings: optionalArray(GeminiSafetySetting),
|
|
110
111
|
serviceTier: Schema.optional(Schema.String),
|
|
111
112
|
systemInstruction: Schema.optional(GeminiSystemInstruction),
|
|
@@ -456,7 +457,7 @@ const step = (state, event) => {
|
|
|
456
457
|
continue;
|
|
457
458
|
}
|
|
458
459
|
if ("functionCall" in part) {
|
|
459
|
-
const input = part.functionCall.args;
|
|
460
|
+
const input = part.functionCall.args === undefined ? {} : part.functionCall.args;
|
|
460
461
|
const id = `tool_${nextToolCallId++}`;
|
|
461
462
|
const metadata = {
|
|
462
463
|
...(part.functionCall.id === undefined ? {} : { functionCallId: part.functionCall.id }),
|
|
@@ -120,8 +120,8 @@ export declare const errorText: (error: unknown) => string;
|
|
|
120
120
|
* decoder, and drops empty / `[DONE]` keep-alive events so the downstream
|
|
121
121
|
* `decodeChunk` sees one JSON string per element. The SSE channel emits a
|
|
122
122
|
* `Retry` control event on its error channel; we drop it here (we don't
|
|
123
|
-
* implement client-driven retries)
|
|
124
|
-
* `AIError`.
|
|
123
|
+
* implement client-driven retries). Decoder failures become provider output
|
|
124
|
+
* errors so the public error channel stays `AIError`.
|
|
125
125
|
*/
|
|
126
126
|
export declare const sseFraming: (bytes: Stream.Stream<Uint8Array, AIError>) => Stream.Stream<string, AIError>;
|
|
127
127
|
/**
|
package/dist/protocols/shared.js
CHANGED
|
@@ -154,10 +154,10 @@ export const errorText = (error) => {
|
|
|
154
154
|
* decoder, and drops empty / `[DONE]` keep-alive events so the downstream
|
|
155
155
|
* `decodeChunk` sees one JSON string per element. The SSE channel emits a
|
|
156
156
|
* `Retry` control event on its error channel; we drop it here (we don't
|
|
157
|
-
* implement client-driven retries)
|
|
158
|
-
* `AIError`.
|
|
157
|
+
* implement client-driven retries). Decoder failures become provider output
|
|
158
|
+
* errors so the public error channel stays `AIError`.
|
|
159
159
|
*/
|
|
160
|
-
export const sseFraming = (bytes) => bytes.pipe(Stream.decodeText(), Stream.pipeThroughChannel(Sse.decode()), Stream.catchTag("Retry", () => Stream.empty), Stream.filter((event) => event.data.length > 0 && event.data !== "[DONE]"), Stream.map((event) => event.data));
|
|
160
|
+
export const sseFraming = (bytes) => bytes.pipe(Stream.decodeText(), Stream.pipeThroughChannel(Sse.decode()), Stream.catchTag("Retry", () => Stream.empty), Stream.catchTag("SseError", (error) => Stream.fail(eventError("sse", error.message))), Stream.filter((event) => event.data.length > 0 && event.data !== "[DONE]"), Stream.map((event) => event.data));
|
|
161
161
|
/**
|
|
162
162
|
* Canonical invalid-request constructor. Lift one-line `const invalid =
|
|
163
163
|
* (message) => invalidRequest(message)` aliases out of every
|
package/dist/provider-error.js
CHANGED
|
@@ -35,7 +35,7 @@ export const isPayloadTooLarge = (message) => payloadPatterns.some((pattern) =>
|
|
|
35
35
|
export const isContextOverflowFailure = (failure) => failure instanceof AIError
|
|
36
36
|
? failure.reason._tag === "InvalidRequest" && failure.reason.classification === "context-overflow"
|
|
37
37
|
: Schema.is(ProviderErrorEvent)(failure) && failure.classification === "context-overflow";
|
|
38
|
-
const decodeJson = Schema.decodeUnknownOption(Schema.
|
|
38
|
+
const decodeJson = Schema.decodeUnknownOption(Schema.fromJsonString(Schema.Unknown));
|
|
39
39
|
const QUOTA_CODES = new Set(["insufficient_quota", "usage_not_included", "billing_error"]);
|
|
40
40
|
const SERVER_CODES = new Set([
|
|
41
41
|
"api_error",
|
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
import type { ProviderPackage } from "../provider-package.js";
|
|
2
2
|
import { Gemini } from "../protocols/gemini.js";
|
|
3
3
|
import { Route, type RouteDefaultsInput } from "../route/client.js";
|
|
4
|
-
import { type ModelID } from "../schema/index.js";
|
|
4
|
+
import { type ModelID, type ProviderOptions } from "../schema/index.js";
|
|
5
5
|
import { GoogleVertexShared } from "./google-vertex-shared.js";
|
|
6
|
-
export
|
|
7
|
-
|
|
6
|
+
export interface GeminiOptionsInput extends Gemini.OptionsInput {
|
|
7
|
+
readonly labels?: Readonly<Record<string, string>>;
|
|
8
|
+
}
|
|
9
|
+
export type GeminiProviderOptionsInput = ProviderOptions & {
|
|
10
|
+
readonly gemini?: GeminiOptionsInput;
|
|
11
|
+
};
|
|
8
12
|
export declare const id: string & import("effect/Brand").Brand<"AI.ProviderID">;
|
|
9
13
|
export type Config = RouteDefaultsInput & GoogleVertexShared.ApiKeyOptions & {
|
|
10
14
|
readonly baseURL?: string;
|
|
11
15
|
readonly location?: string;
|
|
12
16
|
readonly project?: string;
|
|
13
|
-
readonly providerOptions?:
|
|
17
|
+
readonly providerOptions?: GeminiProviderOptionsInput;
|
|
14
18
|
};
|
|
15
19
|
export type Settings = ProviderPackage.Settings & ({
|
|
16
20
|
readonly accessToken?: string;
|
|
@@ -22,7 +26,7 @@ export type Settings = ProviderPackage.Settings & ({
|
|
|
22
26
|
readonly baseURL?: string;
|
|
23
27
|
readonly location?: string;
|
|
24
28
|
readonly project?: string;
|
|
25
|
-
readonly providerOptions?:
|
|
29
|
+
readonly providerOptions?: GeminiProviderOptionsInput;
|
|
26
30
|
};
|
|
27
31
|
export declare const routes: Route<{
|
|
28
32
|
readonly contents: readonly {
|
|
@@ -39,8 +43,8 @@ export declare const routes: Route<{
|
|
|
39
43
|
} | {
|
|
40
44
|
readonly functionCall: {
|
|
41
45
|
readonly name: string;
|
|
42
|
-
readonly args: unknown;
|
|
43
46
|
readonly id?: string | undefined;
|
|
47
|
+
readonly args?: unknown;
|
|
44
48
|
};
|
|
45
49
|
readonly thoughtSignature?: string | undefined;
|
|
46
50
|
} | {
|
|
@@ -78,6 +82,9 @@ export declare const routes: Route<{
|
|
|
78
82
|
readonly threshold: string;
|
|
79
83
|
}[] | undefined;
|
|
80
84
|
readonly serviceTier?: string | undefined;
|
|
85
|
+
readonly labels?: {
|
|
86
|
+
readonly [x: string]: string;
|
|
87
|
+
} | undefined;
|
|
81
88
|
readonly systemInstruction?: {
|
|
82
89
|
readonly parts: readonly {
|
|
83
90
|
readonly text: string;
|
|
@@ -101,15 +108,15 @@ export declare const routes: Route<{
|
|
|
101
108
|
}, import("../route/transport/http.js").HttpPrepared<string>>[];
|
|
102
109
|
export declare const configure: (input?: Config) => {
|
|
103
110
|
id: string & import("effect/Brand").Brand<"AI.ProviderID">;
|
|
104
|
-
model: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<
|
|
111
|
+
model: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<GeminiProviderOptionsInput>;
|
|
105
112
|
configure: (input?: Config) => /*elided*/ any;
|
|
106
113
|
};
|
|
107
114
|
export declare const provider: {
|
|
108
115
|
id: string & import("effect/Brand").Brand<"AI.ProviderID">;
|
|
109
116
|
configure: (input?: Config) => {
|
|
110
117
|
id: string & import("effect/Brand").Brand<"AI.ProviderID">;
|
|
111
|
-
model: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<
|
|
118
|
+
model: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<GeminiProviderOptionsInput>;
|
|
112
119
|
configure: /*elided*/ any;
|
|
113
120
|
};
|
|
114
121
|
};
|
|
115
|
-
export declare const model: ProviderPackage.Definition<Settings,
|
|
122
|
+
export declare const model: ProviderPackage.Definition<Settings, GeminiProviderOptionsInput>["model"];
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
1
2
|
import { Gemini } from "../protocols/gemini.js";
|
|
3
|
+
import { ProviderShared } from "../protocols/shared.js";
|
|
2
4
|
import { Auth } from "../route/auth.js";
|
|
3
5
|
import { Route } from "../route/client.js";
|
|
4
6
|
import { Endpoint } from "../route/endpoint.js";
|
|
@@ -6,11 +8,26 @@ import { Framing } from "../route/framing.js";
|
|
|
6
8
|
import { ProviderID } from "../schema/index.js";
|
|
7
9
|
import { GoogleVertexShared } from "./google-vertex-shared.js";
|
|
8
10
|
export const id = ProviderID.make("google-vertex");
|
|
11
|
+
const fromRequest = Effect.fn("GoogleVertex.fromRequest")(function* (request) {
|
|
12
|
+
const body = yield* Gemini.protocol.body.from(request);
|
|
13
|
+
const value = request.providerOptions?.gemini?.labels;
|
|
14
|
+
const labels = ProviderShared.isRecord(value)
|
|
15
|
+
? Object.fromEntries(Object.entries(value).filter((entry) => typeof entry[1] === "string"))
|
|
16
|
+
: undefined;
|
|
17
|
+
return { ...body, labels };
|
|
18
|
+
});
|
|
19
|
+
const protocol = {
|
|
20
|
+
...Gemini.protocol,
|
|
21
|
+
body: {
|
|
22
|
+
...Gemini.protocol.body,
|
|
23
|
+
from: fromRequest,
|
|
24
|
+
},
|
|
25
|
+
};
|
|
9
26
|
const route = Route.make({
|
|
10
27
|
id: "google-vertex-gemini",
|
|
11
28
|
provider: id,
|
|
12
29
|
providerMetadataKey: "google",
|
|
13
|
-
protocol
|
|
30
|
+
protocol,
|
|
14
31
|
endpoint: Endpoint.path(({ request }) => {
|
|
15
32
|
const model = String(request.model.id);
|
|
16
33
|
return `/${model.startsWith("endpoints/") ? model : `models/${model}`}:streamGenerateContent?alt=sse`;
|
|
@@ -22,8 +22,8 @@ export declare const routes: import("../route/client.js").Route<{
|
|
|
22
22
|
} | {
|
|
23
23
|
readonly functionCall: {
|
|
24
24
|
readonly name: string;
|
|
25
|
-
readonly args: unknown;
|
|
26
25
|
readonly id?: string | undefined;
|
|
26
|
+
readonly args?: unknown;
|
|
27
27
|
};
|
|
28
28
|
readonly thoughtSignature?: string | undefined;
|
|
29
29
|
} | {
|
|
@@ -61,6 +61,9 @@ export declare const routes: import("../route/client.js").Route<{
|
|
|
61
61
|
readonly threshold: string;
|
|
62
62
|
}[] | undefined;
|
|
63
63
|
readonly serviceTier?: string | undefined;
|
|
64
|
+
readonly labels?: {
|
|
65
|
+
readonly [x: string]: string;
|
|
66
|
+
} | undefined;
|
|
64
67
|
readonly systemInstruction?: {
|
|
65
68
|
readonly parts: readonly {
|
|
66
69
|
readonly text: string;
|
package/dist/schema/errors.js
CHANGED
|
@@ -132,7 +132,7 @@ export const AIErrorReason = Schema.Union([
|
|
|
132
132
|
InvalidProviderOutputReason,
|
|
133
133
|
UnknownProviderReason,
|
|
134
134
|
]).pipe(Schema.toTaggedUnion("_tag"));
|
|
135
|
-
export class AIError extends Schema.
|
|
135
|
+
export class AIError extends Schema.TaggedError()("AI.Error", {
|
|
136
136
|
module: Schema.String,
|
|
137
137
|
method: Schema.String,
|
|
138
138
|
reason: AIErrorReason,
|
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-17603",
|
|
4
4
|
"name": "@opencode-ai/ai",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@clack/prompts": "1.0.0-alpha.1",
|
|
32
|
-
"@effect/platform-node": "4.0.0-beta.
|
|
33
|
-
"@opencode-ai/http-recorder": "0.0.0-dev-
|
|
32
|
+
"@effect/platform-node": "4.0.0-beta.107",
|
|
33
|
+
"@opencode-ai/http-recorder": "0.0.0-dev-17603",
|
|
34
34
|
"@tsconfig/bun": "1.0.9",
|
|
35
35
|
"@types/bun": "1.3.13",
|
|
36
36
|
"@typescript/native-preview": "7.0.0-dev.20251207.1",
|
|
@@ -39,9 +39,9 @@
|
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@smithy/eventstream-codec": "4.2.14",
|
|
41
41
|
"@smithy/util-utf8": "4.2.2",
|
|
42
|
-
"@opencode-ai/schema": "0.0.0-dev-
|
|
42
|
+
"@opencode-ai/schema": "0.0.0-dev-17603",
|
|
43
43
|
"aws4fetch": "1.0.20",
|
|
44
|
-
"effect": "4.0.0-beta.
|
|
44
|
+
"effect": "4.0.0-beta.107",
|
|
45
45
|
"google-auth-library": "10.5.0"
|
|
46
46
|
}
|
|
47
47
|
}
|