@oh-my-pi/pi-ai 13.5.6 → 13.5.8

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/CHANGELOG.md CHANGED
@@ -2,6 +2,11 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [13.5.8] - 2026-03-02
6
+ ### Fixed
7
+
8
+ - Fixed schema compatibility issue where patternProperties in tool parameters caused failures when converting to legacy Antigravity format
9
+
5
10
  ## [13.5.5] - 2026-03-01
6
11
 
7
12
  ### Changed
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@oh-my-pi/pi-ai",
4
- "version": "13.5.6",
4
+ "version": "13.5.8",
5
5
  "description": "Unified LLM API with automatic model discovery and provider configuration",
6
6
  "homepage": "https://github.com/can1357/oh-my-pi",
7
7
  "author": "Can Boluk",
@@ -41,7 +41,7 @@
41
41
  "@aws-sdk/client-bedrock-runtime": "^3.998",
42
42
  "@bufbuild/protobuf": "^2.11",
43
43
  "@google/genai": "^1.43",
44
- "@oh-my-pi/pi-utils": "13.5.6",
44
+ "@oh-my-pi/pi-utils": "13.5.8",
45
45
  "@sinclair/typebox": "^0.34",
46
46
  "@smithy/node-http-handler": "^4.4",
47
47
  "ajv": "^8.18",
@@ -746,18 +746,18 @@ type SystemBlockOptions = {
746
746
  includeClaudeCodeInstruction?: boolean;
747
747
  extraInstructions?: string[];
748
748
  billingPayload?: unknown;
749
+ cacheControl?: AnthropicCacheControl;
749
750
  };
750
751
 
