@economic/agents 2.3.20 → 2.3.22

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.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { a as verifyJwt, i as extractTokenFromConnectRequest, n as createAgentTracer, r as recordFeedbackAnalytics, t as routeAgentRequest } from "./route-agent-request-sspiKVkm.mjs";
1
+ import { a as verifyJwt, i as extractTokenFromConnectRequest, n as createAgentTracer, r as recordFeedbackAnalytics, t as routeAgentRequest } from "./route-agent-request-DBGSXu2O.mjs";
2
2
  import { Agent as Agent$1, callable, getCurrentAgent } from "agents";
3
3
  import { Think, skills } from "@cloudflare/think";
4
4
  import { Output, convertToModelMessages, generateText, jsonSchema, pruneMessages, tool as tool$1 } from "ai";
@@ -105,14 +105,16 @@ async function verifyJwt(request, config) {
105
105
  /**
106
106
  * Extracts the skill names loaded by an `activate_skill` tool call.
107
107
  *
108
- * v2 `activate_skill` input is `{ skills: string[] }` a single call can load
109
- * multiple skills, so this returns every requested skill name.
108
+ * v1 `activate_skill` input is `{ skills: string[] }`; v2 uses
109
+ * `{ name: string }`. Return every requested skill name while ignoring empty
110
+ * values so analytics does not group activations under a blank skill.
110
111
  */
111
112
  function extractSkillNames(toolName, input) {
112
113
  if (toolName !== "activate_skill" || !input || typeof input !== "object") return [];
113
- const { skills } = input;
114
- if (!Array.isArray(skills)) return [];
115
- return skills.filter((skill) => typeof skill === "string");
114
+ const { name, skills } = input;
115
+ if (typeof name === "string" && name) return [name];
116
+ if (Array.isArray(skills)) return skills.filter((skill) => typeof skill === "string" && skill !== "");
117
+ return [];
116
118
  }
117
119
  /**
118
120
  * Single-skill variant used where one representative skill name is sufficient
@@ -277,6 +279,15 @@ async function handleAuditSpan(span, auditLogs, context) {
277
279
  }
278
280
  //#endregion
279
281
  //#region src/server/features/telemetry/analytics.ts
282
+ const emittedToolCallIds = /* @__PURE__ */ new Set();
283
+ function safeJsonString(value) {
284
+ if (value === void 0) return void 0;
285
+ try {
286
+ return JSON.stringify(value);
287
+ } catch {
288
+ return;
289
+ }
290
+ }
280
291
  function writeAnalyticsDatapoint(analytics, dataPoint) {
281
292
  if (!analytics) return;
282
293
  try {
@@ -308,6 +319,7 @@ function handleAnalyticsSpan(span, analytics, context) {
308
319
  if (span.name === "ai.streamText.doStream") {
309
320
  const promptMessages = parseJson(stringAttribute(span, "ai.prompt.messages"));
310
321
  const responseText = stringAttribute(span, "ai.response.text") ?? "";
322
+ const responseToolCalls = parseJson(stringAttribute(span, "ai.response.toolCalls"));
311
323
  writeAnalyticsDatapoint(analytics, {
312
324
  indexes: [context.actorId],
313
325
  blobs: [
@@ -329,10 +341,48 @@ function handleAnalyticsSpan(span, analytics, context) {
329
341
  responseText.length
330
342
  ]
331
343
  });
344
+ if (Array.isArray(responseToolCalls)) for (const value of responseToolCalls) {
345
+ if (!value || typeof value !== "object") continue;
346
+ const toolCall = value;
347
+ const toolCallId = typeof toolCall.toolCallId === "string" ? toolCall.toolCallId : void 0;
348
+ if (toolCallId && emittedToolCallIds.has(toolCallId)) continue;
349
+ const toolName = typeof toolCall.toolName === "string" ? toolCall.toolName : void 0;
350
+ if (!toolName) continue;
351
+ const input = toolCall.input;
352
+ const argsRaw = safeJsonString(input);
353
+ const success = span.status.code === 0;
354
+ const activatedSkills = extractSkillNames(toolName, input);
355
+ const skillNames = activatedSkills.length ? activatedSkills : [currentSkillByChat.get(context.durableObjectName) ?? ""];
356
+ if (toolCallId) emittedToolCallIds.add(toolCallId);
357
+ for (const skillName of skillNames) writeAnalyticsDatapoint(analytics, {
358
+ indexes: [context.actorId],
359
+ blobs: [
360
+ "tool_call",
361
+ context.agentName,
362
+ context.durableObjectName,
363
+ toolName,
364
+ skillName,
365
+ success ? "success" : "error"
366
+ ],
367
+ doubles: [
368
+ 0,
369
+ success ? 1 : 0,
370
+ argsRaw?.length ?? 0,
371
+ 0,
372
+ 0,
373
+ 0,
374
+ 0,
375
+ 0
376
+ ]
377
+ });
378
+ }
332
379
  return;
333
380
  }
334
381
  if (span.name === "ai.toolCall") {
335
382
  const toolName = stringAttribute(span, "ai.toolCall.name");
383
+ const toolCallId = stringAttribute(span, "ai.toolCall.id");
384
+ if (toolCallId && emittedToolCallIds.has(toolCallId)) return;
385
+ if (toolCallId) emittedToolCallIds.add(toolCallId);
336
386
  const argsRaw = stringAttribute(span, "ai.toolCall.args");
337
387
  const toolInput = parseJson(argsRaw);
338
388
  const success = span.status.code === 0;
package/dist/v1.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { a as verifyJwt, i as extractTokenFromConnectRequest, n as createAgentTracer, t as routeAgentRequest } from "./route-agent-request-sspiKVkm.mjs";
1
+ import { a as verifyJwt, i as extractTokenFromConnectRequest, n as createAgentTracer, t as routeAgentRequest } from "./route-agent-request-DBGSXu2O.mjs";
2
2
  import { Agent as Agent$1, callable, getCurrentAgent } from "agents";
3
3
  import { Output, convertToModelMessages, generateText, jsonSchema, stepCountIs, streamText, tool } from "ai";
4
4
  import { AIChatAgent } from "@cloudflare/ai-chat";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@economic/agents",
3
- "version": "2.3.20",
3
+ "version": "2.3.22",
4
4
  "description": "A starter for creating a TypeScript package.",
5
5
  "license": "MIT",
6
6
  "files": [