@opencode/ai 0.0.0-dev-20061 → 0.0.0-dev-20065
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 +56 -1
- package/dist/image-client.d.ts +14 -7
- package/dist/image-client.js +24 -8
- package/dist/image.d.ts +392 -12
- package/dist/image.js +41 -9
- package/dist/media-model.d.ts +3 -1
- package/dist/media-model.js +10 -0
- package/dist/promise.d.ts +33 -5
- package/dist/promise.js +4 -2
- package/dist/protocols/bfl-images.d.ts +32 -0
- package/dist/protocols/bfl-images.js +153 -0
- package/dist/protocols/fal-images.d.ts +24 -0
- package/dist/protocols/fal-images.js +114 -0
- package/dist/protocols/fal-video.d.ts +0 -10
- package/dist/protocols/fal-video.js +8 -59
- package/dist/protocols/openai-images.d.ts +124 -3
- package/dist/protocols/openai-images.js +102 -35
- package/dist/protocols/openai-responses.d.ts +5 -5
- package/dist/protocols/replicate-images.d.ts +28 -0
- package/dist/protocols/replicate-images.js +133 -0
- package/dist/protocols/stability-images.d.ts +38 -0
- package/dist/protocols/stability-images.js +148 -0
- package/dist/protocols/utils/fal-queue.d.ts +28 -0
- package/dist/protocols/utils/fal-queue.js +69 -0
- package/dist/protocols/utils/media-input.d.ts +4 -0
- package/dist/protocols/utils/media-input.js +4 -0
- package/dist/provider-error.js +3 -0
- package/dist/providers/azure.d.ts +2 -2
- package/dist/providers/black-forest-labs.d.ts +25 -0
- package/dist/providers/black-forest-labs.js +28 -0
- package/dist/providers/cloudflare-ai-gateway.d.ts +2 -2
- package/dist/providers/fal.d.ts +5 -0
- package/dist/providers/fal.js +8 -4
- package/dist/providers/index.d.ts +3 -0
- package/dist/providers/index.js +3 -0
- package/dist/providers/openai.d.ts +1 -1
- package/dist/providers/replicate.d.ts +25 -0
- package/dist/providers/replicate.js +22 -0
- package/dist/providers/stability.d.ts +28 -0
- package/dist/providers/stability.js +23 -0
- package/dist/route/media-protocol.d.ts +3 -1
- package/dist/route/media.d.ts +13 -2
- package/dist/route/media.js +37 -2
- package/dist/transcription-client.d.ts +1 -1
- package/dist/transcription-client.js +10 -35
- package/dist/transcription.d.ts +2 -2
- package/dist/transcription.js +2 -9
- package/package.json +3 -3
package/dist/route/media.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Effect, Stream } from "effect";
|
|
2
2
|
import { Auth } from "./auth.js";
|
|
3
3
|
import { Endpoint } from "./endpoint.js";
|
|
4
|
-
import type
|
|
4
|
+
import { type Interface } from "./executor-service.js";
|
|
5
5
|
import { MediaProtocol } from "./media-protocol.js";
|
|
6
|
-
import { Generation } from "../generation.js";
|
|
6
|
+
import { Generation, type AwaitOptions, type Observation } from "../generation.js";
|
|
7
7
|
import { AIError, HttpOptions, ProviderID } from "../schema/index.js";
|
|
8
8
|
export type Execute = Interface["execute"];
|
|
9
9
|
/** The minimum a media request must carry for the route to build a transport request. */
|
|
@@ -50,6 +50,7 @@ export interface StreamRoute<Request extends MediaRequest, Event, Response> {
|
|
|
50
50
|
readonly stream: (request: Request, execute: Execute) => Stream.Stream<Event, AIError>;
|
|
51
51
|
readonly generate: (request: Request, execute: Execute) => Effect.Effect<Response, AIError>;
|
|
52
52
|
}
|
|
53
|
+
export type AnyRoute<Request extends MediaRequest, Event, Response> = Route<Request, Response> | StreamRoute<Request, Event, Response> | QueuedRoute<Request, Response>;
|
|
53
54
|
export interface Composition<Request extends MediaRequest> {
|
|
54
55
|
readonly id: string;
|
|
55
56
|
readonly provider: string | ProviderID;
|
|
@@ -83,4 +84,14 @@ export declare const inline: <Request extends MediaRequest, Response>(input: Inl
|
|
|
83
84
|
export declare const queued: <Request extends MediaRequest, Response, Token>(input: QueuedInput<Request, Response, Token>) => QueuedRoute<Request, Response>;
|
|
84
85
|
/** Compose a streaming media protocol; `generate` runs the same stream in `generate` mode and folds it with `collect`. */
|
|
85
86
|
export declare const stream: <Request extends MediaRequest, Event, Response, Frame, State>(input: StreamInput<Request, Event, Response, Frame, State>) => StreamRoute<Request, Event, Response>;
|
|
87
|
+
export declare const dispatch: <Event, Response>(input: {
|
|
88
|
+
readonly modality: string;
|
|
89
|
+
readonly execute: Execute;
|
|
90
|
+
readonly responseEvents: (response: Response) => ReadonlyArray<Event>;
|
|
91
|
+
}) => {
|
|
92
|
+
start: <Request extends MediaRequest>(route: AnyRoute<Request, Event, Response>, request: Request) => Effect.Effect<Generation<Response>, AIError, never>;
|
|
93
|
+
resume: <Request extends MediaRequest>(route: AnyRoute<Request, Event, Response>, model: MediaRequest["model"], token: unknown) => Effect.Effect<Generation<Response>, AIError, never>;
|
|
94
|
+
generate: <Request extends MediaRequest>(route: AnyRoute<Request, Event, Response>, request: Request, options?: AwaitOptions) => Effect.Effect<Response, AIError, never>;
|
|
95
|
+
stream: <Request extends MediaRequest>(route: AnyRoute<Request, Event, Response>, request: Request, options?: AwaitOptions) => Stream.Stream<Event | Observation, AIError>;
|
|
96
|
+
};
|
|
86
97
|
export * as MediaRoute from "./media.js";
|
package/dist/route/media.js
CHANGED
|
@@ -2,9 +2,10 @@ import { Effect, Schema, Stream } from "effect";
|
|
|
2
2
|
import { Headers, HttpClientRequest } from "effect/unstable/http";
|
|
3
3
|
import { Auth } from "./auth.js";
|
|
4
4
|
import { Endpoint } from "./endpoint.js";
|
|
5
|
+
import { Service as RequestExecutorService } from "./executor-service.js";
|
|
5
6
|
import { RequestExecutor } from "./executor.js";
|
|
6
7
|
import { MediaProtocol } from "./media-protocol.js";
|
|
7
|
-
import { Generation } from "../generation.js";
|
|
8
|
+
import { Generation, resultEvents, } from "../generation.js";
|
|
8
9
|
import { ProviderShared } from "../protocols/shared.js";
|
|
9
10
|
import { AIError, AIErrorReason, HttpOptions, InvalidRequestError, ProviderID, mergeHttpOptions, } from "../schema/index.js";
|
|
10
11
|
import { sanitizeSurrogates } from "../utils/sanitize.js";
|
|
@@ -39,9 +40,10 @@ export const queued = (input) => {
|
|
|
39
40
|
// A protocol producing a token its own codec rejects is a programmer defect, not a provider error.
|
|
40
41
|
const encodeToken = Schema.encodeSync(protocol.token);
|
|
41
42
|
const generationRoute = (token, http, execute) => {
|
|
43
|
+
const materialize = (asset) => asset.materialize().pipe(Effect.provideService(RequestExecutorService, { execute }));
|
|
42
44
|
const poll = (operation) => transport
|
|
43
45
|
.call("GET", operation.path(token), http, execute)
|
|
44
|
-
.pipe(Effect.flatMap((sent) => operation.decode(sent.response, { token, auth: sent.auth })));
|
|
46
|
+
.pipe(Effect.flatMap((sent) => operation.decode(sent.response, { token, auth: sent.auth, materialize })));
|
|
45
47
|
const cancel = protocol.cancel;
|
|
46
48
|
const route = {
|
|
47
49
|
status: poll(protocol.status),
|
|
@@ -104,6 +106,39 @@ export const stream = (input) => {
|
|
|
104
106
|
generate: (request, execute) => events(request, execute, "generate").pipe(Stream.runCollect, Effect.flatMap(input.collect)),
|
|
105
107
|
};
|
|
106
108
|
};
|
|
109
|
+
export const dispatch = (input) => {
|
|
110
|
+
const notQueued = (route, operation) => ProviderShared.unsupportedOperation({
|
|
111
|
+
operation: `${input.modality}.${operation}`,
|
|
112
|
+
provider: route.provider,
|
|
113
|
+
route: route.id,
|
|
114
|
+
message: `${route.provider}/${route.id} is not a queued route; use generate or stream`,
|
|
115
|
+
});
|
|
116
|
+
const start = (route, request) => {
|
|
117
|
+
if (route.kind !== "queued")
|
|
118
|
+
return Effect.fail(notQueued(route, "start"));
|
|
119
|
+
return route.start(request, input.execute);
|
|
120
|
+
};
|
|
121
|
+
return {
|
|
122
|
+
start,
|
|
123
|
+
resume: (route, model, token) => {
|
|
124
|
+
if (route.kind !== "queued")
|
|
125
|
+
return Effect.fail(notQueued(route, "resume"));
|
|
126
|
+
return route.resume(model, token, input.execute);
|
|
127
|
+
},
|
|
128
|
+
generate: (route, request, options) => {
|
|
129
|
+
if (route.kind !== "queued")
|
|
130
|
+
return route.generate(request, input.execute);
|
|
131
|
+
return start(route, request).pipe(Effect.flatMap((generation) => generation.await(options)));
|
|
132
|
+
},
|
|
133
|
+
stream: (route, request, options) => {
|
|
134
|
+
if (route.kind === "stream")
|
|
135
|
+
return route.stream(request, input.execute);
|
|
136
|
+
if (route.kind === "queued")
|
|
137
|
+
return Stream.unwrap(start(route, request).pipe(Effect.map((generation) => resultEvents(generation, input.responseEvents, options))));
|
|
138
|
+
return Stream.fromIterableEffect(Effect.map(route.generate(request, input.execute), input.responseEvents));
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
};
|
|
107
142
|
// ---------------------------------------------------------------------------
|
|
108
143
|
// Transport plumbing shared by every kind
|
|
109
144
|
// ---------------------------------------------------------------------------
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Context, Effect, Layer, Stream } from "effect";
|
|
2
|
-
import {
|
|
2
|
+
import type { AwaitOptions, Generation } from "./generation.js";
|
|
3
3
|
import { RequestExecutor } from "./route/executor.js";
|
|
4
4
|
import type { AIError } from "./schema/index.js";
|
|
5
5
|
import { type TranscriptionEvent, type TranscriptionModel, type TranscriptionOptions, type TranscriptionRequestFor, type TranscriptionResponse } from "./transcription.js";
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Context, Effect, Layer, Stream } from "effect";
|
|
2
|
-
import { resultEvents } from "./generation.js";
|
|
3
|
-
import { ProviderShared } from "./protocols/shared.js";
|
|
4
2
|
import { RequestExecutor } from "./route/executor.js";
|
|
3
|
+
import { MediaRoute } from "./route/media.js";
|
|
5
4
|
import { responseEvents, } from "./transcription.js";
|
|
6
5
|
export class Service extends Context.Service()("@opencode/TranscriptionClient") {
|
|
7
6
|
}
|
|
@@ -21,42 +20,18 @@ export const resume = (model, token) => Effect.gen(function* () {
|
|
|
21
20
|
const client = yield* Service;
|
|
22
21
|
return yield* client.resume(model, token);
|
|
23
22
|
});
|
|
24
|
-
const notQueued = (route, operation) => ProviderShared.unsupportedOperation({
|
|
25
|
-
operation: `transcription.${operation}`,
|
|
26
|
-
provider: route.provider,
|
|
27
|
-
route: route.id,
|
|
28
|
-
message: `${route.provider}/${route.id} is not a queued route; use Transcription.generate or Transcription.stream`,
|
|
29
|
-
});
|
|
30
23
|
export const layer = Layer.effect(Service, Effect.gen(function* () {
|
|
31
24
|
const executor = yield* RequestExecutor.Service;
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
};
|
|
25
|
+
const dispatch = MediaRoute.dispatch({
|
|
26
|
+
modality: "transcription",
|
|
27
|
+
execute: executor.execute,
|
|
28
|
+
responseEvents,
|
|
29
|
+
});
|
|
38
30
|
return Service.of({
|
|
39
|
-
start,
|
|
40
|
-
resume: (model, token) =>
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
return Effect.fail(notQueued(route, "resume"));
|
|
44
|
-
return route.resume(model, token, executor.execute);
|
|
45
|
-
},
|
|
46
|
-
generate: (request, options) => {
|
|
47
|
-
const route = request.model.route;
|
|
48
|
-
if (route.kind !== "queued")
|
|
49
|
-
return route.generate(request, executor.execute);
|
|
50
|
-
return start(request).pipe(Effect.flatMap((generation) => generation.await(options)));
|
|
51
|
-
},
|
|
52
|
-
stream: (request, options) => {
|
|
53
|
-
const route = request.model.route;
|
|
54
|
-
if (route.kind === "stream")
|
|
55
|
-
return route.stream(request, executor.execute);
|
|
56
|
-
if (route.kind === "queued")
|
|
57
|
-
return Stream.unwrap(start(request).pipe(Effect.map((generation) => resultEvents(generation, responseEvents, options))));
|
|
58
|
-
return Stream.fromIterableEffect(Effect.map(route.generate(request, executor.execute), responseEvents));
|
|
59
|
-
},
|
|
31
|
+
start: (request) => dispatch.start(request.model.route, request),
|
|
32
|
+
resume: (model, token) => dispatch.resume(model.route, model, token),
|
|
33
|
+
generate: (request, options) => dispatch.generate(request.model.route, request, options),
|
|
34
|
+
stream: (request, options) => dispatch.stream(request.model.route, request, options),
|
|
60
35
|
});
|
|
61
36
|
}));
|
|
62
37
|
export const TranscriptionClient = {
|
package/dist/transcription.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ import type { MediaProtocol } from "./route/media-protocol.js";
|
|
|
7
7
|
import { AIError, HttpOptions } from "./schema/index.js";
|
|
8
8
|
import { Service } from "./transcription-client.js";
|
|
9
9
|
export type TranscriptionOptions = Record<string, unknown>;
|
|
10
|
-
export type TranscriptionRoute<Options extends TranscriptionOptions = TranscriptionOptions> = MediaRoute.
|
|
10
|
+
export type TranscriptionRoute<Options extends TranscriptionOptions = TranscriptionOptions> = MediaRoute.AnyRoute<TranscriptionRequestFor<Options>, TranscriptionEvent, TranscriptionResponse>;
|
|
11
11
|
export declare class TranscriptionModel<Options extends TranscriptionOptions = TranscriptionOptions> extends MediaModel<TranscriptionRoute<Options>, Options> {
|
|
12
12
|
protected readonly _TranscriptionModel: void;
|
|
13
13
|
static make<Options extends TranscriptionOptions = TranscriptionOptions>(input: MediaModel.Input<TranscriptionRoute<Options>>): TranscriptionModel<Options>;
|
|
@@ -20,7 +20,7 @@ export declare namespace TranscriptionModel {
|
|
|
20
20
|
type InlineRouteInput<Options extends TranscriptionOptions = TranscriptionOptions> = MediaModel.RouteInput<TranscriptionRequestFor<Options>, MediaProtocol.Inline<TranscriptionRequestFor<Options>, TranscriptionResponse>>;
|
|
21
21
|
type StreamRouteInput<Options extends TranscriptionOptions = TranscriptionOptions, Frame = unknown, State = unknown> = MediaModel.RouteInput<MediaProtocol.Addressed<TranscriptionRequestFor<Options>>, MediaProtocol.Streamed<TranscriptionRequestFor<Options>, TranscriptionEvent, Frame, State>>;
|
|
22
22
|
type QueuedRouteInput<Options extends TranscriptionOptions = TranscriptionOptions, Token = unknown> = MediaModel.RouteInput<TranscriptionRequestFor<Options>, MediaProtocol.Queued<TranscriptionRequestFor<Options>, TranscriptionResponse, Token>>;
|
|
23
|
-
type RouteInput<Options extends TranscriptionOptions = TranscriptionOptions, Frame = unknown, State = unknown, Token = unknown> =
|
|
23
|
+
type RouteInput<Options extends TranscriptionOptions = TranscriptionOptions, Frame = unknown, State = unknown, Token = unknown> = MediaModel.AnyRouteInput<TranscriptionRequestFor<Options>, TranscriptionEvent, TranscriptionResponse, Frame, State, Token>;
|
|
24
24
|
}
|
|
25
25
|
export declare const TranscriptionModelSchema: Schema.declare<TranscriptionModel<TranscriptionOptions>, TranscriptionModel<TranscriptionOptions>>;
|
|
26
26
|
export declare const TranscriptionTimestamps: Schema.Literals<readonly ["none", "segment", "word"]>;
|
package/dist/transcription.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Effect, Schema, Stream } from "effect";
|
|
2
2
|
import { Generation, ProgressEvent, QueuedEvent } from "./generation.js";
|
|
3
3
|
import { Media } from "./media.js";
|
|
4
|
-
import { MediaModel,
|
|
4
|
+
import { MediaModel, composeAnyRoute, tryRequest } from "./media-model.js";
|
|
5
5
|
import { MediaRoute } from "./route/media.js";
|
|
6
6
|
import { AIError, HttpOptions, MediaUsage, ProviderMetadata } from "./schema/index.js";
|
|
7
7
|
import { TranscriptionClient, Service } from "./transcription-client.js";
|
|
@@ -10,21 +10,14 @@ export class TranscriptionModel extends MediaModel {
|
|
|
10
10
|
return new TranscriptionModel(input);
|
|
11
11
|
}
|
|
12
12
|
static fromRoute(route, input) {
|
|
13
|
-
const composed = isStreamInput(route)
|
|
14
|
-
? composeRoute((composition) => MediaRoute.stream({ ...composition, collect: collectResponse }), route, input)
|
|
15
|
-
: isQueuedInput(route)
|
|
16
|
-
? composeRoute(MediaRoute.queued, route, input)
|
|
17
|
-
: composeRoute(MediaRoute.inline, route, input);
|
|
18
13
|
return new TranscriptionModel({
|
|
19
14
|
id: input.id,
|
|
20
15
|
provider: route.provider,
|
|
21
16
|
http: input.http,
|
|
22
|
-
route:
|
|
17
|
+
route: composeAnyRoute(route, input, collectResponse),
|
|
23
18
|
});
|
|
24
19
|
}
|
|
25
20
|
}
|
|
26
|
-
const isStreamInput = (route) => route.protocol.kind === "stream";
|
|
27
|
-
const isQueuedInput = (route) => route.protocol.kind === "queued";
|
|
28
21
|
export const TranscriptionModelSchema = Schema.declare((value) => value instanceof TranscriptionModel, { expected: "Transcription.Model" });
|
|
29
22
|
// ---------------------------------------------------------------------------
|
|
30
23
|
// Request
|
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-20065",
|
|
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-20065",
|
|
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-20065",
|
|
48
48
|
"aws4fetch": "1.0.20",
|
|
49
49
|
"effect": "4.0.0-rc.112",
|
|
50
50
|
"google-auth-library": "10.5.0"
|