@opencode/ai 0.0.0-beta-19425 → 0.0.0-beta-19500
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 +4 -1
- package/dist/protocols/open-responses-channel.d.ts +2 -0
- package/dist/protocols/open-responses-channel.js +2 -2
- package/dist/protocols/open-responses-continuation.d.ts +7 -3
- package/dist/protocols/open-responses-continuation.js +8 -6
- package/dist/protocols/open-responses.d.ts +137 -2
- package/dist/protocols/open-responses.js +24 -5
- package/dist/provider-package.d.ts +4 -0
- package/dist/providers/alibaba.d.ts +1 -2
- package/dist/providers/alibaba.js +12 -4
- package/dist/providers/amazon-bedrock-mantle.d.ts +4 -62
- package/dist/providers/amazon-bedrock-mantle.js +23 -20
- package/dist/providers/amazon-bedrock.js +3 -3
- package/dist/providers/anthropic-compatible.d.ts +1 -2
- package/dist/providers/anthropic-compatible.js +18 -12
- package/dist/providers/anthropic.d.ts +1 -2
- package/dist/providers/anthropic.js +12 -9
- package/dist/providers/azure.d.ts +1 -2
- package/dist/providers/azure.js +14 -14
- package/dist/providers/baseten.d.ts +2 -3
- package/dist/providers/baseten.js +6 -6
- package/dist/providers/cerebras.d.ts +2 -3
- package/dist/providers/cerebras.js +6 -6
- package/dist/providers/cloudflare-ai-gateway.d.ts +1 -2
- package/dist/providers/cloudflare-ai-gateway.js +16 -10
- package/dist/providers/cloudflare-workers-ai.d.ts +1 -2
- package/dist/providers/cloudflare-workers-ai.js +15 -9
- package/dist/providers/deepinfra.d.ts +2 -3
- package/dist/providers/deepinfra.js +6 -6
- package/dist/providers/deepseek.d.ts +2 -3
- package/dist/providers/deepseek.js +6 -6
- package/dist/providers/fireworks.d.ts +2 -3
- package/dist/providers/fireworks.js +6 -6
- package/dist/providers/google-vertex-chat.d.ts +2 -3
- package/dist/providers/google-vertex-chat.js +12 -12
- package/dist/providers/google-vertex-messages.d.ts +2 -3
- package/dist/providers/google-vertex-messages.js +12 -12
- package/dist/providers/google-vertex-responses.d.ts +2 -3
- package/dist/providers/google-vertex-responses.js +12 -12
- package/dist/providers/google-vertex-shared.js +14 -3
- package/dist/providers/google-vertex.d.ts +1 -2
- package/dist/providers/google-vertex.js +18 -12
- package/dist/providers/google.d.ts +2 -3
- package/dist/providers/google.js +6 -6
- package/dist/providers/groq.d.ts +2 -3
- package/dist/providers/groq.js +6 -6
- package/dist/providers/meta.d.ts +2 -3
- package/dist/providers/meta.js +6 -6
- package/dist/providers/minimax/chat.js +6 -6
- package/dist/providers/minimax/responses.js +6 -6
- package/dist/providers/minimax.d.ts +2 -3
- package/dist/providers/minimax.js +6 -6
- package/dist/providers/mistral.d.ts +2 -3
- package/dist/providers/mistral.js +6 -6
- package/dist/providers/moonshot/messages.js +6 -6
- package/dist/providers/moonshot/responses.js +6 -6
- package/dist/providers/moonshot.d.ts +2 -3
- package/dist/providers/moonshot.js +6 -6
- package/dist/providers/openai-compatible-responses.d.ts +2 -3
- package/dist/providers/openai-compatible-responses.js +7 -7
- package/dist/providers/openai-compatible.d.ts +2 -3
- package/dist/providers/openai-compatible.js +7 -7
- package/dist/providers/openai.d.ts +2 -3
- package/dist/providers/openai.js +9 -9
- package/dist/providers/openrouter.d.ts +2 -3
- package/dist/providers/openrouter.js +6 -6
- package/dist/providers/togetherai.d.ts +2 -3
- package/dist/providers/togetherai.js +6 -6
- package/dist/providers/xai.d.ts +2 -3
- package/dist/providers/xai.js +10 -6
- package/dist/providers/zai-coding-plan/messages.js +6 -6
- package/dist/providers/zai-coding-plan/responses.js +6 -6
- package/dist/providers/zai-coding-plan.d.ts +2 -3
- package/dist/providers/zai-coding-plan.js +6 -6
- package/dist/providers/zai.d.ts +2 -3
- package/dist/providers/zai.js +6 -6
- package/dist/route/client.js +5 -2
- package/dist/schema/errors.d.ts +12 -0
- package/dist/schema/errors.js +11 -0
- package/package.json +3 -3
|
@@ -1432,7 +1432,10 @@ export const transport = () => {
|
|
|
1432
1432
|
};
|
|
1433
1433
|
};
|
|
1434
1434
|
function requiredBetaHeaders(body) {
|
|
1435
|
-
|
|
1435
|
+
// Always request interleaved thinking. The API accepts the header on any
|
|
1436
|
+
// model and ignores it where unsupported, while manual-thinking models need
|
|
1437
|
+
// it for thinking between tool calls.
|
|
1438
|
+
const betas = ["interleaved-thinking-2025-05-14"];
|
|
1436
1439
|
const requestsCompaction = (body.context_management?.edits.length ?? 0) > 0;
|
|
1437
1440
|
const replaysCompaction = body.messages.some((message) => message.content.some((block) => block.type === "compaction"));
|
|
1438
1441
|
if (requestsCompaction || replaysCompaction)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Headers } from "effect/unstable/http";
|
|
2
2
|
import { HttpTransport, type Transport, type WebSocketChannelDriver } from "../route/transport/index.js";
|
|
3
|
+
import { OpenResponsesContinuation } from "./open-responses-continuation.js";
|
|
3
4
|
export interface Options {
|
|
4
5
|
readonly id: string;
|
|
5
6
|
readonly name: string;
|
|
@@ -7,6 +8,7 @@ export interface Options {
|
|
|
7
8
|
readonly enabled?: (url: string) => boolean;
|
|
8
9
|
readonly url?: (url: string) => string;
|
|
9
10
|
readonly headers?: (headers: Headers.Headers) => Headers.Headers;
|
|
11
|
+
readonly continuation?: OpenResponsesContinuation.Shape;
|
|
10
12
|
}
|
|
11
13
|
export interface Prepared {
|
|
12
14
|
readonly http: HttpTransport.HttpPrepared<string>;
|
|
@@ -10,7 +10,6 @@ const WebSocketResponseCreate = Schema.StructWithRest(Schema.Struct({ type: Sche
|
|
|
10
10
|
]);
|
|
11
11
|
const decodeMessage = ProviderShared.validateWith(Schema.decodeUnknownEffect(WebSocketResponseCreate));
|
|
12
12
|
const encodeMessage = Schema.encodeSync(Schema.fromJsonString(WebSocketResponseCreate));
|
|
13
|
-
const decodeEvent = Schema.decodeUnknownEffect(OpenResponses.protocol.stream.event);
|
|
14
13
|
const message = (body) => Effect.gen(function* () {
|
|
15
14
|
if (!ProviderShared.isRecord(body))
|
|
16
15
|
return yield* ProviderShared.invalidRequest("Open Responses WebSocket body must be a JSON object");
|
|
@@ -28,7 +27,7 @@ const driver = (options, body) => {
|
|
|
28
27
|
return { message: body, mode: "full" };
|
|
29
28
|
}),
|
|
30
29
|
observe: (_create, frame) => Effect.gen(function* () {
|
|
31
|
-
const event = yield*
|
|
30
|
+
const event = yield* OpenResponses.decodeChannelEvent(frame).pipe(Effect.mapError((cause) => ProviderShared.eventError(options.id, `Invalid ${options.name} WebSocket event`, frame, cause)));
|
|
32
31
|
if (terminal)
|
|
33
32
|
return yield* ProviderShared.eventError(options.id, `${options.name} emitted ${event.type} after a terminal event`, frame);
|
|
34
33
|
if (event.type === "error") {
|
|
@@ -97,6 +96,7 @@ export const transport = (options) => {
|
|
|
97
96
|
request: create.request,
|
|
98
97
|
message: create.message,
|
|
99
98
|
base,
|
|
99
|
+
continuation: options.continuation,
|
|
100
100
|
}),
|
|
101
101
|
};
|
|
102
102
|
})
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import type { WebSocketChannelDriver } from "../route/transport/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Fields to send next to `previous_response_id` on an incremental step, or undefined to send the step in full.
|
|
4
|
+
* Whether omitted fields carry over from the continued response is provider behavior the route must know.
|
|
5
|
+
*/
|
|
6
|
+
export type Shape = (request: Readonly<Record<string, unknown>>) => Readonly<Record<string, unknown>> | undefined;
|
|
2
7
|
export interface DriverInput {
|
|
3
8
|
readonly id: string;
|
|
4
9
|
readonly name: string;
|
|
5
10
|
readonly request: Readonly<Record<string, unknown>>;
|
|
6
11
|
readonly message: string;
|
|
7
12
|
readonly base: WebSocketChannelDriver;
|
|
13
|
+
readonly continuation?: Shape;
|
|
8
14
|
}
|
|
9
15
|
export declare const driver: (input: DriverInput) => WebSocketChannelDriver;
|
|
10
|
-
export
|
|
11
|
-
readonly driver: (input: DriverInput) => WebSocketChannelDriver;
|
|
12
|
-
};
|
|
16
|
+
export * as OpenResponsesContinuation from "./open-responses-continuation.js";
|
|
@@ -4,7 +4,6 @@ import * as ProviderShared from "./shared.js";
|
|
|
4
4
|
import { OpenResponses } from "./open-responses.js";
|
|
5
5
|
const PROTOCOL = "open-responses.websocket.v1";
|
|
6
6
|
const VERSION = 1;
|
|
7
|
-
const decodeEvent = Schema.decodeUnknownEffect(OpenResponses.protocol.stream.event);
|
|
8
7
|
const checkpointValue = (checkpoint) => {
|
|
9
8
|
if (checkpoint?.protocol !== PROTOCOL || !ProviderShared.isRecord(checkpoint.value))
|
|
10
9
|
return undefined;
|
|
@@ -104,21 +103,24 @@ const rejected = (observation, recovery) => ({
|
|
|
104
103
|
});
|
|
105
104
|
export const driver = (input) => {
|
|
106
105
|
const { previous_response_id: _previousResponseID, ...request } = input.request;
|
|
106
|
+
const shape = input.continuation ?? ((fields) => fields);
|
|
107
107
|
let output = [];
|
|
108
108
|
return {
|
|
109
109
|
create: (checkpoint) => Effect.sync(() => {
|
|
110
110
|
output = [];
|
|
111
111
|
const previous = checkpointValue(checkpoint);
|
|
112
|
-
|
|
113
|
-
|
|
112
|
+
// Ask the route first: diffing the whole history is wasted when it declines the continuation.
|
|
113
|
+
const fields = previous ? shape(request) : undefined;
|
|
114
|
+
const delta = previous && fields ? incremental(request, previous) : undefined;
|
|
115
|
+
if (!previous || !fields || !delta)
|
|
114
116
|
return { message: ProviderShared.encodeJson(request), mode: "full" };
|
|
115
117
|
return {
|
|
116
|
-
message: ProviderShared.encodeJson({ ...
|
|
118
|
+
message: ProviderShared.encodeJson({ ...fields, input: delta, previous_response_id: previous.responseID }),
|
|
117
119
|
mode: "incremental",
|
|
118
120
|
};
|
|
119
121
|
}),
|
|
120
122
|
observe: (create, frame) => Effect.gen(function* () {
|
|
121
|
-
const event = yield*
|
|
123
|
+
const event = yield* OpenResponses.decodeChannelEvent(frame).pipe(Effect.mapError((cause) => ProviderShared.eventError(input.id, `Invalid ${input.name} WebSocket event`, frame, cause)));
|
|
122
124
|
const observation = yield* input.base.observe(create, frame);
|
|
123
125
|
if (event.type === "response.output_item.done" && event.item)
|
|
124
126
|
output.push(event.item);
|
|
@@ -165,4 +167,4 @@ export const driver = (input) => {
|
|
|
165
167
|
}),
|
|
166
168
|
};
|
|
167
169
|
};
|
|
168
|
-
export
|
|
170
|
+
export * as OpenResponsesContinuation from "./open-responses-continuation.js";
|
|
@@ -585,7 +585,7 @@ export declare const decodeKnownErrorEvent: (event: Event) => Effect.Effect<{
|
|
|
585
585
|
readonly param?: string | null | undefined;
|
|
586
586
|
readonly status_code?: number | undefined;
|
|
587
587
|
}, Schema.SchemaError, never>;
|
|
588
|
-
export declare const Event: Schema.StructWithRest<Schema.Struct<{
|
|
588
|
+
export declare const Event: Schema.decodeTo<Schema.toType<Schema.StructWithRest<Schema.Struct<{
|
|
589
589
|
readonly type: Schema.String;
|
|
590
590
|
readonly delta: Schema.optional<Schema.String>;
|
|
591
591
|
readonly arguments: Schema.optional<Schema.String>;
|
|
@@ -648,11 +648,146 @@ export declare const Event: Schema.StructWithRest<Schema.Struct<{
|
|
|
648
648
|
readonly status: Schema.optional<Schema.Unknown>;
|
|
649
649
|
readonly status_code: Schema.optional<Schema.Unknown>;
|
|
650
650
|
readonly headers: Schema.optional<Schema.Unknown>;
|
|
651
|
-
}>, readonly [Schema.$Record<Schema.String, Schema.Unknown>]
|
|
651
|
+
}>, readonly [Schema.$Record<Schema.String, Schema.Unknown>]>>, Schema.StructWithRest<Schema.Struct<{
|
|
652
|
+
readonly type: Schema.String;
|
|
653
|
+
readonly delta: Schema.optional<Schema.String>;
|
|
654
|
+
readonly arguments: Schema.optional<Schema.String>;
|
|
655
|
+
readonly text: Schema.optional<Schema.String>;
|
|
656
|
+
readonly item_id: Schema.optional<Schema.String>;
|
|
657
|
+
readonly output_index: Schema.optional<Schema.Number>;
|
|
658
|
+
readonly summary_index: Schema.optional<Schema.Number>;
|
|
659
|
+
readonly item: Schema.optional<Schema.NullOr<Schema.StructWithRest<Schema.Struct<{
|
|
660
|
+
readonly type: Schema.String;
|
|
661
|
+
readonly id: Schema.optional<Schema.String>;
|
|
662
|
+
readonly call_id: Schema.optional<Schema.String>;
|
|
663
|
+
readonly name: Schema.optional<Schema.String>;
|
|
664
|
+
readonly namespace: Schema.optional<Schema.String>;
|
|
665
|
+
readonly arguments: Schema.optional<Schema.String>;
|
|
666
|
+
readonly encrypted_content: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
667
|
+
}>, readonly [Schema.$Record<Schema.String, Schema.Unknown>]>>>;
|
|
668
|
+
readonly response: Schema.optional<Schema.StructWithRest<Schema.Struct<{
|
|
669
|
+
readonly id: Schema.optional<Schema.String>;
|
|
670
|
+
readonly service_tier: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
671
|
+
readonly incomplete_details: Schema.optional<Schema.NullOr<Schema.Struct<{
|
|
672
|
+
readonly reason: Schema.optional<Schema.String>;
|
|
673
|
+
}>>>;
|
|
674
|
+
readonly output: Schema.optional<Schema.$Array<Schema.StructWithRest<Schema.Struct<{
|
|
675
|
+
readonly type: Schema.String;
|
|
676
|
+
readonly id: Schema.optional<Schema.String>;
|
|
677
|
+
readonly call_id: Schema.optional<Schema.String>;
|
|
678
|
+
readonly name: Schema.optional<Schema.String>;
|
|
679
|
+
readonly namespace: Schema.optional<Schema.String>;
|
|
680
|
+
readonly arguments: Schema.optional<Schema.String>;
|
|
681
|
+
readonly encrypted_content: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
682
|
+
}>, readonly [Schema.$Record<Schema.String, Schema.Unknown>]>>>;
|
|
683
|
+
readonly usage: Schema.optional<Schema.NullOr<Schema.Struct<{
|
|
684
|
+
readonly input_tokens: Schema.optional<Schema.Number>;
|
|
685
|
+
readonly input_tokens_details: Schema.optional<Schema.NullOr<Schema.Struct<{
|
|
686
|
+
readonly cached_tokens: Schema.optional<Schema.Number>;
|
|
687
|
+
readonly cache_write_tokens: Schema.optional<Schema.Number>;
|
|
688
|
+
}>>>;
|
|
689
|
+
readonly output_tokens: Schema.optional<Schema.Number>;
|
|
690
|
+
readonly output_tokens_details: Schema.optional<Schema.NullOr<Schema.Struct<{
|
|
691
|
+
readonly reasoning_tokens: Schema.optional<Schema.Number>;
|
|
692
|
+
}>>>;
|
|
693
|
+
readonly total_tokens: Schema.optional<Schema.Number>;
|
|
694
|
+
}>>>;
|
|
695
|
+
readonly error: Schema.optional<Schema.NullOr<Schema.Struct<{
|
|
696
|
+
readonly type: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
697
|
+
readonly code: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
698
|
+
readonly message: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
699
|
+
readonly param: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
700
|
+
}>>>;
|
|
701
|
+
}>, readonly [Schema.$Record<Schema.String, Schema.Unknown>]>>;
|
|
702
|
+
readonly code: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
703
|
+
readonly message: Schema.optional<Schema.String>;
|
|
704
|
+
readonly param: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
705
|
+
readonly error: Schema.optional<Schema.NullOr<Schema.Struct<{
|
|
706
|
+
readonly type: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
707
|
+
readonly code: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
708
|
+
readonly message: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
709
|
+
readonly param: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
710
|
+
}>>>;
|
|
711
|
+
readonly status: Schema.optional<Schema.Unknown>;
|
|
712
|
+
readonly status_code: Schema.optional<Schema.Unknown>;
|
|
713
|
+
readonly headers: Schema.optional<Schema.Unknown>;
|
|
714
|
+
}>, readonly [Schema.$Record<Schema.String, Schema.Unknown>]>, never, never>;
|
|
652
715
|
export type Event = Schema.Schema.Type<typeof Event>;
|
|
653
716
|
export type NormalizedEvent = Event & {
|
|
654
717
|
readonly item?: OutputItem | null;
|
|
655
718
|
};
|
|
719
|
+
/**
|
|
720
|
+
* Decodes one WebSocket frame. xAI answers a rejected `response.create` with `{ "error": { "message", "type" } }` and no
|
|
721
|
+
* event type; that envelope reads as an error event so the failure classifies instead of failing decoding.
|
|
722
|
+
*/
|
|
723
|
+
export declare const decodeChannelEvent: (frame: string) => Effect.Effect<{
|
|
724
|
+
readonly [x: string]: unknown;
|
|
725
|
+
readonly type: string;
|
|
726
|
+
readonly status?: unknown;
|
|
727
|
+
readonly code?: string | null | undefined;
|
|
728
|
+
readonly message?: string | undefined;
|
|
729
|
+
readonly headers?: unknown;
|
|
730
|
+
readonly text?: string | undefined;
|
|
731
|
+
readonly error?: {
|
|
732
|
+
readonly type?: string | null | undefined;
|
|
733
|
+
readonly code?: string | null | undefined;
|
|
734
|
+
readonly message?: string | null | undefined;
|
|
735
|
+
readonly param?: string | null | undefined;
|
|
736
|
+
} | null | undefined;
|
|
737
|
+
readonly item?: {
|
|
738
|
+
readonly [x: string]: unknown;
|
|
739
|
+
readonly type: string;
|
|
740
|
+
readonly id?: string | undefined;
|
|
741
|
+
readonly name?: string | undefined;
|
|
742
|
+
readonly namespace?: string | undefined;
|
|
743
|
+
readonly arguments?: string | undefined;
|
|
744
|
+
readonly encrypted_content?: string | null | undefined;
|
|
745
|
+
readonly call_id?: string | undefined;
|
|
746
|
+
} | null | undefined;
|
|
747
|
+
readonly delta?: string | undefined;
|
|
748
|
+
readonly response?: {
|
|
749
|
+
readonly [x: string]: unknown;
|
|
750
|
+
readonly id?: string | undefined;
|
|
751
|
+
readonly output?: readonly {
|
|
752
|
+
readonly [x: string]: unknown;
|
|
753
|
+
readonly type: string;
|
|
754
|
+
readonly id?: string | undefined;
|
|
755
|
+
readonly name?: string | undefined;
|
|
756
|
+
readonly namespace?: string | undefined;
|
|
757
|
+
readonly arguments?: string | undefined;
|
|
758
|
+
readonly encrypted_content?: string | null | undefined;
|
|
759
|
+
readonly call_id?: string | undefined;
|
|
760
|
+
}[] | undefined;
|
|
761
|
+
readonly error?: {
|
|
762
|
+
readonly type?: string | null | undefined;
|
|
763
|
+
readonly code?: string | null | undefined;
|
|
764
|
+
readonly message?: string | null | undefined;
|
|
765
|
+
readonly param?: string | null | undefined;
|
|
766
|
+
} | null | undefined;
|
|
767
|
+
readonly usage?: {
|
|
768
|
+
readonly input_tokens?: number | undefined;
|
|
769
|
+
readonly output_tokens?: number | undefined;
|
|
770
|
+
readonly output_tokens_details?: {
|
|
771
|
+
readonly reasoning_tokens?: number | undefined;
|
|
772
|
+
} | null | undefined;
|
|
773
|
+
readonly total_tokens?: number | undefined;
|
|
774
|
+
readonly input_tokens_details?: {
|
|
775
|
+
readonly cached_tokens?: number | undefined;
|
|
776
|
+
readonly cache_write_tokens?: number | undefined;
|
|
777
|
+
} | null | undefined;
|
|
778
|
+
} | null | undefined;
|
|
779
|
+
readonly service_tier?: string | null | undefined;
|
|
780
|
+
readonly incomplete_details?: {
|
|
781
|
+
readonly reason?: string | undefined;
|
|
782
|
+
} | null | undefined;
|
|
783
|
+
} | undefined;
|
|
784
|
+
readonly arguments?: string | undefined;
|
|
785
|
+
readonly param?: string | null | undefined;
|
|
786
|
+
readonly status_code?: unknown;
|
|
787
|
+
readonly item_id?: string | undefined;
|
|
788
|
+
readonly output_index?: number | undefined;
|
|
789
|
+
readonly summary_index?: number | undefined;
|
|
790
|
+
}, Schema.SchemaError, never>;
|
|
656
791
|
export interface ProviderAdapter {
|
|
657
792
|
readonly id: string;
|
|
658
793
|
readonly name: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Effect, Option, Schema } from "effect";
|
|
1
|
+
import { Effect, Option, Schema, SchemaGetter } from "effect";
|
|
2
2
|
import { HttpTransport } from "../route/transport/index.js";
|
|
3
3
|
import { Protocol } from "../route/protocol.js";
|
|
4
4
|
import { AIError, LLMEvent, ProviderInternalError, Usage, } from "../schema/index.js";
|
|
@@ -232,9 +232,8 @@ export const StreamItem = Schema.StructWithRest(Schema.Struct({
|
|
|
232
232
|
arguments: Schema.optional(Schema.String),
|
|
233
233
|
encrypted_content: optionalNull(Schema.String),
|
|
234
234
|
}), [Schema.Record(Schema.String, Schema.Unknown)]);
|
|
235
|
-
//
|
|
236
|
-
// response failures under `response.error`.
|
|
237
|
-
// event-level `error` envelope, so accept all three shapes here.
|
|
235
|
+
// Responses-compatible providers put streaming error details at the top level or
|
|
236
|
+
// under `error`, and response failures under `response.error`. Accept all three shapes.
|
|
238
237
|
// https://www.openresponses.org/specification
|
|
239
238
|
const OpenResponsesErrorPayload = Schema.Struct({
|
|
240
239
|
type: optionalNull(Schema.String),
|
|
@@ -287,7 +286,27 @@ export const Event = Schema.StructWithRest(Schema.Struct({
|
|
|
287
286
|
status: Schema.optional(Schema.Unknown),
|
|
288
287
|
status_code: Schema.optional(Schema.Unknown),
|
|
289
288
|
headers: Schema.optional(Schema.Unknown),
|
|
290
|
-
}), [Schema.Record(Schema.String, Schema.Unknown)])
|
|
289
|
+
}), [Schema.Record(Schema.String, Schema.Unknown)]).pipe(Schema.decode({
|
|
290
|
+
decode: SchemaGetter.transform((event) => {
|
|
291
|
+
if (event.type !== "error" || event.error != null)
|
|
292
|
+
return event;
|
|
293
|
+
const { code, message, param, ...rest } = event;
|
|
294
|
+
if (code === undefined && message === undefined && param === undefined)
|
|
295
|
+
return event;
|
|
296
|
+
// Flat errors (for example, Meta's) can also arrive through generic Responses endpoints.
|
|
297
|
+
return { ...rest, error: { code, message, param } };
|
|
298
|
+
}),
|
|
299
|
+
encode: SchemaGetter.passthrough(),
|
|
300
|
+
}));
|
|
301
|
+
const decodeEventValue = Schema.decodeUnknownEffect(Event);
|
|
302
|
+
const decodeFrame = Schema.decodeUnknownEffect(ProviderShared.Json);
|
|
303
|
+
/**
|
|
304
|
+
* Decodes one WebSocket frame. xAI answers a rejected `response.create` with `{ "error": { "message", "type" } }` and no
|
|
305
|
+
* event type; that envelope reads as an error event so the failure classifies instead of failing decoding.
|
|
306
|
+
*/
|
|
307
|
+
export const decodeChannelEvent = (frame) => decodeFrame(frame).pipe(Effect.flatMap((value) => decodeEventValue(ProviderShared.isRecord(value) && value.type === undefined && ProviderShared.isRecord(value.error)
|
|
308
|
+
? { ...value, type: "error" }
|
|
309
|
+
: value)));
|
|
291
310
|
const BASE_ADAPTER = { id: ADAPTER, name: NAME };
|
|
292
311
|
// =============================================================================
|
|
293
312
|
// Request Lowering
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import type { LanguageModel, ProviderOptions } from "./schema/index.js";
|
|
2
2
|
import type { CompactionOperations } from "./route/client.js";
|
|
3
|
+
/**
|
|
4
|
+
* Flat, serializable settings for `model(modelID, settings)`. Each entrypoint declares the connection keys it
|
|
5
|
+
* reads; every other key is a request option for the route's protocol.
|
|
6
|
+
*/
|
|
3
7
|
export interface Settings extends Readonly<Record<string, unknown>> {
|
|
4
8
|
readonly baseURL?: string;
|
|
5
9
|
readonly headers?: Readonly<Record<string, string>>;
|
|
@@ -20,9 +20,8 @@ type Location = AtLeastOne<{
|
|
|
20
20
|
export type Config = Location & Omit<RouteDefaultsInput, "providerOptions"> & ProviderAuthOption<"optional"> & {
|
|
21
21
|
readonly providerOptions?: ChatOptionsInput | MessagesOptionsInput | ResponsesOptionsInput;
|
|
22
22
|
};
|
|
23
|
-
export type Settings<Options = ChatOptionsInput> = Location & ProviderPackage.Settings & {
|
|
23
|
+
export type Settings<Options = ChatOptionsInput> = Location & ProviderPackage.Settings & Options & {
|
|
24
24
|
readonly apiKey?: string;
|
|
25
|
-
readonly providerOptions?: Options;
|
|
26
25
|
};
|
|
27
26
|
export declare const routes: (Route<{
|
|
28
27
|
readonly model: string;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Struct } from "effect";
|
|
1
2
|
import { AlibabaChat } from "../protocols/alibaba-chat.js";
|
|
2
3
|
import { AlibabaMessages } from "../protocols/alibaba-messages.js";
|
|
3
4
|
import { AlibabaResponses } from "../protocols/alibaba-responses.js";
|
|
@@ -5,7 +6,7 @@ import { AuthOptions } from "../route/auth-options.js";
|
|
|
5
6
|
import { Route } from "../route/client.js";
|
|
6
7
|
import { Endpoint } from "../route/endpoint.js";
|
|
7
8
|
import { Framing } from "../route/framing.js";
|
|
8
|
-
import { ProviderID, ToolDefinition } from "../schema/index.js";
|
|
9
|
+
import { ProviderConfigurationError, ProviderID, ToolDefinition } from "../schema/index.js";
|
|
9
10
|
export const id = ProviderID.make("alibaba");
|
|
10
11
|
const hosts = new Map([
|
|
11
12
|
["ap-southeast-1", "dashscope-intl.aliyuncs.com"],
|
|
@@ -48,9 +49,12 @@ export const configure = (input) => {
|
|
|
48
49
|
: `${workspaceID}.${region}.maas.aliyuncs.com`;
|
|
49
50
|
if (baseURL === undefined) {
|
|
50
51
|
if (region === undefined)
|
|
51
|
-
throw new
|
|
52
|
+
throw new ProviderConfigurationError({ provider: id, message: "Alibaba requires region or baseURL" });
|
|
52
53
|
if (host === undefined)
|
|
53
|
-
throw new
|
|
54
|
+
throw new ProviderConfigurationError({
|
|
55
|
+
provider: id,
|
|
56
|
+
message: `Alibaba region ${region} requires workspaceID or baseURL`,
|
|
57
|
+
});
|
|
54
58
|
}
|
|
55
59
|
const opts = { ...rest, auth: AuthOptions.bearer(input, ["DASHSCOPE_API_KEY", "ALIBABA_API_KEY"]) };
|
|
56
60
|
const common = { ...opts, endpoint: { baseURL: baseURL ?? `https://${host}/compatible-mode/v1` } };
|
|
@@ -70,7 +74,11 @@ export const messagesModel = (id, input) => fromSettings(input).messages(id);
|
|
|
70
74
|
export const responsesModel = (id, input) => fromSettings(input).responses(id);
|
|
71
75
|
function fromSettings(input) {
|
|
72
76
|
const { body, ...rest } = input;
|
|
73
|
-
return configure({
|
|
77
|
+
return configure({
|
|
78
|
+
...rest,
|
|
79
|
+
http: body === undefined ? undefined : { body },
|
|
80
|
+
providerOptions: Struct.omit(rest, ["apiKey", "baseURL", "headers", "region", "workspaceID"]),
|
|
81
|
+
});
|
|
74
82
|
}
|
|
75
83
|
export const webSearch = () => hostedTool("web_search", "Search the web with Alibaba's hosted search tool.");
|
|
76
84
|
export const webExtractor = () => hostedTool("web_extractor", "Extract web page content with Alibaba's hosted tool.");
|
|
@@ -17,7 +17,7 @@ export type Config = RouteDefaultsInput & {
|
|
|
17
17
|
readonly region?: string;
|
|
18
18
|
readonly providerOptions?: OpenAIProviderOptionsInput;
|
|
19
19
|
};
|
|
20
|
-
export
|
|
20
|
+
export type Settings = ProviderPackage.Settings & OpenAIProviderOptionsInput & {
|
|
21
21
|
readonly apiKey?: string;
|
|
22
22
|
readonly auth?: "bearer" | "sigv4";
|
|
23
23
|
readonly baseURL?: string;
|
|
@@ -25,8 +25,7 @@ export interface Settings extends ProviderPackage.Settings {
|
|
|
25
25
|
readonly profile?: string;
|
|
26
26
|
readonly region?: string;
|
|
27
27
|
readonly topP?: number;
|
|
28
|
-
|
|
29
|
-
}
|
|
28
|
+
};
|
|
30
29
|
export declare const routes: (Route<{
|
|
31
30
|
readonly model: string;
|
|
32
31
|
readonly messages: readonly ({
|
|
@@ -237,34 +236,6 @@ export declare const routes: (Route<{
|
|
|
237
236
|
readonly type: "input_video";
|
|
238
237
|
readonly video_url: string;
|
|
239
238
|
})[];
|
|
240
|
-
} | {
|
|
241
|
-
readonly [x: string]: unknown;
|
|
242
|
-
readonly id: string;
|
|
243
|
-
readonly type: "computer_call";
|
|
244
|
-
readonly status?: string | undefined;
|
|
245
|
-
readonly action?: {
|
|
246
|
-
readonly [x: string]: unknown;
|
|
247
|
-
} | null | undefined;
|
|
248
|
-
readonly call_id?: string | undefined;
|
|
249
|
-
readonly pending_safety_checks?: readonly {
|
|
250
|
-
readonly [x: string]: unknown;
|
|
251
|
-
}[] | undefined;
|
|
252
|
-
} | {
|
|
253
|
-
readonly [x: string]: unknown;
|
|
254
|
-
readonly id: string;
|
|
255
|
-
readonly type: "web_search_preview_call";
|
|
256
|
-
readonly status?: string | undefined;
|
|
257
|
-
readonly action?: {
|
|
258
|
-
readonly [x: string]: unknown;
|
|
259
|
-
} | null | undefined;
|
|
260
|
-
} | {
|
|
261
|
-
readonly [x: string]: unknown;
|
|
262
|
-
readonly id: string;
|
|
263
|
-
readonly type: "image_generation_call";
|
|
264
|
-
readonly status?: string | undefined;
|
|
265
|
-
readonly result?: string | null | undefined;
|
|
266
|
-
readonly revised_prompt?: string | null | undefined;
|
|
267
|
-
readonly output_format?: "png" | "jpeg" | "webp" | undefined;
|
|
268
239
|
})[];
|
|
269
240
|
readonly model: string;
|
|
270
241
|
readonly stream: true;
|
|
@@ -276,7 +247,7 @@ export declare const routes: (Route<{
|
|
|
276
247
|
readonly summary?: "auto" | "concise" | "detailed" | undefined;
|
|
277
248
|
readonly effort?: import("../protocols/utils/open-responses-options.js").ReasoningEffort | undefined;
|
|
278
249
|
} | undefined;
|
|
279
|
-
readonly tools?: readonly
|
|
250
|
+
readonly tools?: readonly {
|
|
280
251
|
readonly type: "function";
|
|
281
252
|
readonly description: string;
|
|
282
253
|
readonly name: string;
|
|
@@ -284,39 +255,12 @@ export declare const routes: (Route<{
|
|
|
284
255
|
readonly [x: string]: unknown;
|
|
285
256
|
};
|
|
286
257
|
readonly strict?: boolean | undefined;
|
|
287
|
-
} |
|
|
288
|
-
readonly type: "image_generation";
|
|
289
|
-
readonly size?: string | undefined;
|
|
290
|
-
readonly action?: "generate" | "auto" | "edit" | undefined;
|
|
291
|
-
readonly output_format?: "png" | "jpeg" | "webp" | undefined;
|
|
292
|
-
readonly quality?: "auto" | "low" | "medium" | "high" | undefined;
|
|
293
|
-
readonly background?: "auto" | "opaque" | "transparent" | undefined;
|
|
294
|
-
readonly output_compression?: number | undefined;
|
|
295
|
-
readonly input_fidelity?: "low" | "high" | undefined;
|
|
296
|
-
readonly partial_images?: number | undefined;
|
|
297
|
-
} | {
|
|
298
|
-
readonly type: "namespace";
|
|
299
|
-
readonly name: string;
|
|
300
|
-
readonly description: string;
|
|
301
|
-
readonly tools: readonly {
|
|
302
|
-
readonly type: "function";
|
|
303
|
-
readonly description: string;
|
|
304
|
-
readonly name: string;
|
|
305
|
-
readonly parameters: {
|
|
306
|
-
readonly [x: string]: unknown;
|
|
307
|
-
};
|
|
308
|
-
readonly strict?: boolean | undefined;
|
|
309
|
-
}[];
|
|
310
|
-
})[] | undefined;
|
|
258
|
+
}[] | undefined;
|
|
311
259
|
readonly text?: {
|
|
312
260
|
readonly verbosity?: import("../protocols/utils/open-responses-options.js").TextVerbosity | undefined;
|
|
313
261
|
} | undefined;
|
|
314
262
|
readonly temperature?: number | undefined;
|
|
315
263
|
readonly service_tier?: import("../protocols/utils/open-responses-options.js").ServiceTier | undefined;
|
|
316
|
-
readonly context_management?: readonly {
|
|
317
|
-
readonly type: "compaction";
|
|
318
|
-
readonly compact_threshold?: number | undefined;
|
|
319
|
-
}[] | undefined;
|
|
320
264
|
readonly tool_choice?: "required" | "auto" | "none" | {
|
|
321
265
|
readonly type: "function";
|
|
322
266
|
readonly name: string;
|
|
@@ -327,8 +271,6 @@ export declare const routes: (Route<{
|
|
|
327
271
|
readonly type: "function";
|
|
328
272
|
readonly name: string;
|
|
329
273
|
}[];
|
|
330
|
-
} | {
|
|
331
|
-
readonly type: "image_generation";
|
|
332
274
|
} | undefined;
|
|
333
275
|
readonly top_p?: number | undefined;
|
|
334
276
|
readonly frequency_penalty?: number | undefined;
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { Route } from "../route/client.js";
|
|
2
|
+
import { Endpoint } from "../route/endpoint.js";
|
|
2
3
|
import { OpenAIChat } from "../protocols/openai-chat.js";
|
|
3
|
-
import {
|
|
4
|
+
import { OpenResponses } from "../protocols/open-responses.js";
|
|
4
5
|
import { BedrockAuth } from "../protocols/utils/bedrock-auth.js";
|
|
5
|
-
import { ProviderID } from "../schema/index.js";
|
|
6
|
+
import { ProviderConfigurationError, ProviderID } from "../schema/index.js";
|
|
6
7
|
import { withOpenAIOptions } from "./openai-options.js";
|
|
7
8
|
export const id = ProviderID.make("amazon-bedrock");
|
|
8
9
|
const responsesRoute = Route.make({
|
|
9
10
|
id: "bedrock-mantle-responses",
|
|
10
11
|
provider: id,
|
|
11
12
|
providerMetadataKey: "mantle",
|
|
12
|
-
protocol:
|
|
13
|
-
endpoint:
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
defaults: OpenAIResponses.route.defaults,
|
|
13
|
+
protocol: OpenResponses.protocol,
|
|
14
|
+
endpoint: Endpoint.path(OpenResponses.PATH),
|
|
15
|
+
transport: OpenResponses.httpTransport,
|
|
16
|
+
defaults: { providerOptions: { store: false, include: ["reasoning.encrypted_content"] } },
|
|
17
17
|
});
|
|
18
18
|
const chatRoute = OpenAIChat.route.with({
|
|
19
19
|
id: "bedrock-mantle-chat",
|
|
@@ -38,9 +38,12 @@ const defaults = (input) => {
|
|
|
38
38
|
};
|
|
39
39
|
export const configure = (input = {}) => {
|
|
40
40
|
if (input.auth === "bearer" && input.apiKey === undefined && process.env.AWS_BEARER_TOKEN_BEDROCK === undefined)
|
|
41
|
-
throw new
|
|
41
|
+
throw new ProviderConfigurationError({ provider: id, message: "Amazon Bedrock Mantle bearer auth requires apiKey" });
|
|
42
42
|
if (input.auth === "sigv4" && input.apiKey !== undefined)
|
|
43
|
-
throw new
|
|
43
|
+
throw new ProviderConfigurationError({
|
|
44
|
+
provider: id,
|
|
45
|
+
message: "Amazon Bedrock Mantle SigV4 auth does not accept apiKey",
|
|
46
|
+
});
|
|
44
47
|
const configuredResponsesRoute = configuredRoute(responsesRoute, input);
|
|
45
48
|
const configuredChatRoute = configuredRoute(chatRoute, input);
|
|
46
49
|
const modelDefaults = defaults(input);
|
|
@@ -59,17 +62,17 @@ export const configure = (input = {}) => {
|
|
|
59
62
|
};
|
|
60
63
|
};
|
|
61
64
|
export const provider = configure();
|
|
62
|
-
const fromSettings = (
|
|
63
|
-
apiKey
|
|
64
|
-
auth
|
|
65
|
-
baseURL
|
|
66
|
-
credentials
|
|
67
|
-
generation:
|
|
68
|
-
headers:
|
|
69
|
-
http:
|
|
70
|
-
profile
|
|
71
|
-
providerOptions
|
|
72
|
-
region
|
|
65
|
+
const fromSettings = ({ apiKey, auth, baseURL, body, credentials, headers, profile, region, topP, ...providerOptions }) => configure({
|
|
66
|
+
apiKey,
|
|
67
|
+
auth,
|
|
68
|
+
baseURL,
|
|
69
|
+
credentials,
|
|
70
|
+
generation: topP === undefined ? undefined : { topP },
|
|
71
|
+
headers: headers === undefined ? undefined : { ...headers },
|
|
72
|
+
http: body === undefined ? undefined : { body: { ...body } },
|
|
73
|
+
profile,
|
|
74
|
+
providerOptions,
|
|
75
|
+
region,
|
|
73
76
|
});
|
|
74
77
|
export const chatModel = (modelID, settings) => fromSettings(settings).chat(modelID);
|
|
75
78
|
export const responsesModel = (modelID, settings) => fromSettings(settings).responses(modelID);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ProviderID } from "../schema/index.js";
|
|
1
|
+
import { ProviderConfigurationError, ProviderID } from "../schema/index.js";
|
|
2
2
|
import * as BedrockConverse from "../protocols/bedrock-converse.js";
|
|
3
3
|
import { BedrockAuth } from "../protocols/utils/bedrock-auth.js";
|
|
4
4
|
export const id = ProviderID.make("amazon-bedrock");
|
|
@@ -7,9 +7,9 @@ const bedrockBaseURL = (region) => `https://bedrock-runtime.${region}.amazonaws.
|
|
|
7
7
|
const configuredRoute = (input) => {
|
|
8
8
|
const { apiKey, auth, credentials, profile, region, baseURL, ...rest } = input;
|
|
9
9
|
if (auth === "bearer" && apiKey === undefined && process.env.AWS_BEARER_TOKEN_BEDROCK === undefined)
|
|
10
|
-
throw new
|
|
10
|
+
throw new ProviderConfigurationError({ provider: id, message: "Amazon Bedrock bearer auth requires apiKey" });
|
|
11
11
|
if (auth === "sigv4" && apiKey !== undefined)
|
|
12
|
-
throw new
|
|
12
|
+
throw new ProviderConfigurationError({ provider: id, message: "Amazon Bedrock SigV4 auth does not accept apiKey" });
|
|
13
13
|
const resolvedRegion = BedrockAuth.resolveRegion(input);
|
|
14
14
|
return BedrockConverse.route.with({
|
|
15
15
|
...rest,
|
|
@@ -12,7 +12,7 @@ export type Config = RouteDefaultsInput & ProviderAuthOption<"optional"> & {
|
|
|
12
12
|
readonly baseURL: string;
|
|
13
13
|
readonly providerOptions?: AnthropicMessages.ProviderOptionsInput;
|
|
14
14
|
};
|
|
15
|
-
export type Settings = ProviderPackage.Settings & ({
|
|
15
|
+
export type Settings = ProviderPackage.Settings & AnthropicMessages.ProviderOptionsInput & ({
|
|
16
16
|
readonly apiKey?: string;
|
|
17
17
|
readonly authToken?: never;
|
|
18
18
|
} | {
|
|
@@ -21,7 +21,6 @@ export type Settings = ProviderPackage.Settings & ({
|
|
|
21
21
|
}) & {
|
|
22
22
|
readonly baseURL: string;
|
|
23
23
|
readonly provider?: string;
|
|
24
|
-
readonly providerOptions?: AnthropicMessages.ProviderOptionsInput;
|
|
25
24
|
};
|
|
26
25
|
export declare const routes: import("../route/client.js").Route<{
|
|
27
26
|
readonly max_tokens: number;
|