@aerostack/sdk-openai 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 (44) hide show
  1. package/README.md +73 -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 +149 -0
  5. package/dist/commonjs/__tests__/converter.test.js.map +1 -0
  6. package/dist/commonjs/__tests__/executor.test.d.ts +2 -0
  7. package/dist/commonjs/__tests__/executor.test.d.ts.map +1 -0
  8. package/dist/commonjs/__tests__/executor.test.js +141 -0
  9. package/dist/commonjs/__tests__/executor.test.js.map +1 -0
  10. package/dist/commonjs/converter.d.ts +35 -0
  11. package/dist/commonjs/converter.d.ts.map +1 -0
  12. package/dist/commonjs/converter.js +89 -0
  13. package/dist/commonjs/converter.js.map +1 -0
  14. package/dist/commonjs/executor.d.ts +40 -0
  15. package/dist/commonjs/executor.d.ts.map +1 -0
  16. package/dist/commonjs/executor.js +84 -0
  17. package/dist/commonjs/executor.js.map +1 -0
  18. package/dist/commonjs/index.d.ts +88 -0
  19. package/dist/commonjs/index.d.ts.map +1 -0
  20. package/dist/commonjs/index.js +132 -0
  21. package/dist/commonjs/index.js.map +1 -0
  22. package/dist/commonjs/package.json +3 -0
  23. package/dist/esm/__tests__/converter.test.d.ts +2 -0
  24. package/dist/esm/__tests__/converter.test.d.ts.map +1 -0
  25. package/dist/esm/__tests__/converter.test.js +147 -0
  26. package/dist/esm/__tests__/converter.test.js.map +1 -0
  27. package/dist/esm/__tests__/executor.test.d.ts +2 -0
  28. package/dist/esm/__tests__/executor.test.d.ts.map +1 -0
  29. package/dist/esm/__tests__/executor.test.js +139 -0
  30. package/dist/esm/__tests__/executor.test.js.map +1 -0
  31. package/dist/esm/converter.d.ts +35 -0
  32. package/dist/esm/converter.d.ts.map +1 -0
  33. package/dist/esm/converter.js +82 -0
  34. package/dist/esm/converter.js.map +1 -0
  35. package/dist/esm/executor.d.ts +40 -0
  36. package/dist/esm/executor.d.ts.map +1 -0
  37. package/dist/esm/executor.js +79 -0
  38. package/dist/esm/executor.js.map +1 -0
  39. package/dist/esm/index.d.ts +88 -0
  40. package/dist/esm/index.d.ts.map +1 -0
  41. package/dist/esm/index.js +120 -0
  42. package/dist/esm/index.js.map +1 -0
  43. package/dist/esm/package.json +3 -0
  44. package/package.json +65 -0
