@opencode-ai/ai 0.0.0-next-17028 → 0.0.0-next-17038

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.
@@ -272,12 +272,13 @@ const lowerAssistantMessage = Effect.fn("OpenAIChat.lowerAssistantMessage")(func
272
272
  return text;
273
273
  })();
274
274
  const cached = message.content.findLast((part) => "cache" in part && part.cache !== undefined);
275
+ const cacheControl = options.cacheControl?.(cached && "cache" in cached ? cached.cache : undefined);
275
276
  const result = {
276
277
  role: "assistant",
277
- content: content.length === 0 ? null : ProviderShared.joinText(content),
278
- tool_calls: toolCalls.length === 0 ? undefined : toolCalls,
279
- reasoning_details: details,
280
- cache_control: options.cacheControl?.(cached && "cache" in cached ? cached.cache : undefined),
278
+ content: content.length > 0 ? content.map((part) => part.text).join("") : toolCalls.length > 0 ? null : "",
279
+ ...(toolCalls.length > 0 ? { tool_calls: toolCalls } : {}),
280
+ ...(details !== undefined ? { reasoning_details: details } : {}),
281
+ ...(cacheControl !== undefined ? { cache_control: cacheControl } : {}),
281
282
  };
282
283
  if (field === undefined || reasoningText === undefined)
283
284
  return result;
