smoltalk 0.5.0 → 0.5.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.
|
@@ -56,7 +56,7 @@ export class BaseClient {
|
|
|
56
56
|
const messageLimitResult = this.checkMessageLimit(promptConfig);
|
|
57
57
|
if (messageLimitResult)
|
|
58
58
|
return messageLimitResult;
|
|
59
|
-
const hostedError = validateHostedTools(promptConfig.hostedTools, promptConfig.model, promptConfig.modelData);
|
|
59
|
+
const hostedError = validateHostedTools(promptConfig.hostedTools, promptConfig.model, promptConfig.provider, promptConfig.modelData);
|
|
60
60
|
if (hostedError) {
|
|
61
61
|
return failure(hostedError);
|
|
62
62
|
}
|
|
@@ -269,7 +269,7 @@ export class BaseClient {
|
|
|
269
269
|
};
|
|
270
270
|
return;
|
|
271
271
|
}
|
|
272
|
-
const hostedError = validateHostedTools(config.hostedTools, config.model, config.modelData);
|
|
272
|
+
const hostedError = validateHostedTools(config.hostedTools, config.model, config.provider, config.modelData);
|
|
273
273
|
if (hostedError) {
|
|
274
274
|
yield { type: "error", error: hostedError };
|
|
275
275
|
return;
|
package/dist/models.js
CHANGED
|
@@ -1600,9 +1600,16 @@ export function getHostedTools(opts = {}) {
|
|
|
1600
1600
|
if (opts.modelData) {
|
|
1601
1601
|
tools = mergeHostedTools(tools, opts.modelData.hostedTools);
|
|
1602
1602
|
}
|
|
1603
|
+
// A provider override is authoritative: it decides which API the model routes
|
|
1604
|
+
// through, and therefore which hosted tools are available for it.
|
|
1603
1605
|
let modelProvider;
|
|
1604
1606
|
if (opts.model) {
|
|
1605
|
-
|
|
1607
|
+
if (opts.provider) {
|
|
1608
|
+
modelProvider = opts.provider;
|
|
1609
|
+
}
|
|
1610
|
+
else {
|
|
1611
|
+
modelProvider = getModel(opts.model, opts.modelData)?.provider;
|
|
1612
|
+
}
|
|
1606
1613
|
}
|
|
1607
1614
|
return tools.filter((tool) => {
|
|
1608
1615
|
if (tool.disabled && !opts.includeDisabled) {
|
|
@@ -3,7 +3,7 @@ import type { CostEstimate } from "../types/costEstimate.js";
|
|
|
3
3
|
import type { HostedToolResult, WebSearchSource, WebSearchCitation } from "../types.js";
|
|
4
4
|
export declare const WEB_SEARCH = "web_search";
|
|
5
5
|
export declare const IMPLEMENTED_HOSTED_TOOLS: Set<string>;
|
|
6
|
-
export declare function validateHostedTools(requested: string[] | undefined, model: string, modelData?: ModelDataBlob): string | null;
|
|
6
|
+
export declare function validateHostedTools(requested: string[] | undefined, model: string, provider?: string, modelData?: ModelDataBlob): string | null;
|
|
7
7
|
export declare function estimateHostedToolCost(result: HostedToolResult, model: string, modelData?: ModelDataBlob): number | undefined;
|
|
8
8
|
export declare function foldHostedToolCost(cost: CostEstimate | undefined, results: HostedToolResult[]): CostEstimate | undefined;
|
|
9
9
|
export declare function webSearchResult(provider: string, parts: {
|
package/dist/util/hostedTools.js
CHANGED
|
@@ -6,12 +6,15 @@ export const WEB_SEARCH = "web_search";
|
|
|
6
6
|
export const IMPLEMENTED_HOSTED_TOOLS = new Set([WEB_SEARCH]);
|
|
7
7
|
// Returns an error message if any requested capability is unusable for this
|
|
8
8
|
// model, else null. Capabilities are matched against the catalog `category`.
|
|
9
|
-
|
|
9
|
+
// A `provider` override is authoritative: the same model can route through a
|
|
10
|
+
// different API (e.g. gpt-4o-mini via "openai-responses"), which changes which
|
|
11
|
+
// hosted tools are available.
|
|
12
|
+
export function validateHostedTools(requested, model, provider, modelData) {
|
|
10
13
|
if (!requested || requested.length === 0) {
|
|
11
14
|
return null;
|
|
12
15
|
}
|
|
13
16
|
const allCategories = new Set(getHostedTools({ includeDisabled: true, modelData }).map((t) => t.category));
|
|
14
|
-
const availableCategories = new Set(getHostedTools({ model, modelData }).map((t) => t.category));
|
|
17
|
+
const availableCategories = new Set(getHostedTools({ model, provider, modelData }).map((t) => t.category));
|
|
15
18
|
for (const name of requested) {
|
|
16
19
|
if (!IMPLEMENTED_HOSTED_TOOLS.has(name)) {
|
|
17
20
|
if (allCategories.has(name)) {
|
|
@@ -20,8 +23,11 @@ export function validateHostedTools(requested, model, modelData) {
|
|
|
20
23
|
return `Unknown hosted tool "${name}".`;
|
|
21
24
|
}
|
|
22
25
|
if (!availableCategories.has(name)) {
|
|
23
|
-
|
|
24
|
-
|
|
26
|
+
let effectiveProvider = provider;
|
|
27
|
+
if (!effectiveProvider) {
|
|
28
|
+
effectiveProvider = getModel(model, modelData)?.provider ?? "unknown";
|
|
29
|
+
}
|
|
30
|
+
return `${name} is a hosted capability; ${model} (${effectiveProvider}) doesn't offer it — pass a search function as a tool instead.`;
|
|
25
31
|
}
|
|
26
32
|
}
|
|
27
33
|
return null;
|
|
@@ -32,7 +38,15 @@ export function estimateHostedToolCost(result, model, modelData) {
|
|
|
32
38
|
if (!result.callCount) {
|
|
33
39
|
return undefined;
|
|
34
40
|
}
|
|
35
|
-
|
|
41
|
+
// The result names the provider that produced it, which may differ from the
|
|
42
|
+
// model's registered provider (e.g. a base model routed through Responses).
|
|
43
|
+
// Use it so the catalog lookup isn't filtered out by the wrong provider.
|
|
44
|
+
const tools = getHostedTools({
|
|
45
|
+
model,
|
|
46
|
+
provider: result.provider,
|
|
47
|
+
includeDisabled: true,
|
|
48
|
+
modelData,
|
|
49
|
+
});
|
|
36
50
|
const tool = tools.find((t) => t.category === result.tool && t.provider === result.provider);
|
|
37
51
|
if (!tool) {
|
|
38
52
|
return undefined;
|