@objectstack/service-ai 4.0.4 → 4.0.5

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 (52) hide show
  1. package/dist/index.cjs +1176 -135
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +1225 -430
  4. package/dist/index.d.ts +1225 -430
  5. package/dist/index.js +1160 -128
  6. package/dist/index.js.map +1 -1
  7. package/package.json +35 -8
  8. package/.turbo/turbo-build.log +0 -22
  9. package/CHANGELOG.md +0 -61
  10. package/src/__tests__/ai-service.test.ts +0 -981
  11. package/src/__tests__/auth-and-toolcalling.test.ts +0 -677
  12. package/src/__tests__/chatbot-features.test.ts +0 -1116
  13. package/src/__tests__/metadata-tools.test.ts +0 -970
  14. package/src/__tests__/objectql-conversation-service.test.ts +0 -382
  15. package/src/__tests__/tool-routes.test.ts +0 -191
  16. package/src/__tests__/vercel-stream-encoder.test.ts +0 -310
  17. package/src/adapters/index.ts +0 -6
  18. package/src/adapters/memory-adapter.ts +0 -72
  19. package/src/adapters/types.ts +0 -3
  20. package/src/adapters/vercel-adapter.ts +0 -148
  21. package/src/agent-runtime.ts +0 -154
  22. package/src/agents/data-chat-agent.ts +0 -79
  23. package/src/agents/index.ts +0 -4
  24. package/src/agents/metadata-assistant-agent.ts +0 -87
  25. package/src/ai-service.ts +0 -364
  26. package/src/conversation/in-memory-conversation-service.ts +0 -103
  27. package/src/conversation/index.ts +0 -4
  28. package/src/conversation/objectql-conversation-service.ts +0 -301
  29. package/src/index.ts +0 -60
  30. package/src/objects/ai-conversation.object.ts +0 -86
  31. package/src/objects/ai-message.object.ts +0 -86
  32. package/src/objects/index.ts +0 -10
  33. package/src/plugin.ts +0 -391
  34. package/src/routes/agent-routes.ts +0 -190
  35. package/src/routes/ai-routes.ts +0 -439
  36. package/src/routes/index.ts +0 -5
  37. package/src/routes/message-utils.ts +0 -90
  38. package/src/routes/tool-routes.ts +0 -142
  39. package/src/stream/index.ts +0 -3
  40. package/src/stream/vercel-stream-encoder.ts +0 -153
  41. package/src/tools/add-field.tool.ts +0 -70
  42. package/src/tools/create-object.tool.ts +0 -66
  43. package/src/tools/data-tools.ts +0 -293
  44. package/src/tools/delete-field.tool.ts +0 -38
  45. package/src/tools/describe-object.tool.ts +0 -31
  46. package/src/tools/index.ts +0 -18
  47. package/src/tools/list-objects.tool.ts +0 -34
  48. package/src/tools/metadata-tools.ts +0 -430
  49. package/src/tools/modify-field.tool.ts +0 -44
  50. package/src/tools/tool-registry.ts +0 -132
  51. package/tsconfig.json +0 -17
  52. package/vitest.config.ts +0 -23
