@usabledev/usable-chat 1.208.0 → 1.209.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/cli.js +229 -24
- package/package.json +1 -1
package/cli.js
CHANGED
|
@@ -29452,7 +29452,24 @@ function convertToOpenRouterMessages(messages4, modelId) {
|
|
|
29452
29452
|
});
|
|
29453
29453
|
}
|
|
29454
29454
|
}
|
|
29455
|
-
|
|
29455
|
+
const normalizedMessages = messages4.flatMap((message2) => {
|
|
29456
|
+
if (message2.role !== "user" || !Array.isArray(message2.content)) return [message2];
|
|
29457
|
+
const blocks2 = message2.content;
|
|
29458
|
+
const results = blocks2.filter((block2) => block2.type === "tool_result");
|
|
29459
|
+
if (!results.length) return [message2];
|
|
29460
|
+
const other2 = blocks2.filter((block2) => block2.type !== "tool_result");
|
|
29461
|
+
return [
|
|
29462
|
+
...results.map(
|
|
29463
|
+
(block2) => ({
|
|
29464
|
+
role: "tool",
|
|
29465
|
+
tool_call_id: block2.tool_use_id,
|
|
29466
|
+
content: `${block2.is_error ? "[TOOL ERROR] " : ""}${typeof block2.content === "string" ? block2.content : JSON.stringify(block2.content)}`
|
|
29467
|
+
})
|
|
29468
|
+
),
|
|
29469
|
+
...other2.length ? [{ ...message2, content: other2 }] : []
|
|
29470
|
+
];
|
|
29471
|
+
});
|
|
29472
|
+
return normalizedMessages.map((msg) => {
|
|
29456
29473
|
const extMsg = msg;
|
|
29457
29474
|
let content = extMsg.content;
|
|
29458
29475
|
if (Array.isArray(content)) {
|
|
@@ -45580,6 +45597,21 @@ var init_model_pricing = __esm({
|
|
|
45580
45597
|
"src/lib/model-pricing.ts"() {
|
|
45581
45598
|
"use strict";
|
|
45582
45599
|
MODEL_PRICING = {
|
|
45600
|
+
"openai/gpt-6-sol": {
|
|
45601
|
+
input: 2e-6,
|
|
45602
|
+
output: 1e-5,
|
|
45603
|
+
multiplier: 16
|
|
45604
|
+
},
|
|
45605
|
+
"openai/gpt-6-luna": {
|
|
45606
|
+
input: 1e-7,
|
|
45607
|
+
output: 5e-7,
|
|
45608
|
+
multiplier: 1
|
|
45609
|
+
},
|
|
45610
|
+
"anthropic/claude-opus-5.5": {
|
|
45611
|
+
input: 4e-6,
|
|
45612
|
+
output: 2e-5,
|
|
45613
|
+
multiplier: 32
|
|
45614
|
+
},
|
|
45583
45615
|
// Amazon Models
|
|
45584
45616
|
"amazon/nova-2-lite-v1": {
|
|
45585
45617
|
input: 3e-7,
|
|
@@ -46912,6 +46944,75 @@ var init_model_registry_generated = __esm({
|
|
|
46912
46944
|
"src/lib/model-registry-generated.ts"() {
|
|
46913
46945
|
"use strict";
|
|
46914
46946
|
GENERATED_MODELS = [
|
|
46947
|
+
{
|
|
46948
|
+
id: "openai/gpt-6-luna",
|
|
46949
|
+
displayName: "GPT-6 Luna",
|
|
46950
|
+
vendor: "openai",
|
|
46951
|
+
category: "fast",
|
|
46952
|
+
capabilities: {
|
|
46953
|
+
vision: true,
|
|
46954
|
+
reasoning: true,
|
|
46955
|
+
maxTokens: 128e3,
|
|
46956
|
+
contextLength: 105e4
|
|
46957
|
+
},
|
|
46958
|
+
pricing: {
|
|
46959
|
+
inputPer1M: 0.1,
|
|
46960
|
+
outputPer1M: 0.5,
|
|
46961
|
+
multiplier: 1
|
|
46962
|
+
},
|
|
46963
|
+
availability: {
|
|
46964
|
+
mainChat: false,
|
|
46965
|
+
experts: true,
|
|
46966
|
+
embeds: true
|
|
46967
|
+
},
|
|
46968
|
+
createdAt: 1790100786
|
|
46969
|
+
},
|
|
46970
|
+
{
|
|
46971
|
+
id: "openai/gpt-6-sol",
|
|
46972
|
+
displayName: "GPT-6 Sol",
|
|
46973
|
+
vendor: "openai",
|
|
46974
|
+
category: "balanced",
|
|
46975
|
+
capabilities: {
|
|
46976
|
+
vision: true,
|
|
46977
|
+
reasoning: true,
|
|
46978
|
+
maxTokens: 128e3,
|
|
46979
|
+
contextLength: 105e4
|
|
46980
|
+
},
|
|
46981
|
+
pricing: {
|
|
46982
|
+
inputPer1M: 2,
|
|
46983
|
+
outputPer1M: 10,
|
|
46984
|
+
multiplier: 16
|
|
46985
|
+
},
|
|
46986
|
+
availability: {
|
|
46987
|
+
mainChat: false,
|
|
46988
|
+
experts: true,
|
|
46989
|
+
embeds: true
|
|
46990
|
+
},
|
|
46991
|
+
createdAt: 1790100775
|
|
46992
|
+
},
|
|
46993
|
+
{
|
|
46994
|
+
id: "anthropic/claude-opus-5.5",
|
|
46995
|
+
displayName: "Claude Opus 5.5",
|
|
46996
|
+
vendor: "anthropic",
|
|
46997
|
+
category: "powerful",
|
|
46998
|
+
capabilities: {
|
|
46999
|
+
vision: true,
|
|
47000
|
+
reasoning: true,
|
|
47001
|
+
maxTokens: 128e3,
|
|
47002
|
+
contextLength: 1e6
|
|
47003
|
+
},
|
|
47004
|
+
pricing: {
|
|
47005
|
+
inputPer1M: 4,
|
|
47006
|
+
outputPer1M: 20,
|
|
47007
|
+
multiplier: 32
|
|
47008
|
+
},
|
|
47009
|
+
availability: {
|
|
47010
|
+
mainChat: false,
|
|
47011
|
+
experts: true,
|
|
47012
|
+
embeds: true
|
|
47013
|
+
},
|
|
47014
|
+
createdAt: 1790094732
|
|
47015
|
+
},
|
|
46915
47016
|
{
|
|
46916
47017
|
id: "openai/gpt-6-astra",
|
|
46917
47018
|
displayName: "GPT-6 Astra",
|
|
@@ -52518,6 +52619,7 @@ var init_model_registry = __esm({
|
|
|
52518
52619
|
"claude-sonnet-4-6": { bedrockId: "anthropic.claude-sonnet-4-6", crossRegion: true },
|
|
52519
52620
|
"claude-sonnet-5": { bedrockId: "global.anthropic.claude-sonnet-5", crossRegion: false },
|
|
52520
52621
|
"claude-opus-5": { bedrockId: "global.anthropic.claude-opus-5", crossRegion: false },
|
|
52622
|
+
"claude-opus-5-5": { bedrockId: "global.anthropic.claude-opus-5-5", crossRegion: false },
|
|
52521
52623
|
// Opus 4.7 uses the Global Cross-Region Inference profile (no regional Geo access required)
|
|
52522
52624
|
"claude-opus-4-7": { bedrockId: "global.anthropic.claude-opus-4-7", crossRegion: false },
|
|
52523
52625
|
"claude-opus-4-20250514": {
|
|
@@ -138126,6 +138228,7 @@ function extractClaudeModel(modelId) {
|
|
|
138126
138228
|
"anthropic/claude-opus-4.7": "claude-opus-4-7",
|
|
138127
138229
|
"anthropic/claude-opus-4.8": "claude-opus-4-8",
|
|
138128
138230
|
"anthropic/claude-opus-5": "claude-opus-5",
|
|
138231
|
+
"anthropic/claude-opus-5.5": "claude-opus-5-5",
|
|
138129
138232
|
// Claude Fable models
|
|
138130
138233
|
"anthropic/claude-fable-5": "claude-fable-5",
|
|
138131
138234
|
"anthropic/claude-fable-5.1": "claude-fable-5-1",
|
|
@@ -165240,8 +165343,8 @@ var init_model_tiers = __esm({
|
|
|
165240
165343
|
effort: "medium"
|
|
165241
165344
|
},
|
|
165242
165345
|
{
|
|
165243
|
-
id: "openai/gpt-
|
|
165244
|
-
displayName: "GPT-
|
|
165346
|
+
id: "openai/gpt-6-luna",
|
|
165347
|
+
displayName: "GPT-6 Luna",
|
|
165245
165348
|
description: "Efficient high-volume reasoning, multimodal input, and 1M+ context",
|
|
165246
165349
|
provider: "OpenAI",
|
|
165247
165350
|
multiLingual: true,
|
|
@@ -165271,8 +165374,8 @@ var init_model_tiers = __esm({
|
|
|
165271
165374
|
zdr: true
|
|
165272
165375
|
},
|
|
165273
165376
|
{
|
|
165274
|
-
id: "openai/gpt-
|
|
165275
|
-
displayName: "GPT-
|
|
165377
|
+
id: "openai/gpt-6-sol",
|
|
165378
|
+
displayName: "GPT-6 Sol",
|
|
165276
165379
|
description: "Balanced intelligence and cost for reasoning, coding, and agents",
|
|
165277
165380
|
provider: "OpenAI",
|
|
165278
165381
|
multiLingual: true,
|
|
@@ -165285,8 +165388,8 @@ var init_model_tiers = __esm({
|
|
|
165285
165388
|
name: "Deep Research",
|
|
165286
165389
|
models: [
|
|
165287
165390
|
{
|
|
165288
|
-
id: "anthropic/claude-opus-5",
|
|
165289
|
-
displayName: "Claude Opus 5",
|
|
165391
|
+
id: "anthropic/claude-opus-5.5",
|
|
165392
|
+
displayName: "Claude Opus 5.5",
|
|
165290
165393
|
description: "Frontier coding, agents, architecture, and long-running research",
|
|
165291
165394
|
provider: "Anthropic",
|
|
165292
165395
|
costTier: "Very Expensive",
|
|
@@ -166063,6 +166166,7 @@ var init_model_config = __esm({
|
|
|
166063
166166
|
"anthropic/claude-4.5-sonnet": { vision: true, reasoning: true },
|
|
166064
166167
|
"anthropic/claude-opus-4.7": { vision: true, reasoning: false },
|
|
166065
166168
|
"anthropic/claude-opus-5": { vision: true, reasoning: true },
|
|
166169
|
+
"anthropic/claude-opus-5.5": { vision: true, reasoning: true },
|
|
166066
166170
|
"anthropic/claude-fable-5.1": { vision: true, reasoning: true },
|
|
166067
166171
|
"google/gemini-2.5-flash": { vision: true, reasoning: true },
|
|
166068
166172
|
"google/gemini-2.5-flash-lite": { vision: true, reasoning: true },
|
|
@@ -166076,6 +166180,8 @@ var init_model_config = __esm({
|
|
|
166076
166180
|
"openai/gpt-5.2-codex": { vision: true, reasoning: true },
|
|
166077
166181
|
"openai/gpt-5.5": { vision: true, reasoning: true },
|
|
166078
166182
|
"openai/gpt-5.6-sol": { vision: true, reasoning: true },
|
|
166183
|
+
"openai/gpt-6-sol": { vision: true, reasoning: true },
|
|
166184
|
+
"openai/gpt-6-luna": { vision: true, reasoning: true },
|
|
166079
166185
|
"openai/gpt-6-astra": { vision: true, reasoning: true },
|
|
166080
166186
|
"deepseek/deepseek-r1": { vision: false, reasoning: true }
|
|
166081
166187
|
};
|
|
@@ -167300,6 +167406,25 @@ var init_logger3 = __esm({
|
|
|
167300
167406
|
}
|
|
167301
167407
|
});
|
|
167302
167408
|
|
|
167409
|
+
// src/core/ai/openrouter-tool-format.ts
|
|
167410
|
+
function toOpenRouterToolFormat(tools) {
|
|
167411
|
+
return tools.map(
|
|
167412
|
+
(tool2) => "input_schema" in tool2 ? {
|
|
167413
|
+
type: "function",
|
|
167414
|
+
function: {
|
|
167415
|
+
name: tool2.name,
|
|
167416
|
+
description: tool2.description,
|
|
167417
|
+
parameters: tool2.input_schema
|
|
167418
|
+
}
|
|
167419
|
+
} : tool2
|
|
167420
|
+
);
|
|
167421
|
+
}
|
|
167422
|
+
var init_openrouter_tool_format = __esm({
|
|
167423
|
+
"src/core/ai/openrouter-tool-format.ts"() {
|
|
167424
|
+
"use strict";
|
|
167425
|
+
}
|
|
167426
|
+
});
|
|
167427
|
+
|
|
167303
167428
|
// src/lib/reasoning-config.ts
|
|
167304
167429
|
function getReasoningConfig(modelId, hasReasoningCapability = false, forceEnable = true, reasoningEffort) {
|
|
167305
167430
|
if (reasoningEffort === void 0) {
|
|
@@ -359561,30 +359686,99 @@ function matchOriginAgainstDomains(origin, domains) {
|
|
|
359561
359686
|
if (!origin || domains.length === 0) {
|
|
359562
359687
|
return false;
|
|
359563
359688
|
}
|
|
359564
|
-
let
|
|
359689
|
+
let parsedOrigin;
|
|
359565
359690
|
try {
|
|
359566
|
-
|
|
359691
|
+
parsedOrigin = new URL(origin);
|
|
359692
|
+
if (!["http:", "https:"].includes(parsedOrigin.protocol) || parsedOrigin.username || parsedOrigin.password)
|
|
359693
|
+
return false;
|
|
359567
359694
|
} catch {
|
|
359568
359695
|
return false;
|
|
359569
359696
|
}
|
|
359570
359697
|
return domains.some((allowed) => {
|
|
359571
|
-
const
|
|
359572
|
-
|
|
359573
|
-
|
|
359574
|
-
|
|
359575
|
-
|
|
359576
|
-
return allowed;
|
|
359577
|
-
}
|
|
359578
|
-
})();
|
|
359579
|
-
if (isWildcard) {
|
|
359580
|
-
return originHost.endsWith("." + allowedHost) || originHost === allowedHost;
|
|
359581
|
-
}
|
|
359582
|
-
return originHost === allowedHost;
|
|
359698
|
+
const rule = parseAllowedDomain(allowed);
|
|
359699
|
+
if (!rule) return false;
|
|
359700
|
+
if (rule.kind === "origin") return rule.value === parsedOrigin.origin;
|
|
359701
|
+
const host = parsedOrigin.hostname;
|
|
359702
|
+
return host === rule.value || rule.kind === "wildcard" && host.endsWith("." + rule.value);
|
|
359583
359703
|
});
|
|
359584
359704
|
}
|
|
359705
|
+
function isValidAllowedDomain(value) {
|
|
359706
|
+
return parseAllowedDomain(value) !== null;
|
|
359707
|
+
}
|
|
359708
|
+
function parseAllowedDomain(allowed) {
|
|
359709
|
+
if ([...allowed].some((char2) => char2.charCodeAt(0) <= 32 || char2.charCodeAt(0) === 127))
|
|
359710
|
+
return null;
|
|
359711
|
+
if (/^[a-z][a-z0-9+.-]*:/i.test(allowed)) {
|
|
359712
|
+
if (!explicitOriginPattern.test(allowed) || allowed.includes("*")) return null;
|
|
359713
|
+
try {
|
|
359714
|
+
const configured = new URL(allowed);
|
|
359715
|
+
if (!["http:", "https:"].includes(configured.protocol) || configured.username || configured.password || configured.pathname !== "/" || configured.search || configured.hash)
|
|
359716
|
+
return null;
|
|
359717
|
+
return { kind: "origin", value: configured.origin };
|
|
359718
|
+
} catch {
|
|
359719
|
+
return null;
|
|
359720
|
+
}
|
|
359721
|
+
}
|
|
359722
|
+
const wildcard = allowed.startsWith("*.");
|
|
359723
|
+
const host = wildcard ? allowed.slice(2) : allowed;
|
|
359724
|
+
const ipv63 = !wildcard && ipv6HostPattern.test(host);
|
|
359725
|
+
if (!ipv63 && /[:/\\?#@%\s]/u.test(host)) return null;
|
|
359726
|
+
try {
|
|
359727
|
+
const normalized = new URL(`https://${host}`).hostname;
|
|
359728
|
+
if (!hostnamePattern.test(normalized) && !(ipv63 && ipv6HostPattern.test(normalized)))
|
|
359729
|
+
return null;
|
|
359730
|
+
return { kind: wildcard ? "wildcard" : "host", value: normalized };
|
|
359731
|
+
} catch {
|
|
359732
|
+
return null;
|
|
359733
|
+
}
|
|
359734
|
+
}
|
|
359735
|
+
var explicitOriginPattern, hostnamePattern, ipv6HostPattern, allowedDomainValidationMessage;
|
|
359585
359736
|
var init_origin_matcher = __esm({
|
|
359586
359737
|
"src/lib/utils/origin-matcher.ts"() {
|
|
359587
359738
|
"use strict";
|
|
359739
|
+
explicitOriginPattern = /^https?:\/\/(?:\[[a-f0-9:.]+\]|[^:/\\?#@%\s]+)(?::[0-9]+)?\/?$/i;
|
|
359740
|
+
hostnamePattern = /^(?:[a-z0-9_](?:[a-z0-9_-]{0,61}[a-z0-9_])?\.)*[a-z0-9_](?:[a-z0-9_-]{0,61}[a-z0-9_])?\.?$/i;
|
|
359741
|
+
ipv6HostPattern = /^\[[a-f0-9:.]+\]$/i;
|
|
359742
|
+
allowedDomainValidationMessage = "Use an HTTP(S) origin without a path (https://example.com:8443), a bare hostname, or *.example.com. Scheme wildcards and bare host:port are not supported.";
|
|
359743
|
+
}
|
|
359744
|
+
});
|
|
359745
|
+
|
|
359746
|
+
// src/core/types/embed-key.ts
|
|
359747
|
+
var allowedDomainSchema, createEmbedKeyObjectSchema, createEmbedKeySchema, updateEmbedKeySchema, embedKeyAccessPolicySchema, rawUsablePatSchema;
|
|
359748
|
+
var init_embed_key = __esm({
|
|
359749
|
+
"src/core/types/embed-key.ts"() {
|
|
359750
|
+
"use strict";
|
|
359751
|
+
init_zod();
|
|
359752
|
+
init_origin_matcher();
|
|
359753
|
+
allowedDomainSchema = external_exports.string().min(1).refine(isValidAllowedDomain, allowedDomainValidationMessage);
|
|
359754
|
+
createEmbedKeyObjectSchema = external_exports.object({
|
|
359755
|
+
configId: external_exports.string().uuid(),
|
|
359756
|
+
label: external_exports.string().min(1).max(255),
|
|
359757
|
+
allowedDomains: external_exports.array(allowedDomainSchema).default([]),
|
|
359758
|
+
public: external_exports.boolean().default(false),
|
|
359759
|
+
expiresAt: external_exports.union([external_exports.date(), external_exports.string().datetime()]).optional()
|
|
359760
|
+
});
|
|
359761
|
+
createEmbedKeySchema = createEmbedKeyObjectSchema.refine(
|
|
359762
|
+
(data2) => data2.public || data2.allowedDomains.length > 0,
|
|
359763
|
+
{
|
|
359764
|
+
message: "At least one allowed domain is required when the key is not public",
|
|
359765
|
+
path: ["allowedDomains"]
|
|
359766
|
+
}
|
|
359767
|
+
);
|
|
359768
|
+
updateEmbedKeySchema = external_exports.object({
|
|
359769
|
+
label: external_exports.string().min(1).max(255).optional(),
|
|
359770
|
+
allowedDomains: external_exports.array(allowedDomainSchema).optional(),
|
|
359771
|
+
public: external_exports.boolean().optional(),
|
|
359772
|
+
expiresAt: external_exports.union([external_exports.date(), external_exports.string().datetime()]).nullable().optional()
|
|
359773
|
+
});
|
|
359774
|
+
embedKeyAccessPolicySchema = external_exports.object({
|
|
359775
|
+
public: external_exports.boolean(),
|
|
359776
|
+
allowedDomains: external_exports.array(allowedDomainSchema)
|
|
359777
|
+
}).refine((data2) => data2.public || data2.allowedDomains.length > 0, {
|
|
359778
|
+
message: "At least one allowed domain is required when the key is not public",
|
|
359779
|
+
path: ["allowedDomains"]
|
|
359780
|
+
});
|
|
359781
|
+
rawUsablePatSchema = external_exports.string().min(1).max(4096);
|
|
359588
359782
|
}
|
|
359589
359783
|
});
|
|
359590
359784
|
|
|
@@ -359710,7 +359904,16 @@ async function resolveEmbedKeyUncached(token, origin, options2) {
|
|
|
359710
359904
|
if (key2.expiresAt && new Date(key2.expiresAt) < /* @__PURE__ */ new Date()) {
|
|
359711
359905
|
return { success: false, error: { code: "KEY_EXPIRED", message: "This embed key has expired" } };
|
|
359712
359906
|
}
|
|
359713
|
-
if (key2.
|
|
359907
|
+
if (!key2.public && key2.allowedDomains.length === 0) {
|
|
359908
|
+
return {
|
|
359909
|
+
success: false,
|
|
359910
|
+
error: {
|
|
359911
|
+
code: "ORIGIN_NOT_ALLOWED",
|
|
359912
|
+
message: "This private embed key has no allowed domains"
|
|
359913
|
+
}
|
|
359914
|
+
};
|
|
359915
|
+
}
|
|
359916
|
+
if (!key2.public && !options2?.skipOriginCheck) {
|
|
359714
359917
|
if (!origin) {
|
|
359715
359918
|
return {
|
|
359716
359919
|
success: false,
|
|
@@ -359762,6 +359965,7 @@ var EMBED_KEY_CACHE_TTL_MS, EMBED_KEY_CACHE_MAX_ENTRIES, embedKeyCache, EMBED_KE
|
|
|
359762
359965
|
var init_embed_key_service = __esm({
|
|
359763
359966
|
"src/lib/services/embed-key.service.ts"() {
|
|
359764
359967
|
"use strict";
|
|
359968
|
+
init_embed_key();
|
|
359765
359969
|
init_client7();
|
|
359766
359970
|
init_schema_embed_keys();
|
|
359767
359971
|
init_schema3();
|
|
@@ -364010,7 +364214,7 @@ async function callLLM({
|
|
|
364010
364214
|
stream_options: {
|
|
364011
364215
|
include_usage: true
|
|
364012
364216
|
},
|
|
364013
|
-
tools,
|
|
364217
|
+
tools: tools ? toOpenRouterToolFormat(tools) : void 0,
|
|
364014
364218
|
tool_choice: shouldEnableTools ? forcedToolName ? { type: "function", function: { name: forcedToolName } } : "auto" : void 0,
|
|
364015
364219
|
temperature,
|
|
364016
364220
|
max_tokens: maxTokens,
|
|
@@ -368256,6 +368460,7 @@ var init_orchestrator = __esm({
|
|
|
368256
368460
|
init_mcp();
|
|
368257
368461
|
init_model_registry();
|
|
368258
368462
|
init_openrouter_direct();
|
|
368463
|
+
init_openrouter_tool_format();
|
|
368259
368464
|
init_codex_direct();
|
|
368260
368465
|
init_reasoning_config();
|
|
368261
368466
|
init_claude_stream_adapter();
|
|
@@ -391609,7 +391814,7 @@ init_tui_select();
|
|
|
391609
391814
|
init_model_registry();
|
|
391610
391815
|
|
|
391611
391816
|
// package.json
|
|
391612
|
-
var version2 = "1.
|
|
391817
|
+
var version2 = "1.209.0";
|
|
391613
391818
|
|
|
391614
391819
|
// src/adapters/cli/model-catalog.ts
|
|
391615
391820
|
init_codex_auth();
|