@opencode/ai 2.0.14 → 2.0.15
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/README.md +115 -56
- package/dist/experimental/evaluation-client.d.ts +1 -1
- package/dist/experimental/evaluation-client.js +39 -3
- package/dist/experimental/evaluation.d.ts +4 -4
- package/dist/experimental/evaluation.js +2 -2
- package/dist/experimental/system-one.d.ts +3 -3
- package/dist/experimental/system-one.js +40 -51
- package/dist/generation.d.ts +69 -0
- package/dist/generation.js +84 -0
- package/dist/image-client.d.ts +6 -4
- package/dist/image-client.js +11 -11
- package/dist/image.d.ts +1040 -62
- package/dist/image.js +80 -52
- package/dist/index.d.ts +5 -2
- package/dist/index.js +3 -1
- package/dist/llm.d.ts +9 -1
- package/dist/media.d.ts +212 -0
- package/dist/media.js +228 -0
- package/dist/promise.d.ts +554 -0
- package/dist/promise.js +44 -0
- package/dist/protocols/anthropic-messages.js +7 -17
- package/dist/protocols/bedrock-converse.d.ts +4 -4
- package/dist/protocols/bedrock-converse.js +1 -6
- package/dist/protocols/gemini.d.ts +21 -0
- package/dist/protocols/gemini.js +42 -6
- package/dist/protocols/google-images.d.ts +9 -21
- package/dist/protocols/google-images.js +169 -132
- package/dist/protocols/meta-images.d.ts +7 -12
- package/dist/protocols/meta-images.js +92 -66
- package/dist/protocols/mistral-chat.js +7 -6
- package/dist/protocols/open-responses.d.ts +11 -3
- package/dist/protocols/open-responses.js +23 -12
- package/dist/protocols/openai-chat.d.ts +34 -1
- package/dist/protocols/openai-chat.js +100 -31
- package/dist/protocols/openai-images.d.ts +9 -20
- package/dist/protocols/openai-images.js +112 -142
- package/dist/protocols/shared.d.ts +17 -17
- package/dist/protocols/shared.js +32 -35
- package/dist/protocols/utils/bedrock-media.d.ts +2 -3
- package/dist/protocols/utils/bedrock-media.js +4 -4
- package/dist/protocols/utils/media-input.d.ts +10 -0
- package/dist/protocols/utils/media-input.js +17 -0
- package/dist/protocols/utils/responses-compaction.js +6 -5
- package/dist/protocols/utils/tool-stream.d.ts +27 -3
- package/dist/protocols/xai-images.d.ts +9 -15
- package/dist/protocols/xai-images.js +85 -83
- package/dist/protocols/zai-images.d.ts +9 -13
- package/dist/protocols/zai-images.js +59 -57
- package/dist/providers/amazon-bedrock.d.ts +2 -2
- package/dist/providers/cerebras.js +6 -1
- package/dist/providers/deepinfra.js +6 -1
- package/dist/providers/google-vertex.d.ts +7 -0
- package/dist/providers/google.d.ts +7 -0
- package/dist/providers/index.d.ts +1 -0
- package/dist/providers/index.js +1 -0
- package/dist/providers/openrouter.d.ts +19 -0
- package/dist/providers/openrouter.js +13 -1
- package/dist/providers/vercel-ai-gateway.d.ts +41 -0
- package/dist/providers/vercel-ai-gateway.js +85 -0
- package/dist/route/client.d.ts +9 -1
- package/dist/route/endpoint.d.ts +10 -10
- package/dist/route/executor-service.d.ts +12 -0
- package/dist/route/executor-service.js +3 -0
- package/dist/route/executor.d.ts +4 -9
- package/dist/route/executor.js +3 -3
- package/dist/route/index.d.ts +2 -0
- package/dist/route/index.js +2 -0
- package/dist/route/media-protocol.d.ts +45 -0
- package/dist/route/media-protocol.js +40 -0
- package/dist/route/media.d.ts +46 -0
- package/dist/route/media.js +64 -0
- package/dist/schema/errors.d.ts +13 -3
- package/dist/schema/errors.js +7 -0
- package/dist/schema/events.d.ts +563 -40
- package/dist/schema/events.js +35 -2
- package/dist/schema/messages.d.ts +98 -8
- package/dist/schema/messages.js +8 -6
- package/dist/schema/options.d.ts +2 -0
- package/dist/schema/options.js +3 -0
- package/dist/testing.d.ts +72 -8
- package/dist/utils/media-type.d.ts +6 -0
- package/dist/utils/media-type.js +49 -0
- package/dist/utils/sanitize.js +3 -1
- package/package.json +7 -3
- package/dist/protocols/utils/image-input.d.ts +0 -21
- package/dist/protocols/utils/image-input.js +0 -20
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { Duration, Effect, Schedule, Schema, Stream } from "effect";
|
|
2
|
+
import { AIError, TimeoutError } from "./schema/errors.js";
|
|
3
|
+
export const Status = Schema.Literals(["queued", "running", "completed", "failed", "cancelled", "expired"]);
|
|
4
|
+
export const DEFAULT_POLL_INTERVAL = Duration.seconds(5);
|
|
5
|
+
export const DEFAULT_POLL_TIMEOUT = Duration.minutes(10);
|
|
6
|
+
const TERMINAL = new Set(["completed", "failed", "cancelled", "expired"]);
|
|
7
|
+
export class Generation {
|
|
8
|
+
route;
|
|
9
|
+
token;
|
|
10
|
+
id;
|
|
11
|
+
status;
|
|
12
|
+
progress;
|
|
13
|
+
position;
|
|
14
|
+
expiresAt;
|
|
15
|
+
constructor(route, token, snapshot) {
|
|
16
|
+
this.route = route;
|
|
17
|
+
this.token = token;
|
|
18
|
+
this.id = snapshot.id;
|
|
19
|
+
this.status = snapshot.status;
|
|
20
|
+
this.progress = snapshot.progress;
|
|
21
|
+
this.position = snapshot.position;
|
|
22
|
+
this.expiresAt = snapshot.expiresAt;
|
|
23
|
+
}
|
|
24
|
+
get snapshot() {
|
|
25
|
+
return {
|
|
26
|
+
id: this.id,
|
|
27
|
+
status: this.status,
|
|
28
|
+
progress: this.progress,
|
|
29
|
+
position: this.position,
|
|
30
|
+
expiresAt: this.expiresAt,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
get terminal() {
|
|
34
|
+
return TERMINAL.has(this.status);
|
|
35
|
+
}
|
|
36
|
+
refresh() {
|
|
37
|
+
return this.route.status(this.token).pipe(Effect.map((snapshot) => new Generation(this.route, this.token, snapshot)));
|
|
38
|
+
}
|
|
39
|
+
/** Poll until the generation reaches a terminal status, then fetch the result. Fails with a `Timeout` reason on deadline. */
|
|
40
|
+
await(options) {
|
|
41
|
+
const timeout = Duration.fromInputUnsafe(options?.poll?.timeout ?? DEFAULT_POLL_TIMEOUT);
|
|
42
|
+
const settled = this.terminal ? Effect.succeed(this) : this.poll(options?.poll);
|
|
43
|
+
return settled.pipe(
|
|
44
|
+
// Non-completed terminal states also go through `result` so the route can surface its provider failure body.
|
|
45
|
+
Effect.flatMap((generation) => generation.route.result(generation.token)), Effect.timeoutOrElse({
|
|
46
|
+
duration: timeout,
|
|
47
|
+
orElse: () => new AIError({
|
|
48
|
+
reason: new TimeoutError({
|
|
49
|
+
message: `Generation ${this.id} did not finish within ${Duration.format(timeout)}`,
|
|
50
|
+
timeoutMs: Duration.toMillis(timeout),
|
|
51
|
+
}),
|
|
52
|
+
}),
|
|
53
|
+
}));
|
|
54
|
+
}
|
|
55
|
+
cancel() {
|
|
56
|
+
return this.route.cancel?.(this.token) ?? Effect.void;
|
|
57
|
+
}
|
|
58
|
+
/** Status observations as a stream, ending after the first terminal observation. */
|
|
59
|
+
events(options) {
|
|
60
|
+
const observations = this.terminal
|
|
61
|
+
? Stream.make(this)
|
|
62
|
+
: Stream.fromEffectSchedule(this.refresh(), this.schedule(options?.poll)).pipe(Stream.takeUntil((generation) => generation.terminal));
|
|
63
|
+
return observations.pipe(Stream.map((generation) => {
|
|
64
|
+
if (generation.terminal)
|
|
65
|
+
return { type: "generation-finished", id: generation.id, status: generation.status };
|
|
66
|
+
if (generation.status === "queued")
|
|
67
|
+
return { type: "generation-queued", id: generation.id, position: generation.position };
|
|
68
|
+
return { type: "generation-progress", id: generation.id, progress: generation.progress };
|
|
69
|
+
}));
|
|
70
|
+
}
|
|
71
|
+
poll(poll) {
|
|
72
|
+
return this.refresh().pipe(Effect.repeat({ schedule: this.schedule(poll), until: (generation) => generation.terminal }));
|
|
73
|
+
}
|
|
74
|
+
schedule(poll) {
|
|
75
|
+
if (poll?.schedule)
|
|
76
|
+
return poll.schedule.pipe(Schedule.setInputType());
|
|
77
|
+
const interval = poll?.interval ?? DEFAULT_POLL_INTERVAL;
|
|
78
|
+
const pollHint = this.route.pollHint;
|
|
79
|
+
const spaced = Schedule.spaced(interval).pipe(Schedule.setInputType());
|
|
80
|
+
if (!pollHint)
|
|
81
|
+
return spaced;
|
|
82
|
+
return spaced.pipe(Schedule.modifyDelay((metadata) => Effect.succeed(pollHint(metadata.input.snapshot) ?? interval)));
|
|
83
|
+
}
|
|
84
|
+
}
|
package/dist/image-client.d.ts
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
|
-
import { Context, Effect, Layer } from "effect";
|
|
1
|
+
import { Context, Effect, Layer, Stream } from "effect";
|
|
2
2
|
import { RequestExecutor } from "./route/executor.js";
|
|
3
|
-
import {
|
|
4
|
-
import type
|
|
5
|
-
export type Execute = RequestExecutor.Interface["execute"];
|
|
3
|
+
import type { AIError } from "./schema/index.js";
|
|
4
|
+
import { type ImageEvent, type ImageOptions, type ImageRequestFor, type ImageResponse } from "./image.js";
|
|
6
5
|
export interface Interface {
|
|
7
6
|
readonly generate: <Options extends ImageOptions>(request: ImageRequestFor<Options>) => Effect.Effect<ImageResponse, AIError>;
|
|
7
|
+
readonly stream: <Options extends ImageOptions>(request: ImageRequestFor<Options>) => Stream.Stream<ImageEvent, AIError>;
|
|
8
8
|
}
|
|
9
9
|
declare const Service_base: Context.ServiceClass<Service, "@opencode/ImageClient", Interface>;
|
|
10
10
|
export declare class Service extends Service_base {
|
|
11
11
|
}
|
|
12
12
|
export declare const generate: <Options extends ImageOptions>(request: ImageRequestFor<Options>) => Effect.Effect<ImageResponse, AIError, Service>;
|
|
13
|
+
export declare const stream: <Options extends ImageOptions>(request: ImageRequestFor<Options>) => Stream.Stream<ImageEvent, AIError, Service>;
|
|
13
14
|
export declare const layer: Layer.Layer<Service, never, RequestExecutor.Service>;
|
|
14
15
|
export declare const ImageClient: {
|
|
15
16
|
readonly Service: typeof Service;
|
|
16
17
|
readonly layer: Layer.Layer<Service, never, RequestExecutor.Service>;
|
|
17
18
|
readonly generate: <Options extends ImageOptions>(request: ImageRequestFor<Options>) => Effect.Effect<ImageResponse, AIError, Service>;
|
|
19
|
+
readonly stream: <Options extends ImageOptions>(request: ImageRequestFor<Options>) => Stream.Stream<ImageEvent, AIError, Service>;
|
|
18
20
|
};
|
|
19
21
|
export {};
|
package/dist/image-client.js
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
import { Context, Effect, Layer } from "effect";
|
|
1
|
+
import { Context, Effect, Layer, Stream } from "effect";
|
|
2
2
|
import { RequestExecutor } from "./route/executor.js";
|
|
3
|
-
import {
|
|
4
|
-
import { sanitizeSurrogates } from "./utils/sanitize.js";
|
|
3
|
+
import { responseEvents, } from "./image.js";
|
|
5
4
|
export class Service extends Context.Service()("@opencode/ImageClient") {
|
|
6
5
|
}
|
|
7
6
|
export const generate = (request) => Effect.gen(function* () {
|
|
8
7
|
const client = yield* Service;
|
|
9
8
|
return yield* client.generate(request);
|
|
10
9
|
});
|
|
10
|
+
export const stream = (request) => Stream.unwrap(Effect.gen(function* () {
|
|
11
|
+
const client = yield* Service;
|
|
12
|
+
return client.stream(request);
|
|
13
|
+
}));
|
|
11
14
|
export const layer = Layer.effect(Service, Effect.gen(function* () {
|
|
12
15
|
const executor = yield* RequestExecutor.Service;
|
|
16
|
+
const generate = (request) => request.model.route.generate(request, executor.execute);
|
|
13
17
|
return Service.of({
|
|
14
|
-
generate
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
model: undefined,
|
|
18
|
-
http: mergeHttpOptions(request.model.http, request.http),
|
|
19
|
-
}),
|
|
20
|
-
model: request.model,
|
|
21
|
-
}, executor.execute),
|
|
18
|
+
generate,
|
|
19
|
+
// Inline routes have no partial frames yet; the stream is the completed response expanded into events.
|
|
20
|
+
stream: (request) => Stream.unwrap(generate(request).pipe(Effect.map((response) => Stream.fromIterable(responseEvents(response))))),
|
|
22
21
|
});
|
|
23
22
|
}));
|
|
24
23
|
export const ImageClient = {
|
|
25
24
|
Service,
|
|
26
25
|
layer,
|
|
27
26
|
generate,
|
|
27
|
+
stream,
|
|
28
28
|
};
|