@bluecopa/harness 0.1.0-snapshot.43 → 0.1.0-snapshot.44

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bluecopa/harness",
3
- "version": "0.1.0-snapshot.43",
3
+ "version": "0.1.0-snapshot.44",
4
4
  "description": "Provider-agnostic TypeScript agent framework",
5
5
  "license": "UNLICENSED",
6
6
  "scripts": {
@@ -2,6 +2,8 @@ export interface ToolCallInfo {
2
2
  toolCallId: string;
3
3
  toolName: string;
4
4
  args: Record<string, unknown>;
5
+ /** Provider-specific metadata preserved across round-trips (e.g., Gemini thought signatures). */
6
+ providerMetadata?: Record<string, unknown>;
5
7
  }
6
8
 
7
9
  export interface ToolResultInfo {
@@ -20,6 +22,8 @@ export interface AgentMessage {
20
22
  content: string | ContentPart[];
21
23
  toolCalls?: ToolCallInfo[]; // assistant messages: what tools were called
22
24
  toolResults?: ToolResultInfo[]; // tool messages: results keyed by toolCallId
25
+ /** Provider-specific metadata preserved across round-trips (e.g., Gemini thought signatures). */
26
+ providerMetadata?: Record<string, unknown>;
23
27
  }
24
28
 
25
29
  /** Extract plain text from content (string or ContentPart[]). */
@@ -390,16 +390,30 @@ export class AgentRunner {
390
390
  return { messages, output: text, steps: step + 1 };
391
391
  }
392
392
 
393
- const toolCallInfos = toolCalls.map(tc => ({
394
- toolCallId: tc.toolCallId ?? randomUUID(),
395
- toolName: tc.toolName,
396
- args: (tc as { input?: Record<string, unknown> }).input ?? {},
397
- }));
393
+ const toolCallInfos = toolCalls.map(tc => {
394
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
395
+ const raw = tc as any;
396
+ const info: import('../agent/types').ToolCallInfo = {
397
+ toolCallId: raw.toolCallId ?? randomUUID(),
398
+ toolName: raw.toolName,
399
+ args: raw.input ?? {},
400
+ };
401
+ // Preserve provider-specific metadata (e.g., Gemini thought signatures)
402
+ if (raw.providerMetadata || raw.experimental_providerMetadata) {
403
+ info.providerMetadata = raw.providerMetadata ?? raw.experimental_providerMetadata;
404
+ }
405
+ return info;
406
+ });
407
+
408
+ // Preserve response-level provider metadata (e.g., Gemini thought signatures)
409
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
410
+ const responseMetadata = (result as any).providerMetadata ?? (result as any).experimental_providerMetadata;
398
411
 
399
412
  messages.push({
400
413
  role: 'assistant',
401
414
  content: toolCalls.map(tc => `${tc.toolName}(${JSON.stringify((tc as { input?: Record<string, unknown> }).input ?? {}).slice(0, 100)})`).join(', '),
402
415
  toolCalls: toolCallInfos,
416
+ ...(responseMetadata ? { providerMetadata: responseMetadata } : {}),
403
417
  });
404
418
 
405
419
  for (const tc of toolCallInfos) {
@@ -48,14 +48,28 @@ export function toModelMessages(messages: AgentMessage[]): ModelMessage[] {
48
48
  parts.push({ type: 'text', text: textContent });
49
49
  }
50
50
  for (const tc of msg.toolCalls) {
51
- parts.push({
51
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
52
+ const part: any = {
52
53
  type: 'tool-call',
53
54
  toolCallId: tc.toolCallId,
54
55
  toolName: tc.toolName,
55
56
  input: tc.args,
56
- });
57
+ };
58
+ // Preserve per-tool-call provider metadata (e.g., Gemini thought signatures)
59
+ if (tc.providerMetadata) {
60
+ part.providerMetadata = tc.providerMetadata;
61
+ part.experimental_providerMetadata = tc.providerMetadata;
62
+ }
63
+ parts.push(part);
57
64
  }
58
- out.push({ role: 'assistant', content: parts });
65
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
66
+ const assistantMsg: any = { role: 'assistant', content: parts };
67
+ // Preserve response-level provider metadata
68
+ if (msg.providerMetadata) {
69
+ assistantMsg.providerMetadata = msg.providerMetadata;
70
+ assistantMsg.experimental_providerMetadata = msg.providerMetadata;
71
+ }
72
+ out.push(assistantMsg);
59
73
  } else {
60
74
  out.push({ role: 'assistant', content: textContent });
61
75
  }