@apo-ai/sdk 0.8.0 → 0.9.1

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.
@@ -19,7 +19,7 @@ function extractTokenUsage(attrs) {
19
19
  return out;
20
20
  }
21
21
  function toNum(val) {
22
- if (typeof val === "number") return val;
22
+ if (typeof val === "number") return Number.isFinite(val) ? val : void 0;
23
23
  if (typeof val === "string") {
24
24
  const n = Number(val);
25
25
  return Number.isFinite(n) ? n : void 0;
@@ -39,4 +39,4 @@ export {
39
39
  extractTokenUsage,
40
40
  extractTokenCounts
41
41
  };
42
- //# sourceMappingURL=chunk-HLRXQAZ5.js.map
42
+ //# sourceMappingURL=chunk-HRYXLRXJ.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/agent-task/integrations/token-usage.ts"],"sourcesContent":["/**\n * Shared token-usage extraction for the tracing integrations.\n *\n * Both the `createApoTracer` path (`ai-sdk.ts`) and the OTel-native path\n * (`otel-translate.ts` → `otel-processor.ts`) must extract token counts from\n * AI SDK span attributes using the same logic. This helper is the single\n * source of truth — it prevents the two paths from drifting apart (the bug\n * where one path reported tokens and the other silently dropped them).\n *\n * The AI SDK emits usage under `ai.usage.promptTokens` /\n * `ai.usage.completionTokens`. Standard OTel GenAI conventions use\n * `gen_ai.usage.input_tokens` / `gen_ai.usage.output_tokens`. Both are\n * recognized; standard `gen_ai.usage.*` takes precedence when both are present.\n *\n * @internal\n */\n\ntype SpanAttributes = Record<string, unknown>;\n\n/**\n * Extract `prompt_tokens` / `completion_tokens` / `reasoning_tokens` from a\n * span's attributes. Returns an object shaped to spread directly into\n * `trace.endSpan()` params. Omits keys when the corresponding attribute is\n * absent or non-numeric.\n *\n * Recognizes all known attribute-name conventions:\n * - Vercel AI SDK: `ai.usage.promptTokens` / `ai.usage.completionTokens` /\n * `ai.usage.reasoningTokens`\n * - OTel GenAI: `gen_ai.usage.input_tokens` / `gen_ai.usage.output_tokens` /\n * `gen_ai.usage.reasoning.output_tokens`\n * - OTel GenAI (alt): `gen_ai.usage.prompt_tokens` / `gen_ai.usage.completion_tokens`\n * - OpenInference: `llm.token_count.completion_details.reasoning`\n *\n * `gen_ai.usage.*` takes precedence over `ai.usage.*` when both are present.\n * Reasoning is omitted when unreported — a provider that never sends the\n * dimension must surface as unknown downstream, never as zero.\n */\nexport function extractTokenUsage(attrs: SpanAttributes): {\n prompt_tokens?: number;\n completion_tokens?: number;\n reasoning_tokens?: number;\n} {\n const prompt_tokens = toNum(\n attrs[\"gen_ai.usage.input_tokens\"] ??\n attrs[\"gen_ai.usage.prompt_tokens\"] ??\n attrs[\"ai.usage.promptTokens\"],\n );\n const completion_tokens = toNum(\n attrs[\"gen_ai.usage.output_tokens\"] ??\n attrs[\"gen_ai.usage.completion_tokens\"] ??\n attrs[\"ai.usage.completionTokens\"],\n );\n const reasoning_tokens = toNum(\n attrs[\"gen_ai.usage.reasoning.output_tokens\"] ??\n attrs[\"ai.usage.reasoningTokens\"] ??\n attrs[\"llm.token_count.completion_details.reasoning\"],\n );\n const out: {\n prompt_tokens?: number;\n completion_tokens?: number;\n reasoning_tokens?: number;\n } = {};\n if (prompt_tokens !== undefined) out.prompt_tokens = prompt_tokens;\n if (completion_tokens !== undefined) out.completion_tokens = completion_tokens;\n if (reasoning_tokens !== undefined) out.reasoning_tokens = reasoning_tokens;\n return out;\n}\n\n/**\n * Coerce a span attribute value to a number. Accepts numbers directly and\n * parses finite numeric strings; ignores everything else.\n */\nfunction toNum(val: unknown): number | undefined {\n if (typeof val === \"number\") return val;\n if (typeof val === \"string\") {\n const n = Number(val);\n return Number.isFinite(n) ? n : undefined;\n }\n return undefined;\n}\n\n/**\n * Re-exported so the integrations can read prompt/completion tokens as\n * separate values (the OTel translate path returns them individually, not\n * as an endSpan-ready object).\n */\nexport function extractTokenCounts(attrs: SpanAttributes): {\n promptTokens?: number;\n completionTokens?: number;\n reasoningTokens?: number;\n} {\n const { prompt_tokens, completion_tokens, reasoning_tokens } =\n extractTokenUsage(attrs);\n // Plain assignments, not conditional spreads: this runs once per span on\n // the translate hot path, and each spread allocates an intermediate object\n // (three of them measurably regressed the 300-span benchmark).\n const out: {\n promptTokens?: number;\n completionTokens?: number;\n reasoningTokens?: number;\n } = {};\n if (prompt_tokens !== undefined) out.promptTokens = prompt_tokens;\n if (completion_tokens !== undefined) out.completionTokens = completion_tokens;\n if (reasoning_tokens !== undefined) out.reasoningTokens = reasoning_tokens;\n return out;\n}\n"],"mappings":";;;;AAqCO,SAAS,kBAAkB,OAIhC;AACA,QAAM,gBAAgB;AAAA,IACpB,MAAM,2BAA2B,KAC/B,MAAM,4BAA4B,KAClC,MAAM,uBAAuB;AAAA,EACjC;AACA,QAAM,oBAAoB;AAAA,IACxB,MAAM,4BAA4B,KAChC,MAAM,gCAAgC,KACtC,MAAM,2BAA2B;AAAA,EACrC;AACA,QAAM,mBAAmB;AAAA,IACvB,MAAM,sCAAsC,KAC1C,MAAM,0BAA0B,KAChC,MAAM,8CAA8C;AAAA,EACxD;AACA,QAAM,MAIF,CAAC;AACL,MAAI,kBAAkB,OAAW,KAAI,gBAAgB;AACrD,MAAI,sBAAsB,OAAW,KAAI,oBAAoB;AAC7D,MAAI,qBAAqB,OAAW,KAAI,mBAAmB;AAC3D,SAAO;AACT;AAMA,SAAS,MAAM,KAAkC;AAC/C,MAAI,OAAO,QAAQ,SAAU,QAAO;AACpC,MAAI,OAAO,QAAQ,UAAU;AAC3B,UAAM,IAAI,OAAO,GAAG;AACpB,WAAO,OAAO,SAAS,CAAC,IAAI,IAAI;AAAA,EAClC;AACA,SAAO;AACT;AAOO,SAAS,mBAAmB,OAIjC;AACA,QAAM,EAAE,eAAe,mBAAmB,iBAAiB,IACzD,kBAAkB,KAAK;AAIzB,QAAM,MAIF,CAAC;AACL,MAAI,kBAAkB,OAAW,KAAI,eAAe;AACpD,MAAI,sBAAsB,OAAW,KAAI,mBAAmB;AAC5D,MAAI,qBAAqB,OAAW,KAAI,kBAAkB;AAC1D,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../src/agent-task/integrations/token-usage.ts"],"sourcesContent":["/**\n * Shared token-usage extraction for the tracing integrations.\n *\n * Both the `createApoTracer` path (`ai-sdk.ts`) and the OTel-native path\n * (`otel-translate.ts` → `otel-processor.ts`) must extract token counts from\n * AI SDK span attributes using the same logic. This helper is the single\n * source of truth — it prevents the two paths from drifting apart (the bug\n * where one path reported tokens and the other silently dropped them).\n *\n * The AI SDK emits usage under `ai.usage.promptTokens` /\n * `ai.usage.completionTokens`. Standard OTel GenAI conventions use\n * `gen_ai.usage.input_tokens` / `gen_ai.usage.output_tokens`. Both are\n * recognized; standard `gen_ai.usage.*` takes precedence when both are present.\n *\n * @internal\n */\n\ntype SpanAttributes = Record<string, unknown>;\n\n/**\n * Extract `prompt_tokens` / `completion_tokens` / `reasoning_tokens` from a\n * span's attributes. Returns an object shaped to spread directly into\n * `trace.endSpan()` params. Omits keys when the corresponding attribute is\n * absent or non-numeric.\n *\n * Recognizes all known attribute-name conventions:\n * - Vercel AI SDK: `ai.usage.promptTokens` / `ai.usage.completionTokens` /\n * `ai.usage.reasoningTokens`\n * - OTel GenAI: `gen_ai.usage.input_tokens` / `gen_ai.usage.output_tokens` /\n * `gen_ai.usage.reasoning.output_tokens`\n * - OTel GenAI (alt): `gen_ai.usage.prompt_tokens` / `gen_ai.usage.completion_tokens`\n * - OpenInference: `llm.token_count.completion_details.reasoning`\n *\n * `gen_ai.usage.*` takes precedence over `ai.usage.*` when both are present.\n * Reasoning is omitted when unreported — a provider that never sends the\n * dimension must surface as unknown downstream, never as zero.\n */\nexport function extractTokenUsage(attrs: SpanAttributes): {\n prompt_tokens?: number;\n completion_tokens?: number;\n reasoning_tokens?: number;\n} {\n const prompt_tokens = toNum(\n attrs[\"gen_ai.usage.input_tokens\"] ??\n attrs[\"gen_ai.usage.prompt_tokens\"] ??\n attrs[\"ai.usage.promptTokens\"],\n );\n const completion_tokens = toNum(\n attrs[\"gen_ai.usage.output_tokens\"] ??\n attrs[\"gen_ai.usage.completion_tokens\"] ??\n attrs[\"ai.usage.completionTokens\"],\n );\n const reasoning_tokens = toNum(\n attrs[\"gen_ai.usage.reasoning.output_tokens\"] ??\n attrs[\"ai.usage.reasoningTokens\"] ??\n attrs[\"llm.token_count.completion_details.reasoning\"],\n );\n const out: {\n prompt_tokens?: number;\n completion_tokens?: number;\n reasoning_tokens?: number;\n } = {};\n if (prompt_tokens !== undefined) out.prompt_tokens = prompt_tokens;\n if (completion_tokens !== undefined) out.completion_tokens = completion_tokens;\n if (reasoning_tokens !== undefined) out.reasoning_tokens = reasoning_tokens;\n return out;\n}\n\n/**\n * Coerce a span attribute value to a number. Accepts numbers directly and\n * parses finite numeric strings; ignores everything else.\n */\nfunction toNum(val: unknown): number | undefined {\n if (typeof val === \"number\") return Number.isFinite(val) ? val : undefined;\n if (typeof val === \"string\") {\n const n = Number(val);\n return Number.isFinite(n) ? n : undefined;\n }\n return undefined;\n}\n\n/**\n * Re-exported so the integrations can read prompt/completion tokens as\n * separate values (the OTel translate path returns them individually, not\n * as an endSpan-ready object).\n */\nexport function extractTokenCounts(attrs: SpanAttributes): {\n promptTokens?: number;\n completionTokens?: number;\n reasoningTokens?: number;\n} {\n const { prompt_tokens, completion_tokens, reasoning_tokens } =\n extractTokenUsage(attrs);\n // Plain assignments, not conditional spreads: this runs once per span on\n // the translate hot path, and each spread allocates an intermediate object\n // (three of them measurably regressed the 300-span benchmark).\n const out: {\n promptTokens?: number;\n completionTokens?: number;\n reasoningTokens?: number;\n } = {};\n if (prompt_tokens !== undefined) out.promptTokens = prompt_tokens;\n if (completion_tokens !== undefined) out.completionTokens = completion_tokens;\n if (reasoning_tokens !== undefined) out.reasoningTokens = reasoning_tokens;\n return out;\n}\n"],"mappings":";;;;AAqCO,SAAS,kBAAkB,OAIhC;AACA,QAAM,gBAAgB;AAAA,IACpB,MAAM,2BAA2B,KAC/B,MAAM,4BAA4B,KAClC,MAAM,uBAAuB;AAAA,EACjC;AACA,QAAM,oBAAoB;AAAA,IACxB,MAAM,4BAA4B,KAChC,MAAM,gCAAgC,KACtC,MAAM,2BAA2B;AAAA,EACrC;AACA,QAAM,mBAAmB;AAAA,IACvB,MAAM,sCAAsC,KAC1C,MAAM,0BAA0B,KAChC,MAAM,8CAA8C;AAAA,EACxD;AACA,QAAM,MAIF,CAAC;AACL,MAAI,kBAAkB,OAAW,KAAI,gBAAgB;AACrD,MAAI,sBAAsB,OAAW,KAAI,oBAAoB;AAC7D,MAAI,qBAAqB,OAAW,KAAI,mBAAmB;AAC3D,SAAO;AACT;AAMA,SAAS,MAAM,KAAkC;AAC/C,MAAI,OAAO,QAAQ,SAAU,QAAO,OAAO,SAAS,GAAG,IAAI,MAAM;AACjE,MAAI,OAAO,QAAQ,UAAU;AAC3B,UAAM,IAAI,OAAO,GAAG;AACpB,WAAO,OAAO,SAAS,CAAC,IAAI,IAAI;AAAA,EAClC;AACA,SAAO;AACT;AAOO,SAAS,mBAAmB,OAIjC;AACA,QAAM,EAAE,eAAe,mBAAmB,iBAAiB,IACzD,kBAAkB,KAAK;AAIzB,QAAM,MAIF,CAAC;AACL,MAAI,kBAAkB,OAAW,KAAI,eAAe;AACpD,MAAI,sBAAsB,OAAW,KAAI,mBAAmB;AAC5D,MAAI,qBAAqB,OAAW,KAAI,kBAAkB;AAC1D,SAAO;AACT;","names":[]}
@@ -2,7 +2,7 @@
2
2
  // Do not edit by hand — edit the src/ originals and rebuild.
3
3
  import {
4
4
  extractTokenUsage
5
- } from "./chunk-HLRXQAZ5.js";
5
+ } from "./chunk-HRYXLRXJ.js";
6
6
 
7
7
  // src/agent-task/integrations/ai-sdk.ts
8
8
  function safeParse(raw) {
@@ -230,4 +230,4 @@ function extractTextFromAttrs(attrs) {
230
230
  export {
231
231
  createApoTracer
232
232
  };
233
- //# sourceMappingURL=chunk-CKB3SUDO.js.map
233
+ //# sourceMappingURL=chunk-IK4GJX7H.js.map
@@ -2,7 +2,7 @@
2
2
  // Do not edit by hand — edit the src/ originals and rebuild.
3
3
  import {
4
4
  extractTokenCounts
5
- } from "./chunk-HLRXQAZ5.js";
5
+ } from "./chunk-HRYXLRXJ.js";
6
6
 
7
7
  // src/otel/index.ts
8
8
  import {
@@ -493,4 +493,4 @@ export {
493
493
  injectTraceparent,
494
494
  extractTraceparent
495
495
  };
496
- //# sourceMappingURL=chunk-IPQ6IIEG.js.map
496
+ //# sourceMappingURL=chunk-KLZLE3VQ.js.map
@@ -13,8 +13,8 @@ import {
13
13
  traceRetriever,
14
14
  traceTool,
15
15
  withApoTrace
16
- } from "../chunk-IPQ6IIEG.js";
17
- import "../chunk-HLRXQAZ5.js";
16
+ } from "../chunk-KLZLE3VQ.js";
17
+ import "../chunk-HRYXLRXJ.js";
18
18
  export {
19
19
  buildApoAuthHeaders,
20
20
  configureApoTelemetry,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apo-ai/sdk",
3
- "version": "0.8.0",
3
+ "version": "0.9.1",
4
4
  "description": "TypeScript SDK for executable agent capability specifications and harness engineering with Apo",
5
5
  "keywords": [
6
6
  "ai-agents",
@@ -69,6 +69,7 @@
69
69
  },
70
70
  "devDependencies": {
71
71
  "@codspeed/vitest-plugin": "^5.7.1",
72
+ "@modelcontextprotocol/sdk": "^1.31.0",
72
73
  "@types/node": "^20.0.0",
73
74
  "@vitest/coverage-v8": "^4.1.9",
74
75
  "esbuild": "^0.21.5",
@@ -78,6 +79,7 @@
78
79
  "vitest": "^4.1.9"
79
80
  },
80
81
  "dependencies": {
82
+ "@ai-sdk/mcp": "^2.0.62",
81
83
  "@ai-sdk/openai-compatible": "^3.0.48",
82
84
  "@opentelemetry/api": "^1.9.1",
83
85
  "@opentelemetry/context-async-hooks": "^2.9.0",