@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
@@ -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,82 @@
1
+ /** OpenAI function names must match: ^[a-zA-Z0-9_-]{1,64}$ */
2
+ const OPENAI_FUNCTION_NAME_RE = /^[a-zA-Z0-9_-]{1,64}$/;
3
+ /**
4
+ * Convert an array of McpTool definitions to OpenAI ChatCompletionTool format.
5
+ *
6
+ * Handles edge cases:
7
+ * - Undefined inputSchema → empty object schema
8
+ * - Tool names exceeding 64 chars → truncated with hash suffix
9
+ * - Invalid characters in tool names → sanitized
10
+ */
11
+ export function convertTools(mcpTools) {
12
+ return mcpTools.map(convertTool);
13
+ }
14
+ /**
15
+ * Convert a single McpTool to OpenAI ChatCompletionTool format.
16
+ */
17
+ export function convertTool(tool) {
18
+ const name = sanitizeToolName(tool.name);
19
+ const parameters = tool.inputSchema
20
+ ? tool.inputSchema
21
+ : { type: 'object', properties: {} };
22
+ return {
23
+ type: 'function',
24
+ function: {
25
+ name,
26
+ ...(tool.description ? { description: tool.description } : {}),
27
+ parameters,
28
+ },
29
+ };
30
+ }
31
+ /**
32
+ * Sanitize a tool name to comply with OpenAI's function name constraints.
33
+ * - Replace invalid characters with underscores
34
+ * - Truncate to 64 characters (keeping a short hash suffix for uniqueness)
35
+ */
36
+ export function sanitizeToolName(name) {
37
+ if (!name) {
38
+ throw new Error('Tool name cannot be empty');
39
+ }
40
+ // Replace any character not in [a-zA-Z0-9_-] with underscore
41
+ let sanitized = name.replace(/[^a-zA-Z0-9_-]/g, '_');
42
+ // Truncate if over 64 chars — use last 8 chars as hash-like suffix
43
+ if (sanitized.length > 64) {
44
+ const hash = simpleHash(name);
45
+ sanitized = sanitized.slice(0, 55) + '_' + hash;
46
+ }
47
+ return sanitized;
48
+ }
49
+ /** Simple string hash producing an 8-char hex string. */
50
+ function simpleHash(str) {
51
+ let hash = 0;
52
+ for (let i = 0; i < str.length; i++) {
53
+ const char = str.charCodeAt(i);
54
+ hash = ((hash << 5) - hash + char) | 0;
55
+ }
56
+ return Math.abs(hash).toString(16).padStart(8, '0').slice(0, 8);
57
+ }
58
+ /**
59
+ * Build a reverse mapping from sanitized OpenAI tool names back to original MCP tool names.
60
+ * Needed when tool names are truncated/sanitized.
61
+ *
62
+ * Throws if two distinct MCP tool names sanitize to the same OpenAI name,
63
+ * since that would cause silent wrong-dispatch.
64
+ */
65
+ export function buildNameMap(mcpTools) {
66
+ const map = new Map();
67
+ for (const tool of mcpTools) {
68
+ const sanitized = sanitizeToolName(tool.name);
69
+ const existing = map.get(sanitized);
70
+ if (existing && existing !== tool.name) {
71
+ throw new Error(`Tool name collision: "${tool.name}" and "${existing}" both sanitize to "${sanitized}". ` +
72
+ `Rename one of the tools in your workspace to avoid ambiguity.`);
73
+ }
74
+ map.set(sanitized, tool.name);
75
+ }
76
+ return map;
77
+ }
78
+ /** Check if a tool name is valid for OpenAI without modification. */
79
+ export function isValidOpenAIName(name) {
80
+ return OPENAI_FUNCTION_NAME_RE.test(name);
81
+ }
82
+ //# 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"}
@@ -0,0 +1,79 @@
1
+ import { AerostackError } from '@aerostack/core';
2
+ /**
3
+ * Execute a single OpenAI tool call against the Aerostack workspace.
4
+ *
5
+ * Returns a ChatCompletionToolMessageParam ready to append to messages.
6
+ * Errors from the workspace are returned as tool error messages (not thrown),
7
+ * because OpenAI expects a tool message back even when tools fail.
8
+ *
9
+ * @param nameMap - Optional reverse map from sanitized→original tool names
10
+ */
11
+ export async function executeToolCall(client, toolCall, nameMap) {
12
+ const originalName = nameMap?.get(toolCall.function.name) ?? toolCall.function.name;
13
+ let args;
14
+ try {
15
+ args = JSON.parse(toolCall.function.arguments || '{}');
16
+ }
17
+ catch {
18
+ return {
19
+ role: 'tool',
20
+ tool_call_id: toolCall.id,
21
+ content: `Error: Failed to parse tool arguments as JSON`,
22
+ };
23
+ }
24
+ try {
25
+ const result = await client.callTool(originalName, args);
26
+ return {
27
+ role: 'tool',
28
+ tool_call_id: toolCall.id,
29
+ content: formatToolResult(result),
30
+ };
31
+ }
32
+ catch (err) {
33
+ const message = err instanceof AerostackError
34
+ ? `Error (${err.rpcCode}): ${err.message}`
35
+ : err instanceof Error
36
+ ? `Error: ${err.message}`
37
+ : 'Error: Unknown error executing tool';
38
+ return {
39
+ role: 'tool',
40
+ tool_call_id: toolCall.id,
41
+ content: message,
42
+ };
43
+ }
44
+ }
45
+ /**
46
+ * Execute multiple tool calls in parallel.
47
+ *
48
+ * Returns an array of ChatCompletionToolMessageParam in the same order as input.
49
+ */
50
+ export async function executeToolCalls(client, toolCalls, nameMap) {
51
+ return Promise.all(toolCalls.map(tc => executeToolCall(client, tc, nameMap)));
52
+ }
53
+ /**
54
+ * Flatten McpToolResult content array into a single string for OpenAI.
55
+ *
56
+ * McpToolResult.content is an array of content blocks (text, base64 data, etc.).
57
+ * OpenAI tool messages expect a single string. We concatenate text blocks and
58
+ * JSON-serialize any non-text content.
59
+ */
60
+ export function formatToolResult(result) {
61
+ if (!result.content || result.content.length === 0) {
62
+ return result.isError ? 'Error: Tool returned no content' : 'Success (no output)';
63
+ }
64
+ const parts = [];
65
+ for (const block of result.content) {
66
+ if (block.text) {
67
+ parts.push(block.text);
68
+ }
69
+ else if (block.data) {
70
+ parts.push(`[${block.mimeType ?? 'binary'} data: ${block.data.length} chars base64]`);
71
+ }
72
+ else {
73
+ parts.push(JSON.stringify(block));
74
+ }
75
+ }
76
+ const text = parts.join('\n');
77
+ return result.isError ? `Error: ${text}` : text;
78
+ }
79
+ //# sourceMappingURL=executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../src/executor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * @aerostack/sdk-openai — Use Aerostack workspace tools as OpenAI function-calling tools.
3
+ *
4
+ * @example Standalone functions
5
+ * ```ts
6
+ * import { getTools, handleToolCall, handleToolCalls } from '@aerostack/sdk-openai';
7
+ * import OpenAI from 'openai';
8
+ *
9
+ * const openai = new OpenAI();
10
+ * const config = { workspace: 'my-workspace', token: 'mwt_...' };
11
+ *
12
+ * const tools = await getTools(config);
13
+ * const response = await openai.chat.completions.create({
14
+ * model: 'gpt-4o',
15
+ * messages: [{ role: 'user', content: 'Create a GitHub issue for the login bug' }],
16
+ * tools,
17
+ * });
18
+ *
19
+ * const toolCalls = response.choices[0]?.message.tool_calls;
20
+ * if (toolCalls) {
21
+ * const results = await handleToolCalls(toolCalls, config);
22
+ * // results are ChatCompletionToolMessageParam[] — append to messages and continue
23
+ * }
24
+ * ```
25
+ *
26
+ * @example Factory pattern
27
+ * ```ts
28
+ * const client = createAerostackOpenAI({ workspace: 'my-workspace', token: 'mwt_...' });
29
+ * const tools = await client.tools();
30
+ * const results = await client.handleToolCalls(toolCalls);
31
+ * ```
32
+ */
33
+ import type { ChatCompletionTool, ChatCompletionMessageToolCall, ChatCompletionToolMessageParam } from 'openai/resources/chat/completions';
34
+ import { WorkspaceClient } from '@aerostack/core';
35
+ import type { McpTool } from '@aerostack/core';
36
+ import type { WorkspaceConfig } from './executor.js';
37
+ export type { WorkspaceConfig } from './executor.js';
38
+ export { convertTools, convertTool, sanitizeToolName, isValidOpenAIName } from './converter.js';
39
+ export { formatToolResult } from './executor.js';
40
+ /** Result from getTools — includes both the OpenAI tools and the name map for execution. */
41
+ export interface ToolSet {
42
+ /** OpenAI-formatted tools, ready for chat.completions.create({ tools }) */
43
+ tools: ChatCompletionTool[];
44
+ /** Reverse map from sanitized names to original MCP tool names (used internally by handleToolCall) */
45
+ nameMap: Map<string, string>;
46
+ /** Raw MCP tools from the workspace */
47
+ raw: McpTool[];
48
+ }
49
+ /**
50
+ * Fetch tools from an Aerostack workspace and convert to OpenAI format.
51
+ *
52
+ * Returns a ToolSet containing the formatted tools, a name map for execution,
53
+ * and the raw MCP tools for inspection.
54
+ */
55
+ export declare function getTools(config: WorkspaceConfig): Promise<ToolSet>;
56
+ /**
57
+ * Execute a single OpenAI tool call against the workspace.
58
+ *
59
+ * @param toolCall - A tool call from response.choices[0].message.tool_calls
60
+ * @param config - Workspace connection config
61
+ * @param nameMap - Optional name map from getTools() (pass if tools were renamed)
62
+ */
63
+ export declare function handleToolCall(toolCall: ChatCompletionMessageToolCall, config: WorkspaceConfig, nameMap?: Map<string, string>): Promise<ChatCompletionToolMessageParam>;
64
+ /**
65
+ * Execute multiple OpenAI tool calls in parallel against the workspace.
66
+ *
67
+ * Returns ChatCompletionToolMessageParam[] in the same order as input —
68
+ * ready to append to your messages array.
69
+ */
70
+ export declare function handleToolCalls(toolCalls: ChatCompletionMessageToolCall[], config: WorkspaceConfig, nameMap?: Map<string, string>): Promise<ChatCompletionToolMessageParam[]>;
71
+ export interface AerostackOpenAIClient {
72
+ /** Fetch and convert workspace tools to OpenAI format. */
73
+ tools(): Promise<ToolSet>;
74
+ /** Execute a single tool call. */
75
+ handleToolCall(toolCall: ChatCompletionMessageToolCall): Promise<ChatCompletionToolMessageParam>;
76
+ /** Execute multiple tool calls in parallel. */
77
+ handleToolCalls(toolCalls: ChatCompletionMessageToolCall[]): Promise<ChatCompletionToolMessageParam[]>;
78
+ /** Access the underlying WorkspaceClient for advanced use. */
79
+ readonly workspaceClient: WorkspaceClient;
80
+ }
81
+ /**
82
+ * Create a reusable Aerostack OpenAI client.
83
+ *
84
+ * Reuses a single WorkspaceClient instance and caches the name map
85
+ * after the first tools() call for consistent tool name resolution.
86
+ */
87
+ export declare function createAerostackOpenAI(config: WorkspaceConfig): AerostackOpenAIClient;
88
+ //# 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,kBAAkB,EAAE,6BAA6B,EAAE,8BAA8B,EAAE,MAAM,mCAAmC,CAAC;AAC3I,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAG/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGrD,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAChG,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjD,4FAA4F;AAC5F,MAAM,WAAW,OAAO;IACpB,2EAA2E;IAC3E,KAAK,EAAE,kBAAkB,EAAE,CAAC;IAC5B,sGAAsG;IACtG,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,uCAAuC;IACvC,GAAG,EAAE,OAAO,EAAE,CAAC;CAClB;AAcD;;;;;GAKG;AACH,wBAAsB,QAAQ,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,CAMxE;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAChC,QAAQ,EAAE,6BAA6B,EACvC,MAAM,EAAE,eAAe,EACvB,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,OAAO,CAAC,8BAA8B,CAAC,CAGzC;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CACjC,SAAS,EAAE,6BAA6B,EAAE,EAC1C,MAAM,EAAE,eAAe,EACvB,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,OAAO,CAAC,8BAA8B,EAAE,CAAC,CAG3C;AAMD,MAAM,WAAW,qBAAqB;IAClC,0DAA0D;IAC1D,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1B,kCAAkC;IAClC,cAAc,CAAC,QAAQ,EAAE,6BAA6B,GAAG,OAAO,CAAC,8BAA8B,CAAC,CAAC;IACjG,+CAA+C;IAC/C,eAAe,CAAC,SAAS,EAAE,6BAA6B,EAAE,GAAG,OAAO,CAAC,8BAA8B,EAAE,CAAC,CAAC;IACvG,8DAA8D;IAC9D,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;CAC7C;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,eAAe,GAAG,qBAAqB,CAoCpF"}
@@ -0,0 +1,120 @@
1
+ /**
2
+ * @aerostack/sdk-openai — Use Aerostack workspace tools as OpenAI function-calling tools.
3
+ *
4
+ * @example Standalone functions
5
+ * ```ts
6
+ * import { getTools, handleToolCall, handleToolCalls } from '@aerostack/sdk-openai';
7
+ * import OpenAI from 'openai';
8
+ *
9
+ * const openai = new OpenAI();
10
+ * const config = { workspace: 'my-workspace', token: 'mwt_...' };
11
+ *
12
+ * const tools = await getTools(config);
13
+ * const response = await openai.chat.completions.create({
14
+ * model: 'gpt-4o',
15
+ * messages: [{ role: 'user', content: 'Create a GitHub issue for the login bug' }],
16
+ * tools,
17
+ * });
18
+ *
19
+ * const toolCalls = response.choices[0]?.message.tool_calls;
20
+ * if (toolCalls) {
21
+ * const results = await handleToolCalls(toolCalls, config);
22
+ * // results are ChatCompletionToolMessageParam[] — append to messages and continue
23
+ * }
24
+ * ```
25
+ *
26
+ * @example Factory pattern
27
+ * ```ts
28
+ * const client = createAerostackOpenAI({ workspace: 'my-workspace', token: 'mwt_...' });
29
+ * const tools = await client.tools();
30
+ * const results = await client.handleToolCalls(toolCalls);
31
+ * ```
32
+ */
33
+ import { WorkspaceClient } from '@aerostack/core';
34
+ import { convertTools, buildNameMap } from './converter.js';
35
+ import { executeToolCall, executeToolCalls } from './executor.js';
36
+ export { convertTools, convertTool, sanitizeToolName, isValidOpenAIName } from './converter.js';
37
+ export { formatToolResult } from './executor.js';
38
+ function createWorkspaceClient(config) {
39
+ return new WorkspaceClient({
40
+ slug: config.workspace,
41
+ token: config.token,
42
+ baseUrl: config.baseUrl,
43
+ });
44
+ }
45
+ // ---------------------------------------------------------------------------
46
+ // Standalone functions
47
+ // ---------------------------------------------------------------------------
48
+ /**
49
+ * Fetch tools from an Aerostack workspace and convert to OpenAI format.
50
+ *
51
+ * Returns a ToolSet containing the formatted tools, a name map for execution,
52
+ * and the raw MCP tools for inspection.
53
+ */
54
+ export async function getTools(config) {
55
+ const client = createWorkspaceClient(config);
56
+ const raw = await client.listTools();
57
+ const tools = convertTools(raw);
58
+ const nameMap = buildNameMap(raw);
59
+ return { tools, nameMap, raw };
60
+ }
61
+ /**
62
+ * Execute a single OpenAI tool call against the workspace.
63
+ *
64
+ * @param toolCall - A tool call from response.choices[0].message.tool_calls
65
+ * @param config - Workspace connection config
66
+ * @param nameMap - Optional name map from getTools() (pass if tools were renamed)
67
+ */
68
+ export async function handleToolCall(toolCall, config, nameMap) {
69
+ const client = createWorkspaceClient(config);
70
+ return executeToolCall(client, toolCall, nameMap);
71
+ }
72
+ /**
73
+ * Execute multiple OpenAI tool calls in parallel against the workspace.
74
+ *
75
+ * Returns ChatCompletionToolMessageParam[] in the same order as input —
76
+ * ready to append to your messages array.
77
+ */
78
+ export async function handleToolCalls(toolCalls, config, nameMap) {
79
+ const client = createWorkspaceClient(config);
80
+ return executeToolCalls(client, toolCalls, nameMap);
81
+ }
82
+ /**
83
+ * Create a reusable Aerostack OpenAI client.
84
+ *
85
+ * Reuses a single WorkspaceClient instance and caches the name map
86
+ * after the first tools() call for consistent tool name resolution.
87
+ */
88
+ export function createAerostackOpenAI(config) {
89
+ const wsClient = createWorkspaceClient(config);
90
+ let cachedNameMap;
91
+ /** Ensure name map is populated — fetches tools on first call. */
92
+ async function ensureNameMap() {
93
+ if (!cachedNameMap) {
94
+ const raw = await wsClient.listTools();
95
+ cachedNameMap = buildNameMap(raw);
96
+ }
97
+ return cachedNameMap;
98
+ }
99
+ return {
100
+ async tools() {
101
+ const raw = await wsClient.listTools();
102
+ const tools = convertTools(raw);
103
+ const nameMap = buildNameMap(raw);
104
+ cachedNameMap = nameMap;
105
+ return { tools, nameMap, raw };
106
+ },
107
+ async handleToolCall(toolCall) {
108
+ const nameMap = await ensureNameMap();
109
+ return executeToolCall(wsClient, toolCall, nameMap);
110
+ },
111
+ async handleToolCalls(toolCalls) {
112
+ const nameMap = await ensureNameMap();
113
+ return executeToolCalls(wsClient, toolCalls, nameMap);
114
+ },
115
+ get workspaceClient() {
116
+ return wsClient;
117
+ },
118
+ };
119
+ }
120
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "module"
3
+ }
package/package.json ADDED
@@ -0,0 +1,65 @@
1
+ {
2
+ "name": "@aerostack/sdk-openai",
3
+ "version": "0.10.1",
4
+ "description": "Use Aerostack workspace tools as OpenAI function-calling tools",
5
+ "author": "Aerostack",
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "tshy": {
9
+ "sourceDialects": [
10
+ "@aerostack/sdk-openai/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
+ "openai": "^4.20.0"
29
+ },
30
+ "peerDependenciesMeta": {
31
+ "openai": {
32
+ "optional": false
33
+ }
34
+ },
35
+ "devDependencies": {
36
+ "openai": "^4.80.0",
37
+ "tshy": "^2.0.0",
38
+ "typescript": "~5.8.3",
39
+ "vitest": "^3.2.1"
40
+ },
41
+ "exports": {
42
+ ".": {
43
+ "import": {
44
+ "@aerostack/sdk-openai/source": "./src/index.ts",
45
+ "types": "./dist/esm/index.d.ts",
46
+ "default": "./dist/esm/index.js"
47
+ },
48
+ "require": {
49
+ "types": "./dist/commonjs/index.d.ts",
50
+ "default": "./dist/commonjs/index.js"
51
+ }
52
+ },
53
+ "./package.json": "./package.json"
54
+ },
55
+ "main": "./dist/commonjs/index.js",
56
+ "types": "./dist/commonjs/index.d.ts",
57
+ "module": "./dist/esm/index.js",
58
+ "files": [
59
+ "dist",
60
+ "README.md"
61
+ ],
62
+ "publishConfig": {
63
+ "access": "public"
64
+ }
65
+ }