@aerostack/sdk-vercel-ai 0.10.1

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 (36) hide show
  1. package/README.md +69 -0
  2. package/dist/commonjs/__tests__/converter.test.d.ts +2 -0
  3. package/dist/commonjs/__tests__/converter.test.d.ts.map +1 -0
  4. package/dist/commonjs/__tests__/converter.test.js +141 -0
  5. package/dist/commonjs/__tests__/converter.test.js.map +1 -0
  6. package/dist/commonjs/__tests__/index.test.d.ts +2 -0
  7. package/dist/commonjs/__tests__/index.test.d.ts.map +1 -0
  8. package/dist/commonjs/__tests__/index.test.js +29 -0
  9. package/dist/commonjs/__tests__/index.test.js.map +1 -0
  10. package/dist/commonjs/converter.d.ts +18 -0
  11. package/dist/commonjs/converter.d.ts.map +1 -0
  12. package/dist/commonjs/converter.js +70 -0
  13. package/dist/commonjs/converter.js.map +1 -0
  14. package/dist/commonjs/index.d.ts +71 -0
  15. package/dist/commonjs/index.d.ts.map +1 -0
  16. package/dist/commonjs/index.js +82 -0
  17. package/dist/commonjs/index.js.map +1 -0
  18. package/dist/commonjs/package.json +3 -0
  19. package/dist/esm/__tests__/converter.test.d.ts +2 -0
  20. package/dist/esm/__tests__/converter.test.d.ts.map +1 -0
  21. package/dist/esm/__tests__/converter.test.js +139 -0
  22. package/dist/esm/__tests__/converter.test.js.map +1 -0
  23. package/dist/esm/__tests__/index.test.d.ts +2 -0
  24. package/dist/esm/__tests__/index.test.d.ts.map +1 -0
  25. package/dist/esm/__tests__/index.test.js +27 -0
  26. package/dist/esm/__tests__/index.test.js.map +1 -0
  27. package/dist/esm/converter.d.ts +18 -0
  28. package/dist/esm/converter.d.ts.map +1 -0
  29. package/dist/esm/converter.js +66 -0
  30. package/dist/esm/converter.js.map +1 -0
  31. package/dist/esm/index.d.ts +71 -0
  32. package/dist/esm/index.d.ts.map +1 -0
  33. package/dist/esm/index.js +76 -0
  34. package/dist/esm/index.js.map +1 -0
  35. package/dist/esm/package.json +3 -0
  36. package/package.json +66 -0
