@ai-setting/roy-agent-core 1.7.53 → 1.7.56

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 (124) hide show
  1. package/dist/config/index.js +7 -7
  2. package/dist/env/agent/agent-component.d.ts +30 -0
  3. package/dist/env/agent/index.js +13 -12
  4. package/dist/env/commands/index.js +7 -7
  5. package/dist/env/context/index.js +3 -3
  6. package/dist/env/debug/index.js +7 -7
  7. package/dist/env/environment.d.ts +7 -0
  8. package/dist/env/error-reply.d.ts +184 -0
  9. package/dist/env/event-source/event-source-handlers.d.ts +9 -23
  10. package/dist/env/event-source/index.js +17 -17
  11. package/dist/env/hook/index.js +5 -5
  12. package/dist/env/index.js +41 -40
  13. package/dist/env/llm/adapter-ai-sdk.d.ts +6 -0
  14. package/dist/env/llm/adapter-pi-ai.d.ts +152 -2
  15. package/dist/env/llm/adapter.d.ts +21 -1
  16. package/dist/env/llm/index.js +10 -10
  17. package/dist/env/llm/invoke.d.ts +74 -2
  18. package/dist/env/llm/llm.d.ts +38 -0
  19. package/dist/env/llm/outbound-defense.d.ts +140 -0
  20. package/dist/env/llm/reasoning-defense.d.ts +104 -0
  21. package/dist/env/llm/types.d.ts +26 -0
  22. package/dist/env/log-trace/decorator.d.ts +46 -3
  23. package/dist/env/log-trace/index.d.ts +1 -0
  24. package/dist/env/log-trace/index.js +33 -7
  25. package/dist/env/log-trace/trace-filters.d.ts +127 -0
  26. package/dist/env/mcp/index.js +7 -7
  27. package/dist/env/memory/index.js +7 -7
  28. package/dist/env/plugin/index.js +7 -7
  29. package/dist/env/prompt/index.js +8 -8
  30. package/dist/env/prompt/prompts-index.d.ts +1 -1
  31. package/dist/env/session/index.js +11 -10
  32. package/dist/env/session/session-component.d.ts +4 -0
  33. package/dist/env/session/storage/index.js +5 -3
  34. package/dist/env/skill/index.js +7 -7
  35. package/dist/env/task/backend/index.js +0 -2
  36. package/dist/env/task/backend/types.d.ts +0 -11
  37. package/dist/env/task/delegate/index.js +8 -8
  38. package/dist/env/task/index.js +13 -13
  39. package/dist/env/task/plugins/card-chat-routing.d.ts +42 -89
  40. package/dist/env/task/plugins/index.js +10 -10
  41. package/dist/env/task/plugins/lark-card-patch-notifier.d.ts +0 -51
  42. package/dist/env/task/plugins/lark-cli-task-notify-plugin.d.ts +14 -31
  43. package/dist/env/task/plugins/per-task-group-chat-plugin.d.ts +4 -4
  44. package/dist/env/task/storage/index.js +2 -2
  45. package/dist/env/task/tools/index.js +3 -3
  46. package/dist/env/tool/built-in/index.js +3 -3
  47. package/dist/env/tool/index.js +9 -9
  48. package/dist/env/workflow/engine/engine.d.ts +65 -0
  49. package/dist/env/workflow/engine/index.js +12 -12
  50. package/dist/env/workflow/hooks/index.js +7 -7
  51. package/dist/env/workflow/index.js +23 -22
  52. package/dist/env/workflow/nodes/index.js +2 -2
  53. package/dist/env/workflow/nodes/tool-node.d.ts +6 -0
  54. package/dist/env/workflow/plugins/index.js +8 -8
  55. package/dist/env/workflow/service/index.js +2 -2
  56. package/dist/env/workflow/storage/index.js +3 -3
  57. package/dist/env/workflow/tools/index.js +15 -14
  58. package/dist/env/workflow/tools/workflow-validate-tool.d.ts +11 -2
  59. package/dist/env/workflow/types/run.d.ts +19 -0
  60. package/dist/env/workflow/utils/agent-session-metadata.d.ts +13 -0
  61. package/dist/env/workflow/utils/index.js +5 -5
  62. package/dist/env/workflow/utils/redact-command-secrets.d.ts +70 -0
  63. package/dist/env/workflow/utils/shell-dialect-lint.d.ts +75 -0
  64. package/dist/env/workflow/utils/validate-workflow-definition.d.ts +22 -0
  65. package/dist/index.d.ts +1 -1
  66. package/dist/index.js +82 -56
  67. package/dist/shared/@ai-setting/{roy-agent-core-k25gv86p.js → roy-agent-core-0b3fdnn3.js} +1 -1
  68. package/dist/shared/@ai-setting/{roy-agent-core-vvxb9522.js → roy-agent-core-0bmk44ye.js} +71 -10
  69. package/dist/shared/@ai-setting/{roy-agent-core-k8b440n3.js → roy-agent-core-16t0zfbk.js} +1 -1
  70. package/dist/shared/@ai-setting/{roy-agent-core-4z3rq5gw.js → roy-agent-core-1pnfkspm.js} +2 -2
  71. package/dist/shared/@ai-setting/{roy-agent-core-na73mym1.js → roy-agent-core-202v00x4.js} +213 -2
  72. package/dist/shared/@ai-setting/{roy-agent-core-ph5qbqcx.js → roy-agent-core-2044fbsd.js} +471 -134
  73. package/dist/shared/@ai-setting/{roy-agent-core-fs36xgcs.js → roy-agent-core-3dkzqqsd.js} +1 -1
  74. package/dist/shared/@ai-setting/{roy-agent-core-qm9jda8p.js → roy-agent-core-3kz6934b.js} +1 -1
  75. package/dist/shared/@ai-setting/{roy-agent-core-tjg71zqp.js → roy-agent-core-3mc6vmvj.js} +1 -1
  76. package/dist/shared/@ai-setting/{roy-agent-core-tdbv7ff4.js → roy-agent-core-40xzbjtm.js} +2 -2
  77. package/dist/shared/@ai-setting/{roy-agent-core-athdr2m0.js → roy-agent-core-4zy2v3br.js} +10 -2
  78. package/dist/shared/@ai-setting/{roy-agent-core-t37wbysj.js → roy-agent-core-5gw6w424.js} +4 -4
  79. package/dist/shared/@ai-setting/{roy-agent-core-978b6wfx.js → roy-agent-core-5psjwd08.js} +1 -1
  80. package/dist/shared/@ai-setting/{roy-agent-core-7evvpfwc.js → roy-agent-core-5rxs0ra3.js} +1 -1
  81. package/dist/shared/@ai-setting/{roy-agent-core-gdsqp6j8.js → roy-agent-core-6masakz4.js} +45 -0
  82. package/dist/shared/@ai-setting/{roy-agent-core-stnddvx9.js → roy-agent-core-6qgq7h1g.js} +4 -4
  83. package/dist/shared/@ai-setting/{roy-agent-core-6167phd4.js → roy-agent-core-833t16n1.js} +3 -3
  84. package/dist/shared/@ai-setting/{roy-agent-core-2k4xffaa.js → roy-agent-core-8cgtwytv.js} +3 -3
  85. package/dist/shared/@ai-setting/{roy-agent-core-rx16h2m1.js → roy-agent-core-97eyghsp.js} +2 -2
  86. package/dist/shared/@ai-setting/{roy-agent-core-fvs48d38.js → roy-agent-core-98aa9r0x.js} +12 -7
  87. package/dist/shared/@ai-setting/{roy-agent-core-3tv1q6f2.js → roy-agent-core-9nv586rw.js} +57 -19
  88. package/dist/shared/@ai-setting/roy-agent-core-b599jgyd.js +578 -0
  89. package/dist/shared/@ai-setting/{roy-agent-core-yd21n6c7.js → roy-agent-core-bwzy00t2.js} +12 -5
  90. package/dist/shared/@ai-setting/{roy-agent-core-dwx9hjwx.js → roy-agent-core-c6at31ra.js} +1 -1
  91. package/dist/shared/@ai-setting/{roy-agent-core-1cv9j4dg.js → roy-agent-core-d14h726p.js} +3 -3
  92. package/dist/shared/@ai-setting/{roy-agent-core-4sx6sdb2.js → roy-agent-core-d4jpn06f.js} +22 -9
  93. package/dist/shared/@ai-setting/{roy-agent-core-39xejr39.js → roy-agent-core-e0wbq0qq.js} +7 -7
  94. package/dist/shared/@ai-setting/{roy-agent-core-vrsxhw9e.js → roy-agent-core-e677am8e.js} +1 -1
  95. package/dist/shared/@ai-setting/{roy-agent-core-hch2geta.js → roy-agent-core-ezsyyjxw.js} +21 -190
  96. package/dist/shared/@ai-setting/{roy-agent-core-ne2t1pay.js → roy-agent-core-f8sp1txg.js} +2 -2
  97. package/dist/shared/@ai-setting/{roy-agent-core-ak4dc3kg.js → roy-agent-core-gn8f4rhs.js} +1 -1
  98. package/dist/shared/@ai-setting/{roy-agent-core-qcspfszy.js → roy-agent-core-gngjkw3b.js} +1 -1
  99. package/dist/shared/@ai-setting/{roy-agent-core-9jzysq50.js → roy-agent-core-heft3j4c.js} +2 -2
  100. package/dist/shared/@ai-setting/{roy-agent-core-5apmk4qw.js → roy-agent-core-jszgaevt.js} +1 -1
  101. package/dist/shared/@ai-setting/{roy-agent-core-nde5gzta.js → roy-agent-core-m8n0dffe.js} +1 -1
  102. package/dist/shared/@ai-setting/{roy-agent-core-x8n1r7h4.js → roy-agent-core-n3b7ztms.js} +189 -8
  103. package/dist/shared/@ai-setting/{roy-agent-core-4vpk40ss.js → roy-agent-core-nhk0dsxr.js} +13 -13
  104. package/dist/shared/@ai-setting/{roy-agent-core-j8e92gj8.js → roy-agent-core-nntphgww.js} +1 -60
  105. package/dist/shared/@ai-setting/{roy-agent-core-8s9jd2qy.js → roy-agent-core-nra8vfrs.js} +1 -1
  106. package/dist/shared/@ai-setting/{roy-agent-core-pk1b3kvf.js → roy-agent-core-ns3pbyz4.js} +1 -1
  107. package/dist/shared/@ai-setting/{roy-agent-core-7g03zkkb.js → roy-agent-core-pemxr5n4.js} +1 -1
  108. package/dist/shared/@ai-setting/{roy-agent-core-skzjs973.js → roy-agent-core-pjxa78mp.js} +5 -5
  109. package/dist/shared/@ai-setting/{roy-agent-core-p8ak03s0.js → roy-agent-core-q7zksbw0.js} +117 -315
  110. package/dist/shared/@ai-setting/{roy-agent-core-zd3ddm4k.js → roy-agent-core-qjjf4tjb.js} +1 -1
  111. package/dist/shared/@ai-setting/{roy-agent-core-qamktze3.js → roy-agent-core-qyqnmz8c.js} +1 -1
  112. package/dist/shared/@ai-setting/{roy-agent-core-9csa89jx.js → roy-agent-core-r9qe0ghe.js} +2 -2
  113. package/dist/shared/@ai-setting/{roy-agent-core-h93v6p6y.js → roy-agent-core-tc7gw38m.js} +2 -2
  114. package/dist/shared/@ai-setting/{roy-agent-core-35s1w7tc.js → roy-agent-core-v2188rnk.js} +157 -85
  115. package/dist/shared/@ai-setting/{roy-agent-core-p2r27era.js → roy-agent-core-vmg30n5x.js} +8 -8
  116. package/dist/shared/@ai-setting/{roy-agent-core-rnwr39b0.js → roy-agent-core-w7hnjhvx.js} +5 -3
  117. package/dist/shared/@ai-setting/{roy-agent-core-dv714bqh.js → roy-agent-core-wafk25ff.js} +1 -1
  118. package/dist/shared/@ai-setting/{roy-agent-core-brwzs8wf.js → roy-agent-core-xcq04fq0.js} +5 -5
  119. package/dist/shared/@ai-setting/{roy-agent-core-2gay3sjt.js → roy-agent-core-yg247mk4.js} +1 -1
  120. package/dist/shared/@ai-setting/{roy-agent-core-zy3hqfwg.js → roy-agent-core-yv9x4wmg.js} +631 -35
  121. package/dist/shared/@ai-setting/{roy-agent-core-yhsssn86.js → roy-agent-core-zmeka63k.js} +1 -1
  122. package/dist/test-utils/child-process-mock.d.ts +73 -0
  123. package/package.json +2 -2
  124. package/dist/shared/@ai-setting/roy-agent-core-dsevjbck.js +0 -245
