@sprinterai/runtime 0.2.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.
Files changed (266) hide show
  1. package/LICENSE +21 -0
  2. package/dist/adapters/a2a-adapter.d.ts +24 -0
  3. package/dist/adapters/a2a-adapter.d.ts.map +1 -0
  4. package/dist/adapters/a2a-adapter.js +13 -0
  5. package/dist/adapters/a2a-adapter.js.map +1 -0
  6. package/dist/adapters/http-agent-adapter.d.ts +22 -0
  7. package/dist/adapters/http-agent-adapter.d.ts.map +1 -0
  8. package/dist/adapters/http-agent-adapter.js +13 -0
  9. package/dist/adapters/http-agent-adapter.js.map +1 -0
  10. package/dist/adapters/index.d.ts +9 -0
  11. package/dist/adapters/index.d.ts.map +1 -0
  12. package/dist/adapters/index.js +5 -0
  13. package/dist/adapters/index.js.map +1 -0
  14. package/dist/adapters/mcp-adapter.d.ts +19 -0
  15. package/dist/adapters/mcp-adapter.d.ts.map +1 -0
  16. package/dist/adapters/mcp-adapter.js +13 -0
  17. package/dist/adapters/mcp-adapter.js.map +1 -0
  18. package/dist/adapters/openclaw-adapter.d.ts +20 -0
  19. package/dist/adapters/openclaw-adapter.d.ts.map +1 -0
  20. package/dist/adapters/openclaw-adapter.js +13 -0
  21. package/dist/adapters/openclaw-adapter.js.map +1 -0
  22. package/dist/agent/agent-registry.d.ts +25 -0
  23. package/dist/agent/agent-registry.d.ts.map +1 -0
  24. package/dist/agent/agent-registry.js +42 -0
  25. package/dist/agent/agent-registry.js.map +1 -0
  26. package/dist/agent/agent-registry.test.d.ts +2 -0
  27. package/dist/agent/agent-registry.test.d.ts.map +1 -0
  28. package/dist/agent/agent-registry.test.js +55 -0
  29. package/dist/agent/agent-registry.test.js.map +1 -0
  30. package/dist/agent/agent-resolver.d.ts +41 -0
  31. package/dist/agent/agent-resolver.d.ts.map +1 -0
  32. package/dist/agent/agent-resolver.js +76 -0
  33. package/dist/agent/agent-resolver.js.map +1 -0
  34. package/dist/agent/agent-resolver.test.d.ts +2 -0
  35. package/dist/agent/agent-resolver.test.d.ts.map +1 -0
  36. package/dist/agent/agent-resolver.test.js +116 -0
  37. package/dist/agent/agent-resolver.test.js.map +1 -0
  38. package/dist/agent/delegate.d.ts +14 -0
  39. package/dist/agent/delegate.d.ts.map +1 -0
  40. package/dist/agent/delegate.js +35 -0
  41. package/dist/agent/delegate.js.map +1 -0
  42. package/dist/agent/delegate.test.d.ts +2 -0
  43. package/dist/agent/delegate.test.d.ts.map +1 -0
  44. package/dist/agent/delegate.test.js +64 -0
  45. package/dist/agent/delegate.test.js.map +1 -0
  46. package/dist/agent/execute-agent.d.ts +43 -0
  47. package/dist/agent/execute-agent.d.ts.map +1 -0
  48. package/dist/agent/execute-agent.js +43 -0
  49. package/dist/agent/execute-agent.js.map +1 -0
  50. package/dist/agent/index.d.ts +10 -0
  51. package/dist/agent/index.d.ts.map +1 -0
  52. package/dist/agent/index.js +6 -0
  53. package/dist/agent/index.js.map +1 -0
  54. package/dist/agent/prompt-builder.d.ts +16 -0
  55. package/dist/agent/prompt-builder.d.ts.map +1 -0
  56. package/dist/agent/prompt-builder.js +17 -0
  57. package/dist/agent/prompt-builder.js.map +1 -0
  58. package/dist/agent/prompt-builder.test.d.ts +2 -0
  59. package/dist/agent/prompt-builder.test.d.ts.map +1 -0
  60. package/dist/agent/prompt-builder.test.js +60 -0
  61. package/dist/agent/prompt-builder.test.js.map +1 -0
  62. package/dist/chat/chat-handler.d.ts +63 -0
  63. package/dist/chat/chat-handler.d.ts.map +1 -0
  64. package/dist/chat/chat-handler.js +74 -0
  65. package/dist/chat/chat-handler.js.map +1 -0
  66. package/dist/chat/chat-handler.test.d.ts +2 -0
  67. package/dist/chat/chat-handler.test.d.ts.map +1 -0
  68. package/dist/chat/chat-handler.test.js +112 -0
  69. package/dist/chat/chat-handler.test.js.map +1 -0
  70. package/dist/chat/index.d.ts +4 -0
  71. package/dist/chat/index.d.ts.map +1 -0
  72. package/dist/chat/index.js +3 -0
  73. package/dist/chat/index.js.map +1 -0
  74. package/dist/chat/message-utils.d.ts +26 -0
  75. package/dist/chat/message-utils.d.ts.map +1 -0
  76. package/dist/chat/message-utils.js +65 -0
  77. package/dist/chat/message-utils.js.map +1 -0
  78. package/dist/chat/message-utils.test.d.ts +2 -0
  79. package/dist/chat/message-utils.test.d.ts.map +1 -0
  80. package/dist/chat/message-utils.test.js +85 -0
  81. package/dist/chat/message-utils.test.js.map +1 -0
  82. package/dist/eval/eval-runner.d.ts +22 -0
  83. package/dist/eval/eval-runner.d.ts.map +1 -0
  84. package/dist/eval/eval-runner.js +56 -0
  85. package/dist/eval/eval-runner.js.map +1 -0
  86. package/dist/eval/eval-runner.test.d.ts +2 -0
  87. package/dist/eval/eval-runner.test.d.ts.map +1 -0
  88. package/dist/eval/eval-runner.test.js +89 -0
  89. package/dist/eval/eval-runner.test.js.map +1 -0
  90. package/dist/eval/index.d.ts +4 -0
  91. package/dist/eval/index.d.ts.map +1 -0
  92. package/dist/eval/index.js +3 -0
  93. package/dist/eval/index.js.map +1 -0
  94. package/dist/eval/scorers.d.ts +26 -0
  95. package/dist/eval/scorers.d.ts.map +1 -0
  96. package/dist/eval/scorers.js +76 -0
  97. package/dist/eval/scorers.js.map +1 -0
  98. package/dist/eval/scorers.test.d.ts +2 -0
  99. package/dist/eval/scorers.test.d.ts.map +1 -0
  100. package/dist/eval/scorers.test.js +91 -0
  101. package/dist/eval/scorers.test.js.map +1 -0
  102. package/dist/guardrail/guardrail-pipeline.d.ts +37 -0
  103. package/dist/guardrail/guardrail-pipeline.d.ts.map +1 -0
  104. package/dist/guardrail/guardrail-pipeline.js +63 -0
  105. package/dist/guardrail/guardrail-pipeline.js.map +1 -0
  106. package/dist/guardrail/guardrail-pipeline.test.d.ts +2 -0
  107. package/dist/guardrail/guardrail-pipeline.test.d.ts.map +1 -0
  108. package/dist/guardrail/guardrail-pipeline.test.js +74 -0
  109. package/dist/guardrail/guardrail-pipeline.test.js.map +1 -0
  110. package/dist/guardrail/index.d.ts +3 -0
  111. package/dist/guardrail/index.d.ts.map +1 -0
  112. package/dist/guardrail/index.js +2 -0
  113. package/dist/guardrail/index.js.map +1 -0
  114. package/dist/index.d.ts +46 -0
  115. package/dist/index.d.ts.map +1 -0
  116. package/dist/index.js +39 -0
  117. package/dist/index.js.map +1 -0
  118. package/dist/memory/index.d.ts +4 -0
  119. package/dist/memory/index.d.ts.map +1 -0
  120. package/dist/memory/index.js +3 -0
  121. package/dist/memory/index.js.map +1 -0
  122. package/dist/memory/memory-manager.d.ts +28 -0
  123. package/dist/memory/memory-manager.d.ts.map +1 -0
  124. package/dist/memory/memory-manager.js +34 -0
  125. package/dist/memory/memory-manager.js.map +1 -0
  126. package/dist/memory/memory-prompt.d.ts +10 -0
  127. package/dist/memory/memory-prompt.d.ts.map +1 -0
  128. package/dist/memory/memory-prompt.js +29 -0
  129. package/dist/memory/memory-prompt.js.map +1 -0
  130. package/dist/module/create-runtime.d.ts +65 -0
  131. package/dist/module/create-runtime.d.ts.map +1 -0
  132. package/dist/module/create-runtime.js +75 -0
  133. package/dist/module/create-runtime.js.map +1 -0
  134. package/dist/module/create-runtime.test.d.ts +2 -0
  135. package/dist/module/create-runtime.test.d.ts.map +1 -0
  136. package/dist/module/create-runtime.test.js +144 -0
  137. package/dist/module/create-runtime.test.js.map +1 -0
  138. package/dist/module/index.d.ts +5 -0
  139. package/dist/module/index.d.ts.map +1 -0
  140. package/dist/module/index.js +3 -0
  141. package/dist/module/index.js.map +1 -0
  142. package/dist/module/module-loader.d.ts +32 -0
  143. package/dist/module/module-loader.d.ts.map +1 -0
  144. package/dist/module/module-loader.js +123 -0
  145. package/dist/module/module-loader.js.map +1 -0
  146. package/dist/module/module-loader.test.d.ts +2 -0
  147. package/dist/module/module-loader.test.d.ts.map +1 -0
  148. package/dist/module/module-loader.test.js +96 -0
  149. package/dist/module/module-loader.test.js.map +1 -0
  150. package/dist/scoring/compute-score.d.ts +32 -0
  151. package/dist/scoring/compute-score.d.ts.map +1 -0
  152. package/dist/scoring/compute-score.js +54 -0
  153. package/dist/scoring/compute-score.js.map +1 -0
  154. package/dist/scoring/compute-score.test.d.ts +2 -0
  155. package/dist/scoring/compute-score.test.d.ts.map +1 -0
  156. package/dist/scoring/compute-score.test.js +99 -0
  157. package/dist/scoring/compute-score.test.js.map +1 -0
  158. package/dist/scoring/index.d.ts +3 -0
  159. package/dist/scoring/index.d.ts.map +1 -0
  160. package/dist/scoring/index.js +2 -0
  161. package/dist/scoring/index.js.map +1 -0
  162. package/dist/testing/in-memory-agent-store.d.ts +16 -0
  163. package/dist/testing/in-memory-agent-store.d.ts.map +1 -0
  164. package/dist/testing/in-memory-agent-store.js +37 -0
  165. package/dist/testing/in-memory-agent-store.js.map +1 -0
  166. package/dist/testing/in-memory-agent-store.test.d.ts +2 -0
  167. package/dist/testing/in-memory-agent-store.test.d.ts.map +1 -0
  168. package/dist/testing/in-memory-agent-store.test.js +111 -0
  169. package/dist/testing/in-memory-agent-store.test.js.map +1 -0
  170. package/dist/testing/in-memory-chat-store.d.ts +28 -0
  171. package/dist/testing/in-memory-chat-store.d.ts.map +1 -0
  172. package/dist/testing/in-memory-chat-store.js +87 -0
  173. package/dist/testing/in-memory-chat-store.js.map +1 -0
  174. package/dist/testing/in-memory-entity-store.d.ts +34 -0
  175. package/dist/testing/in-memory-entity-store.d.ts.map +1 -0
  176. package/dist/testing/in-memory-entity-store.js +134 -0
  177. package/dist/testing/in-memory-entity-store.js.map +1 -0
  178. package/dist/testing/in-memory-entity-store.test.d.ts +2 -0
  179. package/dist/testing/in-memory-entity-store.test.d.ts.map +1 -0
  180. package/dist/testing/in-memory-entity-store.test.js +341 -0
  181. package/dist/testing/in-memory-entity-store.test.js.map +1 -0
  182. package/dist/testing/in-memory-memory-store.d.ts +25 -0
  183. package/dist/testing/in-memory-memory-store.d.ts.map +1 -0
  184. package/dist/testing/in-memory-memory-store.js +59 -0
  185. package/dist/testing/in-memory-memory-store.js.map +1 -0
  186. package/dist/testing/in-memory-task-store.d.ts +20 -0
  187. package/dist/testing/in-memory-task-store.d.ts.map +1 -0
  188. package/dist/testing/in-memory-task-store.js +59 -0
  189. package/dist/testing/in-memory-task-store.js.map +1 -0
  190. package/dist/testing/in-memory-tenant-store.d.ts +16 -0
  191. package/dist/testing/in-memory-tenant-store.d.ts.map +1 -0
  192. package/dist/testing/in-memory-tenant-store.js +46 -0
  193. package/dist/testing/in-memory-tenant-store.js.map +1 -0
  194. package/dist/testing/in-memory-tool-store.d.ts +17 -0
  195. package/dist/testing/in-memory-tool-store.d.ts.map +1 -0
  196. package/dist/testing/in-memory-tool-store.js +39 -0
  197. package/dist/testing/in-memory-tool-store.js.map +1 -0
  198. package/dist/testing/index.d.ts +8 -0
  199. package/dist/testing/index.d.ts.map +1 -0
  200. package/dist/testing/index.js +8 -0
  201. package/dist/testing/index.js.map +1 -0
  202. package/dist/tool/ai-bridge.d.ts +13 -0
  203. package/dist/tool/ai-bridge.d.ts.map +1 -0
  204. package/dist/tool/ai-bridge.js +27 -0
  205. package/dist/tool/ai-bridge.js.map +1 -0
  206. package/dist/tool/ai-bridge.test.d.ts +2 -0
  207. package/dist/tool/ai-bridge.test.d.ts.map +1 -0
  208. package/dist/tool/ai-bridge.test.js +40 -0
  209. package/dist/tool/ai-bridge.test.js.map +1 -0
  210. package/dist/tool/entity-tools-factory.d.ts +7 -0
  211. package/dist/tool/entity-tools-factory.d.ts.map +1 -0
  212. package/dist/tool/entity-tools-factory.js +160 -0
  213. package/dist/tool/entity-tools-factory.js.map +1 -0
  214. package/dist/tool/entity-tools-factory.test.d.ts +2 -0
  215. package/dist/tool/entity-tools-factory.test.d.ts.map +1 -0
  216. package/dist/tool/entity-tools-factory.test.js +160 -0
  217. package/dist/tool/entity-tools-factory.test.js.map +1 -0
  218. package/dist/tool/index.d.ts +8 -0
  219. package/dist/tool/index.d.ts.map +1 -0
  220. package/dist/tool/index.js +6 -0
  221. package/dist/tool/index.js.map +1 -0
  222. package/dist/tool/resolve-tools.d.ts +28 -0
  223. package/dist/tool/resolve-tools.d.ts.map +1 -0
  224. package/dist/tool/resolve-tools.js +54 -0
  225. package/dist/tool/resolve-tools.js.map +1 -0
  226. package/dist/tool/resolve-tools.test.d.ts +2 -0
  227. package/dist/tool/resolve-tools.test.d.ts.map +1 -0
  228. package/dist/tool/resolve-tools.test.js +111 -0
  229. package/dist/tool/resolve-tools.test.js.map +1 -0
  230. package/dist/tool/tool-executor.d.ts +30 -0
  231. package/dist/tool/tool-executor.d.ts.map +1 -0
  232. package/dist/tool/tool-executor.js +64 -0
  233. package/dist/tool/tool-executor.js.map +1 -0
  234. package/dist/tool/tool-executor.test.d.ts +2 -0
  235. package/dist/tool/tool-executor.test.d.ts.map +1 -0
  236. package/dist/tool/tool-executor.test.js +105 -0
  237. package/dist/tool/tool-executor.test.js.map +1 -0
  238. package/dist/tool/tool-registry.d.ts +29 -0
  239. package/dist/tool/tool-registry.d.ts.map +1 -0
  240. package/dist/tool/tool-registry.js +59 -0
  241. package/dist/tool/tool-registry.js.map +1 -0
  242. package/dist/tool/tool-registry.test.d.ts +2 -0
  243. package/dist/tool/tool-registry.test.d.ts.map +1 -0
  244. package/dist/tool/tool-registry.test.js +76 -0
  245. package/dist/tool/tool-registry.test.js.map +1 -0
  246. package/dist/workflow/compile.d.ts +17 -0
  247. package/dist/workflow/compile.d.ts.map +1 -0
  248. package/dist/workflow/compile.js +83 -0
  249. package/dist/workflow/compile.js.map +1 -0
  250. package/dist/workflow/compile.test.d.ts +2 -0
  251. package/dist/workflow/compile.test.d.ts.map +1 -0
  252. package/dist/workflow/compile.test.js +154 -0
  253. package/dist/workflow/compile.test.js.map +1 -0
  254. package/dist/workflow/index.d.ts +4 -0
  255. package/dist/workflow/index.d.ts.map +1 -0
  256. package/dist/workflow/index.js +3 -0
  257. package/dist/workflow/index.js.map +1 -0
  258. package/dist/workflow/status.d.ts +21 -0
  259. package/dist/workflow/status.d.ts.map +1 -0
  260. package/dist/workflow/status.js +55 -0
  261. package/dist/workflow/status.js.map +1 -0
  262. package/dist/workflow/status.test.d.ts +2 -0
  263. package/dist/workflow/status.test.d.ts.map +1 -0
  264. package/dist/workflow/status.test.js +176 -0
  265. package/dist/workflow/status.test.js.map +1 -0
  266. package/package.json +100 -0
