@exulu/backend 1.48.2 → 1.49.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 (164) hide show
  1. package/dist/index.cjs +351 -42
  2. package/dist/index.d.cts +96 -1
  3. package/dist/index.d.ts +96 -1
  4. package/dist/index.js +340 -38
  5. package/ee/{markdown.ts → chunking/markdown.ts} +2 -2
  6. package/ee/python/README.md +295 -0
  7. package/ee/python/documents/processing/README.md +155 -0
  8. package/ee/{documents → python/documents}/processing/doc_processor.ts +25 -17
  9. package/ee/{documents/processing/pdf_to_markdown.py → python/documents/processing/document_to_markdown.py} +3 -10
  10. package/ee/python/setup.sh +180 -0
  11. package/package.json +14 -3
  12. package/scripts/postinstall.cjs +149 -0
  13. package/.agents/skills/mintlify/SKILL.md +0 -347
  14. package/.editorconfig +0 -15
  15. package/.eslintrc.json +0 -52
  16. package/.github/workflows/release-backend.yml +0 -38
  17. package/.husky/commit-msg +0 -1
  18. package/.jscpd.json +0 -18
  19. package/.mcp.json +0 -25
  20. package/.nvmrc +0 -1
  21. package/.prettierignore +0 -5
  22. package/.prettierrc.json +0 -12
  23. package/CHANGELOG.md +0 -8
  24. package/SECURITY.md +0 -5
  25. package/commitlint.config.js +0 -4
  26. package/devops/documentation/patch-older-releases.md +0 -42
  27. package/ee/documents/processing/build_pdf_processor.sh +0 -35
  28. package/ee/documents/processing/chunk_markdown.py +0 -263
  29. package/ee/documents/processing/pdf_processor.spec +0 -115
  30. package/eslint.config.js +0 -88
  31. package/jest.config.ts +0 -25
  32. package/mintlify-docs/.mintignore +0 -7
  33. package/mintlify-docs/AGENTS.md +0 -33
  34. package/mintlify-docs/CLAUDE.MD +0 -50
  35. package/mintlify-docs/CONTRIBUTING.md +0 -32
  36. package/mintlify-docs/LICENSE +0 -21
  37. package/mintlify-docs/README.md +0 -55
  38. package/mintlify-docs/ai-tools/claude-code.mdx +0 -43
  39. package/mintlify-docs/ai-tools/cursor.mdx +0 -39
  40. package/mintlify-docs/ai-tools/windsurf.mdx +0 -39
  41. package/mintlify-docs/api-reference/core-types/agent-types.mdx +0 -110
  42. package/mintlify-docs/api-reference/core-types/analytics-types.mdx +0 -95
  43. package/mintlify-docs/api-reference/core-types/configuration-types.mdx +0 -83
  44. package/mintlify-docs/api-reference/core-types/evaluation-types.mdx +0 -106
  45. package/mintlify-docs/api-reference/core-types/job-types.mdx +0 -135
  46. package/mintlify-docs/api-reference/core-types/overview.mdx +0 -73
  47. package/mintlify-docs/api-reference/core-types/prompt-types.mdx +0 -102
  48. package/mintlify-docs/api-reference/core-types/rbac-types.mdx +0 -163
  49. package/mintlify-docs/api-reference/core-types/session-types.mdx +0 -77
  50. package/mintlify-docs/api-reference/core-types/user-management.mdx +0 -112
  51. package/mintlify-docs/api-reference/core-types/workflow-types.mdx +0 -88
  52. package/mintlify-docs/api-reference/core-types.mdx +0 -585
  53. package/mintlify-docs/api-reference/dynamic-types.mdx +0 -851
  54. package/mintlify-docs/api-reference/endpoint/create.mdx +0 -4
  55. package/mintlify-docs/api-reference/endpoint/delete.mdx +0 -4
  56. package/mintlify-docs/api-reference/endpoint/get.mdx +0 -4
  57. package/mintlify-docs/api-reference/endpoint/webhook.mdx +0 -4
  58. package/mintlify-docs/api-reference/introduction.mdx +0 -661
  59. package/mintlify-docs/api-reference/mutations.mdx +0 -1012
  60. package/mintlify-docs/api-reference/openapi.json +0 -217
  61. package/mintlify-docs/api-reference/queries.mdx +0 -1154
  62. package/mintlify-docs/backend/introduction.mdx +0 -218
  63. package/mintlify-docs/changelog.mdx +0 -387
  64. package/mintlify-docs/community-edition.mdx +0 -304
  65. package/mintlify-docs/core/exulu-agent/api-reference.mdx +0 -894
  66. package/mintlify-docs/core/exulu-agent/configuration.mdx +0 -690
  67. package/mintlify-docs/core/exulu-agent/introduction.mdx +0 -552
  68. package/mintlify-docs/core/exulu-app/api-reference.mdx +0 -481
  69. package/mintlify-docs/core/exulu-app/configuration.mdx +0 -319
  70. package/mintlify-docs/core/exulu-app/introduction.mdx +0 -117
  71. package/mintlify-docs/core/exulu-authentication.mdx +0 -810
  72. package/mintlify-docs/core/exulu-chunkers/api-reference.mdx +0 -1011
  73. package/mintlify-docs/core/exulu-chunkers/configuration.mdx +0 -596
  74. package/mintlify-docs/core/exulu-chunkers/introduction.mdx +0 -403
  75. package/mintlify-docs/core/exulu-context/api-reference.mdx +0 -911
  76. package/mintlify-docs/core/exulu-context/configuration.mdx +0 -648
  77. package/mintlify-docs/core/exulu-context/introduction.mdx +0 -394
  78. package/mintlify-docs/core/exulu-database.mdx +0 -811
  79. package/mintlify-docs/core/exulu-default-agents.mdx +0 -545
  80. package/mintlify-docs/core/exulu-eval/api-reference.mdx +0 -772
  81. package/mintlify-docs/core/exulu-eval/configuration.mdx +0 -680
  82. package/mintlify-docs/core/exulu-eval/introduction.mdx +0 -459
  83. package/mintlify-docs/core/exulu-logging.mdx +0 -464
  84. package/mintlify-docs/core/exulu-otel.mdx +0 -670
  85. package/mintlify-docs/core/exulu-queues/api-reference.mdx +0 -648
  86. package/mintlify-docs/core/exulu-queues/configuration.mdx +0 -650
  87. package/mintlify-docs/core/exulu-queues/introduction.mdx +0 -474
  88. package/mintlify-docs/core/exulu-reranker/api-reference.mdx +0 -630
  89. package/mintlify-docs/core/exulu-reranker/configuration.mdx +0 -663
  90. package/mintlify-docs/core/exulu-reranker/introduction.mdx +0 -516
  91. package/mintlify-docs/core/exulu-tool/api-reference.mdx +0 -723
  92. package/mintlify-docs/core/exulu-tool/configuration.mdx +0 -805
  93. package/mintlify-docs/core/exulu-tool/introduction.mdx +0 -539
  94. package/mintlify-docs/core/exulu-variables/api-reference.mdx +0 -699
  95. package/mintlify-docs/core/exulu-variables/configuration.mdx +0 -736
  96. package/mintlify-docs/core/exulu-variables/introduction.mdx +0 -511
  97. package/mintlify-docs/development.mdx +0 -94
  98. package/mintlify-docs/docs.json +0 -248
  99. package/mintlify-docs/enterprise-edition.mdx +0 -538
  100. package/mintlify-docs/essentials/code.mdx +0 -35
  101. package/mintlify-docs/essentials/images.mdx +0 -59
  102. package/mintlify-docs/essentials/markdown.mdx +0 -88
  103. package/mintlify-docs/essentials/navigation.mdx +0 -87
  104. package/mintlify-docs/essentials/reusable-snippets.mdx +0 -110
  105. package/mintlify-docs/essentials/settings.mdx +0 -318
  106. package/mintlify-docs/favicon.svg +0 -3
  107. package/mintlify-docs/frontend/introduction.mdx +0 -39
  108. package/mintlify-docs/getting-started.mdx +0 -267
  109. package/mintlify-docs/guides/custom-agent.mdx +0 -608
  110. package/mintlify-docs/guides/first-agent.mdx +0 -315
  111. package/mintlify-docs/images/admin_ui.png +0 -0
  112. package/mintlify-docs/images/contexts.png +0 -0
  113. package/mintlify-docs/images/create_agents.png +0 -0
  114. package/mintlify-docs/images/evals.png +0 -0
  115. package/mintlify-docs/images/graphql.png +0 -0
  116. package/mintlify-docs/images/graphql_api.png +0 -0
  117. package/mintlify-docs/images/hero-dark.png +0 -0
  118. package/mintlify-docs/images/hero-light.png +0 -0
  119. package/mintlify-docs/images/hero.png +0 -0
  120. package/mintlify-docs/images/knowledge_sources.png +0 -0
  121. package/mintlify-docs/images/mcp.png +0 -0
  122. package/mintlify-docs/images/scaling.png +0 -0
  123. package/mintlify-docs/index.mdx +0 -411
  124. package/mintlify-docs/logo/dark.svg +0 -9
  125. package/mintlify-docs/logo/light.svg +0 -9
  126. package/mintlify-docs/partners.mdx +0 -558
  127. package/mintlify-docs/products.mdx +0 -77
  128. package/mintlify-docs/snippets/snippet-intro.mdx +0 -4
  129. package/mintlify-docs/styles.css +0 -207
  130. package/ngrok.bash +0 -1
  131. package/ngrok.md +0 -6
  132. package/ngrok.yml +0 -10
  133. package/release.config.cjs +0 -15
  134. package/skills-lock.json +0 -10
  135. package/types/context-processor.ts +0 -45
  136. package/types/enums/eval-types.ts +0 -5
  137. package/types/enums/field-types.ts +0 -1
  138. package/types/enums/jobs.ts +0 -11
  139. package/types/enums/statistics.ts +0 -13
  140. package/types/exulu-table-definition.ts +0 -79
  141. package/types/file-types.ts +0 -18
  142. package/types/models/agent-session.ts +0 -27
  143. package/types/models/agent.ts +0 -68
  144. package/types/models/context.ts +0 -53
  145. package/types/models/embedding.ts +0 -17
  146. package/types/models/eval-run.ts +0 -40
  147. package/types/models/exulu-agent-tool-config.ts +0 -11
  148. package/types/models/item.ts +0 -21
  149. package/types/models/job.ts +0 -8
  150. package/types/models/project.ts +0 -16
  151. package/types/models/rate-limiter-rules.ts +0 -7
  152. package/types/models/test-case.ts +0 -25
  153. package/types/models/tool.ts +0 -9
  154. package/types/models/user-role.ts +0 -12
  155. package/types/models/user.ts +0 -20
  156. package/types/models/variable.ts +0 -8
  157. package/types/models/vector-methods.ts +0 -7
  158. package/types/provider-config.ts +0 -21
  159. package/types/queue-config.ts +0 -16
  160. package/types/rbac-rights-modes.ts +0 -1
  161. package/types/statistics.ts +0 -20
  162. package/types/workflow.ts +0 -31
  163. /package/ee/{documents → python/documents}/THIRD_PARTY_LICENSES/docling.txt +0 -0
  164. /package/ee/{documents/processing → python}/requirements.txt +0 -0
