@tanstack/openai-base 0.9.14 → 0.9.15
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.
- package/dist/esm/adapters/chat-completions-text.js +1 -1
- package/dist/esm/adapters/responses-text.js +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/tools/apply-patch-tool.js +3 -2
- package/dist/esm/tools/apply-patch-tool.js.map +1 -1
- package/dist/esm/tools/code-interpreter-tool.js +4 -3
- package/dist/esm/tools/code-interpreter-tool.js.map +1 -1
- package/dist/esm/tools/computer-use-tool.js +4 -3
- package/dist/esm/tools/computer-use-tool.js.map +1 -1
- package/dist/esm/tools/custom-tool.js +4 -3
- package/dist/esm/tools/custom-tool.js.map +1 -1
- package/dist/esm/tools/file-search-tool.js +4 -3
- package/dist/esm/tools/file-search-tool.js.map +1 -1
- package/dist/esm/tools/image-generation-tool.d.ts +2 -4
- package/dist/esm/tools/image-generation-tool.js +6 -7
- package/dist/esm/tools/image-generation-tool.js.map +1 -1
- package/dist/esm/tools/index.js +14 -0
- package/dist/esm/tools/local-shell-tool.js +3 -2
- package/dist/esm/tools/local-shell-tool.js.map +1 -1
- package/dist/esm/tools/mcp-tool.js +7 -6
- package/dist/esm/tools/mcp-tool.js.map +1 -1
- package/dist/esm/tools/openai-provider-tool.d.ts +20 -0
- package/dist/esm/tools/openai-provider-tool.js +49 -0
- package/dist/esm/tools/openai-provider-tool.js.map +1 -0
- package/dist/esm/tools/shell-tool.js +4 -3
- package/dist/esm/tools/shell-tool.js.map +1 -1
- package/dist/esm/tools/tool-converter.js +7 -18
- package/dist/esm/tools/tool-converter.js.map +1 -1
- package/dist/esm/tools/web-search-preview-tool.d.ts +1 -2
- package/dist/esm/tools/web-search-preview-tool.js +5 -5
- package/dist/esm/tools/web-search-preview-tool.js.map +1 -1
- package/dist/esm/tools/web-search-tool.d.ts +2 -4
- package/dist/esm/tools/web-search-tool.js +6 -7
- package/dist/esm/tools/web-search-tool.js.map +1 -1
- package/package.json +3 -3
- package/src/tools/apply-patch-tool.ts +9 -5
- package/src/tools/code-interpreter-tool.ts +17 -8
- package/src/tools/computer-use-tool.ts +14 -7
- package/src/tools/custom-tool.ts +14 -7
- package/src/tools/file-search-tool.ts +14 -7
- package/src/tools/image-generation-tool.ts +19 -11
- package/src/tools/local-shell-tool.ts +9 -5
- package/src/tools/mcp-tool.ts +19 -9
- package/src/tools/openai-provider-tool.ts +72 -0
- package/src/tools/shell-tool.ts +17 -9
- package/src/tools/tool-converter.ts +28 -43
- package/src/tools/web-search-preview-tool.ts +17 -8
- package/src/tools/web-search-tool.ts +18 -10
|
@@ -1,13 +1,13 @@
|
|
|
1
|
+
import { getOpenAIProviderToolMetadata, openAIProviderTool } from "./openai-provider-tool.js";
|
|
1
2
|
//#region src/tools/web-search-preview-tool.ts
|
|
2
3
|
/**
|
|
3
4
|
* Converts a standard Tool to OpenAI WebSearchPreviewTool format. Force the
|
|
4
5
|
* literal `type: 'web_search_preview'` instead of trusting `metadata.type`,
|
|
5
|
-
*
|
|
6
|
-
* malformed payload while the dispatcher already routed by `tool.name`.
|
|
6
|
+
* so a missing or wrong metadata type cannot produce a malformed payload.
|
|
7
7
|
*/
|
|
8
8
|
function convertWebSearchPreviewToolToAdapterFormat(tool) {
|
|
9
9
|
return {
|
|
10
|
-
...tool
|
|
10
|
+
...getOpenAIProviderToolMetadata(tool),
|
|
11
11
|
type: "web_search_preview"
|
|
12
12
|
};
|
|
13
13
|
}
|
|
@@ -18,11 +18,11 @@ function convertWebSearchPreviewToolToAdapterFormat(tool) {
|
|
|
18
18
|
* re-wrap this in their own package.
|
|
19
19
|
*/
|
|
20
20
|
function webSearchPreviewTool(toolData) {
|
|
21
|
-
return {
|
|
21
|
+
return openAIProviderTool({
|
|
22
22
|
name: "web_search_preview",
|
|
23
23
|
description: "Search the web (preview version)",
|
|
24
24
|
metadata: toolData
|
|
25
|
-
};
|
|
25
|
+
}, "web_search_preview");
|
|
26
26
|
}
|
|
27
27
|
//#endregion
|
|
28
28
|
export { convertWebSearchPreviewToolToAdapterFormat, webSearchPreviewTool };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-search-preview-tool.js","names":[],"sources":["../../../src/tools/web-search-preview-tool.ts"],"sourcesContent":["import type { WebSearchPreviewTool as WebSearchPreviewToolConfig } from 'openai/resources/responses/responses'\nimport type { Tool } from '@tanstack/ai'\n\nexport type { WebSearchPreviewToolConfig }\n\n/** @deprecated Renamed to `WebSearchPreviewToolConfig`. Will be removed in a future release. */\nexport type WebSearchPreviewTool = WebSearchPreviewToolConfig\n\n/**\n * Converts a standard Tool to OpenAI WebSearchPreviewTool format. Force the\n * literal `type: 'web_search_preview'` instead of trusting `metadata.type`,\n *
|
|
1
|
+
{"version":3,"file":"web-search-preview-tool.js","names":[],"sources":["../../../src/tools/web-search-preview-tool.ts"],"sourcesContent":["import {\n getOpenAIProviderToolMetadata,\n openAIProviderTool,\n} from './openai-provider-tool'\nimport type { WebSearchPreviewTool as WebSearchPreviewToolConfig } from 'openai/resources/responses/responses'\nimport type { Tool } from '@tanstack/ai'\n\nexport type { WebSearchPreviewToolConfig }\n\n/** @deprecated Renamed to `WebSearchPreviewToolConfig`. Will be removed in a future release. */\nexport type WebSearchPreviewTool = WebSearchPreviewToolConfig\n\n/**\n * Converts a standard Tool to OpenAI WebSearchPreviewTool format. Force the\n * literal `type: 'web_search_preview'` instead of trusting `metadata.type`,\n * so a missing or wrong metadata type cannot produce a malformed payload.\n */\nexport function convertWebSearchPreviewToolToAdapterFormat(\n tool: Tool,\n): WebSearchPreviewToolConfig {\n const metadata = getOpenAIProviderToolMetadata(tool) as Omit<\n WebSearchPreviewToolConfig,\n 'type'\n >\n return {\n ...metadata,\n type: 'web_search_preview',\n }\n}\n\n/**\n * Creates a standard Tool from WebSearchPreviewTool parameters.\n *\n * Base (non-branded) factory. Providers that need branded return types should\n * re-wrap this in their own package.\n */\nexport function webSearchPreviewTool(\n toolData: WebSearchPreviewToolConfig,\n): Tool {\n return openAIProviderTool(\n {\n name: 'web_search_preview',\n description: 'Search the web (preview version)',\n metadata: toolData,\n },\n 'web_search_preview',\n )\n}\n"],"mappings":";;;;;;;AAiBA,SAAgB,2CACd,MAC4B;CAK5B,OAAO;EACL,GALe,8BAA8B,IAK1C;EACH,MAAM;CACR;AACF;;;;;;;AAQA,SAAgB,qBACd,UACM;CACN,OAAO,mBACL;EACE,MAAM;EACN,aAAa;EACb,UAAU;CACZ,GACA,oBACF;AACF"}
|
|
@@ -5,10 +5,8 @@ export type { WebSearchToolConfig };
|
|
|
5
5
|
export type WebSearchTool = WebSearchToolConfig;
|
|
6
6
|
/**
|
|
7
7
|
* Converts a standard Tool to OpenAI WebSearchTool format. Spread `metadata`
|
|
8
|
-
* first, then force `type: 'web_search'` last
|
|
9
|
-
*
|
|
10
|
-
* authored by hand with a different `metadata.type` would emit a malformed
|
|
11
|
-
* payload.
|
|
8
|
+
* first, then force `type: 'web_search'` last so a different metadata type
|
|
9
|
+
* cannot produce a malformed payload.
|
|
12
10
|
*/
|
|
13
11
|
export declare function convertWebSearchToolToAdapterFormat(tool: Tool): WebSearchToolConfig;
|
|
14
12
|
/**
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
+
import { getOpenAIProviderToolMetadata, openAIProviderTool } from "./openai-provider-tool.js";
|
|
1
2
|
//#region src/tools/web-search-tool.ts
|
|
2
3
|
/**
|
|
3
4
|
* Converts a standard Tool to OpenAI WebSearchTool format. Spread `metadata`
|
|
4
|
-
* first, then force `type: 'web_search'` last
|
|
5
|
-
*
|
|
6
|
-
* authored by hand with a different `metadata.type` would emit a malformed
|
|
7
|
-
* payload.
|
|
5
|
+
* first, then force `type: 'web_search'` last so a different metadata type
|
|
6
|
+
* cannot produce a malformed payload.
|
|
8
7
|
*/
|
|
9
8
|
function convertWebSearchToolToAdapterFormat(tool) {
|
|
10
9
|
return {
|
|
11
|
-
...tool
|
|
10
|
+
...getOpenAIProviderToolMetadata(tool),
|
|
12
11
|
type: "web_search"
|
|
13
12
|
};
|
|
14
13
|
}
|
|
@@ -19,11 +18,11 @@ function convertWebSearchToolToAdapterFormat(tool) {
|
|
|
19
18
|
* re-wrap this in their own package.
|
|
20
19
|
*/
|
|
21
20
|
function webSearchTool(toolData) {
|
|
22
|
-
return {
|
|
21
|
+
return openAIProviderTool({
|
|
23
22
|
name: "web_search",
|
|
24
23
|
description: "Search the web",
|
|
25
24
|
metadata: toolData
|
|
26
|
-
};
|
|
25
|
+
}, "web_search");
|
|
27
26
|
}
|
|
28
27
|
//#endregion
|
|
29
28
|
export { convertWebSearchToolToAdapterFormat, webSearchTool };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-search-tool.js","names":[],"sources":["../../../src/tools/web-search-tool.ts"],"sourcesContent":["import type { WebSearchTool as WebSearchToolConfig } from 'openai/resources/responses/responses'\nimport type { Tool } from '@tanstack/ai'\n\nexport type { WebSearchToolConfig }\n\n/** @deprecated Renamed to `WebSearchToolConfig`. Will be removed in a future release. */\nexport type WebSearchTool = WebSearchToolConfig\n\n/**\n * Converts a standard Tool to OpenAI WebSearchTool format. Spread `metadata`\n * first, then force `type: 'web_search'` last
|
|
1
|
+
{"version":3,"file":"web-search-tool.js","names":[],"sources":["../../../src/tools/web-search-tool.ts"],"sourcesContent":["import {\n getOpenAIProviderToolMetadata,\n openAIProviderTool,\n} from './openai-provider-tool'\nimport type { WebSearchTool as WebSearchToolConfig } from 'openai/resources/responses/responses'\nimport type { Tool } from '@tanstack/ai'\n\nexport type { WebSearchToolConfig }\n\n/** @deprecated Renamed to `WebSearchToolConfig`. Will be removed in a future release. */\nexport type WebSearchTool = WebSearchToolConfig\n\n/**\n * Converts a standard Tool to OpenAI WebSearchTool format. Spread `metadata`\n * first, then force `type: 'web_search'` last so a different metadata type\n * cannot produce a malformed payload.\n */\nexport function convertWebSearchToolToAdapterFormat(\n tool: Tool,\n): WebSearchToolConfig {\n const metadata = getOpenAIProviderToolMetadata(tool) as Omit<\n WebSearchToolConfig,\n 'type'\n >\n return {\n ...metadata,\n type: 'web_search',\n }\n}\n\n/**\n * Creates a standard Tool from WebSearchTool parameters.\n *\n * Base (non-branded) factory. Providers that need branded return types should\n * re-wrap this in their own package.\n */\nexport function webSearchTool(toolData: WebSearchToolConfig): Tool {\n return openAIProviderTool(\n {\n name: 'web_search',\n description: 'Search the web',\n metadata: toolData,\n },\n 'web_search',\n )\n}\n"],"mappings":";;;;;;;AAiBA,SAAgB,oCACd,MACqB;CAKrB,OAAO;EACL,GALe,8BAA8B,IAK1C;EACH,MAAM;CACR;AACF;;;;;;;AAQA,SAAgB,cAAc,UAAqC;CACjE,OAAO,mBACL;EACE,MAAM;EACN,aAAa;EACb,UAAU;CACZ,GACA,YACF;AACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/openai-base",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.15",
|
|
4
4
|
"description": "Shared OpenAI SDK base adapters for TanStack AI providers using Chat Completions and Responses APIs.",
|
|
5
5
|
"author": "Tanner Linsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -47,13 +47,13 @@
|
|
|
47
47
|
"@tanstack/ai-utils": "^0.4.0"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
|
-
"@tanstack/ai": "^0.
|
|
50
|
+
"@tanstack/ai": "^0.46.0"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@vitest/coverage-v8": "4.1.10",
|
|
54
54
|
"vite": "^8.2.1",
|
|
55
55
|
"zod": "^4.2.0",
|
|
56
|
-
"@tanstack/ai": "0.
|
|
56
|
+
"@tanstack/ai": "0.46.0"
|
|
57
57
|
},
|
|
58
58
|
"scripts": {
|
|
59
59
|
"build": "vite build",
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { openAIProviderTool } from './openai-provider-tool'
|
|
1
2
|
import type { ApplyPatchTool as ApplyPatchToolConfig } from 'openai/resources/responses/responses'
|
|
2
3
|
import type { Tool } from '@tanstack/ai'
|
|
3
4
|
|
|
@@ -24,9 +25,12 @@ export function convertApplyPatchToolToAdapterFormat(
|
|
|
24
25
|
* re-wrap this in their own package.
|
|
25
26
|
*/
|
|
26
27
|
export function applyPatchTool(): Tool {
|
|
27
|
-
return
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
return openAIProviderTool(
|
|
29
|
+
{
|
|
30
|
+
name: 'apply_patch',
|
|
31
|
+
description: 'Apply a patch to modify files',
|
|
32
|
+
metadata: {},
|
|
33
|
+
},
|
|
34
|
+
'apply_patch',
|
|
35
|
+
)
|
|
32
36
|
}
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getOpenAIProviderToolMetadata,
|
|
3
|
+
openAIProviderTool,
|
|
4
|
+
} from './openai-provider-tool'
|
|
1
5
|
import type { Tool as SDKTool } from 'openai/resources/responses/responses'
|
|
2
6
|
import type { Tool } from '@tanstack/ai'
|
|
3
7
|
|
|
@@ -14,7 +18,9 @@ export type CodeInterpreterTool = CodeInterpreterToolConfig
|
|
|
14
18
|
export function convertCodeInterpreterToolToAdapterFormat(
|
|
15
19
|
tool: Tool,
|
|
16
20
|
): CodeInterpreterToolConfig {
|
|
17
|
-
const metadata =
|
|
21
|
+
const metadata = getOpenAIProviderToolMetadata(
|
|
22
|
+
tool,
|
|
23
|
+
) as CodeInterpreterToolConfig
|
|
18
24
|
return {
|
|
19
25
|
type: 'code_interpreter',
|
|
20
26
|
container: metadata.container,
|
|
@@ -30,12 +36,15 @@ export function convertCodeInterpreterToolToAdapterFormat(
|
|
|
30
36
|
export function codeInterpreterTool(
|
|
31
37
|
container: CodeInterpreterToolConfig,
|
|
32
38
|
): Tool {
|
|
33
|
-
return
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
+
return openAIProviderTool(
|
|
40
|
+
{
|
|
41
|
+
name: 'code_interpreter',
|
|
42
|
+
description: 'Execute code in a sandboxed environment',
|
|
43
|
+
metadata: {
|
|
44
|
+
type: 'code_interpreter',
|
|
45
|
+
container,
|
|
46
|
+
},
|
|
39
47
|
},
|
|
40
|
-
|
|
48
|
+
'code_interpreter',
|
|
49
|
+
)
|
|
41
50
|
}
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getOpenAIProviderToolMetadata,
|
|
3
|
+
openAIProviderTool,
|
|
4
|
+
} from './openai-provider-tool'
|
|
1
5
|
import type { ComputerUsePreviewTool as ComputerUseToolConfig } from 'openai/resources/responses/responses'
|
|
2
6
|
import type { Tool } from '@tanstack/ai'
|
|
3
7
|
|
|
@@ -12,7 +16,7 @@ export type ComputerUseTool = ComputerUseToolConfig
|
|
|
12
16
|
export function convertComputerUseToolToAdapterFormat(
|
|
13
17
|
tool: Tool,
|
|
14
18
|
): ComputerUseToolConfig {
|
|
15
|
-
const metadata = tool
|
|
19
|
+
const metadata = getOpenAIProviderToolMetadata(tool) as ComputerUseToolConfig
|
|
16
20
|
return {
|
|
17
21
|
type: 'computer_use_preview',
|
|
18
22
|
display_height: metadata.display_height,
|
|
@@ -28,11 +32,14 @@ export function convertComputerUseToolToAdapterFormat(
|
|
|
28
32
|
* re-wrap this in their own package.
|
|
29
33
|
*/
|
|
30
34
|
export function computerUseTool(toolData: ComputerUseToolConfig): Tool {
|
|
31
|
-
return
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
return openAIProviderTool(
|
|
36
|
+
{
|
|
37
|
+
name: 'computer_use_preview',
|
|
38
|
+
description: 'Control a virtual computer',
|
|
39
|
+
metadata: {
|
|
40
|
+
...toolData,
|
|
41
|
+
},
|
|
36
42
|
},
|
|
37
|
-
|
|
43
|
+
'computer_use',
|
|
44
|
+
)
|
|
38
45
|
}
|
package/src/tools/custom-tool.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getOpenAIProviderToolMetadata,
|
|
3
|
+
openAIProviderTool,
|
|
4
|
+
} from './openai-provider-tool'
|
|
1
5
|
import type { CustomTool as CustomToolConfig } from 'openai/resources/responses/responses'
|
|
2
6
|
import type { Tool } from '@tanstack/ai'
|
|
3
7
|
|
|
@@ -10,7 +14,7 @@ export type CustomTool = CustomToolConfig
|
|
|
10
14
|
* Converts a standard Tool to OpenAI CustomTool format
|
|
11
15
|
*/
|
|
12
16
|
export function convertCustomToolToAdapterFormat(tool: Tool): CustomToolConfig {
|
|
13
|
-
const metadata = tool
|
|
17
|
+
const metadata = getOpenAIProviderToolMetadata(tool) as CustomToolConfig
|
|
14
18
|
// Conditional spread: the SDK's `CustomToolConfig` declares optional
|
|
15
19
|
// fields as `description?: string` (no `| undefined`) under
|
|
16
20
|
// exactOptionalPropertyTypes, so we omit absent fields rather than
|
|
@@ -29,11 +33,14 @@ export function convertCustomToolToAdapterFormat(tool: Tool): CustomToolConfig {
|
|
|
29
33
|
* Creates a standard Tool from CustomTool parameters.
|
|
30
34
|
*/
|
|
31
35
|
export function customTool(toolData: CustomToolConfig): Tool {
|
|
32
|
-
return
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
return openAIProviderTool(
|
|
37
|
+
{
|
|
38
|
+
name: 'custom',
|
|
39
|
+
description: toolData.description || 'A custom tool',
|
|
40
|
+
metadata: {
|
|
41
|
+
...toolData,
|
|
42
|
+
},
|
|
37
43
|
},
|
|
38
|
-
|
|
44
|
+
'custom',
|
|
45
|
+
)
|
|
39
46
|
}
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getOpenAIProviderToolMetadata,
|
|
3
|
+
openAIProviderTool,
|
|
4
|
+
} from './openai-provider-tool'
|
|
1
5
|
import type { FileSearchTool as FileSearchToolConfig } from 'openai/resources/responses/responses'
|
|
2
6
|
import type { Tool } from '@tanstack/ai'
|
|
3
7
|
|
|
@@ -21,7 +25,7 @@ export type FileSearchTool = FileSearchToolConfig
|
|
|
21
25
|
export function convertFileSearchToolToAdapterFormat(
|
|
22
26
|
tool: Tool,
|
|
23
27
|
): FileSearchToolConfig {
|
|
24
|
-
const metadata = tool
|
|
28
|
+
const metadata = getOpenAIProviderToolMetadata(tool) as FileSearchToolConfig
|
|
25
29
|
// Conditional spread: SDK's `FileSearchToolConfig` declares the
|
|
26
30
|
// optional fields without `| undefined`, so we omit absent values
|
|
27
31
|
// rather than passing them through as explicit `undefined`.
|
|
@@ -46,13 +50,16 @@ export function convertFileSearchToolToAdapterFormat(
|
|
|
46
50
|
*/
|
|
47
51
|
export function fileSearchTool(toolData: FileSearchToolConfig): Tool {
|
|
48
52
|
validateMaxNumResults(toolData.max_num_results)
|
|
49
|
-
return
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
53
|
+
return openAIProviderTool(
|
|
54
|
+
{
|
|
55
|
+
name: 'file_search',
|
|
56
|
+
description: 'Search files in vector stores',
|
|
57
|
+
metadata: {
|
|
58
|
+
...toolData,
|
|
59
|
+
},
|
|
54
60
|
},
|
|
55
|
-
|
|
61
|
+
'file_search',
|
|
62
|
+
)
|
|
56
63
|
}
|
|
57
64
|
|
|
58
65
|
export { validateMaxNumResults }
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getOpenAIProviderToolMetadata,
|
|
3
|
+
openAIProviderTool,
|
|
4
|
+
} from './openai-provider-tool'
|
|
1
5
|
import type { Tool as SDKTool } from 'openai/resources/responses/responses'
|
|
2
6
|
import type { Tool } from '@tanstack/ai'
|
|
3
7
|
|
|
@@ -16,15 +20,16 @@ const validatePartialImages = (value: number | undefined) => {
|
|
|
16
20
|
|
|
17
21
|
/**
|
|
18
22
|
* Converts a standard Tool to OpenAI ImageGenerationTool format. Spread
|
|
19
|
-
* `metadata` first, then force `type: 'image_generation'` last
|
|
20
|
-
* `metadata.type`
|
|
21
|
-
* the dispatcher (which routed by `tool.name`) would emit a tool whose
|
|
22
|
-
* runtime `type` doesn't match `image_generation`.
|
|
23
|
+
* `metadata` first, then force `type: 'image_generation'` last so a stray
|
|
24
|
+
* `metadata.type` cannot shadow the wire discriminator.
|
|
23
25
|
*/
|
|
24
26
|
export function convertImageGenerationToolToAdapterFormat(
|
|
25
27
|
tool: Tool,
|
|
26
28
|
): ImageGenerationToolConfig {
|
|
27
|
-
const metadata = tool
|
|
29
|
+
const metadata = getOpenAIProviderToolMetadata(tool) as Omit<
|
|
30
|
+
ImageGenerationToolConfig,
|
|
31
|
+
'type'
|
|
32
|
+
>
|
|
28
33
|
return {
|
|
29
34
|
...metadata,
|
|
30
35
|
type: 'image_generation',
|
|
@@ -41,13 +46,16 @@ export function imageGenerationTool(
|
|
|
41
46
|
toolData: Omit<ImageGenerationToolConfig, 'type'>,
|
|
42
47
|
): Tool {
|
|
43
48
|
validatePartialImages(toolData.partial_images)
|
|
44
|
-
return
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
return openAIProviderTool(
|
|
50
|
+
{
|
|
51
|
+
name: 'image_generation',
|
|
52
|
+
description: 'Generate images based on text descriptions',
|
|
53
|
+
metadata: {
|
|
54
|
+
...toolData,
|
|
55
|
+
},
|
|
49
56
|
},
|
|
50
|
-
|
|
57
|
+
'image_generation',
|
|
58
|
+
)
|
|
51
59
|
}
|
|
52
60
|
|
|
53
61
|
export { validatePartialImages }
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { openAIProviderTool } from './openai-provider-tool'
|
|
1
2
|
import type { Tool as SDKTool } from 'openai/resources/responses/responses'
|
|
2
3
|
import type { Tool } from '@tanstack/ai'
|
|
3
4
|
|
|
@@ -26,9 +27,12 @@ export function convertLocalShellToolToAdapterFormat(
|
|
|
26
27
|
* re-wrap this in their own package.
|
|
27
28
|
*/
|
|
28
29
|
export function localShellTool(): Tool {
|
|
29
|
-
return
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
return openAIProviderTool(
|
|
31
|
+
{
|
|
32
|
+
name: 'local_shell',
|
|
33
|
+
description: 'Execute local shell commands',
|
|
34
|
+
metadata: {},
|
|
35
|
+
},
|
|
36
|
+
'local_shell',
|
|
37
|
+
)
|
|
34
38
|
}
|
package/src/tools/mcp-tool.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getOpenAIProviderToolMetadata,
|
|
3
|
+
openAIProviderTool,
|
|
4
|
+
} from './openai-provider-tool'
|
|
1
5
|
import type { Tool as SDKTool } from 'openai/resources/responses/responses'
|
|
2
6
|
import type { Tool } from '@tanstack/ai'
|
|
3
7
|
|
|
@@ -21,15 +25,18 @@ export function validateMCPtool(tool: MCPToolConfig) {
|
|
|
21
25
|
* Converts a standard Tool to OpenAI MCPTool format
|
|
22
26
|
*/
|
|
23
27
|
export function convertMCPToolToAdapterFormat(tool: Tool): MCPToolConfig {
|
|
24
|
-
const metadata = tool
|
|
28
|
+
const metadata = getOpenAIProviderToolMetadata(tool) as Omit<
|
|
29
|
+
MCPToolConfig,
|
|
30
|
+
'type'
|
|
31
|
+
>
|
|
25
32
|
|
|
26
|
-
const
|
|
33
|
+
const convertedTool: MCPToolConfig = {
|
|
27
34
|
...metadata,
|
|
28
35
|
type: 'mcp',
|
|
29
36
|
}
|
|
30
37
|
|
|
31
|
-
validateMCPtool(
|
|
32
|
-
return
|
|
38
|
+
validateMCPtool(convertedTool)
|
|
39
|
+
return convertedTool
|
|
33
40
|
}
|
|
34
41
|
|
|
35
42
|
/**
|
|
@@ -41,9 +48,12 @@ export function convertMCPToolToAdapterFormat(tool: Tool): MCPToolConfig {
|
|
|
41
48
|
export function mcpTool(toolData: Omit<MCPToolConfig, 'type'>): Tool {
|
|
42
49
|
validateMCPtool({ ...toolData, type: 'mcp' })
|
|
43
50
|
|
|
44
|
-
return
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
51
|
+
return openAIProviderTool(
|
|
52
|
+
{
|
|
53
|
+
name: 'mcp',
|
|
54
|
+
description: toolData.server_description || '',
|
|
55
|
+
metadata: toolData,
|
|
56
|
+
},
|
|
57
|
+
'mcp',
|
|
58
|
+
)
|
|
49
59
|
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { Tool } from '@tanstack/ai'
|
|
2
|
+
|
|
3
|
+
const OPENAI_PROVIDER_TOOL_KINDS = {
|
|
4
|
+
apply_patch: 'openai.apply_patch',
|
|
5
|
+
code_interpreter: 'openai.code_interpreter',
|
|
6
|
+
computer_use: 'openai.computer_use',
|
|
7
|
+
custom: 'openai.custom',
|
|
8
|
+
file_search: 'openai.file_search',
|
|
9
|
+
image_generation: 'openai.image_generation',
|
|
10
|
+
local_shell: 'openai.local_shell',
|
|
11
|
+
mcp: 'openai.mcp',
|
|
12
|
+
shell: 'openai.shell',
|
|
13
|
+
web_search: 'openai.web_search',
|
|
14
|
+
web_search_preview: 'openai.web_search_preview',
|
|
15
|
+
} as const
|
|
16
|
+
|
|
17
|
+
export type OpenAIProviderToolKind = keyof typeof OPENAI_PROVIDER_TOOL_KINDS
|
|
18
|
+
|
|
19
|
+
export function openAIProviderTool(
|
|
20
|
+
tool: Tool,
|
|
21
|
+
toolKind: OpenAIProviderToolKind,
|
|
22
|
+
): Tool {
|
|
23
|
+
return {
|
|
24
|
+
...tool,
|
|
25
|
+
metadata: {
|
|
26
|
+
...tool.metadata,
|
|
27
|
+
__kind: OPENAI_PROVIDER_TOOL_KINDS[toolKind],
|
|
28
|
+
},
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function getOpenAIProviderToolKind(
|
|
33
|
+
tool: Tool,
|
|
34
|
+
): OpenAIProviderToolKind | undefined {
|
|
35
|
+
const toolKind = tool.metadata?.['__kind']
|
|
36
|
+
switch (toolKind) {
|
|
37
|
+
case 'openai.apply_patch':
|
|
38
|
+
return 'apply_patch'
|
|
39
|
+
case 'openai.code_interpreter':
|
|
40
|
+
return 'code_interpreter'
|
|
41
|
+
case 'openai.computer_use':
|
|
42
|
+
return 'computer_use'
|
|
43
|
+
case 'openai.custom':
|
|
44
|
+
return 'custom'
|
|
45
|
+
case 'openai.file_search':
|
|
46
|
+
return 'file_search'
|
|
47
|
+
case 'openai.image_generation':
|
|
48
|
+
return 'image_generation'
|
|
49
|
+
case 'openai.local_shell':
|
|
50
|
+
return 'local_shell'
|
|
51
|
+
case 'openai.mcp':
|
|
52
|
+
return 'mcp'
|
|
53
|
+
case 'openai.shell':
|
|
54
|
+
return 'shell'
|
|
55
|
+
case 'openai.web_search':
|
|
56
|
+
return 'web_search'
|
|
57
|
+
case 'openai.web_search_preview':
|
|
58
|
+
return 'web_search_preview'
|
|
59
|
+
default:
|
|
60
|
+
return undefined
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Returns adapter metadata without the internal runtime discriminator. */
|
|
65
|
+
export function getOpenAIProviderToolMetadata(tool: Tool): Tool['metadata'] {
|
|
66
|
+
if (!tool.metadata) {
|
|
67
|
+
return undefined
|
|
68
|
+
}
|
|
69
|
+
const { __kind: _kind, ...metadata } = tool.metadata
|
|
70
|
+
void _kind
|
|
71
|
+
return metadata
|
|
72
|
+
}
|
package/src/tools/shell-tool.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getOpenAIProviderToolMetadata,
|
|
3
|
+
openAIProviderTool,
|
|
4
|
+
} from './openai-provider-tool'
|
|
1
5
|
import type { FunctionShellTool as ShellToolConfig } from 'openai/resources/responses/responses'
|
|
2
6
|
import type { Tool } from '@tanstack/ai'
|
|
3
7
|
|
|
@@ -21,7 +25,8 @@ export interface ShellToolFactoryConfig {
|
|
|
21
25
|
* `environment` (container config + skills) stored in metadata.
|
|
22
26
|
*/
|
|
23
27
|
export function convertShellToolToAdapterFormat(tool: Tool): ShellToolConfig {
|
|
24
|
-
const metadata = (tool
|
|
28
|
+
const metadata = (getOpenAIProviderToolMetadata(tool) ??
|
|
29
|
+
{}) as ShellToolFactoryConfig
|
|
25
30
|
return {
|
|
26
31
|
type: 'shell',
|
|
27
32
|
...(metadata.environment !== undefined && {
|
|
@@ -37,13 +42,16 @@ export function convertShellToolToAdapterFormat(tool: Tool): ShellToolConfig {
|
|
|
37
42
|
* re-wrap this in their own package.
|
|
38
43
|
*/
|
|
39
44
|
export function shellTool(config: ShellToolFactoryConfig = {}): Tool {
|
|
40
|
-
return
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
return openAIProviderTool(
|
|
46
|
+
{
|
|
47
|
+
name: 'shell',
|
|
48
|
+
description: 'Execute shell commands',
|
|
49
|
+
metadata: {
|
|
50
|
+
...(config.environment !== undefined && {
|
|
51
|
+
environment: config.environment,
|
|
52
|
+
}),
|
|
53
|
+
},
|
|
47
54
|
},
|
|
48
|
-
|
|
55
|
+
'shell',
|
|
56
|
+
)
|
|
49
57
|
}
|
|
@@ -7,62 +7,47 @@ import { convertFunctionToolToAdapterFormat } from './function-tool'
|
|
|
7
7
|
import { convertImageGenerationToolToAdapterFormat } from './image-generation-tool'
|
|
8
8
|
import { convertLocalShellToolToAdapterFormat } from './local-shell-tool'
|
|
9
9
|
import { convertMCPToolToAdapterFormat } from './mcp-tool'
|
|
10
|
+
import { getOpenAIProviderToolKind } from './openai-provider-tool'
|
|
10
11
|
import { convertShellToolToAdapterFormat } from './shell-tool'
|
|
11
12
|
import { convertWebSearchPreviewToolToAdapterFormat } from './web-search-preview-tool'
|
|
12
13
|
import { convertWebSearchToolToAdapterFormat } from './web-search-tool'
|
|
13
14
|
import type { OpenAITool } from './index'
|
|
15
|
+
import { assertUniqueToolNames } from '@tanstack/ai/adapter-internals'
|
|
14
16
|
import type { Tool } from '@tanstack/ai'
|
|
15
17
|
|
|
16
|
-
const SPECIAL_TOOL_NAMES = new Set([
|
|
17
|
-
'apply_patch',
|
|
18
|
-
'code_interpreter',
|
|
19
|
-
'computer_use_preview',
|
|
20
|
-
'file_search',
|
|
21
|
-
'image_generation',
|
|
22
|
-
'local_shell',
|
|
23
|
-
'mcp',
|
|
24
|
-
'shell',
|
|
25
|
-
'web_search_preview',
|
|
26
|
-
'web_search',
|
|
27
|
-
'custom',
|
|
28
|
-
])
|
|
29
|
-
|
|
30
18
|
/**
|
|
31
19
|
* Converts an array of standard Tools to OpenAI-specific format
|
|
32
20
|
*/
|
|
33
21
|
export function convertToolsToProviderFormat(
|
|
34
22
|
tools: Array<Tool>,
|
|
35
23
|
): Array<OpenAITool> {
|
|
24
|
+
assertUniqueToolNames(tools)
|
|
36
25
|
return tools.map((tool) => {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
return convertCustomToolToAdapterFormat(tool)
|
|
63
|
-
}
|
|
26
|
+
switch (getOpenAIProviderToolKind(tool)) {
|
|
27
|
+
case 'apply_patch':
|
|
28
|
+
return convertApplyPatchToolToAdapterFormat(tool)
|
|
29
|
+
case 'code_interpreter':
|
|
30
|
+
return convertCodeInterpreterToolToAdapterFormat(tool)
|
|
31
|
+
case 'computer_use':
|
|
32
|
+
return convertComputerUseToolToAdapterFormat(tool)
|
|
33
|
+
case 'custom':
|
|
34
|
+
return convertCustomToolToAdapterFormat(tool)
|
|
35
|
+
case 'file_search':
|
|
36
|
+
return convertFileSearchToolToAdapterFormat(tool)
|
|
37
|
+
case 'image_generation':
|
|
38
|
+
return convertImageGenerationToolToAdapterFormat(tool)
|
|
39
|
+
case 'local_shell':
|
|
40
|
+
return convertLocalShellToolToAdapterFormat(tool)
|
|
41
|
+
case 'mcp':
|
|
42
|
+
return convertMCPToolToAdapterFormat(tool)
|
|
43
|
+
case 'shell':
|
|
44
|
+
return convertShellToolToAdapterFormat(tool)
|
|
45
|
+
case 'web_search_preview':
|
|
46
|
+
return convertWebSearchPreviewToolToAdapterFormat(tool)
|
|
47
|
+
case 'web_search':
|
|
48
|
+
return convertWebSearchToolToAdapterFormat(tool)
|
|
49
|
+
case undefined:
|
|
50
|
+
return convertFunctionToolToAdapterFormat(tool)
|
|
64
51
|
}
|
|
65
|
-
|
|
66
|
-
return convertFunctionToolToAdapterFormat(tool)
|
|
67
52
|
})
|
|
68
53
|
}
|