@opencode/ai 0.0.0-dev-20415 → 0.0.0-dev-20416
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.
|
@@ -2,6 +2,7 @@ import { Effect } from "effect";
|
|
|
2
2
|
import { Headers, HttpClientRequest } from "effect/unstable/http";
|
|
3
3
|
import { Framing } from "../framing.js";
|
|
4
4
|
import type { HttpMiddleware, Transport, TransportPrepareInput } from "./index.js";
|
|
5
|
+
import { AIError } from "../../schema/index.js";
|
|
5
6
|
export type JsonRequestInput<Body> = TransportPrepareInput<Body>;
|
|
6
7
|
export interface JsonRequestParts<Body = unknown> {
|
|
7
8
|
readonly url: string;
|
|
@@ -19,7 +20,7 @@ export declare const jsonRequestParts: <Body>(input: JsonRequestInput<Body>) =>
|
|
|
19
20
|
jsonBody: Record<string, unknown> | Body;
|
|
20
21
|
bodyText: string;
|
|
21
22
|
headers: Headers.Headers;
|
|
22
|
-
},
|
|
23
|
+
}, AIError, never>;
|
|
23
24
|
export interface HttpJsonInput<_Body, Frame> {
|
|
24
25
|
readonly framing: Framing.Definition<Frame>;
|
|
25
26
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { Effect } from "effect";
|
|
1
|
+
import { Clock, Duration, Effect, Stream } from "effect";
|
|
2
2
|
import { Headers, HttpClientRequest } from "effect/unstable/http";
|
|
3
3
|
import { Auth } from "../auth.js";
|
|
4
4
|
import { render as renderEndpoint } from "../endpoint.js";
|
|
5
5
|
import { Framing } from "../framing.js";
|
|
6
6
|
import * as ProviderShared from "../../protocols/shared.js";
|
|
7
|
-
import { mergeJsonRecords } from "../../schema/index.js";
|
|
7
|
+
import { AIError, DEFAULT_HTTP_TIMEOUT_MS, mergeJsonRecords, TransportError, } from "../../schema/index.js";
|
|
8
8
|
import { RequestExecutor } from "../executor.js";
|
|
9
9
|
const applyQuery = (url, query) => {
|
|
10
10
|
if (!query)
|
|
@@ -53,15 +53,37 @@ export const httpJson = (input) => ({
|
|
|
53
53
|
middleware: prepareInput.middleware,
|
|
54
54
|
};
|
|
55
55
|
}),
|
|
56
|
-
execute: (prepared,
|
|
57
|
-
const
|
|
56
|
+
execute: (prepared, request, runtime) => Effect.gen(function* () {
|
|
57
|
+
const timeout = (operation, message, http) => new AIError({
|
|
58
|
+
reason: new TransportError({
|
|
59
|
+
message,
|
|
60
|
+
transport: "http",
|
|
61
|
+
operation,
|
|
62
|
+
code: "Timeout",
|
|
63
|
+
url: prepared.request.url,
|
|
64
|
+
http,
|
|
65
|
+
}),
|
|
66
|
+
});
|
|
67
|
+
const started = yield* Clock.currentTimeMillis;
|
|
68
|
+
// Unlike the header and chunk limits, the whole-request budget has no default.
|
|
69
|
+
const total = request.http?.timeout ? Duration.millis(request.http.timeout) : Duration.infinity;
|
|
70
|
+
const response = yield* runtime.http.execute(prepared.request, prepared.middleware).pipe(Effect.timeoutOrElse({
|
|
71
|
+
duration: Duration.min(timeoutDuration(request.http?.headerTimeout), total),
|
|
72
|
+
orElse: () => timeout("request", "Timed out waiting for response headers"),
|
|
73
|
+
}));
|
|
74
|
+
const http = RequestExecutor.responseHttp(response);
|
|
75
|
+
const remaining = Duration.subtract(total, Duration.millis((yield* Clock.currentTimeMillis) - started));
|
|
58
76
|
return {
|
|
59
|
-
frames: prepared.framing.frame(RequestExecutor.responseStream(response)
|
|
60
|
-
|
|
77
|
+
frames: prepared.framing.frame(RequestExecutor.responseStream(response).pipe(Stream.timeoutOrElse({
|
|
78
|
+
duration: timeoutDuration(request.http?.chunkTimeout),
|
|
79
|
+
orElse: () => Stream.fail(timeout("read", "Timed out waiting for response data", http)),
|
|
80
|
+
}), Stream.interruptWhen(Effect.sleep(remaining).pipe(Effect.andThen(Effect.fail(timeout("read", "Timed out waiting for the response to complete", http))))))),
|
|
81
|
+
http,
|
|
61
82
|
body: prepared.framing.body,
|
|
62
83
|
};
|
|
63
84
|
}),
|
|
64
85
|
});
|
|
86
|
+
const timeoutDuration = (value) => value === false ? Duration.infinity : Duration.millis(value ?? DEFAULT_HTTP_TIMEOUT_MS);
|
|
65
87
|
export const sseJson = {
|
|
66
88
|
id: "http-json/sse",
|
|
67
89
|
with: () => httpJson({ framing: Framing.sse }),
|
package/dist/schema/options.d.ts
CHANGED
|
@@ -9,10 +9,21 @@ export type ProviderOptions = Schema.Schema.Type<typeof ProviderOptions>;
|
|
|
9
9
|
export declare const ProviderMetadata: Schema.$Record<Schema.String, Schema.$Record<Schema.String, Schema.Unknown>>;
|
|
10
10
|
export type ProviderMetadata = Schema.Schema.Type<typeof ProviderMetadata>;
|
|
11
11
|
export declare const mergeProviderOptions: (...items: ReadonlyArray<ProviderOptions | undefined>) => ProviderOptions | undefined;
|
|
12
|
+
/** Milliseconds for an HTTP timeout, or `false` to disable it. */
|
|
13
|
+
export declare const HttpTimeout: Schema.Union<readonly [Schema.Number, Schema.Literal<false>]>;
|
|
14
|
+
export type HttpTimeout = Schema.Schema.Type<typeof HttpTimeout>;
|
|
15
|
+
/** Applied to `headerTimeout` and `chunkTimeout` when a request leaves them unset. */
|
|
16
|
+
export declare const DEFAULT_HTTP_TIMEOUT_MS = 300000;
|
|
12
17
|
declare const HttpOptions_base: Schema.Class<HttpOptions, Schema.Struct<{
|
|
13
18
|
readonly body: Schema.optional<Schema.$Record<Schema.String, Schema.Unknown>>;
|
|
14
19
|
readonly headers: Schema.optional<Schema.$Record<Schema.String, Schema.String>>;
|
|
15
20
|
readonly query: Schema.optional<Schema.$Record<Schema.String, Schema.String>>;
|
|
21
|
+
/** Time allowed for the whole request, from send until the response completes. Unbounded when unset. */
|
|
22
|
+
readonly timeout: Schema.optional<Schema.Union<readonly [Schema.Number, Schema.Literal<false>]>>;
|
|
23
|
+
/** Time allowed for response headers to arrive. */
|
|
24
|
+
readonly headerTimeout: Schema.optional<Schema.Union<readonly [Schema.Number, Schema.Literal<false>]>>;
|
|
25
|
+
/** Time allowed between streamed response chunks once headers have arrived. */
|
|
26
|
+
readonly chunkTimeout: Schema.optional<Schema.Union<readonly [Schema.Number, Schema.Literal<false>]>>;
|
|
16
27
|
}>, {}>;
|
|
17
28
|
export declare class HttpOptions extends HttpOptions_base {
|
|
18
29
|
}
|
package/dist/schema/options.js
CHANGED
|
@@ -32,10 +32,20 @@ export const ProviderMetadata = Schema.Record(Schema.String, Schema.Record(Schem
|
|
|
32
32
|
identifier: "LLM.ProviderMetadata",
|
|
33
33
|
});
|
|
34
34
|
export const mergeProviderOptions = (...items) => mergeJsonRecords(...items);
|
|
35
|
+
/** Milliseconds for an HTTP timeout, or `false` to disable it. */
|
|
36
|
+
export const HttpTimeout = Schema.Union([Schema.Number.check(Schema.isGreaterThan(0)), Schema.Literal(false)]);
|
|
37
|
+
/** Applied to `headerTimeout` and `chunkTimeout` when a request leaves them unset. */
|
|
38
|
+
export const DEFAULT_HTTP_TIMEOUT_MS = 300_000;
|
|
35
39
|
export class HttpOptions extends Schema.Class("AI.HttpOptions")({
|
|
36
40
|
body: Schema.optional(JsonSchema),
|
|
37
41
|
headers: Schema.optional(Schema.Record(Schema.String, Schema.String)),
|
|
38
42
|
query: Schema.optional(Schema.Record(Schema.String, Schema.String)),
|
|
43
|
+
/** Time allowed for the whole request, from send until the response completes. Unbounded when unset. */
|
|
44
|
+
timeout: Schema.optional(HttpTimeout),
|
|
45
|
+
/** Time allowed for response headers to arrive. */
|
|
46
|
+
headerTimeout: Schema.optional(HttpTimeout),
|
|
47
|
+
/** Time allowed between streamed response chunks once headers have arrived. */
|
|
48
|
+
chunkTimeout: Schema.optional(HttpTimeout),
|
|
39
49
|
}) {
|
|
40
50
|
}
|
|
41
51
|
(function (HttpOptions) {
|
|
@@ -50,9 +60,12 @@ export const mergeHttpOptions = (...items) => {
|
|
|
50
60
|
const body = mergeJsonRecords(...items.map((item) => item?.body));
|
|
51
61
|
const headers = mergeStringRecords(...items.map((item) => item?.headers));
|
|
52
62
|
const query = mergeStringRecords(...items.map((item) => item?.query));
|
|
53
|
-
|
|
63
|
+
const timeout = items.findLast((item) => item?.timeout !== undefined)?.timeout;
|
|
64
|
+
const headerTimeout = items.findLast((item) => item?.headerTimeout !== undefined)?.headerTimeout;
|
|
65
|
+
const chunkTimeout = items.findLast((item) => item?.chunkTimeout !== undefined)?.chunkTimeout;
|
|
66
|
+
if (!body && !headers && !query && timeout === undefined && headerTimeout === undefined && chunkTimeout === undefined)
|
|
54
67
|
return undefined;
|
|
55
|
-
return new HttpOptions({ body, headers, query });
|
|
68
|
+
return new HttpOptions({ body, headers, query, timeout, headerTimeout, chunkTimeout });
|
|
56
69
|
};
|
|
57
70
|
export class GenerationOptions extends Schema.Class("LLM.GenerationOptions")({
|
|
58
71
|
maxTokens: Schema.optional(Schema.Number),
|
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-20416",
|
|
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-20416",
|
|
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-20416",
|
|
48
48
|
"aws4fetch": "1.0.20",
|
|
49
49
|
"effect": "4.0.0-rc.112",
|
|
50
50
|
"google-auth-library": "10.5.0"
|