@opencode/ai 0.0.0-dev-21801 → 0.0.0-dev-21803
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 +45 -37
- package/dist/effect.d.ts +39 -0
- package/dist/effect.js +28 -0
- package/dist/effort-updates.d.ts +2 -2
- package/dist/image-client.d.ts +4 -4
- package/dist/index.d.ts +1030 -39
- package/dist/index.js +106 -28
- package/dist/protocols/alibaba-responses.d.ts +3 -3
- package/dist/protocols/openai-compatible-chat.d.ts +1 -1
- package/dist/protocols/openai-compatible-responses.d.ts +5 -5
- package/dist/protocols/utils/image-sizing.d.ts +1 -1
- package/dist/speech-client.d.ts +4 -4
- package/dist/transcription-client.d.ts +4 -4
- package/dist/video-client.d.ts +4 -4
- package/package.json +6 -6
- package/dist/promise.d.ts +0 -1030
- package/dist/promise.js +0 -106
package/dist/index.js
CHANGED
|
@@ -1,28 +1,106 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
export
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
1
|
+
import { Effect, Layer, ManagedRuntime, Stream } from "effect";
|
|
2
|
+
import { AIClient } from "./ai-client.js";
|
|
3
|
+
import { Decision } from "./decision.js";
|
|
4
|
+
import { Image } from "./image.js";
|
|
5
|
+
import { LLM } from "./effect.js";
|
|
6
|
+
import { Media } from "./media.js";
|
|
7
|
+
import { RequestExecutor } from "./route/executor.js";
|
|
8
|
+
import { AIError, InvalidRequestError, LanguageModel } from "./schema/index.js";
|
|
9
|
+
import { Speech } from "./speech.js";
|
|
10
|
+
import { Transcription, } from "./transcription.js";
|
|
11
|
+
import { fileMediaType } from "./utils/media-type.js";
|
|
12
|
+
import { Video } from "./video.js";
|
|
13
|
+
// Fails with `signal.reason` so aborted calls reject and aborted streams throw like `fetch`: an `AbortError` by default.
|
|
14
|
+
const abortEffect = (signal) => signal === undefined
|
|
15
|
+
? Effect.never
|
|
16
|
+
: Effect.callback((resume) => {
|
|
17
|
+
if (signal.aborted) {
|
|
18
|
+
resume(Effect.fail(signal.reason));
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const onAbort = () => resume(Effect.fail(signal.reason));
|
|
22
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
23
|
+
return Effect.sync(() => signal.removeEventListener("abort", onAbort));
|
|
24
|
+
});
|
|
25
|
+
export const make = (options = {}) => {
|
|
26
|
+
const runtime = ManagedRuntime.make(AIClient.layerWith(options.layer ?? RequestExecutor.fetchLayer));
|
|
27
|
+
/** Run any package Effect (for example `LLMClient.compact(...)`) inside this runtime. */
|
|
28
|
+
const run = (effect, options) => runtime.runPromise(Effect.raceFirst(effect, abortEffect(options?.signal)));
|
|
29
|
+
const iterate = (stream, options) => Stream.toAsyncIterable(Stream.unwrap(runtime.contextEffect.pipe(Effect.map((context) => stream.pipe(Stream.interruptWhen(abortEffect(options?.signal)), Stream.provideContext(context))))));
|
|
30
|
+
const handle = (generation) => ({
|
|
31
|
+
...generation.snapshot,
|
|
32
|
+
token: generation.token,
|
|
33
|
+
await: (options) => run(generation.await({ poll: options?.poll }), options),
|
|
34
|
+
events: (options) => iterate(generation.events({ poll: options?.poll }), options),
|
|
35
|
+
result: (options) => run(generation.result(), options),
|
|
36
|
+
refresh: (options) => run(generation.refresh(), options).then(handle),
|
|
37
|
+
cancel: (options) => run(generation.cancel(), options),
|
|
38
|
+
});
|
|
39
|
+
return {
|
|
40
|
+
run,
|
|
41
|
+
/** Decoded asset bytes, downloading `url` sources through the executor. */
|
|
42
|
+
bytes: (asset, options) => run(asset.bytes(), options),
|
|
43
|
+
base64: (asset, options) => run(asset.base64(), options),
|
|
44
|
+
/** Pull a `url` asset into owned bytes before the provider URL expires. */
|
|
45
|
+
materialize: (asset, options) => run(asset.materialize(), options),
|
|
46
|
+
/** Read a file into an asset like `Media.file`: sniffed media type, then the extension's. */
|
|
47
|
+
file: async (path, options) => {
|
|
48
|
+
const { readFile } = await import("node:fs/promises");
|
|
49
|
+
return run(Effect.tryPromise({
|
|
50
|
+
try: (signal) => readFile(path, { signal }),
|
|
51
|
+
catch: (cause) => fileError(`Failed to read media file ${path}`, cause),
|
|
52
|
+
}).pipe(Effect.map((buffer) => {
|
|
53
|
+
const data = new Uint8Array(buffer);
|
|
54
|
+
return Media.bytes(data, fileMediaType(data, path), options);
|
|
55
|
+
})), options);
|
|
56
|
+
},
|
|
57
|
+
/** Write an asset's bytes like `Media.write`, downloading `url` sources through the executor. */
|
|
58
|
+
write: async (asset, path, options) => {
|
|
59
|
+
const { writeFile } = await import("node:fs/promises");
|
|
60
|
+
return run(asset.bytes().pipe(Effect.flatMap((data) => Effect.tryPromise({
|
|
61
|
+
try: (signal) => writeFile(path, data, { signal }),
|
|
62
|
+
catch: (cause) => fileError(`Failed to write media file ${path}`, cause),
|
|
63
|
+
}))), options);
|
|
64
|
+
},
|
|
65
|
+
llm: {
|
|
66
|
+
request: LLM.request,
|
|
67
|
+
generate: (input, options) => run(LLM.generate(input), options),
|
|
68
|
+
stream: (input, options) => iterate(LLM.stream(input), options),
|
|
69
|
+
},
|
|
70
|
+
image: {
|
|
71
|
+
request: Image.request,
|
|
72
|
+
generate: (input, options) => run(Image.generate(input, { poll: options?.poll }), options),
|
|
73
|
+
stream: (input, options) => iterate(Image.stream(input, { poll: options?.poll }), options),
|
|
74
|
+
start: (input, options) => run(Image.start(input), options).then(handle),
|
|
75
|
+
resume: (model, token, options) => run(Image.resume(model, token), options).then(handle),
|
|
76
|
+
},
|
|
77
|
+
video: {
|
|
78
|
+
request: Video.request,
|
|
79
|
+
start: (input, options) => run(Video.start(input), options).then(handle),
|
|
80
|
+
generate: (input, options) => run(Video.generate(input, { poll: options?.poll }), options),
|
|
81
|
+
resume: (model, token, options) => run(Video.resume(model, token), options).then(handle),
|
|
82
|
+
stream: (input, options) => iterate(Video.stream(input, { poll: options?.poll }), options),
|
|
83
|
+
},
|
|
84
|
+
speech: {
|
|
85
|
+
request: Speech.request,
|
|
86
|
+
generate: (input, options) => run(Speech.generate(input), options),
|
|
87
|
+
stream: (input, options) => iterate(Speech.stream(input), options),
|
|
88
|
+
},
|
|
89
|
+
transcription: {
|
|
90
|
+
request: Transcription.request,
|
|
91
|
+
generate: (input, options) => run(Transcription.generate(input, { poll: options?.poll }), options),
|
|
92
|
+
stream: (input, options) => iterate(Transcription.stream(input, { poll: options?.poll }), options),
|
|
93
|
+
start: (input, options) => run(Transcription.start(input), options).then(handle),
|
|
94
|
+
resume: (model, token, options) => run(Transcription.resume(model, token), options).then(handle),
|
|
95
|
+
},
|
|
96
|
+
decision: {
|
|
97
|
+
request: Decision.request,
|
|
98
|
+
generate: (input, options) => run(Decision.generate(input), options),
|
|
99
|
+
},
|
|
100
|
+
dispose: () => runtime.dispose(),
|
|
101
|
+
};
|
|
102
|
+
};
|
|
103
|
+
const fileError = (message, cause) => new AIError({ reason: new InvalidRequestError({ message, cause }) });
|
|
104
|
+
/** Default client over `RequestExecutor.fetchLayer` for scripts; the runtime builds its layer on first use. */
|
|
105
|
+
export const ai = make();
|
|
106
|
+
export * as AI from "./index.js";
|
|
@@ -172,15 +172,15 @@ export declare const protocol: Protocol<{
|
|
|
172
172
|
} | undefined;
|
|
173
173
|
readonly top_logprobs?: number | undefined;
|
|
174
174
|
readonly truncation?: "auto" | "disabled" | undefined;
|
|
175
|
-
readonly service_tier?: import("../
|
|
175
|
+
readonly service_tier?: import("../effect.js").OpenString<"auto" | "default" | "flex" | "priority"> | undefined;
|
|
176
176
|
readonly prompt_cache_key?: string | undefined;
|
|
177
|
-
readonly include?: readonly import("../
|
|
177
|
+
readonly include?: readonly import("../effect.js").OpenString<"code_interpreter_call.outputs" | "computer_call_output.output.image_url" | "file_search_call.results" | "message.input_image.image_url" | "message.output_text.logprobs" | "reasoning.encrypted_content" | "web_search_call.action.sources" | "web_search_call.results">[] | undefined;
|
|
178
178
|
readonly reasoning?: {
|
|
179
179
|
readonly effort?: OpenResponsesOptions.ReasoningEffort | undefined;
|
|
180
180
|
readonly summary?: "auto" | "concise" | "detailed" | undefined;
|
|
181
181
|
} | undefined;
|
|
182
182
|
readonly text?: {
|
|
183
|
-
readonly verbosity?: import("../
|
|
183
|
+
readonly verbosity?: import("../effect.js").OpenString<"high" | "low" | "medium"> | undefined;
|
|
184
184
|
} | undefined;
|
|
185
185
|
readonly max_output_tokens?: number | undefined;
|
|
186
186
|
readonly max_tool_calls?: number | undefined;
|
|
@@ -127,7 +127,7 @@ export declare const route: Route<{
|
|
|
127
127
|
} | undefined;
|
|
128
128
|
readonly store?: boolean | undefined;
|
|
129
129
|
readonly prompt_cache_key?: string | undefined;
|
|
130
|
-
readonly reasoning_effort?: import("../
|
|
130
|
+
readonly reasoning_effort?: import("../effect.js").ReasoningEffort | undefined;
|
|
131
131
|
readonly tool_stream?: boolean | undefined;
|
|
132
132
|
readonly max_completion_tokens?: number | undefined;
|
|
133
133
|
readonly max_tokens?: number | undefined;
|
|
@@ -9,7 +9,7 @@ export declare const route: Route<{
|
|
|
9
9
|
readonly input: readonly ({
|
|
10
10
|
readonly type: "configuration_update";
|
|
11
11
|
readonly reasoning: {
|
|
12
|
-
readonly effort: import("../
|
|
12
|
+
readonly effort: import("../effect.js").ReasoningEffort;
|
|
13
13
|
};
|
|
14
14
|
} | {
|
|
15
15
|
readonly type: "message";
|
|
@@ -166,15 +166,15 @@ export declare const route: Route<{
|
|
|
166
166
|
} | undefined;
|
|
167
167
|
readonly top_logprobs?: number | undefined;
|
|
168
168
|
readonly truncation?: "auto" | "disabled" | undefined;
|
|
169
|
-
readonly service_tier?: import("../
|
|
169
|
+
readonly service_tier?: import("../effect.js").OpenString<"auto" | "default" | "flex" | "priority"> | undefined;
|
|
170
170
|
readonly prompt_cache_key?: string | undefined;
|
|
171
|
-
readonly include?: readonly import("../
|
|
171
|
+
readonly include?: readonly import("../effect.js").OpenString<"code_interpreter_call.outputs" | "computer_call_output.output.image_url" | "file_search_call.results" | "message.input_image.image_url" | "message.output_text.logprobs" | "reasoning.encrypted_content" | "web_search_call.action.sources" | "web_search_call.results">[] | undefined;
|
|
172
172
|
readonly reasoning?: {
|
|
173
|
-
readonly effort?: import("../
|
|
173
|
+
readonly effort?: import("../effect.js").ReasoningEffort | undefined;
|
|
174
174
|
readonly summary?: "auto" | "concise" | "detailed" | undefined;
|
|
175
175
|
} | undefined;
|
|
176
176
|
readonly text?: {
|
|
177
|
-
readonly verbosity?: import("../
|
|
177
|
+
readonly verbosity?: import("../effect.js").OpenString<"high" | "low" | "medium"> | undefined;
|
|
178
178
|
} | undefined;
|
|
179
179
|
readonly max_output_tokens?: number | undefined;
|
|
180
180
|
readonly max_tool_calls?: number | undefined;
|
|
@@ -30,5 +30,5 @@ export declare const nearest: (shape: Shape, sizes: ReadonlyArray<Size>) => Size
|
|
|
30
30
|
/** Reports a size more than 2% off the requested aspect or more than √2 per edge off the requested tier. */
|
|
31
31
|
export declare const notice: (name: string, shape: Shape, size: Size) => Media.Notice | undefined;
|
|
32
32
|
/** Free width and height that must honor the shape; a size that misses it fails instead of returning a notice. */
|
|
33
|
-
export declare const exact: (route: MediaProtocol.Identity, shape: Shape, limits: Limits) => Effect.Effect<undefined, never, never> | Effect.Effect<never, import("../../
|
|
33
|
+
export declare const exact: (route: MediaProtocol.Identity, shape: Shape, limits: Limits) => Effect.Effect<undefined, never, never> | Effect.Effect<never, import("../../effect.js").AIError, never> | Effect.Effect<Size, never, never>;
|
|
34
34
|
export * as ImageSizing from "./image-sizing.js";
|
package/dist/speech-client.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export declare const Service: typeof SpeechClientService;
|
|
|
9
9
|
export type Service = SpeechClientService;
|
|
10
10
|
export declare const SpeechClient: {
|
|
11
11
|
readonly layer: import("effect/Layer").Layer<SpeechClientService, never, import("./route/executor-service.js").RequestExecutorService>;
|
|
12
|
-
readonly generate: (request: SpeechRequestFor, options?: import("./generation.js").AwaitOptions) => import("effect/Effect").Effect<SpeechResponse, import("./
|
|
12
|
+
readonly generate: (request: SpeechRequestFor, options?: import("./generation.js").AwaitOptions) => import("effect/Effect").Effect<SpeechResponse, import("./effect.js").AIError, SpeechClientService>;
|
|
13
13
|
readonly stream: (request: SpeechRequestFor, options?: import("./generation.js").AwaitOptions) => import("effect/Stream").Stream<{
|
|
14
14
|
readonly type: "audio-delta";
|
|
15
15
|
readonly chunk: Uint8Array<ArrayBufferLike>;
|
|
@@ -58,11 +58,11 @@ export declare const SpeechClient: {
|
|
|
58
58
|
readonly [x: string]: unknown;
|
|
59
59
|
};
|
|
60
60
|
} | undefined;
|
|
61
|
-
} | import("./generation.js").Observation, import("./
|
|
62
|
-
readonly start: (request: SpeechRequestFor) => import("effect/Effect").Effect<import("./generation.js").Generation<SpeechResponse>, import("./
|
|
61
|
+
} | import("./generation.js").Observation, import("./effect.js").AIError, SpeechClientService>;
|
|
62
|
+
readonly start: (request: SpeechRequestFor) => import("effect/Effect").Effect<import("./generation.js").Generation<SpeechResponse>, import("./effect.js").AIError, SpeechClientService>;
|
|
63
63
|
readonly resume: (model: import("./speech.js").SpeechModel<{
|
|
64
64
|
readonly [x: string]: unknown;
|
|
65
|
-
}>, token: unknown) => import("effect/Effect").Effect<import("./generation.js").Generation<SpeechResponse>, import("./
|
|
65
|
+
}>, token: unknown) => import("effect/Effect").Effect<import("./generation.js").Generation<SpeechResponse>, import("./effect.js").AIError, SpeechClientService>;
|
|
66
66
|
readonly Service: typeof SpeechClientService;
|
|
67
67
|
};
|
|
68
68
|
export {};
|
|
@@ -9,7 +9,7 @@ export declare const Service: typeof TranscriptionClientService;
|
|
|
9
9
|
export type Service = TranscriptionClientService;
|
|
10
10
|
export declare const TranscriptionClient: {
|
|
11
11
|
readonly layer: import("effect/Layer").Layer<TranscriptionClientService, never, import("./route/executor-service.js").RequestExecutorService>;
|
|
12
|
-
readonly generate: (request: TranscriptionRequestFor, options?: import("./generation.js").AwaitOptions) => import("effect/Effect").Effect<TranscriptionResponse, import("./
|
|
12
|
+
readonly generate: (request: TranscriptionRequestFor, options?: import("./generation.js").AwaitOptions) => import("effect/Effect").Effect<TranscriptionResponse, import("./effect.js").AIError, TranscriptionClientService>;
|
|
13
13
|
readonly stream: (request: TranscriptionRequestFor, options?: import("./generation.js").AwaitOptions) => import("effect/Stream").Stream<{
|
|
14
14
|
readonly type: "text-delta";
|
|
15
15
|
readonly delta: string;
|
|
@@ -74,11 +74,11 @@ export declare const TranscriptionClient: {
|
|
|
74
74
|
};
|
|
75
75
|
} | undefined;
|
|
76
76
|
readonly type: "finish";
|
|
77
|
-
} | import("./generation.js").Observation, import("./
|
|
78
|
-
readonly start: (request: TranscriptionRequestFor) => import("effect/Effect").Effect<import("./generation.js").Generation<TranscriptionResponse>, import("./
|
|
77
|
+
} | import("./generation.js").Observation, import("./effect.js").AIError, TranscriptionClientService>;
|
|
78
|
+
readonly start: (request: TranscriptionRequestFor) => import("effect/Effect").Effect<import("./generation.js").Generation<TranscriptionResponse>, import("./effect.js").AIError, TranscriptionClientService>;
|
|
79
79
|
readonly resume: (model: import("./transcription.js").TranscriptionModel<{
|
|
80
80
|
readonly [x: string]: unknown;
|
|
81
|
-
}>, token: unknown) => import("effect/Effect").Effect<import("./generation.js").Generation<TranscriptionResponse>, import("./
|
|
81
|
+
}>, token: unknown) => import("effect/Effect").Effect<import("./generation.js").Generation<TranscriptionResponse>, import("./effect.js").AIError, TranscriptionClientService>;
|
|
82
82
|
readonly Service: typeof TranscriptionClientService;
|
|
83
83
|
};
|
|
84
84
|
export {};
|
package/dist/video-client.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export declare const Service: typeof VideoClientService;
|
|
|
9
9
|
export type Service = VideoClientService;
|
|
10
10
|
export declare const VideoClient: {
|
|
11
11
|
readonly layer: import("effect/Layer").Layer<VideoClientService, never, import("./route/executor-service.js").RequestExecutorService>;
|
|
12
|
-
readonly generate: (request: VideoRequestFor, options?: import("./generation.js").AwaitOptions) => import("effect/Effect").Effect<VideoResponse, import("./
|
|
12
|
+
readonly generate: (request: VideoRequestFor, options?: import("./generation.js").AwaitOptions) => import("effect/Effect").Effect<VideoResponse, import("./effect.js").AIError, VideoClientService>;
|
|
13
13
|
readonly stream: (request: VideoRequestFor, options?: import("./generation.js").AwaitOptions) => import("effect/Stream").Stream<{
|
|
14
14
|
readonly type: "video";
|
|
15
15
|
readonly index: number;
|
|
@@ -51,11 +51,11 @@ export declare const VideoClient: {
|
|
|
51
51
|
readonly [x: string]: unknown;
|
|
52
52
|
};
|
|
53
53
|
} | undefined;
|
|
54
|
-
} | import("./generation.js").Observation, import("./
|
|
55
|
-
readonly start: (request: VideoRequestFor) => import("effect/Effect").Effect<import("./generation.js").Generation<VideoResponse>, import("./
|
|
54
|
+
} | import("./generation.js").Observation, import("./effect.js").AIError, VideoClientService>;
|
|
55
|
+
readonly start: (request: VideoRequestFor) => import("effect/Effect").Effect<import("./generation.js").Generation<VideoResponse>, import("./effect.js").AIError, VideoClientService>;
|
|
56
56
|
readonly resume: (model: import("./video.js").VideoModel<{
|
|
57
57
|
readonly [x: string]: unknown;
|
|
58
|
-
}>, token: unknown) => import("effect/Effect").Effect<import("./generation.js").Generation<VideoResponse>, import("./
|
|
58
|
+
}>, token: unknown) => import("effect/Effect").Effect<import("./generation.js").Generation<VideoResponse>, import("./effect.js").AIError, VideoClientService>;
|
|
59
59
|
readonly Service: typeof VideoClientService;
|
|
60
60
|
};
|
|
61
61
|
export {};
|
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-21803",
|
|
4
4
|
"name": "@opencode/ai",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -19,9 +19,9 @@
|
|
|
19
19
|
"import": "./dist/index.js",
|
|
20
20
|
"types": "./dist/index.d.ts"
|
|
21
21
|
},
|
|
22
|
-
"./
|
|
23
|
-
"import": "./dist/
|
|
24
|
-
"types": "./dist/
|
|
22
|
+
"./effect": {
|
|
23
|
+
"import": "./dist/effect.js",
|
|
24
|
+
"types": "./dist/effect.d.ts"
|
|
25
25
|
},
|
|
26
26
|
"./testing": {
|
|
27
27
|
"import": "./dist/testing.js",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@clack/prompts": "1.0.0-alpha.1",
|
|
37
37
|
"@effect/platform-node": "4.0.1",
|
|
38
|
-
"@opencode/http-recorder": "0.0.0-dev-
|
|
38
|
+
"@opencode/http-recorder": "0.0.0-dev-21803",
|
|
39
39
|
"@tsconfig/bun": "1.0.9",
|
|
40
40
|
"@types/bun": "1.4.3",
|
|
41
41
|
"@typescript/native": "npm:typescript@7.1.0-beta",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"@aws-sdk/credential-providers": "3.1057.0",
|
|
46
46
|
"@smithy/eventstream-codec": "4.2.14",
|
|
47
47
|
"@smithy/util-utf8": "4.2.2",
|
|
48
|
-
"@opencode/schema": "0.0.0-dev-
|
|
48
|
+
"@opencode/schema": "0.0.0-dev-21803",
|
|
49
49
|
"aws4fetch": "1.0.20",
|
|
50
50
|
"effect": "4.0.1",
|
|
51
51
|
"google-auth-library": "10.5.0"
|