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

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.
Files changed (88) hide show
  1. package/dist/channels.d.mts +3 -11
  2. package/dist/channels.d.ts +3 -11
  3. package/dist/channels.mjs +1 -181
  4. package/dist/component.d.mts +2 -0
  5. package/dist/component.d.ts +2 -0
  6. package/dist/component.mjs +2 -418
  7. package/dist/inbound.d.mts +7 -5
  8. package/dist/inbound.d.ts +7 -5
  9. package/dist/inbound.mjs +1 -32
  10. package/dist/index.d.mts +49 -8
  11. package/dist/index.d.ts +49 -8
  12. package/dist/index.mjs +1 -18
  13. package/dist/naming.mjs +1 -8
  14. package/dist/packem_shared/AGENT_MODULE-M4D1EejI.mjs +1 -0
  15. package/dist/packem_shared/VoiceSessionDO-BdvnaLoO.mjs +1 -0
  16. package/dist/packem_shared/adaptMcpResult-CVlq-_TO.mjs +2 -0
  17. package/dist/packem_shared/agent-loop-B3KTMfqm.mjs +3 -0
  18. package/dist/packem_shared/agentAsTool-CgZb6ycK.mjs +1 -0
  19. package/dist/packem_shared/base64-5eyBfWO3.mjs +1 -0
  20. package/dist/packem_shared/braintrustTelemetry-Byne8uPK.mjs +1 -0
  21. package/dist/packem_shared/branch-marker-boZ00zmk.mjs +1 -0
  22. package/dist/packem_shared/buildModelMessages-Y4tGo1T9.mjs +5 -0
  23. package/dist/packem_shared/codeTool-BQb-K3my.mjs +1 -0
  24. package/dist/packem_shared/collectAgenticMemoryTools-BeMWT2qt.mjs +1 -0
  25. package/dist/packem_shared/combineTelemetry-DgE9W9G8.mjs +1 -0
  26. package/dist/packem_shared/common-CJSjtsfv.mjs +1 -0
  27. package/dist/packem_shared/compileAgentWorkflow-DRkaF9sV.mjs +1 -0
  28. package/dist/packem_shared/component-shared-G8ngerkU.mjs +1 -0
  29. package/dist/packem_shared/consoleTelemetry-BZY3Y-Ly.mjs +1 -0
  30. package/dist/packem_shared/createAgentContext-DPFZ88dr.mjs +1 -0
  31. package/dist/packem_shared/createAgentGenerate-BOILDUZj.mjs +3 -0
  32. package/dist/packem_shared/createDispatchRunner-BMgSkFiH-DjUQx8vg.mjs +1 -0
  33. package/dist/packem_shared/defineAgent-Q3MlQjYs.mjs +3 -0
  34. package/dist/packem_shared/defineSkill-DGGvDWNq.mjs +1 -0
  35. package/dist/packem_shared/fnv1a-BNN96GYb.mjs +1 -0
  36. package/dist/packem_shared/functionTool-D3CP4f8-.mjs +1 -0
  37. package/dist/packem_shared/in-flight-calls-GH1A_1P3.mjs +1 -0
  38. package/dist/packem_shared/normalizeEntityName-k3fjicAG.mjs +2 -0
  39. package/dist/packem_shared/otlpTelemetry-ByqrB-72.mjs +1 -0
  40. package/dist/packem_shared/positive-integer-ztHqqpBk.mjs +1 -0
  41. package/dist/packem_shared/runAgentLoop-DJvzWDgh.mjs +1 -0
  42. package/dist/packem_shared/runVoiceTurn-D1WCjVPw.mjs +1 -0
  43. package/dist/packem_shared/sandboxComponent-BtOkUYpY.mjs +5 -0
  44. package/dist/packem_shared/sentryTelemetry-BHeydiAB.mjs +1 -0
  45. package/dist/packem_shared/tool-output-Cmk3JWMG.mjs +1 -0
  46. package/dist/packem_shared/{types.d-boAM2Yi1.d.mts → types.d-B8WZl1rU.d.mts} +255 -22
  47. package/dist/packem_shared/{types.d-boAM2Yi1.d.ts → types.d-B8WZl1rU.d.ts} +255 -22
  48. package/dist/packem_shared/voice-turn-D1ZzTzcE.mjs +1 -0
  49. package/dist/reply.d.mts +40 -0
  50. package/dist/reply.d.ts +40 -0
  51. package/dist/reply.mjs +1 -0
  52. package/dist/sandbox.d.mts +14 -13
  53. package/dist/sandbox.d.ts +14 -13
  54. package/dist/sandbox.mjs +1 -113
  55. package/dist/skill-markdown.d.mts +36 -0
  56. package/dist/skill-markdown.d.ts +36 -0
  57. package/dist/skill-markdown.mjs +1 -0
  58. package/dist/telemetry/index.d.mts +152 -33
  59. package/dist/telemetry/index.d.ts +152 -33
  60. package/dist/telemetry/index.mjs +1 -5
  61. package/package.json +18 -9
  62. package/dist/packem_shared/AGENT_MODULE-Dnt_-AAT.mjs +0 -24
  63. package/dist/packem_shared/VoiceSessionDO-BdwlLaXC.mjs +0 -297
  64. package/dist/packem_shared/adaptMcpResult-wtNMvLoP.mjs +0 -65
  65. package/dist/packem_shared/agentAsTool-CUHlWsmt.mjs +0 -98
  66. package/dist/packem_shared/base64-BVwtgRJV.mjs +0 -18
  67. package/dist/packem_shared/braintrustTelemetry-TP7Kwuuj.mjs +0 -47
  68. package/dist/packem_shared/buildModelMessages-BWFigaoo.mjs +0 -69
  69. package/dist/packem_shared/codeTool-CjgJOC9t.mjs +0 -122
  70. package/dist/packem_shared/collectAgenticMemoryTools-QrzpV-WX.mjs +0 -97
  71. package/dist/packem_shared/combineTelemetry-DCyaaWAI.mjs +0 -43
  72. package/dist/packem_shared/common-DQXayow6.mjs +0 -89
  73. package/dist/packem_shared/compileAgentWorkflow-DAfyUuI5.mjs +0 -78
  74. package/dist/packem_shared/consoleTelemetry--3sWfu1R.mjs +0 -93
  75. package/dist/packem_shared/createAgentContext-4xJGXNR4.mjs +0 -50
  76. package/dist/packem_shared/createAgentGenerate-DO7Z96zX.mjs +0 -192
  77. package/dist/packem_shared/createDispatchRunner-DSbp_dph-ZHTtxy3f.mjs +0 -69
  78. package/dist/packem_shared/defineAgent-DAwAZC9P.mjs +0 -148
  79. package/dist/packem_shared/defineSkill-Ctf_S-rz.mjs +0 -22
  80. package/dist/packem_shared/functionTool-D6lCa2jB.mjs +0 -20
  81. package/dist/packem_shared/graph-component-Bbaxxymp.mjs +0 -217
  82. package/dist/packem_shared/memory-D4FPcBsX.mjs +0 -12
  83. package/dist/packem_shared/normalizeEntityName-BouctxLC.mjs +0 -3
  84. package/dist/packem_shared/otlpTelemetry-CKgmWVLg.mjs +0 -170
  85. package/dist/packem_shared/runAgentLoop-M8PKbtWT.mjs +0 -493
  86. package/dist/packem_shared/runVoiceTurn-LnqLvCRR.mjs +0 -211
  87. package/dist/packem_shared/sandboxComponent-DR3pTwBL.mjs +0 -194
  88. package/dist/packem_shared/sentryTelemetry-A4F5ndh9.mjs +0 -36