package/README.md ADDED
@@ -0,0 +1,73 @@
1
+ # @aerostack/sdk-openai
2
+
3
+ Use [Aerostack](https://aerostack.dev) workspace tools as OpenAI function-calling tools.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @aerostack/sdk-openai openai
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```typescript
14
+ import OpenAI from 'openai';
15
+ import { getTools, handleToolCalls } from '@aerostack/sdk-openai';
16
+
17
+ const openai = new OpenAI();
18
+ const config = { workspace: 'my-workspace', token: 'mwt_...' };
19
+
20
+ // 1. Fetch workspace tools in OpenAI format
21
+ const { tools } = await getTools(config);
22
+
23
+ // 2. Use them in a chat completion
24
+ const response = await openai.chat.completions.create({
25
+ model: 'gpt-4o',
26
+ messages: [{ role: 'user', content: 'Create a GitHub issue for the login bug' }],
27
+ tools,
28
+ });
29
+
30
+ // 3. Execute tool calls
31
+ const toolCalls = response.choices[0]?.message.tool_calls;
32
+ if (toolCalls) {
33
+ const results = await handleToolCalls(toolCalls, config);
34
+ // results are ChatCompletionToolMessageParam[] — append to messages and continue
35
+ }
36
+ ```
37
+
38
+ ## Factory Pattern
39
+
40
+ For reusable clients that cache tool name mappings:
41
+
42
+ ```typescript
43
+ import { createAerostackOpenAI } from '@aerostack/sdk-openai';
44
+
45
+ const aero = createAerostackOpenAI({ workspace: 'my-workspace', token: 'mwt_...' });
46
+
47
+ const { tools } = await aero.tools();
48
+ // ... after getting tool_calls from OpenAI ...
49
+ const results = await aero.handleToolCalls(toolCalls);
50
+ ```
51
+
52
+ ## API
53
+
54
+ ### `getTools(config)` → `Promise<ToolSet>`
55
+
56
+ Fetches tools from the workspace and converts to OpenAI format. Returns `{ tools, nameMap, raw }`.
57
+
58
+ ### `handleToolCall(toolCall, config, nameMap?)` → `Promise<ChatCompletionToolMessageParam>`
59
+
60
+ Executes a single tool call. Errors are returned as tool messages (not thrown).
61
+
62
+ ### `handleToolCalls(toolCalls, config, nameMap?)` → `Promise<ChatCompletionToolMessageParam[]>`
63
+
64
+ Executes multiple tool calls in parallel.
65
+
66
+ ### `createAerostackOpenAI(config)` → `AerostackOpenAIClient`
67
+
68
+ Creates a reusable client with cached name mappings.
69
+
70
+ ## Requirements
71
+
72
+ - `openai` >= 4.20.0
73
+ - 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,149 @@
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
+ (0, vitest_1.describe)('convertTool', () => {
6
+ (0, vitest_1.it)('converts a standard MCP tool to OpenAI format', () => {
7
+ const mcpTool = {
8
+ name: 'github__create_issue',
9
+ description: 'Create a GitHub issue',
10
+ inputSchema: {
11
+ type: 'object',
12
+ properties: {
13
+ title: { type: 'string' },
14
+ body: { type: 'string' },
15
+ },
16
+ required: ['title'],
17
+ },
18
+ };
19
+ const result = (0, converter_js_1.convertTool)(mcpTool);
20
+ (0, vitest_1.expect)(result).toEqual({
21
+ type: 'function',
22
+ function: {
23
+ name: 'github__create_issue',
24
+ description: 'Create a GitHub issue',
25
+ parameters: {
26
+ type: 'object',
27
+ properties: {
28
+ title: { type: 'string' },
29
+ body: { type: 'string' },
30
+ },
31
+ required: ['title'],
32
+ },
33
+ },
34
+ });
35
+ });
36
+ (0, vitest_1.it)('handles undefined inputSchema with empty object schema', () => {
37
+ const mcpTool = {
38
+ name: 'slack__ping',
39
+ description: 'Ping Slack',
40
+ };
41
+ const result = (0, converter_js_1.convertTool)(mcpTool);
42
+ (0, vitest_1.expect)(result.function.parameters).toEqual({
43
+ type: 'object',
44
+ properties: {},
45
+ });
46
+ });
47
+ (0, vitest_1.it)('handles undefined description', () => {
48
+ const mcpTool = {
49
+ name: 'my_tool',
50
+ inputSchema: { type: 'object', properties: {} },
51
+ };
52
+ const result = (0, converter_js_1.convertTool)(mcpTool);
53
+ (0, vitest_1.expect)(result.function.description).toBeUndefined();
54
+ (0, vitest_1.expect)(result.function.name).toBe('my_tool');
55
+ });
56
+ (0, vitest_1.it)('handles tool with empty description', () => {
57
+ const mcpTool = {
58
+ name: 'my_tool',
59
+ description: '',
60
+ inputSchema: { type: 'object', properties: {} },
61
+ };
62
+ const result = (0, converter_js_1.convertTool)(mcpTool);
63
+ // Empty string is falsy, so description should be omitted
64
+ (0, vitest_1.expect)(result.function).not.toHaveProperty('description');
65
+ });
66
+ });
67
+ (0, vitest_1.describe)('convertTools', () => {
68
+ (0, vitest_1.it)('converts an array of tools', () => {
69
+ const tools = [
70
+ { name: 'tool_a', description: 'A' },
71
+ { name: 'tool_b', description: 'B' },
72
+ ];
73
+ const result = (0, converter_js_1.convertTools)(tools);
74
+ (0, vitest_1.expect)(result).toHaveLength(2);
75
+ (0, vitest_1.expect)(result[0].function.name).toBe('tool_a');
76
+ (0, vitest_1.expect)(result[1].function.name).toBe('tool_b');
77
+ });
78
+ (0, vitest_1.it)('handles empty array', () => {
79
+ (0, vitest_1.expect)((0, converter_js_1.convertTools)([])).toEqual([]);
80
+ });
81
+ });
82
+ (0, vitest_1.describe)('sanitizeToolName', () => {
83
+ (0, vitest_1.it)('passes through valid names unchanged', () => {
84
+ (0, vitest_1.expect)((0, converter_js_1.sanitizeToolName)('github__create_issue')).toBe('github__create_issue');
85
+ (0, vitest_1.expect)((0, converter_js_1.sanitizeToolName)('my-tool-123')).toBe('my-tool-123');
86
+ });
87
+ (0, vitest_1.it)('replaces invalid characters with underscores', () => {
88
+ (0, vitest_1.expect)((0, converter_js_1.sanitizeToolName)('my.tool.name')).toBe('my_tool_name');
89
+ (0, vitest_1.expect)((0, converter_js_1.sanitizeToolName)('tool with spaces')).toBe('tool_with_spaces');
90
+ });
91
+ (0, vitest_1.it)('throws on empty name', () => {
92
+ (0, vitest_1.expect)(() => (0, converter_js_1.sanitizeToolName)('')).toThrow(/empty/i);
93
+ });
94
+ (0, vitest_1.it)('truncates names over 64 characters', () => {
95
+ const longName = 'a'.repeat(100);
96
+ const result = (0, converter_js_1.sanitizeToolName)(longName);
97
+ (0, vitest_1.expect)(result.length).toBeLessThanOrEqual(64);
98
+ });
99
+ (0, vitest_1.it)('produces different truncated names for different long inputs', () => {
100
+ const name1 = 'server_one__' + 'a'.repeat(100);
101
+ const name2 = 'server_two__' + 'b'.repeat(100);
102
+ const result1 = (0, converter_js_1.sanitizeToolName)(name1);
103
+ const result2 = (0, converter_js_1.sanitizeToolName)(name2);
104
+ (0, vitest_1.expect)(result1).not.toBe(result2);
105
+ });
106
+ });
107
+ (0, vitest_1.describe)('buildNameMap', () => {
108
+ (0, vitest_1.it)('maps sanitized names back to originals', () => {
109
+ const tools = [
110
+ { name: 'github__create_issue' },
111
+ { name: 'slack.post.message' },
112
+ ];
113
+ const map = (0, converter_js_1.buildNameMap)(tools);
114
+ (0, vitest_1.expect)(map.get('github__create_issue')).toBe('github__create_issue');
115
+ (0, vitest_1.expect)(map.get('slack_post_message')).toBe('slack.post.message');
116
+ });
117
+ (0, vitest_1.it)('throws on name collision', () => {
118
+ const tools = [
119
+ { name: 'server.create' },
120
+ { name: 'server_create' },
121
+ ];
122
+ (0, vitest_1.expect)(() => (0, converter_js_1.buildNameMap)(tools)).toThrow(/collision/i);
123
+ });
124
+ (0, vitest_1.it)('allows duplicate identical names', () => {
125
+ const tools = [
126
+ { name: 'my_tool' },
127
+ { name: 'my_tool' },
128
+ ];
129
+ (0, vitest_1.expect)(() => (0, converter_js_1.buildNameMap)(tools)).not.toThrow();
130
+ });
131
+ });
132
+ (0, vitest_1.describe)('isValidOpenAIName', () => {
133
+ (0, vitest_1.it)('accepts valid names', () => {
134
+ (0, vitest_1.expect)((0, converter_js_1.isValidOpenAIName)('my_tool')).toBe(true);
135
+ (0, vitest_1.expect)((0, converter_js_1.isValidOpenAIName)('github__create_issue')).toBe(true);
136
+ (0, vitest_1.expect)((0, converter_js_1.isValidOpenAIName)('a-b-c')).toBe(true);
137
+ });
138
+ (0, vitest_1.it)('rejects names with invalid characters', () => {
139
+ (0, vitest_1.expect)((0, converter_js_1.isValidOpenAIName)('my.tool')).toBe(false);
140
+ (0, vitest_1.expect)((0, converter_js_1.isValidOpenAIName)('tool name')).toBe(false);
141
+ });
142
+ (0, vitest_1.it)('rejects names over 64 characters', () => {
143
+ (0, vitest_1.expect)((0, converter_js_1.isValidOpenAIName)('a'.repeat(65))).toBe(false);
144
+ });
145
+ (0, vitest_1.it)('rejects empty string', () => {
146
+ (0, vitest_1.expect)((0, converter_js_1.isValidOpenAIName)('')).toBe(false);
147
+ });
148
+ });
149
+ //# 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=executor.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/executor.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 executor_js_1 = require("../executor.js");
5
+ const core_1 = require("@aerostack/core");
6
+ function mockClient(callToolResult, shouldThrow = false) {
7
+ return {
8
+ callTool: shouldThrow
9
+ ? vitest_1.vi.fn().mockRejectedValue(callToolResult)
10
+ : vitest_1.vi.fn().mockResolvedValue(callToolResult),
11
+ };
12
+ }
13
+ function makeToolCall(overrides = {}) {
14
+ return {
15
+ id: 'call_abc123',
16
+ type: 'function',
17
+ function: {
18
+ name: 'github__create_issue',
19
+ arguments: JSON.stringify({ title: 'Bug fix' }),
20
+ },
21
+ ...overrides,
22
+ };
23
+ }
24
+ (0, vitest_1.describe)('executeToolCall', () => {
25
+ (0, vitest_1.it)('executes a tool call and returns a tool message', async () => {
26
+ const client = mockClient({
27
+ content: [{ type: 'text', text: 'Issue #42 created' }],
28
+ });
29
+ const result = await (0, executor_js_1.executeToolCall)(client, makeToolCall());
30
+ (0, vitest_1.expect)(result).toEqual({
31
+ role: 'tool',
32
+ tool_call_id: 'call_abc123',
33
+ content: 'Issue #42 created',
34
+ });
35
+ (0, vitest_1.expect)(client.callTool).toHaveBeenCalledWith('github__create_issue', { title: 'Bug fix' });
36
+ });
37
+ (0, vitest_1.it)('uses nameMap to resolve sanitized names', async () => {
38
+ const client = mockClient({
39
+ content: [{ type: 'text', text: 'done' }],
40
+ });
41
+ const nameMap = new Map([['slack_post_message', 'slack.post.message']]);
42
+ const tc = makeToolCall({
43
+ function: { name: 'slack_post_message', arguments: '{}' },
44
+ });
45
+ await (0, executor_js_1.executeToolCall)(client, tc, nameMap);
46
+ (0, vitest_1.expect)(client.callTool).toHaveBeenCalledWith('slack.post.message', {});
47
+ });
48
+ (0, vitest_1.it)('returns error message when AerostackError is thrown', async () => {
49
+ const err = new core_1.AerostackError('MCP server down', 503, -32603, 'req-123');
50
+ const client = mockClient(err, true);
51
+ const result = await (0, executor_js_1.executeToolCall)(client, makeToolCall());
52
+ (0, vitest_1.expect)(result.role).toBe('tool');
53
+ (0, vitest_1.expect)(result.content).toContain('Error (-32603)');
54
+ (0, vitest_1.expect)(result.content).toContain('MCP server down');
55
+ });
56
+ (0, vitest_1.it)('returns error message for generic errors', async () => {
57
+ const err = new Error('Network timeout');
58
+ const client = mockClient(err, true);
59
+ const result = await (0, executor_js_1.executeToolCall)(client, makeToolCall());
60
+ (0, vitest_1.expect)(result.content).toBe('Error: Network timeout');
61
+ });
62
+ (0, vitest_1.it)('returns error for malformed JSON arguments', async () => {
63
+ const client = mockClient({});
64
+ const tc = makeToolCall({
65
+ function: { name: 'test', arguments: 'not json{' },
66
+ });
67
+ const result = await (0, executor_js_1.executeToolCall)(client, tc);
68
+ (0, vitest_1.expect)(result.content).toContain('Failed to parse tool arguments');
69
+ });
70
+ (0, vitest_1.it)('handles empty arguments string', async () => {
71
+ const client = mockClient({
72
+ content: [{ type: 'text', text: 'ok' }],
73
+ });
74
+ const tc = makeToolCall({
75
+ function: { name: 'test', arguments: '' },
76
+ });
77
+ await (0, executor_js_1.executeToolCall)(client, tc);
78
+ (0, vitest_1.expect)(client.callTool).toHaveBeenCalledWith('test', {});
79
+ });
80
+ });
81
+ (0, vitest_1.describe)('executeToolCalls', () => {
82
+ (0, vitest_1.it)('executes multiple tool calls in parallel', async () => {
83
+ const client = mockClient({
84
+ content: [{ type: 'text', text: 'done' }],
85
+ });
86
+ const toolCalls = [
87
+ makeToolCall({ id: 'call_1' }),
88
+ makeToolCall({ id: 'call_2' }),
89
+ ];
90
+ const results = await (0, executor_js_1.executeToolCalls)(client, toolCalls);
91
+ (0, vitest_1.expect)(results).toHaveLength(2);
92
+ (0, vitest_1.expect)(results[0].tool_call_id).toBe('call_1');
93
+ (0, vitest_1.expect)(results[1].tool_call_id).toBe('call_2');
94
+ });
95
+ (0, vitest_1.it)('handles empty array', async () => {
96
+ const client = mockClient({});
97
+ const results = await (0, executor_js_1.executeToolCalls)(client, []);
98
+ (0, vitest_1.expect)(results).toEqual([]);
99
+ });
100
+ });
101
+ (0, vitest_1.describe)('formatToolResult', () => {
102
+ (0, vitest_1.it)('formats single text content', () => {
103
+ const result = (0, executor_js_1.formatToolResult)({
104
+ content: [{ type: 'text', text: 'Hello world' }],
105
+ });
106
+ (0, vitest_1.expect)(result).toBe('Hello world');
107
+ });
108
+ (0, vitest_1.it)('concatenates multiple text blocks', () => {
109
+ const result = (0, executor_js_1.formatToolResult)({
110
+ content: [
111
+ { type: 'text', text: 'Line 1' },
112
+ { type: 'text', text: 'Line 2' },
113
+ ],
114
+ });
115
+ (0, vitest_1.expect)(result).toBe('Line 1\nLine 2');
116
+ });
117
+ (0, vitest_1.it)('handles binary data blocks', () => {
118
+ const result = (0, executor_js_1.formatToolResult)({
119
+ content: [{ type: 'image', data: 'base64data...', mimeType: 'image/png' }],
120
+ });
121
+ (0, vitest_1.expect)(result).toContain('image/png');
122
+ (0, vitest_1.expect)(result).toContain('base64');
123
+ });
124
+ (0, vitest_1.it)('prefixes error results', () => {
125
+ const result = (0, executor_js_1.formatToolResult)({
126
+ content: [{ type: 'text', text: 'Something failed' }],
127
+ isError: true,
128
+ });
129
+ (0, vitest_1.expect)(result).toBe('Error: Something failed');
130
+ });
131
+ (0, vitest_1.it)('handles empty content array', () => {
132
+ (0, vitest_1.expect)((0, executor_js_1.formatToolResult)({ content: [] })).toBe('Success (no output)');
133
+ });
134
+ (0, vitest_1.it)('handles undefined content', () => {
135
+ (0, vitest_1.expect)((0, executor_js_1.formatToolResult)({})).toBe('Success (no output)');
136
+ });
137
+ (0, vitest_1.it)('handles empty content with isError', () => {
138
+ (0, vitest_1.expect)((0, executor_js_1.formatToolResult)({ content: [], isError: true })).toBe('Error: Tool returned no content');
139
+ });
140
+ });
141
+ //# sourceMappingURL=executor.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.test.js","sourceRoot":"","sources":["../../../src/__tests__/executor.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Converts Aerostack McpTool definitions to OpenAI ChatCompletionTool format.
3
+ */
4
+ import type { ChatCompletionTool } from 'openai/resources/chat/completions';
5
+ import type { McpTool } from '@aerostack/core';
6
+ /**
7
+ * Convert an array of McpTool definitions to OpenAI ChatCompletionTool format.
8
+ *
9
+ * Handles edge cases:
10
+ * - Undefined inputSchema → empty object schema
11
+ * - Tool names exceeding 64 chars → truncated with hash suffix
12
+ * - Invalid characters in tool names → sanitized
13
+ */
14
+ export declare function convertTools(mcpTools: McpTool[]): ChatCompletionTool[];
15
+ /**
16
+ * Convert a single McpTool to OpenAI ChatCompletionTool format.
17
+ */
18
+ export declare function convertTool(tool: McpTool): ChatCompletionTool;
19
+ /**
20
+ * Sanitize a tool name to comply with OpenAI's function name constraints.
21
+ * - Replace invalid characters with underscores
22
+ * - Truncate to 64 characters (keeping a short hash suffix for uniqueness)
23
+ */
24
+ export declare function sanitizeToolName(name: string): string;
25
+ /**
26
+ * Build a reverse mapping from sanitized OpenAI tool names back to original MCP tool names.
27
+ * Needed when tool names are truncated/sanitized.
28
+ *
29
+ * Throws if two distinct MCP tool names sanitize to the same OpenAI name,
30
+ * since that would cause silent wrong-dispatch.
31
+ */
32
+ export declare function buildNameMap(mcpTools: McpTool[]): Map<string, string>;
33
+ /** Check if a tool name is valid for OpenAI without modification. */
34
+ export declare function isValidOpenAIName(name: string): boolean;
35
+ //# sourceMappingURL=converter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"converter.d.ts","sourceRoot":"","sources":["../../src/converter.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AAC5E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAK/C;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,kBAAkB,EAAE,CAEtE;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,kBAAkB,CAc7D;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAerD;AAYD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAcrE;AAED,qEAAqE;AACrE,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEvD"}
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.convertTools = convertTools;
4
+ exports.convertTool = convertTool;
5
+ exports.sanitizeToolName = sanitizeToolName;
6
+ exports.buildNameMap = buildNameMap;
7
+ exports.isValidOpenAIName = isValidOpenAIName;
8
+ /** OpenAI function names must match: ^[a-zA-Z0-9_-]{1,64}$ */
9
+ const OPENAI_FUNCTION_NAME_RE = /^[a-zA-Z0-9_-]{1,64}$/;
10
+ /**
11
+ * Convert an array of McpTool definitions to OpenAI ChatCompletionTool format.
12
+ *
13
+ * Handles edge cases:
14
+ * - Undefined inputSchema → empty object schema
15
+ * - Tool names exceeding 64 chars → truncated with hash suffix
16
+ * - Invalid characters in tool names → sanitized
17
+ */
18
+ function convertTools(mcpTools) {
19
+ return mcpTools.map(convertTool);
20
+ }
21
+ /**
22
+ * Convert a single McpTool to OpenAI ChatCompletionTool format.
23
+ */
24
+ function convertTool(tool) {
25
+ const name = sanitizeToolName(tool.name);
26
+ const parameters = tool.inputSchema
27
+ ? tool.inputSchema
28
+ : { type: 'object', properties: {} };
29
+ return {
30
+ type: 'function',
31
+ function: {
32
+ name,
33
+ ...(tool.description ? { description: tool.description } : {}),
34
+ parameters,
35
+ },
36
+ };
37
+ }
38
+ /**
39
+ * Sanitize a tool name to comply with OpenAI's function name constraints.
40
+ * - Replace invalid characters with underscores
41
+ * - Truncate to 64 characters (keeping a short hash suffix for uniqueness)
42
+ */
43
+ function sanitizeToolName(name) {
44
+ if (!name) {
45
+ throw new Error('Tool name cannot be empty');
46
+ }
47
+ // Replace any character not in [a-zA-Z0-9_-] with underscore
48
+ let sanitized = name.replace(/[^a-zA-Z0-9_-]/g, '_');
49
+ // Truncate if over 64 chars — use last 8 chars as hash-like suffix
50
+ if (sanitized.length > 64) {
51
+ const hash = simpleHash(name);
52
+ sanitized = sanitized.slice(0, 55) + '_' + hash;
53
+ }
54
+ return sanitized;
55
+ }
56
+ /** Simple string hash producing an 8-char hex string. */
57
+ function simpleHash(str) {
58
+ let hash = 0;
59
+ for (let i = 0; i < str.length; i++) {
60
+ const char = str.charCodeAt(i);
61
+ hash = ((hash << 5) - hash + char) | 0;
62
+ }
63
+ return Math.abs(hash).toString(16).padStart(8, '0').slice(0, 8);
64
+ }
65
+ /**
66
+ * Build a reverse mapping from sanitized OpenAI tool names back to original MCP tool names.
67
+ * Needed when tool names are truncated/sanitized.
68
+ *
69
+ * Throws if two distinct MCP tool names sanitize to the same OpenAI name,
70
+ * since that would cause silent wrong-dispatch.
71
+ */
72
+ function buildNameMap(mcpTools) {
73
+ const map = new Map();
74
+ for (const tool of mcpTools) {
75
+ const sanitized = sanitizeToolName(tool.name);
76
+ const existing = map.get(sanitized);
77
+ if (existing && existing !== tool.name) {
78
+ throw new Error(`Tool name collision: "${tool.name}" and "${existing}" both sanitize to "${sanitized}". ` +
79
+ `Rename one of the tools in your workspace to avoid ambiguity.`);
80
+ }
81
+ map.set(sanitized, tool.name);
82
+ }
83
+ return map;
84
+ }
85
+ /** Check if a tool name is valid for OpenAI without modification. */
86
+ function isValidOpenAIName(name) {
87
+ return OPENAI_FUNCTION_NAME_RE.test(name);
88
+ }
89
+ //# sourceMappingURL=converter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"converter.js","sourceRoot":"","sources":["../../src/converter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Executes OpenAI tool calls by proxying them through WorkspaceClient.
3
+ */
4
+ import type { ChatCompletionMessageToolCall } from 'openai/resources/chat/completions';
5
+ import type { ChatCompletionToolMessageParam } from 'openai/resources/chat/completions';
6
+ import { WorkspaceClient } from '@aerostack/core';
7
+ import type { McpToolResult } from '@aerostack/core';
8
+ export interface WorkspaceConfig {
9
+ /** Workspace slug */
10
+ workspace: string;
11
+ /** Workspace token (mwt_...) */
12
+ token: string;
13
+ /** Override gateway base URL */
14
+ baseUrl?: string;
15
+ }
16
+ /**
17
+ * Execute a single OpenAI tool call against the Aerostack workspace.
18
+ *
19
+ * Returns a ChatCompletionToolMessageParam ready to append to messages.
20
+ * Errors from the workspace are returned as tool error messages (not thrown),
21
+ * because OpenAI expects a tool message back even when tools fail.
22
+ *
23
+ * @param nameMap - Optional reverse map from sanitized→original tool names
24
+ */
25
+ export declare function executeToolCall(client: WorkspaceClient, toolCall: ChatCompletionMessageToolCall, nameMap?: Map<string, string>): Promise<ChatCompletionToolMessageParam>;
26
+ /**
27
+ * Execute multiple tool calls in parallel.
28
+ *
29
+ * Returns an array of ChatCompletionToolMessageParam in the same order as input.
30
+ */
31
+ export declare function executeToolCalls(client: WorkspaceClient, toolCalls: ChatCompletionMessageToolCall[], nameMap?: Map<string, string>): Promise<ChatCompletionToolMessageParam[]>;
32
+ /**
33
+ * Flatten McpToolResult content array into a single string for OpenAI.
34
+ *
35
+ * McpToolResult.content is an array of content blocks (text, base64 data, etc.).
36
+ * OpenAI tool messages expect a single string. We concatenate text blocks and
37
+ * JSON-serialize any non-text content.
38
+ */
39
+ export declare function formatToolResult(result: McpToolResult): string;
40
+ //# sourceMappingURL=executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../src/executor.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,mCAAmC,CAAC;AACvF,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,mCAAmC,CAAC;AACxF,OAAO,EAAE,eAAe,EAAkB,MAAM,iBAAiB,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,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;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CACjC,MAAM,EAAE,eAAe,EACvB,QAAQ,EAAE,6BAA6B,EACvC,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,OAAO,CAAC,8BAA8B,CAAC,CAkCzC;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CAClC,MAAM,EAAE,eAAe,EACvB,SAAS,EAAE,6BAA6B,EAAE,EAC1C,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,OAAO,CAAC,8BAA8B,EAAE,CAAC,CAI3C;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAkB9D"}