@opencode-ai/ai 0.0.0-dev-17714 → 0.0.0-dev-17720

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.
@@ -210,6 +210,19 @@ export const Event = Schema.StructWithRest(Schema.Struct({
210
210
  status_code: Schema.optional(Schema.Unknown),
211
211
  headers: Schema.optional(Schema.Unknown),
212
212
  }), [Schema.Record(Schema.String, Schema.Unknown)]);
213
+ const RefusalEvent = Schema.Union([
214
+ Schema.Struct({
215
+ type: Schema.tag("response.refusal.delta"),
216
+ item_id: Schema.String,
217
+ delta: Schema.String,
218
+ }),
219
+ Schema.Struct({
220
+ type: Schema.tag("response.refusal.done"),
221
+ item_id: Schema.String,
222
+ refusal: Schema.String,
223
+ }),
224
+ ]);
225
+ const isRefusalEvent = Schema.is(RefusalEvent);
213
226
  const BASE = { id: ADAPTER, name: NAME };
214
227
  // =============================================================================
215
228
  // Request Lowering
@@ -832,6 +845,13 @@ export const step = (state, event) => {
832
845
  ? onOutputTextDelta(state, event, event.item_id)
833
846
  : onOutputTextDone(state, event, event.item_id));
834
847
  }
848
+ if (event.type === "response.refusal.delta" || event.type === "response.refusal.done") {
849
+ if (!isRefusalEvent(event))
850
+ return ProviderShared.eventError(state.id, `${event.type} is malformed`);
851
+ return Effect.succeed(event.type === "response.refusal.delta"
852
+ ? onOutputTextDelta(state, event, event.item_id)
853
+ : onOutputTextDone(state, { ...event, text: event.refusal }, event.item_id));
854
+ }
835
855
  if (event.type === "response.reasoning.delta" || event.type === "response.reasoning_summary_text.delta") {
836
856
  if (!event.item_id)
837
857
  return ProviderShared.eventError(state.id, `${event.type} is missing item_id`);
@@ -204,6 +204,7 @@ export declare const OpenAIChatEvent: Schema.Struct<{
204
204
  readonly choices: Schema.optional<Schema.NullOr<Schema.$Array<Schema.Struct<{
205
205
  readonly delta: Schema.optional<Schema.NullOr<Schema.StructWithRest<Schema.Struct<{
206
206
  readonly content: Schema.optional<Schema.NullOr<Schema.String>>;
207
+ readonly refusal: Schema.optional<Schema.NullOr<Schema.String>>;
207
208
  readonly reasoning_content: Schema.optional<Schema.NullOr<Schema.String>>;
208
209
  readonly reasoning: Schema.optional<Schema.NullOr<Schema.String>>;
209
210
  readonly reasoning_text: Schema.optional<Schema.NullOr<Schema.String>>;
@@ -584,6 +585,7 @@ export declare const protocol: Protocol<{
584
585
  readonly reasoning_content?: string | null | undefined;
585
586
  readonly reasoning_text?: string | null | undefined;
586
587
  readonly content?: string | null | undefined;
588
+ readonly refusal?: string | null | undefined;
587
589
  readonly tool_calls?: readonly {
588
590
  readonly function?: {
589
591
  readonly name?: string | null | undefined;
@@ -13,7 +13,7 @@ import { Lifecycle } from "./utils/lifecycle.js";
13
13
  import { ToolSchemaProjection } from "./utils/tool-schema.js";
14
14
  import { ToolStream } from "./utils/tool-stream.js";
15
15
  const ADAPTER = "openai-chat";
16
- const RESERVED_REASONING_FIELDS = new Set(["role", "content", "tool_calls"]);
16
+ const RESERVED_REASONING_FIELDS = new Set(["role", "content", "refusal", "tool_calls"]);
17
17
  export const DEFAULT_BASE_URL = "https://api.openai.com/v1";
18
18
  export const PATH = "/chat/completions";
19
19
  // =============================================================================
@@ -144,6 +144,7 @@ const OpenAIChatToolCallDelta = Schema.Struct({
144
144
  });
145
145
  const OpenAIChatDelta = Schema.StructWithRest(Schema.Struct({
146
146
  content: optionalNull(Schema.String),
147
+ refusal: optionalNull(Schema.String),
147
148
  reasoning_content: optionalNull(Schema.String),
148
149
  reasoning: optionalNull(Schema.String),
149
150
  reasoning_text: optionalNull(Schema.String),
@@ -568,6 +569,7 @@ const step = (state, event) => Effect.gen(function* () {
568
569
  let lifecycle = state.lifecycle;
569
570
  const reasoning = reasoningDelta(delta, state.reasoningField);
570
571
  const hasLateContent = Boolean(delta?.content) ||
572
+ Boolean(delta?.refusal) ||
571
573
  reasoning !== undefined ||
572
574
  (Array.isArray(delta?.reasoning_details) && delta.reasoning_details.length > 0) ||
573
575
  toolDeltas.some((tool) => Boolean(tool.id) || Boolean(tool.function?.name) || Boolean(tool.function?.arguments));
@@ -587,13 +589,17 @@ const step = (state, event) => Effect.gen(function* () {
587
589
  lifecycle = Lifecycle.reasoningDelta(lifecycle, events, "reasoning-0", text, deltaMetadata);
588
590
  else if (reasoningDetailsObserved &&
589
591
  !lifecycle.reasoning.has("reasoning-0") &&
590
- (Boolean(delta?.content) || toolDeltas.length > 0))
592
+ (Boolean(delta?.content) || Boolean(delta?.refusal) || toolDeltas.length > 0))
591
593
  lifecycle = Lifecycle.reasoningStart(lifecycle, events, "reasoning-0", deltaMetadata);
592
594
  const reasoningEmitted = state.reasoningEmitted || lifecycle.reasoning.has("reasoning-0");
593
595
  if (delta?.content) {
594
596
  lifecycle = Lifecycle.reasoningEnd(lifecycle, events, "reasoning-0", reasoningMetadata(reasoningField, reasoningDetailsObserved ? state.reasoningDetails : undefined));
595
597
  lifecycle = Lifecycle.textDelta(lifecycle, events, "text-0", delta.content);
596
598
  }
599
+ if (delta?.refusal) {
600
+ lifecycle = Lifecycle.reasoningEnd(lifecycle, events, "reasoning-0", reasoningMetadata(reasoningField, reasoningDetailsObserved ? state.reasoningDetails : undefined));
601
+ lifecycle = Lifecycle.textDelta(lifecycle, events, "text-0", delta.refusal);
602
+ }
597
603
  // Compatible providers may omit indexes. Prefer durable identity, then use
598
604
  // batch position for parallel deltas or the latest call for sparse chunks.
599
605
  for (const [position, tool] of toolDeltas.entries()) {
@@ -307,6 +307,7 @@ export declare const protocol: Protocol<{
307
307
  readonly reasoning_content?: string | null | undefined;
308
308
  readonly reasoning_text?: string | null | undefined;
309
309
  readonly content?: string | null | undefined;
310
+ readonly refusal?: string | null | undefined;
310
311
  readonly tool_calls?: readonly {
311
312
  readonly function?: {
312
313
  readonly name?: string | null | undefined;
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-17714",
3
+ "version": "0.0.0-dev-17720",
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.110",
33
- "@opencode-ai/http-recorder": "0.0.0-dev-17714",
33
+ "@opencode-ai/http-recorder": "0.0.0-dev-17720",
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-17714",
42
+ "@opencode-ai/schema": "0.0.0-dev-17720",
43
43
  "aws4fetch": "1.0.20",
44
44
  "effect": "4.0.0-rc.110",
45
45
  "google-auth-library": "10.5.0"