@ai-setting/roy-agent-core 1.6.42 → 1.7.0

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.
@@ -2,8 +2,8 @@ import {
2
2
  AgentComponent,
3
3
  AgentComponentConfigSchema,
4
4
  SummaryAgent
5
- } from "../../shared/@ai-setting/roy-agent-core-fzyn4fxx.js";
6
- import"../../shared/@ai-setting/roy-agent-core-c1stgqnw.js";
5
+ } from "../../shared/@ai-setting/roy-agent-core-q34tv05y.js";
6
+ import"../../shared/@ai-setting/roy-agent-core-167qsqrz.js";
7
7
  import"../../shared/@ai-setting/roy-agent-core-h28gcd77.js";
8
8
  import"../../shared/@ai-setting/roy-agent-core-br7dmedr.js";
9
9
  import"../../shared/@ai-setting/roy-agent-core-t3yqzgse.js";
@@ -12,8 +12,8 @@ import"../../shared/@ai-setting/roy-agent-core-x0yztmm6.js";
12
12
  import"../../shared/@ai-setting/roy-agent-core-qxnbvgwe.js";
13
13
  import"../../shared/@ai-setting/roy-agent-core-c1v263jn.js";
14
14
  import"../../shared/@ai-setting/roy-agent-core-ctdhjv68.js";
15
- import"../../shared/@ai-setting/roy-agent-core-1k9j90s7.js";
16
- import"../../shared/@ai-setting/roy-agent-core-12gac5zn.js";
15
+ import"../../shared/@ai-setting/roy-agent-core-879dbkpx.js";
16
+ import"../../shared/@ai-setting/roy-agent-core-ddrc00er.js";
17
17
  import"../../shared/@ai-setting/roy-agent-core-7hh0brvs.js";
18
18
  import"../../shared/@ai-setting/roy-agent-core-pde8hkq4.js";
19
19
  import"../../shared/@ai-setting/roy-agent-core-5ts23mx0.js";
package/dist/env/index.js CHANGED
@@ -21,7 +21,7 @@ import"../shared/@ai-setting/roy-agent-core-gns3wa97.js";
21
21
  import"../shared/@ai-setting/roy-agent-core-az13yzmc.js";
22
22
  import {
23
23
  WorkflowComponent
24
- } from "../shared/@ai-setting/roy-agent-core-9yf6we04.js";
24
+ } from "../shared/@ai-setting/roy-agent-core-mhayyp5c.js";
25
25
  import"../shared/@ai-setting/roy-agent-core-3e0w0ekw.js";
26
26
  import"../shared/@ai-setting/roy-agent-core-s4r8f6se.js";
27
27
  import"../shared/@ai-setting/roy-agent-core-6atd905e.js";
@@ -30,7 +30,7 @@ import"../shared/@ai-setting/roy-agent-core-h1cb2jzh.js";
30
30
  import"../shared/@ai-setting/roy-agent-core-ddwa0n6h.js";
31
31
  import"../shared/@ai-setting/roy-agent-core-hhrg314p.js";
32
32
  import"../shared/@ai-setting/roy-agent-core-0qjw25e8.js";
33
- import"../shared/@ai-setting/roy-agent-core-dbwvfe0m.js";
33
+ import"../shared/@ai-setting/roy-agent-core-mreh3s0v.js";
34
34
  import"../shared/@ai-setting/roy-agent-core-1db4vpc6.js";
35
35
  import"../shared/@ai-setting/roy-agent-core-j9ybhwnq.js";
36
36
  import"../shared/@ai-setting/roy-agent-core-w8rv08d3.js";
@@ -41,8 +41,8 @@ import"../shared/@ai-setting/roy-agent-core-1ce3fqrk.js";
41
41
  import {
42
42
  AgentComponent,
43
43
  AgentComponentConfigSchema
44
- } from "../shared/@ai-setting/roy-agent-core-fzyn4fxx.js";
45
- import"../shared/@ai-setting/roy-agent-core-c1stgqnw.js";
44
+ } from "../shared/@ai-setting/roy-agent-core-q34tv05y.js";
45
+ import"../shared/@ai-setting/roy-agent-core-167qsqrz.js";
46
46
  import"../shared/@ai-setting/roy-agent-core-h28gcd77.js";
47
47
  import"../shared/@ai-setting/roy-agent-core-br7dmedr.js";
48
48
  import"../shared/@ai-setting/roy-agent-core-t3yqzgse.js";
@@ -72,11 +72,11 @@ import {
72
72
  import"../shared/@ai-setting/roy-agent-core-ctdhjv68.js";
73
73
  import"../shared/@ai-setting/roy-agent-core-fnv3ev18.js";
74
74
  import"../shared/@ai-setting/roy-agent-core-dxfd6p1c.js";
75
- import"../shared/@ai-setting/roy-agent-core-f2nync7q.js";
75
+ import"../shared/@ai-setting/roy-agent-core-bs3c1x02.js";
76
76
  import"../shared/@ai-setting/roy-agent-core-rvxg1wps.js";
77
- import"../shared/@ai-setting/roy-agent-core-afb03wwp.js";
78
- import"../shared/@ai-setting/roy-agent-core-1k9j90s7.js";
79
- import"../shared/@ai-setting/roy-agent-core-12gac5zn.js";
77
+ import"../shared/@ai-setting/roy-agent-core-xcs0vjqg.js";
78
+ import"../shared/@ai-setting/roy-agent-core-879dbkpx.js";
79
+ import"../shared/@ai-setting/roy-agent-core-ddrc00er.js";
80
80
  import"../shared/@ai-setting/roy-agent-core-7hh0brvs.js";
81
81
  import {
82
82
  BaseComponent
@@ -1,14 +1,20 @@
1
1
  import {
2
+ ADAPTER_NAMES,
3
+ AiSdkAdapter,
2
4
  LLMComponent,
3
5
  LLMConfigSchema,
4
6
  LLMDefaultConfigSchema,
5
7
  LLMHooks,
6
8
  LLMTransform,
7
9
  ModelLimitsSchema,
10
+ PiAiAdapter,
8
11
  ProviderCapabilitiesSchema,
9
12
  ProviderConfigSchema,
10
- ProviderManager
11
- } from "../../shared/@ai-setting/roy-agent-core-7wv7gh6t.js";
13
+ ProviderManager,
14
+ createLLMAdapter,
15
+ getLLMProviderOverride,
16
+ setLLMProvider
17
+ } from "../../shared/@ai-setting/roy-agent-core-w66q6zst.js";
12
18
  import"../../shared/@ai-setting/roy-agent-core-y3g3ar7a.js";
13
19
  import {
14
20
  convertToSDKMessages,
@@ -16,9 +22,9 @@ import {
16
22
  invoke,
17
23
  invokeNonStream,
18
24
  parseModelString
19
- } from "../../shared/@ai-setting/roy-agent-core-c1stgqnw.js";
25
+ } from "../../shared/@ai-setting/roy-agent-core-167qsqrz.js";
20
26
  import"../../shared/@ai-setting/roy-agent-core-ctdhjv68.js";
21
- import"../../shared/@ai-setting/roy-agent-core-12gac5zn.js";
27
+ import"../../shared/@ai-setting/roy-agent-core-ddrc00er.js";
22
28
  import"../../shared/@ai-setting/roy-agent-core-7hh0brvs.js";
23
29
  import"../../shared/@ai-setting/roy-agent-core-pde8hkq4.js";
24
30
  import"../../shared/@ai-setting/roy-agent-core-5ts23mx0.js";
@@ -31,18 +37,24 @@ import"../../shared/@ai-setting/roy-agent-core-1khp1m0r.js";
31
37
  import"../../shared/@ai-setting/roy-agent-core-4an1p9a1.js";
32
38
  import"../../shared/@ai-setting/roy-agent-core-fs0mn2jk.js";
33
39
  export {
40
+ setLLMProvider,
34
41
  parseModelString,
35
42
  invokeNonStream,
36
43
  invoke,
44
+ getLLMProviderOverride,
45
+ createLLMAdapter,
37
46
  createInvokeConfig,
38
47
  convertToSDKMessages,
39
48
  ProviderManager,
40
49
  ProviderConfigSchema,
41
50
  ProviderCapabilitiesSchema,
51
+ PiAiAdapter,
42
52
  ModelLimitsSchema,
43
53
  LLMTransform,
44
54
  LLMHooks,
45
55
  LLMDefaultConfigSchema,
46
56
  LLMConfigSchema,
47
- LLMComponent
57
+ LLMComponent,
58
+ AiSdkAdapter,
59
+ ADAPTER_NAMES
48
60
  };
@@ -3,15 +3,15 @@ import {
3
3
  MIN_SESSION_ID_LENGTH,
4
4
  SessionComponent,
5
5
  isValidSessionId
6
- } from "../../shared/@ai-setting/roy-agent-core-f2nync7q.js";
6
+ } from "../../shared/@ai-setting/roy-agent-core-bs3c1x02.js";
7
7
  import"../../shared/@ai-setting/roy-agent-core-rvxg1wps.js";
