@lunora/agent 1.0.0-alpha.8 → 1.0.0-alpha.9

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
- export { runAgentLoop, splitForCompaction } from './packem_shared/runAgentLoop-B3Q2o-Uz.mjs';
1
+ export { runAgentLoop, splitForCompaction } from './packem_shared/runAgentLoop-M8PKbtWT.mjs';
2
2
  export { collectAgenticMemoryTools, toSearchResults } from './packem_shared/collectAgenticMemoryTools-QrzpV-WX.mjs';
3
3
  export { agentAsTool } from './packem_shared/agentAsTool-CUHlWsmt.mjs';
4
4
  export { codeTool } from './packem_shared/codeTool-CjgJOC9t.mjs';
@@ -6,13 +6,13 @@ export { agentComponent, agentExtension } from './component.mjs';
6
6
  export { default as createAgentContext } from './packem_shared/createAgentContext-4xJGXNR4.mjs';
7
7
  export { defineAgent, defineAgentTool, isAgentDefinition } from './packem_shared/defineAgent-DAwAZC9P.mjs';
8
8
  export { functionTool } from './packem_shared/functionTool-D6lCa2jB.mjs';
9
- export { createAgentGenerate, createEpisodeExtract, createGraphExtract, createStreamGenerate, resolveAgentModel } from './packem_shared/createAgentGenerate-BQv9YJ01.mjs';
9
+ export { createAgentGenerate, createEpisodeExtract, createGraphExtract, createStreamGenerate, resolveAgentModel } from './packem_shared/createAgentGenerate-DO7Z96zX.mjs';
10
10
  export { adaptMcpResult, mcpTools } from './packem_shared/adaptMcpResult-wtNMvLoP.mjs';
11
11
  export { buildModelMessages } from './packem_shared/buildModelMessages-BWFigaoo.mjs';
12
12
  export { agentBindingName, agentClassName, agentDefaultName, voiceBindingName, voiceClassName } from './naming.mjs';
13
13
  export { AGENT_MODULE, DEFAULT_AGENT_FUNCTION_PATHS, SANDBOX_INVOKE_PATH, SANDBOX_MODULE, toFunctionReference } from './packem_shared/AGENT_MODULE-Dnt_-AAT.mjs';
14
14
  export { browserTool, containerTool, fsTool } from './sandbox.mjs';
15
15
  export { defineSkill, isSkillDefinition } from './packem_shared/defineSkill-Ctf_S-rz.mjs';
16
- export { default as VoiceSessionDO } from './packem_shared/VoiceSessionDO-DLoXsHGF.mjs';
16
+ export { default as VoiceSessionDO } from './packem_shared/VoiceSessionDO-BdwlLaXC.mjs';
17
17
  export { runVoiceTurn } from './packem_shared/runVoiceTurn-LnqLvCRR.mjs';
18
- export { default as compileAgentWorkflow } from './packem_shared/compileAgentWorkflow-DXNKigj0.mjs';
18
+ export { default as compileAgentWorkflow } from './packem_shared/compileAgentWorkflow-DAfyUuI5.mjs';
@@ -1,7 +1,7 @@
1
1
  import { createAi } from '@lunora/ai';
2
2
  import { c as createDispatchRunner } from './createDispatchRunner-DSbp_dph-ZHTtxy3f.mjs';
3
3
  import { t as toBase64 } from './base64-BVwtgRJV.mjs';
4
- import { createStreamGenerate } from './createAgentGenerate-BQv9YJ01.mjs';
4
+ import { createStreamGenerate } from './createAgentGenerate-DO7Z96zX.mjs';
5
5
  import { DEFAULT_AGENT_FUNCTION_PATHS, toFunctionReference } from './AGENT_MODULE-Dnt_-AAT.mjs';
6
6
  import { parseIdentity, pcmToWav, readTranscriptionText, readSynthesisAudio, runVoiceTurn, toByteIterable } from './runVoiceTurn-LnqLvCRR.mjs';
