@ai-setting/roy-agent-core 1.5.37 → 1.5.40

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 (74) hide show
  1. package/dist/config/index.js +4 -3
  2. package/dist/env/agent/index.js +10 -9
  3. package/dist/env/commands/index.js +7 -6
  4. package/dist/env/context/index.js +21 -0
  5. package/dist/env/debug/index.js +4 -3
  6. package/dist/env/event-source/index.js +12 -6
  7. package/dist/env/hook/index.js +2 -1
  8. package/dist/env/index.js +41 -18
  9. package/dist/env/llm/index.js +8 -7
  10. package/dist/env/log-trace/index.js +10 -9
  11. package/dist/env/mcp/index.js +8 -7
  12. package/dist/env/mcp/tool/index.js +4 -4
  13. package/dist/env/memory/index.js +12 -11
  14. package/dist/env/memory/plugin/index.js +4 -4
  15. package/dist/env/plugin/index.js +18 -0
  16. package/dist/env/prompt/index.js +7 -6
  17. package/dist/env/session/index.js +11 -10
  18. package/dist/env/session/storage/index.js +2 -6
  19. package/dist/env/skill/index.js +7 -6
  20. package/dist/env/task/delegate/index.js +6 -5
  21. package/dist/env/task/index.js +10 -8
  22. package/dist/env/task/plugins/index.js +13 -6
  23. package/dist/env/task/storage/index.js +4 -4
  24. package/dist/env/tool/built-in/index.js +3 -3
  25. package/dist/env/tool/index.js +8 -7
  26. package/dist/env/workflow/engine/index.js +5 -5
  27. package/dist/env/workflow/index.js +9 -8
  28. package/dist/env/workflow/storage/index.js +5 -5
  29. package/dist/env/workflow/tools/index.js +3 -3
  30. package/dist/env/workflow/utils/index.js +4 -4
  31. package/dist/index.js +67 -60
  32. package/dist/shared/@ai-setting/{roy-agent-core-44hnfb02.js → roy-agent-core-10n2jh7p.js} +1 -1
  33. package/dist/shared/@ai-setting/{roy-agent-core-xt3fx7m1.js → roy-agent-core-15x8fe5h.js} +38 -56
  34. package/dist/shared/@ai-setting/{roy-agent-core-1akcqxj9.js → roy-agent-core-1bfmxx89.js} +1 -1
  35. package/dist/shared/@ai-setting/{roy-agent-core-ty94k28r.js → roy-agent-core-2jnzv9at.js} +2 -2
  36. package/dist/shared/@ai-setting/{roy-agent-core-3jywqmdd.js → roy-agent-core-2x07feb7.js} +317 -65
  37. package/dist/shared/@ai-setting/{roy-agent-core-cefh9hjv.js → roy-agent-core-4jqq077c.js} +1 -1
  38. package/dist/shared/@ai-setting/{roy-agent-core-xs5rsgat.js → roy-agent-core-58k274fg.js} +108 -23
  39. package/dist/shared/@ai-setting/{roy-agent-core-mx489p7f.js → roy-agent-core-728h32vx.js} +263 -33
  40. package/dist/shared/@ai-setting/{roy-agent-core-jfh9q2qh.js → roy-agent-core-7b35emr7.js} +0 -15
  41. package/dist/shared/@ai-setting/{roy-agent-core-3rr5k71j.js → roy-agent-core-8n4bz6y3.js} +1 -1
  42. package/dist/shared/@ai-setting/{roy-agent-core-zpn0bqa8.js → roy-agent-core-9ffsvvcf.js} +1 -1
  43. package/dist/shared/@ai-setting/roy-agent-core-az13yzmc.js +11 -0
  44. package/dist/shared/@ai-setting/{roy-agent-core-0wdjp769.js → roy-agent-core-b4wd9tn6.js} +2 -2
  45. package/dist/shared/@ai-setting/{roy-agent-core-6kvtahqv.js → roy-agent-core-c3ct1346.js} +1 -1
  46. package/dist/shared/@ai-setting/{roy-agent-core-psv4v63c.js → roy-agent-core-c6592r3c.js} +19 -2
  47. package/dist/shared/@ai-setting/{roy-agent-core-c2wjwx16.js → roy-agent-core-c8f2hync.js} +305 -287
  48. package/dist/shared/@ai-setting/roy-agent-core-cevpwnq7.js +147 -0
  49. package/dist/shared/@ai-setting/{roy-agent-core-hkb529dw.js → roy-agent-core-dxbsc1zy.js} +7 -7
  50. package/dist/shared/@ai-setting/{roy-agent-core-vqspcspb.js → roy-agent-core-e130w7mv.js} +3 -3
  51. package/dist/shared/@ai-setting/{roy-agent-core-j0ke54vy.js → roy-agent-core-ee6nnnqw.js} +5 -5
  52. package/dist/shared/@ai-setting/{roy-agent-core-qdmt6nz7.js → roy-agent-core-eg6nv09z.js} +2 -2
  53. package/dist/shared/@ai-setting/{roy-agent-core-hd1z20yq.js → roy-agent-core-frx4p6d1.js} +1 -1
  54. package/dist/shared/@ai-setting/{roy-agent-core-bvr1761x.js → roy-agent-core-hsxn8m1j.js} +1 -1
  55. package/dist/shared/@ai-setting/{roy-agent-core-86gphny5.js → roy-agent-core-jqy2mdyq.js} +15 -1
  56. package/dist/shared/@ai-setting/{roy-agent-core-c0d3dtjd.js → roy-agent-core-kajktp3d.js} +7 -7
  57. package/dist/shared/@ai-setting/{roy-agent-core-eajcvp4e.js → roy-agent-core-kwhv9dcd.js} +2 -2
  58. package/dist/shared/@ai-setting/{roy-agent-core-r9ezzemr.js → roy-agent-core-m0wp34r4.js} +1 -1
  59. package/dist/shared/@ai-setting/{roy-agent-core-fg1kxf70.js → roy-agent-core-nqgrjja0.js} +5 -5
  60. package/dist/shared/@ai-setting/{roy-agent-core-d7cyjkf7.js → roy-agent-core-pwkk12p4.js} +1 -1
  61. package/dist/shared/@ai-setting/{roy-agent-core-97ma0pr5.js → roy-agent-core-pxcrzyv9.js} +2 -2
  62. package/dist/shared/@ai-setting/{roy-agent-core-zgypchmt.js → roy-agent-core-q5qj0fes.js} +19 -11
  63. package/dist/shared/@ai-setting/{roy-agent-core-sx7wsvnn.js → roy-agent-core-qakqwbbh.js} +2 -2
  64. package/dist/shared/@ai-setting/{roy-agent-core-qfdp3pvq.js → roy-agent-core-rsybkb38.js} +1 -1
  65. package/dist/shared/@ai-setting/roy-agent-core-ty33mnr7.js +14 -0
  66. package/dist/shared/@ai-setting/{roy-agent-core-3prpabp8.js → roy-agent-core-v53rfk99.js} +2 -2
  67. package/dist/shared/@ai-setting/{roy-agent-core-wjd5kars.js → roy-agent-core-wb43x8hd.js} +3 -3
  68. package/dist/shared/@ai-setting/{roy-agent-core-e2vk2qh7.js → roy-agent-core-yc543gnq.js} +6 -6
  69. package/dist/shared/@ai-setting/{roy-agent-core-gf2c2pxr.js → roy-agent-core-ycg9rk6z.js} +3 -3
  70. package/dist/shared/@ai-setting/roy-agent-core-z33en0cz.js +44 -0
  71. package/dist/shared/@ai-setting/{roy-agent-core-by55z88t.js → roy-agent-core-zrja5v78.js} +11 -11
  72. package/dist/shared/@ai-setting/{roy-agent-core-wft9ra24.js → roy-agent-core-zwp3jp02.js} +4 -4
  73. package/package.json +1 -1
  74. package/dist/shared/@ai-setting/roy-agent-core-bcbqy27c.js +0 -14
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  SQLiteSpanStorage,
3
3
  init_span_storage
