@elizaos/plugin-elizacloud 2.0.3-beta.4 → 2.0.3-beta.6

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": "@elizaos/plugin-elizacloud",
3
- "version": "2.0.3-beta.4",
3
+ "version": "2.0.3-beta.6",
4
4
  "type": "module",
5
5
  "main": "dist/node/index.node.js",
6
6
  "module": "dist/node/index.node.js",
@@ -69,9 +69,9 @@
69
69
  "@ai-sdk/openai": "^3.0.9",
70
70
  "@ai-sdk/provider": "3.0.10",
71
71
  "@ai-sdk/provider-utils": "4.0.26",
72
- "@elizaos/cloud-sdk": "2.0.3-beta.4",
73
- "@elizaos/core": "2.0.3-beta.4",
74
- "@elizaos/shared": "2.0.3-beta.4",
72
+ "@elizaos/cloud-sdk": "2.0.3-beta.6",
73
+ "@elizaos/core": "2.0.3-beta.6",
74
+ "@elizaos/shared": "2.0.3-beta.6",
75
75
  "@noble/curves": "2.2.0",
76
76
  "@noble/hashes": "1.8.0",
77
77
  "@opentelemetry/api": "1.9.1",
@@ -102,7 +102,7 @@
102
102
  "dev": "bun run build.ts --watch",
103
103
  "typecheck": "tsgo --noEmit -p tsconfig.json",
104
104
  "lint": "bunx @biomejs/biome check --write --unsafe .",
105
- "clean": "rm -rf dist .turbo .turbo-tsconfig.json tsconfig.tsbuildinfo",
105
+ "clean": "node ../../packages/scripts/rm-path-recursive.mjs dist .turbo .turbo-tsconfig.json tsconfig.tsbuildinfo",
106
106
  "format": "bunx @biomejs/biome format --write .",
107
107
  "format:check": "bunx @biomejs/biome format .",
108
108
  "test": "vitest run",
@@ -322,7 +322,7 @@
322
322
  }
323
323
  }
324
324
  },
325
- "gitHead": "f76f55793a0fb8d6b869dd8ddce03970de061e34",
325
+ "gitHead": "990dc996172b3e0fb525a75052a5ac28a4cd4de5",
326
326
  "eliza": {
327
327
  "platforms": [
328
328
  "browser",
@@ -1245,6 +1245,31 @@ interface StreamingToolCallAcc {
1245
1245
  args: string;
1246
1246
  }
1247
1247
 
1248
+ /**
1249
+ * True when `value` is one complete, self-contained JSON object (it parses and
1250
+ * is a plain object — not an array or scalar). Used to recognise Cerebras's
1251
+ * final aggregated tool-call frame, which re-sends the whole arguments object
1252
+ * rather than the next incremental fragment.
1253
+ *
1254
+ * Parsing (not brace-counting) is load-bearing: a proper prefix of a single
1255
+ * JSON object never itself parses as complete — the outer `{` stays open even
1256
+ * when an inner `}` arrives mid-stream (e.g. `{"a":{"b":1}`) — so this only
1257
+ * becomes true once the WHOLE object has arrived, which is exactly the resend
1258
+ * boundary. A brace counter would be fooled by that inner close.
1259
+ */
1260
+ function isCompleteJsonObject(value: string): boolean {
1261
+ const trimmed = value.trim();
1262
+ if (!trimmed.startsWith("{")) return false;
1263
+ try {
1264
+ const parsed: unknown = JSON.parse(trimmed);
1265
+ return (
1266
+ parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)
1267
+ );
1268
+ } catch {
1269
+ return false;
1270
+ }
1271
+ }
1272
+
1248
1273
  /** Fold one SSE `delta.tool_calls[]` array into the per-index accumulator. */
1249
1274
  export function accumulateToolCallDeltas(
1250
1275
  acc: Map<number, StreamingToolCallAcc>,
@@ -1260,7 +1285,22 @@ export function accumulateToolCallDeltas(
1260
1285
  const fn = recordAt(d, "function");
1261
1286
  const name = firstString(fn.name);
1262
1287
  if (name) cur.name = name;
1263
- if (typeof fn.arguments === "string") cur.args += fn.arguments;
1288
+ if (typeof fn.arguments === "string") {
1289
+ // Cerebras streams the tool-call arguments incrementally, then emits a
1290
+ // FINAL aggregated frame that re-sends the COMPLETE arguments object
1291
+ // (re-carrying id + name). Blindly appending that re-send doubles the
1292
+ // JSON (`{…}{…}`); downstream parsing can only recover when both copies
1293
+ // are byte-identical, and the cloud character ("lowercase naturally")
1294
+ // makes the copies diverge on casing — dead-ending terse replies. When
1295
+ // the accumulated args AND the incoming fragment are each a complete,
1296
+ // self-contained object the incoming is the authoritative full copy:
1297
+ // replace rather than concatenate.
1298
+ if (isCompleteJsonObject(cur.args) && isCompleteJsonObject(fn.arguments)) {
1299
+ cur.args = fn.arguments;
1300
+ } else {
1301
+ cur.args += fn.arguments;
1302
+ }
1303
+ }
1264
1304
  acc.set(index, cur);
1265
1305
  }
1266
1306
  }