@@ -0,0 +1,160 @@
1
+ import { describe, it, expect, beforeEach } from 'vitest';
2
+ import { InMemoryEntityStore } from '../testing/in-memory-entity-store';
3
+ import { createEntityTools } from './entity-tools-factory';
4
+ const TENANT_ID = 'test-tenant';
5
+ function makeEntityType(slug) {
6
+ return {
7
+ id: `et-${slug}`,
8
+ tenant_id: TENANT_ID,
9
+ slug,
10
+ name: slug.charAt(0).toUpperCase() + slug.slice(1),
11
+ json_schema: null,
12
+ visibility: 'tenant',
13
+ created_at: new Date().toISOString(),
14
+ updated_at: new Date().toISOString(),
15
+ };
16
+ }
17
+ describe('createEntityTools', () => {
18
+ let store;
19
+ let tools;
20
+ beforeEach(() => {
21
+ store = new InMemoryEntityStore();
22
+ store.seedEntityType(makeEntityType('company'));
23
+ store.seedEntityType(makeEntityType('person'));
24
+ tools = createEntityTools(store, TENANT_ID);
25
+ });
26
+ function findTool(slug) {
27
+ const tool = tools.find((t) => t.slug === slug);
28
+ if (!tool)
29
+ throw new Error(`Tool ${slug} not found`);
30
+ return tool;
31
+ }
32
+ it('creates 8 entity tools', () => {
33
+ expect(tools).toHaveLength(8);
34
+ const slugs = tools.map((t) => t.slug);
35
+ expect(slugs).toContain('searchEntities');
36
+ expect(slugs).toContain('getEntity');
37
+ expect(slugs).toContain('createEntity');
38
+ expect(slugs).toContain('updateEntity');
39
+ expect(slugs).toContain('deleteEntity');
40
+ expect(slugs).toContain('createRelation');
41
+ expect(slugs).toContain('listEntityTypes');
42
+ expect(slugs).toContain('getEntityStats');
43
+ });
44
+ it('all tools have requiredPermission set', () => {
45
+ for (const tool of tools) {
46
+ expect(tool.requiredPermission).toBeDefined();
47
+ }
48
+ });
49
+ it('searchEntities searches by query', async () => {
50
+ await store.createEntity({
51
+ typeSlug: 'company',
52
+ title: 'Acme Corp',
53
+ content: {},
54
+ });
55
+ await store.createEntity({
56
+ typeSlug: 'company',
57
+ title: 'Beta Inc',
58
+ content: {},
59
+ });
60
+ const result = await findTool('searchEntities').execute({
61
+ query: 'acme',
62
+ });
63
+ const entities = result;
64
+ expect(entities).toHaveLength(1);
65
+ expect(entities[0].title).toBe('Acme Corp');
66
+ });
67
+ it('getEntity returns entity by ID', async () => {
68
+ const created = await store.createEntity({
69
+ typeSlug: 'company',
70
+ title: 'Test Co',
71
+ content: {},
72
+ });
73
+ const result = await findTool('getEntity').execute({ id: created.id });
74
+ const entity = result;
75
+ expect(entity.id).toBe(created.id);
76
+ expect(entity.title).toBe('Test Co');
77
+ });
78
+ it('getEntity returns error for missing entity', async () => {
79
+ const result = await findTool('getEntity').execute({ id: 'nonexistent' });
80
+ expect(result).toEqual({ error: 'Entity not found: nonexistent' });
81
+ });
82
+ it('createEntity creates and returns entity', async () => {
83
+ const result = await findTool('createEntity').execute({
84
+ typeSlug: 'company',
85
+ title: 'New Corp',
86
+ content: { website: 'https://newcorp.com' },
87
+ });
88
+ const entity = result;
89
+ expect(entity.title).toBe('New Corp');
90
+ expect(entity.id).toBeDefined();
91
+ });
92
+ it('updateEntity updates entity fields', async () => {
93
+ const created = await store.createEntity({
94
+ typeSlug: 'company',
95
+ title: 'Old Name',
96
+ content: {},
97
+ });
98
+ const result = await findTool('updateEntity').execute({
99
+ id: created.id,
100
+ title: 'New Name',
101
+ });
102
+ const updated = result;
103
+ expect(updated.title).toBe('New Name');
104
+ });
105
+ it('deleteEntity removes entity', async () => {
106
+ const created = await store.createEntity({
107
+ typeSlug: 'company',
108
+ title: 'To Delete',
109
+ content: {},
110
+ });
111
+ await findTool('deleteEntity').execute({ id: created.id });
112
+ const fetched = await store.getEntity(created.id);
113
+ expect(fetched).toBeNull();
114
+ });
115
+ it('createRelation creates a relation', async () => {
116
+ const a = await store.createEntity({
117
+ typeSlug: 'company',
118
+ title: 'A',
119
+ content: {},
120
+ });
121
+ const b = await store.createEntity({
122
+ typeSlug: 'person',
123
+ title: 'B',
124
+ content: {},
125
+ });
126
+ const result = await findTool('createRelation').execute({
127
+ fromId: a.id,
128
+ toId: b.id,
129
+ type: 'employs',
130
+ });
131
+ expect(result).toEqual({
132
+ created: true,
133
+ from: a.id,
134
+ to: b.id,
135
+ type: 'employs',
136
+ });
137
+ expect(store.getRelations()).toHaveLength(1);
138
+ });
139
+ it('listEntityTypes returns all types', async () => {
140
+ const result = await findTool('listEntityTypes').execute({});
141
+ const types = result;
142
+ expect(types).toHaveLength(2);
143
+ });
144
+ it('getEntityStats returns counts', async () => {
145
+ await store.createEntity({
146
+ typeSlug: 'company',
147
+ title: 'A',
148
+ content: {},
149
+ });
150
+ await store.createEntity({
151
+ typeSlug: 'company',
152
+ title: 'B',
153
+ content: {},
154
+ });
155
+ const result = await findTool('getEntityStats').execute({});
156
+ const counts = result;
157
+ expect(counts['et-company']).toBe(2);
158
+ });
159
+ });
160
+ //# sourceMappingURL=entity-tools-factory.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity-tools-factory.test.js","sourceRoot":"","sources":["../../src/tool/entity-tools-factory.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export { ToolRegistry } from "./tool-registry";
2
+ export { toAITool, toAIToolSet } from "./ai-bridge";
3
+ export { executeTool } from "./tool-executor";
4
+ export type { ExecuteToolOptions, ExecuteToolResult } from "./tool-executor";
5
+ export { createEntityTools } from "./entity-tools-factory";
6
+ export { resolveAgentTools } from "./resolve-tools";
7
+ export type { ResolveToolsOptions } from "./resolve-tools";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tool/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAC7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,YAAY,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,6 @@
1
+ export { ToolRegistry } from "./tool-registry";
2
+ export { toAITool, toAIToolSet } from "./ai-bridge";
3
+ export { executeTool } from "./tool-executor";
4
+ export { createEntityTools } from "./entity-tools-factory";
5
+ export { resolveAgentTools } from "./resolve-tools";
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tool/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,28 @@
1
+ import type { AgentConfig, ToolDefinition, AppPermission } from '@sprinterai/core';
2
+ import type { ToolSet } from 'ai';
3
+ /** Options for resolving tools. */
4
+ export interface ResolveToolsOptions {
5
+ /** All registered tools (the full registry). */
6
+ allTools: ToolDefinition[];
7
+ /** Agent config with toolGroups and customTools. */
8
+ agentConfig: AgentConfig;
9
+ /** Caller's permissions. Tools requiring missing permissions are filtered out. */
10
+ permissions?: AppPermission[];
11
+ /** Map from tool group name to tool slugs in that group. */
12
+ toolGroupMap?: Record<string, string[]>;
13
+ }
14
+ /**
15
+ * Resolve tools for an agent: apply tool groups, custom tools, and permission filtering.
16
+ *
17
+ * Steps:
18
+ * 1. Collect tool slugs from agent's toolGroups (using toolGroupMap)
19
+ * 2. Add agent's customTools
20
+ * 3. Look up each slug in allTools
21
+ * 4. Filter out tools that require a permission the caller doesn't have
22
+ * 5. Convert to AI SDK ToolSet
23
+ */
24
+ export declare function resolveAgentTools(options: ResolveToolsOptions): {
25
+ tools: ToolDefinition[];
26
+ toolSet: ToolSet;
27
+ };
28
+ //# sourceMappingURL=resolve-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-tools.d.ts","sourceRoot":"","sources":["../../src/tool/resolve-tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACnF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAIlC,mCAAmC;AACnC,MAAM,WAAW,mBAAmB;IAClC,gDAAgD;IAChD,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,oDAAoD;IACpD,WAAW,EAAE,WAAW,CAAC;IACzB,kFAAkF;IAClF,WAAW,CAAC,EAAE,aAAa,EAAE,CAAC;IAC9B,4DAA4D;IAC5D,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CACzC;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,mBAAmB,GAAG;IAC/D,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;CAClB,CAgDA"}
@@ -0,0 +1,54 @@
1
+ import { toAIToolSet } from './ai-bridge';
2
+ /**
3
+ * Resolve tools for an agent: apply tool groups, custom tools, and permission filtering.
4
+ *
5
+ * Steps:
6
+ * 1. Collect tool slugs from agent's toolGroups (using toolGroupMap)
7
+ * 2. Add agent's customTools
8
+ * 3. Look up each slug in allTools
9
+ * 4. Filter out tools that require a permission the caller doesn't have
10
+ * 5. Convert to AI SDK ToolSet
11
+ */
12
+ export function resolveAgentTools(options) {
13
+ const { allTools, agentConfig, permissions, toolGroupMap } = options;
14
+ // Build a lookup map
15
+ const toolMap = new Map();
16
+ for (const t of allTools) {
17
+ toolMap.set(t.slug, t);
18
+ }
19
+ // Collect slugs from tool groups
20
+ const slugs = new Set();
21
+ if (agentConfig.toolGroups && toolGroupMap) {
22
+ for (const group of agentConfig.toolGroups) {
23
+ const groupSlugs = toolGroupMap[group];
24
+ if (groupSlugs) {
25
+ for (const slug of groupSlugs) {
26
+ slugs.add(slug);
27
+ }
28
+ }
29
+ }
30
+ }
31
+ // Add custom tool slugs
32
+ if (agentConfig.customTools) {
33
+ for (const slug of agentConfig.customTools) {
34
+ slugs.add(slug);
35
+ }
36
+ }
37
+ // Look up tools and filter by permission
38
+ const resolved = [];
39
+ for (const slug of slugs) {
40
+ const tool = toolMap.get(slug);
41
+ if (!tool)
42
+ continue;
43
+ // If permissions are provided, filter tools that require a missing permission
44
+ if (permissions && tool.requiredPermission && !permissions.includes(tool.requiredPermission)) {
45
+ continue;
46
+ }
47
+ resolved.push(tool);
48
+ }
49
+ return {
50
+ tools: resolved,
51
+ toolSet: toAIToolSet(resolved),
52
+ };
53
+ }
54
+ //# sourceMappingURL=resolve-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-tools.js","sourceRoot":"","sources":["../../src/tool/resolve-tools.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAc1C;;;;;;;;;GASG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAA4B;IAI5D,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC;IAErE,qBAAqB;IACrB,MAAM,OAAO,GAAG,IAAI,GAAG,EAA0B,CAAC;IAClD,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACzB,CAAC;IAED,iCAAiC;IACjC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAEhC,IAAI,WAAW,CAAC,UAAU,IAAI,YAAY,EAAE,CAAC;QAC3C,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,UAAU,EAAE,CAAC;YAC3C,MAAM,UAAU,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YACvC,IAAI,UAAU,EAAE,CAAC;gBACf,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;oBAC9B,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBAClB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,wBAAwB;IACxB,IAAI,WAAW,CAAC,WAAW,EAAE,CAAC;QAC5B,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,WAAW,EAAE,CAAC;YAC3C,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAED,yCAAyC;IACzC,MAAM,QAAQ,GAAqB,EAAE,CAAC;IACtC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,CAAC,IAAI;YAAE,SAAS;QAEpB,8EAA8E;QAC9E,IAAI,WAAW,IAAI,IAAI,CAAC,kBAAkB,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC;YAC7F,SAAS;QACX,CAAC;QAED,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC;IAED,OAAO;QACL,KAAK,EAAE,QAAQ;QACf,OAAO,EAAE,WAAW,CAAC,QAAQ,CAAC;KAC/B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=resolve-tools.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-tools.test.d.ts","sourceRoot":"","sources":["../../src/tool/resolve-tools.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,111 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { z } from 'zod';
3
+ import { resolveAgentTools } from './resolve-tools';
4
+ function makeTool(slug, overrides) {
5
+ return {
6
+ slug,
7
+ name: `Tool ${slug}`,
8
+ description: `Desc ${slug}`,
9
+ category: 'test',
10
+ icon: 'wrench',
11
+ inputSchema: z.object({ q: z.string() }),
12
+ execute: async () => ({}),
13
+ ...overrides,
14
+ };
15
+ }
16
+ describe('resolveAgentTools', () => {
17
+ const allTools = [
18
+ makeTool('searchEntities', {
19
+ requiredPermission: 'entities.team.read',
20
+ }),
21
+ makeTool('createEntity', {
22
+ requiredPermission: 'entities.team.create',
23
+ }),
24
+ makeTool('deleteEntity', {
25
+ requiredPermission: 'entities.team.delete',
26
+ }),
27
+ makeTool('webSearch'),
28
+ makeTool('customCalc'),
29
+ ];
30
+ const toolGroupMap = {
31
+ entity: ['searchEntities', 'createEntity', 'deleteEntity'],
32
+ web: ['webSearch'],
33
+ };
34
+ it('resolves tools from toolGroups', () => {
35
+ const config = { toolGroups: ['entity'] };
36
+ const { tools, toolSet } = resolveAgentTools({
37
+ allTools,
38
+ agentConfig: config,
39
+ toolGroupMap,
40
+ });
41
+ expect(tools.map((t) => t.slug)).toEqual(expect.arrayContaining(['searchEntities', 'createEntity', 'deleteEntity']));
42
+ expect(Object.keys(toolSet)).toHaveLength(3);
43
+ });
44
+ it('resolves custom tools by slug', () => {
45
+ const config = { customTools: ['customCalc'] };
46
+ const { tools } = resolveAgentTools({
47
+ allTools,
48
+ agentConfig: config,
49
+ toolGroupMap,
50
+ });
51
+ expect(tools.map((t) => t.slug)).toEqual(['customCalc']);
52
+ });
53
+ it('merges toolGroups and customTools', () => {
54
+ const config = {
55
+ toolGroups: ['web'],
56
+ customTools: ['customCalc'],
57
+ };
58
+ const { tools } = resolveAgentTools({
59
+ allTools,
60
+ agentConfig: config,
61
+ toolGroupMap,
62
+ });
63
+ const slugs = tools.map((t) => t.slug);
64
+ expect(slugs).toContain('webSearch');
65
+ expect(slugs).toContain('customCalc');
66
+ });
67
+ it('filters tools by permissions', () => {
68
+ const config = { toolGroups: ['entity'] };
69
+ const { tools } = resolveAgentTools({
70
+ allTools,
71
+ agentConfig: config,
72
+ toolGroupMap,
73
+ permissions: ['entities.team.read'],
74
+ });
75
+ // Only searchEntities should pass (requires entities.team.read)
76
+ // createEntity (entities.team.create) and deleteEntity (entities.team.delete) filtered
77
+ expect(tools.map((t) => t.slug)).toEqual(['searchEntities']);
78
+ });
79
+ it('skips permission check when permissions not provided', () => {
80
+ const config = { toolGroups: ['entity'] };
81
+ const { tools } = resolveAgentTools({
82
+ allTools,
83
+ agentConfig: config,
84
+ toolGroupMap,
85
+ });
86
+ // All 3 entity tools included
87
+ expect(tools).toHaveLength(3);
88
+ });
89
+ it('ignores unknown slugs gracefully', () => {
90
+ const config = {
91
+ customTools: ['nonexistent', 'customCalc'],
92
+ };
93
+ const { tools } = resolveAgentTools({
94
+ allTools,
95
+ agentConfig: config,
96
+ toolGroupMap,
97
+ });
98
+ expect(tools.map((t) => t.slug)).toEqual(['customCalc']);
99
+ });
100
+ it('returns empty tools for empty config', () => {
101
+ const config = {};
102
+ const { tools, toolSet } = resolveAgentTools({
103
+ allTools,
104
+ agentConfig: config,
105
+ toolGroupMap,
106
+ });
107
+ expect(tools).toHaveLength(0);
108
+ expect(Object.keys(toolSet)).toHaveLength(0);
109
+ });
110
+ });
111
+ //# sourceMappingURL=resolve-tools.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-tools.test.js","sourceRoot":"","sources":["../../src/tool/resolve-tools.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import type { ToolDefinition, ToolStore, AppPermission } from '@sprinterai/core';
2
+ /** Options for tool execution. */
3
+ export interface ExecuteToolOptions {
4
+ /** User's permissions — if set, checks requiredPermission on the tool. */
5
+ permissions?: AppPermission[];
6
+ /** Optional ToolStore to record the run. */
7
+ toolStore?: ToolStore;
8
+ /** Tenant ID for recording. */
9
+ tenantId?: string;
10
+ /** User ID for recording. */
11
+ userId?: string;
12
+ /** Source context. */
13
+ source?: 'web' | 'agent' | 'api';
14
+ /** Optional chat ID for tracing. */
15
+ chatId?: string;
16
+ /** Optional session ID for tracing. */
17
+ sessionId?: string;
18
+ }
19
+ /** Result of a tool execution. */
20
+ export interface ExecuteToolResult {
21
+ output: unknown;
22
+ durationMs: number;
23
+ status: 'success' | 'error';
24
+ error?: string;
25
+ }
26
+ /**
27
+ * Execute a tool: validate input, check permissions, run, optionally record.
28
+ */
29
+ export declare function executeTool(tool: ToolDefinition, input: unknown, options?: ExecuteToolOptions): Promise<ExecuteToolResult>;
30
+ //# sourceMappingURL=tool-executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-executor.d.ts","sourceRoot":"","sources":["../../src/tool/tool-executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjF,kCAAkC;AAClC,MAAM,WAAW,kBAAkB;IACjC,0EAA0E;IAC1E,WAAW,CAAC,EAAE,aAAa,EAAE,CAAC;IAC9B,4CAA4C;IAC5C,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6BAA6B;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sBAAsB;IACtB,MAAM,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,KAAK,CAAC;IACjC,oCAAoC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uCAAuC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,kCAAkC;AAClC,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,cAAc,EACpB,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,iBAAiB,CAAC,CAqE5B"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Execute a tool: validate input, check permissions, run, optionally record.
3
+ */
4
+ export async function executeTool(tool, input, options) {
5
+ // Check permission
6
+ if (tool.requiredPermission &&
7
+ options?.permissions &&
8
+ !options.permissions.includes(tool.requiredPermission)) {
9
+ return {
10
+ output: null,
11
+ durationMs: 0,
12
+ status: 'error',
13
+ error: `Permission denied: requires ${tool.requiredPermission}`,
14
+ };
15
+ }
16
+ // Validate input against schema
17
+ const parseResult = tool.inputSchema.safeParse(input);
18
+ if (!parseResult.success) {
19
+ return {
20
+ output: null,
21
+ durationMs: 0,
22
+ status: 'error',
23
+ error: `Invalid input: ${parseResult.error.message}`,
24
+ };
25
+ }
26
+ const start = Date.now();
27
+ let output = null;
28
+ let status = 'success';
29
+ let error;
30
+ try {
31
+ output = await tool.execute(parseResult.data);
32
+ }
33
+ catch (err) {
34
+ status = 'error';
35
+ error = err instanceof Error ? err.message : String(err);
36
+ }
37
+ const durationMs = Date.now() - start;
38
+ // Record if store provided
39
+ if (options?.toolStore) {
40
+ const runInput = typeof parseResult.data === 'object' && parseResult.data !== null
41
+ ? parseResult.data
42
+ : { _raw: parseResult.data };
43
+ const runOutput = typeof output === 'object' && output !== null
44
+ ? output
45
+ : output !== undefined && output !== null
46
+ ? { _raw: output }
47
+ : null;
48
+ await options.toolStore.recordToolRun({
49
+ tenant_id: options.tenantId ?? '',
50
+ tool_slug: tool.slug,
51
+ user_id: options.userId ?? null,
52
+ input: runInput,
53
+ output: runOutput,
54
+ status,
55
+ error: error ?? null,
56
+ duration_ms: durationMs,
57
+ source: options.source ?? 'api',
58
+ chat_id: options.chatId ?? null,
59
+ session_id: options.sessionId ?? null,
60
+ });
61
+ }
62
+ return { output, durationMs, status, error };
63
+ }
64
+ //# sourceMappingURL=tool-executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-executor.js","sourceRoot":"","sources":["../../src/tool/tool-executor.ts"],"names":[],"mappings":"AA4BA;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,IAAoB,EACpB,KAAc,EACd,OAA4B;IAE5B,mBAAmB;IACnB,IACE,IAAI,CAAC,kBAAkB;QACvB,OAAO,EAAE,WAAW;QACpB,CAAC,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,kBAAkB,CAAC,EACtD,CAAC;QACD,OAAO;YACL,MAAM,EAAE,IAAI;YACZ,UAAU,EAAE,CAAC;YACb,MAAM,EAAE,OAAO;YACf,KAAK,EAAE,+BAA+B,IAAI,CAAC,kBAAkB,EAAE;SAChE,CAAC;IACJ,CAAC;IAED,gCAAgC;IAChC,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACtD,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;QACzB,OAAO;YACL,MAAM,EAAE,IAAI;YACZ,UAAU,EAAE,CAAC;YACb,MAAM,EAAE,OAAO;YACf,KAAK,EAAE,kBAAkB,WAAW,CAAC,KAAK,CAAC,OAAO,EAAE;SACrD,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACzB,IAAI,MAAM,GAAY,IAAI,CAAC;IAC3B,IAAI,MAAM,GAAwB,SAAS,CAAC;IAC5C,IAAI,KAAyB,CAAC;IAE9B,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IAChD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,OAAO,CAAC;QACjB,KAAK,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC3D,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;IAEtC,2BAA2B;IAC3B,IAAI,OAAO,EAAE,SAAS,EAAE,CAAC;QACvB,MAAM,QAAQ,GACZ,OAAO,WAAW,CAAC,IAAI,KAAK,QAAQ,IAAI,WAAW,CAAC,IAAI,KAAK,IAAI;YAC/D,CAAC,CAAE,WAAW,CAAC,IAAgC;YAC/C,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,EAAE,CAAC;QACjC,MAAM,SAAS,GACb,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI;YAC3C,CAAC,CAAE,MAAkC;YACrC,CAAC,CAAC,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,IAAI;gBACvC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE;gBAClB,CAAC,CAAC,IAAI,CAAC;QAEb,MAAM,OAAO,CAAC,SAAS,CAAC,aAAa,CAAC;YACpC,SAAS,EAAE,OAAO,CAAC,QAAQ,IAAI,EAAE;YACjC,SAAS,EAAE,IAAI,CAAC,IAAI;YACpB,OAAO,EAAE,OAAO,CAAC,MAAM,IAAI,IAAI;YAC/B,KAAK,EAAE,QAAQ;YACf,MAAM,EAAE,SAAS;YACjB,MAAM;YACN,KAAK,EAAE,KAAK,IAAI,IAAI;YACpB,WAAW,EAAE,UAAU;YACvB,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,KAAK;YAC/B,OAAO,EAAE,OAAO,CAAC,MAAM,IAAI,IAAI;YAC/B,UAAU,EAAE,OAAO,CAAC,SAAS,IAAI,IAAI;SACtC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AAC/C,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=tool-executor.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-executor.test.d.ts","sourceRoot":"","sources":["../../src/tool/tool-executor.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,105 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { z } from 'zod';
3
+ import { InMemoryToolStore } from '../testing/in-memory-tool-store';
4
+ import { executeTool } from './tool-executor';
5
+ function makeTool(overrides) {
6
+ return {
7
+ slug: 'test-tool',
8
+ name: 'Test Tool',
9
+ description: 'A test tool',
10
+ category: 'test',
11
+ icon: 'wrench',
12
+ inputSchema: z.object({ value: z.number() }),
13
+ execute: async (input) => {
14
+ const typed = input;
15
+ return { doubled: typed.value * 2 };
16
+ },
17
+ ...overrides,
18
+ };
19
+ }
20
+ describe('executeTool', () => {
21
+ it('executes with valid input and returns result', async () => {
22
+ const tool = makeTool();
23
+ const result = await executeTool(tool, { value: 5 });
24
+ expect(result.status).toBe('success');
25
+ expect(result.output).toEqual({ doubled: 10 });
26
+ expect(result.durationMs).toBeGreaterThanOrEqual(0);
27
+ });
28
+ it('rejects invalid input', async () => {
29
+ const tool = makeTool();
30
+ const result = await executeTool(tool, { value: 'not-a-number' });
31
+ expect(result.status).toBe('error');
32
+ expect(result.error).toContain('Invalid input');
33
+ expect(result.output).toBeNull();
34
+ });
35
+ it('catches execute errors', async () => {
36
+ const tool = makeTool({
37
+ execute: async () => {
38
+ throw new Error('boom');
39
+ },
40
+ });
41
+ const result = await executeTool(tool, { value: 1 });
42
+ expect(result.status).toBe('error');
43
+ expect(result.error).toBe('boom');
44
+ });
45
+ it('checks permissions and denies when missing', async () => {
46
+ const tool = makeTool({
47
+ requiredPermission: 'entities.team.delete',
48
+ });
49
+ const result = await executeTool(tool, { value: 1 }, {
50
+ permissions: ['entities.team.read'],
51
+ });
52
+ expect(result.status).toBe('error');
53
+ expect(result.error).toContain('Permission denied');
54
+ });
55
+ it('allows execution when permission is present', async () => {
56
+ const tool = makeTool({
57
+ requiredPermission: 'entities.team.read',
58
+ });
59
+ const result = await executeTool(tool, { value: 3 }, {
60
+ permissions: ['entities.team.read', 'entities.team.create'],
61
+ });
62
+ expect(result.status).toBe('success');
63
+ expect(result.output).toEqual({ doubled: 6 });
64
+ });
65
+ it('skips permission check when no permissions provided', async () => {
66
+ const tool = makeTool({
67
+ requiredPermission: 'entities.team.delete',
68
+ });
69
+ // No permissions option = no check
70
+ const result = await executeTool(tool, { value: 2 });
71
+ expect(result.status).toBe('success');
72
+ });
73
+ it('records to ToolStore when provided', async () => {
74
+ const store = new InMemoryToolStore();
75
+ const tool = makeTool();
76
+ await executeTool(tool, { value: 7 }, {
77
+ toolStore: store,
78
+ tenantId: 't1',
79
+ userId: 'u1',
80
+ source: 'agent',
81
+ chatId: 'c1',
82
+ });
83
+ const runs = await store.getToolRuns({ toolSlug: 'test-tool' });
84
+ expect(runs).toHaveLength(1);
85
+ expect(runs[0].tool_slug).toBe('test-tool');
86
+ expect(runs[0].tenant_id).toBe('t1');
87
+ expect(runs[0].user_id).toBe('u1');
88
+ expect(runs[0].source).toBe('agent');
89
+ expect(runs[0].chat_id).toBe('c1');
90
+ expect(runs[0].status).toBe('success');
91
+ });
92
+ it('records errors to ToolStore', async () => {
93
+ const store = new InMemoryToolStore();
94
+ const tool = makeTool({
95
+ execute: async () => {
96
+ throw new Error('fail');
97
+ },
98
+ });
99
+ await executeTool(tool, { value: 1 }, { toolStore: store });
100
+ const runs = await store.getToolRuns({});
101
+ expect(runs[0].status).toBe('error');
102
+ expect(runs[0].error).toBe('fail');
103
+ });
104
+ });
105
+ //# sourceMappingURL=tool-executor.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-executor.test.js","sourceRoot":"","sources":["../../src/tool/tool-executor.test.ts"],"names":[],"mappings":"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"}