@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,5 +1,5 @@
1
- import { A as AgentDefinition } from "./packem_shared/types.d-boAM2Yi1.mjs";
2
- export type { I as InboundChannelEvent } from "./packem_shared/types.d-boAM2Yi1.mjs";
1
+ import { A as AgentDefinition } from "./packem_shared/types.d-B8WZl1rU.mjs";
2
+ export type { I as InboundChannelEvent } from "./packem_shared/types.d-B8WZl1rU.mjs";
3
3
  import '@lunora/mail/inbound';
4
4
  import 'ai';
5
5
  /**
@@ -51,14 +51,6 @@ interface AgentChannelTarget {
51
51
  * @experimental
52
52
  */
53
53
  type InboundChannelHandler = (request: Request, env: Record<string, unknown>) => Promise<Response>;
54
- /**
55
- * Whether a `workflow.create()` rejection is a duplicate-instance-id error — the
56
- * idempotency signal — as opposed to a transient/config failure (Workflows
57
- * service error, instance-creation quota, bad params). Only the former may be
58
- * acked; every other failure MUST surface so the handler returns non-2xx and the
59
- * provider redelivers, rather than silently dropping the event.
60
- */
61
- declare const isDuplicateInstanceError: (error: unknown) => boolean;
62
54
  /**
63
55
  * Build an HTTP handler that starts a durable agent run from a verified inbound
64
56
  * webhook. The channel is detected from the signature headers; EACH eligible
@@ -71,4 +63,4 @@ declare const isDuplicateInstanceError: (error: unknown) => boolean;
71
63
  * @experimental
72
64
  */
73
65
  declare const dispatchAgentChannel: (targets: ReadonlyArray<AgentChannelTarget>) => InboundChannelHandler;
74
- export { type AgentChannelTarget, type InboundChannelHandler, dispatchAgentChannel, isDuplicateInstanceError, verifyDiscord, verifyGithub, verifySlack };
66
+ export { type AgentChannelTarget, type InboundChannelHandler, dispatchAgentChannel, verifyDiscord, verifyGithub, verifySlack };
@@ -1,5 +1,5 @@
1
- import { A as AgentDefinition } from "./packem_shared/types.d-boAM2Yi1.js";
2
- export type { I as InboundChannelEvent } from "./packem_shared/types.d-boAM2Yi1.js";
1
+ import { A as AgentDefinition } from "./packem_shared/types.d-B8WZl1rU.js";
2
+ export type { I as InboundChannelEvent } from "./packem_shared/types.d-B8WZl1rU.js";
3
3
  import '@lunora/mail/inbound';
4
4
  import 'ai';
5
5
  /**
@@ -51,14 +51,6 @@ interface AgentChannelTarget {
51
51
  * @experimental
52
52
  */
53
53
  type InboundChannelHandler = (request: Request, env: Record<string, unknown>) => Promise<Response>;
54
- /**
55
- * Whether a `workflow.create()` rejection is a duplicate-instance-id error — the
56
- * idempotency signal — as opposed to a transient/config failure (Workflows
57
- * service error, instance-creation quota, bad params). Only the former may be
58
- * acked; every other failure MUST surface so the handler returns non-2xx and the
59
- * provider redelivers, rather than silently dropping the event.
60
- */
61
- declare const isDuplicateInstanceError: (error: unknown) => boolean;
62
54
  /**
63
55
  * Build an HTTP handler that starts a durable agent run from a verified inbound
64
56
  * webhook. The channel is detected from the signature headers; EACH eligible
@@ -71,4 +63,4 @@ declare const isDuplicateInstanceError: (error: unknown) => boolean;
71
63
  * @experimental
72
64
  */
73
65
  declare const dispatchAgentChannel: (targets: ReadonlyArray<AgentChannelTarget>) => InboundChannelHandler;
