@gullabs/xai 0.6.0 → 0.7.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/README.md +66 -1
- package/dist/index.cjs +10 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +10 -2
- package/dist/index.js.map +1 -1
- package/package.json +10 -10
package/README.md
CHANGED
|
@@ -58,6 +58,71 @@ const result = await client.generate(
|
|
|
58
58
|
)
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
+
### Function-calling seam (no agent loop)
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
const tools = [
|
|
65
|
+
{
|
|
66
|
+
name: 'get_temperature',
|
|
67
|
+
description: 'Get current temperature for a location',
|
|
68
|
+
inputJsonSchema: {
|
|
69
|
+
type: 'object',
|
|
70
|
+
properties: { location: { type: 'string' } },
|
|
71
|
+
required: ['location'],
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
]
|
|
75
|
+
|
|
76
|
+
const first = await client.generate(
|
|
77
|
+
{
|
|
78
|
+
provider: 'xai',
|
|
79
|
+
model: 'grok-4.6',
|
|
80
|
+
messages: [{ role: 'user', parts: [{ kind: 'text', text: 'Temperature in SF?' }] }],
|
|
81
|
+
tools,
|
|
82
|
+
toolChoice: 'required',
|
|
83
|
+
},
|
|
84
|
+
{ auth: { apiKey: 'YOUR_XAI_API_KEY' } },
|
|
85
|
+
)
|
|
86
|
+
// first.finishReason === 'tool_calls'
|
|
87
|
+
// first.toolCalls === [{ toolCallId, toolName, args }]
|
|
88
|
+
|
|
89
|
+
const call = first.toolCalls![0]!
|
|
90
|
+
const replay = await client.generate(
|
|
91
|
+
{
|
|
92
|
+
provider: 'xai',
|
|
93
|
+
model: 'grok-4.6',
|
|
94
|
+
messages: [
|
|
95
|
+
{ role: 'user', parts: [{ kind: 'text', text: 'Temperature in SF?' }] },
|
|
96
|
+
{
|
|
97
|
+
role: 'assistant',
|
|
98
|
+
parts: [
|
|
99
|
+
{
|
|
100
|
+
kind: 'tool-call',
|
|
101
|
+
toolCallId: call.toolCallId,
|
|
102
|
+
toolName: call.toolName,
|
|
103
|
+
args: call.args,
|
|
104
|
+
},
|
|
105
|
+
],
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
role: 'user',
|
|
109
|
+
parts: [
|
|
110
|
+
{
|
|
111
|
+
kind: 'tool-result',
|
|
112
|
+
toolCallId: call.toolCallId,
|
|
113
|
+
toolName: call.toolName,
|
|
114
|
+
result: { temperature: 59 },
|
|
115
|
+
},
|
|
116
|
+
],
|
|
117
|
+
},
|
|
118
|
+
],
|
|
119
|
+
tools,
|
|
120
|
+
},
|
|
121
|
+
{ auth: { apiKey: 'YOUR_XAI_API_KEY' } },
|
|
122
|
+
)
|
|
123
|
+
// replay.text — model answer after the host dispatched the tool
|
|
124
|
+
```
|
|
125
|
+
|
|
61
126
|
## grok-4.5 and grok-4.6
|
|
62
127
|
|
|
63
128
|
The default registry ships two canonical models (500k token context window each). They route through this adapter and support:
|
|
@@ -116,7 +181,7 @@ try {
|
|
|
116
181
|
| ZDR teams | New uploads and `file_id` attachments are blocked by xAI; errors mention Zero Data Retention when detectable |
|
|
117
182
|
| Max size | 48 MiB (conservative vs docs 48–50 MB) |
|
|
118
183
|
|
|
119
|
-
**Billing note:** attaching files on Responses implicitly enables xAI's `attachment_search` agentic tool.
|
|
184
|
+
**Billing note:** attaching files on Responses implicitly enables xAI's `attachment_search` agentic tool. Live 2026-08-24 pins `web_search_calls` and `x_search_calls` in `usage.server_side_tool_usage_details` (flattened into `usage.details`). The attachment_search counter is **not** live-pinned (ZDR blocks file attach on this key); a `file-ref` call sets synthetic `usage.details.attachment_search_unpinned = 1` and `Cost.confidence: 'estimated'` — it is never reported as exact `$0`. `server_tools_requested = 1` is adapter-owned. Missing expected web/X counters → `tools: 0`, `estimated`, plus an adapter warning.
|
|
120
185
|
|
|
121
186
|
**Host tests:** `@gullabs/testing` exports `FakeXaiFileStore` (in-memory upload/get/delete with optional TTL clock and `failClosed`).
|
|
122
187
|
|
package/dist/index.cjs
CHANGED
|
@@ -558,6 +558,13 @@ function xaiAdapter(opts) {
|
|
|
558
558
|
)}]; tool cost will be estimated.`
|
|
559
559
|
});
|
|
560
560
|
}
|
|
561
|
+
if (hasFileRef) {
|
|
562
|
+
usage.details["attachment_search_unpinned"] = 1;
|
|
563
|
+
warnings.push({
|
|
564
|
+
type: "other",
|
|
565
|
+
message: "xai: file-ref enables attachment_search but that counter is not live-pinned; tool cost is estimated."
|
|
566
|
+
});
|
|
567
|
+
}
|
|
561
568
|
}
|
|
562
569
|
const citations = collectXaiCitations(response, messageItems);
|
|
563
570
|
const providerMeta = {};
|
|
@@ -1494,7 +1501,8 @@ function computeXaiCost(model, usage, tier) {
|
|
|
1494
1501
|
usage.outputTokens * base.outputPerM * factor / 1e6
|
|
1495
1502
|
);
|
|
1496
1503
|
const serverToolsRequested = usage.details["server_tools_requested"] === 1;
|
|
1497
|
-
const missingRequestedCounters = usage.details["server_tools_missing"] === 1 || serverToolsRequested && !XAI_TOOL_COUNTER_KEYS.some((key) => key in usage.details);
|
|
1504
|
+
const missingRequestedCounters = usage.details["server_tools_missing"] === 1 || serverToolsRequested && usage.details["attachment_search_unpinned"] !== 1 && !XAI_TOOL_COUNTER_KEYS.some((key) => key in usage.details);
|
|
1505
|
+
const attachmentUnpinned = usage.details["attachment_search_unpinned"] === 1;
|
|
1498
1506
|
const toolsCost = missingRequestedCounters ? 0 : XAI_TOOL_COUNTER_KEYS.reduce((sum, key) => {
|
|
1499
1507
|
const count = usage.details[key];
|
|
1500
1508
|
if (typeof count !== "number" || count <= 0) return sum;
|
|
@@ -1505,7 +1513,7 @@ function computeXaiCost(model, usage, tier) {
|
|
|
1505
1513
|
microUsd,
|
|
1506
1514
|
usd: microUsd / 1e6,
|
|
1507
1515
|
pricingVersion: xaiPricingVersion,
|
|
1508
|
-
confidence: missingRequestedCounters ? "estimated" : "exact",
|
|
1516
|
+
confidence: missingRequestedCounters || attachmentUnpinned ? "estimated" : "exact",
|
|
1509
1517
|
details: {
|
|
1510
1518
|
input: inputCost,
|
|
1511
1519
|
cached: cachedCost,
|