@tanstack/ai-grok 0.0.1 → 0.3.0
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/LICENSE +21 -0
- package/README.md +113 -28
- package/dist/esm/adapters/image.d.ts +77 -0
- package/dist/esm/adapters/image.js +63 -0
- package/dist/esm/adapters/image.js.map +1 -0
- package/dist/esm/adapters/summarize.d.ts +75 -0
- package/dist/esm/adapters/summarize.js +86 -0
- package/dist/esm/adapters/summarize.js.map +1 -0
- package/dist/esm/adapters/text.d.ts +96 -0
- package/dist/esm/adapters/text.js +371 -0
- package/dist/esm/adapters/text.js.map +1 -0
- package/dist/esm/image/image-provider-options.d.ts +66 -0
- package/dist/esm/image/image-provider-options.js +39 -0
- package/dist/esm/image/image-provider-options.js.map +1 -0
- package/dist/esm/index.d.ts +7 -0
- package/dist/esm/index.js +18 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/message-types.d.ts +64 -0
- package/dist/esm/model-meta.d.ts +223 -0
- package/dist/esm/model-meta.js +47 -0
- package/dist/esm/model-meta.js.map +1 -0
- package/dist/esm/text/text-provider-options.d.ts +66 -0
- package/dist/esm/text/text-provider-options.js +6 -0
- package/dist/esm/text/text-provider-options.js.map +1 -0
- package/dist/esm/tools/function-tool.d.ts +15 -0
- package/dist/esm/tools/function-tool.js +27 -0
- package/dist/esm/tools/function-tool.js.map +1 -0
- package/dist/esm/tools/index.d.ts +2 -0
- package/dist/esm/tools/tool-converter.d.ts +7 -0
- package/dist/esm/tools/tool-converter.js +10 -0
- package/dist/esm/tools/tool-converter.js.map +1 -0
- package/dist/esm/utils/client.d.ts +18 -0
- package/dist/esm/utils/client.js +26 -0
- package/dist/esm/utils/client.js.map +1 -0
- package/dist/esm/utils/index.d.ts +2 -0
- package/dist/esm/utils/schema-converter.d.ts +24 -0
- package/dist/esm/utils/schema-converter.js +71 -0
- package/dist/esm/utils/schema-converter.js.map +1 -0
- package/package.json +50 -7
- package/src/adapters/image.ts +176 -0
- package/src/adapters/summarize.ts +181 -0
- package/src/adapters/text.ts +612 -0
- package/src/image/image-provider-options.ts +118 -0
- package/src/index.ts +55 -0
- package/src/message-types.ts +67 -0
- package/src/model-meta.ts +298 -0
- package/src/text/text-provider-options.ts +77 -0
- package/src/tools/function-tool.ts +45 -0
- package/src/tools/index.ts +5 -0
- package/src/tools/tool-converter.ts +17 -0
- package/src/utils/client.ts +45 -0
- package/src/utils/index.ts +10 -0
- package/src/utils/schema-converter.ts +110 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import OpenAI_SDK from 'openai'
|
|
2
|
+
|
|
3
|
+
export interface GrokClientConfig {
|
|
4
|
+
apiKey: string
|
|
5
|
+
baseURL?: string
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Creates a Grok SDK client instance using OpenAI SDK with xAI's base URL
|
|
10
|
+
*/
|
|
11
|
+
export function createGrokClient(config: GrokClientConfig): OpenAI_SDK {
|
|
12
|
+
return new OpenAI_SDK({
|
|
13
|
+
apiKey: config.apiKey,
|
|
14
|
+
baseURL: config.baseURL || 'https://api.x.ai/v1',
|
|
15
|
+
})
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Gets Grok API key from environment variables
|
|
20
|
+
* @throws Error if XAI_API_KEY is not found
|
|
21
|
+
*/
|
|
22
|
+
export function getGrokApiKeyFromEnv(): string {
|
|
23
|
+
const env =
|
|
24
|
+
typeof globalThis !== 'undefined' && (globalThis as any).window?.env
|
|
25
|
+
? (globalThis as any).window.env
|
|
26
|
+
: typeof process !== 'undefined'
|
|
27
|
+
? process.env
|
|
28
|
+
: undefined
|
|
29
|
+
const key = env?.XAI_API_KEY
|
|
30
|
+
|
|
31
|
+
if (!key) {
|
|
32
|
+
throw new Error(
|
|
33
|
+
'XAI_API_KEY is required. Please set it in your environment variables or use the factory function with an explicit API key.',
|
|
34
|
+
)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return key
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Generates a unique ID with a prefix
|
|
42
|
+
*/
|
|
43
|
+
export function generateId(prefix: string): string {
|
|
44
|
+
return `${prefix}-${Date.now()}-${Math.random().toString(36).substring(7)}`
|
|
45
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recursively transform null values to undefined in an object.
|
|
3
|
+
*
|
|
4
|
+
* This is needed because Grok's structured output (via OpenAI-compatible API) requires all fields to be
|
|
5
|
+
* in the `required` array, with optional fields made nullable (type: ["string", "null"]).
|
|
6
|
+
* When Grok returns null for optional fields, we need to convert them back to
|
|
7
|
+
* undefined to match the original Zod schema expectations.
|
|
8
|
+
*
|
|
9
|
+
* @param obj - Object to transform
|
|
10
|
+
* @returns Object with nulls converted to undefined
|
|
11
|
+
*/
|
|
12
|
+
export function transformNullsToUndefined<T>(obj: T): T {
|
|
13
|
+
if (obj === null) {
|
|
14
|
+
return undefined as unknown as T
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (Array.isArray(obj)) {
|
|
18
|
+
return obj.map((item) => transformNullsToUndefined(item)) as unknown as T
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (typeof obj === 'object') {
|
|
22
|
+
const result: Record<string, unknown> = {}
|
|
23
|
+
for (const [key, value] of Object.entries(obj as Record<string, unknown>)) {
|
|
24
|
+
const transformed = transformNullsToUndefined(value)
|
|
25
|
+
// Only include the key if the value is not undefined
|
|
26
|
+
// This makes { notes: null } become {} (field absent) instead of { notes: undefined }
|
|
27
|
+
if (transformed !== undefined) {
|
|
28
|
+
result[key] = transformed
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return result as T
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return obj
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Transform a JSON schema to be compatible with Grok's structured output requirements (OpenAI-compatible).
|
|
39
|
+
* Grok requires:
|
|
40
|
+
* - All properties must be in the `required` array
|
|
41
|
+
* - Optional fields should have null added to their type union
|
|
42
|
+
* - additionalProperties must be false for objects
|
|
43
|
+
*
|
|
44
|
+
* @param schema - JSON schema to transform
|
|
45
|
+
* @param originalRequired - Original required array (to know which fields were optional)
|
|
46
|
+
* @returns Transformed schema compatible with Grok structured output
|
|
47
|
+
*/
|
|
48
|
+
export function makeGrokStructuredOutputCompatible(
|
|
49
|
+
schema: Record<string, any>,
|
|
50
|
+
originalRequired: Array<string> = [],
|
|
51
|
+
): Record<string, any> {
|
|
52
|
+
const result = { ...schema }
|
|
53
|
+
|
|
54
|
+
// Handle object types
|
|
55
|
+
if (result.type === 'object' && result.properties) {
|
|
56
|
+
const properties = { ...result.properties }
|
|
57
|
+
const allPropertyNames = Object.keys(properties)
|
|
58
|
+
|
|
59
|
+
// Transform each property
|
|
60
|
+
for (const propName of allPropertyNames) {
|
|
61
|
+
const prop = properties[propName]
|
|
62
|
+
const wasOptional = !originalRequired.includes(propName)
|
|
63
|
+
|
|
64
|
+
// Recursively transform nested objects/arrays
|
|
65
|
+
if (prop.type === 'object' && prop.properties) {
|
|
66
|
+
properties[propName] = makeGrokStructuredOutputCompatible(
|
|
67
|
+
prop,
|
|
68
|
+
prop.required || [],
|
|
69
|
+
)
|
|
70
|
+
} else if (prop.type === 'array' && prop.items) {
|
|
71
|
+
properties[propName] = {
|
|
72
|
+
...prop,
|
|
73
|
+
items: makeGrokStructuredOutputCompatible(
|
|
74
|
+
prop.items,
|
|
75
|
+
prop.items.required || [],
|
|
76
|
+
),
|
|
77
|
+
}
|
|
78
|
+
} else if (wasOptional) {
|
|
79
|
+
// Make optional fields nullable by adding null to the type
|
|
80
|
+
if (prop.type && !Array.isArray(prop.type)) {
|
|
81
|
+
properties[propName] = {
|
|
82
|
+
...prop,
|
|
83
|
+
type: [prop.type, 'null'],
|
|
84
|
+
}
|
|
85
|
+
} else if (Array.isArray(prop.type) && !prop.type.includes('null')) {
|
|
86
|
+
properties[propName] = {
|
|
87
|
+
...prop,
|
|
88
|
+
type: [...prop.type, 'null'],
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
result.properties = properties
|
|
95
|
+
// ALL properties must be required for Grok structured output
|
|
96
|
+
result.required = allPropertyNames
|
|
97
|
+
// additionalProperties must be false
|
|
98
|
+
result.additionalProperties = false
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Handle array types with object items
|
|
102
|
+
if (result.type === 'array' && result.items) {
|
|
103
|
+
result.items = makeGrokStructuredOutputCompatible(
|
|
104
|
+
result.items,
|
|
105
|
+
result.items.required || [],
|
|
106
|
+
)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return result
|
|
110
|
+
}
|