8
8
  import {
9
9
  MemorySessionStore
10
- } from "../../shared/@ai-setting/roy-agent-core-afb03wwp.js";
10
+ } from "../../shared/@ai-setting/roy-agent-core-xcs0vjqg.js";
11
11
  import {
12
12
  SessionMessageConverter
13
- } from "../../shared/@ai-setting/roy-agent-core-1k9j90s7.js";
14
- import"../../shared/@ai-setting/roy-agent-core-12gac5zn.js";
13
+ } from "../../shared/@ai-setting/roy-agent-core-879dbkpx.js";
14
+ import"../../shared/@ai-setting/roy-agent-core-ddrc00er.js";
15
15
  import"../../shared/@ai-setting/roy-agent-core-7hh0brvs.js";
16
16
  import"../../shared/@ai-setting/roy-agent-core-pde8hkq4.js";
17
17
  import"../../shared/@ai-setting/roy-agent-core-5ts23mx0.js";
@@ -3,9 +3,9 @@ import {
3
3
  SQLiteSessionStore,
4
4
  getDefaultDataDir,
5
5
  getDefaultSessionDbPath
6
- } from "../../../shared/@ai-setting/roy-agent-core-afb03wwp.js";
7
- import"../../../shared/@ai-setting/roy-agent-core-1k9j90s7.js";
8
- import"../../../shared/@ai-setting/roy-agent-core-12gac5zn.js";
6
+ } from "../../../shared/@ai-setting/roy-agent-core-xcs0vjqg.js";
7
+ import"../../../shared/@ai-setting/roy-agent-core-879dbkpx.js";
8
+ import"../../../shared/@ai-setting/roy-agent-core-ddrc00er.js";
9
9
  import"../../../shared/@ai-setting/roy-agent-core-kaq037np.js";
10
10
  import"../../../shared/@ai-setting/roy-agent-core-1khp1m0r.js";
11
11
  import"../../../shared/@ai-setting/roy-agent-core-4an1p9a1.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  WorkflowComponent
3
- } from "../../shared/@ai-setting/roy-agent-core-9yf6we04.js";
3
+ } from "../../shared/@ai-setting/roy-agent-core-mhayyp5c.js";
4
4
  import"../../shared/@ai-setting/roy-agent-core-3e0w0ekw.js";
5
5
  import"../../shared/@ai-setting/roy-agent-core-s4r8f6se.js";
6
6
  import"../../shared/@ai-setting/roy-agent-core-6atd905e.js";
@@ -9,7 +9,7 @@ import"../../shared/@ai-setting/roy-agent-core-h1cb2jzh.js";
9
9
  import"../../shared/@ai-setting/roy-agent-core-ddwa0n6h.js";
10
10
  import"../../shared/@ai-setting/roy-agent-core-hhrg314p.js";
11
11
  import"../../shared/@ai-setting/roy-agent-core-0qjw25e8.js";
12
- import"../../shared/@ai-setting/roy-agent-core-dbwvfe0m.js";
12
+ import"../../shared/@ai-setting/roy-agent-core-mreh3s0v.js";
13
13
  import"../../shared/@ai-setting/roy-agent-core-1db4vpc6.js";
14
14
  import"../../shared/@ai-setting/roy-agent-core-j9ybhwnq.js";
15
15
  import"../../shared/@ai-setting/roy-agent-core-w8rv08d3.js";
@@ -84,11 +84,11 @@ import {
84
84
  createWorkflowAskUserEvent
85
85
  } from "../../shared/@ai-setting/roy-agent-core-e25xkv53.js";
86
86
  import"../../shared/@ai-setting/roy-agent-core-c1v263jn.js";
87
- import"../../shared/@ai-setting/roy-agent-core-f2nync7q.js";
87
+ import"../../shared/@ai-setting/roy-agent-core-bs3c1x02.js";
88
88
  import"../../shared/@ai-setting/roy-agent-core-rvxg1wps.js";
89
- import"../../shared/@ai-setting/roy-agent-core-afb03wwp.js";
90
- import"../../shared/@ai-setting/roy-agent-core-1k9j90s7.js";
91
- import"../../shared/@ai-setting/roy-agent-core-12gac5zn.js";
89
+ import"../../shared/@ai-setting/roy-agent-core-xcs0vjqg.js";
90
+ import"../../shared/@ai-setting/roy-agent-core-879dbkpx.js";
91
+ import"../../shared/@ai-setting/roy-agent-core-ddrc00er.js";
92
92
  import"../../shared/@ai-setting/roy-agent-core-7hh0brvs.js";
93
93
  import"../../shared/@ai-setting/roy-agent-core-pde8hkq4.js";
94
94
  import"../../shared/@ai-setting/roy-agent-core-5ts23mx0.js";
@@ -24,7 +24,7 @@ import {
24
24
  getRunWorkflowTool,
25
25
  initRunWorkflowTool,
26
26
  resetRunWorkflowTool
27
- } from "../../../shared/@ai-setting/roy-agent-core-dbwvfe0m.js";
27
+ } from "../../../shared/@ai-setting/roy-agent-core-mreh3s0v.js";
28
28
  import {
29
29
  WORKFLOW_SUBMIT_OUTPUT_TOOL_NAME,
30
30
  WorkflowJsonOutputMarker,
@@ -38,11 +38,11 @@ import"../../../shared/@ai-setting/roy-agent-core-0v74marc.js";
38
38
  import"../../../shared/@ai-setting/roy-agent-core-jrj30vq3.js";
39
39
  import"../../../shared/@ai-setting/roy-agent-core-e25xkv53.js";
40
40
  import"../../../shared/@ai-setting/roy-agent-core-c1v263jn.js";
41
- import"../../../shared/@ai-setting/roy-agent-core-f2nync7q.js";
41
+ import"../../../shared/@ai-setting/roy-agent-core-bs3c1x02.js";
42
42
  import"../../../shared/@ai-setting/roy-agent-core-rvxg1wps.js";
43
- import"../../../shared/@ai-setting/roy-agent-core-afb03wwp.js";
44
- import"../../../shared/@ai-setting/roy-agent-core-1k9j90s7.js";
45
- import"../../../shared/@ai-setting/roy-agent-core-12gac5zn.js";
43
+ import"../../../shared/@ai-setting/roy-agent-core-xcs0vjqg.js";
44
+ import"../../../shared/@ai-setting/roy-agent-core-879dbkpx.js";
45
+ import"../../../shared/@ai-setting/roy-agent-core-ddrc00er.js";
46
46
  import"../../../shared/@ai-setting/roy-agent-core-7hh0brvs.js";
47
47
  import"../../../shared/@ai-setting/roy-agent-core-pde8hkq4.js";
48
48
  import"../../../shared/@ai-setting/roy-agent-core-5ts23mx0.js";
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  ModelLimitsSchema,
10
10
  ProviderCapabilitiesSchema,
11
11
  ProviderConfigSchema
12
- } from "./shared/@ai-setting/roy-agent-core-7wv7gh6t.js";
12
+ } from "./shared/@ai-setting/roy-agent-core-w66q6zst.js";
13
13
  import {
14
14
  ConfigComponent
15
15
  } from "./shared/@ai-setting/roy-agent-core-g7nmwg63.js";
