@opencode-ai/ai 0.0.0-dev-18195 → 0.0.0-dev-18199

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.
@@ -1,7 +1,7 @@
1
1
  import { Context, Effect, Layer } from "effect";
2
2
  import { RequestExecutor } from "./route/executor.js";
3
+ import { type AIError } from "./schema/index.js";
3
4
  import type { ImageOptions, ImageRequestFor, ImageResponse } from "./image.js";
4
- import type { AIError } from "./schema/index.js";
5
5
  export type Execute = RequestExecutor.Interface["execute"];
6
6
  export interface Interface {
7
7
  readonly generate: <Options extends ImageOptions>(request: ImageRequestFor<Options>) => Effect.Effect<ImageResponse, AIError>;
@@ -1,5 +1,7 @@
1
1
  import { Context, Effect, Layer } from "effect";
2
2
  import { RequestExecutor } from "./route/executor.js";
3
+ import { mergeHttpOptions } from "./schema/index.js";
4
+ import { sanitizeSurrogates } from "./utils/sanitize.js";
3
5
  export class Service extends Context.Service()("@opencode/ImageClient") {
4
6
  }
5
7
  export const generate = (request) => Effect.gen(function* () {
@@ -9,7 +11,14 @@ export const generate = (request) => Effect.gen(function* () {
9
11
  export const layer = Layer.effect(Service, Effect.gen(function* () {
10
12
  const executor = yield* RequestExecutor.Service;
11
13
  return Service.of({
12
- generate: (request) => request.model.route.generate(request, executor.execute),
14
+ generate: (request) => request.model.route.generate({
15
+ ...sanitizeSurrogates({
16
+ ...request,
17
+ model: undefined,
18
+ http: mergeHttpOptions(request.model.http, request.http),
19
+ }),
20
+ model: request.model,
21
+ }, executor.execute),
13
22
  });
14
23
  }));
15
24
  export const ImageClient = {
@@ -273,6 +273,14 @@ export declare const protocol: Protocol<{
273
273
  } | undefined;
274
274
  readonly metrics?: unknown;
275
275
  } | undefined;
276
+ readonly exception?: {
277
+ readonly type: string;
278
+ readonly details: {
279
+ readonly message?: string | undefined;
280
+ readonly originalMessage?: string | undefined;
281
+ readonly originalStatusCode?: number | undefined;
282
+ };
283
+ } | undefined;
276
284
  readonly messageStart?: {
277
285
  readonly role: string;
278
286
  } | undefined;
@@ -307,31 +315,6 @@ export declare const protocol: Protocol<{
307
315
  readonly stopReason: string;
308
316
  readonly additionalModelResponseFields?: unknown;
309
317
  } | undefined;
310
- readonly internalServerException?: {
311
- readonly message?: string | undefined;
312
- readonly originalMessage?: string | undefined;
313
- readonly originalStatusCode?: number | undefined;
314
- } | undefined;
315
- readonly modelStreamErrorException?: {
316
- readonly message?: string | undefined;
317
- readonly originalMessage?: string | undefined;
318
- readonly originalStatusCode?: number | undefined;
319
- } | undefined;
320
- readonly validationException?: {
321
- readonly message?: string | undefined;
322
- readonly originalMessage?: string | undefined;
323
- readonly originalStatusCode?: number | undefined;
324
- } | undefined;
325
- readonly throttlingException?: {
326
- readonly message?: string | undefined;
327
- readonly originalMessage?: string | undefined;
328
- readonly originalStatusCode?: number | undefined;
329
- } | undefined;
330
- readonly serviceUnavailableException?: {
331
- readonly message?: string | undefined;
332
- readonly originalMessage?: string | undefined;
333
- readonly originalStatusCode?: number | undefined;
334
- } | undefined;
335
318
  }, {
336
319
  readonly metadata?: {
337
320
  readonly usage?: {
@@ -343,6 +326,14 @@ export declare const protocol: Protocol<{
343
326
  } | undefined;
344
327
  readonly metrics?: unknown;
345
328
  } | undefined;
329
+ readonly exception?: {
330
+ readonly type: string;
331
+ readonly details: {
332
+ readonly message?: string | undefined;
333
+ readonly originalMessage?: string | undefined;
334
+ readonly originalStatusCode?: number | undefined;
335
+ };
336
+ } | undefined;
346
337
  readonly messageStart?: {
347
338
  readonly role: string;
348
339
  } | undefined;
@@ -377,31 +368,6 @@ export declare const protocol: Protocol<{
377
368
  readonly stopReason: string;
378
369
  readonly additionalModelResponseFields?: unknown;
379
370
  } | undefined;
380
- readonly internalServerException?: {
381
- readonly message?: string | undefined;
382
- readonly originalMessage?: string | undefined;
383
- readonly originalStatusCode?: number | undefined;
384
- } | undefined;
385
- readonly modelStreamErrorException?: {
386
- readonly message?: string | undefined;
387
- readonly originalMessage?: string | undefined;
388
- readonly originalStatusCode?: number | undefined;
389
- } | undefined;
390
- readonly validationException?: {
391
- readonly message?: string | undefined;
392
- readonly originalMessage?: string | undefined;
393
- readonly originalStatusCode?: number | undefined;
394
- } | undefined;
395
- readonly throttlingException?: {
396
- readonly message?: string | undefined;
397
- readonly originalMessage?: string | undefined;
398
- readonly originalStatusCode?: number | undefined;
399
- } | undefined;
400
- readonly serviceUnavailableException?: {
401
- readonly message?: string | undefined;
402
- readonly originalMessage?: string | undefined;
403
- readonly originalStatusCode?: number | undefined;
404
- } | undefined;
405
371
  }, ParserState>;
406
372
  export declare const route: Route<{
407
373
  readonly messages: readonly ({
@@ -149,11 +149,7 @@ const BedrockEvent = Schema.Struct({
149
149
  usage: Schema.optional(BedrockUsageSchema),
150
150
  metrics: Schema.optional(Schema.Unknown),
151
151
  })),
152
- internalServerException: Schema.optional(BedrockStreamException),
153
- modelStreamErrorException: Schema.optional(BedrockStreamException),
154
- validationException: Schema.optional(BedrockStreamException),
155
- throttlingException: Schema.optional(BedrockStreamException),
156
- serviceUnavailableException: Schema.optional(BedrockStreamException),
152
+ exception: Schema.optional(Schema.Struct({ type: Schema.String, details: BedrockStreamException })),
157
153
  });
158
154
  // =============================================================================
159
155
  // Request Lowering
@@ -507,20 +503,13 @@ const step = (state, event) => Effect.gen(function* () {
507
503
  [],
508
504
  ];
509
505
  }
510
- const exception = [
511
- ["internalServerException", event.internalServerException],
512
- ["modelStreamErrorException", event.modelStreamErrorException],
513
- ["serviceUnavailableException", event.serviceUnavailableException],
514
- ["throttlingException", event.throttlingException],
515
- ["validationException", event.validationException],
516
- ].find((entry) => entry[1] !== undefined);
517
- if (exception) {
506
+ if (event.exception) {
518
507
  return yield* new AIError({
519
508
  module: ADAPTER,
520
509
  method: "stream",
521
510
  reason: classifyProviderFailure({
522
- message: exception[1]?.message ?? exception[1]?.originalMessage ?? "Bedrock Converse stream error",
523
- code: exception[0],
511
+ message: event.exception.details.message ?? event.exception.details.originalMessage ?? "Bedrock Converse stream error",
512
+ code: event.exception.type,
524
513
  }),
525
514
  });
526
515
  }
@@ -56,7 +56,7 @@ const consumeFrames = (route) => (state, chunk) => Effect.gen(function* () {
56
56
  // against ad-hoc `JSON.parse` calls.
57
57
  const parsed = (yield* ProviderShared.parseJson(route, payload, "Failed to parse Bedrock Converse event-stream payload"));
58
58
  delete parsed.p;
59
- out.push({ [eventType]: parsed });
59
+ out.push(messageType === "exception" ? { exception: { type: eventType, details: parsed } } : { [eventType]: parsed });
60
60
  }
61
61
  return [cursor, out];
62
62
  });
@@ -5,6 +5,7 @@ import { RequestExecutor } from "./executor.js";
5
5
  import { Framing } from "./framing.js";
6
6
  import { HttpTransport } from "./transport/index.js";
7
7
  import { applyCachePolicy } from "../cache-policy.js";
8
+ import { sanitizeSurrogates } from "../utils/sanitize.js";
8
9
  import * as ProviderShared from "../protocols/shared.js";
9
10
  import { AIError, GenerationOptions, HttpOptions, LLMRequest, LLMResponse, LanguageModel, LLMEvent, InvalidProviderOutputReason, ProviderID, mergeGenerationOptions, mergeHttpOptions, mergeProviderOptions, } from "../schema/index.js";
10
11
  const makeRouteLanguageModel = (route, mapped) => {
@@ -159,7 +160,8 @@ export function make(input) {
159
160
  });
160
161
  }
161
162
  const compile = Effect.fn("LLM.compile")(function* (request, options) {
162
- const resolved = applyCachePolicy(resolveRequestOptions(request));
163
+ const original = applyCachePolicy(resolveRequestOptions(request));
164
+ const resolved = LLMRequest.update(original, sanitizeSurrogates({ ...LLMRequest.input(original), model: undefined }));
163
165
  const route = resolved.model.route;
164
166
  const body = yield* route.body
165
167
  .from(resolved)
@@ -0,0 +1 @@
1
+ export declare const sanitizeSurrogates: <T>(value: T) => T;
@@ -0,0 +1,12 @@
1
+ import { isRecord } from "./record.js";
2
+ export const sanitizeSurrogates = (value) => {
3
+ if (typeof value === "string")
4
+ return value.toWellFormed();
5
+ if (Array.isArray(value))
6
+ return value.map(sanitizeSurrogates);
7
+ if (value instanceof Uint8Array || value instanceof Error)
8
+ return value;
9
+ if (isRecord(value))
10
+ return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key.toWellFormed(), sanitizeSurrogates(entry)]));
11
+ return value;
12
+ };
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-18195",
3
+ "version": "0.0.0-dev-18199",
4
4
  "name": "@opencode-ai/ai",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -30,7 +30,7 @@
30
30
  "devDependencies": {
31
31
  "@clack/prompts": "1.0.0-alpha.1",
32
32
  "@effect/platform-node": "4.0.0-rc.111",
33
- "@opencode-ai/http-recorder": "0.0.0-dev-18195",
33
+ "@opencode-ai/http-recorder": "0.0.0-dev-18199",
34
34
  "@tsconfig/bun": "1.0.9",
35
35
  "@types/bun": "1.3.13",
36
36
  "@typescript/native-preview": "7.0.0-dev.20251207.1",
@@ -39,7 +39,7 @@
39
39
  "dependencies": {
40
40
  "@smithy/eventstream-codec": "4.2.14",
41
41
  "@smithy/util-utf8": "4.2.2",
42
- "@opencode-ai/schema": "0.0.0-dev-18195",
42
+ "@opencode-ai/schema": "0.0.0-dev-18199",
43
43
  "aws4fetch": "1.0.20",
44
44
  "effect": "4.0.0-rc.111",
45
45
  "google-auth-library": "10.5.0"