@@ -1,153 +0,0 @@
1
- // Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
2
-
3
- /**
4
- * Vercel AI SDK v6 — UI Message Stream Encoder
5
- *
6
- * Converts `AsyncIterable<TextStreamPart<ToolSet>>` (the internal ObjectStack
7
- * streaming format) into the Vercel AI SDK v6 **UI Message Stream Protocol**.
8
- *
9
- * Wire format: Server-Sent Events (SSE) with JSON payloads.
10
- * `data: {"type":"text-delta","id":"0","delta":"Hello"}\n\n`
11
- *
12
- * The client-side `DefaultChatTransport` from `ai` v6 uses
13
- * `parseJsonEventStream` to parse these SSE events.
14
- *
15
- * @see https://ai-sdk.dev/docs/ai-sdk-ui/stream-protocol
16
- */
17
-
18
- import type { TextStreamPart, ToolSet } from 'ai';
19
-
20
- // ── SSE helpers ──────────────────────────────────────────────────────
21
-
22
- function sse(data: object): string {
23
- return `data: ${JSON.stringify(data)}\n\n`;
24
- }
25
-
26
- /**
27
- * Encode data using Vercel AI SDK Data Stream Protocol prefixes.
28
- * @see https://ai-sdk.dev/docs/ai-sdk-ui/stream-protocol
29
- */
30
- function dataStreamLine(prefix: string, data: object): string {
31
- return `${prefix}:${JSON.stringify(data)}\n`;
32
- }
33
-
34
- // ── Public API ──────────────────────────────────────────────────────
35
-
36
- /**
37
- * Encode a single `TextStreamPart` event into SSE-formatted UI Message
38
- * Stream chunk(s).
39
- *
40
- * Returns an empty string for event types that have no wire-format mapping.
41
- */
42
- export function encodeStreamPart(part: TextStreamPart<ToolSet>): string {
43
- switch (part.type) {
44
- case 'text-delta':
45
- return sse({ type: 'text-delta', id: '0', delta: part.text });
46
-
47
- case 'tool-input-start':
48
- return sse({
49
- type: 'tool-input-start',
50
- toolCallId: part.id,
51
- toolName: part.toolName,
52
- });
53
-
54
- case 'tool-input-delta':
55
- return sse({
56
- type: 'tool-input-delta',
57
- toolCallId: part.id,
58
- inputTextDelta: part.delta,
59
- });
60
-
61
- case 'tool-call':
62
- return sse({
63
- type: 'tool-input-available',
64
- toolCallId: part.toolCallId,
65
- toolName: part.toolName,
66
- input: part.input,
67
- });
68
-
69
- case 'tool-result':
70
- return sse({
71
- type: 'tool-output-available',
72
- toolCallId: part.toolCallId,
73
- output: part.output,
74
- });
75
-
76
- case 'error':
77
- return sse({
78
- type: 'error',
79
- errorText: String(part.error),
80
- });
81
-
82
- // Handle reasoning/thinking streams (DeepSeek R1, o1-style models)
83
- // Use 'g:' prefix for reasoning content per Vercel AI SDK protocol
84
- case 'reasoning-start':
85
- return dataStreamLine('g', { text: '' });
86
-
87
- case 'reasoning-delta':
88
- return dataStreamLine('g', { text: part.text });
89
-
90
- case 'reasoning-end':
91
- return ''; // No specific end marker needed for reasoning
92
-
93
- // finish-step and finish are handled by the generator, not here
94
- default:
95
- // Pass through any unknown event types that might be custom
96
- // (e.g., step-start, step-finish from custom providers)
97
- if ((part as any).type?.startsWith('step-')) {
98
- return sse(part as any);
99
- }
100
- return '';
101
- }
102
- }
103
-
104
- /**
105
- * Transform an `AsyncIterable<TextStreamPart>` into an `AsyncIterable<string>`
106
- * where each yielded string is an SSE-formatted UI Message Stream chunk.
107
- *
108
- * Lifecycle order required by the client:
109
- * start → start-step → text-start → text-delta* → text-end → finish-step → finish → [DONE]
110
- */
111
- export async function* encodeVercelDataStream(
112
- events: AsyncIterable<TextStreamPart<ToolSet>>,
113
- ): AsyncIterable<string> {
114
- // Preamble
115
- yield sse({ type: 'start' });
116
- yield sse({ type: 'start-step' });
117
- yield sse({ type: 'text-start', id: '0' });
118
-
119
- let textOpen = true;
120
- let finishReason = 'stop';
121
-
122
- for await (const part of events) {
123
- // Capture finish reason
124
- if (part.type === 'finish') {
125
- finishReason = part.finishReason ?? 'stop';
126
- }
127
-
128
- // Before finish-step/finish, close the text part first
129
- if (part.type === 'finish-step' || part.type === 'finish') {
130
- if (textOpen) {
131
- yield sse({ type: 'text-end', id: '0' });
132
- textOpen = false;
133
- }
134
- // Don't emit these via encodeStreamPart — we handle them in postamble
135
- continue;
136
- }
137
-
138
- const frame = encodeStreamPart(part);
139
- if (frame) {
140
- yield frame;
141
- }
142
- }
143
-
144
- // Close text if still open (safety)
145
- if (textOpen) {
146
- yield sse({ type: 'text-end', id: '0' });
147
- }
148
-
149
- // Postamble
150
- yield sse({ type: 'finish-step' });
151
- yield sse({ type: 'finish', finishReason });
152
- yield 'data: [DONE]\n\n';
153
- }
@@ -1,70 +0,0 @@
1
- // Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
2
-
3
- import { defineTool } from '@objectstack/spec/ai';
4
-
5
- /**
6
- * add_field — AI Tool Metadata
7
- *
8
- * Adds a new field (column) to an existing data object.
9
- * Validates snake_case for objectName, field name, reference,
10
- * and select option values before merging into the definition.
11
- */
12
- export const addFieldTool = defineTool({
13
- name: 'add_field',
14
- label: 'Add Field',
15
- description:
16
- 'Adds a new field (column) to an existing data object. ' +
17
- 'Use this when the user wants to add a property, column, or attribute to a table.',
18
- category: 'data',
19
- builtIn: true,
20
- parameters: {
21
- type: 'object',
22
- properties: {
23
- objectName: {
24
- type: 'string',
25
- description: 'Target object machine name (snake_case)',
26
- },
27
- name: {
28
- type: 'string',
29
- description: 'Field machine name (snake_case, e.g. due_date)',
30
- },
31
- label: {
32
- type: 'string',
33
- description: 'Human-readable field label (e.g. Due Date)',
34
- },
35
- type: {
36
- type: 'string',
37
- description: 'Field data type',
38
- enum: ['text', 'textarea', 'number', 'boolean', 'date', 'datetime', 'select', 'lookup', 'formula', 'autonumber'],
39
- },
40
- required: {
41
- type: 'boolean',
42
- description: 'Whether the field is required',
43
- },
44
- defaultValue: {
45
- description: 'Default value for the field',
46
- },
47
- options: {
48
- type: 'array',
49
- description: 'Options for select/picklist fields',
50
- items: {
51
- type: 'object',
52
- properties: {
53
- label: { type: 'string' },
54
- value: {
55
- type: 'string',
56
- description: 'Option machine identifier (lowercase snake_case, e.g. high_priority)',
57
- pattern: '^[a-z_][a-z0-9_]*$',
58
- },
59
- },
60
- },
61
- },
62
- reference: {
63
- type: 'string',
64
- description: 'Referenced object name for lookup fields (snake_case, e.g. account)',
65
- },
66
- },
67
- required: ['objectName', 'name', 'type'],
68
- additionalProperties: false,
69
- },
70
- });
@@ -1,66 +0,0 @@
1
- // Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
2
-
3
- import { defineTool } from '@objectstack/spec/ai';
4
-
5
- /**
6
- * create_object — AI Tool Metadata
7
- *
8
- * Creates a new data object (table) with schema validation.
9
- * Validates snake_case naming for object and initial fields,
10
- * checks for duplicates, and registers the object definition.
11
- */
12
- export const createObjectTool = defineTool({
13
- name: 'create_object',
14
- label: 'Create Object',
15
- description:
16
- 'Creates a new data object (table) with the specified name, label, and optional field definitions. ' +
17
- 'Use this when the user wants to create a new entity, table, or data model.',
18
- category: 'data',
19
- builtIn: true,
20
- // NOTE: requiresConfirmation is intentionally false (default) because the
21
- // server-side tool-call loop in AIService.chatWithTools/streamChatWithTools
22
- // executes tool calls immediately without checking this flag. The flag
23
- // should only be set once server-side approval gating is implemented to
24
- // avoid giving users a false sense of safety.
25
- parameters: {
26
- type: 'object',
27
- properties: {
28
- name: {
29
- type: 'string',
30
- description: 'Machine name for the object (snake_case, e.g. project_task)',
31
- },
32
- label: {
33
- type: 'string',
34
- description: 'Human-readable display name (e.g. Project Task)',
35
- },
36
- fields: {
37
- type: 'array',
38
- description: 'Initial fields to create with the object',
39
- items: {
40
- type: 'object',
41
- properties: {
42
- name: { type: 'string', description: 'Field machine name (snake_case)' },
43
- label: { type: 'string', description: 'Field display name' },
44
- type: {
45
- type: 'string',
46
- description: 'Field data type',
47
- enum: ['text', 'textarea', 'number', 'boolean', 'date', 'datetime', 'select', 'lookup', 'formula', 'autonumber'],
48
- },
49
- required: { type: 'boolean', description: 'Whether the field is required' },
50
- },
51
- required: ['name', 'type'],
52
- },
53
- },
54
- enableFeatures: {
55
- type: 'object',
56
- description: 'Object capability flags',
57
- properties: {
58
- trackHistory: { type: 'boolean' },
59
- apiEnabled: { type: 'boolean' },
60
- },
61
- },
62
- },
63
- required: ['name', 'label'],
64
- additionalProperties: false,
65
- },
66
- });
@@ -1,293 +0,0 @@
1
- // Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
2
-
3
- import type { AIToolDefinition, IDataEngine } from '@objectstack/spec/contracts';
4
- import type { ToolHandler } from './tool-registry.js';
5
- import type { ToolRegistry } from './tool-registry.js';
6
-
7
- // ---------------------------------------------------------------------------
8
- // Data context — injected once at registration time
9
- // ---------------------------------------------------------------------------
10
-
11
- /**
12
- * Services required by the built-in data tools.
13
- *
14
- * These are provided by the kernel at `ai:ready` time and closed over
15
- * by the handler functions so they stay framework-agnostic.
16
- */
17
- export interface DataToolContext {
18
- /** ObjectQL data engine for record-level operations. */
19
- dataEngine: IDataEngine;
20
- }
21
-
22
- // ---------------------------------------------------------------------------
23
- // Tool Definitions
24
- // ---------------------------------------------------------------------------
25
-
26
- /** Maximum number of records a single query may return. */
27
- const MAX_QUERY_LIMIT = 200;
28
-
29
- /** Default record limit when not specified. */
30
- const DEFAULT_QUERY_LIMIT = 20;
31
-
32
- export const QUERY_RECORDS_TOOL: AIToolDefinition = {
33
- name: 'query_records',
34
- description:
35
- 'Query records from a data object with optional filters, field selection, ' +
36
- 'sorting, and pagination. Returns an array of matching records.',
37
- parameters: {
38
- type: 'object',
39
- properties: {
40
- objectName: {
41
- type: 'string',
42
- description: 'The snake_case name of the object to query',
43
- },
44
- where: {
45
- type: 'object',
46
- description:
47
- 'Filter conditions as key-value pairs (e.g. { "status": "active" }) ' +
48
- 'or MongoDB-style operators (e.g. { "amount": { "$gt": 100 } })',
49
- },
50
- fields: {
51
- type: 'array',
52
- items: { type: 'string' },
53
- description: 'List of field names to return (omit for all fields)',
54
- },
55
- orderBy: {
56
- type: 'array',
57
- items: {
58
- type: 'object',
59
- properties: {
60
- field: { type: 'string' },
61
- order: { type: 'string', enum: ['asc', 'desc'] },
62
- },
63
- },
64
- description: 'Sort order (e.g. [{ "field": "created_at", "order": "desc" }])',
65
- },
66
- limit: {
67
- type: 'number',
68
- description: `Maximum number of records to return (default ${DEFAULT_QUERY_LIMIT}, max ${MAX_QUERY_LIMIT})`,
69
- },
70
- offset: {
71
- type: 'number',
72
- description: 'Number of records to skip for pagination',
73
- },
74
- },
75
- required: ['objectName'],
76
- additionalProperties: false,
77
- },
78
- };
79
-
80
- export const GET_RECORD_TOOL: AIToolDefinition = {
81
- name: 'get_record',
82
- description: 'Get a single record by its ID from a data object.',
83
- parameters: {
84
- type: 'object',
85
- properties: {
86
- objectName: {
87
- type: 'string',
88
- description: 'The snake_case name of the object',
89
- },
90
- recordId: {
91
- type: 'string',
92
- description: 'The unique ID of the record',
93
- },
94
- fields: {
95
- type: 'array',
96
- items: { type: 'string' },
97
- description: 'List of field names to return (omit for all fields)',
98
- },
99
- },
100
- required: ['objectName', 'recordId'],
101
- additionalProperties: false,
102
- },
103
- };
104
-
105
- export const AGGREGATE_DATA_TOOL: AIToolDefinition = {
106
- name: 'aggregate_data',
107
- description:
108
- 'Perform aggregation/statistical operations on a data object. ' +
109
- 'Supports count, sum, avg, min, max with optional groupBy and where filters.',
110
- parameters: {
111
- type: 'object',
112
- properties: {
113
- objectName: {
114
- type: 'string',
115
- description: 'The snake_case name of the object to aggregate',
116
- },
117
- aggregations: {
118
- type: 'array',
119
- items: {
120
- type: 'object',
121
- properties: {
122
- function: {
123
- type: 'string',
124
- enum: ['count', 'sum', 'avg', 'min', 'max', 'count_distinct'],
125
- description: 'Aggregation function',
126
- },
127
- field: {
128
- type: 'string',
129
- description: 'Field to aggregate (optional for count)',
130
- },
131
- alias: {
132
- type: 'string',
133
- description: 'Result column alias',
134
- },
135
- },
136
- required: ['function', 'alias'],
137
- },
138
- description: 'Aggregation definitions',
139
- },
140
- groupBy: {
141
- type: 'array',
142
- items: { type: 'string' },
143
- description: 'Fields to group by',
144
- },
145
- where: {
146
- type: 'object',
147
- description: 'Filter conditions applied before aggregation',
148
- },
149
- },
150
- required: ['objectName', 'aggregations'],
151
- additionalProperties: false,
152
- },
153
- };
154
-
155
- /** All built-in data tools definitions. */
156
- export const DATA_TOOL_DEFINITIONS: AIToolDefinition[] = [
157
- QUERY_RECORDS_TOOL,
158
- GET_RECORD_TOOL,
159
- AGGREGATE_DATA_TOOL,
160
- ];
161
-
162
- // ---------------------------------------------------------------------------
163
- // Handler Factories
164
- // ---------------------------------------------------------------------------
165
-
166
- function createQueryRecordsHandler(ctx: DataToolContext): ToolHandler {
167
- return async (args) => {
168
- const {
169
- objectName,
170
- where,
171
- fields,
172
- orderBy,
173
- limit,
174
- offset,
175
- } = args as {
176
- objectName: string;
177
- where?: Record<string, unknown>;
178
- fields?: string[];
179
- orderBy?: Array<{ field: string; order: 'asc' | 'desc' }>;
180
- limit?: number;
181
- offset?: number;
182
- };
183
-
184
- // Validate and clamp limit to [1, MAX_QUERY_LIMIT]
185
- const rawLimit = limit ?? DEFAULT_QUERY_LIMIT;
186
- const safeLimit = Number.isFinite(rawLimit) && rawLimit > 0
187
- ? Math.min(Math.floor(rawLimit), MAX_QUERY_LIMIT)
188
- : DEFAULT_QUERY_LIMIT;
189
-
190
- // Validate offset: must be a non-negative finite integer
191
- const safeOffset = (Number.isFinite(offset) && (offset as number) >= 0)
192
- ? Math.floor(offset as number)
193
- : undefined;
194
-
195
- const records = await ctx.dataEngine.find(objectName, {
196
- where,
197
- fields,
198
- orderBy,
199
- limit: safeLimit,
200
- offset: safeOffset,
201
- });
202
-
203
- return JSON.stringify({ count: records.length, records });
204
- };
205
- }
206
-
207
- function createGetRecordHandler(ctx: DataToolContext): ToolHandler {
208
- return async (args) => {
209
- const { objectName, recordId, fields } = args as {
210
- objectName: string;
211
- recordId: string;
212
- fields?: string[];
213
- };
214
-
215
- const record = await ctx.dataEngine.findOne(objectName, {
216
- where: { id: recordId },
217
- fields,
218
- });
219
-
220
- if (!record) {
221
- return JSON.stringify({ error: `Record "${recordId}" not found in "${objectName}"` });
222
- }
223
-
224
- return JSON.stringify(record);
225
- };
226
- }
227
-
228
- /** Aggregation function names supported by the data engine. */
229
- type AggFn = 'count' | 'sum' | 'avg' | 'min' | 'max' | 'count_distinct';
230
-
231
- /** Set of valid aggregation function names for runtime validation. */
232
- const VALID_AGG_FUNCTIONS = new Set<string>([
233
- 'count', 'sum', 'avg', 'min', 'max', 'count_distinct',
234
- ]);
235
-
236
- function createAggregateDataHandler(ctx: DataToolContext): ToolHandler {
237
- return async (args) => {
238
- const { objectName, aggregations, groupBy, where } = args as {
239
- objectName: string;
240
- aggregations: Array<{ function: string; field?: string; alias: string }>;
241
- groupBy?: string[];
242
- where?: Record<string, unknown>;
243
- };
244
-
245
- // Validate aggregation functions at runtime
246
- for (const a of aggregations) {
247
- if (!VALID_AGG_FUNCTIONS.has(a.function)) {
248
- return JSON.stringify({
249
- error: `Invalid aggregation function "${a.function}". ` +
250
- `Allowed: ${[...VALID_AGG_FUNCTIONS].join(', ')}`,
251
- });
252
- }
253
- }
254
-
255
- const result = await ctx.dataEngine.aggregate(objectName, {
256
- where,
257
- groupBy,
258
- aggregations: aggregations.map(a => ({
259
- function: a.function as AggFn,
260
- field: a.field,
261
- alias: a.alias,
262
- })),
263
- });
264
-
265
- return JSON.stringify(result);
266
- };
267
- }
268
-
269
- // ---------------------------------------------------------------------------
270
- // Public Registration Helper
271
- // ---------------------------------------------------------------------------
272
-
273
- /**
274
- * Register all built-in data tools on the given {@link ToolRegistry}.
275
- *
276
- * Typically called from the `ai:ready` hook after the data engine is available.
277
- *
278
- * @example
279
- * ```ts
280
- * ctx.hook('ai:ready', async (aiService) => {
281
- * const dataEngine = ctx.getService<IDataEngine>('data');
282
- * registerDataTools(aiService.toolRegistry, { dataEngine });
283
- * });
284
- * ```
285
- */
286
- export function registerDataTools(
287
- registry: ToolRegistry,
288
- context: DataToolContext,
289
- ): void {
290
- registry.register(QUERY_RECORDS_TOOL, createQueryRecordsHandler(context));
291
- registry.register(GET_RECORD_TOOL, createGetRecordHandler(context));
292
- registry.register(AGGREGATE_DATA_TOOL, createAggregateDataHandler(context));
293
- }
@@ -1,38 +0,0 @@
1
- // Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
2
-
3
- import { defineTool } from '@objectstack/spec/ai';
4
-
5
- /**
6
- * delete_field — AI Tool Metadata
7
- *
8
- * Removes a field (column) from an existing data object.
9
- * This is a destructive operation.
10
- */
11
- export const deleteFieldTool = defineTool({
12
- name: 'delete_field',
13
- label: 'Delete Field',
14
- description:
15
- 'Removes a field (column) from an existing data object. This is a destructive operation. ' +
16
- 'Use this when the user explicitly wants to remove an attribute or column from a table.',
17
- category: 'data',
18
- builtIn: true,
19
- // NOTE: requiresConfirmation is intentionally false (default) because the
20
- // server-side tool-call loop in AIService.chatWithTools/streamChatWithTools
21
- // executes tool calls immediately without checking this flag. The flag
22
- // should only be set once server-side approval gating is implemented.
23
- parameters: {
24
- type: 'object',
25
- properties: {
26
- objectName: {
27
- type: 'string',
28
- description: 'Target object machine name (snake_case)',
29
- },
30
- fieldName: {
31
- type: 'string',
32
- description: 'Field machine name to delete (snake_case)',
33
- },
34
- },
35
- required: ['objectName', 'fieldName'],
36
- additionalProperties: false,
37
- },
38
- });
@@ -1,31 +0,0 @@
1
- // Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
2
-
3
- import { defineTool } from '@objectstack/spec/ai';
4
-
5
- /**
6
- * describe_object — AI Tool Metadata
7
- *
8
- * Returns the full schema of a data object including all fields, types,
9
- * relationships, and configuration. This is the single, unified tool for
10
- * describing objects — used by both data_chat and metadata_assistant agents.
11
- */
12
- export const describeObjectTool = defineTool({
13
- name: 'describe_object',
14
- label: 'Describe Object',
15
- description:
16
- 'Returns the full schema details of a data object, including all fields, types, relationships, and configuration. ' +
17
- 'Use this to understand the structure of a table before querying or modifying it.',
18
- category: 'data',
19
- builtIn: true,
20
- parameters: {
21
- type: 'object',
22
- properties: {
23
- objectName: {
24
- type: 'string',
25
- description: 'Object machine name to describe (snake_case)',
26
- },
27
- },
28
- required: ['objectName'],
29
- additionalProperties: false,
30
- },
31
- });
@@ -1,18 +0,0 @@
1
- // Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
2
-
3
- export { ToolRegistry } from './tool-registry.js';
4
- export type { ToolHandler, ToolExecutionResult } from './tool-registry.js';
5
-
6
- export { registerDataTools, DATA_TOOL_DEFINITIONS } from './data-tools.js';
7
- export type { DataToolContext } from './data-tools.js';
8
-
9
- export { registerMetadataTools, METADATA_TOOL_DEFINITIONS } from './metadata-tools.js';
10
- export type { MetadataToolContext } from './metadata-tools.js';
11
-
12
- // Individual tool metadata exports
13
- export { createObjectTool } from './create-object.tool.js';
14
- export { addFieldTool } from './add-field.tool.js';
15
- export { modifyFieldTool } from './modify-field.tool.js';
16
- export { deleteFieldTool } from './delete-field.tool.js';
17
- export { listObjectsTool } from './list-objects.tool.js';
18
- export { describeObjectTool } from './describe-object.tool.js';