4
- } from "./roy-agent-core-psv4v63c.js";
4
+ } from "./roy-agent-core-c6592r3c.js";
5
5
  import {
6
6
  __esm,
7
7
  __export,
@@ -95,6 +95,9 @@ __export(exports_tracer_provider, {
95
95
  getTracerProvider: () => getTracerProvider,
96
96
  OTelTracerProvider: () => OTelTracerProvider
97
97
  });
98
+ function isOtelTraceDebugEnabled() {
99
+ return process.env.ROY_TRACE_DEBUG_OTEL === "1" || process.env.ROY_TRACE_DEBUG === "1";
100
+ }
98
101
 
99
102
  class OTelSpanImpl {
100
103
  name;
@@ -129,19 +132,40 @@ class OTelSpanImpl {
129
132
  if (error) {
130
133
  this.error = error.message;
131
134
  }
132
- this.storage.save({
133
- traceId: this.spanContext.traceId,
134
- spanId: this.spanContext.spanId,
135
- parentSpanId: this.spanContext.parentSpanId,
136
- name: this.name,
137
- kind: this.kind,
138
- status: error ? "error" /* ERROR */ : "ok" /* OK */,
139
- startTime: this.startTime,
140
- endTime: this.endTime,
141
- attributes: this.attributes,
142
- result,
143
- error: this.error
144
- });
135
+ const duration = this.endTime - (this.startTime || 0);
136
+ if (isOtelTraceDebugEnabled()) {
137
+ console.log(`[OTelSpan] Ending span: name="${this.name}" traceId=${this.spanContext.traceId} spanId=${this.spanContext.spanId} duration=${duration}ms status=${error ? "ERROR" : "OK"}`);
138
+ }
139
+ let storage = this.storage;
140
+ if (!storage) {
141
+ console.warn(`[OTelSpan] storage is null for "${this.name}", attempting to re-fetch...`);
142
+ const provider = getTracerProvider();
143
+ storage = provider.getStorage();
144
+ }
145
+ if (storage) {
146
+ const isInitialized = storage.db || storage.initialized;
147
+ if (!isInitialized) {
148
+ console.warn(`[OTelSpan] storage not initialized for "${this.name}", initializing now...`);
149
+ storage.initialize().catch((err) => {
150
+ console.error(`[OTelSpan] Failed to initialize storage:`, err);
151
+ });
152
+ }
153
+ storage.save({
154
+ traceId: this.spanContext.traceId,
155
+ spanId: this.spanContext.spanId,
156
+ parentSpanId: this.spanContext.parentSpanId,
157
+ name: this.name,
158
+ kind: this.kind,
159
+ status: error ? "error" /* ERROR */ : "ok" /* OK */,
160
+ startTime: this.startTime,
161
+ endTime: this.endTime,
162
+ attributes: this.attributes,
163
+ result,
164
+ error: this.error
165
+ });
166
+ } else {
167
+ console.error(`[OTelSpan] Failed to save span "${this.name}": storage still null after re-fetch`);
168
+ }
145
169
  this.onEnd?.();
146
170
  }
147
171
  }
@@ -154,11 +178,13 @@ class OTelTracerImpl {
154
178
  activeSpans = new Map;
155
179
  onSpanEndCallback;
156
180
  provider;
181
+ instanceId;
157
182
  constructor(name, version, storage, provider) {
158
183
  this.name = name;
159
184
  this.version = version;
160
185
  this.storage = storage;
161
186
  this.provider = provider;
187
+ this.instanceId = `${name}@${provider.instanceId}`;
162
188
  }
163
189
  setOnSpanEndCallback(callback) {
164
190
  this.onSpanEndCallback = callback;
@@ -169,8 +195,37 @@ class OTelTracerImpl {
169
195
  startSpan(name, options) {
170
196
  const parentFromOptions = options?.parent;
171
197
  const hasExplicitParent = options && "parent" in options;
198
+ const hasExplicitContext = options && "context" in options;
172
199
  const globalContext = this.provider.getGlobalContext();
173
200
  let effectiveParentContext;
201
+ let traceId;
202
+ let spanId;
203
+ let parentSpanId;
204
+ let spanContext;
205
+ if (hasExplicitContext && options?.context) {
206
+ const injectedContext = options.context;
207
+ traceId = injectedContext.traceId;
208
+ spanId = this.generateSpanId();
209
+ parentSpanId = injectedContext.spanId;
210
+ spanContext = {
211
+ traceId,
212
+ spanId,
213
+ parentSpanId
214
+ };
215
+ this.currentContext = {
216
+ traceId,
217
+ spanId,
218
+ parentSpanId
219
+ };
220
+ const span2 = new OTelSpanImpl(name, spanContext, this.storage, injectedContext, () => this.handleSpanEnd(spanContext.spanId, injectedContext.spanId));
221
+ if (options?.attributes) {
222
+ for (const [key, value] of Object.entries(options.attributes)) {
223
+ span2.setAttribute(key, value);
224
+ }
225
+ }
226
+ this.activeSpans.set(spanId, span2);
227
+ return span2;
228
+ }
174
229
  if (hasExplicitParent) {
175
230
  effectiveParentContext = parentFromOptions;
176
231
  } else if (this.currentContext) {
@@ -178,9 +233,8 @@ class OTelTracerImpl {
178
233
  } else if (globalContext) {
179
234
  effectiveParentContext = globalContext;
180
235
  }
181
- const traceId = effectiveParentContext?.traceId || this.generateTraceId();
182
- const spanId = this.generateSpanId();
183
- let parentSpanId;
236
+ traceId = effectiveParentContext?.traceId || this.generateTraceId();
237
+ spanId = this.generateSpanId();
184
238
  if (hasExplicitParent && parentFromOptions) {
185
239
  parentSpanId = parentFromOptions.parentSpanId || parentFromOptions.spanId;
186
240
  } else if (this.currentContext) {
@@ -188,7 +242,7 @@ class OTelTracerImpl {
188
242
  } else if (globalContext) {
189
243
  parentSpanId = globalContext.spanId;
190
244
  }
191
- const spanContext = {
245
+ spanContext = {
192
246
  traceId,
193
247
  spanId,
194
248
  parentSpanId
@@ -205,6 +259,9 @@ class OTelTracerImpl {
205
259
  }
206
260
  }
207
261
  this.activeSpans.set(spanId, span);
262
+ if (isOtelTraceDebugEnabled()) {
263
+ console.log(`[OTelTracer] ✓ Span created: name="${name}" traceId=${traceId} spanId=${spanId} parentSpanId=${parentSpanId || "-"}`);
264
+ }
208
265
  return span;
209
266
  }
210
267
  injectToEnv(env) {
@@ -218,6 +275,14 @@ class OTelTracerImpl {
218
275
  setCurrentContext(context) {
219
276
  this.currentContext = context;
220
277
  }
278
+ findStackParentSpan(spanId) {
279
+ for (const [, span] of this.activeSpans) {
280
+ if (span.spanContext.parentSpanId === spanId) {
281
+ return span;
282
+ }
283
+ }
284
+ return;
285
+ }
221
286
  endSpan(span) {
222
287
  const spanContext = span.spanContext;
223
288
  this.activeSpans.delete(spanContext.spanId);
@@ -243,6 +308,16 @@ class OTelTracerImpl {
243
308
  return parentContext;
244
309
  }
245
310
  }
311
+ const stackParentSpan = this.findStackParentSpan(spanContext.spanId);
312
+ if (stackParentSpan) {
313
+ const parentContext = {
314
+ traceId: stackParentSpan.spanContext.traceId,
315
+ spanId: stackParentSpan.spanContext.spanId,
316
+ parentSpanId: stackParentSpan.spanContext.parentSpanId
317
+ };
318
+ this.currentContext = parentContext;
319
+ return parentContext;
320
+ }
246
321
  this.currentContext = undefined;
247
322
  return;
248
323
  }
@@ -255,8 +330,6 @@ class OTelTracerImpl {
255
330
  return Math.floor(Math.random() * 18446744073709552000).toString(16).padStart(16, "0");
256
331
  }
257
332
  handleSpanEnd(spanId, parentSpanId) {
258
- this.activeSpans.delete(spanId);
259
- const currentTraceId = this.currentContext?.traceId;
260
333
  if (parentSpanId) {
261
334
  const parentSpan = this.activeSpans.get(parentSpanId);
262
335
  if (parentSpan) {
@@ -267,15 +340,24 @@ class OTelTracerImpl {
267
340
  };
268
341
  return;
269
342
  }
270
- if (currentTraceId) {
343
+ if (this.currentContext?.traceId) {
271
344
  this.currentContext = {
272
- traceId: currentTraceId,
345
+ traceId: this.currentContext.traceId,
273
346
  spanId: parentSpanId,
274
347
  parentSpanId: undefined
275
348
  };
276
349
  return;
277
350
  }
278
351
  }
352
+ const stackParentSpan = this.findStackParentSpan(spanId);
353
+ if (stackParentSpan) {
354
+ this.currentContext = {
355
+ traceId: stackParentSpan.spanContext.traceId,
356
+ spanId: stackParentSpan.spanContext.spanId,
357
+ parentSpanId: stackParentSpan.spanContext.parentSpanId
358
+ };
359
+ return;
360
+ }
279
361
  this.currentContext = undefined;
280
362
  }
281
363
  }
@@ -285,7 +367,10 @@ class OTelTracerProvider {
285
367
  storage;
286
368
  initialized = false;
287
369
  globalContext;
370
+ instanceId;
288
371
  constructor(storage, dbPath) {
372
+ providerCounter++;
373
+ this.instanceId = `Provider#${providerCounter}`;
289
374
  this.storage = storage || new SQLiteSpanStorage(dbPath || getDefaultDbPath());
290
375
  }
291
376
  async initialize() {
@@ -358,7 +443,7 @@ function getDefaultDbPath() {
358
443
  const dataHome = process.env.XDG_DATA_HOME || path.join(home, ".local", "share");
359
444
  return path.join(dataHome, "roy-agent", "traces.db");
360
445
  }
361
- var providerInstance = null;
446
+ var providerInstance = null, providerCounter = 0;
362
447
  var init_tracer_provider = __esm(() => {
363
448
  init_span_storage();
364
449
  init_propagation();
@@ -1,22 +1,45 @@
1
+ import {
2
+ TaskTagPlugin,
3
+ createLarkCliTaskNotifyHook
4
+ } from "./roy-agent-core-2x07feb7.js";
1
5
  import {
2
6
  envKeyToConfigKey
3
7
  } from "./roy-agent-core-qxhq8ven.js";
4
8
  import {
5
9
  BaseComponent
6
- } from "./roy-agent-core-cefh9hjv.js";
10
+ } from "./roy-agent-core-4jqq077c.js";
7
11
  import {
8
12
  globalHookManager
9
- } from "./roy-agent-core-86gphny5.js";
13
+ } from "./roy-agent-core-jqy2mdyq.js";
14
+ import {
15
+ createEnvContext,
16
+ runWithEnvContext
17
+ } from "./roy-agent-core-z33en0cz.js";
10
18
  import {
11
19
  createLogger,
12
20
  init_logger
13
- } from "./roy-agent-core-44hnfb02.js";
21
+ } from "./roy-agent-core-10n2jh7p.js";
22
+ import {
23
+ getTracerProvider
24
+ } from "./roy-agent-core-58k274fg.js";
14
25
  import {
15
26
  __require
16
27
  } from "./roy-agent-core-fs0mn2jk.js";
17
28
 
18
29
  // src/env/event-source/event-source-handlers.ts
19
30
  import { spawn } from "child_process";
31
+ var BUILT_IN_PLUGIN_FACTORIES = {
32
+ LarkCliTaskNotifyPlugin: (cfg) => createLarkCliTaskNotifyHook(cfg),
33
+ "task-tag": () => new TaskTagPlugin
34
+ };
35
+ function generateTraceId() {
36
+ const chars = "0123456789abcdef";
37
+ let traceId = "";
38
+ for (let i = 0;i < 32; i++) {
39
+ traceId += chars[Math.floor(Math.random() * chars.length)];
40
+ }
41
+ return traceId;
42
+ }
20
43
  function matchEventType(eventType, patterns) {
21
44
  for (const pattern of patterns) {
22
45
  if (pattern === "*")
@@ -35,26 +58,39 @@ function extractMetadata(rawEvent, eventType) {
35
58
  const event = rawEvent;
36
59
  const metadata = {};
37
60
  const larkInnerEvent = event.event;
38
- const header = event.header;
39
- const message = larkInnerEvent?.message || event.message;
61
+ const header = larkInnerEvent?.header || event.header;
40
62
  const sender = larkInnerEvent?.sender || event.sender;
41
63
  const senderId = sender?.sender_id;
64
+ let messageData;
65
+ if (larkInnerEvent?.message) {
66
+ messageData = larkInnerEvent.message;
67
+ } else if (typeof event.message === "object" && event.message !== null) {
68
+ messageData = event.message;
69
+ } else {
70
+ messageData = {
71
+ message_id: event.message_id || event.id,
72
+ chat_id: event.chat_id,
73
+ chat_type: event.chat_type,
74
+ message_type: event.message_type,
75
+ content: event.content
76
+ };
77
+ }
42
78
  if (header) {
43
79
  metadata.eventType = header.event_type;
44
80
  metadata.appId = header.app_id;
45
81
  metadata.tenantKey = header.tenant_key;
46
82
  }
47
- if (message) {
48
- metadata.chatId = message.chat_id;
49
- metadata.chatType = message.chat_type;
50
- metadata.messageId = message.message_id;
51
- metadata.messageType = message.message_type;
83
+ if (messageData) {
84
+ metadata.chatId = messageData.chat_id;
85
+ metadata.chatType = messageData.chat_type;
86
+ metadata.messageId = messageData.message_id;
87
+ metadata.messageType = messageData.message_type;
52
88
  }
53
89
  if (senderId) {
54
90
  metadata.senderId = senderId.open_id || senderId.user_id || senderId.union_id;
55
91
  }
56
92
  let recommendedAction;
57
- if (eventType === "im.message.receive_v1") {
93
+ if (eventType === "im.message.receive_v1" || event.type === "im.message.receive_v1") {
58
94
  recommendedAction = {
59
95
  action: '处理飞书消息并以机器人身份回复,比如lark-cli im +messages-reply --message-id "xxxxid" --as bot --text "回复内容"',
60
96
  replyTo: {
@@ -67,8 +103,8 @@ function extractMetadata(rawEvent, eventType) {
67
103
  const replyChannel = {
68
104
  type: "lark-cli",
69
105
  appId: metadata.appId,
70
- chatId: metadata.chatId,
71
- messageId: metadata.messageId
106
+ chatId: messageData?.chat_id,
107
+ messageId: messageData?.message_id
72
108
  };
73
109
  return { metadata, replyChannel, recommendedAction };
74
110
  }
@@ -164,39 +200,107 @@ class LarkCliInstance {
164
200
  for (const pluginName of plugins) {
165
201
  const plugin = await this.importPlugin(pluginName);
166
202
  if (plugin) {
203
+ const hookPoints = this.getPluginHookPoints(plugin);
167
204
  this.registerPluginHooks(plugin);
168
205
  this.loadedPlugins.push({
169
206
  name: pluginName,
170
- hooks: plugin.hooks.map((h) => ({ point: h.point, name: `${pluginName}:${h.point}` }))
207
+ hooks: hookPoints.map((h) => ({ point: h, name: `${pluginName}:${h}` }))
171
208
  });
172
209
  }
173
210
  }
174
211
  }
212
+ getPluginHookPoints(plugin) {
213
+ if (Array.isArray(plugin.hooks)) {
214
+ return plugin.hooks.map((h) => h.point || h);
215
+ }
216
+ if (typeof plugin.execute === "function" && plugin.hookPoint) {
217
+ return [plugin.hookPoint];
218
+ }
219
+ if (plugin.name && typeof plugin.execute === "function") {
220
+ return ["task:after.create", "task:after.update"];
221
+ }
222
+ return [];
223
+ }
175
224
  async importPlugin(name) {
176
- const PLUGIN_PATHS = {
177
- "task-tag": "@ai-setting/roy-agent-core/env/task/plugins/task-tag-plugin"
178
- };
179
- const path = PLUGIN_PATHS[name] || name;
225
+ const factory = BUILT_IN_PLUGIN_FACTORIES[name];
226
+ if (!factory) {
227
+ console.error(`[LarkCliInstance] Unknown plugin: ${name}`);
228
+ return null;
229
+ }
180
230
  try {
181
- const module = await import(path);
182
- const PluginClass = module.TaskPlugin || module.default;
183
- return new PluginClass;
231
+ return factory({
232
+ sourceId: this.config.id,
233
+ pluginName: name
234
+ });
184
235
  } catch (error) {
185
- console.error(`[LarkCliInstance] Failed to load plugin ${name}:`, error);
236
+ console.error(`[LarkCliInstance] Failed to instantiate plugin ${name}:`, error);
186
237
  return null;
187
238
  }
188
239
  }
189
240
  registerPluginHooks(plugin) {
190
- for (const hook of plugin.hooks) {
191
- globalHookManager.register(hook.point, {
192
- name: `${plugin.name}:${hook.point}`,
193
- priority: hook.priority ?? 0,
194
- pluginName: plugin.name,
195
- sourceId: this.config.id,
196
- execute: async (ctx) => {
197
- await plugin.execute(ctx);
241
+ const pluginName = plugin.name || "unknown";
242
+ if (typeof plugin.init === "function") {
243
+ const pluginEnv = {
244
+ getComponent: () => null,
245
+ registerAgent: () => {},
246
+ registerTool: () => {},
247
+ registerHook: (hook) => {
248
+ globalHookManager.register(hook.point, {
249
+ name: `${pluginName}:${hook.point}`,
250
+ priority: hook.priority ?? 0,
251
+ pluginName,
252
+ sourceId: this.config.id,
253
+ execute: hook.handler
254
+ });
255
+ },
256
+ logger: {
257
+ debug: (...args) => console.debug(`[plugin:${pluginName}]`, ...args),
258
+ info: (...args) => console.info(`[plugin:${pluginName}]`, ...args),
259
+ warn: (...args) => console.warn(`[plugin:${pluginName}]`, ...args),
260
+ error: (...args) => console.error(`[plugin:${pluginName}]`, ...args)
198
261
  }
199
- });
262
+ };
263
+ plugin.init(pluginEnv);
264
+ return;
265
+ }
266
+ if (typeof plugin.execute === "function") {
267
+ if (plugin.hookPoint) {
268
+ globalHookManager.register(plugin.hookPoint, {
269
+ name: `${pluginName}:${plugin.hookPoint}`,
270
+ priority: plugin.priority ?? 0,
271
+ pluginName,
272
+ sourceId: this.config.id,
273
+ execute: plugin.execute
274
+ });
275
+ } else {
276
+ const hookPoints = this.getPluginHookPoints(plugin);
277
+ for (const hookPoint of hookPoints) {
278
+ globalHookManager.register(hookPoint, {
279
+ name: `${pluginName}:${hookPoint}`,
280
+ priority: plugin.priority ?? 0,
281
+ pluginName,
282
+ sourceId: this.config.id,
283
+ execute: plugin.execute.bind(plugin)
284
+ });
285
+ }
286
+ }
287
+ return;
288
+ }
289
+ if (Array.isArray(plugin.hooks)) {
290
+ for (const hook of plugin.hooks) {
291
+ const hookPoint = hook.point || hook;
292
+ const priority = hook.priority ?? 0;
293
+ globalHookManager.register(hookPoint, {
294
+ name: `${pluginName}:${hookPoint}`,
295
+ priority,
296
+ pluginName,
297
+ sourceId: this.config.id,
298
+ execute: async (ctx) => {
299
+ await plugin.execute(ctx);
300
+ }
301
+ });
302
+ }
303
+ return;
200
304
  }
201
305
  }
202
306
  unloadPlugins() {
@@ -219,6 +323,20 @@ class LarkCliInstance {
219
323
  }
220
324
  }
221
325
  handleEvent(rawData) {
326
+ const provider = getTracerProvider();
327
+ const tracer = provider.getTracer("roy-tracer");
328
+ const rootTraceId = generateTraceId();
329
+ const rootSpanId = tracer.generateSpanId();
330
+ const rootContext = {
331
+ traceId: rootTraceId,
332
+ spanId: rootSpanId,
333
+ parentSpanId: undefined
334
+ };
335
+ const rootSpan = tracer.startSpan("lark-cli.handleEvent", {
336
+ context: rootContext,
337
+ attributes: { rawData: rawData.substring(0, 500) }
338
+ });
339
+ provider.setGlobalContext(rootSpan.spanContext);
222
340
  try {
223
341
  let rawEvent;
224
342
  try {
@@ -246,6 +364,11 @@ class LarkCliInstance {
246
364
  recommendedAction
247
365
  });
248
366
  const timestamp = Date.now();
367
+ const plugins = this.config.handleRule?.plugins || [];
368
+ const pluginEnabled = {};
369
+ for (const pluginName of plugins) {
370
+ pluginEnabled[`${this.config.id}:${pluginName}`] = true;
371
+ }
249
372
  const evt = {
250
373
  id: `es-${this.config.id}-${timestamp}`,
251
374
  type: "event-source.event.lark-cli",
@@ -253,7 +376,10 @@ class LarkCliInstance {
253
376
  metadata: {
254
377
  source: "event-source",
255
378
  sourceId: this.config.id,
256
- sourceMessageType: eventType
379
+ sourceMessageType: eventType,
380
+ plugins,
381
+ pluginEnabled,
382
+ replyChannel
257
383
  },
258
384
  payload: {
259
385
  sourceId: this.config.id,
@@ -266,10 +392,114 @@ class LarkCliInstance {
266
392
  timestamp
267
393
  }
268
394
  };
269
- this.eventHandler?.(evt);
395
+ const userId = this.extractUserId(rawEvent);
396
+ const envReplyChannel = this.buildReplyChannel(replyChannel);
397
+ const envContext = createEnvContext({
398
+ envEvent: evt,
399
+ sourceId: this.config.id,
400
+ userId,
401
+ replyChannel: envReplyChannel,
402
+ pluginEnabled,
403
+ plugins
404
+ });
405
+ runWithEnvContext(envContext, () => {
406
+ this.eventHandler?.(evt);
407
+ });
270
408
  } catch (error) {
271
409
  console.error(`[LarkCliInstance] Error handling event: ${error}`);
410
+ rootSpan.setAttribute("error", String(error));
411
+ } finally {
412
+ rootSpan.end();
413
+ }
414
+ }
415
+ extractUserId(rawEvent) {
416
+ const event = rawEvent;
417
+ const innerEvent = event.event;
418
+ const message = innerEvent?.message || event.message;
419
+ const sender = innerEvent?.sender || event.sender || message?.sender;
420
+ const senderId = sender?.sender_id;
421
+ return senderId?.open_id || senderId?.user_id || senderId?.union_id || "unknown";
422
+ }
423
+ buildReplyChannel(replyChannel) {
424
+ if (!replyChannel || !replyChannel.chatId && !replyChannel.messageId) {
425
+ return;
272
426
  }
427
+ return {
428
+ type: replyChannel.type,
429
+ messageId: replyChannel.messageId,
430
+ chatId: replyChannel.chatId,
431
+ userId: replyChannel.params?.userId,
432
+ identity: "bot",
433
+ sendText: async (text) => {
434
+ await this.sendLarkMessage({
435
+ chatId: replyChannel.chatId,
436
+ userId: replyChannel.params?.userId,
437
+ content: text,
438
+ as: "bot"
439
+ });
440
+ },
441
+ sendMarkdown: async (markdown) => {
442
+ await this.sendLarkMessage({
443
+ chatId: replyChannel.chatId,
444
+ userId: replyChannel.params?.userId,
445
+ content: markdown,
446
+ as: "bot"
447
+ });
448
+ },
449
+ sendMessage: async (content) => {
450
+ await this.sendLarkMessage({
451
+ chatId: replyChannel.chatId,
452
+ userId: replyChannel.params?.userId,
453
+ content: JSON.stringify(content),
454
+ as: "bot"
455
+ });
456
+ },
457
+ reply: async (content) => {
458
+ if (replyChannel.messageId) {
459
+ await this.sendLarkMessage({
460
+ messageId: replyChannel.messageId,
461
+ content: JSON.stringify(content),
462
+ as: "bot"
463
+ });
464
+ }
465
+ }
466
+ };
467
+ }
468
+ async sendLarkMessage(options) {
469
+ return new Promise((resolve, reject) => {
470
+ const { chatId, userId, messageId, content, as: identity } = options;
471
+ const args = ["im", "+messages-send", "--as", identity];
472
+ if (messageId) {
473
+ args.push("+messages-reply", "--message-id", messageId, "--text", content);
474
+ } else if (chatId) {
475
+ args.push("--chat-id", chatId, "--text", content);
476
+ } else if (userId) {
477
+ args.push("--user-id", userId, "--text", content);
478
+ } else {
479
+ reject(new Error("No target specified for sending message"));
480
+ return;
481
+ }
482
+ const proc = spawn("lark-cli", args, {
483
+ shell: false,
484
+ stdio: ["pipe", "pipe", "pipe"]
485
+ });
486
+ let stdout = "";
487
+ let stderr = "";
488
+ proc.stdout?.on("data", (data) => {
489
+ stdout += data.toString();
490
+ });
491
+ proc.stderr?.on("data", (data) => {
492
+ stderr += data.toString();
493
+ });
494
+ proc.on("close", (code) => {
495
+ if (code === 0) {
496
+ resolve();
497
+ } else {
498
+ reject(new Error(`lark-cli exited with code ${code}: ${stderr}`));
499
+ }
500
+ });
501
+ proc.on("error", reject);
502
+ });
273
503
  }
274
504
  }
275
505
  var larkCliHandler = {
@@ -1,13 +1,4 @@
1
- import {
2
- TracedAs,
3
- init_decorator
4
- } from "./roy-agent-core-zgypchmt.js";
5
- import {
6
- __legacyDecorateClassTS
7
- } from "./roy-agent-core-fs0mn2jk.js";
8
-
9
1
  // src/env/session/session-message-converter.ts
10
- init_decorator();
11
2
  import { randomUUID } from "crypto";
12
3
  var DEFAULT_REASONING_BUDGET_TOKENS = 1e4;
13
4
 
@@ -194,11 +185,5 @@ class SessionMessageConverter {
194
185
  };
195
186
  }
196
187
  }
197
- __legacyDecorateClassTS([
198
- TracedAs("session-message-converter.toModelMessage", { recordParams: true, recordResult: true, log: true })
199
- ], SessionMessageConverter.prototype, "toModelMessage", null);
200
- __legacyDecorateClassTS([
201
- TracedAs("session-message-converter.fromModelMessage", { recordParams: true, recordResult: true, log: true })
202
- ], SessionMessageConverter.prototype, "fromModelMessage", null);
203
188
 
204
189
  export { SessionMessageConverter };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getDatabase
3
- } from "./roy-agent-core-zpn0bqa8.js";
3
+ } from "./roy-agent-core-9ffsvvcf.js";
4
4
  import {
5
5
  exports_search_query_parser,
6
6
  init_search_query_parser
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createLogger,
3
3
  init_logger
4
- } from "./roy-agent-core-44hnfb02.js";
4
+ } from "./roy-agent-core-10n2jh7p.js";
5
5
  import {
6
6
  __require
7
7
  } from "./roy-agent-core-fs0mn2jk.js";
@@ -0,0 +1,11 @@
1
+ // src/env/plugin/types.ts
2
+ class BasePlugin {
3
+ version = "1.0.0";
4
+ description;
5
+ priority = 0;
6
+ constructor() {}
7
+ init(env) {}
8
+ dispose() {}
9
+ }
10
+
11
+ export { BasePlugin };