@@ -1,723 +0,0 @@
1
- ---
2
- title: "API reference"
3
- description: "Complete method and property reference for ExuluTool"
4
- ---
5
-
6
- ## Constructor
7
-
8
- ```typescript
9
- const tool = new ExuluTool(options: ExuluToolOptions);
10
- ```
11
-
12
- Creates a new ExuluTool instance. See the [configuration guide](/core/exulu-tool/configuration) for all available options.
13
-
14
- ## Methods
15
-
16
- ### execute()
17
-
18
- Executes the tool directly with provided inputs. Used for programmatic tool invocation outside of agent workflows.
19
-
20
- ```typescript
21
- async execute({
22
- agent,
23
- config,
24
- user,
25
- inputs,
26
- project,
27
- items
28
- }: ExecuteOptions): Promise<{
29
- result?: string;
30
- job?: string;
31
- items?: Item[];
32
- }>
33
- ```
34
-
35
- <ParamField path="agent" type="string" required>
36
- Agent ID that is executing the tool. Used for loading agent configuration and API keys.
37
- </ParamField>
38
-
39
- <ParamField path="config" type="ExuluConfig" required>
40
- ExuluApp configuration object
41
- </ParamField>
42
-
43
- <ParamField path="user" type="User">
44
- User object for access control and tracking
45
- </ParamField>
46
-
47
- <ParamField path="inputs" type="any" required>
48
- Input parameters for the tool, validated against the inputSchema
49
- </ParamField>
50
-
51
- <ParamField path="project" type="string">
52
- Project ID for context (used in multi-tenant scenarios)
53
- </ParamField>
54
-
55
- <ParamField path="items" type="string[]">
56
- Array of item IDs for context (used when tool operates on specific items)
57
- </ParamField>
58
-
59
- <ResponseField name="result" type="string">
60
- The result returned by the tool execution
61
- </ResponseField>
62
-
63
- <ResponseField name="job" type="string">
64
- Job ID if the tool queued a background task
65
- </ResponseField>
66
-
67
- <ResponseField name="items" type="Item[]">
68
- Array of items (typically used by context search tools)
69
- </ResponseField>
70
-
71
- ```typescript
72
- const calculatorTool = new ExuluTool({
73
- id: "calculator",
74
- name: "add",
75
- description: "Adds two numbers",
76
- type: "function",
77
- inputSchema: z.object({
78
- a: z.number(),
79
- b: z.number()
80
- }),
81
- config: [],
82
- execute: async ({ a, b }) => ({
83
- result: JSON.stringify({ sum: a + b })
84
- })
85
- });
86
-
87
- // Direct execution
88
- const result = await calculatorTool.execute({
89
- agent: "assistant",
90
- config: exuluConfig,
91
- user: currentUser,
92
- inputs: {
93
- a: 5,
94
- b: 3
95
- }
96
- });
97
-
98
- console.log(result.result); // {"sum":8}
99
- ```
100
-
101
- <Info>
102
- The `execute()` method is primarily used for programmatic tool invocation. When tools are used by agents, the AI SDK calls the internal tool execution automatically.
103
- </Info>
104
-
105
- <Note>
106
- This method loads the specified agent to access its provider API key and tool configuration, then converts the ExuluTool to an AI SDK tool before execution.
107
- </Note>
108
-
109
- ## Properties
110
-
111
- ### id
112
-
113
- <ResponseField name="id" type="string">
114
- Unique identifier for the tool. Must start with a letter or underscore, contain only alphanumeric characters and underscores, 5-80 characters long.
115
- </ResponseField>
116
-
117
- ```typescript
118
- console.log(tool.id); // "get_user_profile"
119
- ```
120
-
121
- <Warning>
122
- The ID should not change after creation as it's used for database references.
123
- </Warning>
124
-
125
- ### name
126
-
127
- <ResponseField name="name" type="string">
128
- Human-readable name used for tool invocation
129
- </ResponseField>
130
-
131
- ```typescript
132
- console.log(tool.name); // "get_user_profile"
133
- ```
134
-
135
- ### description
136
-
137
- <ResponseField name="description" type="string">
138
- Description of what the tool does, shown to agents
139
- </ResponseField>
140
-
141
- ```typescript
142
- console.log(tool.description); // "Retrieves a user's profile information"
143
- ```
144
-
145
- ### category
146
-
147
- <ResponseField name="category" type="string">
148
- Category for organizing tools (defaults to "default")
149
- </ResponseField>
150
-
151
- ```typescript
152
- console.log(tool.category); // "database"
153
- ```
154
-
155
- ### type
156
-
157
- <ResponseField name="type" type="'context' | 'function' | 'agent' | 'web_search'">
158
- The type of tool
159
- </ResponseField>
160
-
161
- ```typescript
162
- console.log(tool.type); // "function"
163
- ```
164
-
165
- ### inputSchema
166
-
167
- <ResponseField name="inputSchema" type="z.ZodType | undefined">
168
- Zod schema that defines and validates the tool's input parameters
169
- </ResponseField>
170
-
171
- ```typescript
172
- console.log(tool.inputSchema); // ZodObject { ... }
173
- ```
174
-
175
- ### config
176
-
177
- <ResponseField name="config" type="ConfigParameter[]">
178
- Array of configuration parameters for the tool
179
- </ResponseField>
180
-
181
- ```typescript
182
- tool.config.forEach(param => {
183
- console.log(`${param.name}: ${param.type} = ${param.default}`);
184
- });
185
-
186
- // Output:
187
- // api_endpoint: string = https://api.example.com
188
- // timeout_ms: number = 5000
189
- // enable_cache: boolean = true
190
- ```
191
-
192
- ### tool
193
-
194
- <ResponseField name="tool" type="Tool">
195
- The AI SDK tool instance created from this ExuluTool
196
- </ResponseField>
197
-
198
- ```typescript
199
- // The tool property is used internally by the AI SDK
200
- const aiTool = tool.tool;
201
- console.log(aiTool.description); // Tool description
202
- console.log(aiTool.parameters); // Tool input schema
203
- ```
204
-
205
- <Note>
206
- This property is automatically created in the constructor by wrapping the execute function with the AI SDK's `tool()` function.
207
- </Note>
208
-
209
- ## Usage examples
210
-
211
- ### Creating and registering a tool
212
-
213
- ```typescript
214
- import { ExuluApp, ExuluTool } from "@exulu/backend";
215
- import { z } from "zod";
216
-
217
- // Create tool
218
- const weatherTool = new ExuluTool({
219
- id: "weather_lookup",
220
- name: "get_weather",
221
- description: "Gets current weather for a location",
222
- type: "function",
223
- category: "api",
224
- inputSchema: z.object({
225
- location: z.string().describe("City name"),
226
- units: z.enum(["metric", "imperial"]).optional()
227
- }),
228
- config: [
229
- {
230
- name: "api_key",
231
- description: "Weather API key",
232
- type: "variable"
233
- }
234
- ],
235
- execute: async ({ location, units = "metric" }) => {
236
- const weather = await fetchWeather(location, units);
237
- return {
238
- result: JSON.stringify(weather)
239
- };
240
- }
241
- });
242
-
243
- // Register with app
244
- const app = new ExuluApp();
245
- await app.create({
246
- tools: {
247
- weather: weatherTool
248
- },
249
- config: { /* ... */ }
250
- });
251
-
252
- // Now agents can use the tool automatically
253
- ```
254
-
255
- ### Direct tool execution
256
-
257
- ```typescript
258
- // Execute tool programmatically
259
- const result = await weatherTool.execute({
260
- agent: "assistant",
261
- config: app.config,
262
- user: currentUser,
263
- inputs: {
264
- location: "London",
265
- units: "metric"
266
- }
267
- });
268
-
269
- console.log(result.result);
270
- // {"temperature":15,"condition":"Partly cloudy","humidity":65}
271
- ```
272
-
273
- ### Database query tool
274
-
275
- ```typescript
276
- const getUserTool = new ExuluTool({
277
- id: "get_user",
278
- name: "get_user",
279
- description: "Retrieves user information from database",
280
- type: "function",
281
- category: "database",
282
- inputSchema: z.object({
283
- userId: z.string(),
284
- includeHistory: z.boolean().optional()
285
- }),
286
- config: [
287
- {
288
- name: "database_url",
289
- description: "Database connection URL",
290
- type: "variable"
291
- }
292
- ],
293
- execute: async ({ userId, includeHistory = false }) => {
294
- const user = await db.users.findOne({ id: userId });
295
-
296
- if (!user) {
297
- return {
298
- result: JSON.stringify({
299
- error: "User not found",
300
- userId
301
- })
302
- };
303
- }
304
-
305
- if (includeHistory) {
306
- user.history = await db.userHistory.find({ userId });
307
- }
308
-
309
- return {
310
- result: JSON.stringify(user)
311
- };
312
- }
313
- });
314
-
315
- // Use in agent workflow
316
- const app = new ExuluApp();
317
- await app.create({
318
- tools: { getUser: getUserTool },
319
- agents: { assistant: assistantAgent },
320
- config: { /* ... */ }
321
- });
322
- ```
323
-
324
- ### API integration tool
325
-
326
- ```typescript
327
- const githubTool = new ExuluTool({
328
- id: "github_search",
329
- name: "search_github",
330
- description: "Searches GitHub repositories",
331
- type: "function",
332
- category: "api",
333
- inputSchema: z.object({
334
- query: z.string().describe("Search query"),
335
- sort: z.enum(["stars", "forks", "updated"]).optional(),
336
- limit: z.number().int().min(1).max(100).optional()
337
- }),
338
- config: [
339
- {
340
- name: "github_token",
341
- description: "GitHub API token",
342
- type: "variable"
343
- },
344
- {
345
- name: "api_endpoint",
346
- description: "GitHub API base URL",
347
- type: "string",
348
- default: "https://api.github.com"
349
- }
350
- ],
351
- execute: async ({ query, sort = "stars", limit = 10 }) => {
352
- const url = new URL(`${config.api_endpoint}/search/repositories`);
353
- url.searchParams.append("q", query);
354
- url.searchParams.append("sort", sort);
355
- url.searchParams.append("per_page", limit.toString());
356
-
357
- const response = await fetch(url, {
358
- headers: {
359
- Authorization: `Bearer ${config.github_token}`,
360
- Accept: "application/vnd.github.v3+json"
361
- }
362
- });
363
-
364
- const data = await response.json();
365
-
366
- return {
367
- result: JSON.stringify({
368
- total: data.total_count,
369
- repositories: data.items.map(repo => ({
370
- name: repo.full_name,
371
- description: repo.description,
372
- stars: repo.stargazers_count,
373
- url: repo.html_url
374
- }))
375
- })
376
- };
377
- }
378
- });
379
- ```
380
-
381
- ### Streaming tool with generator
382
-
383
- ```typescript
384
- const processBatchTool = new ExuluTool({
385
- id: "process_batch",
386
- name: "process_batch",
387
- description: "Processes multiple items and streams results",
388
- type: "function",
389
- category: "processing",
390
- inputSchema: z.object({
391
- itemIds: z.array(z.string()).min(1).max(50)
392
- }),
393
- config: [],
394
- execute: async function* ({ itemIds }) {
395
- for (const itemId of itemIds) {
396
- try {
397
- const result = await processItem(itemId);
398
-
399
- yield {
400
- result: JSON.stringify({
401
- itemId,
402
- status: "success",
403
- data: result
404
- })
405
- };
406
- } catch (error) {
407
- yield {
408
- result: JSON.stringify({
409
- itemId,
410
- status: "error",
411
- error: error.message
412
- })
413
- };
414
- }
415
- }
416
- }
417
- });
418
-
419
- // When executed, results stream back as each item completes
420
- const generator = await processBatchTool.execute({
421
- agent: "processor",
422
- config: exuluConfig,
423
- inputs: {
424
- itemIds: ["item1", "item2", "item3"]
425
- }
426
- });
427
-
428
- // Consume the stream
429
- for await (const chunk of generator) {
430
- console.log(chunk.result);
431
- // {"itemId":"item1","status":"success","data":{...}}
432
- // {"itemId":"item2","status":"success","data":{...}}
433
- // {"itemId":"item3","status":"success","data":{...}}
434
- }
435
- ```
436
-
437
- ### Tool with background job
438
-
439
- ```typescript
440
- const embedTool = new ExuluTool({
441
- id: "generate_embeddings",
442
- name: "generate_embeddings",
443
- description: "Generates embeddings for documents",
444
- type: "function",
445
- category: "processing",
446
- inputSchema: z.object({
447
- contextId: z.string(),
448
- itemIds: z.array(z.string()).optional()
449
- }),
450
- config: [],
451
- execute: async ({ contextId, itemIds }) => {
452
- const context = app.context(contextId);
453
-
454
- if (!context) {
455
- throw new Error(`Context not found: ${contextId}`);
456
- }
457
-
458
- if (itemIds && itemIds.length > 0) {
459
- const jobs = [];
460
- for (const itemId of itemIds) {
461
- const { job } = await context.embeddings.generate.one({
462
- item: { id: itemId },
463
- trigger: "api",
464
- config: exuluConfig
465
- });
466
- if (job) jobs.push(job);
467
- }
468
-
469
- return {
470
- result: JSON.stringify({
471
- status: "queued",
472
- count: itemIds.length
473
- }),
474
- job: jobs.join(",")
475
- };
476
- } else {
477
- const { jobs, items } = await context.embeddings.generate.all(
478
- exuluConfig
479
- );
480
-
481
- return {
482
- result: JSON.stringify({
483
- status: "queued",
484
- count: items
485
- }),
486
- job: jobs.join(",")
487
- };
488
- }
489
- }
490
- });
491
- ```
492
-
493
- ### Accessing tool properties
494
-
495
- ```typescript
496
- const tool = new ExuluTool({
497
- id: "example_tool",
498
- name: "example",
499
- description: "Example tool",
500
- type: "function",
501
- category: "examples",
502
- inputSchema: z.object({
503
- input: z.string()
504
- }),
505
- config: [
506
- {
507
- name: "setting",
508
- description: "Example setting",
509
- type: "string",
510
- default: "default_value"
511
- }
512
- ],
513
- execute: async ({ input }) => ({
514
- result: input
515
- })
516
- });
517
-
518
- // Access properties
519
- console.log(tool.id); // "example_tool"
520
- console.log(tool.name); // "example"
521
- console.log(tool.description); // "Example tool"
522
- console.log(tool.type); // "function"
523
- console.log(tool.category); // "examples"
524
-
525
- // Access config
526
- tool.config.forEach(param => {
527
- console.log(param.name); // "setting"
528
- console.log(param.type); // "string"
529
- console.log(param.default); // "default_value"
530
- });
531
-
532
- // Access inputSchema
533
- if (tool.inputSchema) {
534
- const result = tool.inputSchema.safeParse({ input: "test" });
535
- console.log(result.success); // true
536
- }
537
-
538
- // Access AI SDK tool
539
- console.log(tool.tool.description); // "Example tool"
540
- ```
541
-
542
- ### Error handling in tools
543
-
544
- ```typescript
545
- const safeTool = new ExuluTool({
546
- id: "safe_operation",
547
- name: "safe_operation",
548
- description: "Performs operation with error handling",
549
- type: "function",
550
- inputSchema: z.object({
551
- data: z.string()
552
- }),
553
- config: [],
554
- execute: async ({ data }) => {
555
- try {
556
- // Validate input
557
- if (!data || data.length === 0) {
558
- return {
559
- result: JSON.stringify({
560
- success: false,
561
- error: "Data is required"
562
- })
563
- };
564
- }
565
-
566
- // Perform operation
567
- const result = await performRiskyOperation(data);
568
-
569
- // Return success
570
- return {
571
- result: JSON.stringify({
572
- success: true,
573
- data: result
574
- })
575
- };
576
- } catch (error) {
577
- // Handle errors gracefully
578
- console.error("Tool execution error:", error);
579
-
580
- return {
581
- result: JSON.stringify({
582
- success: false,
583
- error: error.message,
584
- code: error.code || "UNKNOWN_ERROR"
585
- })
586
- };
587
- }
588
- }
589
- });
590
- ```
591
-
592
- ## Type definitions
593
-
594
- ```typescript
595
- // Tool configuration parameter
596
- type ConfigParameter = {
597
- name: string;
598
- description: string;
599
- type: "boolean" | "string" | "number" | "variable";
600
- default?: string | boolean | number;
601
- };
602
-
603
- // Execute function types
604
- type ExecuteFunction =
605
- | ((inputs: any) => Promise<ExecuteResult>)
606
- | ((inputs: any) => AsyncGenerator<ExecuteResult>);
607
-
608
- type ExecuteResult = {
609
- result?: string;
610
- job?: string;
611
- items?: Item[];
612
- };
613
-
614
- // Execute method options
615
- type ExecuteOptions = {
616
- agent: string;
617
- config: ExuluConfig;
618
- user?: User;
619
- inputs: any;
620
- project?: string;
621
- items?: string[];
622
- };
623
-
624
- // Tool constructor options
625
- type ExuluToolOptions = {
626
- id: string;
627
- name: string;
628
- description: string;
629
- category?: string;
630
- inputSchema?: z.ZodType;
631
- type: "context" | "function" | "agent" | "web_search";
632
- config: ConfigParameter[];
633
- execute: ExecuteFunction;
634
- };
635
- ```
636
-
637
- ## Internal implementation notes
638
-
639
- <AccordionGroup>
640
- <Accordion title="AI SDK integration">
641
- ExuluTool wraps the AI SDK's `tool()` function in the constructor:
642
-
643
- ```typescript
644
- this.tool = tool({
645
- description: description,
646
- inputSchema: inputSchema || z.object({}),
647
- execute
648
- });
649
- ```
650
-
651
- This provides native integration with AI SDK streaming and tool calling.
652
- </Accordion>
653
-
654
- <Accordion title="Direct execution flow">
655
- When `execute()` is called:
656
-
657
- 1. Loads the specified agent to get provider API key
658
- 2. Converts the ExuluTool to an AI SDK tool
659
- 3. Generates a unique tool call ID
660
- 4. Executes the tool via AI SDK
661
- 5. Handles streaming results if using generator
662
- 6. Parses and returns the final result
663
-
664
- This allows tools to be executed outside of agent workflows while maintaining consistency.
665
- </Accordion>
666
-
667
- <Accordion title="Name sanitization">
668
- Tool names are sanitized during execution to ensure compatibility:
669
-
670
- ```typescript
671
- const sanitizedName = sanitizeName(this.name);
672
- ```
673
-
674
- This handles special characters and ensures the name works with the AI SDK.
675
- </Accordion>
676
-
677
- <Accordion title="Variable resolution">
678
- When `config` parameters use `type: "variable"`:
679
-
680
- 1. The variable name is looked up in the `variables` table
681
- 2. If encrypted, the value is decrypted using `NEXTAUTH_SECRET`
682
- 3. The decrypted value is used in tool execution
683
-
684
- This enables secure storage of API keys and secrets.
685
- </Accordion>
686
- </AccordionGroup>
687
-
688
- ## Best practices
689
-
690
- <Tip>
691
- **Return JSON strings**: Always stringify non-string results. The AI SDK and agents expect string results.
692
-
693
- ```typescript
694
- // Good
695
- return { result: JSON.stringify({ data: value }) };
696
-
697
- // Avoid
698
- return { result: value }; // Will be coerced to string
699
- ```
700
- </Tip>
701
-
702
- <Note>
703
- **Error handling**: Always handle errors gracefully and return error information in the result rather than throwing (unless you want the framework to catch it).
704
- </Note>
705
-
706
- <Warning>
707
- **ID stability**: Never change a tool's `id` after creation. It's used for database references and changing it will break existing integrations.
708
- </Warning>
709
-
710
- <Info>
711
- **Input descriptions**: Always use `.describe()` on Zod schema fields. These descriptions are shown to agents and significantly improve tool selection accuracy.
712
- </Info>
713
-
714
- ## Next steps
715
-
716
- <CardGroup cols={2}>
717
- <Card title="Configuration guide" icon="gear" href="/core/exulu-tool/configuration">
718
- Learn about all configuration options
719
- </Card>
720
- <Card title="ExuluApp" icon="cube" href="/core/exulu-app/introduction">
721
- Learn how to register tools
722
- </Card>
723
- </CardGroup>