@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,805 +0,0 @@
1
- ---
2
- title: "Configuration"
3
- description: "Complete guide to configuring ExuluTool for agent tool calling"
4
- ---
5
-
6
- ## Constructor parameters
7
-
8
- The ExuluTool constructor accepts a configuration object with the following parameters:
9
-
10
- ```typescript
11
- const tool = new ExuluTool({
12
- id: string,
13
- name: string,
14
- description: string,
15
- category?: string,
16
- inputSchema?: z.ZodType,
17
- type: "context" | "function" | "agent" | "web_search",
18
- config: ConfigParameter[],
19
- execute: ExecuteFunction
20
- });
21
- ```
22
-
23
- ## Required parameters
24
-
25
- ### id
26
-
27
- <ParamField path="id" type="string" required>
28
- Unique identifier for the tool. Must start with a letter (a-z) or underscore (_). Subsequent characters can be letters, digits (0-9), or underscores. Must be 5-80 characters long.
29
- </ParamField>
30
-
31
- ```typescript
32
- id: "get_user_profile"
33
- ```
34
-
35
- <Warning>
36
- The ID is used for database references and should not change after creation. Changing the ID requires updating all references in your database.
37
- </Warning>
38
-
39
- <Info>
40
- The ID must follow PostgreSQL identifier rules since it's used for storing tool references.
41
- </Info>
42
-
43
- ### name
44
-
45
- <ParamField path="name" type="string" required>
46
- Human-readable name used for tool invocation. Agents use this name when calling the tool.
47
- </ParamField>
48
-
49
- ```typescript
50
- name: "get_user_profile"
51
- ```
52
-
53
- <Note>
54
- The name is sanitized during execution to ensure compatibility with the AI SDK. Use snake_case or camelCase for consistency.
55
- </Note>
56
-
57
- ### description
58
-
59
- <ParamField path="description" type="string" required>
60
- Clear description of what the tool does. This is shown to agents to help them understand when to use the tool.
61
- </ParamField>
62
-
63
- ```typescript
64
- description: "Retrieves a user's profile information including name, email, and preferences"
65
- ```
66
-
67
- <Tip>
68
- Write descriptions from the agent's perspective. Explain what the tool does and when to use it. Good descriptions improve tool selection accuracy.
69
- </Tip>
70
-
71
- ### type
72
-
73
- <ParamField path="type" type="'context' | 'function' | 'agent' | 'web_search'" required>
74
- The type of tool determines its behavior and execution context
75
- </ParamField>
76
-
77
- ```typescript
78
- type: "function"
79
- ```
80
-
81
- <Tabs>
82
- <Tab title="function">
83
- Custom function tools that execute your business logic, API calls, or data processing.
84
-
85
- ```typescript
86
- type: "function"
87
- ```
88
-
89
- Use for: Database queries, calculations, API integrations, file processing
90
- </Tab>
91
-
92
- <Tab title="context">
93
- Semantic search tools that query ExuluContext instances for RAG applications.
94
-
95
- ```typescript
96
- type: "context"
97
- ```
98
-
99
- Use for: Knowledge base queries, document search, semantic retrieval
100
-
101
- <Note>
102
- Context tools are typically auto-generated by ExuluContext when `enableAsTool: true`.
103
- </Note>
104
- </Tab>
105
-
106
- <Tab title="agent">
107
- Agent delegation tools that invoke other agents for specialized tasks.
108
-
109
- ```typescript
110
- type: "agent"
111
- ```
112
-
113
- Use for: Multi-agent workflows, task routing, specialized expertise
114
- </Tab>
115
-
116
- <Tab title="web_search">
117
- Web search tools that fetch real-time information from the internet.
118
-
119
- ```typescript
120
- type: "web_search"
121
- ```
122
-
123
- Use for: Current events, real-time data, fact-checking
124
- </Tab>
125
- </Tabs>
126
-
127
- ### config
128
-
129
- <ParamField path="config" type="ConfigParameter[]" required>
130
- Array of configuration parameters that define runtime settings for the tool
131
- </ParamField>
132
-
133
- ```typescript
134
- config: [
135
- {
136
- name: "api_endpoint",
137
- description: "Base URL for the API",
138
- type: "string",
139
- default: "https://api.example.com"
140
- },
141
- {
142
- name: "enable_cache",
143
- description: "Enable response caching",
144
- type: "boolean",
145
- default: true
146
- },
147
- {
148
- name: "timeout_ms",
149
- description: "Request timeout in milliseconds",
150
- type: "number",
151
- default: 5000
152
- },
153
- {
154
- name: "api_key",
155
- description: "API authentication key",
156
- type: "variable" // References ExuluVariables
157
- }
158
- ]
159
- ```
160
-
161
- #### Config parameter properties
162
-
163
- <ParamField path="config[].name" type="string" required>
164
- Parameter name used to reference this configuration value
165
- </ParamField>
166
-
167
- <ParamField path="config[].description" type="string" required>
168
- Description of what this parameter controls
169
- </ParamField>
170
-
171
- <ParamField path="config[].type" type="'boolean' | 'string' | 'number' | 'variable'" required>
172
- Data type of the parameter
173
- </ParamField>
174
-
175
- <ParamField path="config[].default" type="string | boolean | number">
176
- Default value if not specified (not applicable for type `"variable"`)
177
- </ParamField>
178
-
179
- ### execute
180
-
181
- <ParamField path="execute" type="ExecuteFunction" required>
182
- The function that implements the tool's logic. Can be async function or async generator.
183
- </ParamField>
184
-
185
- ```typescript
186
- execute: async (inputs: any) => {
187
- // Your logic here
188
- return {
189
- result?: string,
190
- job?: string,
191
- items?: Item[]
192
- };
193
- }
194
- ```
195
-
196
- <Tabs>
197
- <Tab title="Async function">
198
- Standard async function for single result:
199
-
200
- ```typescript
201
- execute: async ({ userId, includeHistory }) => {
202
- const user = await db.users.findOne({ id: userId });
203
-
204
- if (includeHistory) {
205
- user.history = await db.userHistory.find({ userId });
206
- }
207
-
208
- return {
209
- result: JSON.stringify(user)
210
- };
211
- }
212
- ```
213
- </Tab>
214
-
215
- <Tab title="Async generator">
216
- Generator function for streaming results:
217
-
218
- ```typescript
219
- execute: async function* ({ documentIds }) {
220
- for (const docId of documentIds) {
221
- const doc = await processDocument(docId);
222
-
223
- yield {
224
- result: JSON.stringify({
225
- documentId: docId,
226
- status: "processed",
227
- content: doc.content
228
- })
229
- };
230
- }
231
- }
232
- ```
233
- </Tab>
234
- </Tabs>
235
-
236
- #### Execute function return type
237
-
238
- The execute function should return an object with one or more of these properties:
239
-
240
- <ResponseField name="result" type="string">
241
- The main result to return to the agent. Typically JSON stringified data.
242
- </ResponseField>
243
-
244
- <ResponseField name="job" type="string">
245
- Optional job ID if the tool queued a background task for async processing
246
- </ResponseField>
247
-
248
- <ResponseField name="items" type="Item[]">
249
- Optional array of items (typically used by context search tools)
250
- </ResponseField>
251
-
252
- ```typescript
253
- return {
254
- result: JSON.stringify({
255
- status: "success",
256
- data: processedData
257
- }),
258
- job: "job-uuid-123" // If queued
259
- };
260
- ```
261
-
262
- ## Optional parameters
263
-
264
- ### category
265
-
266
- <ParamField path="category" type="string">
267
- Category for organizing tools. Defaults to `"default"` if not specified.
268
- </ParamField>
269
-
270
- ```typescript
271
- category: "database"
272
- ```
273
-
274
- Common categories:
275
- - `"database"` - Database queries and operations
276
- - `"api"` - External API integrations
277
- - `"file"` - File operations and processing
278
- - `"math"` - Mathematical calculations
279
- - `"search"` - Search and retrieval operations
280
- - `"workflow"` - Multi-step workflows
281
-
282
- ### inputSchema
283
-
284
- <ParamField path="inputSchema" type="z.ZodType">
285
- Zod schema that defines and validates the tool's input parameters. If not provided, defaults to an empty object schema.
286
- </ParamField>
287
-
288
- ```typescript
289
- import { z } from "zod";
290
-
291
- inputSchema: z.object({
292
- userId: z.string().describe("The user ID to look up"),
293
- includeHistory: z.boolean()
294
- .optional()
295
- .describe("Include user's history in the response"),
296
- maxResults: z.number()
297
- .int()
298
- .positive()
299
- .max(100)
300
- .optional()
301
- .describe("Maximum number of results to return")
302
- })
303
- ```
304
-
305
- <Note>
306
- Always use `.describe()` on schema fields. These descriptions are shown to agents and help them understand what each parameter does.
307
- </Note>
308
-
309
- #### Zod schema best practices
310
-
311
- <AccordionGroup>
312
- <Accordion title="Use descriptive field names">
313
- ```typescript
314
- // Good
315
- z.object({
316
- userEmail: z.string(),
317
- includeDeletedRecords: z.boolean()
318
- })
319
-
320
- // Avoid
321
- z.object({
322
- email: z.string(), // Ambiguous - could be any email
323
- deleted: z.boolean() // Unclear what this controls
324
- })
325
- ```
326
- </Accordion>
327
-
328
- <Accordion title="Add descriptions to all fields">
329
- ```typescript
330
- z.object({
331
- query: z.string()
332
- .min(1)
333
- .describe("Search query to find relevant documents"),
334
- limit: z.number()
335
- .int()
336
- .positive()
337
- .max(50)
338
- .optional()
339
- .describe("Maximum number of results to return (default: 10)")
340
- })
341
- ```
342
- </Accordion>
343
-
344
- <Accordion title="Use enums for fixed options">
345
- ```typescript
346
- z.object({
347
- sortBy: z.enum(["date", "relevance", "popularity"])
348
- .describe("Sort order for results"),
349
- format: z.enum(["json", "csv", "xml"])
350
- .optional()
351
- .describe("Output format (default: json)")
352
- })
353
- ```
354
- </Accordion>
355
-
356
- <Accordion title="Add validation constraints">
357
- ```typescript
358
- z.object({
359
- email: z.string()
360
- .email()
361
- .describe("User's email address"),
362
- age: z.number()
363
- .int()
364
- .min(0)
365
- .max(120)
366
- .describe("User's age in years"),
367
- username: z.string()
368
- .min(3)
369
- .max(20)
370
- .regex(/^[a-zA-Z0-9_]+$/)
371
- .describe("Username (3-20 alphanumeric characters)")
372
- })
373
- ```
374
- </Accordion>
375
-
376
- <Accordion title="Use optional for non-required fields">
377
- ```typescript
378
- z.object({
379
- // Required
380
- userId: z.string()
381
- .describe("User ID (required)"),
382
-
383
- // Optional with default behavior
384
- includeArchived: z.boolean()
385
- .optional()
386
- .describe("Include archived items (default: false)"),
387
-
388
- // Optional with no default
389
- filterTag: z.string()
390
- .optional()
391
- .describe("Optional tag to filter by")
392
- })
393
- ```
394
- </Accordion>
395
- </AccordionGroup>
396
-
397
- ## Configuration examples
398
-
399
- ### Simple function tool
400
-
401
- ```typescript
402
- import { ExuluTool } from "@exulu/backend";
403
- import { z } from "zod";
404
-
405
- const addTool = new ExuluTool({
406
- id: "add_numbers",
407
- name: "add",
408
- description: "Adds two numbers together",
409
- type: "function",
410
- category: "math",
411
- inputSchema: z.object({
412
- a: z.number().describe("First number"),
413
- b: z.number().describe("Second number")
414
- }),
415
- config: [],
416
- execute: async ({ a, b }) => {
417
- return {
418
- result: JSON.stringify({ sum: a + b })
419
- };
420
- }
421
- });
422
- ```
423
-
424
- ### Database query tool
425
-
426
- ```typescript
427
- const getUserTool = new ExuluTool({
428
- id: "get_user_profile",
429
- name: "get_user_profile",
430
- description: "Retrieves user profile information from the database",
431
- type: "function",
432
- category: "database",
433
- inputSchema: z.object({
434
- userId: z.string().describe("User ID to look up"),
435
- includePreferences: z.boolean()
436
- .optional()
437
- .describe("Include user preferences (default: false)")
438
- }),
439
- config: [
440
- {
441
- name: "database_url",
442
- description: "Database connection URL",
443
- type: "variable"
444
- },
445
- {
446
- name: "timeout_seconds",
447
- description: "Query timeout in seconds",
448
- type: "number",
449
- default: 10
450
- }
451
- ],
452
- execute: async ({ userId, includePreferences = false }) => {
453
- const user = await db.users.findOne({ id: userId });
454
-
455
- if (!user) {
456
- return {
457
- result: JSON.stringify({
458
- error: "User not found",
459
- userId
460
- })
461
- };
462
- }
463
-
464
- if (includePreferences) {
465
- user.preferences = await db.preferences.findOne({ userId });
466
- }
467
-
468
- return {
469
- result: JSON.stringify(user)
470
- };
471
- }
472
- });
473
- ```
474
-
475
- ### API integration tool
476
-
477
- ```typescript
478
- const weatherTool = new ExuluTool({
479
- id: "weather_lookup",
480
- name: "get_weather",
481
- description: "Gets current weather and forecast for a location",
482
- type: "function",
483
- category: "api",
484
- inputSchema: z.object({
485
- location: z.string().describe("City name or coordinates (lat,long)"),
486
- units: z.enum(["metric", "imperial"])
487
- .optional()
488
- .describe("Temperature units (default: metric)"),
489
- includeForecast: z.boolean()
490
- .optional()
491
- .describe("Include 7-day forecast (default: false)")
492
- }),
493
- config: [
494
- {
495
- name: "api_key",
496
- description: "Weather API authentication key",
497
- type: "variable"
498
- },
499
- {
500
- name: "api_endpoint",
501
- description: "Weather API base URL",
502
- type: "string",
503
- default: "https://api.weatherapi.com/v1"
504
- },
505
- {
506
- name: "cache_duration",
507
- description: "Cache responses for this many seconds",
508
- type: "number",
509
- default: 300
510
- }
511
- ],
512
- execute: async ({ location, units = "metric", includeForecast = false }) => {
513
- const url = `${config.api_endpoint}/current.json?key=${config.api_key}&q=${location}`;
514
-
515
- const response = await fetch(url);
516
- const data = await response.json();
517
-
518
- if (includeForecast) {
519
- const forecastUrl = `${config.api_endpoint}/forecast.json?key=${config.api_key}&q=${location}&days=7`;
520
- const forecastResponse = await fetch(forecastUrl);
521
- data.forecast = await forecastResponse.json();
522
- }
523
-
524
- return {
525
- result: JSON.stringify(data)
526
- };
527
- }
528
- });
529
- ```
530
-
531
- ### Streaming tool with generator
532
-
533
- ```typescript
534
- const batchProcessTool = new ExuluTool({
535
- id: "batch_process_files",
536
- name: "batch_process_files",
537
- description: "Processes multiple files and streams results as they complete",
538
- type: "function",
539
- category: "file",
540
- inputSchema: z.object({
541
- fileKeys: z.array(z.string())
542
- .min(1)
543
- .max(50)
544
- .describe("S3 keys of files to process (max 50)"),
545
- operation: z.enum(["extract_text", "generate_thumbnail", "convert_format"])
546
- .describe("Operation to perform on each file")
547
- }),
548
- config: [
549
- {
550
- name: "s3_bucket",
551
- description: "S3 bucket name",
552
- type: "variable"
553
- },
554
- {
555
- name: "parallel_limit",
556
- description: "Maximum number of parallel operations",
557
- type: "number",
558
- default: 5
559
- }
560
- ],
561
- execute: async function* ({ fileKeys, operation }) {
562
- for (const fileKey of fileKeys) {
563
- try {
564
- const result = await processFile(fileKey, operation);
565
-
566
- yield {
567
- result: JSON.stringify({
568
- fileKey,
569
- status: "success",
570
- operation,
571
- output: result
572
- })
573
- };
574
- } catch (error) {
575
- yield {
576
- result: JSON.stringify({
577
- fileKey,
578
- status: "error",
579
- operation,
580
- error: error.message
581
- })
582
- };
583
- }
584
- }
585
- }
586
- });
587
- ```
588
-
589
- ### Tool with background job queuing
590
-
591
- ```typescript
592
- const embedGeneratorTool = new ExuluTool({
593
- id: "generate_embeddings",
594
- name: "generate_embeddings",
595
- description: "Generates embeddings for documents (queued for background processing)",
596
- type: "function",
597
- category: "processing",
598
- inputSchema: z.object({
599
- contextId: z.string().describe("Context ID to generate embeddings for"),
600
- itemIds: z.array(z.string())
601
- .optional()
602
- .describe("Specific item IDs (if not provided, processes all items)")
603
- }),
604
- config: [
605
- {
606
- name: "queue_name",
607
- description: "BullMQ queue name",
608
- type: "string",
609
- default: "embeddings"
610
- },
611
- {
612
- name: "priority",
613
- description: "Job priority (1-10, higher is more important)",
614
- type: "number",
615
- default: 5
616
- }
617
- ],
618
- execute: async ({ contextId, itemIds }) => {
619
- const context = app.context(contextId);
620
-
621
- if (!context) {
622
- return {
623
- result: JSON.stringify({
624
- error: "Context not found",
625
- contextId
626
- })
627
- };
628
- }
629
-
630
- if (itemIds && itemIds.length > 0) {
631
- // Process specific items
632
- const jobs = [];
633
- for (const itemId of itemIds) {
634
- const { job } = await context.embeddings.generate.one({
635
- item: { id: itemId },
636
- trigger: "api",
637
- config: exuluConfig
638
- });
639
- jobs.push(job);
640
- }
641
-
642
- return {
643
- result: JSON.stringify({
644
- status: "queued",
645
- itemCount: itemIds.length
646
- }),
647
- job: jobs.join(",")
648
- };
649
- } else {
650
- // Process all items
651
- const { jobs, items } = await context.embeddings.generate.all(
652
- exuluConfig
653
- );
654
-
655
- return {
656
- result: JSON.stringify({
657
- status: "queued",
658
- itemCount: items
659
- }),
660
- job: jobs.join(",")
661
- };
662
- }
663
- }
664
- });
665
- ```
666
-
667
- ## Configuration types reference
668
-
669
- <AccordionGroup>
670
- <Accordion title="string">
671
- Text configuration values
672
-
673
- ```typescript
674
- {
675
- name: "api_endpoint",
676
- description: "API base URL",
677
- type: "string",
678
- default: "https://api.example.com"
679
- }
680
- ```
681
- </Accordion>
682
-
683
- <Accordion title="number">
684
- Numeric configuration values
685
-
686
- ```typescript
687
- {
688
- name: "timeout_ms",
689
- description: "Request timeout in milliseconds",
690
- type: "number",
691
- default: 5000
692
- }
693
- ```
694
- </Accordion>
695
-
696
- <Accordion title="boolean">
697
- True/false flags
698
-
699
- ```typescript
700
- {
701
- name: "enable_cache",
702
- description: "Enable response caching",
703
- type: "boolean",
704
- default: true
705
- }
706
- ```
707
- </Accordion>
708
-
709
- <Accordion title="variable">
710
- References to ExuluVariables (for secrets and environment values)
711
-
712
- ```typescript
713
- {
714
- name: "api_key",
715
- description: "API authentication key",
716
- type: "variable"
717
- // No default - must be set in variables table
718
- }
719
- ```
720
-
721
- <Note>
722
- Variables are stored in the database and can be encrypted. Perfect for API keys, credentials, and environment-specific values.
723
- </Note>
724
- </Accordion>
725
- </AccordionGroup>
726
-
727
- ## Error handling patterns
728
-
729
- <Tabs>
730
- <Tab title="Return error in result">
731
- ```typescript
732
- execute: async (inputs) => {
733
- try {
734
- const data = await riskyOperation(inputs);
735
- return {
736
- result: JSON.stringify({ success: true, data })
737
- };
738
- } catch (error) {
739
- return {
740
- result: JSON.stringify({
741
- success: false,
742
- error: error.message
743
- })
744
- };
745
- }
746
- }
747
- ```
748
- </Tab>
749
-
750
- <Tab title="Throw error (will be caught by framework)">
751
- ```typescript
752
- execute: async (inputs) => {
753
- if (!inputs.userId) {
754
- throw new Error("userId is required");
755
- }
756
-
757
- const user = await db.users.findOne({ id: inputs.userId });
758
-
759
- if (!user) {
760
- throw new Error(`User not found: ${inputs.userId}`);
761
- }
762
-
763
- return { result: JSON.stringify(user) };
764
- }
765
- ```
766
- </Tab>
767
-
768
- <Tab title="Partial errors in streaming">
769
- ```typescript
770
- execute: async function* (inputs) {
771
- for (const item of inputs.items) {
772
- try {
773
- const result = await processItem(item);
774
- yield {
775
- result: JSON.stringify({
776
- item,
777
- status: "success",
778
- data: result
779
- })
780
- };
781
- } catch (error) {
782
- yield {
783
- result: JSON.stringify({
784
- item,
785
- status: "error",
786
- error: error.message
787
- })
788
- };
789
- }
790
- }
791
- }
792
- ```
793
- </Tab>
794
- </Tabs>
795
-
796
- ## Next steps
797
-
798
- <CardGroup cols={2}>
799
- <Card title="API reference" icon="code" href="/core/exulu-tool/api-reference">
800
- Explore methods and properties
801
- </Card>
802
- <Card title="ExuluApp" icon="cube" href="/core/exulu-app/introduction">
803
- Learn how to register tools with ExuluApp
804
- </Card>
805
- </CardGroup>