7
7
 
@@ -30,7 +30,7 @@ class VoiceSessionDO {
30
30
  this.agent = agent;
31
31
  this.exportName = exportName;
32
32
  this.paths = DEFAULT_AGENT_FUNCTION_PATHS;
33
- this.ai = createAi({ binding: env["AI"] });
33
+ this.ai = createAi({ binding: env["AI"], env });
34
34
  this.streamGenerate = createStreamGenerate(agent, env);
35
35
  this.sttModel = agent.voice?.stt ?? DEFAULT_STT_MODEL;
36
36
  this.ttsModel = agent.voice?.tts ?? DEFAULT_TTS_MODEL;
@@ -1,4 +1,4 @@
1
- import { d as describeError, t as toolInputOf, r as readField } from './common-DAeFCot5.mjs';
1
+ import { d as describeError, t as toolInputOf, r as readField } from './common-DQXayow6.mjs';
2
2
 
3
3
  const stringOr = (value, fallback) => typeof value === "string" && value.length > 0 ? value : fallback;
4
4
  const braintrustTelemetry = (options) => {
@@ -14,6 +14,34 @@ const summarizeUsage = (usage) => {
14
14
  }
15
15
  return Object.keys(summary).length > 0 ? summary : void 0;
16
16
  };
17
+ const summarizeGatewayTelemetry = (result) => {
18
+ const gateway = readField(readField(result, "providerMetadata"), "gateway");
19
+ const headers = readField(readField(result, "response"), "headers");
20
+ const readHeader = (name) => {
21
+ const getter = readField(headers, "get");
22
+ const value = typeof getter === "function" ? getter.call(headers, name) : readField(headers, name);
23
+ return typeof value === "string" && value.length > 0 ? value : void 0;
24
+ };
25
+ const summary = {};
26
+ const cost = readField(gateway, "cost");
27
+ if (typeof cost === "number" && Number.isFinite(cost)) {
28
+ summary.cost = cost;
29
+ }
30
+ const cachedField = readField(gateway, "cached");
31
+ const cacheStatusField = readField(gateway, "cacheStatus");
32
+ const cacheStatus = typeof cacheStatusField === "string" ? cacheStatusField : readHeader("cf-aig-cache-status");
33
+ if (typeof cachedField === "boolean") {
34
+ summary.cached = cachedField;
35
+ } else if (typeof cacheStatus === "string") {
36
+ summary.cached = cacheStatus.toUpperCase() === "HIT";
37
+ }
38
+ const metadataLogId = readField(gateway, "logId") ?? readField(gateway, "log_id");
39
+ const logId = typeof metadataLogId === "string" && metadataLogId.length > 0 ? metadataLogId : readHeader("cf-aig-log-id");
40
+ if (typeof logId === "string" && logId.length > 0) {
41
+ summary.logId = logId;
42
+ }
43
+ return Object.keys(summary).length > 0 ? summary : void 0;
44
+ };
17
45
  const describeToolOutcome = (event) => {
18
46
  const toolCall = readField(event, "toolCall");
19
47
  const nameValue = readField(toolCall, "toolName");
@@ -58,4 +86,4 @@ const describeError = (error) => {
58
86
  return error;
59
87
  };
60
88
 
61
- export { toolNameOf as a, describeToolOutcome as b, contentText as c, describeError as d, readField as r, summarizeUsage as s, toolInputOf as t };
89
+ export { toolNameOf as a, describeToolOutcome as b, contentText as c, describeError as d, summarizeGatewayTelemetry as e, readField as r, summarizeUsage as s, toolInputOf as t };
@@ -1,10 +1,10 @@
1
1
  import { defineWorkflow } from '@lunora/workflow';
2
- import { runAgentLoop } from './runAgentLoop-B3Q2o-Uz.mjs';
3
- import { createStreamGenerate, createAgentGenerate, createEpisodeExtract, createGraphExtract, createCompact } from './createAgentGenerate-BQv9YJ01.mjs';
2
+ import { runAgentLoop } from './runAgentLoop-M8PKbtWT.mjs';
3
+ import { createStreamGenerate, createAgentGenerate, createEpisodeExtract, createGraphExtract, createCompact } from './createAgentGenerate-DO7Z96zX.mjs';
4
4
  import { agentDefaultName } from '../naming.mjs';
5
5
  import { DEFAULT_AGENT_FUNCTION_PATHS } from './AGENT_MODULE-Dnt_-AAT.mjs';
6
6
  import { c as createDispatchRunner } from './createDispatchRunner-DSbp_dph-ZHTtxy3f.mjs';
7
- import { otlpTelemetry } from './otlpTelemetry-9ypXork9.mjs';
7
+ import { otlpTelemetry } from './otlpTelemetry-CKgmWVLg.mjs';
8
8
 
9
9
  const resolveAgentRun = (contextRun, owner, env) => {
10
10
  if (owner === void 0) {
@@ -13,7 +13,7 @@ const resolveAgentRun = (contextRun, owner, env) => {
13
13
  return createDispatchRunner({ env, identity: { userId: owner }, label: "@lunora/agent" });
14
14
  };
15
15
 
16
- const withAutoOtlpTelemetry = (agent, env) => {
16
+ const withAutoOtlpTelemetry = (agent, env, conversationId) => {
17
17
  const endpoint = env.LUNORA_OTLP_ENDPOINT;
18
18
  if (typeof endpoint !== "string" || endpoint === "" || agent.telemetry?.isEnabled === false) {
19
19
  return agent;
@@ -24,14 +24,17 @@ const withAutoOtlpTelemetry = (agent, env) => {
24
24
  ...agent,
25
25
  telemetry: {
26
26
  ...agent.telemetry,
27
- integrations: [...existingList, otlpTelemetry({ endpoint, token })],
27
+ // Tag every generation span with the run's thread as its conversation
28
+ // id (one thread = one multi-turn conversation), so the cloud groups a
29
+ // deployed agent's turns with no app wiring. Absent → ungrouped, as before.
30
+ integrations: [...existingList, otlpTelemetry({ conversationId, endpoint, token })],
28
31
  isEnabled: true
29
32
  }
30
33
  };
31
34
  };
32
35
  const compileAgentWorkflow = (agent, exportName, options) => defineWorkflow({
33
36
  handler: async (context) => {
34
- const runtimeAgent = withAutoOtlpTelemetry(agent, context.env);
37
+ const runtimeAgent = withAutoOtlpTelemetry(agent, context.env, context.params.threadKey);
35
38
  return runAgentLoop({
36
39
  agent: runtimeAgent,
37
40
  // Automatic history compaction. Dormant unless the agent declares
@@ -1,4 +1,4 @@
1
- import { s as summarizeUsage, c as contentText, t as toolInputOf, d as describeError, r as readField, a as toolNameOf, b as describeToolOutcome } from './common-DAeFCot5.mjs';
1
+ import { s as summarizeUsage, c as contentText, t as toolInputOf, d as describeError, r as readField, a as toolNameOf, b as describeToolOutcome } from './common-DQXayow6.mjs';
2
2
 
3
3
  const defaultLogger = (level, message, fields) => {
4
4
  const target = globalThis.console;
@@ -33,7 +33,7 @@ const resolveAgentModel = (model, env) => {
33
33
  `@lunora/agent: the agent model "${model}" is a Workers AI id but there is no \`AI\` binding on the workflow env — declare the ai binding in wrangler.jsonc`
34
34
  );
35
35
  }
36
- return createAi({ binding }).model(model);
36
+ return createAi({ binding, env }).model(model);
37
37
  }
38
38
  return model;
39
39
  };
@@ -1,4 +1,4 @@
1
- import { s as summarizeUsage, r as readField, c as contentText, t as toolInputOf, a as toolNameOf } from './common-DAeFCot5.mjs';
1
+ import { s as summarizeUsage, r as readField, e as summarizeGatewayTelemetry, c as contentText, t as toolInputOf, a as toolNameOf } from './common-DQXayow6.mjs';
2
2
 
3
3
  const otlpUnixNano = (ms) => `${String(Math.round(ms))}000000`;
4
4
  const otlpRandomHex = (bytes) => {
@@ -81,7 +81,7 @@ const observeSettled = (promise, onSettle) => {
81
81
  run().catch(() => void 0);
82
82
  };
83
83
  const otlpTelemetry = (options) => {
84
- const { endpoint, headers, recordInputs = false, recordOutputs = false, token, traceId: fixedTraceId, waitUntil } = options;
84
+ const { conversationId, endpoint, headers, recordInputs = false, recordOutputs = false, token, traceId: fixedTraceId, waitUntil } = options;
85
85
  const serviceName = options.serviceName ?? "lunora";
86
86
  let base = endpoint;
87
87
  while (base.endsWith("/")) {
@@ -123,12 +123,19 @@ const otlpTelemetry = (options) => {
123
123
  pushAttribute(attributes, "gen_ai.operation.name", "chat");
124
124
  pushAttribute(attributes, "gen_ai.request.model", modelId);
125
125
  pushAttribute(attributes, "gen_ai.system", readField(options_, "provider"));
126
+ pushAttribute(attributes, "gen_ai.conversation.id", conversationId);
126
127
  const usage = summarizeUsage(readField(result, "usage"));
127
128
  if (usage) {
128
129
  pushAttribute(attributes, "gen_ai.usage.input_tokens", usage.inputTokens);
129
130
  pushAttribute(attributes, "gen_ai.usage.output_tokens", usage.outputTokens);
130
131
  pushAttribute(attributes, "gen_ai.usage.total_tokens", usage.totalTokens);
131
132
  }
133
+ const gateway = summarizeGatewayTelemetry(result);
134
+ if (gateway) {
135
+ pushAttribute(attributes, "gen_ai.usage.cost", gateway.cost);
136
+ pushAttribute(attributes, "gen_ai.response.cached", gateway.cached);
137
+ pushAttribute(attributes, "cf.aig.log_id", gateway.logId);
138
+ }
132
139
  if (recordInputs) {
133
140
  pushAttribute(attributes, "gen_ai.prompt", readField(options_, "messages"));
134
141
  }
@@ -1,4 +1,4 @@
1
- import { resolveAgentModel } from './createAgentGenerate-BQv9YJ01.mjs';
1
+ import { resolveAgentModel } from './createAgentGenerate-DO7Z96zX.mjs';
2
2
  import { f as firstGraphSource, m as memoryStepName, a as firstEpisodicSource, r as resolveInjectedSources } from './memory-D4FPcBsX.mjs';
3
3
  import { buildModelMessages } from './buildModelMessages-BWFigaoo.mjs';
4
4
  import { agentBindingName } from '../naming.mjs';
@@ -1,4 +1,4 @@
1
- import { r as readField, t as toolInputOf } from './common-DAeFCot5.mjs';
1
+ import { r as readField, t as toolInputOf } from './common-DQXayow6.mjs';
2
2
 
3
3
  const stringOr = (value, fallback) => typeof value === "string" && value.length > 0 ? value : fallback;
4
4
  const sentryTelemetry = (options) => {
@@ -127,6 +127,15 @@ declare const consoleTelemetry: (options?: ConsoleTelemetryOptions) => Telemetry
127
127
  * @experimental
128
128
  */
129
129
  interface OtlpTelemetryOptions extends CommonOptions {
130
+ /**
131
+ * Conversation / session id to tag each generation span with, emitted as the
132
+ * `gen_ai.conversation.id` semantic-convention attribute so a multi-turn
133
+ * conversation's model turns group in the trace store. On a deployed agent the
134
+ * platform wiring passes the run's `threadKey` here automatically (one thread =
135
+ * one conversation). Omitted → the attribute is absent (backward-compatible),
136
+ * and each turn's span is ungrouped.
137
+ */
138
+ conversationId?: string;
130
139
  /**
131
140
  * The OTLP-over-HTTP collector base endpoint (e.g. the Lunora Cloud's `/v1`
132
141
  * base). Spans are POSTed to `${endpoint}/v1/traces`; a trailing slash is
@@ -127,6 +127,15 @@ declare const consoleTelemetry: (options?: ConsoleTelemetryOptions) => Telemetry
127
127
  * @experimental
128
128
  */
129
129
  interface OtlpTelemetryOptions extends CommonOptions {
130
+ /**
131
+ * Conversation / session id to tag each generation span with, emitted as the
132
+ * `gen_ai.conversation.id` semantic-convention attribute so a multi-turn
133
+ * conversation's model turns group in the trace store. On a deployed agent the
134
+ * platform wiring passes the run's `threadKey` here automatically (one thread =
135
+ * one conversation). Omitted → the attribute is absent (backward-compatible),
136
+ * and each turn's span is ungrouped.
137
+ */
138
+ conversationId?: string;
130
139
  /**
131
140
  * The OTLP-over-HTTP collector base endpoint (e.g. the Lunora Cloud's `/v1`
132
141
  * base). Spans are POSTed to `${endpoint}/v1/traces`; a trailing slash is
@@ -1,5 +1,5 @@
1
- export { braintrustTelemetry } from '../packem_shared/braintrustTelemetry-wuGDErob.mjs';
1
+ export { braintrustTelemetry } from '../packem_shared/braintrustTelemetry-TP7Kwuuj.mjs';
2
2
  export { combineTelemetry } from '../packem_shared/combineTelemetry-DCyaaWAI.mjs';
3
- export { consoleTelemetry } from '../packem_shared/consoleTelemetry-z2MiP1jt.mjs';
4
- export { otlpTelemetry } from '../packem_shared/otlpTelemetry-9ypXork9.mjs';
5
- export { sentryTelemetry } from '../packem_shared/sentryTelemetry-CgqFJyLO.mjs';
3
+ export { consoleTelemetry } from '../packem_shared/consoleTelemetry--3sWfu1R.mjs';
4
+ export { otlpTelemetry } from '../packem_shared/otlpTelemetry-CKgmWVLg.mjs';
5
+ export { sentryTelemetry } from '../packem_shared/sentryTelemetry-A4F5ndh9.mjs';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/agent",
3
- "version": "1.0.0-alpha.8",
3
+ "version": "1.0.0-alpha.9",
4
4
  "description": "Durable AI agents for Lunora: defineAgent compiles a replay-safe tool-loop onto Cloudflare Workflows, with DO SQLite threads and live message subscriptions",
5
5
  "keywords": [
6
6
  "agent",
@@ -76,12 +76,12 @@
76
76
  "access": "public"
77
77
  },
78
78
  "dependencies": {
79
- "@lunora/ai": "1.0.0-alpha.19",
80
- "@lunora/errors": "1.0.0-alpha.6",
81
- "@lunora/mail": "1.0.0-alpha.16",
82
- "@lunora/server": "1.0.0-alpha.29",
83
- "@lunora/values": "1.0.0-alpha.9",
84
- "@lunora/workflow": "1.0.0-alpha.11",
79
+ "@lunora/ai": "1.0.0-alpha.24",
80
+ "@lunora/errors": "1.0.0-alpha.7",
81
+ "@lunora/mail": "1.0.0-alpha.17",
82
+ "@lunora/server": "1.0.0-alpha.30",
83
+ "@lunora/values": "1.0.0-alpha.10",
84
+ "@lunora/workflow": "1.0.0-alpha.12",
85
85
  "@modelcontextprotocol/sdk": "^1.29.0",
86
86
  "ai": "7.0.31"
87
87
  },