@@ -102,7 +102,7 @@ import {
102
102
  } from "./shared/@ai-setting/roy-agent-core-az13yzmc.js";
103
103
  import {
104
104
  WorkflowComponent
105
- } from "./shared/@ai-setting/roy-agent-core-9yf6we04.js";
105
+ } from "./shared/@ai-setting/roy-agent-core-mhayyp5c.js";
106
106
  import {
107
107
  init_node_registry_helper,
108
108
  registerDecoratorNodeType
@@ -114,7 +114,7 @@ import"./shared/@ai-setting/roy-agent-core-h1cb2jzh.js";
114
114
  import"./shared/@ai-setting/roy-agent-core-ddwa0n6h.js";
115
115
  import"./shared/@ai-setting/roy-agent-core-hhrg314p.js";
116
116
  import"./shared/@ai-setting/roy-agent-core-0qjw25e8.js";
117
- import"./shared/@ai-setting/roy-agent-core-dbwvfe0m.js";
117
+ import"./shared/@ai-setting/roy-agent-core-mreh3s0v.js";
118
118
  import"./shared/@ai-setting/roy-agent-core-1db4vpc6.js";
119
119
  import"./shared/@ai-setting/roy-agent-core-j9ybhwnq.js";
120
120
  import"./shared/@ai-setting/roy-agent-core-w8rv08d3.js";
@@ -131,13 +131,13 @@ import"./shared/@ai-setting/roy-agent-core-1ce3fqrk.js";
131
131
  import {
132
132
  AgentComponent,
133
133
  AgentComponentConfigSchema
134
- } from "./shared/@ai-setting/roy-agent-core-fzyn4fxx.js";
134
+ } from "./shared/@ai-setting/roy-agent-core-q34tv05y.js";
135
135
  import {
136
136
  createInvokeConfig,
137
137
  invoke,
138
138
  invokeNonStream,
139
139
  parseModelString
140
- } from "./shared/@ai-setting/roy-agent-core-c1stgqnw.js";
140
+ } from "./shared/@ai-setting/roy-agent-core-167qsqrz.js";
141
141
  import {
142
142
  ToolComponent,
143
143
  ToolRegistry,
@@ -200,13 +200,13 @@ import"./shared/@ai-setting/roy-agent-core-fnv3ev18.js";
200
200
  import"./shared/@ai-setting/roy-agent-core-dxfd6p1c.js";
201
201
  import {
202
202
  SessionComponent
203
- } from "./shared/@ai-setting/roy-agent-core-f2nync7q.js";
203
+ } from "./shared/@ai-setting/roy-agent-core-bs3c1x02.js";
204
204
  import"./shared/@ai-setting/roy-agent-core-rvxg1wps.js";
205
205
  import {
206
206
  MemorySessionStore
207
- } from "./shared/@ai-setting/roy-agent-core-afb03wwp.js";
208
- import"./shared/@ai-setting/roy-agent-core-1k9j90s7.js";
209
- import"./shared/@ai-setting/roy-agent-core-12gac5zn.js";
207
+ } from "./shared/@ai-setting/roy-agent-core-xcs0vjqg.js";
208
+ import"./shared/@ai-setting/roy-agent-core-879dbkpx.js";
209
+ import"./shared/@ai-setting/roy-agent-core-ddrc00er.js";
210
210
  import"./shared/@ai-setting/roy-agent-core-7hh0brvs.js";
211
211
  import {
212
212
  BaseComponent
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  safeParseToolArgs
3
- } from "./roy-agent-core-12gac5zn.js";
3
+ } from "./roy-agent-core-ddrc00er.js";
4
4
  import {
5
5
  createLogger,
6
6
  init_logger
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  safeParseToolArgs
3
- } from "./roy-agent-core-12gac5zn.js";
3
+ } from "./roy-agent-core-ddrc00er.js";
4
4
 
5
5
  // src/env/session/session-message-converter.ts
6
6
  import { randomUUID } from "crypto";
@@ -6,7 +6,7 @@ import {
6
6
  import {
7
7
  MemorySessionStore,
8
8
  SQLiteSessionStore
9
- } from "./roy-agent-core-afb03wwp.js";
9
+ } from "./roy-agent-core-xcs0vjqg.js";
10
10
  import {
11
11
  envKeyToConfigKey
12
12
  } from "./roy-agent-core-7hh0brvs.js";
@@ -34,7 +34,13 @@ function safeParseToolArgs(args, depth = 0) {
34
34
  return {};
35
35
  }
36
36
  return { value: parsed };
37
- } catch {
37
+ } catch (e) {
38
+ logger.warn(`[safeParseToolArgs] JSON.parse failed at depth ${depth}`, {
39
+ parse_failed: true,
40
+ input_length: args.length,
41
+ depth,
42
+ error: e.message
43
+ });
38
44
  return {};
39
45
  }
40
46
  }
@@ -18,7 +18,7 @@ import {
18
18
  createWorkflowSearchTool,
19
19
  createWorkflowTagListTool,
20
20
  createWorkflowValidateTool
21
- } from "./roy-agent-core-dbwvfe0m.js";
21
+ } from "./roy-agent-core-mreh3s0v.js";
22
22
  import {
23
23
  WorkflowService
24
24
  } from "./roy-agent-core-j9ybhwnq.js";
@@ -14,7 +14,7 @@ import {
14
14
  } from "./roy-agent-core-c1v263jn.js";
15
15
  import {
16
16
  isValidSessionId
17
- } from "./roy-agent-core-f2nync7q.js";
17
+ } from "./roy-agent-core-bs3c1x02.js";
18
18
  import {
19
19
  TracedAs,
20
20
  init_decorator
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  withTimeout
3
- } from "./roy-agent-core-c1stgqnw.js";
3
+ } from "./roy-agent-core-167qsqrz.js";
4
4
  import {
5
5
  truncateOutputInline
6
6
  } from "./roy-agent-core-h28gcd77.js";
@@ -22,10 +22,10 @@ import {
22
22
  } from "./roy-agent-core-ctdhjv68.js";
23
23
  import {
24
24
  SessionMessageConverter
25
- } from "./roy-agent-core-1k9j90s7.js";
25
+ } from "./roy-agent-core-879dbkpx.js";
26
26
  import {
27
27
  safeParseToolArgs
28
- } from "./roy-agent-core-12gac5zn.js";
28
+ } from "./roy-agent-core-ddrc00er.js";
29
29
  import {
30
30
  envKeyToConfigKey
31
31
  } from "./roy-agent-core-7hh0brvs.js";
@@ -1034,7 +1034,7 @@ class AgentComponent extends BaseComponent {
1034
1034
  }
