@veryfront/ext-llm-google 0.1.1241 → 0.1.1243

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 +1 @@
1
- {"version":3,"file":"google-provider.d.ts","sourceRoot":"","sources":["../src/google-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC/E,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EACZ,2BAA2B,EAC5B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,kBAAkB,EAMlB,aAAa,EACb,UAAU,EACV,iBAAiB,EACjB,aAAa,EACb,aAAa,EACb,uBAAuB,EACvB,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,EAKpB,+BAA+B,EAC/B,qBAAqB,EACtB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAEL,KAAK,+BAA+B,EACrC,MAAM,6BAA6B,CAAC;AAwBrC,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,UAAU,EACV,iBAAiB,EACjB,aAAa,EACb,aAAa,EACb,uBAAuB,EACvB,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,EACpB,+BAA+B,EAC/B,qBAAqB,GACtB,CAAC;AAEF,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;CACjC;AAmdD,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,mBAAmB,EAC3B,OAAO,EAAE,MAAM,GACd,YAAY,CAAC,+BAA+B,EAAE,2BAA2B,CAAC,CA2E5E;AAED,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,mBAAmB,EAC3B,OAAO,EAAE,MAAM,GACd,gBAAgB,CAiFlB;AAED,qBAAa,cAAe,YAAW,WAAW;IAChD,QAAQ,CAAC,EAAE,YAAY;IAEvB,WAAW,CACT,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,iBAAiB,GACxB,YAAY,CAAC,+BAA+B,EAAE,2BAA2B,CAAC;IAY7E,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,GAAG,gBAAgB;CAW9E"}
1
+ {"version":3,"file":"google-provider.d.ts","sourceRoot":"","sources":["../src/google-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC/E,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EACZ,2BAA2B,EAC5B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,kBAAkB,EAMlB,aAAa,EACb,UAAU,EACV,iBAAiB,EACjB,aAAa,EACb,aAAa,EACb,uBAAuB,EACvB,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,EAKpB,+BAA+B,EAC/B,qBAAqB,EACtB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAEL,KAAK,+BAA+B,EACrC,MAAM,6BAA6B,CAAC;AAyBrC,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,UAAU,EACV,iBAAiB,EACjB,aAAa,EACb,aAAa,EACb,uBAAuB,EACvB,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,EACpB,+BAA+B,EAC/B,qBAAqB,GACtB,CAAC;AAEF,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;CACjC;AAmdD,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,mBAAmB,EAC3B,OAAO,EAAE,MAAM,GACd,YAAY,CAAC,+BAA+B,EAAE,2BAA2B,CAAC,CAsF5E;AAED,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,mBAAmB,EAC3B,OAAO,EAAE,MAAM,GACd,gBAAgB,CAiFlB;AAED,qBAAa,cAAe,YAAW,WAAW;IAChD,QAAQ,CAAC,EAAE,YAAY;IAEvB,WAAW,CACT,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,iBAAiB,GACxB,YAAY,CAAC,+BAA+B,EAAE,2BAA2B,CAAC;IAY7E,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,GAAG,gBAAgB;CAW9E"}
@@ -10,7 +10,7 @@ import { buildProviderError, createGoogleRequestInit, createWarningCollector, ge
10
10
  import { buildGoogleGenerateContentRequest, } from "./google-request-builder.js";
11
11
  import { createGoogleToolCallCorrelationRegistry, GOOGLE_CODE_EXECUTION_TOOL_NAME, googleCodeExecutionInput, googleCodeExecutionOutput, readGoogleCodeExecutionResult, readGoogleExecutableCode, readGooglePartDataField, } from "./google-content-parts.js";
12
12
  import { readGoogleGroundingMetadata } from "./google-grounding-metadata.js";
13
- import { createGoogleProviderMetadata, readGoogleThoughtSignature, } from "./google-thought-signatures.js";
13
+ import { createGoogleProviderMetadata, readGoogleThoughtSignature, reconcileGoogleProviderMetadata, } from "./google-thought-signatures.js";
14
14
  import { extractGoogleCandidateParts, extractGoogleUsage, normalizeGoogleFinishReason, streamGoogleCompatibleParts, } from "./google-stream.js";
15
15
  // Re-export error classes so extension tests can import them from this module
16
16
  // and from `veryfront/provider/shared` interchangeably.
@@ -371,6 +371,9 @@ export function createGoogleModelRuntime(config, modelId) {
371
371
  modelId,
372
372
  specificationVersion: "v3",
373
373
  supportedUrls: {},
374
+ _reconcileProviderMetadata(input) {
375
+ return reconcileGoogleProviderMetadata(input.providerMetadata, input.suppressedToolCalls);
376
+ },
374
377
  doGenerate(options) {
375
378
  const url = getGoogleGenerateContentUrl(config.baseURL, modelId);
376
379
  const warnings = createWarningCollector();
@@ -1 +1 @@
1
- {"version":3,"file":"google-request-builder.d.ts","sourceRoot":"","sources":["../src/google-request-builder.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,uBAAuB,EAEvB,0BAA0B,EAE3B,MAAM,2BAA2B,CAAC;AAYnC,MAAM,WAAW,+BAAgC,SAAQ,uBAAuB;IAC9E,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,oBAAoB,CAAC,EAAE,aAAa,CAAC;QACnC,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC,CAAC;CACJ;AAED,gGAAgG;AAChG,MAAM,MAAM,qBAAqB,GAAG,0BAA0B,CAAC;AAE/D,KAAK,gBAAgB,GAAG;IACtB,IAAI,CAAC,OAAO,EAAE;QACZ,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC;QACtC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,IAAI,CAAC;IACT,KAAK,IAAI,KAAK,CAAC;QACb,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC;QACtC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC,CAAC;CACJ,CAAC;AAEF,KAAK,uBAAuB,GAAG;IAC7B,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,KAAK,EAAE,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;CAC3C,CAAC;AAEF,KAAK,uBAAuB,GAAG;IAC7B,QAAQ,EAAE,uBAAuB,EAAE,CAAC;IACpC,iBAAiB,CAAC,EAAE;QAClB,KAAK,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KAChC,CAAC;IACF,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACvC,UAAU,CAAC,EAAE;QACX,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAChD,CAAC;IACF,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,CAAC;AA0yBF,wBAAgB,iCAAiC,CAC/C,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,+BAA+B,EACxC,QAAQ,EAAE,gBAAgB,GACzB,uBAAuB,CAqDzB"}
1
+ {"version":3,"file":"google-request-builder.d.ts","sourceRoot":"","sources":["../src/google-request-builder.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,uBAAuB,EAEvB,0BAA0B,EAE3B,MAAM,2BAA2B,CAAC;AAYnC,MAAM,WAAW,+BAAgC,SAAQ,uBAAuB;IAC9E,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,oBAAoB,CAAC,EAAE,aAAa,CAAC;QACnC,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC,CAAC;CACJ;AAED,gGAAgG;AAChG,MAAM,MAAM,qBAAqB,GAAG,0BAA0B,CAAC;AAE/D,KAAK,gBAAgB,GAAG;IACtB,IAAI,CAAC,OAAO,EAAE;QACZ,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC;QACtC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,IAAI,CAAC;IACT,KAAK,IAAI,KAAK,CAAC;QACb,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC;QACtC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC,CAAC;CACJ,CAAC;AAEF,KAAK,uBAAuB,GAAG;IAC7B,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,KAAK,EAAE,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;CAC3C,CAAC;AAEF,KAAK,uBAAuB,GAAG;IAC7B,QAAQ,EAAE,uBAAuB,EAAE,CAAC;IACpC,iBAAiB,CAAC,EAAE;QAClB,KAAK,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KAChC,CAAC;IACF,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACvC,UAAU,CAAC,EAAE;QACX,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAChD,CAAC;IACF,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,CAAC;AAmzBF,wBAAgB,iCAAiC,CAC/C,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,+BAA+B,EACxC,QAAQ,EAAE,gBAAgB,GACzB,uBAAuB,CAqDzB"}
@@ -1,10 +1,10 @@
1
1
  import { jsonValuesEqual, readProviderOptions, readRecord, unwrapToolInputSchema, } from "veryfront/provider/shared";
2
2
  import { createGoogleToolCallCorrelationRegistry, GOOGLE_CODE_EXECUTION_TOOL_NAME, googleCodeExecutionInput, googleCodeExecutionOutput, readGoogleCodeExecutionResult, readGoogleExecutableCode, readGooglePartDataField, } from "./google-content-parts.js";
3
- import { readGoogleRawAssistantParts } from "./google-thought-signatures.js";
3
+ import { readGoogleRawAssistantReplay } from "./google-thought-signatures.js";
4
4
  function invalidGoogleProviderHistory() {
5
5
  return new TypeError("Google raw assistant metadata did not match canonical provider tool history");
6
6
  }
7
- function readGoogleRawToolHistory(rawAssistantParts) {
7
+ function readGoogleRawToolHistory(rawAssistantParts, rawAssistantPartIndexes) {
8
8
  const registry = createGoogleToolCallCorrelationRegistry();
9
9
  const ordinaryCalls = [];
10
10
  const legacyOrdinaryCalls = [];
@@ -30,7 +30,7 @@ function readGoogleRawToolHistory(rawAssistantParts) {
30
30
  throw invalidGoogleProviderHistory();
31
31
  }
32
32
  const providerId = typeof functionCall.id === "string" ? functionCall.id : undefined;
33
- const id = registry.registerFunctionCall(partIndex, providerId);
33
+ const id = registry.registerFunctionCall(rawAssistantPartIndexes[partIndex] ?? partIndex, providerId);
34
34
  // Histories persisted before raw-position ids used the anonymous-call
35
35
  // occurrence instead. Build both complete projections so validation
36
36
  // cannot accept a mixture that no implementation ever emitted.
@@ -125,7 +125,7 @@ function survivingToolEvents(events, activeKinds) {
125
125
  }
126
126
  return surviving;
127
127
  }
128
- function validateGoogleToolReplay(message, rawAssistantParts) {
128
+ function validateGoogleToolReplay(message, rawAssistantParts, rawAssistantPartIndexes) {
129
129
  const providerToolCalls = (message.providerToolCalls ?? []).map((call) => ({
130
130
  id: call.toolCallId,
131
131
  name: call.toolName,
@@ -189,7 +189,7 @@ function validateGoogleToolReplay(message, rawAssistantParts) {
189
189
  rejectDuplicateIds([...ordinaryCalls, ...canonicalProviderCalls]);
190
190
  let rawHistory;
191
191
  try {
192
- rawHistory = readGoogleRawToolHistory(rawAssistantParts);
192
+ rawHistory = readGoogleRawToolHistory(rawAssistantParts, rawAssistantPartIndexes);
193
193
  }
194
194
  catch {
195
195
  throw invalidGoogleProviderHistory();
@@ -246,10 +246,10 @@ function toGoogleContents(prompt) {
246
246
  });
247
247
  break;
248
248
  case "assistant": {
249
- const rawAssistantParts = readGoogleRawAssistantParts(message.providerMetadata);
250
- if (rawAssistantParts) {
251
- validateGoogleToolReplay(message, rawAssistantParts);
252
- contents.push({ role: "model", parts: rawAssistantParts });
249
+ const rawAssistantReplay = readGoogleRawAssistantReplay(message.providerMetadata);
250
+ if (rawAssistantReplay) {
251
+ validateGoogleToolReplay(message, rawAssistantReplay.parts, rawAssistantReplay.partIndexes);
252
+ contents.push({ role: "model", parts: rawAssistantReplay.parts });
253
253
  break;
254
254
  }
255
255
  const parts = [];
@@ -1,5 +1,18 @@
1
1
  export declare const MAX_GOOGLE_PROVIDER_METADATA_BYTES: number;
2
2
  export declare function readGoogleThoughtSignature(part: Record<string, unknown>): string | undefined;
3
- export declare function createGoogleProviderMetadata(parts: Array<Record<string, unknown>>, groundingMetadata?: Record<string, unknown>): Record<string, unknown> | undefined;
3
+ export declare function createGoogleProviderMetadata(parts: Array<Record<string, unknown>>, groundingMetadata?: Record<string, unknown>, rawAssistantPartIndexes?: readonly number[]): Record<string, unknown> | undefined;
4
+ export type GoogleRawAssistantReplay = {
5
+ parts: readonly Record<string, unknown>[];
6
+ partIndexes: readonly number[];
7
+ };
8
+ export declare function readGoogleRawAssistantReplay(providerMetadata: Record<string, unknown> | undefined): GoogleRawAssistantReplay | undefined;
4
9
  export declare function readGoogleRawAssistantParts(providerMetadata: Record<string, unknown> | undefined): readonly Record<string, unknown>[] | undefined;
10
+ /**
11
+ * Remove provider tool parts that the runtime deliberately suppressed while
12
+ * preserving the exact signed parts for every surviving Google tool call.
13
+ */
14
+ export declare function reconcileGoogleProviderMetadata(providerMetadata: Record<string, unknown>, suppressedToolCalls: readonly {
15
+ id: string;
16
+ name: string;
17
+ }[]): Record<string, unknown> | undefined;
5
18
  //# sourceMappingURL=google-thought-signatures.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"google-thought-signatures.d.ts","sourceRoot":"","sources":["../src/google-thought-signatures.ts"],"names":[],"mappings":"AAiBA,eAAO,MAAM,kCAAkC,QAAkB,CAAC;AA4MlE,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,MAAM,GAAG,SAAS,CASpB;AAED,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACrC,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC1C,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAgCrC;AA4ED,wBAAgB,2BAA2B,CACzC,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GACpD,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,SAAS,CAsBhD"}
1
+ {"version":3,"file":"google-thought-signatures.d.ts","sourceRoot":"","sources":["../src/google-thought-signatures.ts"],"names":[],"mappings":"AAkBA,eAAO,MAAM,kCAAkC,QAAkB,CAAC;AA6OlE,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,MAAM,GAAG,SAAS,CASpB;AAED,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACrC,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC3C,uBAAuB,CAAC,EAAE,SAAS,MAAM,EAAE,GAC1C,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CA2CrC;AAuGD,MAAM,MAAM,wBAAwB,GAAG;IACrC,KAAK,EAAE,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IAC1C,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;CAChC,CAAC;AAEF,wBAAgB,4BAA4B,CAC1C,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GACpD,wBAAwB,GAAG,SAAS,CAiCtC;AAED,wBAAgB,2BAA2B,CACzC,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GACpD,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,SAAS,CAEhD;AAED;;;GAGG;AACH,wBAAgB,+BAA+B,CAC7C,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACzC,mBAAmB,EAAE,SAAS;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,GAC3D,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAqErC"}
@@ -2,6 +2,7 @@ import { readRecord, snapshotProviderJsonValue, } from "veryfront/provider/share
2
2
  import { createGoogleToolCallCorrelationRegistry, readGoogleCodeExecutionResult, readGoogleExecutableCode, readGooglePartDataField, } from "./google-content-parts.js";
3
3
  const GOOGLE_METADATA_KEY = "google";
4
4
  const RAW_ASSISTANT_PARTS_KEY = "rawAssistantParts";
5
+ const RAW_ASSISTANT_PART_INDEXES_KEY = "rawAssistantPartIndexes";
5
6
  const GROUNDING_METADATA_KEY = "groundingMetadata";
6
7
  const MAX_GOOGLE_RAW_ASSISTANT_PARTS = 4_096;
7
8
  export const MAX_GOOGLE_PROVIDER_METADATA_BYTES = 8 * 1024 * 1024;
@@ -57,6 +58,28 @@ function readGoogleRawPartsValue(googleMetadata) {
57
58
  }
58
59
  return descriptor.value;
59
60
  }
61
+ function readGoogleRawPartIndexesValue(googleMetadata) {
62
+ if (googleMetadata === null ||
63
+ typeof googleMetadata !== "object" ||
64
+ Array.isArray(googleMetadata)) {
65
+ throw new TypeError("Google provider metadata must be an object");
66
+ }
67
+ let descriptor;
68
+ try {
69
+ descriptor = Object.getOwnPropertyDescriptor(googleMetadata, RAW_ASSISTANT_PART_INDEXES_KEY);
70
+ }
71
+ catch {
72
+ throw new TypeError("Google provider metadata could not be inspected");
73
+ }
74
+ if (descriptor === undefined) {
75
+ return undefined;
76
+ }
77
+ if (descriptor.enumerable !== true ||
78
+ !Object.hasOwn(descriptor, "value")) {
79
+ throw new TypeError("Google raw assistant part indexes must be an enumerable data property");
80
+ }
81
+ return descriptor.value;
82
+ }
60
83
  function hasGoogleReplayTriggerProperty(part, key) {
61
84
  let descriptor;
62
85
  try {
@@ -176,7 +199,7 @@ export function readGoogleThoughtSignature(part) {
176
199
  }
177
200
  return signature;
178
201
  }
179
- export function createGoogleProviderMetadata(parts, groundingMetadata) {
202
+ export function createGoogleProviderMetadata(parts, groundingMetadata, rawAssistantPartIndexes) {
180
203
  const needsExactReplay = needsGoogleExactReplay(parts);
181
204
  if (!needsExactReplay && groundingMetadata === undefined) {
182
205
  return undefined;
@@ -190,11 +213,18 @@ export function createGoogleProviderMetadata(parts, groundingMetadata) {
190
213
  if (partsSnapshot.length > MAX_GOOGLE_RAW_ASSISTANT_PARTS) {
191
214
  throw new TypeError(`Google raw assistant parts exceeded ${MAX_GOOGLE_RAW_ASSISTANT_PARTS} entries`);
192
215
  }
193
- ownedParts = validateGoogleRawAssistantParts(partsSnapshot);
216
+ const ownedPartIndexes = rawAssistantPartIndexes === undefined
217
+ ? undefined
218
+ : validateGoogleRawAssistantPartIndexes(snapshotGoogleProviderMetadata(rawAssistantPartIndexes), partsSnapshot.length);
219
+ ownedParts = validateGoogleRawAssistantParts(partsSnapshot, ownedPartIndexes);
220
+ rawAssistantPartIndexes = ownedPartIndexes;
194
221
  }
195
222
  const metadata = snapshotGoogleProviderMetadata({
196
223
  [GOOGLE_METADATA_KEY]: {
197
224
  ...(needsExactReplay ? { [RAW_ASSISTANT_PARTS_KEY]: ownedParts } : {}),
225
+ ...(needsExactReplay && rawAssistantPartIndexes !== undefined
226
+ ? { [RAW_ASSISTANT_PART_INDEXES_KEY]: rawAssistantPartIndexes }
227
+ : {}),
198
228
  ...(groundingMetadata !== undefined ? { [GROUNDING_METADATA_KEY]: groundingMetadata } : {}),
199
229
  },
200
230
  });
@@ -204,7 +234,7 @@ export function createGoogleProviderMetadata(parts, groundingMetadata) {
204
234
  }
205
235
  return metadataRecord;
206
236
  }
207
- function validateGoogleRawAssistantParts(rawParts) {
237
+ function validateGoogleRawAssistantParts(rawParts, rawPartIndexes) {
208
238
  if (rawParts.length === 0) {
209
239
  throw new TypeError("Google raw assistant parts must be a non-empty array");
210
240
  }
@@ -231,7 +261,7 @@ function validateGoogleRawAssistantParts(rawParts) {
231
261
  const functionCall = readRecord(part.functionCall);
232
262
  const functionCallId = typeof functionCall?.id === "string" ? functionCall.id : undefined;
233
263
  try {
234
- toolCallRegistry.registerFunctionCall(partIndex, functionCallId);
264
+ toolCallRegistry.registerFunctionCall(rawPartIndexes?.[partIndex] ?? partIndex, functionCallId);
235
265
  }
236
266
  catch {
237
267
  throw new TypeError("Google raw assistant tool call id was duplicated");
@@ -273,7 +303,24 @@ function validateGoogleRawAssistantParts(rawParts) {
273
303
  // a shallow collection whose contents could diverge before serialization.
274
304
  return rawParts;
275
305
  }
276
- export function readGoogleRawAssistantParts(providerMetadata) {
306
+ function validateGoogleRawAssistantPartIndexes(value, partCount) {
307
+ if (!Array.isArray(value) || value.length !== partCount) {
308
+ throw new TypeError("Google raw assistant part indexes must match the raw parts");
309
+ }
310
+ let previous = -1;
311
+ for (const index of value) {
312
+ if (typeof index !== "number" ||
313
+ !Number.isSafeInteger(index) ||
314
+ index <= previous ||
315
+ index < 0 ||
316
+ index >= MAX_GOOGLE_RAW_ASSISTANT_PARTS) {
317
+ throw new TypeError("Google raw assistant part indexes must be increasing safe integers");
318
+ }
319
+ previous = index;
320
+ }
321
+ return value;
322
+ }
323
+ export function readGoogleRawAssistantReplay(providerMetadata) {
277
324
  if (providerMetadata === undefined) {
278
325
  return undefined;
279
326
  }
@@ -282,15 +329,87 @@ export function readGoogleRawAssistantParts(providerMetadata) {
282
329
  return undefined;
283
330
  }
284
331
  const rawParts = readGoogleRawPartsValue(rawGoogleMetadata);
332
+ const rawPartIndexes = readGoogleRawPartIndexesValue(rawGoogleMetadata);
285
333
  if (rawParts === undefined) {
334
+ if (rawPartIndexes !== undefined) {
335
+ throw new TypeError("Google raw assistant part indexes require raw parts");
336
+ }
286
337
  return undefined;
287
338
  }
288
- // Grounding and future Google metadata fields are not replayed. Snapshot
289
- // only the exact wire value that will be validated and transmitted so those
290
- // independent fields cannot consume replay budgets or invoke accessors.
291
339
  const rawPartsSnapshot = snapshotGoogleProviderMetadata(rawParts);
292
340
  if (!Array.isArray(rawPartsSnapshot)) {
293
341
  throw new TypeError("Google raw assistant parts must be a non-empty array");
294
342
  }
295
- return validateGoogleRawAssistantParts(rawPartsSnapshot);
343
+ const partIndexes = rawPartIndexes === undefined
344
+ ? rawPartsSnapshot.map((_part, index) => index)
345
+ : validateGoogleRawAssistantPartIndexes(snapshotGoogleProviderMetadata(rawPartIndexes), rawPartsSnapshot.length);
346
+ return {
347
+ parts: validateGoogleRawAssistantParts(rawPartsSnapshot, partIndexes),
348
+ partIndexes,
349
+ };
350
+ }
351
+ export function readGoogleRawAssistantParts(providerMetadata) {
352
+ return readGoogleRawAssistantReplay(providerMetadata)?.parts;
353
+ }
354
+ /**
355
+ * Remove provider tool parts that the runtime deliberately suppressed while
356
+ * preserving the exact signed parts for every surviving Google tool call.
357
+ */
358
+ export function reconcileGoogleProviderMetadata(providerMetadata, suppressedToolCalls) {
359
+ if (suppressedToolCalls.length === 0) {
360
+ return providerMetadata;
361
+ }
362
+ const replay = readGoogleRawAssistantReplay(providerMetadata);
363
+ if (replay === undefined) {
364
+ return providerMetadata;
365
+ }
366
+ const { partIndexes, parts: rawAssistantParts } = replay;
367
+ const suppressedIds = new Set(suppressedToolCalls.map((toolCall) => toolCall.id));
368
+ const matchedSuppressedIds = new Set();
369
+ const retainedParts = [];
370
+ const retainedPartIndexes = [];
371
+ const registry = createGoogleToolCallCorrelationRegistry();
372
+ let retainedToolPart = false;
373
+ for (let partIndex = 0; partIndex < rawAssistantParts.length; partIndex += 1) {
374
+ const part = rawAssistantParts[partIndex];
375
+ if (part === undefined) {
376
+ throw new TypeError("Google raw assistant parts must be dense");
377
+ }
378
+ const dataField = readGooglePartDataField(part);
379
+ let toolCallId;
380
+ if (dataField === "functionCall") {
381
+ const functionCall = readRecord(part.functionCall);
382
+ const providerId = typeof functionCall?.id === "string" ? functionCall.id : undefined;
383
+ toolCallId = registry.registerFunctionCall(partIndexes[partIndex] ?? partIndex, providerId);
384
+ }
385
+ else if (dataField === "executableCode") {
386
+ const executableCode = readGoogleExecutableCode(part.executableCode);
387
+ toolCallId = registry.registerCodeExecution(executableCode.providerId);
388
+ }
389
+ else if (dataField === "codeExecutionResult") {
390
+ const result = readGoogleCodeExecutionResult(part.codeExecutionResult);
391
+ toolCallId = registry.resolveCodeExecutionResult(result.providerId);
392
+ }
393
+ if (toolCallId !== undefined && suppressedIds.has(toolCallId)) {
394
+ matchedSuppressedIds.add(toolCallId);
395
+ continue;
396
+ }
397
+ retainedParts.push(part);
398
+ retainedPartIndexes.push(partIndexes[partIndex] ?? partIndex);
399
+ retainedToolPart ||= dataField === "functionCall" ||
400
+ dataField === "executableCode" ||
401
+ dataField === "codeExecutionResult";
402
+ }
403
+ registry.assertSettled();
404
+ if (matchedSuppressedIds.size === 0) {
405
+ return providerMetadata;
406
+ }
407
+ if (retainedParts.length === 0) {
408
+ return undefined;
409
+ }
410
+ const reconciled = createGoogleProviderMetadata(retainedParts, undefined, retainedPartIndexes);
411
+ if (reconciled === undefined && retainedToolPart) {
412
+ throw new TypeError("Google provider metadata could not preserve a surviving signed tool call");
413
+ }
414
+ return reconciled;
296
415
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@veryfront/ext-llm-google",
3
- "version": "0.1.1241",
3
+ "version": "0.1.1243",
4
4
  "description": "Veryfront first-party extension package for ext-llm-google",
5
5
  "keywords": [
6
6
  "veryfront",
@@ -45,7 +45,7 @@
45
45
  "capabilities": []
46
46
  },
47
47
  "peerDependencies": {
48
- "veryfront": "^0.1.1241"
48
+ "veryfront": "^0.1.1243"
49
49
  },
50
50
  "type": "module",
51
51
  "types": "./esm/index.d.ts",