@corbat-tech/coco 2.27.5 → 2.28.0

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/dist/index.js CHANGED
@@ -16483,6 +16483,17 @@ function extractSseEventData(rawEvent) {
16483
16483
  }
16484
16484
  return dataLines.join("\n");
16485
16485
  }
16486
+ function getToolCallFingerprint(part) {
16487
+ const name = part.functionCall?.name ?? "unknown_function";
16488
+ let argsSerialized = "{}";
16489
+ try {
16490
+ argsSerialized = JSON.stringify(part.functionCall?.args ?? {});
16491
+ } catch {
16492
+ argsSerialized = "{}";
16493
+ }
16494
+ const thoughtSignature = part.thoughtSignature ?? part.thought_signature ?? part.functionCall?.thoughtSignature ?? part.functionCall?.thought_signature ?? "";
16495
+ return `${name}:${argsSerialized}:${thoughtSignature}`;
16496
+ }
16486
16497
  var VertexProvider = class {
16487
16498
  id = "vertex";
16488
16499
  name = "Google Vertex AI Gemini";
@@ -16558,6 +16569,7 @@ var VertexProvider = class {
16558
16569
  );
16559
16570
  let stopReason = "end_turn";
16560
16571
  let streamToolCallCounter = 0;
16572
+ const emittedToolFingerprints = /* @__PURE__ */ new Set();
16561
16573
  for await (const chunk of stream) {
16562
16574
  const candidate = chunk.candidates?.[0];
16563
16575
  const parts = candidate?.content?.parts ?? [];
@@ -16566,6 +16578,11 @@ var VertexProvider = class {
16566
16578
  yield { type: "text", text: part.text };
16567
16579
  }
16568
16580
  if (part.functionCall) {
16581
+ const fingerprint = getToolCallFingerprint(part);
16582
+ if (emittedToolFingerprints.has(fingerprint)) {
16583
+ continue;
16584
+ }
16585
+ emittedToolFingerprints.add(fingerprint);
16569
16586
  streamToolCallCounter++;
16570
16587
  const geminiThoughtSignature = part.thoughtSignature ?? part.thought_signature ?? part.functionCall.thoughtSignature ?? part.functionCall.thought_signature;
16571
16588
  yield {
@@ -28526,6 +28543,25 @@ var MCPServerManager = class _MCPServerManager {
28526
28543
  connections = /* @__PURE__ */ new Map();
28527
28544
  logger = getLogger();
28528
28545
  static STOP_TIMEOUT_MS = 5e3;
28546
+ /**
28547
+ * Run an async operation with a timeout, always clearing timer resources.
28548
+ */
28549
+ async runWithTimeout(operation, timeoutMs, timeoutMessage) {
28550
+ let timeoutId;
28551
+ const timeoutPromise = new Promise((_, reject) => {
28552
+ timeoutId = setTimeout(() => reject(new Error(timeoutMessage)), timeoutMs);
28553
+ if (typeof timeoutId.unref === "function") {
28554
+ timeoutId.unref();
28555
+ }
28556
+ });
28557
+ try {
28558
+ return await Promise.race([operation, timeoutPromise]);
28559
+ } finally {
28560
+ if (timeoutId) {
28561
+ clearTimeout(timeoutId);
28562
+ }
28563
+ }
28564
+ }
28529
28565
  /**
28530
28566
  * Create transport for a server config
28531
28567
  */
@@ -28612,15 +28648,11 @@ var MCPServerManager = class _MCPServerManager {
28612
28648
  }
28613
28649
  this.logger.info(`Stopping MCP server: ${name}`);
28614
28650
  try {
28615
- await Promise.race([
28651
+ await this.runWithTimeout(
28616
28652
  connection.transport.disconnect(),
28617
- new Promise(
28618
- (_, reject) => setTimeout(
28619
- () => reject(new Error("MCP disconnect timeout")),
28620
- _MCPServerManager.STOP_TIMEOUT_MS
28621
- )
28622
- )
28623
- ]);
28653
+ _MCPServerManager.STOP_TIMEOUT_MS,
28654
+ "MCP disconnect timeout"
28655
+ );
28624
28656
  } catch (error) {
28625
28657
  this.logger.error(
28626
28658
  `Error disconnecting server '${name}': ${error instanceof Error ? error.message : String(error)}`
@@ -28657,12 +28689,11 @@ var MCPServerManager = class _MCPServerManager {
28657
28689
  }
28658
28690
  const startTime = performance.now();
28659
28691
  try {
28660
- const { tools } = await Promise.race([
28692
+ const { tools } = await this.runWithTimeout(
28661
28693
  connection.client.listTools(),
28662
- new Promise(
28663
- (_, reject) => setTimeout(() => reject(new Error("Health check timeout")), 5e3)
28664
- )
28665
- ]);
28694
+ 5e3,
28695
+ "Health check timeout"
28696
+ );
28666
28697
  const latencyMs = performance.now() - startTime;
28667
28698
  connection.healthy = true;
28668
28699
  connection.toolCount = tools.length;