@@ -1,65 +0,0 @@
1
- import { LunoraError } from '@lunora/errors';
2
- import { jsonSchema } from 'ai';
3
-
4
- const adaptMcpResult = (result) => {
5
- if (result.structuredContent !== void 0) {
6
- return result.structuredContent;
7
- }
8
- const text = (result.content ?? []).filter((part) => part.type === "text" && typeof part.text === "string").map((part) => part.text).join("\n");
9
- if (result.isError === true) {
10
- return `MCP tool error: ${text.length > 0 ? text : "unknown error"}`;
11
- }
12
- if (text.length > 0) {
13
- return text;
14
- }
15
- return result.content;
16
- };
17
- const adaptMcpTool = (client, info) => {
18
- return {
19
- description: info.description ?? `MCP tool "${info.name}".`,
20
- // Runs inside the loop's `tool:NAME:CALL_ID` durable step: a completed
21
- // call is memoized on replay, and a failed step retries at-least-once —
22
- // the same idempotency contract every agent tool carries.
23
- execute: async (input) => adaptMcpResult(await client.callTool({ arguments: input, name: info.name })),
24
- inputSchema: jsonSchema(info.inputSchema),
25
- isLunoraAgentTool: true
26
- };
27
- };
28
- const connectClient = async (options) => {
29
- if (options.command !== void 0) {
30
- throw new LunoraError(
31
- "INTERNAL",
32
- "@lunora/agent: mcpTools `command` (stdio transport) cannot run in the Workers runtime — pass a `url` for an HTTP/SSE MCP server, or inject a connected `client`"
33
- );
34
- }
35
- if (options.url === void 0) {
36
- throw new LunoraError("INTERNAL", "@lunora/agent: mcpTools requires a `url` (an HTTP/SSE MCP server) or an injected `client`");
37
- }
38
- const url = new URL(options.url);
39
- const { Client } = await import('@modelcontextprotocol/sdk/client/index.js');
40
- let transport;
41
- if (options.transport === "sse") {
42
- const { SSEClientTransport } = await import('@modelcontextprotocol/sdk/client/sse.js');
43
- transport = new SSEClientTransport(url);
44
- } else {
45
- const { StreamableHTTPClientTransport } = await import('@modelcontextprotocol/sdk/client/streamableHttp.js');
46
- transport = new StreamableHTTPClientTransport(url);
47
- }
48
- const client = new Client({ name: options.name ?? "lunora-agent", version: options.version ?? "0.0.0" });
49
- await client.connect(transport);
50
- return client;
51
- };
52
- const mcpTools = async (options) => {
53
- const client = options.client ?? await connectClient(options);
54
- const { tools: listed } = await client.listTools();
55
- const record = {};
56
- for (const info of listed) {
57
- if (options.only !== void 0 && !options.only.includes(info.name)) {
58
- continue;
59
- }
60
- record[`${options.prefix ?? ""}${info.name}`] = adaptMcpTool(client, info);
61
- }
62
- return record;
63
- };
64
-
65
- export { adaptMcpResult, mcpTools };
@@ -1,98 +0,0 @@
1
- import { LunoraError } from '@lunora/errors';
2
- import { jsonSchema } from 'ai';
3
- import { isDuplicateInstanceError } from '../channels.mjs';
4
- import { agentBindingName } from '../naming.mjs';
5
- import { toFunctionReference, DEFAULT_AGENT_FUNCTION_PATHS } from './AGENT_MODULE-Dnt_-AAT.mjs';
6
-
7
- const TERMINAL_STATUSES = /* @__PURE__ */ new Set(["complete", "errored", "terminated"]);
8
- const DEFAULT_MAX_POLLS = 120;
9
- const DEFAULT_POLL_INTERVAL_MS = 500;
10
- const readStatus = (raw) => {
11
- if (raw !== null && typeof raw === "object" && typeof raw.status === "string") {
12
- return raw.status;
13
- }
14
- return "unknown";
15
- };
16
- const defaultWait = async (ms) => {
17
- await new Promise((resolve) => {
18
- setTimeout(resolve, ms);
19
- });
20
- };
21
- const pollUntilTerminal = async (instance, maxPolls, pollIntervalMs, wait) => {
22
- for (let attempt = 0; attempt < maxPolls; attempt += 1) {
23
- const status = readStatus(await instance.status());
24
- if (TERMINAL_STATUSES.has(status)) {
25
- return status;
26
- }
27
- await wait(pollIntervalMs);
28
- }
29
- return "timeout";
30
- };
31
- const finalAnswer = (history) => {
32
- for (let index = history.length - 1; index >= 0; index -= 1) {
33
- const row = history[index];
34
- if (row?.role === "assistant" && (row.toolCalls === void 0 || row.toolCalls.length === 0)) {
35
- return row.content;
36
- }
37
- }
38
- return "";
39
- };
40
- const agentAsTool = (options) => {
41
- if (typeof options.name !== "string" || options.name.length === 0) {
42
- throw new LunoraError("INTERNAL", "@lunora/agent: agent.asTool requires a `name` (the child agent's export name, selecting its AGENT_* binding)");
43
- }
44
- if (typeof options.description !== "string" || options.description.length === 0) {
45
- throw new LunoraError("INTERNAL", "@lunora/agent: agent.asTool requires a non-empty `description` (the parent model decides from it)");
46
- }
47
- const { name } = options;
48
- const bindingName = agentBindingName(name);
49
- const maxPolls = options.maxPolls ?? DEFAULT_MAX_POLLS;
50
- const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
51
- const wait = options.wait ?? defaultWait;
52
- const listMessages = toFunctionReference(DEFAULT_AGENT_FUNCTION_PATHS.listMessages);
53
- const execute = async (input, context) => {
54
- const binding = context.env[bindingName];
55
- if (!binding || typeof binding.create !== "function" || typeof binding.get !== "function") {
56
- throw new LunoraError(
57
- "INTERNAL",
58
- `@lunora/agent: agent.asTool("${name}") found no Workflow binding "${bindingName}" on env — declare the "${name}" agent so codegen wires its binding`
59
- );
60
- }
61
- const childThreadKey = `${context.threadKey}::sub::${name}::${context.toolCallId}`;
62
- const childInstanceId = `sub-${name}-${context.toolCallId}`;
63
- const params = { input: input.prompt, threadKey: childThreadKey };
64
- let instance;
65
- try {
66
- const handle = await binding.create({ id: childInstanceId, params });
67
- instance = await binding.get(handle.id);
68
- } catch (error) {
69
- if (!isDuplicateInstanceError(error)) {
70
- throw error;
71
- }
72
- instance = await binding.get(childInstanceId);
73
- }
74
- const terminal = await pollUntilTerminal(instance, maxPolls, pollIntervalMs, wait);
75
- if (terminal === "errored" || terminal === "terminated") {
76
- return `Sub-agent "${name}" ${terminal} before producing an answer.`;
77
- }
78
- if (terminal === "timeout") {
79
- return `Sub-agent "${name}" did not finish within the allotted time.`;
80
- }
81
- const history = await context.run(listMessages, { key: childThreadKey });
82
- return finalAnswer(history);
83
- };
84
- return {
85
- description: options.description,
86
- execute,
87
- inputSchema: jsonSchema({
88
- properties: {
89
- prompt: { description: "The task or question to delegate to the sub-agent.", type: "string" }
90
- },
91
- required: ["prompt"],
92
- type: "object"
93
- }),
94
- isLunoraAgentTool: true
95
- };
96
- };
97
-
98
- export { agentAsTool };
@@ -1,18 +0,0 @@
1
- const toBase64 = (bytes) => {
2
- let binary = "";
3
- const chunk = 32768;
4
- for (let index = 0; index < bytes.length; index += chunk) {
5
- binary += String.fromCharCode(...bytes.subarray(index, index + chunk));
6
- }
7
- return btoa(binary);
8
- };
9
- const fromBase64 = (base64) => {
10
- const binary = atob(base64);
11
- const bytes = new Uint8Array(binary.length);
12
- for (let index = 0; index < binary.length; index += 1) {
13
- bytes[index] = binary.codePointAt(index) ?? 0;
14
- }
15
- return bytes;
16
- };
17
-
18
- export { fromBase64 as f, toBase64 as t };
@@ -1,47 +0,0 @@
1
- import { d as describeError, t as toolInputOf, r as readField } from './common-DQXayow6.mjs';
2
-
3
- const stringOr = (value, fallback) => typeof value === "string" && value.length > 0 ? value : fallback;
4
- const braintrustTelemetry = (options) => {
5
- const { functionId, logger, recordInputs = false, recordOutputs = false } = options;
6
- return {
7
- executeLanguageModelCall: (options_) => logger.traced(
8
- async (span) => {
9
- if (recordInputs) {
10
- span.log({ input: readField(options_, "messages"), model: readField(options_, "modelId") });
11
- }
12
- const output = await options_.execute();
13
- if (recordOutputs) {
14
- span.log({ output });
15
- }
16
- return output;
17
- },
18
- { name: stringOr(functionId, "language_model_call"), type: "llm" }
19
- ),
20
- executeTool: (options_) => {
21
- const toolName = readField(readField(options_, "toolCall"), "toolName");
22
- return logger.traced(
23
- async (span) => {
24
- if (recordInputs) {
25
- span.log({ input: toolInputOf(options_), tool: toolName });
26
- }
27
- const output = await options_.execute();
28
- if (recordOutputs) {
29
- span.log({ output });
30
- }
31
- return output;
32
- },
33
- { name: stringOr(toolName, "execute_tool"), type: "tool" }
34
- );
35
- },
36
- onError: (error) => {
37
- logger.traced(
38
- (span) => {
39
- span.log({ error: describeError(error) });
40
- },
41
- { name: "error", type: "error" }
42
- );
43
- }
44
- };
45
- };
46
-
47
- export { braintrustTelemetry };
@@ -1,69 +0,0 @@
1
- const assistantMessage = (row) => {
2
- if (row.toolCalls === void 0 || row.toolCalls.length === 0) {
3
- return { content: row.content, role: "assistant" };
4
- }
5
- return {
6
- content: [
7
- ...row.content.length > 0 ? [{ text: row.content, type: "text" }] : [],
8
- ...row.toolCalls.map((call) => {
9
- return { input: call.input, toolCallId: call.id, toolName: call.name, type: "tool-call" };
10
- })
11
- ],
12
- role: "assistant"
13
- };
14
- };
15
- const toolMessage = (row) => {
16
- return {
17
- content: [
18
- {
19
- output: { type: "text", value: row.content },
20
- toolCallId: row.toolCallId ?? "",
21
- toolName: row.toolName ?? "",
22
- type: "tool-result"
23
- }
24
- ],
25
- role: "tool"
26
- };
27
- };
28
- const buildModelMessages = (options) => {
29
- const messages = [];
30
- if (options.instructions !== void 0 && options.instructions.length > 0) {
31
- messages.push({ content: options.instructions, role: "system" });
32
- }
33
- if (options.memoryContext !== void 0 && options.memoryContext.length > 0) {
34
- messages.push({ content: `Relevant context retrieved for this conversation:
35
-
36
- ${options.memoryContext}`, role: "system" });
37
- }
38
- if (options.summary !== void 0 && options.summary.length > 0) {
39
- messages.push({ content: `Summary of the earlier conversation:
40
-
41
- ${options.summary}`, role: "system" });
42
- }
43
- for (const row of options.history) {
44
- if (row.status === "awaiting_approval") {
45
- continue;
46
- }
47
- switch (row.role) {
48
- case "assistant": {
49
- messages.push(assistantMessage(row));
50
- break;
51
- }
52
- case "system": {
53
- messages.push({ content: row.content, role: "system" });
54
- break;
55
- }
56
- case "tool": {
57
- messages.push(toolMessage(row));
58
- break;
59
- }
60
- case "user": {
61
- messages.push({ content: row.content, role: "user" });
62
- break;
63
- }
64
- }
65
- }
66
- return messages;
67
- };
68
-
69
- export { buildModelMessages };
@@ -1,122 +0,0 @@
1
- import { LunoraError } from '@lunora/errors';
2
- import { jsonSchema } from 'ai';
3
-
4
- const DEFAULT_MAX_STEPS = 16;
5
- const MAX_STEP_OUTPUT_CHARS = 4e3;
6
- const capOutput = (output) => {
7
- if (output === void 0) {
8
- return output;
9
- }
10
- const serialized = typeof output === "string" ? output : JSON.stringify(output);
11
- if (serialized.length <= MAX_STEP_OUTPUT_CHARS) {
12
- return output;
13
- }
14
- return `${serialized.slice(0, MAX_STEP_OUTPUT_CHARS)}… [truncated]`;
15
- };
16
- const getPath = (value, path) => {
17
- let current = value;
18
- for (const key of path.split(".")) {
19
- if (current === null || typeof current !== "object" || !Object.hasOwn(current, key)) {
20
- return void 0;
21
- }
22
- current = current[key];
23
- }
24
- return current;
25
- };
26
- const resolveReferences = (value, results) => {
27
- if (Array.isArray(value)) {
28
- return value.map((item) => resolveReferences(item, results));
29
- }
30
- if (value === null || typeof value !== "object") {
31
- return value;
32
- }
33
- const object = value;
34
- if (typeof object["$from"] === "string") {
35
- const from = object["$from"];
36
- if (!(from in results)) {
37
- throw new LunoraError("BAD_REQUEST", `@lunora/agent: code step references unknown result "${from}" (define it in an earlier step)`);
38
- }
39
- return typeof object["$path"] === "string" ? getPath(results[from], object["$path"]) : results[from];
40
- }
41
- const resolved = {};
42
- for (const [key, nested] of Object.entries(object)) {
43
- resolved[key] = resolveReferences(nested, results);
44
- }
45
- return resolved;
46
- };
47
- const runToolScript = async (script, tools, context, maxSteps) => {
48
- const steps = Array.isArray(script.steps) ? script.steps.slice(0, maxSteps) : [];
49
- const byId = {};
50
- const results = [];
51
- const seenIds = /* @__PURE__ */ new Set();
52
- for (const step of steps) {
53
- if (seenIds.has(step.id)) {
54
- throw new LunoraError(
55
- "BAD_REQUEST",
56
- `@lunora/agent: duplicate code step id "${step.id}" — each step id must be unique (later steps reference an output by id via $from)`
57
- );
58
- }
59
- seenIds.add(step.id);
60
- }
61
- for (const step of steps) {
62
- const tool = tools[step.tool];
63
- if (!tool) {
64
- throw new LunoraError("BAD_REQUEST", `@lunora/agent: code step calls unknown tool "${step.tool}" (available: ${Object.keys(tools).join(", ")})`);
65
- }
66
- const input = resolveReferences(step.input ?? {}, byId);
67
- const stepContext = {
68
- ...context,
69
- idempotencyKey: `${context.idempotencyKey}:${step.id}`,
70
- toolCallId: `${context.toolCallId}:${step.id}`
71
- };
72
- const output = await tool.execute(input, stepContext);
73
- byId[step.id] = output;
74
- results.push({ id: step.id, output: capOutput(output) });
75
- }
76
- return { final: results.at(-1)?.output, results };
77
- };
78
- const buildCodeDescription = (tools) => `Compose MULTIPLE tool calls in one turn as a script, instead of one call per turn. Provide \`steps\`: an ordered array of \`{ id, tool, input }\`. A later step's \`input\` may reference an earlier step's output with \`{ "$from": "<stepId>", "$path": "optional.dot.path" }\`. Available tools: ${Object.entries(tools).map(([name, tool]) => `"${name}" — ${tool.description}`).join("; ")}.`;
79
- const CODE_TOOL_SCHEMA = jsonSchema({
80
- properties: {
81
- steps: {
82
- description: "Ordered tool calls; a later input may reference an earlier output via { $from, $path }.",
83
- items: {
84
- additionalProperties: false,
85
- properties: {
86
- id: { description: "A name later steps reference this output by.", type: "string" },
87
- input: { additionalProperties: true, description: "The tool input (may embed $from refs).", type: "object" },
88
- tool: { description: "The tool to call.", type: "string" }
89
- },
90
- required: ["id", "tool"],
91
- type: "object"
92
- },
93
- type: "array"
94
- }
95
- },
96
- required: ["steps"],
97
- type: "object"
98
- });
99
- const codeTool = (tools, options = {}) => {
100
- const provided = tools;
101
- if (!provided || typeof provided !== "object" || Object.keys(provided).length === 0) {
102
- throw new LunoraError("INTERNAL", "@lunora/agent: codeTool requires a non-empty map of tools to compose");
103
- }
104
- for (const [name, tool] of Object.entries(provided)) {
105
- if (tool.needsApproval !== void 0 && tool.needsApproval !== false) {
106
- throw new LunoraError(
107
- "INTERNAL",
108
- `@lunora/agent: codeTool cannot compose "${name}" — it has a \`needsApproval\` gate a code-mode script can't pause for. Expose it as a normal top-level tool, or gate the whole script via codeTool's \`needsApproval\`.`
109
- );
110
- }
111
- }
112
- const maxSteps = options.maxSteps ?? DEFAULT_MAX_STEPS;
113
- return {
114
- description: options.description ?? buildCodeDescription(tools),
115
- execute: (script, context) => runToolScript(script, tools, context, maxSteps),
116
- inputSchema: CODE_TOOL_SCHEMA,
117
- isLunoraAgentTool: true,
118
- ...options.needsApproval === void 0 ? {} : { needsApproval: options.needsApproval }
119
- };
120
- };
121
-
122
- export { codeTool, resolveReferences, runToolScript };
@@ -1,97 +0,0 @@
1
- import { jsonSchema } from 'ai';
2
- import { toFunctionReference } from './AGENT_MODULE-Dnt_-AAT.mjs';
3
-
4
- const DEFAULT_SNIPPET_CHARS = 240;
5
- const MAX_SEARCH_TOPK = 50;
6
- const snippet = (text, max) => text.length <= max ? text : `${text.slice(0, max)}…`;
7
- const clampSearchTopK = (value) => {
8
- if (value === void 0 || !Number.isFinite(value)) {
9
- return void 0;
10
- }
11
- return Math.min(MAX_SEARCH_TOPK, Math.max(1, Math.trunc(value)));
12
- };
13
- const toSearchResults = (retrieved, snippetChars) => {
14
- const raw = retrieved ?? {};
15
- const chunks = Array.isArray(raw.chunks) ? raw.chunks : [];
16
- const sources = Array.isArray(raw.sources) ? raw.sources : [];
17
- return {
18
- results: chunks.map((chunk) => {
19
- return {
20
- id: typeof chunk.id === "string" ? chunk.id : "",
21
- score: typeof chunk.score === "number" ? chunk.score : 0,
22
- snippet: snippet(typeof chunk.text === "string" ? chunk.text : "", snippetChars),
23
- sourceId: typeof chunk.sourceId === "string" ? chunk.sourceId : ""
24
- };
25
- }),
26
- sources
27
- };
28
- };
29
- const searchInputSchema = jsonSchema({
30
- additionalProperties: false,
31
- properties: {
32
- query: { description: "Natural-language search query.", type: "string" },
33
- topK: { description: "Maximum number of hits to return.", type: "number" }
34
- },
35
- required: ["query"],
36
- type: "object"
37
- });
38
- const readInputSchema = jsonSchema({
39
- additionalProperties: false,
40
- properties: {
41
- id: { description: "The `id` of a hit returned by the search tool.", type: "string" }
42
- },
43
- required: ["id"],
44
- type: "object"
45
- });
46
- const buildSearchTool = (source, sourceReference, readToolName) => {
47
- const target = toFunctionReference(sourceReference);
48
- const snippetChars = Math.max(1, source.snippetChars ?? DEFAULT_SNIPPET_CHARS);
49
- const configuredTopK = source.topK;
50
- const pull = readToolName === void 0 ? "" : ` Use \`${readToolName}\` with a hit's \`id\` to fetch its full text.`;
51
- return {
52
- description: `Search long-term memory for passages relevant to a query. Returns ranked { id, sourceId, score, snippet } hits — call again with a refined query to dig deeper.${pull}`,
53
- execute: async (input, context) => {
54
- const topK = clampSearchTopK(input.topK) ?? configuredTopK;
55
- const retrieved = await context.run(target, { query: input.query, ...topK === void 0 ? {} : { topK } });
56
- return toSearchResults(retrieved, snippetChars);
57
- },
58
- inputSchema: searchInputSchema,
59
- isLunoraAgentTool: true
60
- };
61
- };
62
- const buildReadTool = (readReference) => {
63
- const target = toFunctionReference(readReference);
64
- return {
65
- description: "Fetch the full text of a memory document by the `id` from a search hit.",
66
- execute: (input, context) => context.run(target, { id: input.id }),
67
- inputSchema: readInputSchema,
68
- isLunoraAgentTool: true
69
- };
70
- };
71
- const collectAgenticMemoryTools = (config, skills) => {
72
- const sources = [];
73
- if (config.memory) {
74
- sources.push({ key: "default", ...config.memory });
75
- }
76
- for (const skill of skills) {
77
- if (skill.knowledge) {
78
- sources.push({ key: skill.name, ...skill.knowledge });
79
- }
80
- }
81
- const tools = {};
82
- for (const source of sources) {
83
- if (source.kind === "graph" || source.kind === "episodic" || source.mode !== "agentic" || source.source === void 0) {
84
- continue;
85
- }
86
- const searchName = source.key === "default" ? "searchMemory" : `search_${source.key}`;
87
- const readName = source.key === "default" ? "readMemory" : `read_${source.key}`;
88
- const hasRead = source.read !== void 0;
89
- tools[searchName] = buildSearchTool(source, source.source, hasRead ? readName : void 0);
90
- if (hasRead) {
91
- tools[readName] = buildReadTool(source.read);
92
- }
93
- }
94
- return tools;
95
- };
96
-
97
- export { collectAgenticMemoryTools, toSearchResults };
@@ -1,43 +0,0 @@
1
- const fanOut = (callbacks) => async (event) => {
2
- await Promise.allSettled(callbacks.map(async (callback) => callback?.(event)));
3
- };
4
- const composeWrappers = (wrappers) => {
5
- const defined = wrappers.filter((wrapper) => typeof wrapper === "function");
6
- const combined = (options) => {
7
- let composed = options.execute;
8
- for (const wrapper of defined.toReversed()) {
9
- const inner = composed;
10
- composed = () => wrapper({ ...options, execute: inner });
11
- }
12
- return composed();
13
- };
14
- return combined;
15
- };
16
- const combineTelemetry = (...integrations) => {
17
- return {
18
- executeLanguageModelCall: composeWrappers(integrations.map((integration) => integration.executeLanguageModelCall)),
19
- executeTool: composeWrappers(integrations.map((integration) => integration.executeTool)),
20
- onAbort: fanOut(integrations.map((integration) => integration.onAbort)),
21
- onEmbedEnd: fanOut(integrations.map((integration) => integration.onEmbedEnd)),
22
- onEmbedStart: fanOut(integrations.map((integration) => integration.onEmbedStart)),
23
- onEnd: fanOut(integrations.map((integration) => integration.onEnd)),
24
- onError: fanOut(integrations.map((integration) => integration.onError)),
25
- onLanguageModelCallEnd: fanOut(integrations.map((integration) => integration.onLanguageModelCallEnd)),
26
- onLanguageModelCallStart: fanOut(integrations.map((integration) => integration.onLanguageModelCallStart)),
27
- // eslint-disable-next-line sonarjs/deprecation -- deprecated in the ai@7 type but still actively dispatched (dist onObjectStepEnd fan-out); combine must not drop an integration's callback
28
- onObjectStepEnd: fanOut(integrations.map((integration) => integration.onObjectStepEnd)),
29
- // eslint-disable-next-line sonarjs/deprecation -- deprecated in the ai@7 type but still actively dispatched (dist onObjectStepStart fan-out); combine must not drop an integration's callback
30
- onObjectStepStart: fanOut(integrations.map((integration) => integration.onObjectStepStart)),
31
- onRerankEnd: fanOut(integrations.map((integration) => integration.onRerankEnd)),
32
- onRerankStart: fanOut(integrations.map((integration) => integration.onRerankStart)),
33
- onStart: fanOut(integrations.map((integration) => integration.onStart)),
34
- onStepEnd: fanOut(integrations.map((integration) => integration.onStepEnd)),
35
- // eslint-disable-next-line sonarjs/deprecation -- deprecated alias of onStepEnd but ai@7 still fans step-end events to it (dist onStepEnd → onStepFinish); combine must not drop an integration's callback
36
- onStepFinish: fanOut(integrations.map((integration) => integration.onStepFinish)),
37
- onStepStart: fanOut(integrations.map((integration) => integration.onStepStart)),
38
- onToolExecutionEnd: fanOut(integrations.map((integration) => integration.onToolExecutionEnd)),
39
- onToolExecutionStart: fanOut(integrations.map((integration) => integration.onToolExecutionStart))
40
- };
41
- };
42
-
43
- export { combineTelemetry };
@@ -1,89 +0,0 @@
1
- const readField = (source, key) => {
2
- if (source === null || typeof source !== "object") {
3
- return void 0;
4
- }
5
- return source[key];
6
- };
7
- const summarizeUsage = (usage) => {
8
- const summary = {};
9
- for (const key of ["inputTokens", "outputTokens", "totalTokens"]) {
10
- const value = readField(usage, key);
11
- if (typeof value === "number") {
12
- summary[key] = value;
13
- }
14
- }
15
- return Object.keys(summary).length > 0 ? summary : void 0;
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
- };
45
- const describeToolOutcome = (event) => {
46
- const toolCall = readField(event, "toolCall");
47
- const nameValue = readField(toolCall, "toolName");
48
- const name = typeof nameValue === "string" ? nameValue : void 0;
49
- const toolOutput = readField(event, "toolOutput");
50
- const outputType = readField(toolOutput, "type");
51
- const successField = readField(event, "success");
52
- const success = typeof successField === "boolean" ? successField : outputType !== "tool-error";
53
- const executionMs = readField(event, "toolExecutionMs");
54
- return {
55
- error: success ? void 0 : readField(toolOutput, "error") ?? readField(event, "error"),
56
- name,
57
- output: success ? readField(toolOutput, "output") : void 0,
58
- success,
59
- toolExecutionMs: typeof executionMs === "number" ? executionMs : void 0
60
- };
61
- };
62
- const toolNameOf = (event) => {
63
- const nameValue = readField(readField(event, "toolCall"), "toolName");
64
- return typeof nameValue === "string" ? nameValue : void 0;
65
- };
66
- const toolInputOf = (event) => readField(readField(event, "toolCall"), "input");
67
- const contentText = (content) => {
68
- if (!Array.isArray(content)) {
69
- return void 0;
70
- }
71
- let text = "";
72
- for (const part of content) {
73
- if (readField(part, "type") === "text") {
74
- const value = readField(part, "text");
75
- if (typeof value === "string") {
76
- text += value;
77
- }
78
- }
79
- }
80
- return text.length > 0 ? text : void 0;
81
- };
82
- const describeError = (error) => {
83
- if (error instanceof Error) {
84
- return { message: error.message, name: error.name };
85
- }
86
- return error;
87
- };
88
-
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 };