@@ -3,14 +3,10 @@ import {
3
3
  parseJSONC
4
4
  } from "./roy-agent-core-adg9ghbt.js";
5
5
  import {
6
- sniffImageMime
7
- } from "./roy-agent-core-zjdzk1gg.js";
8
- import {
9
- buildOpencodeHeaders,
6
+ PiAiAdapter,
10
7
  invoke,
11
- invokeNonStream,
12
- toolParametersToJsonSchema
13
- } from "./roy-agent-core-zy3hqfwg.js";
8
+ invokeNonStream
9
+ } from "./roy-agent-core-yv9x4wmg.js";
14
10
  import {
15
11
  ContextError,
16
12
  ErrorCodes
@@ -21,17 +17,22 @@ import {
21
17
  } from "./roy-agent-core-7hh0brvs.js";
22
18
  import {
23
19
  BaseComponent
24
- } from "./roy-agent-core-tdbv7ff4.js";
20
+ } from "./roy-agent-core-40xzbjtm.js";
25
21
  import {
26
22
  LLMHookPoints,
27
23
  globalHookManager,
28
24
  init_global_hook_manager
29
- } from "./roy-agent-core-4z3rq5gw.js";
25
+ } from "./roy-agent-core-1pnfkspm.js";
30
26
  import {
31
27
  TracedAs,
28
+ embedParamFilter,
29
+ embedResultFilter,
32
30
  init_decorator,
31
+ init_trace_filters,
32
+ llmInvokeParamFilter,
33
+ llmInvokeResultFilter,
33
34
  wrapFunction
34
- } from "./roy-agent-core-dsevjbck.js";
35
+ } from "./roy-agent-core-b599jgyd.js";
35
36
  import {
36
37
  createLogger,
37
38
  init_logger
@@ -43,287 +44,9 @@ import {
43
44
 
44
45
  // src/env/llm/adapter.ts
45
46
  var ADAPTER_NAMES = ["pi-ai", "ai-sdk"];
46
- // src/env/llm/adapter-pi-ai.ts
47
- init_decorator();
48
- init_logger();
49
- import {
50
- complete,
51
- stream as piStream,
52
- getModel
53
- } from "@earendil-works/pi-ai";
54
- var logger = createLogger("llm:adapter-pi-ai");
55
- var KNOWN_PROVIDER_APIS = {
56
- anthropic: { api: "anthropic-messages", contextLimit: 200000, maxTokensLimit: 8192 },
57
- openai: { api: "openai-responses", contextLimit: 128000, maxTokensLimit: 16384 },
58
- google: { api: "google-generative-ai", contextLimit: 1e6, maxTokensLimit: 8192 },
59
- "google-vertex": { api: "google-vertex", contextLimit: 1e6, maxTokensLimit: 8192 },
60
- deepseek: { api: "openai-completions", contextLimit: 64000, maxTokensLimit: 8192 },
61
- xai: { api: "openai-completions", contextLimit: 131072, maxTokensLimit: 8192 },
62
- groq: { api: "openai-completions", contextLimit: 32768, maxTokensLimit: 8192 },
63
- minimax: { api: "openai-completions", contextLimit: 128000, maxTokensLimit: 8192 },
64
- "minimax-cn": { api: "openai-completions", contextLimit: 128000, maxTokensLimit: 8192 },
65
- moonshotai: { api: "openai-completions", contextLimit: 128000, maxTokensLimit: 8192 },
66
- "kimi-coding": { api: "openai-completions", contextLimit: 128000, maxTokensLimit: 8192 }
67
- };
68
- function resolvePiModel(provider, modelId, baseURL) {
69
- const builtIn = getModel(provider, modelId);
70
- if (builtIn)
71
- return baseURL ? { ...builtIn, baseUrl: baseURL } : builtIn;
72
- const providerApiOverride = {
73
- "minimax-responses": "openai-responses",
74
- "minimax-openai": "openai-completions"
75
- };
76
- let configuredApi;
77
- if (providerApiOverride[provider]) {
78
- configuredApi = providerApiOverride[provider];
79
- } else if (provider === "minimax" || provider === "minimax-cn") {
80
- configuredApi = baseURL?.includes("anthropic") ? "anthropic-messages" : "openai-completions";
81
- } else if (baseURL?.includes("/responses")) {
82
- configuredApi = "openai-responses";
83
- } else if (baseURL?.includes("anthropic")) {
84
- configuredApi = "anthropic-messages";
85
- } else {
86
- configuredApi = KNOWN_PROVIDER_APIS[provider]?.api || "openai-completions";
87
- }
88
- return {
89
- id: modelId,
90
- name: modelId,
91
- api: configuredApi,
92
- provider,
93
- baseUrl: baseURL || "",
94
- reasoning: false,
95
- input: ["text", "image"],
96
- cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
97
- contextWindow: KNOWN_PROVIDER_APIS[provider]?.contextLimit || 128000,
98
- maxTokens: KNOWN_PROVIDER_APIS[provider]?.maxTokensLimit || 8192
99
- };
100
- }
101
- function toPiMessages(messages) {
102
- const out = [];
103
- const ts = Date.now();
104
- for (const m of messages) {
105
- if (m.role === "system")
106
- continue;
107
- if (m.role === "user") {
108
- if (typeof m.content === "string") {
109
- out.push({ role: "user", content: m.content, timestamp: ts });
110
- } else {
111
- out.push({ role: "user", content: m.content.flatMap((c) => {
112
- if (c.type === "text")
113
- return [{ type: "text", text: c.text }];
114
- if (c.type === "image")
115
- return [{ type: "image", data: c.image instanceof Uint8Array ? Buffer.from(c.image).toString("base64") : c.image, mimeType: sniffImageMime(c.image, c.mediaType) }];
116
- return [{ type: "text", text: `[file:${c.mediaType}] ${typeof c.file === "string" ? c.file : Buffer.from(c.file).toString("base64")}` }];
117
- }), timestamp: ts });
118
- }
119
- continue;
120
- }
121
- if (m.role === "tool") {
122
- out.push({ role: "toolResult", toolCallId: m.toolCallId || "", toolName: m.name || "", content: [{ type: "text", text: typeof m.content === "string" ? m.content : JSON.stringify(m.content) }], isError: false, timestamp: ts });
123
- continue;
124
- }
125
- const content = [];
126
- if (typeof m.content === "string" && m.content)
127
- content.push({ type: "text", text: m.content });
128
- else if (Array.isArray(m.content))
129
- for (const c of m.content) {
130
- if (c.type === "text")
131
- content.push({ type: "text", text: c.text });
132
- else if (c.type === "image")
133
- content.push({ type: "image", data: c.image instanceof Uint8Array ? Buffer.from(c.image).toString("base64") : c.image, mimeType: sniffImageMime(c.image, c.mediaType) });
134
- else
135
- content.push({ type: "text", text: `[file:${c.mediaType}] ${typeof c.file === "string" ? c.file : Buffer.from(c.file).toString("base64")}` });
136
- }
137
- for (const tc of m.toolCalls || [])
138
- content.push({ type: "toolCall", id: tc.id, name: tc.name, arguments: safeJson(tc.arguments) });
139
- out.push({ role: "assistant", content, api: "openai-completions", model: "", provider: "", usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, totalTokens: 0, cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 } }, stopReason: "stop", timestamp: ts });
140
- }
141
- return out;
142
- }
143
- function extractSystemPrompt(messages) {
144
- const prompts = messages.filter((m) => m.role === "system").map((m) => typeof m.content === "string" ? m.content : m.content.filter((c) => c.type === "text").map((c) => c.text).join(""));
145
- return prompts.length ? prompts.join(`
146
-
147
- `) : undefined;
148
- }
149
- function safeJson(s) {
150
- try {
151
- return JSON.parse(s);
152
- } catch (e) {
153
- logger.warn(`[safeJson] JSON.parse failed`, {
154
- parse_failed: true,
155
- input_length: s.length,
156
- error: e.message
157
- });
158
- return {};
159
- }
160
- }
161
- function convertToolParameters(parameters) {
162
- return toolParametersToJsonSchema(parameters);
163
- }
164
- function toPiTools(tools) {
165
- if (!tools)
166
- return;
167
- return tools.map((t) => ({
168
- name: t.name,
169
- description: t.description || "",
170
- parameters: convertToolParameters(t.parameters)
171
- }));
172
- }
173
- function piRequestExtras(req) {
174
- const headers = buildOpencodeHeaders(req.provider, req.sessionId, req.baseURL);
175
- return Object.keys(headers).length > 0 ? { headers } : {};
176
- }
177
- function fromAssistantMessage(msg) {
178
- let text = "";
179
- const toolCalls = [];
180
- for (const block of msg.content) {
181
- const b = block;
182
- if (b.type === "text") {
183
- text += b.text || "";
184
- } else if (b.type === "toolCall") {
185
- toolCalls.push({
186
- id: b.id || "",
187
- name: b.name || "",
188
- arguments: typeof b.arguments === "string" ? b.arguments : JSON.stringify(b.arguments ?? {})
189
- });
190
- }
191
- }
192
- return {
193
- text,
194
- finishReason: msg.stopReason || "stop",
195
- toolCalls: toolCalls.length ? toolCalls : undefined,
196
- usage: {
197
- promptTokens: msg.usage?.input ?? 0,
198
- completionTokens: msg.usage?.output ?? 0,
199
- totalTokens: msg.usage?.totalTokens ?? 0,
200
- cacheRead: msg.usage?.cacheRead,
201
- cacheWrite: msg.usage?.cacheWrite
202
- },
203
- raw: msg
204
- };
205
- }
206
-
207
- class EmbeddingNotSupportedError extends Error {
208
- constructor(adapter) {
209
- super(`Embedding is not supported by ${adapter}; use AiSdkAdapter.embed() or apply at higher layer.`);
210
- this.name = "EmbeddingNotSupportedError";
211
- }
212
- }
213
-
214
- class PiAiAdapter {
215
- name = "pi-ai";
216
- async chat(req) {
217
- const model = resolvePiModel(req.provider, req.modelId, req.baseURL);
218
- const ctx = {
219
- systemPrompt: [req.systemPrompt, extractSystemPrompt(req.messages)].filter(Boolean).join(`
220
-
221
- `) || undefined,
222
- messages: toPiMessages(req.messages),
223
- tools: toPiTools(req.tools)
224
- };
225
- const msg = await complete(model, ctx, {
226
- apiKey: req.apiKey,
227
- baseURL: req.baseURL,
228
- temperature: req.temperature,
229
- maxTokens: req.maxTokens,
230
- signal: req.signal,
231
- ...piRequestExtras(req)
232
- });
233
- return fromAssistantMessage(msg);
234
- }
235
- async stream(req) {
236
- const model = resolvePiModel(req.provider, req.modelId, req.baseURL);
237
- const ctx = {
238
- systemPrompt: [req.systemPrompt, extractSystemPrompt(req.messages)].filter(Boolean).join(`
239
-
240
- `) || undefined,
241
- messages: toPiMessages(req.messages),
242
- tools: toPiTools(req.tools)
243
- };
244
- const eventStream = piStream(model, ctx, { apiKey: req.apiKey, baseURL: req.baseURL, temperature: req.temperature, maxTokens: req.maxTokens, signal: req.signal, ...piRequestExtras(req) });
245
- return { events: eventStream, result: async () => fromAssistantMessage(await eventStream.result()) };
246
- }
247
- async embed(_req) {
248
- throw new EmbeddingNotSupportedError(this.name);
249
- }
250
- async resolveProvider(provider, modelId) {
251
- const model = resolvePiModel(provider, modelId);
252
- const caps = KNOWN_PROVIDER_APIS[provider] || {
253
- api: model.api,
254
- contextLimit: model.contextWindow,
255
- maxTokensLimit: model.maxTokens
256
- };
257
- return {
258
- api: model.api,
259
- provider,
260
- modelId,
261
- contextLimit: caps.contextLimit,
262
- maxTokensLimit: caps.maxTokensLimit
263
- };
264
- }
265
- }
266
- __legacyDecorateClassTS([
267
- TracedAs("llm.adapter.chat", {
268
- recordParams: true,
269
- recordResult: true,
270
- log: true,
271
- paramFilter: (args) => {
272
- const req = args[0];
273
- return {
274
- provider: req?.provider,
275
- model_id: req?.modelId,
276
- messages_count: req?.messages?.length,
277
- tools_count: req?.tools?.length,
278
- temperature: req?.temperature,
279
- max_tokens: req?.maxTokens
280
- };
281
- },
282
- resultFilter: (r) => ({
283
- finish_reason: r?.finishReason,
284
- usage_input: r?.usage?.promptTokens,
285
- usage_output: r?.usage?.completionTokens,
286
- usage_total: r?.usage?.totalTokens,
287
- content_length: r?.text?.length
288
- })
289
- })
290
- ], PiAiAdapter.prototype, "chat", null);
291
- __legacyDecorateClassTS([
292
- TracedAs("llm.adapter.stream", {
293
- recordParams: true,
294
- recordResult: false,
295
- log: true,
296
- paramFilter: (args) => {
297
- const req = args[0];
298
- return {
299
- provider: req?.provider,
300
- model_id: req?.modelId,
301
- messages_count: req?.messages?.length
302
- };
303
- }
304
- })
305
- ], PiAiAdapter.prototype, "stream", null);
306
- __legacyDecorateClassTS([
307
- TracedAs("llm.adapter.embed", { recordParams: true, recordResult: false, log: true })
308
- ], PiAiAdapter.prototype, "embed", null);
309
- __legacyDecorateClassTS([
310
- TracedAs("llm.adapter.resolve_provider", {
311
- recordParams: true,
312
- recordResult: true,
313
- log: true,
314
- paramFilter: (args) => ({
315
- provider: args[0],
316
- model_id: args[1]
317
- }),
318
- resultFilter: (r) => ({
319
- api: r?.api,
320
- context_limit: r?.contextLimit,
321
- max_tokens_limit: r?.maxTokensLimit
322
- })
323
- })
324
- ], PiAiAdapter.prototype, "resolveProvider", null);
325
47
  // src/env/llm/adapter-ai-sdk.ts