1035
1035
  const func = toolCall.function;
1036
1036
  const tcName = func?.name || toolCall.name || "unknown";
1037
- const tcArgs = func?.arguments ? typeof func.arguments === "string" ? safeParseToolArgs(func.arguments) : func.arguments : toolCall.arguments;
1037
+ const tcArgs = this.parseToolCallArguments(toolCall);
1038
1038
  hookCtx.currentToolCall = {
1039
1039
  id: toolCall.id,
1040
1040
  name: tcName,
@@ -1401,6 +1401,10 @@ ${additionInfo}`
1401
1401
  finishReason: "stop"
1402
1402
  };
1403
1403
  }
1404
+ parseToolCallArguments(toolCall) {
1405
+ const rawArgs = toolCall.function?.arguments ?? toolCall.arguments;
1406
+ return safeParseToolArgs(rawArgs);
1407
+ }
1404
1408
  async executeTool(ctx) {
1405
1409
  const toolCall = ctx.currentToolCall;
1406
1410
  const toolName = toolCall.function?.name || toolCall.name || "unknown";
@@ -1695,6 +1699,28 @@ __legacyDecorateClassTS([
1695
1699
  __legacyDecorateClassTS([
1696
1700
  TracedAs("agent.component.invokeLLM", { recordParams: true, recordResult: true, log: true })
1697
1701
  ], AgentComponent.prototype, "invokeLLM", null);
1702
+ __legacyDecorateClassTS([
1703
+ TracedAs("agent.tool_call.parse", {
1704
+ recordParams: true,
1705
+ recordResult: true,
1706
+ log: true,
1707
+ paramFilter: (args) => {
1708
+ const toolCall = args[0];
1709
+ const hasFunctionArgs = toolCall?.function?.arguments !== undefined;
1710
+ const rawArgs = hasFunctionArgs ? toolCall.function.arguments : toolCall?.arguments;
1711
+ return {
1712
+ tool_call_id: toolCall?.id,
1713
+ tool_name: toolCall?.function?.name ?? toolCall?.name ?? "unknown",
1714
+ argument_source: hasFunctionArgs ? "function.arguments" : "arguments",
1715
+ argument_type: rawArgs === null ? "null" : Array.isArray(rawArgs) ? "array" : typeof rawArgs
1716
+ };
1717
+ },
1718
+ resultFilter: (result) => ({
1719
+ argument_type: "object",
1720
+ keys: Object.keys(result).sort()
1721
+ })
1722
+ })
1723
+ ], AgentComponent.prototype, "parseToolCallArguments", null);
1698
1724
  __legacyDecorateClassTS([
1699
1725
  TracedAs("agent.component.executeTool", { recordParams: true, recordResult: true, log: true })
1700
1726
  ], AgentComponent.prototype, "executeTool", null);
@@ -2,8 +2,9 @@ import {
2
2
  EnvSource
3
3
  } from "./roy-agent-core-y3g3ar7a.js";
4
4
  import {
5
- invoke
6
- } from "./roy-agent-core-c1stgqnw.js";
5
+ invoke,
6
+ invokeNonStream
7
+ } from "./roy-agent-core-167qsqrz.js";
7
8
  import {
8
9
  ContextError,
9
10
  ErrorCodes
@@ -22,16 +23,467 @@ import {
22
23
  } from "./roy-agent-core-j29yg06n.js";
23
24
  import {
24
25
  TracedAs,
25
- init_decorator
26
+ init_decorator,
27
+ wrapFunction
26
28
  } from "./roy-agent-core-gb7pm9c0.js";
27
29
  import {
28
30
  createLogger,
29
31
  init_logger
30
32
  } from "./roy-agent-core-kaq037np.js";
31
33
  import {
32
- __legacyDecorateClassTS
34
+ __legacyDecorateClassTS,
35
+ __require
33
36
  } from "./roy-agent-core-fs0mn2jk.js";
34
37
 
38
+ // src/env/llm/adapter.ts
39
+ var ADAPTER_NAMES = ["pi-ai", "ai-sdk"];
40
+ // src/env/llm/adapter-pi-ai.ts
41
+ init_decorator();
42
+ init_logger();
43
+ import {
44
+ complete,
45
+ stream as piStream,
46
+ getModel
47
+ } from "@earendil-works/pi-ai";
48
+ import { zodToJsonSchema } from "zod-to-json-schema";
49
+ var logger = createLogger("llm:adapter-pi-ai");
50
+ var KNOWN_PROVIDER_APIS = {
51
+ anthropic: { api: "anthropic-messages", contextLimit: 200000, maxTokensLimit: 8192 },
52
+ openai: { api: "openai-responses", contextLimit: 128000, maxTokensLimit: 16384 },
53
+ google: { api: "google-generative-ai", contextLimit: 1e6, maxTokensLimit: 8192 },
54
+ "google-vertex": { api: "google-vertex", contextLimit: 1e6, maxTokensLimit: 8192 },
55
+ deepseek: { api: "openai-completions", contextLimit: 64000, maxTokensLimit: 8192 },
56
+ xai: { api: "openai-completions", contextLimit: 131072, maxTokensLimit: 8192 },
57
+ groq: { api: "openai-completions", contextLimit: 32768, maxTokensLimit: 8192 },
58
+ minimax: { api: "openai-completions", contextLimit: 128000, maxTokensLimit: 8192 },
59
+ "minimax-cn": { api: "openai-completions", contextLimit: 128000, maxTokensLimit: 8192 },
60
+ moonshotai: { api: "openai-completions", contextLimit: 128000, maxTokensLimit: 8192 },
61
+ "kimi-coding": { api: "openai-completions", contextLimit: 128000, maxTokensLimit: 8192 }
62
+ };
63
+ function resolvePiModel(provider, modelId, baseURL) {
64
+ const builtIn = getModel(provider, modelId);
65
+ if (builtIn)
66
+ return baseURL ? { ...builtIn, baseUrl: baseURL } : builtIn;
67
+ const providerApiOverride = {
68
+ "minimax-responses": "openai-responses",
69
+ "minimax-openai": "openai-completions"
70
+ };
71
+ let configuredApi;
72
+ if (providerApiOverride[provider]) {
73
+ configuredApi = providerApiOverride[provider];
74
+ } else if (provider === "minimax" || provider === "minimax-cn") {
75
+ configuredApi = baseURL?.includes("anthropic") ? "anthropic-messages" : "openai-completions";
76
+ } else if (baseURL?.includes("/responses")) {
77
+ configuredApi = "openai-responses";
78
+ } else if (baseURL?.includes("anthropic")) {
79
+ configuredApi = "anthropic-messages";
80
+ } else {
81
+ configuredApi = KNOWN_PROVIDER_APIS[provider]?.api || "openai-completions";
82
+ }
83
+ return {
84
+ id: modelId,
85
+ name: modelId,
86
+ api: configuredApi,
87
+ provider,
88
+ baseUrl: baseURL || "",
89
+ reasoning: false,
90
+ input: ["text"],
91
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
92
+ contextWindow: KNOWN_PROVIDER_APIS[provider]?.contextLimit || 128000,
93
+ maxTokens: KNOWN_PROVIDER_APIS[provider]?.maxTokensLimit || 8192
94
+ };
95
+ }
96
+ function toPiMessages(messages) {
97
+ const out = [];
98
+ const ts = Date.now();
99
+ for (const m of messages) {
100
+ if (m.role === "system")
101
+ continue;
102
+ if (m.role === "user") {
103
+ if (typeof m.content === "string") {
104
+ out.push({ role: "user", content: m.content, timestamp: ts });
105
+ } else {
106
+ out.push({ role: "user", content: m.content.flatMap((c) => {
107
+ if (c.type === "text")
108
+ return [{ type: "text", text: c.text }];
109
+ if (c.type === "image")
110
+ return [{ type: "image", data: c.image instanceof Uint8Array ? Buffer.from(c.image).toString("base64") : c.image, mimeType: "image/*" }];
111
+ return [{ type: "text", text: `[file:${c.mediaType}] ${typeof c.file === "string" ? c.file : Buffer.from(c.file).toString("base64")}` }];
112
+ }), timestamp: ts });
113
+ }
114
+ continue;
115
+ }
116
+ if (m.role === "tool") {
117
+ 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 });
118
+ continue;
119
+ }
120
+ const content = [];
121
+ if (typeof m.content === "string" && m.content)
122
+ content.push({ type: "text", text: m.content });
123
+ else if (Array.isArray(m.content))
124
+ for (const c of m.content) {
125
+ if (c.type === "text")
126
+ content.push({ type: "text", text: c.text });
127
+ else if (c.type === "image")
128
+ content.push({ type: "image", data: c.image instanceof Uint8Array ? Buffer.from(c.image).toString("base64") : c.image, mimeType: "image/*" });
129
+ else
130
+ content.push({ type: "text", text: `[file:${c.mediaType}] ${typeof c.file === "string" ? c.file : Buffer.from(c.file).toString("base64")}` });
131
+ }
132
+ for (const tc of m.toolCalls || [])
133
+ content.push({ type: "toolCall", id: tc.id, name: tc.name, arguments: safeJson(tc.arguments) });
134
+ 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 });
135
+ }
136
+ return out;
137
+ }
138
+ function extractSystemPrompt(messages) {
139
+ 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(""));
140
+ return prompts.length ? prompts.join(`
141
+
142
+ `) : undefined;
143
+ }
144
+ function safeJson(s) {
145
+ try {
146
+ return JSON.parse(s);
147
+ } catch (e) {
148
+ logger.warn(`[safeJson] JSON.parse failed`, {
149
+ parse_failed: true,
150
+ input_length: s.length,
151
+ error: e.message
152
+ });
153
+ return {};
154
+ }
155
+ }
156
+ function isZodSchema(obj) {
157
+ return !!obj && typeof obj === "object" && "_def" in obj;
158
+ }
159
+ function convertToolParameters(parameters) {
160
+ if (parameters == null)
161
+ return { type: "object", properties: {} };
162
+ if (typeof parameters !== "object")
163
+ return { type: "object", properties: {} };
164
+ if (isZodSchema(parameters)) {
165
+ try {
166
+ const jsonSchema = zodToJsonSchema(parameters, "zod");
167
+ if ("$ref" in jsonSchema && jsonSchema.definitions) {
168
+ const def = jsonSchema.definitions.zod;
169
+ if (def && def.type === "object" && def.properties) {
170
+ return def;
171
+ }
172
+ }
173
+ return jsonSchema;
174
+ } catch {
175
+ return { type: "object", properties: {} };
176
+ }
177
+ }
178
+ const paramsObj = parameters;
179
+ if (paramsObj.type === "object" && paramsObj.properties) {
180
+ return paramsObj;
181
+ }
182
+ return { type: "object", properties: {} };
183
+ }
184
+ function toPiTools(tools) {
185
+ if (!tools)
186
+ return;
187
+ return tools.map((t) => ({
188
+ name: t.name,
189
+ description: t.description || "",
190
+ parameters: convertToolParameters(t.parameters)
191
+ }));
192
+ }
193
+ function fromAssistantMessage(msg) {
194
+ let text = "";
195
+ const toolCalls = [];
196
+ for (const block of msg.content) {
197
+ const b = block;
198
+ if (b.type === "text") {
199
+ text += b.text || "";
200
+ } else if (b.type === "toolCall") {
201
+ toolCalls.push({
202
+ id: b.id || "",
203
+ name: b.name || "",
204
+ arguments: typeof b.arguments === "string" ? b.arguments : JSON.stringify(b.arguments ?? {})
205
+ });
206
+ }
207
+ }
208
+ return {
209
+ text,
210
+ finishReason: msg.stopReason || "stop",
211
+ toolCalls: toolCalls.length ? toolCalls : undefined,
212
+ usage: {
213
+ promptTokens: msg.usage?.input ?? 0,
214
+ completionTokens: msg.usage?.output ?? 0,
215
+ totalTokens: msg.usage?.totalTokens ?? 0,
216
+ cacheRead: msg.usage?.cacheRead,
217
+ cacheWrite: msg.usage?.cacheWrite
218
+ },
219
+ raw: msg
220
+ };
221
+ }
222
+
223
+ class EmbeddingNotSupportedError extends Error {
224
+ constructor(adapter) {
225
+ super(`Embedding is not supported by ${adapter}; use AiSdkAdapter.embed() or apply at higher layer.`);
226
+ this.name = "EmbeddingNotSupportedError";
227
+ }
228
+ }
229
+
230
+ class PiAiAdapter {
231
+ name = "pi-ai";
232
+ async chat(req) {
233
+ const model = resolvePiModel(req.provider, req.modelId, req.baseURL);
234
+ const ctx = {
235
+ systemPrompt: [req.systemPrompt, extractSystemPrompt(req.messages)].filter(Boolean).join(`
236
+
237
+ `) || undefined,
238
+ messages: toPiMessages(req.messages),
239
+ tools: toPiTools(req.tools)
240
+ };
241
+ const msg = await complete(model, ctx, {
242
+ apiKey: req.apiKey,
243
+ baseURL: req.baseURL,
244
+ temperature: req.temperature,
245
+ maxTokens: req.maxTokens,
246
+ signal: req.signal
247
+ });
248
+ return fromAssistantMessage(msg);
249
+ }
250
+ async stream(req) {
251
+ const model = resolvePiModel(req.provider, req.modelId, req.baseURL);
252
+ const ctx = {
253
+ systemPrompt: [req.systemPrompt, extractSystemPrompt(req.messages)].filter(Boolean).join(`
254
+
255
+ `) || undefined,
256
+ messages: toPiMessages(req.messages),
257
+ tools: toPiTools(req.tools)
258
+ };
259
+ const eventStream = piStream(model, ctx, { apiKey: req.apiKey, baseURL: req.baseURL, temperature: req.temperature, maxTokens: req.maxTokens, signal: req.signal });
260
+ return { events: eventStream, result: async () => fromAssistantMessage(await eventStream.result()) };
261
+ }
262
+ async embed(_req) {
263
+ throw new EmbeddingNotSupportedError(this.name);
264
+ }
265
+ async resolveProvider(provider, modelId) {
266
+ const model = resolvePiModel(provider, modelId);
267
+ const caps = KNOWN_PROVIDER_APIS[provider] || {
268
+ api: model.api,
269
+ contextLimit: model.contextWindow,
270
+ maxTokensLimit: model.maxTokens
271
+ };
272
+ return {
273
+ api: model.api,
274
+ provider,
275
+ modelId,
276
+ contextLimit: caps.contextLimit,
277
+ maxTokensLimit: caps.maxTokensLimit
278
+ };
279
+ }
280
+ }
281
+ __legacyDecorateClassTS([
282
+ TracedAs("llm.adapter.chat", {
283
+ recordParams: true,
284
+ recordResult: true,
285
+ log: true,
286
+ paramFilter: (args) => {
287
+ const req = args[0];
288
+ return {
289
+ provider: req?.provider,
290
+ model_id: req?.modelId,
291
+ messages_count: req?.messages?.length,
292
+ tools_count: req?.tools?.length,
293
+ temperature: req?.temperature,
294
+ max_tokens: req?.maxTokens
295
+ };
296
+ },
297
+ resultFilter: (r) => ({
298
+ finish_reason: r?.finishReason,
299
+ usage_input: r?.usage?.promptTokens,
300
+ usage_output: r?.usage?.completionTokens,
301
+ usage_total: r?.usage?.totalTokens,
302
+ content_length: r?.text?.length
303
+ })
304
+ })
305
+ ], PiAiAdapter.prototype, "chat", null);
306
+ __legacyDecorateClassTS([
307
+ TracedAs("llm.adapter.stream", {
308
+ recordParams: true,
309
+ recordResult: false,
310
+ log: true,
311
+ paramFilter: (args) => {
312
+ const req = args[0];
313
+ return {
314
+ provider: req?.provider,
315
+ model_id: req?.modelId,
316
+ messages_count: req?.messages?.length
317
+ };
318
+ }
319
+ })
320
+ ], PiAiAdapter.prototype, "stream", null);
321
+ __legacyDecorateClassTS([
322
+ TracedAs("llm.adapter.embed", { recordParams: true, recordResult: false, log: true })
323
+ ], PiAiAdapter.prototype, "embed", null);
324
+ __legacyDecorateClassTS([
325
+ TracedAs("llm.adapter.resolve_provider", {
326
+ recordParams: true,
327
+ recordResult: true,
328
+ log: true,
329
+ paramFilter: (args) => ({
330
+ provider: args[0],
331
+ model_id: args[1]
332
+ }),
333
+ resultFilter: (r) => ({
334
+ api: r?.api,
335
+ context_limit: r?.contextLimit,
336
+ max_tokens_limit: r?.maxTokensLimit
337
+ })
338
+ })
339
+ ], PiAiAdapter.prototype, "resolveProvider", null);
340
+ // src/env/llm/adapter-ai-sdk.ts
341
+ init_decorator();
342
+ import { embed as aiEmbed, embedMany as aiEmbedMany } from "ai";
343
+ class AiSdkAdapter {
344
+ name = "ai-sdk";
345
+ async chat(req) {
346
+ const config = this.toInvokeConfig(req);
347
+ const opts = this.toInvokeOptions(req);
348
+ const ctx = { abort: req.signal };
349
+ const out = await invokeNonStream(config, opts, ctx);
350
+ return {
351
+ text: out.content || "",
352
+ finishReason: out.finishReason || "stop",
353
+ toolCalls: out.toolCalls?.map((tc) => ({
354
+ id: tc.id,
355
+ name: tc.name,
356
+ arguments: tc.arguments
357
+ })),
358
+ usage: out.usage || { promptTokens: 0, completionTokens: 0, totalTokens: 0 },
359
+ raw: out
360
+ };
361
+ }
362
+ async stream(req) {
363
+ const config = this.toInvokeConfig(req);
364
+ const opts = this.toInvokeOptions(req);
365
+ const ctx = { abort: req.signal };
366
+ let output;
367
+ const events = async function* () {
368
+ output = await invoke(config, opts, ctx);
369
+ yield output;
370
+ }();
371
+ return {
372
+ events,
373
+ result: async () => ({
374
+ text: output?.content || "",
375
+ finishReason: output?.finishReason || "stop",
376
+ toolCalls: output?.toolCalls?.map((tc) => ({
377
+ id: tc.id,
378
+ name: tc.name,
379
+ arguments: tc.arguments
380
+ })),
381
+ usage: output?.usage || { promptTokens: 0, completionTokens: 0, totalTokens: 0 },
382
+ raw: output
383
+ })
384
+ };
385
+ }
386
+ async embed(req) {
387
+ const { createOpenAICompatible } = await import("@ai-sdk/openai-compatible");
388
+ const provider = createOpenAICompatible({ name: req.provider, apiKey: req.apiKey, baseURL: req.baseURL });
389
+ const model = provider.textEmbeddingModel(req.modelId);
390
+ const values = Array.isArray(req.input) ? req.input : [req.input];
391
+ const result = values.length === 1 ? { embeddings: [(await aiEmbed({ model, value: values[0], abortSignal: req.signal })).embedding] } : await aiEmbedMany({ model, values, abortSignal: req.signal });
392
+ return { embeddings: result.embeddings, usage: { promptTokens: 0, completionTokens: 0, totalTokens: 0 } };
393
+ }
394
+ async resolveProvider(provider, modelId) {
395
+ return {
396
+ api: provider === "anthropic" ? "anthropic-messages" : "openai-completions",
397
+ provider,
398
+ modelId,
399
+ contextLimit: 0,
400
+ maxTokensLimit: 0
401
+ };
402
+ }
403
+ toInvokeConfig(req) {
404
+ return {
405
+ model: `${req.provider}/${req.modelId}`,
406
+ baseURL: req.baseURL,
407
+ apiKey: req.apiKey
408
+ };
409
+ }
410
+ toInvokeOptions(req) {
411
+ return {
412
+ messages: req.messages,
413
+ tools: req.tools,
414
+ temperature: req.temperature,
415
+ maxTokens: req.maxTokens,
416
+ model: req.modelId
417
+ };
418
+ }
419
+ }
420
+ __legacyDecorateClassTS([
421
+ TracedAs("llm.adapter.ai_sdk.chat", {
422
+ recordParams: true,
423
+ recordResult: true,
424
+ log: true,
425
+ paramFilter: (args) => {
426
+ const req = args[0];
427
+ return {
428
+ provider: req?.provider,
429
+ model_id: req?.modelId,
430
+ messages_count: req?.messages?.length
431
+ };
432
+ },
433
+ resultFilter: (r) => ({
434
+ finish_reason: r?.finishReason,
435
+ usage_input: r?.usage?.promptTokens,
436
+ usage_output: r?.usage?.completionTokens
437
+ })
438
+ })
439
+ ], AiSdkAdapter.prototype, "chat", null);
440
+ __legacyDecorateClassTS([
441
+ TracedAs("llm.adapter.ai_sdk.stream", {
442
+ recordParams: true,
443
+ recordResult: false,
444
+ log: true
445
+ })
446
+ ], AiSdkAdapter.prototype, "stream", null);
447
+ __legacyDecorateClassTS([
448
+ TracedAs("llm.adapter.ai_sdk.embed", { recordParams: true, recordResult: true, log: true })
449
+ ], AiSdkAdapter.prototype, "embed", null);
450
+ __legacyDecorateClassTS([
451
+ TracedAs("llm.adapter.ai_sdk.resolve_provider", {
452
+ recordParams: true,
453
+ recordResult: true,
454
+ log: true
455
+ })
456
+ ], AiSdkAdapter.prototype, "resolveProvider", null);
457
+ // src/env/llm/factory.ts
458
+ init_decorator();
459
+ var runtimeOverride;
460
+ function setLLMProvider(name) {
461
+ runtimeOverride = name;
462
+ }
463
+ function getLLMProviderOverride() {
464
+ return runtimeOverride;
465
+ }
466
+ var _createLLMAdapter = function _createLLMAdapter2() {
467
+ const arg = runtimeOverride ?? process.env.ROY_LLM_PROVIDER ?? "pi-ai";
468
+ switch (arg) {
469
+ case "pi-ai":
470
+ return new PiAiAdapter;
471
+ case "ai-sdk":
472
+ return new AiSdkAdapter;
473
+ default:
474
+ throw new Error(`Invalid ROY_LLM_PROVIDER value: "${arg}". Expected: pi-ai | ai-sdk`);
475
+ }
476
+ };
477
+ var createLLMAdapter = wrapFunction(_createLLMAdapter, "llm.adapter.factory", {
478
+ recordParams: false,
479
+ recordResult: true,
480
+ log: true,
481
+ resultFilter: (_r) => ({
482
+ adapter_name: _r?.name,
483
+ env_arg: process.env.ROY_LLM_PROVIDER ?? null,
484
+ runtime_override: runtimeOverride ?? null
485
+ })
486
+ });
35
487
  // src/env/llm/types.ts
36
488
  import { z } from "zod";
37
489
  var ProviderCapabilitiesSchema = z.object({
@@ -450,13 +902,16 @@ class LLMHooks {
450
902
  // src/env/llm/llm.ts
451
903
  init_logger();
452
904
  init_decorator();
453
- var logger = createLogger("llm");
905
+ import { randomUUID } from "crypto";
906
+ var logger2 = createLogger("llm");
454
907
 
455
908
  class LLMComponent extends BaseComponent {
456
909
  name = "llm";
457
910
  version = "2.0.0";
458
911
  configComponent;
459
912
  configWatcher;
913
+ cachedAdapter;
914
+ cachedAdapterProvider;
460
915
  constructor() {
461
916
  super();
462
917
  }
@@ -562,7 +1017,7 @@ class LLMComponent extends BaseComponent {
562
1017
  componentName: "llm",
563
1018
  knownKeys,
564
1019
  logger: {
565
- warn: (msg) => logger.warn(msg)
1020
+ warn: (msg) => logger2.warn(msg)
566
1021
  }
567
1022
  });
568
1023
  }
@@ -596,24 +1051,24 @@ class LLMComponent extends BaseComponent {
596
1051
  }
597
1052
  registerConfigWatcher(configComponent) {
598
1053
  if (typeof configComponent.watch !== "function") {
599
- logger.debug("ConfigComponent does not support watch, hot reload disabled");
1054
+ logger2.debug("ConfigComponent does not support watch, hot reload disabled");
600
1055
  return;
601
1056
  }
602
1057
  this.configWatcher = configComponent.watch("llm.*", (event) => {
603
1058
  this.onConfigChange(event);
604
1059
  });
605
- logger.debug("Config hot reload watcher registered for llm.*");
1060
+ logger2.debug("Config hot reload watcher registered for llm.*");
606
1061
  }
607
1062
  onConfigChange(event) {
608
- logger.info(`LLM config changed: ${event.key}`);
1063
+ logger2.info(`LLM config changed: ${event.key}`);
609
1064
  if (event.key === "llm.providers" || event.key.startsWith("llm.providers.")) {
610
- logger.info(`LLM provider config changed, will use new config on next call`);
1065
+ logger2.info(`LLM provider config changed, will use new config on next call`);
611
1066
  } else if (event.key === "llm.defaultModel") {
612
- logger.info(`LLM default model changed to: ${event.newValue}`);
1067
+ logger2.info(`LLM default model changed to: ${event.newValue}`);
613
1068
  } else if (event.key === "llm.defaultProvider") {
614
- logger.info(`LLM default provider changed to: ${event.newValue}`);
1069
+ logger2.info(`LLM default provider changed to: ${event.newValue}`);
615
1070
  } else {
616
- logger.debug(`LLM config updated: ${event.key}`);
1071
+ logger2.debug(`LLM config updated: ${event.key}`);
617
1072
  }
618
1073
  }
619
1074
  async onStart() {
@@ -691,52 +1146,177 @@ class LLMComponent extends BaseComponent {
691
1146
  abortSignal: request.abortSignal
692
1147
  };
693
1148
  }
1149
+ getAdapter() {
1150
+ const currentProvider = process.env.ROY_LLM_PROVIDER || "pi-ai";
1151
+ if (this.cachedAdapter && this.cachedAdapterProvider === currentProvider) {
1152
+ return this.cachedAdapter;
1153
+ }
1154
+ this.cachedAdapter = createLLMAdapter();
1155
+ this.cachedAdapterProvider = currentProvider;
1156
+ return this.cachedAdapter;
1157
+ }
1158
+ invalidateAdapterCache() {
1159
+ this.cachedAdapter = undefined;
1160
+ this.cachedAdapterProvider = undefined;
1161
+ }
694
1162
  async invoke(request) {
695
1163
  const startTime = Date.now();
696
1164
  if (this._status !== "running") {
697
1165
  throw new Error("LLMComponent is not running");
698
1166
  }
699
1167
  const ctx = this.resolveRequest(request);
1168
+ const adapter = this.getAdapter();
1169
+ const chatReq = {
1170
+ provider: ctx.providerId,
1171
+ modelId: ctx.model,
1172
+ messages: ctx.messages,
1173
+ tools: request.tools,
1174
+ systemPrompt: undefined,
1175
+ temperature: ctx.temperature,
1176
+ maxTokens: ctx.maxTokens,
1177
+ apiKey: ctx.invokeConfig.apiKey || "",
1178
+ baseURL: ctx.invokeConfig.baseURL,
1179
+ signal: ctx.abortSignal
1180
+ };
700
1181
  let output = {
701
1182
  content: "",
702
1183
  reasoning: undefined,
703
1184
  finishReason: "stop"
704
1185
  };
705
1186
  let finishUsage;
706
- const result = await invoke(ctx.invokeConfig, {
707
- messages: ctx.messages,
708
- model: ctx.invokeConfig.model,
709
- temperature: ctx.temperature,
710
- maxTokens: ctx.maxTokens,
711
- tools: request.tools,
712
- env: this.env,
713
- context: {
714
- sessionId: request.context?.sessionId,
715
- messageId: request.context?.messageId
716
- },
717
- toolChoice: request.toolChoice
718
- }, { abort: ctx.abortSignal });
719
- if (result.isError) {
720
- throw new Error(result.result);
1187
+ let resp;
1188
+ try {
1189
+ const streamHandle = await adapter.stream(chatReq);
1190
+ resp = await this.consumeStreamAndGetResult(streamHandle, request, ctx);
1191
+ if (resp.finishReason === "error") {
1192
+ throw new Error(resp.raw?.errorMessage || "adapter returned an error response");
1193
+ }
1194
+ } catch (adapterErr) {
1195
+ logger2.warn(`[LLMComponent.invoke] adapter(${adapter.name}) failed, falling back to AI SDK invoke: ${adapterErr.message}`);
1196
+ const result = await invoke(ctx.invokeConfig, {
1197
+ messages: ctx.messages,
1198
+ model: ctx.invokeConfig.model,
1199
+ temperature: ctx.temperature,
1200
+ maxTokens: ctx.maxTokens,
1201
+ tools: request.tools,
1202
+ env: this.env,
1203
+ context: {
1204
+ sessionId: request.context?.sessionId,
1205
+ messageId: request.context?.messageId
1206
+ },
1207
+ toolChoice: request.toolChoice
1208
+ }, { abort: ctx.abortSignal });
1209
+ if (result.isError) {
1210
+ throw new Error(result.result);
1211
+ }
1212
+ try {
1213
+ const parsed = JSON.parse(result.result);
1214
+ output.content = parsed.content || "";
1215
+ output.reasoning = parsed.reasoning || undefined;
1216
+ output.finishReason = parsed.tool_calls?.length ? "tool-calls" : "stop";
1217
+ output.toolCalls = parsed.tool_calls || [];
1218
+ if (parsed.usage) {
1219
+ finishUsage = {
1220
+ promptTokens: parsed.usage.promptTokens ?? parsed.usage.inputTokens ?? 0,
1221
+ completionTokens: parsed.usage.completionTokens ?? parsed.usage.outputTokens ?? 0,
1222
+ totalTokens: parsed.usage.totalTokens ?? 0
1223
+ };
1224
+ }
1225
+ output.usage = finishUsage;
1226
+ } catch {
1227
+ output.content = result.result;
1228
+ output.finishReason = "stop";
1229
+ }
1230
+ return this.finalizeOutput(request, ctx, output, finishUsage, startTime, `adapter-fallback:${adapter.name}`);
1231
+ }
1232
+ output.content = resp.text || "";
1233
+ output.finishReason = resp.finishReason;
1234
+ output.toolCalls = resp.toolCalls || [];
1235
+ if (resp.usage) {
1236
+ finishUsage = {
1237
+ promptTokens: resp.usage.promptTokens ?? 0,
1238
+ completionTokens: resp.usage.completionTokens ?? 0,
1239
+ totalTokens: resp.usage.totalTokens ?? 0
1240
+ };
721
1241
  }
1242
+ output.usage = finishUsage;
1243
+ return this.finalizeOutput(request, ctx, output, finishUsage, startTime, adapter.name);
1244
+ }
1245
+ async consumeStreamAndGetResult(streamHandle, request, ctx) {
1246
+ let accumulatedText = "";
1247
+ let accumulatedReasoning = "";
1248
+ let capturedResult;
1249
+ const emitEnvEvent = (fullType, payload) => {
1250
+ try {
1251
+ this.env?.pushEnvEvent?.({
1252
+ id: randomUUID(),
1253
+ type: fullType,
1254
+ timestamp: Date.now(),
1255
+ metadata: {
1256
+ source: "llm.adapter.stream",
1257
+ sessionId: request.context?.sessionId,
1258
+ messageId: request.context?.messageId,
1259
+ provider: ctx.providerId,
1260
+ model: ctx.model
1261
+ },
1262
+ payload
1263
+ });
1264
+ } catch (err) {
1265
+ logger2.warn(`Failed to push env event ${fullType}`, { error: String(err) });
1266
+ }
1267
+ };
722
1268
  try {
723
- const parsed = JSON.parse(result.result);
724
- output.content = parsed.content || "";
725
- output.reasoning = parsed.reasoning || undefined;
726
- output.finishReason = parsed.tool_calls?.length ? "tool-calls" : "stop";
727
- output.toolCalls = parsed.tool_calls || [];
728
- if (parsed.usage) {
729
- finishUsage = {
730
- promptTokens: parsed.usage.promptTokens ?? parsed.usage.inputTokens ?? 0,
731
- completionTokens: parsed.usage.completionTokens ?? parsed.usage.outputTokens ?? 0,
732
- totalTokens: parsed.usage.totalTokens ?? 0
733
- };
1269
+ for await (const rawEvent of streamHandle.events) {
1270
+ const event = rawEvent;
1271
+ if (!event || typeof event !== "object")
1272
+ continue;
1273
+ switch (event.type) {
1274
+ case "text_delta": {
1275
+ if (typeof event.delta === "string" && event.delta.length > 0) {
1276
+ accumulatedText += event.delta;
1277
+ emitEnvEvent("llm.text", {
1278
+ type: "text",
1279
+ content: accumulatedText,
1280
+ delta: event.delta,
1281
+ contentIndex: event.contentIndex
1282
+ });
1283
+ }
1284
+ break;
1285
+ }
1286
+ case "thinking_delta": {
1287
+ if (typeof event.delta === "string" && event.delta.length > 0) {
1288
+ accumulatedReasoning += event.delta;
1289
+ emitEnvEvent("llm.reasoning", {
1290
+ type: "reasoning",
1291
+ content: accumulatedReasoning,
1292
+ delta: event.delta,
1293
+ contentIndex: event.contentIndex
1294
+ });
1295
+ }
1296
+ break;
1297
+ }
1298
+ default:
1299
+ break;
1300
+ }
1301
+ }
1302
+ } finally {
1303
+ try {
1304
+ capturedResult = await streamHandle.result();
1305
+ } catch (resultErr) {
1306
+ if (accumulatedText) {
1307
+ capturedResult = {
1308
+ text: accumulatedText,
1309
+ finishReason: "aborted",
1310
+ usage: { promptTokens: 0, completionTokens: 0, totalTokens: 0 }
1311
+ };
1312
+ } else {
1313
+ throw resultErr;
1314
+ }
734
1315
  }
735
- output.usage = finishUsage;
736
- } catch {
737
- output.content = result.result;
738
- output.finishReason = "stop";
739
1316
  }
1317
+ return capturedResult;
1318
+ }
1319
+ finalizeOutput(request, ctx, output, finishUsage, startTime, adapterName) {
740
1320
  const latencyMs = Date.now() - startTime;
741
1321
  if (!request.skipThresholdCheck) {
742
1322
  const sessionId = request.context?.sessionId;
@@ -746,7 +1326,8 @@ class LLMComponent extends BaseComponent {
746
1326
  content: output.content,
747
1327
  reasoning: output.reasoning,
748
1328
  toolCalls: output.toolCalls,
749
- usage: output.usage
1329
+ usage: output.usage,
1330
+ adapter: adapterName
750
1331
  };
751
1332
  throw contextError;
752
1333
  }
@@ -810,4 +1391,4 @@ class LLMComponent extends BaseComponent {
810
1391
  __legacyDecorateClassTS([
811
1392
  TracedAs("llm.component.invoke", { recordParams: true, recordResult: true, log: true })
812
1393
  ], LLMComponent.prototype, "invoke", null);
813
- export { ProviderCapabilitiesSchema, ModelLimitsSchema, ProviderConfigSchema, LLMDefaultConfigSchema, LLMConfigSchema, ProviderManager, LLMTransform, LLMHooks, LLMComponent };
1394
+ export { ADAPTER_NAMES, PiAiAdapter, AiSdkAdapter, setLLMProvider, getLLMProviderOverride, createLLMAdapter, ProviderCapabilitiesSchema, ModelLimitsSchema, ProviderConfigSchema, LLMDefaultConfigSchema, LLMConfigSchema, ProviderManager, LLMTransform, LLMHooks, LLMComponent };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  SessionMessageConverter
3
- } from "./roy-agent-core-1k9j90s7.js";
3
+ } from "./roy-agent-core-879dbkpx.js";
4
4
  import {
5
5
  createLogger,
6
6
  init_logger
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-setting/roy-agent-core",
3
- "version": "1.6.42",
3
+ "version": "1.7.0",
4
4
  "type": "module",
5
5
  "description": "Core SDK for roy-agent - Environment, Components, Tools, Sessions, Tasks",
6
6
  "main": "./dist/index.js",
@@ -31,13 +31,16 @@
31
31
  "build": "bunup",
32
32
  "build:main": "bunup -- --entry src/index.ts",
33
33
  "clean": "rm -rf dist",
34
- "typecheck": "npx tsc --noEmit --skipLibCheck --project tsconfig.json"
34
+ "typecheck": "npx tsc --noEmit --skipLibCheck --project tsconfig.json",
35
+ "test:llm": "bun test test/llm/",
36
+ "test:llm:fast": "bun test --parallel 4 test/llm/"
35
37
  },
36
38
  "dependencies": {
37
39
  "@ai-sdk/anthropic": "^3.0.0",
38
40
  "@ai-sdk/google": "^3.0.0",
39
41
  "@ai-sdk/openai": "^3.0.0",
40
42
  "@ai-sdk/openai-compatible": "^2.0.0",
43
+ "@earendil-works/pi-ai": "^0.74.2",
41
44
  "@effect/platform": "^0.96.1",
42
45
  "@effect/platform-node": "^0.106.0",
43
46
  "@modelcontextprotocol/sdk": "^1.29.0",