74
- export { type AgentChannelTarget, type InboundChannelHandler, dispatchAgentChannel, isDuplicateInstanceError, verifyDiscord, verifyGithub, verifySlack };
66
+ export { type AgentChannelTarget, type InboundChannelHandler, dispatchAgentChannel, verifyDiscord, verifyGithub, verifySlack };
package/dist/channels.mjs CHANGED
@@ -1,181 +1 @@
1
- import { LunoraError } from '@lunora/errors';
2
-
3
- const DEFAULT_TIMESTAMP_TOLERANCE = 300;
4
- const NON_HEX = /[^0-9a-f]/iu;
5
- const encoder = new TextEncoder();
6
- const utf8 = (value) => new Uint8Array(encoder.encode(value));
7
- const hexToBytes = (hex) => {
8
- if (hex.length % 2 !== 0 || NON_HEX.test(hex)) {
9
- throw new LunoraError("BAD_REQUEST", "@lunora/agent: malformed hex signature");
10
- }
11
- const bytes = new Uint8Array(hex.length / 2);
12
- for (let index = 0; index < bytes.length; index += 1) {
13
- bytes[index] = Number.parseInt(hex.slice(index * 2, index * 2 + 2), 16);
14
- }
15
- return bytes;
16
- };
17
- const verifyHmacSha256 = async (secret, message, signatureHex) => {
18
- try {
19
- const key = await crypto.subtle.importKey("raw", utf8(secret), { hash: "SHA-256", name: "HMAC" }, false, ["verify"]);
20
- return await crypto.subtle.verify("HMAC", key, hexToBytes(signatureHex), utf8(message));
21
- } catch {
22
- return false;
23
- }
24
- };
25
- const isFreshTimestamp = (timestampSeconds, nowSeconds, tolerance) => Number.isFinite(timestampSeconds) && Math.abs(nowSeconds - timestampSeconds) <= tolerance;
26
- const verifySlack = async (options) => {
27
- const { body, now = Date.now() / 1e3, signature, signingSecret, timestamp, tolerance = DEFAULT_TIMESTAMP_TOLERANCE } = options;
28
- if (!signature || !timestamp || !signature.startsWith("v0=")) {
29
- return false;
30
- }
31
- if (!isFreshTimestamp(Number(timestamp), now, tolerance)) {
32
- return false;
33
- }
34
- return verifyHmacSha256(signingSecret, `v0:${timestamp}:${body}`, signature.slice("v0=".length));
35
- };
36
- const verifyGithub = async (options) => {
37
- const { body, secret, signature } = options;
38
- if (!signature?.startsWith("sha256=")) {
39
- return false;
40
- }
41
- return verifyHmacSha256(secret, body, signature.slice("sha256=".length));
42
- };
43
- const verifyDiscord = async (options) => {
44
- const { body, publicKey, signature, timestamp } = options;
45
- if (!signature || !timestamp) {
46
- return false;
47
- }
48
- try {
49
- const key = await crypto.subtle.importKey("raw", hexToBytes(publicKey), { name: "Ed25519" }, false, ["verify"]);
50
- return await crypto.subtle.verify({ name: "Ed25519" }, key, hexToBytes(signature), utf8(timestamp + body));
51
- } catch {
52
- return false;
53
- }
54
- };
55
- const detectChannel = (headers) => {
56
- if (headers.has("x-slack-signature")) {
57
- return "slack";
58
- }
59
- if (headers.has("x-hub-signature-256")) {
60
- return "github";
61
- }
62
- if (headers.has("x-signature-ed25519")) {
63
- return "discord";
64
- }
65
- return void 0;
66
- };
67
- const resolveSecret = (secret, env) => {
68
- if (typeof secret === "function") {
69
- return secret(env);
70
- }
71
- const value = env[secret];
72
- return typeof value === "string" ? value : void 0;
73
- };
74
- const verifyChannel = async (channel, secret, headers, body) => {
75
- switch (channel) {
76
- case "discord": {
77
- return verifyDiscord({
78
- body,
79
- publicKey: secret,
80
- signature: headers.get("x-signature-ed25519") ?? void 0,
81
- timestamp: headers.get("x-signature-timestamp") ?? void 0
82
- });
83
- }
84
- case "github": {
85
- return verifyGithub({ body, secret, signature: headers.get("x-hub-signature-256") ?? void 0 });
86
- }
87
- case "slack": {
88
- return verifySlack({
89
- body,
90
- signature: headers.get("x-slack-signature") ?? void 0,
91
- signingSecret: secret,
92
- timestamp: headers.get("x-slack-request-timestamp") ?? void 0
93
- });
94
- }
95
- default: {
96
- return false;
97
- }
98
- }
99
- };
100
- const discordPongResponse = (channel, body) => {
101
- if (channel !== "discord") {
102
- return void 0;
103
- }
104
- try {
105
- if (JSON.parse(body).type === 1) {
106
- return Response.json({ type: 1 });
107
- }
108
- } catch {
109
- }
110
- return void 0;
111
- };
112
- const UNSAFE_INSTANCE_ID = /[^\w-]/gu;
113
- const DUPLICATE_INSTANCE = /already[\s-]?exists/iu;
114
- const ack = () => new Response(void 0, { status: 200 });
115
- const isDuplicateInstanceError = (error) => DUPLICATE_INSTANCE.test(error instanceof Error ? error.message : String(error));
116
- const deliveryId = (channel, headers, body) => {
117
- if (channel === "github") {
118
- return headers.get("x-github-delivery") ?? void 0;
119
- }
120
- try {
121
- const parsed = JSON.parse(body);
122
- const raw = channel === "slack" ? parsed.event_id : parsed.id;
123
- return typeof raw === "string" ? raw : void 0;
124
- } catch {
125
- return void 0;
126
- }
127
- };
128
- const startChannelRun = async (workflow, run, channel, id) => {
129
- const sanitizedId = id === void 0 ? "" : id.replaceAll(UNSAFE_INSTANCE_ID, "");
130
- if (sanitizedId === "") {
131
- await workflow.create({ params: run });
132
- return ack();
133
- }
134
- try {
135
- await workflow.create({ id: `${channel}-${sanitizedId}`.slice(0, 60), params: run });
136
- } catch (error) {
137
- if (isDuplicateInstanceError(error)) {
138
- return ack();
139
- }
140
- throw error;
141
- }
142
- return ack();
143
- };
144
- const dispatchAgentChannel = (targets) => async (request, env) => {
145
- const body = await request.text();
146
- const channel = detectChannel(request.headers);
147
- if (channel === void 0) {
148
- return new Response("Unrecognized webhook", { status: 400 });
149
- }
150
- const eligible = targets.map((target) => {
151
- return { config: target.agent.onInbound, target };
152
- }).filter((entry) => entry.config?.channel === channel);
153
- const event = { channel, headers: request.headers, json: () => JSON.parse(body), rawBody: body };
154
- let verifiedAny = false;
155
- for (const { config, target } of eligible) {
156
- const secret = resolveSecret(config.secret, env);
157
- if (secret === void 0 || !await verifyChannel(channel, secret, request.headers, body)) {
158
- continue;
159
- }
160
- verifiedAny = true;
161
- const pong = discordPongResponse(channel, body);
162
- if (pong) {
163
- return pong;
164
- }
165
- const run = await config.map(event);
166
- if (!run) {
167
- continue;
168
- }
169
- const workflow = env[target.binding];
170
- if (!workflow || typeof workflow.create !== "function") {
171
- throw new LunoraError(
172
- "INTERNAL",
173
- `@lunora/agent: no Workflow binding "${target.binding}" on env for an inbound-channel agent — run codegen/dev so wrangler.jsonc declares it`
174
- );
175
- }
176
- return await startChannelRun(workflow, run, channel, deliveryId(channel, request.headers, body));
177
- }
178
- return verifiedAny ? new Response(void 0, { status: 204 }) : new Response("Invalid signature", { status: 401 });
179
- };
180
-
181
- export { dispatchAgentChannel, isDuplicateInstanceError, verifyDiscord, verifyGithub, verifySlack };
1
+ import{LunoraError as d}from"@lunora/errors";import{isDuplicateInstanceError as w}from"@lunora/workflow";import{h as b,B as E}from"./packem_shared/branch-marker-boZ00zmk.mjs";import{f as A}from"./packem_shared/fnv1a-BNN96GYb.mjs";const R=300,k=/[^0-9a-f]/iu,x=new TextEncoder,f=t=>new Uint8Array(x.encode(t)),l=t=>{if(t.length%2!==0||k.test(t))throw new d("BAD_REQUEST","@lunora/agent: malformed hex signature");const e=new Uint8Array(t.length/2);for(let n=0;n<e.length;n+=1)e[n]=Number.parseInt(t.slice(n*2,n*2+2),16);return e},m=async(t,e,n)=>{try{const r=await crypto.subtle.importKey("raw",f(t),{hash:"SHA-256",name:"HMAC"},!1,["verify"]);return await crypto.subtle.verify("HMAC",r,l(n),f(e))}catch{return!1}},N=(t,e,n)=>Number.isFinite(t)&&Math.abs(e-t)<=n,S=async t=>{const{body:e,now:n=Date.now()/1e3,signature:r,signingSecret:s,timestamp:a,tolerance:o=R}=t;return!r||!a||!r.startsWith("v0=")||!N(Number(a),n,o)?!1:m(s,`v0:${a}:${e}`,r.slice(3))},T=async t=>{const{body:e,secret:n,signature:r}=t;return r?.startsWith("sha256=")?m(n,e,r.slice(7)):!1},C=async t=>{const{body:e,publicKey:n,signature:r,timestamp:s}=t;if(!r||!s)return!1;try{const a=await crypto.subtle.importKey("raw",l(n),{name:"Ed25519"},!1,["verify"]);return await crypto.subtle.verify({name:"Ed25519"},a,l(r),f(s+e))}catch{return!1}},I=t=>{if(t.has("x-slack-signature"))return"slack";if(t.has("x-hub-signature-256"))return"github";if(t.has("x-signature-ed25519"))return"discord"},_=(t,e)=>{if(typeof t=="function")return t(e);const n=e[t];return typeof n=="string"?n:void 0},B=async(t,e,n,r)=>{switch(t){case"discord":return C({body:r,publicKey:e,signature:n.get("x-signature-ed25519")??void 0,timestamp:n.get("x-signature-timestamp")??void 0});case"github":return T({body:r,secret:e,signature:n.get("x-hub-signature-256")??void 0});case"slack":return S({body:r,signature:n.get("x-slack-signature")??void 0,signingSecret:e,timestamp:n.get("x-slack-request-timestamp")??void 0});default:return!1}},H=(t,e)=>{if(t==="discord")try{if(JSON.parse(e).type===1)return Response.json({type:1})}catch{}},u=()=>new Response(void 0,{status:200}),M=(t,e,n)=>{if(t==="github")return e.get("x-github-delivery")??void 0;try{const r=JSON.parse(n),s=t==="slack"?r.event_id:r.id;return typeof s=="string"?s:void 0}catch{return}},D=async(t,e,n,r)=>{if(b(e))throw new d("BAD_REQUEST",`@lunora/agent: inbound channel run params ${E}`);if(r===void 0||r==="")return await t.create({params:e}),u();try{await t.create({id:`${n}-${A(r)}`,params:e})}catch(s){if(w(s))return u();throw s}return u()},J=t=>async(e,n)=>{const r=await e.text(),s=I(e.headers);if(s===void 0)return new Response("Unrecognized webhook",{status:400});const a=t.map(i=>({config:i.agent.onInbound,target:i})).filter(i=>i.config?.channel===s),o={channel:s,headers:e.headers,json:()=>JSON.parse(r),rawBody:r};let g=!1;for(const{config:i,target:y}of a){const h=_(i.secret,n);if(h===void 0||!await B(s,h,e.headers,r))continue;g=!0;const p=H(s,r);if(p)return p;const v=await i.map(o);if(!v)continue;const c=n[y.binding];if(!c||typeof c.create!="function")throw new d("INTERNAL",`@lunora/agent: no Workflow binding "${y.binding}" on env for an inbound-channel agent — run codegen/dev so wrangler.jsonc declares it`);return await D(c,v,s,M(s,e.headers,r))}return g?new Response(void 0,{status:204}):new Response("Invalid signature",{status:401})};export{J as dispatchAgentChannel,C as verifyDiscord,T as verifyGithub,S as verifySlack};
@@ -72,6 +72,8 @@ interface AgentComponent {
72
72
  extension: SchemaExtension;
73
73
  functions: {
74
74
  agentAppendMessage: AgentRegisteredFunction;
75
+ agentCompleteRun: AgentRegisteredFunction;
76
+ agentDeleteMessage: AgentRegisteredFunction;
75
77
  agentEnsureThread: AgentRegisteredFunction;
76
78
  agentEpisodeRecall: AgentRegisteredFunction;
77
79
  agentEpisodeUpsert: AgentRegisteredFunction;
@@ -72,6 +72,8 @@ interface AgentComponent {
72
72
  extension: SchemaExtension;
73
73
  functions: {
74
74
  agentAppendMessage: AgentRegisteredFunction;
75
+ agentCompleteRun: AgentRegisteredFunction;
76
+ agentDeleteMessage: AgentRegisteredFunction;
75
77
  agentEnsureThread: AgentRegisteredFunction;
76
78
  agentEpisodeRecall: AgentRegisteredFunction;
77
79
  agentEpisodeUpsert: AgentRegisteredFunction;