package/README.md ADDED
@@ -0,0 +1,69 @@
1
+ # @aerostack/sdk-vercel-ai
2
+
3
+ Use [Aerostack](https://aerostack.dev) workspace tools with the [Vercel AI SDK](https://sdk.vercel.ai/).
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @aerostack/sdk-vercel-ai ai
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```typescript
14
+ import { openai } from '@ai-sdk/openai';
15
+ import { generateText } from 'ai';
16
+ import { getTools } from '@aerostack/sdk-vercel-ai';
17
+
18
+ const { tools } = await getTools({ workspace: 'my-workspace', token: 'mwt_...' });
19
+
20
+ const { text } = await generateText({
21
+ model: openai('gpt-4o'),
22
+ tools,
23
+ maxSteps: 5,
24
+ prompt: 'Create a GitHub issue for the login bug',
25
+ });
26
+ ```
27
+
28
+ ## Streaming
29
+
30
+ ```typescript
31
+ import { streamText } from 'ai';
32
+
33
+ const { tools } = await getTools({ workspace: 'my-workspace', token: 'mwt_...' });
34
+
35
+ const result = streamText({
36
+ model: openai('gpt-4o'),
37
+ tools,
38
+ maxSteps: 10,
39
+ prompt: 'Summarize Notion pages and post to Slack',
40
+ });
41
+
42
+ for await (const chunk of result.textStream) {
43
+ process.stdout.write(chunk);
44
+ }
45
+ ```
46
+
47
+ ## Factory Pattern
48
+
49
+ ```typescript
50
+ import { createAerostackVercelAI } from '@aerostack/sdk-vercel-ai';
51
+
52
+ const aero = createAerostackVercelAI({ workspace: 'my-workspace', token: 'mwt_...' });
53
+ const { tools } = await aero.tools();
54
+ ```
55
+
56
+ ## API
57
+
58
+ ### `getTools(config)` → `Promise<ToolSetResult>`
59
+
60
+ Fetches tools from the workspace. Each tool includes an `execute` function that calls the workspace gateway. Returns `{ tools, raw }`.
61
+
62
+ ### `createAerostackVercelAI(config)` → `AerostackVercelAIClient`
63
+
64
+ Creates a reusable client that shares a single WorkspaceClient instance.
65
+
66
+ ## Requirements
67
+
68
+ - `ai` >= 3.0.0
69
+ - An Aerostack workspace with a token (`mwt_...`)
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=converter.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"converter.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/converter.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,141 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const converter_js_1 = require("../converter.js");
5
+ function mockClient(callToolResult, shouldThrow = false) {
6
+ return {
7
+ callTool: shouldThrow
8
+ ? vitest_1.vi.fn().mockRejectedValue(callToolResult)
9
+ : vitest_1.vi.fn().mockResolvedValue(callToolResult),
10
+ };
11
+ }
12
+ (0, vitest_1.describe)('convertTools', () => {
13
+ (0, vitest_1.it)('converts MCP tools to Vercel AI SDK ToolSet', () => {
14
+ const mcpTools = [
15
+ {
16
+ name: 'github__create_issue',
17
+ description: 'Create a GitHub issue',
18
+ inputSchema: {
19
+ type: 'object',
20
+ properties: { title: { type: 'string' } },
21
+ required: ['title'],
22
+ },
23
+ },
24
+ {
25
+ name: 'slack__post_message',
26
+ description: 'Post to Slack',
27
+ inputSchema: {
28
+ type: 'object',
29
+ properties: { channel: { type: 'string' }, text: { type: 'string' } },
30
+ },
31
+ },
32
+ ];
33
+ const client = mockClient({});
34
+ const tools = (0, converter_js_1.convertTools)(mcpTools, client);
35
+ (0, vitest_1.expect)(Object.keys(tools)).toEqual(['github__create_issue', 'slack__post_message']);
36
+ (0, vitest_1.expect)(tools['github__create_issue']).toBeDefined();
37
+ (0, vitest_1.expect)(tools['slack__post_message']).toBeDefined();
38
+ });
39
+ (0, vitest_1.it)('handles tools with no inputSchema', () => {
40
+ const mcpTools = [
41
+ { name: 'ping', description: 'Ping the server' },
42
+ ];
43
+ const client = mockClient({});
44
+ const tools = (0, converter_js_1.convertTools)(mcpTools, client);
45
+ (0, vitest_1.expect)(tools['ping']).toBeDefined();
46
+ });
47
+ (0, vitest_1.it)('handles tools with no description', () => {
48
+ const mcpTools = [
49
+ { name: 'my_tool', inputSchema: { type: 'object', properties: {} } },
50
+ ];
51
+ const client = mockClient({});
52
+ const tools = (0, converter_js_1.convertTools)(mcpTools, client);
53
+ (0, vitest_1.expect)(tools['my_tool']).toBeDefined();
54
+ });
55
+ (0, vitest_1.it)('skips tools with empty names', () => {
56
+ const mcpTools = [
57
+ { name: '', description: 'Bad tool' },
58
+ { name: 'good_tool', description: 'Good tool' },
59
+ ];
60
+ const client = mockClient({});
61
+ const tools = (0, converter_js_1.convertTools)(mcpTools, client);
62
+ (0, vitest_1.expect)(Object.keys(tools)).toEqual(['good_tool']);
63
+ });
64
+ (0, vitest_1.it)('handles empty tools array', () => {
65
+ const client = mockClient({});
66
+ const tools = (0, converter_js_1.convertTools)([], client);
67
+ (0, vitest_1.expect)(Object.keys(tools)).toEqual([]);
68
+ });
69
+ (0, vitest_1.it)('execute function calls WorkspaceClient.callTool', async () => {
70
+ const mcpTools = [
71
+ {
72
+ name: 'test_tool',
73
+ description: 'Test',
74
+ inputSchema: { type: 'object', properties: { x: { type: 'number' } } },
75
+ },
76
+ ];
77
+ const client = mockClient({
78
+ content: [{ type: 'text', text: 'result123' }],
79
+ });
80
+ const tools = (0, converter_js_1.convertTools)(mcpTools, client);
81
+ const result = await tools['test_tool'].execute({ x: 42 }, { toolCallId: 'tc_1', messages: [], abortSignal: new AbortController().signal });
82
+ (0, vitest_1.expect)(client.callTool).toHaveBeenCalledWith('test_tool', { x: 42 });
83
+ (0, vitest_1.expect)(result).toBe('result123');
84
+ });
85
+ (0, vitest_1.it)('execute function handles AerostackError gracefully', async () => {
86
+ const { AerostackError } = await import('@aerostack/core');
87
+ const err = new AerostackError('Server down', 503, -32603, 'req-1');
88
+ const client = mockClient(err, true);
89
+ const mcpTools = [
90
+ { name: 'failing_tool', description: 'Fails' },
91
+ ];
92
+ const tools = (0, converter_js_1.convertTools)(mcpTools, client);
93
+ const result = await tools['failing_tool'].execute({}, { toolCallId: 'tc_1', messages: [], abortSignal: new AbortController().signal });
94
+ (0, vitest_1.expect)(result).toContain('Error (-32603)');
95
+ (0, vitest_1.expect)(result).toContain('Server down');
96
+ });
97
+ (0, vitest_1.it)('execute function handles generic errors', async () => {
98
+ const client = mockClient(new Error('Network timeout'), true);
99
+ const mcpTools = [
100
+ { name: 'timeout_tool', description: 'Timeouts' },
101
+ ];
102
+ const tools = (0, converter_js_1.convertTools)(mcpTools, client);
103
+ const result = await tools['timeout_tool'].execute({}, { toolCallId: 'tc_1', messages: [], abortSignal: new AbortController().signal });
104
+ (0, vitest_1.expect)(result).toBe('Error: Network timeout');
105
+ });
106
+ });
107
+ (0, vitest_1.describe)('formatToolResult', () => {
108
+ (0, vitest_1.it)('formats single text content', () => {
109
+ (0, vitest_1.expect)((0, converter_js_1.formatToolResult)({
110
+ content: [{ type: 'text', text: 'Hello' }],
111
+ })).toBe('Hello');
112
+ });
113
+ (0, vitest_1.it)('concatenates multiple text blocks', () => {
114
+ (0, vitest_1.expect)((0, converter_js_1.formatToolResult)({
115
+ content: [
116
+ { type: 'text', text: 'Line 1' },
117
+ { type: 'text', text: 'Line 2' },
118
+ ],
119
+ })).toBe('Line 1\nLine 2');
120
+ });
121
+ (0, vitest_1.it)('handles binary data blocks', () => {
122
+ const result = (0, converter_js_1.formatToolResult)({
123
+ content: [{ type: 'image', data: 'abc123', mimeType: 'image/png' }],
124
+ });
125
+ (0, vitest_1.expect)(result).toContain('image/png');
126
+ });
127
+ (0, vitest_1.it)('prefixes error results', () => {
128
+ (0, vitest_1.expect)((0, converter_js_1.formatToolResult)({
129
+ content: [{ type: 'text', text: 'Something failed' }],
130
+ isError: true,
131
+ })).toBe('Error: Something failed');
132
+ });
133
+ (0, vitest_1.it)('handles empty content', () => {
134
+ (0, vitest_1.expect)((0, converter_js_1.formatToolResult)({ content: [] })).toBe('Success (no output)');
135
+ (0, vitest_1.expect)((0, converter_js_1.formatToolResult)({})).toBe('Success (no output)');
136
+ });
137
+ (0, vitest_1.it)('handles empty content with isError', () => {
138
+ (0, vitest_1.expect)((0, converter_js_1.formatToolResult)({ content: [], isError: true })).toBe('Error: Tool returned no content');
139
+ });
140
+ });
141
+ //# sourceMappingURL=converter.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"converter.test.js","sourceRoot":"","sources":["../../../src/__tests__/converter.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/index.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const index_js_1 = require("../index.js");
5
+ // We can't easily mock WorkspaceClient in the module, so test the factory structure
6
+ (0, vitest_1.describe)('createAerostackVercelAI', () => {
7
+ (0, vitest_1.it)('returns an object with tools() and workspaceClient', () => {
8
+ const client = (0, index_js_1.createAerostackVercelAI)({
9
+ workspace: 'test-ws',
10
+ token: 'mwt_test',
11
+ });
12
+ (0, vitest_1.expect)(client.tools).toBeTypeOf('function');
13
+ (0, vitest_1.expect)(client.workspaceClient).toBeDefined();
14
+ });
15
+ (0, vitest_1.it)('workspaceClient is configured with the correct slug', () => {
16
+ const client = (0, index_js_1.createAerostackVercelAI)({
17
+ workspace: 'my-ws',
18
+ token: 'mwt_abc',
19
+ baseUrl: 'https://custom.gateway.dev',
20
+ });
21
+ (0, vitest_1.expect)(client.workspaceClient).toBeDefined();
22
+ });
23
+ });
24
+ (0, vitest_1.describe)('getTools', () => {
25
+ (0, vitest_1.it)('is exported as a function', () => {
26
+ (0, vitest_1.expect)(index_js_1.getTools).toBeTypeOf('function');
27
+ });
28
+ });
29
+ //# sourceMappingURL=index.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../../../src/__tests__/index.test.ts"],"names":[],"mappings":";;AAAA,mCAAkD;AAClD,0CAAgE;AAEhE,oFAAoF;AACpF,IAAA,iBAAQ,EAAC,yBAAyB,EAAE,GAAG,EAAE;IACrC,IAAA,WAAE,EAAC,oDAAoD,EAAE,GAAG,EAAE;QAC1D,MAAM,MAAM,GAAG,IAAA,kCAAuB,EAAC;YACnC,SAAS,EAAE,SAAS;YACpB,KAAK,EAAE,UAAU;SACpB,CAAC,CAAC;QAEH,IAAA,eAAM,EAAC,MAAM,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QAC5C,IAAA,eAAM,EAAC,MAAM,CAAC,eAAe,CAAC,CAAC,WAAW,EAAE,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,qDAAqD,EAAE,GAAG,EAAE;QAC3D,MAAM,MAAM,GAAG,IAAA,kCAAuB,EAAC;YACnC,SAAS,EAAE,OAAO;YAClB,KAAK,EAAE,SAAS;YAChB,OAAO,EAAE,4BAA4B;SACxC,CAAC,CAAC;QAEH,IAAA,eAAM,EAAC,MAAM,CAAC,eAAe,CAAC,CAAC,WAAW,EAAE,CAAC;IACjD,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC;AAEH,IAAA,iBAAQ,EAAC,UAAU,EAAE,GAAG,EAAE;IACtB,IAAA,WAAE,EAAC,2BAA2B,EAAE,GAAG,EAAE;QACjC,IAAA,eAAM,EAAC,mBAAQ,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { ToolSet as VercelToolSet } from 'ai';
2
+ import { WorkspaceClient } from '@aerostack/core';
3
+ import type { McpTool, McpToolResult } from '@aerostack/core';
4
+ /**
5
+ * Convert McpTool array to Vercel AI SDK ToolSet.
6
+ *
7
+ * Each tool gets an `execute` function that proxies through WorkspaceClient.callTool().
8
+ * Tool names are used as-is (Vercel AI SDK has no name restrictions like OpenAI).
9
+ *
10
+ * @param mcpTools - Tools from WorkspaceClient.listTools()
11
+ * @param client - WorkspaceClient instance for executing tool calls
12
+ */
13
+ export declare function convertTools(mcpTools: McpTool[], client: WorkspaceClient): VercelToolSet;
14
+ /**
15
+ * Flatten McpToolResult content array into a single string.
16
+ */
17
+ export declare function formatToolResult(result: McpToolResult): string;
18
+ //# sourceMappingURL=converter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"converter.d.ts","sourceRoot":"","sources":["../../src/converter.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,IAAI,CAAC;AACnD,OAAO,EAAE,eAAe,EAAkB,MAAM,iBAAiB,CAAC;AAClE,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAE9D;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,eAAe,GAAG,aAAa,CA8BxF;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAkB9D"}
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.convertTools = convertTools;
4
+ exports.formatToolResult = formatToolResult;
5
+ /**
6
+ * Converts Aerostack McpTool definitions to Vercel AI SDK tool format.
7
+ */
8
+ const ai_1 = require("ai");
9
+ const core_1 = require("@aerostack/core");
10
+ /**
11
+ * Convert McpTool array to Vercel AI SDK ToolSet.
12
+ *
13
+ * Each tool gets an `execute` function that proxies through WorkspaceClient.callTool().
14
+ * Tool names are used as-is (Vercel AI SDK has no name restrictions like OpenAI).
15
+ *
16
+ * @param mcpTools - Tools from WorkspaceClient.listTools()
17
+ * @param client - WorkspaceClient instance for executing tool calls
18
+ */
19
+ function convertTools(mcpTools, client) {
20
+ const tools = {};
21
+ for (const mcpTool of mcpTools) {
22
+ if (!mcpTool.name)
23
+ continue;
24
+ const parameters = mcpTool.inputSchema
25
+ ? (0, ai_1.jsonSchema)(mcpTool.inputSchema)
26
+ : (0, ai_1.jsonSchema)({ type: 'object', properties: {} });
27
+ tools[mcpTool.name] = (0, ai_1.tool)({
28
+ description: mcpTool.description ?? '',
29
+ parameters,
30
+ execute: async (args) => {
31
+ try {
32
+ const result = await client.callTool(mcpTool.name, args);
33
+ return formatToolResult(result);
34
+ }
35
+ catch (err) {
36
+ if (err instanceof core_1.AerostackError) {
37
+ return `Error (${err.rpcCode}): ${err.message}`;
38
+ }
39
+ return err instanceof Error
40
+ ? `Error: ${err.message}`
41
+ : 'Error: Unknown error executing tool';
42
+ }
43
+ },
44
+ });
45
+ }
46
+ return tools;
47
+ }
48
+ /**
49
+ * Flatten McpToolResult content array into a single string.
50
+ */
51
+ function formatToolResult(result) {
52
+ if (!result.content || result.content.length === 0) {
53
+ return result.isError ? 'Error: Tool returned no content' : 'Success (no output)';
54
+ }
55
+ const parts = [];
56
+ for (const block of result.content) {
57
+ if (block.text) {
58
+ parts.push(block.text);
59
+ }
60
+ else if (block.data) {
61
+ parts.push(`[${block.mimeType ?? 'binary'} data: ${block.data.length} chars base64]`);
62
+ }
63
+ else {
64
+ parts.push(JSON.stringify(block));
65
+ }
66
+ }
67
+ const text = parts.join('\n');
68
+ return result.isError ? `Error: ${text}` : text;
69
+ }
70
+ //# sourceMappingURL=converter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"converter.js","sourceRoot":"","sources":["../../src/converter.ts"],"names":[],"mappings":";;AAiBA,oCA8BC;AAKD,4CAkBC;AAtED;;GAEG;AACH,2BAAsC;AAEtC,0CAAkE;AAGlE;;;;;;;;GAQG;AACH,SAAgB,YAAY,CAAC,QAAmB,EAAE,MAAuB;IACrE,MAAM,KAAK,GAAkB,EAAE,CAAC;IAEhC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC7B,IAAI,CAAC,OAAO,CAAC,IAAI;YAAE,SAAS;QAE5B,MAAM,UAAU,GAAG,OAAO,CAAC,WAAW;YAClC,CAAC,CAAC,IAAA,eAAU,EAAC,OAAO,CAAC,WAA+C,CAAC;YACrE,CAAC,CAAC,IAAA,eAAU,EAAC,EAAE,IAAI,EAAE,QAAiB,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;QAE9D,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,IAAA,SAAI,EAAC;YACvB,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,EAAE;YACtC,UAAU;YACV,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;gBACpB,IAAI,CAAC;oBACD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,IAA+B,CAAC,CAAC;oBACpF,OAAO,gBAAgB,CAAC,MAAM,CAAC,CAAC;gBACpC,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACX,IAAI,GAAG,YAAY,qBAAc,EAAE,CAAC;wBAChC,OAAO,UAAU,GAAG,CAAC,OAAO,MAAM,GAAG,CAAC,OAAO,EAAE,CAAC;oBACpD,CAAC;oBACD,OAAO,GAAG,YAAY,KAAK;wBACvB,CAAC,CAAC,UAAU,GAAG,CAAC,OAAO,EAAE;wBACzB,CAAC,CAAC,qCAAqC,CAAC;gBAChD,CAAC;YACL,CAAC;SACJ,CAAC,CAAC;IACP,CAAC;IAED,OAAO,KAAK,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,SAAgB,gBAAgB,CAAC,MAAqB;IAClD,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjD,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,iCAAiC,CAAC,CAAC,CAAC,qBAAqB,CAAC;IACtF,CAAC;IAED,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACjC,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;YACb,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;aAAM,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;YACpB,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,QAAQ,IAAI,QAAQ,UAAU,KAAK,CAAC,IAAI,CAAC,MAAM,gBAAgB,CAAC,CAAC;QAC1F,CAAC;aAAM,CAAC;YACJ,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;QACtC,CAAC;IACL,CAAC;IAED,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9B,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACpD,CAAC"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * @aerostack/sdk-vercel-ai — Use Aerostack workspace tools with the Vercel AI SDK.
3
+ *
4
+ * @example
5
+ * ```ts
6
+ * import { openai } from '@ai-sdk/openai';
7
+ * import { generateText } from 'ai';
8
+ * import { getTools } from '@aerostack/sdk-vercel-ai';
9
+ *
10
+ * const tools = await getTools({ workspace: 'my-workspace', token: 'mwt_...' });
11
+ *
12
+ * const { text } = await generateText({
13
+ * model: openai('gpt-4o'),
14
+ * tools,
15
+ * maxSteps: 5,
16
+ * prompt: 'Create a GitHub issue for the login bug',
17
+ * });
18
+ * ```
19
+ *
20
+ * @example Factory pattern
21
+ * ```ts
22
+ * const client = createAerostackVercelAI({ workspace: 'my-workspace', token: 'mwt_...' });
23
+ * const tools = await client.tools();
24
+ *
25
+ * const { text } = await streamText({
26
+ * model: anthropic('claude-sonnet-4-20250514'),
27
+ * tools,
28
+ * maxSteps: 10,
29
+ * prompt: 'Summarize the latest Notion pages and post to Slack',
30
+ * });
31
+ * ```
32
+ */
33
+ import type { ToolSet as VercelToolSet } from 'ai';
34
+ import { WorkspaceClient } from '@aerostack/core';
35
+ import type { McpTool } from '@aerostack/core';
36
+ export { formatToolResult } from './converter.js';
37
+ export interface WorkspaceConfig {
38
+ /** Workspace slug */
39
+ workspace: string;
40
+ /** Workspace token (mwt_...) */
41
+ token: string;
42
+ /** Override gateway base URL */
43
+ baseUrl?: string;
44
+ }
45
+ /** Result from getTools — includes both the Vercel AI tools and the raw MCP tools. */
46
+ export interface ToolSetResult {
47
+ /** Vercel AI SDK ToolSet — drop into generateText/streamText({ tools }) */
48
+ tools: VercelToolSet;
49
+ /** Raw MCP tools from the workspace for inspection */
50
+ raw: McpTool[];
51
+ }
52
+ /**
53
+ * Fetch tools from an Aerostack workspace and convert to Vercel AI SDK format.
54
+ *
55
+ * Each tool includes an `execute` function that calls the workspace gateway,
56
+ * so you just pass the tools to `generateText` / `streamText` and it works.
57
+ */
58
+ export declare function getTools(config: WorkspaceConfig): Promise<ToolSetResult>;
59
+ export interface AerostackVercelAIClient {
60
+ /** Fetch and convert workspace tools to Vercel AI SDK format. */
61
+ tools(): Promise<ToolSetResult>;
62
+ /** Access the underlying WorkspaceClient for advanced use. */
63
+ readonly workspaceClient: WorkspaceClient;
64
+ }
65
+ /**
66
+ * Create a reusable Aerostack Vercel AI client.
67
+ *
68
+ * Reuses a single WorkspaceClient instance across tool calls.
69
+ */
70
+ export declare function createAerostackVercelAI(config: WorkspaceConfig): AerostackVercelAIClient;
71
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,KAAK,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,IAAI,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAG/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,MAAM,WAAW,eAAe;IAC5B,qBAAqB;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,gCAAgC;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,sFAAsF;AACtF,MAAM,WAAW,aAAa;IAC1B,2EAA2E;IAC3E,KAAK,EAAE,aAAa,CAAC;IACrB,sDAAsD;IACtD,GAAG,EAAE,OAAO,EAAE,CAAC;CAClB;AAcD;;;;;GAKG;AACH,wBAAsB,QAAQ,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,aAAa,CAAC,CAK9E;AAMD,MAAM,WAAW,uBAAuB;IACpC,iEAAiE;IACjE,KAAK,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC;IAChC,8DAA8D;IAC9D,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;CAC7C;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,eAAe,GAAG,uBAAuB,CAcxF"}
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ /**
3
+ * @aerostack/sdk-vercel-ai — Use Aerostack workspace tools with the Vercel AI SDK.
4
+ *
5
+ * @example
6
+ * ```ts
7
+ * import { openai } from '@ai-sdk/openai';
8
+ * import { generateText } from 'ai';
9
+ * import { getTools } from '@aerostack/sdk-vercel-ai';
10
+ *
11
+ * const tools = await getTools({ workspace: 'my-workspace', token: 'mwt_...' });
12
+ *
13
+ * const { text } = await generateText({
14
+ * model: openai('gpt-4o'),
15
+ * tools,
16
+ * maxSteps: 5,
17
+ * prompt: 'Create a GitHub issue for the login bug',
18
+ * });
19
+ * ```
20
+ *
21
+ * @example Factory pattern
22
+ * ```ts
23
+ * const client = createAerostackVercelAI({ workspace: 'my-workspace', token: 'mwt_...' });
24
+ * const tools = await client.tools();
25
+ *
26
+ * const { text } = await streamText({
27
+ * model: anthropic('claude-sonnet-4-20250514'),
28
+ * tools,
29
+ * maxSteps: 10,
30
+ * prompt: 'Summarize the latest Notion pages and post to Slack',
31
+ * });
32
+ * ```
33
+ */
34
+ Object.defineProperty(exports, "__esModule", { value: true });
35
+ exports.formatToolResult = void 0;
36
+ exports.getTools = getTools;
37
+ exports.createAerostackVercelAI = createAerostackVercelAI;
38
+ const core_1 = require("@aerostack/core");
39
+ const converter_js_1 = require("./converter.js");
40
+ var converter_js_2 = require("./converter.js");
41
+ Object.defineProperty(exports, "formatToolResult", { enumerable: true, get: function () { return converter_js_2.formatToolResult; } });
42
+ function createWorkspaceClient(config) {
43
+ return new core_1.WorkspaceClient({
44
+ slug: config.workspace,
45
+ token: config.token,
46
+ baseUrl: config.baseUrl,
47
+ });
48
+ }
49
+ // ---------------------------------------------------------------------------
50
+ // Standalone function
51
+ // ---------------------------------------------------------------------------
52
+ /**
53
+ * Fetch tools from an Aerostack workspace and convert to Vercel AI SDK format.
54
+ *
55
+ * Each tool includes an `execute` function that calls the workspace gateway,
56
+ * so you just pass the tools to `generateText` / `streamText` and it works.
57
+ */
58
+ async function getTools(config) {
59
+ const client = createWorkspaceClient(config);
60
+ const raw = await client.listTools();
61
+ const tools = (0, converter_js_1.convertTools)(raw, client);
62
+ return { tools, raw };
63
+ }
64
+ /**
65
+ * Create a reusable Aerostack Vercel AI client.
66
+ *
67
+ * Reuses a single WorkspaceClient instance across tool calls.
68
+ */
69
+ function createAerostackVercelAI(config) {
70
+ const wsClient = createWorkspaceClient(config);
71
+ return {
72
+ async tools() {
73
+ const raw = await wsClient.listTools();
74
+ const tools = (0, converter_js_1.convertTools)(raw, wsClient);
75
+ return { tools, raw };
76
+ },
77
+ get workspaceClient() {
78
+ return wsClient;
79
+ },
80
+ };
81
+ }
82
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;;;AA4CH,4BAKC;AAkBD,0DAcC;AA9ED,0CAAkD;AAElD,iDAA8C;AAE9C,+CAAkD;AAAzC,gHAAA,gBAAgB,OAAA;AAmBzB,SAAS,qBAAqB,CAAC,MAAuB;IAClD,OAAO,IAAI,sBAAe,CAAC;QACvB,IAAI,EAAE,MAAM,CAAC,SAAS;QACtB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,OAAO,EAAE,MAAM,CAAC,OAAO;KAC1B,CAAC,CAAC;AACP,CAAC;AAED,8EAA8E;AAC9E,sBAAsB;AACtB,8EAA8E;AAE9E;;;;;GAKG;AACI,KAAK,UAAU,QAAQ,CAAC,MAAuB;IAClD,MAAM,MAAM,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC7C,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,SAAS,EAAE,CAAC;IACrC,MAAM,KAAK,GAAG,IAAA,2BAAY,EAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACxC,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;AAC1B,CAAC;AAaD;;;;GAIG;AACH,SAAgB,uBAAuB,CAAC,MAAuB;IAC3D,MAAM,QAAQ,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAE/C,OAAO;QACH,KAAK,CAAC,KAAK;YACP,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,SAAS,EAAE,CAAC;YACvC,MAAM,KAAK,GAAG,IAAA,2BAAY,EAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;YAC1C,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;QAC1B,CAAC;QAED,IAAI,eAAe;YACf,OAAO,QAAQ,CAAC;QACpB,CAAC;KACJ,CAAC;AACN,CAAC"}
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "commonjs"
3
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=converter.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"converter.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/converter.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,139 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+ import { convertTools, formatToolResult } from '../converter.js';
3
+ function mockClient(callToolResult, shouldThrow = false) {
4
+ return {
5
+ callTool: shouldThrow
6
+ ? vi.fn().mockRejectedValue(callToolResult)
7
+ : vi.fn().mockResolvedValue(callToolResult),
8
+ };
9
+ }
10
+ describe('convertTools', () => {
11
+ it('converts MCP tools to Vercel AI SDK ToolSet', () => {
12
+ const mcpTools = [
13
+ {
14
+ name: 'github__create_issue',
15
+ description: 'Create a GitHub issue',
16
+ inputSchema: {
17
+ type: 'object',
18
+ properties: { title: { type: 'string' } },
19
+ required: ['title'],
20
+ },
21
+ },
22
+ {
23
+ name: 'slack__post_message',
24
+ description: 'Post to Slack',
25
+ inputSchema: {
26
+ type: 'object',
27
+ properties: { channel: { type: 'string' }, text: { type: 'string' } },
28
+ },
29
+ },
30
+ ];
31
+ const client = mockClient({});
32
+ const tools = convertTools(mcpTools, client);
33
+ expect(Object.keys(tools)).toEqual(['github__create_issue', 'slack__post_message']);
34
+ expect(tools['github__create_issue']).toBeDefined();
35
+ expect(tools['slack__post_message']).toBeDefined();
36
+ });
37
+ it('handles tools with no inputSchema', () => {
38
+ const mcpTools = [
39
+ { name: 'ping', description: 'Ping the server' },
40
+ ];
41
+ const client = mockClient({});
42
+ const tools = convertTools(mcpTools, client);
43
+ expect(tools['ping']).toBeDefined();
44
+ });
45
+ it('handles tools with no description', () => {
46
+ const mcpTools = [
47
+ { name: 'my_tool', inputSchema: { type: 'object', properties: {} } },
48
+ ];
49
+ const client = mockClient({});
50
+ const tools = convertTools(mcpTools, client);
51
+ expect(tools['my_tool']).toBeDefined();
52
+ });
53
+ it('skips tools with empty names', () => {
54
+ const mcpTools = [
55
+ { name: '', description: 'Bad tool' },
56
+ { name: 'good_tool', description: 'Good tool' },
57
+ ];
58
+ const client = mockClient({});
59
+ const tools = convertTools(mcpTools, client);
60
+ expect(Object.keys(tools)).toEqual(['good_tool']);
61
+ });
62
+ it('handles empty tools array', () => {
63
+ const client = mockClient({});
64
+ const tools = convertTools([], client);
65
+ expect(Object.keys(tools)).toEqual([]);
66
+ });
67
+ it('execute function calls WorkspaceClient.callTool', async () => {
68
+ const mcpTools = [
69
+ {
70
+ name: 'test_tool',
71
+ description: 'Test',
72
+ inputSchema: { type: 'object', properties: { x: { type: 'number' } } },
73
+ },
74
+ ];
75
+ const client = mockClient({
76
+ content: [{ type: 'text', text: 'result123' }],
77
+ });
78
+ const tools = convertTools(mcpTools, client);
79
+ const result = await tools['test_tool'].execute({ x: 42 }, { toolCallId: 'tc_1', messages: [], abortSignal: new AbortController().signal });
80
+ expect(client.callTool).toHaveBeenCalledWith('test_tool', { x: 42 });
81
+ expect(result).toBe('result123');
82
+ });
83
+ it('execute function handles AerostackError gracefully', async () => {
84
+ const { AerostackError } = await import('@aerostack/core');
85
+ const err = new AerostackError('Server down', 503, -32603, 'req-1');
86
+ const client = mockClient(err, true);
87
+ const mcpTools = [
88
+ { name: 'failing_tool', description: 'Fails' },
89
+ ];
90
+ const tools = convertTools(mcpTools, client);
91
+ const result = await tools['failing_tool'].execute({}, { toolCallId: 'tc_1', messages: [], abortSignal: new AbortController().signal });
92
+ expect(result).toContain('Error (-32603)');
93
+ expect(result).toContain('Server down');
94
+ });
95
+ it('execute function handles generic errors', async () => {
96
+ const client = mockClient(new Error('Network timeout'), true);
97
+ const mcpTools = [
98
+ { name: 'timeout_tool', description: 'Timeouts' },
99
+ ];
100
+ const tools = convertTools(mcpTools, client);
101
+ const result = await tools['timeout_tool'].execute({}, { toolCallId: 'tc_1', messages: [], abortSignal: new AbortController().signal });
102
+ expect(result).toBe('Error: Network timeout');
103
+ });
104
+ });
105
+ describe('formatToolResult', () => {
106
+ it('formats single text content', () => {
107
+ expect(formatToolResult({
108
+ content: [{ type: 'text', text: 'Hello' }],
109
+ })).toBe('Hello');
110
+ });
111
+ it('concatenates multiple text blocks', () => {
112
+ expect(formatToolResult({
113
+ content: [
114
+ { type: 'text', text: 'Line 1' },
115
+ { type: 'text', text: 'Line 2' },
116
+ ],
117
+ })).toBe('Line 1\nLine 2');
118
+ });
119
+ it('handles binary data blocks', () => {
120
+ const result = formatToolResult({
121
+ content: [{ type: 'image', data: 'abc123', mimeType: 'image/png' }],
122
+ });
123
+ expect(result).toContain('image/png');
124
+ });
125
+ it('prefixes error results', () => {
126
+ expect(formatToolResult({
127
+ content: [{ type: 'text', text: 'Something failed' }],
128
+ isError: true,
129
+ })).toBe('Error: Something failed');
130
+ });
131
+ it('handles empty content', () => {
132
+ expect(formatToolResult({ content: [] })).toBe('Success (no output)');
133
+ expect(formatToolResult({})).toBe('Success (no output)');
134
+ });
135
+ it('handles empty content with isError', () => {
136
+ expect(formatToolResult({ content: [], isError: true })).toBe('Error: Tool returned no content');
137
+ });
138
+ });
139
+ //# sourceMappingURL=converter.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"converter.test.js","sourceRoot":"","sources":["../../../src/__tests__/converter.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAIjE,SAAS,UAAU,CAAC,cAAuB,EAAE,WAAW,GAAG,KAAK;IAC5D,OAAO;QACH,QAAQ,EAAE,WAAW;YACjB,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,cAAc,CAAC;YAC3C,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,cAAc,CAAC;KACpB,CAAC;AACpC,CAAC;AAED,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC1B,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACnD,MAAM,QAAQ,GAAc;YACxB;gBACI,IAAI,EAAE,sBAAsB;gBAC5B,WAAW,EAAE,uBAAuB;gBACpC,WAAW,EAAE;oBACT,IAAI,EAAE,QAAQ;oBACd,UAAU,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;oBACzC,QAAQ,EAAE,CAAC,OAAO,CAAC;iBACtB;aACJ;YACD;gBACI,IAAI,EAAE,qBAAqB;gBAC3B,WAAW,EAAE,eAAe;gBAC5B,WAAW,EAAE;oBACT,IAAI,EAAE,QAAQ;oBACd,UAAU,EAAE,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;iBACxE;aACJ;SACJ,CAAC;QAEF,MAAM,MAAM,GAAG,UAAU,CAAC,EAAE,CAAC,CAAC;QAC9B,MAAM,KAAK,GAAG,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAE7C,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,sBAAsB,EAAE,qBAAqB,CAAC,CAAC,CAAC;QACpF,MAAM,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QACpD,MAAM,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IACvD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QACzC,MAAM,QAAQ,GAAc;YACxB,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,iBAAiB,EAAE;SACnD,CAAC;QAEF,MAAM,MAAM,GAAG,UAAU,CAAC,EAAE,CAAC,CAAC;QAC9B,MAAM,KAAK,GAAG,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAE7C,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QACzC,MAAM,QAAQ,GAAc;YACxB,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE,EAAE;SACvE,CAAC;QAEF,MAAM,MAAM,GAAG,UAAU,CAAC,EAAE,CAAC,CAAC;QAC9B,MAAM,KAAK,GAAG,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAE7C,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;QACpC,MAAM,QAAQ,GAAc;YACxB,EAAE,IAAI,EAAE,EAAE,EAAE,WAAW,EAAE,UAAU,EAAE;YACrC,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE;SAClD,CAAC;QAEF,MAAM,MAAM,GAAG,UAAU,CAAC,EAAE,CAAC,CAAC;QAC9B,MAAM,KAAK,GAAG,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAE7C,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACjC,MAAM,MAAM,GAAG,UAAU,CAAC,EAAE,CAAC,CAAC;QAC9B,MAAM,KAAK,GAAG,YAAY,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QACvC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;QAC7D,MAAM,QAAQ,GAAc;YACxB;gBACI,IAAI,EAAE,WAAW;gBACjB,WAAW,EAAE,MAAM;gBACnB,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE;aACzE;SACJ,CAAC;QAEF,MAAM,MAAM,GAAG,UAAU,CAAC;YACtB,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;SACjD,CAAC,CAAC;QACH,MAAM,KAAK,GAAG,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAE7C,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,WAAW,CAAE,CAAC,OAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,eAAe,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;QAE9I,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,oBAAoB,CAAC,WAAW,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QACrE,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,KAAK,IAAI,EAAE;QAChE,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAC;QAC3D,MAAM,GAAG,GAAG,IAAI,cAAc,CAAC,aAAa,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACpE,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAErC,MAAM,QAAQ,GAAc;YACxB,EAAE,IAAI,EAAE,cAAc,EAAE,WAAW,EAAE,OAAO,EAAE;SACjD,CAAC;QAEF,MAAM,KAAK,GAAG,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC7C,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,cAAc,CAAE,CAAC,OAAQ,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,eAAe,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;QAE1I,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;QAC3C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;QACrD,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,KAAK,CAAC,iBAAiB,CAAC,EAAE,IAAI,CAAC,CAAC;QAE9D,MAAM,QAAQ,GAAc;YACxB,EAAE,IAAI,EAAE,cAAc,EAAE,WAAW,EAAE,UAAU,EAAE;SACpD,CAAC;QAEF,MAAM,KAAK,GAAG,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC7C,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,cAAc,CAAE,CAAC,OAAQ,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,eAAe,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;QAE1I,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAC9B,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACnC,MAAM,CAAC,gBAAgB,CAAC;YACpB,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;SAC7C,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACtB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QACzC,MAAM,CAAC,gBAAgB,CAAC;YACpB,OAAO,EAAE;gBACL,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE;gBAChC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE;aACnC;SACJ,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;QAClC,MAAM,MAAM,GAAG,gBAAgB,CAAC;YAC5B,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;SACtE,CAAC,CAAC;QACH,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wBAAwB,EAAE,GAAG,EAAE;QAC9B,MAAM,CAAC,gBAAgB,CAAC;YACpB,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC;YACrD,OAAO,EAAE,IAAI;SAChB,CAAC,CAAC,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uBAAuB,EAAE,GAAG,EAAE;QAC7B,MAAM,CAAC,gBAAgB,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;QACtE,MAAM,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC1C,MAAM,CAAC,gBAAgB,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;IACrG,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/index.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,27 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { getTools, createAerostackVercelAI } from '../index.js';
3
+ // We can't easily mock WorkspaceClient in the module, so test the factory structure
4
+ describe('createAerostackVercelAI', () => {
5
+ it('returns an object with tools() and workspaceClient', () => {
6
+ const client = createAerostackVercelAI({
7
+ workspace: 'test-ws',
8
+ token: 'mwt_test',
9
+ });
10
+ expect(client.tools).toBeTypeOf('function');
11
+ expect(client.workspaceClient).toBeDefined();
12
+ });
13
+ it('workspaceClient is configured with the correct slug', () => {
14
+ const client = createAerostackVercelAI({
15
+ workspace: 'my-ws',
16
+ token: 'mwt_abc',
17
+ baseUrl: 'https://custom.gateway.dev',
18
+ });
19
+ expect(client.workspaceClient).toBeDefined();
20
+ });
21
+ });
22
+ describe('getTools', () => {
23
+ it('is exported as a function', () => {
24
+ expect(getTools).toBeTypeOf('function');
25
+ });
26
+ });
27
+ //# sourceMappingURL=index.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../../../src/__tests__/index.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAM,MAAM,QAAQ,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAEhE,oFAAoF;AACpF,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;IACrC,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC1D,MAAM,MAAM,GAAG,uBAAuB,CAAC;YACnC,SAAS,EAAE,SAAS;YACpB,KAAK,EAAE,UAAU;SACpB,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,WAAW,EAAE,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC3D,MAAM,MAAM,GAAG,uBAAuB,CAAC;YACnC,SAAS,EAAE,OAAO;YAClB,KAAK,EAAE,SAAS;YAChB,OAAO,EAAE,4BAA4B;SACxC,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,WAAW,EAAE,CAAC;IACjD,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,UAAU,EAAE,GAAG,EAAE;IACtB,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACjC,MAAM,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { ToolSet as VercelToolSet } from 'ai';
2
+ import { WorkspaceClient } from '@aerostack/core';
3
+ import type { McpTool, McpToolResult } from '@aerostack/core';
4
+ /**
5
+ * Convert McpTool array to Vercel AI SDK ToolSet.
6
+ *
7
+ * Each tool gets an `execute` function that proxies through WorkspaceClient.callTool().
8
+ * Tool names are used as-is (Vercel AI SDK has no name restrictions like OpenAI).
9
+ *
10
+ * @param mcpTools - Tools from WorkspaceClient.listTools()
11
+ * @param client - WorkspaceClient instance for executing tool calls
12
+ */
13
+ export declare function convertTools(mcpTools: McpTool[], client: WorkspaceClient): VercelToolSet;
14
+ /**
15
+ * Flatten McpToolResult content array into a single string.
16
+ */
17
+ export declare function formatToolResult(result: McpToolResult): string;
18
+ //# sourceMappingURL=converter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"converter.d.ts","sourceRoot":"","sources":["../../src/converter.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,IAAI,CAAC;AACnD,OAAO,EAAE,eAAe,EAAkB,MAAM,iBAAiB,CAAC;AAClE,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAE9D;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,eAAe,GAAG,aAAa,CA8BxF;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAkB9D"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Converts Aerostack McpTool definitions to Vercel AI SDK tool format.
3
+ */
4
+ import { tool, jsonSchema } from 'ai';
5
+ import { AerostackError } from '@aerostack/core';
6
+ /**
7
+ * Convert McpTool array to Vercel AI SDK ToolSet.
8
+ *
9
+ * Each tool gets an `execute` function that proxies through WorkspaceClient.callTool().
10
+ * Tool names are used as-is (Vercel AI SDK has no name restrictions like OpenAI).
11
+ *
12
+ * @param mcpTools - Tools from WorkspaceClient.listTools()
13
+ * @param client - WorkspaceClient instance for executing tool calls
14
+ */
15
+ export function convertTools(mcpTools, client) {
16
+ const tools = {};
17
+ for (const mcpTool of mcpTools) {
18
+ if (!mcpTool.name)
19
+ continue;
20
+ const parameters = mcpTool.inputSchema
21
+ ? jsonSchema(mcpTool.inputSchema)
22
+ : jsonSchema({ type: 'object', properties: {} });
23
+ tools[mcpTool.name] = tool({
24
+ description: mcpTool.description ?? '',
25
+ parameters,
26
+ execute: async (args) => {
27
+ try {
28
+ const result = await client.callTool(mcpTool.name, args);
29
+ return formatToolResult(result);
30
+ }
31
+ catch (err) {
32
+ if (err instanceof AerostackError) {
33
+ return `Error (${err.rpcCode}): ${err.message}`;
34
+ }
35
+ return err instanceof Error
36
+ ? `Error: ${err.message}`
37
+ : 'Error: Unknown error executing tool';
38
+ }
39
+ },
40
+ });
41
+ }
42
+ return tools;
43
+ }
44
+ /**
45
+ * Flatten McpToolResult content array into a single string.
46
+ */
47
+ export function formatToolResult(result) {
48
+ if (!result.content || result.content.length === 0) {
49
+ return result.isError ? 'Error: Tool returned no content' : 'Success (no output)';
50
+ }
51
+ const parts = [];
52
+ for (const block of result.content) {
53
+ if (block.text) {
54
+ parts.push(block.text);
55
+ }
56
+ else if (block.data) {
57
+ parts.push(`[${block.mimeType ?? 'binary'} data: ${block.data.length} chars base64]`);
58
+ }
59
+ else {
60
+ parts.push(JSON.stringify(block));
61
+ }
62
+ }
63
+ const text = parts.join('\n');
64
+ return result.isError ? `Error: ${text}` : text;
65
+ }
66
+ //# sourceMappingURL=converter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"converter.js","sourceRoot":"","sources":["../../src/converter.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAEtC,OAAO,EAAmB,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGlE;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY,CAAC,QAAmB,EAAE,MAAuB;IACrE,MAAM,KAAK,GAAkB,EAAE,CAAC;IAEhC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC7B,IAAI,CAAC,OAAO,CAAC,IAAI;YAAE,SAAS;QAE5B,MAAM,UAAU,GAAG,OAAO,CAAC,WAAW;YAClC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,WAA+C,CAAC;YACrE,CAAC,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,QAAiB,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;QAE9D,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;YACvB,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,EAAE;YACtC,UAAU;YACV,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;gBACpB,IAAI,CAAC;oBACD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,IAA+B,CAAC,CAAC;oBACpF,OAAO,gBAAgB,CAAC,MAAM,CAAC,CAAC;gBACpC,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACX,IAAI,GAAG,YAAY,cAAc,EAAE,CAAC;wBAChC,OAAO,UAAU,GAAG,CAAC,OAAO,MAAM,GAAG,CAAC,OAAO,EAAE,CAAC;oBACpD,CAAC;oBACD,OAAO,GAAG,YAAY,KAAK;wBACvB,CAAC,CAAC,UAAU,GAAG,CAAC,OAAO,EAAE;wBACzB,CAAC,CAAC,qCAAqC,CAAC;gBAChD,CAAC;YACL,CAAC;SACJ,CAAC,CAAC;IACP,CAAC;IAED,OAAO,KAAK,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAqB;IAClD,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjD,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,iCAAiC,CAAC,CAAC,CAAC,qBAAqB,CAAC;IACtF,CAAC;IAED,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACjC,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;YACb,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;aAAM,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;YACpB,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,QAAQ,IAAI,QAAQ,UAAU,KAAK,CAAC,IAAI,CAAC,MAAM,gBAAgB,CAAC,CAAC;QAC1F,CAAC;aAAM,CAAC;YACJ,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;QACtC,CAAC;IACL,CAAC;IAED,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9B,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACpD,CAAC"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * @aerostack/sdk-vercel-ai — Use Aerostack workspace tools with the Vercel AI SDK.
3
+ *
4
+ * @example
5
+ * ```ts
6
+ * import { openai } from '@ai-sdk/openai';
7
+ * import { generateText } from 'ai';
8
+ * import { getTools } from '@aerostack/sdk-vercel-ai';
9
+ *
10
+ * const tools = await getTools({ workspace: 'my-workspace', token: 'mwt_...' });
11
+ *
12
+ * const { text } = await generateText({
13
+ * model: openai('gpt-4o'),
14
+ * tools,
15
+ * maxSteps: 5,
16
+ * prompt: 'Create a GitHub issue for the login bug',
17
+ * });
18
+ * ```
19
+ *
20
+ * @example Factory pattern
21
+ * ```ts
22
+ * const client = createAerostackVercelAI({ workspace: 'my-workspace', token: 'mwt_...' });
23
+ * const tools = await client.tools();
24
+ *
25
+ * const { text } = await streamText({
26
+ * model: anthropic('claude-sonnet-4-20250514'),
27
+ * tools,
28
+ * maxSteps: 10,
29
+ * prompt: 'Summarize the latest Notion pages and post to Slack',
30
+ * });
31
+ * ```
32
+ */
33
+ import type { ToolSet as VercelToolSet } from 'ai';
34
+ import { WorkspaceClient } from '@aerostack/core';
35
+ import type { McpTool } from '@aerostack/core';
36
+ export { formatToolResult } from './converter.js';
37
+ export interface WorkspaceConfig {
38
+ /** Workspace slug */
39
+ workspace: string;
40
+ /** Workspace token (mwt_...) */
41
+ token: string;
42
+ /** Override gateway base URL */
43
+ baseUrl?: string;
44
+ }
45
+ /** Result from getTools — includes both the Vercel AI tools and the raw MCP tools. */
46
+ export interface ToolSetResult {
47
+ /** Vercel AI SDK ToolSet — drop into generateText/streamText({ tools }) */
48
+ tools: VercelToolSet;
49
+ /** Raw MCP tools from the workspace for inspection */
50
+ raw: McpTool[];
51
+ }
52
+ /**
53
+ * Fetch tools from an Aerostack workspace and convert to Vercel AI SDK format.
54
+ *
55
+ * Each tool includes an `execute` function that calls the workspace gateway,
56
+ * so you just pass the tools to `generateText` / `streamText` and it works.
57
+ */
58
+ export declare function getTools(config: WorkspaceConfig): Promise<ToolSetResult>;
59
+ export interface AerostackVercelAIClient {
60
+ /** Fetch and convert workspace tools to Vercel AI SDK format. */
61
+ tools(): Promise<ToolSetResult>;
62
+ /** Access the underlying WorkspaceClient for advanced use. */
63
+ readonly workspaceClient: WorkspaceClient;
64
+ }
65
+ /**
66
+ * Create a reusable Aerostack Vercel AI client.
67
+ *
68
+ * Reuses a single WorkspaceClient instance across tool calls.
69
+ */
70
+ export declare function createAerostackVercelAI(config: WorkspaceConfig): AerostackVercelAIClient;
71
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,KAAK,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,IAAI,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAG/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,MAAM,WAAW,eAAe;IAC5B,qBAAqB;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,gCAAgC;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,sFAAsF;AACtF,MAAM,WAAW,aAAa;IAC1B,2EAA2E;IAC3E,KAAK,EAAE,aAAa,CAAC;IACrB,sDAAsD;IACtD,GAAG,EAAE,OAAO,EAAE,CAAC;CAClB;AAcD;;;;;GAKG;AACH,wBAAsB,QAAQ,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,aAAa,CAAC,CAK9E;AAMD,MAAM,WAAW,uBAAuB;IACpC,iEAAiE;IACjE,KAAK,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC;IAChC,8DAA8D;IAC9D,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;CAC7C;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,eAAe,GAAG,uBAAuB,CAcxF"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * @aerostack/sdk-vercel-ai — Use Aerostack workspace tools with the Vercel AI SDK.
3
+ *
4
+ * @example
5
+ * ```ts
6
+ * import { openai } from '@ai-sdk/openai';
7
+ * import { generateText } from 'ai';
8
+ * import { getTools } from '@aerostack/sdk-vercel-ai';
9
+ *
10
+ * const tools = await getTools({ workspace: 'my-workspace', token: 'mwt_...' });
11
+ *
12
+ * const { text } = await generateText({
13
+ * model: openai('gpt-4o'),
14
+ * tools,
15
+ * maxSteps: 5,
16
+ * prompt: 'Create a GitHub issue for the login bug',
17
+ * });
18
+ * ```
19
+ *
20
+ * @example Factory pattern
21
+ * ```ts
22
+ * const client = createAerostackVercelAI({ workspace: 'my-workspace', token: 'mwt_...' });
23
+ * const tools = await client.tools();
24
+ *
25
+ * const { text } = await streamText({
26
+ * model: anthropic('claude-sonnet-4-20250514'),
27
+ * tools,
28
+ * maxSteps: 10,
29
+ * prompt: 'Summarize the latest Notion pages and post to Slack',
30
+ * });
31
+ * ```
32
+ */
33
+ import { WorkspaceClient } from '@aerostack/core';
34
+ import { convertTools } from './converter.js';
35
+ export { formatToolResult } from './converter.js';
36
+ function createWorkspaceClient(config) {
37
+ return new WorkspaceClient({
38
+ slug: config.workspace,
39
+ token: config.token,
40
+ baseUrl: config.baseUrl,
41
+ });
42
+ }
43
+ // ---------------------------------------------------------------------------
44
+ // Standalone function
45
+ // ---------------------------------------------------------------------------
46
+ /**
47
+ * Fetch tools from an Aerostack workspace and convert to Vercel AI SDK format.
48
+ *
49
+ * Each tool includes an `execute` function that calls the workspace gateway,
50
+ * so you just pass the tools to `generateText` / `streamText` and it works.
51
+ */
52
+ export async function getTools(config) {
53
+ const client = createWorkspaceClient(config);
54
+ const raw = await client.listTools();
55
+ const tools = convertTools(raw, client);
56
+ return { tools, raw };
57
+ }
58
+ /**
59
+ * Create a reusable Aerostack Vercel AI client.
60
+ *
61
+ * Reuses a single WorkspaceClient instance across tool calls.
62
+ */
63
+ export function createAerostackVercelAI(config) {
64
+ const wsClient = createWorkspaceClient(config);
65
+ return {
66
+ async tools() {
67
+ const raw = await wsClient.listTools();
68
+ const tools = convertTools(raw, wsClient);
69
+ return { tools, raw };
70
+ },
71
+ get workspaceClient() {
72
+ return wsClient;
73
+ },
74
+ };
75
+ }
76
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAGH,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAmBlD,SAAS,qBAAqB,CAAC,MAAuB;IAClD,OAAO,IAAI,eAAe,CAAC;QACvB,IAAI,EAAE,MAAM,CAAC,SAAS;QACtB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,OAAO,EAAE,MAAM,CAAC,OAAO;KAC1B,CAAC,CAAC;AACP,CAAC;AAED,8EAA8E;AAC9E,sBAAsB;AACtB,8EAA8E;AAE9E;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,MAAuB;IAClD,MAAM,MAAM,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC7C,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,SAAS,EAAE,CAAC;IACrC,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACxC,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;AAC1B,CAAC;AAaD;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,MAAuB;IAC3D,MAAM,QAAQ,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAE/C,OAAO;QACH,KAAK,CAAC,KAAK;YACP,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,SAAS,EAAE,CAAC;YACvC,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;YAC1C,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;QAC1B,CAAC;QAED,IAAI,eAAe;YACf,OAAO,QAAQ,CAAC;QACpB,CAAC;KACJ,CAAC;AACN,CAAC"}
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "module"
3
+ }
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "@aerostack/sdk-vercel-ai",
3
+ "version": "0.10.1",
4
+ "description": "Use Aerostack workspace tools with the Vercel AI SDK",
5
+ "author": "Aerostack",
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "tshy": {
9
+ "sourceDialects": [
10
+ "@aerostack/sdk-vercel-ai/source"
11
+ ],
12
+ "exports": {
13
+ ".": "./src/index.ts",
14
+ "./package.json": "./package.json"
15
+ }
16
+ },
17
+ "sideEffects": false,
18
+ "scripts": {
19
+ "lint": "eslint --cache --max-warnings=0 src",
20
+ "build": "tshy",
21
+ "test": "vitest run",
22
+ "prepublishOnly": "npm run build"
23
+ },
24
+ "dependencies": {
25
+ "@aerostack/core": "^0.10.1"
26
+ },
27
+ "peerDependencies": {
28
+ "ai": "^3.0.0 || ^4.0.0"
29
+ },
30
+ "peerDependenciesMeta": {
31
+ "ai": {
32
+ "optional": false
33
+ }
34
+ },
35
+ "devDependencies": {
36
+ "ai": "^4.3.0",
37
+ "tshy": "^2.0.0",
38
+ "typescript": "~5.8.3",
39
+ "vitest": "^3.2.1",
40
+ "zod": "^3.25.0"
41
+ },
42
+ "exports": {
43
+ ".": {
44
+ "import": {
45
+ "@aerostack/sdk-vercel-ai/source": "./src/index.ts",
46
+ "types": "./dist/esm/index.d.ts",
47
+ "default": "./dist/esm/index.js"
48
+ },
49
+ "require": {
50
+ "types": "./dist/commonjs/index.d.ts",
51
+ "default": "./dist/commonjs/index.js"
52
+ }
53
+ },
54
+ "./package.json": "./package.json"
55
+ },
56
+ "main": "./dist/commonjs/index.js",
57
+ "types": "./dist/commonjs/index.d.ts",
58
+ "module": "./dist/esm/index.js",
59
+ "files": [
60
+ "dist",
61
+ "README.md"
62
+ ],
63
+ "publishConfig": {
64
+ "access": "public"
65
+ }
66
+ }