@@ -574,14 +575,14 @@ const step = (state, event) => Effect.gen(function* () {
574
575
  return yield* ProviderShared.eventError(ADAPTER, "OpenAI Chat received content after the finish reason");
575
576
  return [{ ...state, usage }, events];
576
577
  }
577
- const reasoningField = state.reasoningField ?? (!state.lifecycle.text.has("text-0") ? reasoning?.field : undefined);
578
+ const reasoningField = state.reasoningField ?? reasoning?.field;
578
579
  const detailDelta = Array.isArray(delta?.reasoning_details) ? delta.reasoning_details : undefined;
579
580
  if (detailDelta !== undefined)
580
581
  appendReasoningDetails(state.reasoningDetails, detailDelta);
581
582
  const reasoningDetailsObserved = state.reasoningDetailsObserved || detailDelta !== undefined;
582
583
  const deltaMetadata = reasoningMetadata(reasoningField);
583
584
  const text = detailDelta?.length ? (detailText(detailDelta) ?? reasoning?.text) : reasoning?.text;
584
- if (!state.lifecycle.text.has("text-0") && text !== undefined)
585
+ if (text !== undefined)
585
586
  lifecycle = Lifecycle.reasoningDelta(lifecycle, events, "reasoning-0", text, deltaMetadata);
586
587
  else if (reasoningDetailsObserved &&
587
588
  !lifecycle.reasoning.has("reasoning-0") &&
@@ -652,22 +653,24 @@ const step = (state, event) => Effect.gen(function* () {
652
653
  });
653
654
  const finishEvents = (state) => {
654
655
  const events = [];
655
- const hasToolCalls = state.toolCallEvents.length > 0;
656
+ const toolCallEvents = state.finishReason === undefined && Object.keys(state.tools).length > 0
657
+ ? Effect.runSync(ToolStream.finishAll(ADAPTER, state.tools)).events
658
+ : state.toolCallEvents;
659
+ const hasToolCalls = toolCallEvents.length > 0;
656
660
  const reason = state.finishReason
657
661
  ? {
658
662
  ...state.finishReason,
659
663
  normalized: state.finishReason.normalized === "stop" && hasToolCalls ? "tool-calls" : state.finishReason.normalized,
660
664
  }
661
- : undefined;
665
+ : { normalized: hasToolCalls ? "tool-calls" : "unknown" };
662
666
  const metadata = reasoningMetadata(state.reasoningField, state.reasoningDetailsObserved ? state.reasoningDetails : undefined);
663
667
  const started = state.reasoningDetailsObserved && !state.reasoningEmitted
664
668
  ? Lifecycle.reasoningStart(state.lifecycle, events, "reasoning-0", reasoningMetadata(state.reasoningField))
665
669
  : state.lifecycle;
666
670
  const ended = Lifecycle.reasoningEnd(started, events, "reasoning-0", metadata);
667
- const lifecycle = state.toolCallEvents.length ? Lifecycle.stepStart(ended, events) : ended;
668
- events.push(...state.toolCallEvents);
669
- if (reason)
670
- Lifecycle.finish(lifecycle, events, { reason, usage: state.usage });
671
+ const lifecycle = toolCallEvents.length ? Lifecycle.stepStart(ended, events) : ended;
672
+ events.push(...toolCallEvents);
673
+ Lifecycle.finish(lifecycle, events, { reason, usage: state.usage });
671
674
  return events;
672
675
  };
673
676
  // =============================================================================
@@ -33,6 +33,28 @@ export declare const MediaPart: Schema.Struct<{
33
33
  readonly metadata: Schema.optional<Schema.$Record<Schema.String, Schema.Unknown>>;
34
34
  }>;
35
35
  export type MediaPart = Schema.Schema.Type<typeof MediaPart>;
36
+ declare const toolResultValueSchema: Schema.Union<readonly [Schema.Struct<{
37
+ readonly type: Schema.Literal<"json">;
38
+ readonly value: Schema.Unknown;
39
+ }>, Schema.Struct<{
40
+ readonly type: Schema.Literal<"text">;
41
+ readonly value: Schema.Unknown;
42
+ }>, Schema.Struct<{
43
+ readonly type: Schema.Literal<"error">;
44
+ readonly value: Schema.Unknown;
45
+ }>, Schema.Struct<{
46
+ readonly type: Schema.Literal<"content">;
47
+ readonly value: Schema.$Array<Schema.Union<readonly [Schema.Struct<{
48
+ readonly type: Schema.Literal<"text">;
49
+ readonly text: Schema.String;
50
+ }>, Schema.Struct<{
51
+ readonly type: Schema.Literal<"file">;
52
+ readonly uri: Schema.String;
53
+ readonly mime: Schema.String;
54
+ readonly name: Schema.optional<Schema.String>;
55
+ }>]>>;
56
+ }>]>;
57
+ export type ToolResultValue = Schema.Schema.Type<typeof toolResultValueSchema>;
36
58
  export declare const ToolResultValue: Schema.Union<readonly [Schema.Struct<{
37
59
  readonly type: Schema.Literal<"json">;
38
60
  readonly value: Schema.Unknown;
@@ -57,7 +79,6 @@ export declare const ToolResultValue: Schema.Union<readonly [Schema.Struct<{
57
79
  is: (value: unknown) => value is ToolResultValue;
58
80
  make: (value: unknown, type?: ToolResultValue["type"]) => ToolResultValue;
59
81
  };
60
- export type ToolResultValue = Schema.Schema.Type<typeof ToolResultValue>;
61
82
  export interface ToolOutput {
62
83
  readonly structured: unknown;
63
84
  readonly content: ReadonlyArray<Tool.Content>;
@@ -35,7 +35,7 @@ export const MediaPart = Schema.Struct({
35
35
  const isToolResultValue = (value) => isRecord(value) &&
36
36
  (value.type === "text" || value.type === "json" || value.type === "error" || value.type === "content") &&
37
37
  "value" in value;
38
- export const ToolResultValue = Object.assign(Schema.Union([
38
+ const toolResultValueSchema = Schema.Union([
39
39
  Schema.Struct({
40
40
  type: Schema.Literal("json"),
41
41
  value: Schema.Unknown,
@@ -52,7 +52,8 @@ export const ToolResultValue = Object.assign(Schema.Union([
52
52
  type: Schema.Literal("content"),
53
53
  value: Schema.Array(Tool.Content),
54
54
  }),
55
- ]).annotate({ identifier: "LLM.ToolResult" }), {
55
+ ]).annotate({ identifier: "LLM.ToolResult" });
56
+ export const ToolResultValue = Object.assign(toolResultValueSchema, {
56
57
  is: isToolResultValue,
57
58
  make: (value, type = "json") => {
58
59
  if (isToolResultValue(value))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
- "version": "0.0.0-next-17028",
3
+ "version": "0.0.0-next-17038",
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-beta.101",
33
- "@opencode-ai/http-recorder": "0.0.0-next-17028",
33
+ "@opencode-ai/http-recorder": "0.0.0-next-17038",
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-next-17028",
42
+ "@opencode-ai/schema": "0.0.0-next-17038",
43
43
  "aws4fetch": "1.0.20",
44
44
  "effect": "4.0.0-beta.101",
45
45
  "google-auth-library": "10.5.0"