751
752
  export function buildAnthropicSystemBlocks(
752
753
  systemPrompt: string | undefined,
753
754
  options: SystemBlockOptions = {},
754
755
  ): AnthropicSystemBlock[] | undefined {
755
- const { includeClaudeCodeInstruction = false, extraInstructions = [], billingPayload } = options;
756
+ const { includeClaudeCodeInstruction = false, extraInstructions = [], billingPayload, cacheControl } = options;
756
757
  const blocks: AnthropicSystemBlock[] = [];
757
758
  const sanitizedPrompt = systemPrompt ? systemPrompt.toWellFormed() : "";
758
759
  const trimmedInstructions = extraInstructions.map(instruction => instruction.trim()).filter(Boolean);
759
760
  const hasBillingHeader = sanitizedPrompt.includes(CLAUDE_BILLING_HEADER_PREFIX);
760
- const claudeCodeSystemCacheControl: AnthropicCacheControl = { type: "ephemeral" };
761
761
 
762
762
  if (includeClaudeCodeInstruction && !hasBillingHeader) {
763
763
  const payloadSeed = billingPayload ?? {
@@ -777,7 +777,7 @@ export function buildAnthropicSystemBlocks(
777
777
  blocks.push({
778
778
  type: "text",
779
779
  text: instruction,
780
- ...(includeClaudeCodeInstruction ? { cache_control: claudeCodeSystemCacheControl } : {}),
780
+ ...(cacheControl ? { cache_control: cacheControl } : {}),
781
781
  });
782
782
  }
783
783
 
@@ -785,7 +785,7 @@ export function buildAnthropicSystemBlocks(
785
785
  blocks.push({
786
786
  type: "text",
787
787
  text: sanitizedPrompt,
788
- ...(includeClaudeCodeInstruction ? { cache_control: claudeCodeSystemCacheControl } : {}),
788
+ ...(cacheControl ? { cache_control: cacheControl } : {}),
789
789
  });
790
790
  }
791
791
 
@@ -923,10 +923,6 @@ type CacheControlBlock = {
923
923
  cache_control?: AnthropicCacheControl | null;
924
924
  };
925
925
 
926
- function hasCacheControlInBlocks<T extends CacheControlBlock>(blocks: T[]): boolean {
927
- return blocks.some(block => "cache_control" in block && block.cache_control != null);
928
- }
929
-
930
926
  function applyCacheControlToLastBlock<T extends CacheControlBlock>(
931
927
  blocks: T[],
932
928
  cacheControl: AnthropicCacheControl,
@@ -952,11 +948,12 @@ function applyCacheControlToLastTextBlock(
952
948
 
953
949
  function applyPromptCaching(params: MessageCreateParamsStreaming, cacheControl?: AnthropicCacheControl): void {
954
950
  if (!cacheControl) return;
955
- if (params.tools && hasCacheControlInBlocks(params.tools as Array<CacheControlBlock>)) return;
956
- if (params.system && Array.isArray(params.system) && hasCacheControlInBlocks(params.system)) return;
951
+
952
+ // Skip if cache_control breakpoints were already placed externally on messages.
957
953
  for (const message of params.messages) {
958
954
  if (Array.isArray(message.content)) {
959
- if (hasCacheControlInBlocks(message.content as Array<ContentBlockParam & CacheControlBlock>)) return;
955
+ if ((message.content as Array<ContentBlockParam & CacheControlBlock>).some(b => b.cache_control != null))
956
+ return;
960
957
  }
961
958
  }
962
959
 
@@ -8,6 +8,14 @@ export function inferCopilotInitiator(messages: unknown[]): "user" | "agent" {
8
8
  if (messages.length === 0) return "user";
9
9
 
10
10
  const last = messages[messages.length - 1] as Record<string, unknown>;
11
+ const attribution = last.attribution;
12
+ if (typeof attribution === "string") {
13
+ const normalizedAttribution = attribution.trim().toLowerCase();
14
+ if (normalizedAttribution === "user" || normalizedAttribution === "agent") {
15
+ return normalizedAttribution;
16
+ }
17
+ }
18
+
11
19
  const role = last.role as string | undefined;
12
20
  if (!role) return "user";
13
21
 
@@ -23,6 +23,7 @@ import { appendRawHttpRequestDumpFor400, type RawHttpRequestDump, withHttpStatus
23
23
  import { refreshAntigravityToken } from "../utils/oauth/google-antigravity";
24
24
  import { refreshGoogleCloudToken } from "../utils/oauth/google-gemini-cli";
25
25
  import { extractHttpStatusFromError } from "../utils/retry";
26
+ import { sanitizeSchemaForCCA } from "../utils/schema";
26
27
  import {
27
28
  convertMessages,
28
29
  convertTools,
@@ -981,14 +982,14 @@ function normalizeAntigravityTools(
981
982
  return tools?.map(tool => ({
982
983
  ...tool,
983
984
  functionDeclarations: tool.functionDeclarations.map(declaration => {
984
- if (!("parametersJsonSchema" in declaration)) {
985
+ if ("parameters" in declaration) {
985
986
  return declaration;
986
987
  }
987
988
 
988
989
  const { parametersJsonSchema, ...rest } = declaration;
989
990
  return {
990
991
  ...rest,
991
- parameters: parametersJsonSchema,
992
+ parameters: sanitizeSchemaForCCA(parametersJsonSchema),
992
993
  };
993
994
  }),
994
995
  }));
package/src/types.ts CHANGED
@@ -112,6 +112,8 @@ export type ThinkingLevel = "minimal" | "low" | "medium" | "high" | "xhigh";
112
112
  /** Token budgets for each thinking level (token-based providers only) */
113
113
  export type ThinkingBudgets = { [key in ThinkingLevel]?: number };
114
114
 
115
+ export type MessageAttribution = "user" | "agent";
116
+
115
117
  export type ToolChoice =
116
118
  | "auto"
117
119
  | "none"
@@ -257,12 +259,16 @@ export interface UserMessage {
257
259
  content: string | (TextContent | ImageContent)[];
258
260
  /** True if the message was injected by the system (e.g., auto-continue). */
259
261
  synthetic?: boolean;
262
+ /** Who initiated this message for billing/attribution semantics. */
263
+ attribution?: MessageAttribution;
260
264
  timestamp: number; // Unix timestamp in milliseconds
261
265
  }
262
266
 
263
267
  export interface DeveloperMessage {
264
268
  role: "developer";
265
269
  content: string | (TextContent | ImageContent)[];
270
+ /** Who initiated this message for billing/attribution semantics. */
271
+ attribution?: MessageAttribution;
266
272
  timestamp: number; // Unix timestamp in milliseconds
267
273
  }
268
274
 
@@ -287,6 +293,8 @@ export interface ToolResultMessage<TDetails = any> {
287
293
  content: (TextContent | ImageContent)[]; // Supports text and images
288
294
  details?: TDetails;
289
295
  isError: boolean;
296
+ /** Who initiated this message for billing/attribution semantics. */
297
+ attribution?: MessageAttribution;
290
298
  /** Timestamp when output was pruned (ms since epoch). Undefined if unpruned. */
291
299
  prunedAt?: number;
292
300
  timestamp: number; // Unix timestamp in milliseconds