326
48
  init_decorator();
49
+ init_trace_filters();
327
50
  import { embed as aiEmbed, embedMany as aiEmbedMany } from "ai";
328
51
  class AiSdkAdapter {
329
52
  name = "ai-sdk";
@@ -431,7 +154,12 @@ __legacyDecorateClassTS([
431
154
  })
432
155
  ], AiSdkAdapter.prototype, "stream", null);
433
156
  __legacyDecorateClassTS([
434
- TracedAs("llm.adapter.ai_sdk.embed", { recordParams: true, recordResult: true, log: true })
157
+ TracedAs("llm.adapter.ai_sdk.embed", {
158
+ paramFilter: embedParamFilter,
159
+ resultFilter: embedResultFilter,
160
+ recordResult: false,
161
+ log: true
162
+ })
435
163
  ], AiSdkAdapter.prototype, "embed", null);
436
164
  __legacyDecorateClassTS([
437
165
  TracedAs("llm.adapter.ai_sdk.resolve_provider", {
@@ -888,11 +616,45 @@ class LLMHooks {
888
616
  // src/env/llm/llm.ts
889
617
  init_logger();
890
618
  init_decorator();
619
+ init_trace_filters();
891
620
  import { randomUUID } from "crypto";
892
621
  import * as fs from "node:fs/promises";
893
622
  import * as os from "node:os";
894
623
  import * as path from "node:path";
895
- var logger2 = createLogger("llm");
624
+ var logger = createLogger("llm");
625
+ function normalizeUsage(usage) {
626
+ if (!usage)
627
+ return;
628
+ const normalized = {
629
+ promptTokens: usage.promptTokens ?? 0,
630
+ completionTokens: usage.completionTokens ?? 0,
631
+ totalTokens: usage.totalTokens ?? 0
632
+ };
633
+ if (usage.cacheRead !== undefined)
634
+ normalized.cacheRead = usage.cacheRead;
635
+ if (usage.cacheWrite !== undefined)
636
+ normalized.cacheWrite = usage.cacheWrite;
637
+ if (usage.cacheMiss !== undefined)
638
+ normalized.cacheMiss = usage.cacheMiss;
639
+ if (usage.cacheRead !== undefined || usage.cacheWrite !== undefined) {
640
+ const reads = usage.cacheRead ?? 0;
641
+ const writes = usage.cacheWrite ?? 0;
642
+ const cacheSum = reads + writes;
643
+ const prompt = usage.promptTokens ?? 0;
644
+ const completion = usage.completionTokens ?? 0;
645
+ const nonCachedTotal = prompt + completion + cacheSum;
646
+ const aiSdkTotal = prompt + completion;
647
+ const isPiAiShape = Math.abs(usage.totalTokens - nonCachedTotal) <= 1;
648
+ if (isPiAiShape) {
649
+ normalized.promptTokensTotal = prompt + cacheSum;
650
+ } else if (Math.abs(usage.totalTokens - aiSdkTotal) <= 1) {
651
+ normalized.promptTokensTotal = Math.max(prompt, cacheSum);
652
+ } else {
653
+ normalized.promptTokensTotal = Math.max(prompt, cacheSum);
654
+ }
655
+ }
656
+ return normalized;
657
+ }
896
658
  async function resolveFallbackProviderConfig(providerId) {
897
659
  const home = os.homedir();
898
660
  const authPath = path.join(home, ".roy-agent", "auth.json");
@@ -929,6 +691,7 @@ class LLMComponent extends BaseComponent {
929
691
  configWatcher;
930
692
  cachedAdapter;
931
693
  cachedAdapterProvider;
694
+ adapterOverride;
932
695
  constructor() {
933
696
  super();
934
697
  }
@@ -1034,7 +797,7 @@ class LLMComponent extends BaseComponent {
1034
797
  componentName: "llm",
1035
798
  knownKeys,
1036
799
  logger: {
1037
- warn: (msg) => logger2.warn(msg)
800
+ warn: (msg) => logger.warn(msg)
1038
801
  }
1039
802
  });
1040
803
  }
@@ -1068,24 +831,24 @@ class LLMComponent extends BaseComponent {
1068
831
  }
1069
832
  registerConfigWatcher(configComponent) {
1070
833
  if (typeof configComponent.watch !== "function") {
1071
- logger2.debug("ConfigComponent does not support watch, hot reload disabled");
834
+ logger.debug("ConfigComponent does not support watch, hot reload disabled");
1072
835
  return;
1073
836
  }
1074
837
  this.configWatcher = configComponent.watch("llm.*", (event) => {
1075
838
  this.onConfigChange(event);
1076
839
  });
1077
- logger2.debug("Config hot reload watcher registered for llm.*");
840
+ logger.debug("Config hot reload watcher registered for llm.*");
1078
841
  }
1079
842
  onConfigChange(event) {
1080
- logger2.info(`LLM config changed: ${event.key}`);
843
+ logger.info(`LLM config changed: ${event.key}`);
1081
844
  if (event.key === "llm.providers" || event.key.startsWith("llm.providers.")) {
1082
- logger2.info(`LLM provider config changed, will use new config on next call`);
845
+ logger.info(`LLM provider config changed, will use new config on next call`);
1083
846
  } else if (event.key === "llm.defaultModel") {
1084
- logger2.info(`LLM default model changed to: ${event.newValue}`);
847
+ logger.info(`LLM default model changed to: ${event.newValue}`);
1085
848
  } else if (event.key === "llm.defaultProvider") {
1086
- logger2.info(`LLM default provider changed to: ${event.newValue}`);
849
+ logger.info(`LLM default provider changed to: ${event.newValue}`);
1087
850
  } else {
1088
- logger2.debug(`LLM config updated: ${event.key}`);
851
+ logger.debug(`LLM config updated: ${event.key}`);
1089
852
  }
1090
853
  }
1091
854
  async onStart() {
@@ -1146,6 +909,7 @@ class LLMComponent extends BaseComponent {
1146
909
  model: `${providerId}/${model}`,
1147
910
  apiKey,
1148
911
  baseURL: provider?.baseURL,
912
+ ...capabilities ? { capabilities } : {},
1149
913
  ...effectiveThinkingInText?.enabled ? {
1150
914
  options: {
1151
915
  thinkingInText: {
@@ -1164,6 +928,8 @@ class LLMComponent extends BaseComponent {
1164
928
  };
1165
929
  }
1166
930
  getAdapter() {
931
+ if (this.adapterOverride)
932
+ return this.adapterOverride;
1167
933
  const currentProvider = process.env.ROY_LLM_PROVIDER || "pi-ai";
1168
934
  if (this.cachedAdapter && this.cachedAdapterProvider === currentProvider) {
1169
935
  return this.cachedAdapter;
@@ -1172,6 +938,9 @@ class LLMComponent extends BaseComponent {
1172
938
  this.cachedAdapterProvider = currentProvider;
1173
939
  return this.cachedAdapter;
1174
940
  }
941
+ __setAdapterForTest(adapter) {
942
+ this.adapterOverride = adapter;
943
+ }
1175
944
  invalidateAdapterCache() {
1176
945
  this.cachedAdapter = undefined;
1177
946
  this.cachedAdapterProvider = undefined;
@@ -1194,7 +963,9 @@ class LLMComponent extends BaseComponent {
1194
963
  apiKey: ctx.invokeConfig.apiKey || "",
1195
964
  baseURL: ctx.invokeConfig.baseURL,
1196
965
  signal: ctx.abortSignal,
1197
- sessionId: request.context?.sessionId
966
+ sessionId: request.context?.sessionId,
967
+ capabilities: ctx.invokeConfig.capabilities,
968
+ cacheRetention: request.cacheRetention
1198
969
  };
1199
970
  let output = {
1200
971
  content: "",
@@ -1210,7 +981,7 @@ class LLMComponent extends BaseComponent {
1210
981
  throw new Error(resp.raw?.errorMessage || "adapter returned an error response");
1211
982
  }
1212
983
  } catch (adapterErr) {
1213
- logger2.warn(`[LLMComponent.invoke] adapter(${adapter.name}) failed, falling back to AI SDK invoke: ${adapterErr.message}`);
984
+ logger.warn(`[LLMComponent.invoke] adapter(${adapter.name}) failed, falling back to AI SDK invoke: ${adapterErr.message}`);
1214
985
  let fallbackInvokeConfig = ctx.invokeConfig;
1215
986
  try {
1216
987
  const fallback = await resolveFallbackProviderConfig(ctx.providerId);
@@ -1219,9 +990,9 @@ class LLMComponent extends BaseComponent {
1219
990
  apiKey: fallback.apiKey,
1220
991
  baseURL: fallback.baseURL
1221
992
  };
1222
- logger2.warn(`[LLMComponent.invoke] fallback re-resolved baseURL from auth.json: ${fallback.baseURL}`);
993
+ logger.warn(`[LLMComponent.invoke] fallback re-resolved baseURL from auth.json: ${fallback.baseURL}`);
1223
994
  } catch (configErr) {
1224
- logger2.warn(`[LLMComponent.invoke] resolveFallbackProviderConfig failed, using ctx.invokeConfig as-is: ${configErr.message}`);
995
+ logger.warn(`[LLMComponent.invoke] resolveFallbackProviderConfig failed, using ctx.invokeConfig as-is: ${configErr.message}`);
1225
996
  }
1226
997
  const result = await invoke(fallbackInvokeConfig, {
1227
998
  messages: ctx.messages,
@@ -1234,7 +1005,8 @@ class LLMComponent extends BaseComponent {
1234
1005
  sessionId: request.context?.sessionId,
1235
1006
  messageId: request.context?.messageId
1236
1007
  },
1237
- toolChoice: request.toolChoice
1008
+ toolChoice: request.toolChoice,
1009
+ cacheRetention: chatReq.cacheRetention
1238
1010
  }, { abort: ctx.abortSignal });
1239
1011
  if (result.isError) {
1240
1012
  throw new Error(result.result);
@@ -1246,11 +1018,14 @@ class LLMComponent extends BaseComponent {
1246
1018
  output.finishReason = parsed.tool_calls?.length ? "tool-calls" : "stop";
1247
1019
  output.toolCalls = parsed.tool_calls || [];
1248
1020
  if (parsed.usage) {
1249
- finishUsage = {
1021
+ finishUsage = normalizeUsage({
1250
1022
  promptTokens: parsed.usage.promptTokens ?? parsed.usage.inputTokens ?? 0,
1251
1023
  completionTokens: parsed.usage.completionTokens ?? parsed.usage.outputTokens ?? 0,
1252
- totalTokens: parsed.usage.totalTokens ?? 0
1253
- };
1024
+ totalTokens: parsed.usage.totalTokens ?? 0,
1025
+ cacheRead: parsed.usage.cacheRead,
1026
+ cacheWrite: parsed.usage.cacheWrite,
1027
+ cacheMiss: parsed.usage.cacheMiss
1028
+ });
1254
1029
  }
1255
1030
  output.usage = finishUsage;
1256
1031
  } catch {
@@ -1263,11 +1038,7 @@ class LLMComponent extends BaseComponent {
1263
1038
  output.finishReason = resp.finishReason;
1264
1039
  output.toolCalls = resp.toolCalls || [];
1265
1040
  if (resp.usage) {
1266
- finishUsage = {
1267
- promptTokens: resp.usage.promptTokens ?? 0,
1268
- completionTokens: resp.usage.completionTokens ?? 0,
1269
- totalTokens: resp.usage.totalTokens ?? 0
1270
- };
1041
+ finishUsage = normalizeUsage(resp.usage);
1271
1042
  }
1272
1043
  output.usage = finishUsage;
1273
1044
  return this.finalizeOutput(request, ctx, output, finishUsage, startTime, adapter.name);
@@ -1292,7 +1063,7 @@ class LLMComponent extends BaseComponent {
1292
1063
  payload
1293
1064
  });
1294
1065
  } catch (err) {
1295
- logger2.warn(`Failed to push env event ${fullType}`, { error: String(err) });
1066
+ logger.warn(`Failed to push env event ${fullType}`, { error: String(err) });
1296
1067
  }
1297
1068
  };
1298
1069
  try {
@@ -1362,6 +1133,7 @@ class LLMComponent extends BaseComponent {
1362
1133
  throw contextError;
1363
1134
  }
1364
1135
  }
1136
+ this.emitCompletedEvent(request, `${ctx.providerId}/${ctx.model}`, output.content, output.usage, adapterName);
1365
1137
  return {
1366
1138
  output,
1367
1139
  providerId: ctx.providerId,
@@ -1369,6 +1141,31 @@ class LLMComponent extends BaseComponent {
1369
1141
  latencyMs
1370
1142
  };
1371
1143
  }
1144
+ emitCompletedEvent(request, model, content, usage, adapterName) {
1145
+ try {
1146
+ this.env?.pushEnvEvent?.({
1147
+ id: randomUUID(),
1148
+ type: "llm.completed",
1149
+ timestamp: Date.now(),
1150
+ metadata: {
1151
+ source: "llm.component.invoke",
1152
+ sessionId: request.context?.sessionId,
1153
+ messageId: request.context?.messageId
1154
+ },
1155
+ payload: {
1156
+ type: "completed",
1157
+ content,
1158
+ metadata: {
1159
+ model,
1160
+ usage,
1161
+ adapter: adapterName
1162
+ }
1163
+ }
1164
+ });
1165
+ } catch (err) {
1166
+ logger.warn("Failed to push llm.completed event", { error: String(err) });
1167
+ }
1168
+ }
1372
1169
  getApiKey(providerId) {
1373
1170
  const providers = this.getLLMConfig("llm.providers", {});
1374
1171
  return providers?.[providerId]?.apiKey;
@@ -1419,6 +1216,11 @@ class LLMComponent extends BaseComponent {
1419
1216
  }
1420
1217
  }
1421
1218
  __legacyDecorateClassTS([
1422
- TracedAs("llm.component.invoke", { recordParams: true, recordResult: true, log: true })
1219
+ TracedAs("llm.component.invoke", {
1220
+ paramFilter: llmInvokeParamFilter,
1221
+ resultFilter: llmInvokeResultFilter,
1222
+ logResult: true,
1223
+ log: true
1224
+ })
1423
1225
  ], LLMComponent.prototype, "invoke", null);
1424
- export { ADAPTER_NAMES, PiAiAdapter, AiSdkAdapter, setLLMProvider, getLLMProviderOverride, createLLMAdapter, ProviderCapabilitiesSchema, ModelLimitsSchema, ProviderConfigSchema, LLMDefaultConfigSchema, LLMConfigSchema, ProviderManager, LLMTransform, LLMHooks, LLMComponent };
1226
+ export { ADAPTER_NAMES, AiSdkAdapter, setLLMProvider, getLLMProviderOverride, createLLMAdapter, ProviderCapabilitiesSchema, ModelLimitsSchema, ProviderConfigSchema, LLMDefaultConfigSchema, LLMConfigSchema, ProviderManager, LLMTransform, LLMHooks, LLMComponent };
@@ -4,7 +4,7 @@ import {
4
4
  } from "./roy-agent-core-7hh0brvs.js";
5
5
  import {
6
6
  BaseComponent
7
- } from "./roy-agent-core-tdbv7ff4.js";
7
+ } from "./roy-agent-core-40xzbjtm.js";
8
8
  import {
9
9
  createLogger,
10
10
  init_logger
@@ -8,7 +8,7 @@ import {
8
8
  } from "./roy-agent-core-qxnbvgwe.js";
9
9
  import {
10
10
  BaseComponent
11
- } from "./roy-agent-core-tdbv7ff4.js";
11
+ } from "./roy-agent-core-40xzbjtm.js";
12
12
  import {
13
13
  __require
14
14
  } from "./roy-agent-core-fs0mn2jk.js";
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  init_hook
3
- } from "./roy-agent-core-qcspfszy.js";
3
+ } from "./roy-agent-core-gngjkw3b.js";
4
4
  import {
5
5
  globalHookManager
6
- } from "./roy-agent-core-4z3rq5gw.js";
6
+ } from "./roy-agent-core-1pnfkspm.js";
7
7
  import {
8
8
  __esm
9
9
  } from "./roy-agent-core-fs0mn2jk.js";
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  SessionMessageConverter
3
- } from "./roy-agent-core-pk1b3kvf.js";
3
+ } from "./roy-agent-core-ns3pbyz4.js";
4
4
  import {
5
5
  canonicalizeParts
6
- } from "./roy-agent-core-zy3hqfwg.js";
6
+ } from "./roy-agent-core-yv9x4wmg.js";
7
7
  import {
8
8
  createLogger,
9
9
  init_logger