indusagi 0.13.6 → 0.13.8
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 +661 -0
- package/README.md +7 -1
- package/dist/cli.js +114 -14
- package/dist/index.js +1618 -51
- package/dist/llmgateway.js +114 -14
- package/dist/mcp.js +812 -3
- package/dist/runtime.js +114 -14
- package/dist/sarvam-mcp.js +960 -0
- package/dist/shell-app.js +116 -14
- package/dist/smithy.js +114 -14
- package/dist/swarm.js +114 -14
- package/dist/tracing.js +37 -0
- package/dist/types/connectors-sarvam/connect.d.ts +14 -0
- package/dist/types/connectors-sarvam/connectors-sarvam.test.d.ts +14 -0
- package/dist/types/connectors-sarvam/index.d.ts +14 -0
- package/dist/types/connectors-sarvam/toolbox.d.ts +19 -0
- package/dist/types/connectors-sarvam/types.d.ts +49 -0
- package/dist/types/connectors-zoho/connect.d.ts +22 -0
- package/dist/types/connectors-zoho/connectors-zoho.test.d.ts +10 -0
- package/dist/types/connectors-zoho/index.d.ts +13 -0
- package/dist/types/connectors-zoho/toolbox.d.ts +19 -0
- package/dist/types/connectors-zoho/types.d.ts +56 -0
- package/dist/types/facade/mcp-core/client.d.ts +32 -0
- package/dist/types/facade/mcp-core/index.d.ts +4 -0
- package/dist/types/facade/mcp-core/oauth/flow.d.ts +72 -0
- package/dist/types/facade/mcp-core/oauth/index.d.ts +18 -0
- package/dist/types/facade/mcp-core/oauth/oauth.test.d.ts +8 -0
- package/dist/types/facade/mcp-core/oauth/provider.d.ts +51 -0
- package/dist/types/facade/mcp-core/oauth/token-store.d.ts +31 -0
- package/dist/types/facade/mcp-core/oauth/types.d.ts +96 -0
- package/dist/types/facade/mcp-core/toolbox-bridge.d.ts +46 -0
- package/dist/types/facade/mcp-core/toolbox-bridge.test.d.ts +8 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/llmgateway/contract/model-card.d.ts +1 -1
- package/dist/types/llmgateway/credentials/secrets.d.ts +2 -0
- package/dist/zoho.js +1451 -0
- package/package.json +11 -4
- package/dist/knowledge/guides/authoring-an-agent.md +0 -53
- package/dist/knowledge/guides/choosing-tools.md +0 -49
- package/dist/knowledge/guides/model-selection.md +0 -51
- package/dist/knowledge/guides/writing-system-prompts.md +0 -53
- package/dist/knowledge/index.ts +0 -19
- package/dist/knowledge/loader.ts +0 -200
- package/dist/knowledge/manifest.json +0 -29
package/dist/shell-app.js
CHANGED
|
@@ -476,6 +476,85 @@ var MODEL_CARDS = [
|
|
|
476
476
|
cacheReadPerMTok: 0.15
|
|
477
477
|
}
|
|
478
478
|
},
|
|
479
|
+
// ── MiniMax (Anthropic-compatible Messages API) ─────────────────────────
|
|
480
|
+
// Wire: same dialect as Claude (`anthropic-messages`) at api.minimax.io.
|
|
481
|
+
// Auth: MINIMAX_API_KEY. Ids match facade/models.generated.ts.
|
|
482
|
+
{
|
|
483
|
+
id: "MiniMax-M2",
|
|
484
|
+
provider: "minimax",
|
|
485
|
+
api: "anthropic-messages",
|
|
486
|
+
displayName: "MiniMax M2",
|
|
487
|
+
baseUrl: "https://api.minimax.io/anthropic",
|
|
488
|
+
contextWindow: 204800,
|
|
489
|
+
maxOutputTokens: 131072,
|
|
490
|
+
modalities: ["text"],
|
|
491
|
+
reasoning: true,
|
|
492
|
+
cost: {
|
|
493
|
+
inputPerMTok: 0.3,
|
|
494
|
+
outputPerMTok: 1.2
|
|
495
|
+
}
|
|
496
|
+
},
|
|
497
|
+
{
|
|
498
|
+
id: "MiniMax-M2.1",
|
|
499
|
+
provider: "minimax",
|
|
500
|
+
api: "anthropic-messages",
|
|
501
|
+
displayName: "MiniMax M2.1",
|
|
502
|
+
baseUrl: "https://api.minimax.io/anthropic",
|
|
503
|
+
contextWindow: 204800,
|
|
504
|
+
maxOutputTokens: 131072,
|
|
505
|
+
modalities: ["text"],
|
|
506
|
+
reasoning: true,
|
|
507
|
+
cost: {
|
|
508
|
+
inputPerMTok: 0.3,
|
|
509
|
+
outputPerMTok: 1.2
|
|
510
|
+
}
|
|
511
|
+
},
|
|
512
|
+
{
|
|
513
|
+
id: "MiniMax-M2.5",
|
|
514
|
+
provider: "minimax",
|
|
515
|
+
api: "anthropic-messages",
|
|
516
|
+
displayName: "MiniMax M2.5",
|
|
517
|
+
baseUrl: "https://api.minimax.io/anthropic",
|
|
518
|
+
contextWindow: 204800,
|
|
519
|
+
maxOutputTokens: 131072,
|
|
520
|
+
modalities: ["text"],
|
|
521
|
+
reasoning: true,
|
|
522
|
+
cost: {
|
|
523
|
+
inputPerMTok: 0.3,
|
|
524
|
+
outputPerMTok: 1.2
|
|
525
|
+
}
|
|
526
|
+
},
|
|
527
|
+
{
|
|
528
|
+
id: "MiniMax-M2.7",
|
|
529
|
+
provider: "minimax",
|
|
530
|
+
api: "anthropic-messages",
|
|
531
|
+
displayName: "MiniMax M2.7",
|
|
532
|
+
baseUrl: "https://api.minimax.io/anthropic",
|
|
533
|
+
contextWindow: 204800,
|
|
534
|
+
maxOutputTokens: 131072,
|
|
535
|
+
modalities: ["text"],
|
|
536
|
+
reasoning: true,
|
|
537
|
+
cost: {
|
|
538
|
+
inputPerMTok: 0.3,
|
|
539
|
+
outputPerMTok: 1.2
|
|
540
|
+
}
|
|
541
|
+
},
|
|
542
|
+
{
|
|
543
|
+
id: "MiniMax-M3",
|
|
544
|
+
provider: "minimax",
|
|
545
|
+
api: "anthropic-messages",
|
|
546
|
+
displayName: "MiniMax M3",
|
|
547
|
+
baseUrl: "https://api.minimax.io/anthropic",
|
|
548
|
+
contextWindow: 1048576,
|
|
549
|
+
maxOutputTokens: 512e3,
|
|
550
|
+
modalities: ["text", "image"],
|
|
551
|
+
reasoning: true,
|
|
552
|
+
cost: {
|
|
553
|
+
inputPerMTok: 0.6,
|
|
554
|
+
outputPerMTok: 2.4,
|
|
555
|
+
cacheReadPerMTok: 0.12
|
|
556
|
+
}
|
|
557
|
+
},
|
|
479
558
|
// ── Ollama (local; pricing is zero — your own hardware) ─────────────────
|
|
480
559
|
{
|
|
481
560
|
id: "llama3.1:8b",
|
|
@@ -597,6 +676,19 @@ var SECRET_TABLE = {
|
|
|
597
676
|
envVars: ["MOONSHOT_API_KEY", "KIMI_API_KEY"],
|
|
598
677
|
hint: "Moonshot AI (Kimi) API key."
|
|
599
678
|
},
|
|
679
|
+
minimax: {
|
|
680
|
+
provider: "minimax",
|
|
681
|
+
scheme: "api-key",
|
|
682
|
+
envVars: ["MINIMAX_API_KEY"],
|
|
683
|
+
hint: "MiniMax global API key (api.minimax.io Anthropic-compatible)."
|
|
684
|
+
},
|
|
685
|
+
"minimax-cn": {
|
|
686
|
+
provider: "minimax-cn",
|
|
687
|
+
scheme: "api-key",
|
|
688
|
+
// Same key often works for both; CN-specific override first when set.
|
|
689
|
+
envVars: ["MINIMAX_CN_API_KEY", "MINIMAX_API_KEY"],
|
|
690
|
+
hint: "MiniMax China API key (api.minimaxi.com Anthropic-compatible)."
|
|
691
|
+
},
|
|
600
692
|
ollama: {
|
|
601
693
|
provider: "ollama",
|
|
602
694
|
scheme: "none",
|
|
@@ -1437,7 +1529,7 @@ function endpointFor(model) {
|
|
|
1437
1529
|
const base = (model.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
1438
1530
|
return `${base}/v1/messages`;
|
|
1439
1531
|
}
|
|
1440
|
-
async function postMessages(url, apiKey, body, signal) {
|
|
1532
|
+
async function postMessages(url, apiKey, body, signal, provider = "anthropic") {
|
|
1441
1533
|
let response;
|
|
1442
1534
|
try {
|
|
1443
1535
|
response = await fetch(url, {
|
|
@@ -1452,24 +1544,24 @@ async function postMessages(url, apiKey, body, signal) {
|
|
|
1452
1544
|
});
|
|
1453
1545
|
} catch (cause) {
|
|
1454
1546
|
if (signal?.aborted) {
|
|
1455
|
-
throw gatewayError("aborted",
|
|
1456
|
-
provider
|
|
1547
|
+
throw gatewayError("aborted", `request canceled before ${provider} responded`, {
|
|
1548
|
+
provider,
|
|
1457
1549
|
cause
|
|
1458
1550
|
});
|
|
1459
1551
|
}
|
|
1460
|
-
throw gatewayError("transport",
|
|
1552
|
+
throw gatewayError("transport", `network call to ${provider} failed`, { provider, cause });
|
|
1461
1553
|
}
|
|
1462
1554
|
if (!response.ok) {
|
|
1463
1555
|
const detail = await readErrorBody(response);
|
|
1464
1556
|
const kind = response.status === 401 || response.status === 403 ? "auth" : response.status === 429 ? "rate_limit" : "http";
|
|
1465
|
-
throw gatewayError(kind,
|
|
1466
|
-
provider
|
|
1557
|
+
throw gatewayError(kind, `${provider} returned HTTP ${response.status}${detail}`, {
|
|
1558
|
+
provider,
|
|
1467
1559
|
status: response.status
|
|
1468
1560
|
});
|
|
1469
1561
|
}
|
|
1470
1562
|
if (response.body === null) {
|
|
1471
|
-
throw gatewayError("transport",
|
|
1472
|
-
provider
|
|
1563
|
+
throw gatewayError("transport", `${provider} response arrived with no body`, {
|
|
1564
|
+
provider,
|
|
1473
1565
|
status: response.status
|
|
1474
1566
|
});
|
|
1475
1567
|
}
|
|
@@ -1491,11 +1583,13 @@ function asGatewayError(cause) {
|
|
|
1491
1583
|
}
|
|
1492
1584
|
function createanthropicConnector(deps2) {
|
|
1493
1585
|
const api = "anthropic-messages";
|
|
1494
|
-
async function requireKey(options) {
|
|
1495
|
-
const
|
|
1586
|
+
async function requireKey(model, options) {
|
|
1587
|
+
const provider = model.provider;
|
|
1588
|
+
const key = await deps2.resolveSecret(provider, options.apiKey);
|
|
1496
1589
|
if (key === void 0 || key === "") {
|
|
1497
|
-
|
|
1498
|
-
|
|
1590
|
+
const hint = provider === "minimax" || provider === "minimax-cn" ? "set MINIMAX_API_KEY (or MINIMAX_CN_API_KEY for CN) or pass options.apiKey" : "set ANTHROPIC_API_KEY or pass options.apiKey";
|
|
1591
|
+
throw gatewayError("auth", `no API key found for provider "${provider}" (${hint})`, {
|
|
1592
|
+
provider
|
|
1499
1593
|
});
|
|
1500
1594
|
}
|
|
1501
1595
|
return key;
|
|
@@ -1504,10 +1598,16 @@ function createanthropicConnector(deps2) {
|
|
|
1504
1598
|
return channelOf(async function* run2() {
|
|
1505
1599
|
const collected = [];
|
|
1506
1600
|
try {
|
|
1507
|
-
const apiKey = await requireKey(options);
|
|
1601
|
+
const apiKey = await requireKey(model, options);
|
|
1508
1602
|
const body = toAnthropicRequest(conversation, model, options);
|
|
1509
1603
|
body.stream = true;
|
|
1510
|
-
const response = await postMessages(
|
|
1604
|
+
const response = await postMessages(
|
|
1605
|
+
endpointFor(model),
|
|
1606
|
+
apiKey,
|
|
1607
|
+
body,
|
|
1608
|
+
options.signal,
|
|
1609
|
+
model.provider
|
|
1610
|
+
);
|
|
1511
1611
|
const wire = response.body;
|
|
1512
1612
|
const state = { toolIds: /* @__PURE__ */ new Map(), usage: { inputTokens: 0, outputTokens: 0 } };
|
|
1513
1613
|
for await (const event of sseEvents(wire, options.signal)) {
|
|
@@ -12249,6 +12349,8 @@ var KNOWN_PROVIDERS = [
|
|
|
12249
12349
|
"azure",
|
|
12250
12350
|
"nvidia",
|
|
12251
12351
|
"kimi",
|
|
12352
|
+
"minimax",
|
|
12353
|
+
"minimax-cn",
|
|
12252
12354
|
"ollama",
|
|
12253
12355
|
"mock"
|
|
12254
12356
|
];
|
package/dist/smithy.js
CHANGED
|
@@ -3676,6 +3676,85 @@ var MODEL_CARDS = [
|
|
|
3676
3676
|
cacheReadPerMTok: 0.15
|
|
3677
3677
|
}
|
|
3678
3678
|
},
|
|
3679
|
+
// ── MiniMax (Anthropic-compatible Messages API) ─────────────────────────
|
|
3680
|
+
// Wire: same dialect as Claude (`anthropic-messages`) at api.minimax.io.
|
|
3681
|
+
// Auth: MINIMAX_API_KEY. Ids match facade/models.generated.ts.
|
|
3682
|
+
{
|
|
3683
|
+
id: "MiniMax-M2",
|
|
3684
|
+
provider: "minimax",
|
|
3685
|
+
api: "anthropic-messages",
|
|
3686
|
+
displayName: "MiniMax M2",
|
|
3687
|
+
baseUrl: "https://api.minimax.io/anthropic",
|
|
3688
|
+
contextWindow: 204800,
|
|
3689
|
+
maxOutputTokens: 131072,
|
|
3690
|
+
modalities: ["text"],
|
|
3691
|
+
reasoning: true,
|
|
3692
|
+
cost: {
|
|
3693
|
+
inputPerMTok: 0.3,
|
|
3694
|
+
outputPerMTok: 1.2
|
|
3695
|
+
}
|
|
3696
|
+
},
|
|
3697
|
+
{
|
|
3698
|
+
id: "MiniMax-M2.1",
|
|
3699
|
+
provider: "minimax",
|
|
3700
|
+
api: "anthropic-messages",
|
|
3701
|
+
displayName: "MiniMax M2.1",
|
|
3702
|
+
baseUrl: "https://api.minimax.io/anthropic",
|
|
3703
|
+
contextWindow: 204800,
|
|
3704
|
+
maxOutputTokens: 131072,
|
|
3705
|
+
modalities: ["text"],
|
|
3706
|
+
reasoning: true,
|
|
3707
|
+
cost: {
|
|
3708
|
+
inputPerMTok: 0.3,
|
|
3709
|
+
outputPerMTok: 1.2
|
|
3710
|
+
}
|
|
3711
|
+
},
|
|
3712
|
+
{
|
|
3713
|
+
id: "MiniMax-M2.5",
|
|
3714
|
+
provider: "minimax",
|
|
3715
|
+
api: "anthropic-messages",
|
|
3716
|
+
displayName: "MiniMax M2.5",
|
|
3717
|
+
baseUrl: "https://api.minimax.io/anthropic",
|
|
3718
|
+
contextWindow: 204800,
|
|
3719
|
+
maxOutputTokens: 131072,
|
|
3720
|
+
modalities: ["text"],
|
|
3721
|
+
reasoning: true,
|
|
3722
|
+
cost: {
|
|
3723
|
+
inputPerMTok: 0.3,
|
|
3724
|
+
outputPerMTok: 1.2
|
|
3725
|
+
}
|
|
3726
|
+
},
|
|
3727
|
+
{
|
|
3728
|
+
id: "MiniMax-M2.7",
|
|
3729
|
+
provider: "minimax",
|
|
3730
|
+
api: "anthropic-messages",
|
|
3731
|
+
displayName: "MiniMax M2.7",
|
|
3732
|
+
baseUrl: "https://api.minimax.io/anthropic",
|
|
3733
|
+
contextWindow: 204800,
|
|
3734
|
+
maxOutputTokens: 131072,
|
|
3735
|
+
modalities: ["text"],
|
|
3736
|
+
reasoning: true,
|
|
3737
|
+
cost: {
|
|
3738
|
+
inputPerMTok: 0.3,
|
|
3739
|
+
outputPerMTok: 1.2
|
|
3740
|
+
}
|
|
3741
|
+
},
|
|
3742
|
+
{
|
|
3743
|
+
id: "MiniMax-M3",
|
|
3744
|
+
provider: "minimax",
|
|
3745
|
+
api: "anthropic-messages",
|
|
3746
|
+
displayName: "MiniMax M3",
|
|
3747
|
+
baseUrl: "https://api.minimax.io/anthropic",
|
|
3748
|
+
contextWindow: 1048576,
|
|
3749
|
+
maxOutputTokens: 512e3,
|
|
3750
|
+
modalities: ["text", "image"],
|
|
3751
|
+
reasoning: true,
|
|
3752
|
+
cost: {
|
|
3753
|
+
inputPerMTok: 0.6,
|
|
3754
|
+
outputPerMTok: 2.4,
|
|
3755
|
+
cacheReadPerMTok: 0.12
|
|
3756
|
+
}
|
|
3757
|
+
},
|
|
3679
3758
|
// ── Ollama (local; pricing is zero — your own hardware) ─────────────────
|
|
3680
3759
|
{
|
|
3681
3760
|
id: "llama3.1:8b",
|
|
@@ -3781,6 +3860,19 @@ var SECRET_TABLE = {
|
|
|
3781
3860
|
envVars: ["MOONSHOT_API_KEY", "KIMI_API_KEY"],
|
|
3782
3861
|
hint: "Moonshot AI (Kimi) API key."
|
|
3783
3862
|
},
|
|
3863
|
+
minimax: {
|
|
3864
|
+
provider: "minimax",
|
|
3865
|
+
scheme: "api-key",
|
|
3866
|
+
envVars: ["MINIMAX_API_KEY"],
|
|
3867
|
+
hint: "MiniMax global API key (api.minimax.io Anthropic-compatible)."
|
|
3868
|
+
},
|
|
3869
|
+
"minimax-cn": {
|
|
3870
|
+
provider: "minimax-cn",
|
|
3871
|
+
scheme: "api-key",
|
|
3872
|
+
// Same key often works for both; CN-specific override first when set.
|
|
3873
|
+
envVars: ["MINIMAX_CN_API_KEY", "MINIMAX_API_KEY"],
|
|
3874
|
+
hint: "MiniMax China API key (api.minimaxi.com Anthropic-compatible)."
|
|
3875
|
+
},
|
|
3784
3876
|
ollama: {
|
|
3785
3877
|
provider: "ollama",
|
|
3786
3878
|
scheme: "none",
|
|
@@ -4621,7 +4713,7 @@ function endpointFor(model) {
|
|
|
4621
4713
|
const base = (model.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
4622
4714
|
return `${base}/v1/messages`;
|
|
4623
4715
|
}
|
|
4624
|
-
async function postMessages(url, apiKey, body, signal) {
|
|
4716
|
+
async function postMessages(url, apiKey, body, signal, provider = "anthropic") {
|
|
4625
4717
|
let response;
|
|
4626
4718
|
try {
|
|
4627
4719
|
response = await fetch(url, {
|
|
@@ -4636,24 +4728,24 @@ async function postMessages(url, apiKey, body, signal) {
|
|
|
4636
4728
|
});
|
|
4637
4729
|
} catch (cause) {
|
|
4638
4730
|
if (signal?.aborted) {
|
|
4639
|
-
throw gatewayError("aborted",
|
|
4640
|
-
provider
|
|
4731
|
+
throw gatewayError("aborted", `request canceled before ${provider} responded`, {
|
|
4732
|
+
provider,
|
|
4641
4733
|
cause
|
|
4642
4734
|
});
|
|
4643
4735
|
}
|
|
4644
|
-
throw gatewayError("transport",
|
|
4736
|
+
throw gatewayError("transport", `network call to ${provider} failed`, { provider, cause });
|
|
4645
4737
|
}
|
|
4646
4738
|
if (!response.ok) {
|
|
4647
4739
|
const detail = await readErrorBody(response);
|
|
4648
4740
|
const kind = response.status === 401 || response.status === 403 ? "auth" : response.status === 429 ? "rate_limit" : "http";
|
|
4649
|
-
throw gatewayError(kind,
|
|
4650
|
-
provider
|
|
4741
|
+
throw gatewayError(kind, `${provider} returned HTTP ${response.status}${detail}`, {
|
|
4742
|
+
provider,
|
|
4651
4743
|
status: response.status
|
|
4652
4744
|
});
|
|
4653
4745
|
}
|
|
4654
4746
|
if (response.body === null) {
|
|
4655
|
-
throw gatewayError("transport",
|
|
4656
|
-
provider
|
|
4747
|
+
throw gatewayError("transport", `${provider} response arrived with no body`, {
|
|
4748
|
+
provider,
|
|
4657
4749
|
status: response.status
|
|
4658
4750
|
});
|
|
4659
4751
|
}
|
|
@@ -4675,11 +4767,13 @@ function asGatewayError(cause) {
|
|
|
4675
4767
|
}
|
|
4676
4768
|
function createanthropicConnector(deps2) {
|
|
4677
4769
|
const api = "anthropic-messages";
|
|
4678
|
-
async function requireKey(options) {
|
|
4679
|
-
const
|
|
4770
|
+
async function requireKey(model, options) {
|
|
4771
|
+
const provider = model.provider;
|
|
4772
|
+
const key = await deps2.resolveSecret(provider, options.apiKey);
|
|
4680
4773
|
if (key === void 0 || key === "") {
|
|
4681
|
-
|
|
4682
|
-
|
|
4774
|
+
const hint = provider === "minimax" || provider === "minimax-cn" ? "set MINIMAX_API_KEY (or MINIMAX_CN_API_KEY for CN) or pass options.apiKey" : "set ANTHROPIC_API_KEY or pass options.apiKey";
|
|
4775
|
+
throw gatewayError("auth", `no API key found for provider "${provider}" (${hint})`, {
|
|
4776
|
+
provider
|
|
4683
4777
|
});
|
|
4684
4778
|
}
|
|
4685
4779
|
return key;
|
|
@@ -4688,10 +4782,16 @@ function createanthropicConnector(deps2) {
|
|
|
4688
4782
|
return channelOf(async function* run2() {
|
|
4689
4783
|
const collected = [];
|
|
4690
4784
|
try {
|
|
4691
|
-
const apiKey = await requireKey(options);
|
|
4785
|
+
const apiKey = await requireKey(model, options);
|
|
4692
4786
|
const body = toAnthropicRequest(conversation, model, options);
|
|
4693
4787
|
body.stream = true;
|
|
4694
|
-
const response = await postMessages(
|
|
4788
|
+
const response = await postMessages(
|
|
4789
|
+
endpointFor(model),
|
|
4790
|
+
apiKey,
|
|
4791
|
+
body,
|
|
4792
|
+
options.signal,
|
|
4793
|
+
model.provider
|
|
4794
|
+
);
|
|
4695
4795
|
const wire = response.body;
|
|
4696
4796
|
const state = { toolIds: /* @__PURE__ */ new Map(), usage: { inputTokens: 0, outputTokens: 0 } };
|
|
4697
4797
|
for await (const event of sseEvents(wire, options.signal)) {
|
package/dist/swarm.js
CHANGED
|
@@ -240,6 +240,85 @@ var MODEL_CARDS = [
|
|
|
240
240
|
cacheReadPerMTok: 0.15
|
|
241
241
|
}
|
|
242
242
|
},
|
|
243
|
+
// ── MiniMax (Anthropic-compatible Messages API) ─────────────────────────
|
|
244
|
+
// Wire: same dialect as Claude (`anthropic-messages`) at api.minimax.io.
|
|
245
|
+
// Auth: MINIMAX_API_KEY. Ids match facade/models.generated.ts.
|
|
246
|
+
{
|
|
247
|
+
id: "MiniMax-M2",
|
|
248
|
+
provider: "minimax",
|
|
249
|
+
api: "anthropic-messages",
|
|
250
|
+
displayName: "MiniMax M2",
|
|
251
|
+
baseUrl: "https://api.minimax.io/anthropic",
|
|
252
|
+
contextWindow: 204800,
|
|
253
|
+
maxOutputTokens: 131072,
|
|
254
|
+
modalities: ["text"],
|
|
255
|
+
reasoning: true,
|
|
256
|
+
cost: {
|
|
257
|
+
inputPerMTok: 0.3,
|
|
258
|
+
outputPerMTok: 1.2
|
|
259
|
+
}
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
id: "MiniMax-M2.1",
|
|
263
|
+
provider: "minimax",
|
|
264
|
+
api: "anthropic-messages",
|
|
265
|
+
displayName: "MiniMax M2.1",
|
|
266
|
+
baseUrl: "https://api.minimax.io/anthropic",
|
|
267
|
+
contextWindow: 204800,
|
|
268
|
+
maxOutputTokens: 131072,
|
|
269
|
+
modalities: ["text"],
|
|
270
|
+
reasoning: true,
|
|
271
|
+
cost: {
|
|
272
|
+
inputPerMTok: 0.3,
|
|
273
|
+
outputPerMTok: 1.2
|
|
274
|
+
}
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
id: "MiniMax-M2.5",
|
|
278
|
+
provider: "minimax",
|
|
279
|
+
api: "anthropic-messages",
|
|
280
|
+
displayName: "MiniMax M2.5",
|
|
281
|
+
baseUrl: "https://api.minimax.io/anthropic",
|
|
282
|
+
contextWindow: 204800,
|
|
283
|
+
maxOutputTokens: 131072,
|
|
284
|
+
modalities: ["text"],
|
|
285
|
+
reasoning: true,
|
|
286
|
+
cost: {
|
|
287
|
+
inputPerMTok: 0.3,
|
|
288
|
+
outputPerMTok: 1.2
|
|
289
|
+
}
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
id: "MiniMax-M2.7",
|
|
293
|
+
provider: "minimax",
|
|
294
|
+
api: "anthropic-messages",
|
|
295
|
+
displayName: "MiniMax M2.7",
|
|
296
|
+
baseUrl: "https://api.minimax.io/anthropic",
|
|
297
|
+
contextWindow: 204800,
|
|
298
|
+
maxOutputTokens: 131072,
|
|
299
|
+
modalities: ["text"],
|
|
300
|
+
reasoning: true,
|
|
301
|
+
cost: {
|
|
302
|
+
inputPerMTok: 0.3,
|
|
303
|
+
outputPerMTok: 1.2
|
|
304
|
+
}
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
id: "MiniMax-M3",
|
|
308
|
+
provider: "minimax",
|
|
309
|
+
api: "anthropic-messages",
|
|
310
|
+
displayName: "MiniMax M3",
|
|
311
|
+
baseUrl: "https://api.minimax.io/anthropic",
|
|
312
|
+
contextWindow: 1048576,
|
|
313
|
+
maxOutputTokens: 512e3,
|
|
314
|
+
modalities: ["text", "image"],
|
|
315
|
+
reasoning: true,
|
|
316
|
+
cost: {
|
|
317
|
+
inputPerMTok: 0.6,
|
|
318
|
+
outputPerMTok: 2.4,
|
|
319
|
+
cacheReadPerMTok: 0.12
|
|
320
|
+
}
|
|
321
|
+
},
|
|
243
322
|
// ── Ollama (local; pricing is zero — your own hardware) ─────────────────
|
|
244
323
|
{
|
|
245
324
|
id: "llama3.1:8b",
|
|
@@ -345,6 +424,19 @@ var SECRET_TABLE = {
|
|
|
345
424
|
envVars: ["MOONSHOT_API_KEY", "KIMI_API_KEY"],
|
|
346
425
|
hint: "Moonshot AI (Kimi) API key."
|
|
347
426
|
},
|
|
427
|
+
minimax: {
|
|
428
|
+
provider: "minimax",
|
|
429
|
+
scheme: "api-key",
|
|
430
|
+
envVars: ["MINIMAX_API_KEY"],
|
|
431
|
+
hint: "MiniMax global API key (api.minimax.io Anthropic-compatible)."
|
|
432
|
+
},
|
|
433
|
+
"minimax-cn": {
|
|
434
|
+
provider: "minimax-cn",
|
|
435
|
+
scheme: "api-key",
|
|
436
|
+
// Same key often works for both; CN-specific override first when set.
|
|
437
|
+
envVars: ["MINIMAX_CN_API_KEY", "MINIMAX_API_KEY"],
|
|
438
|
+
hint: "MiniMax China API key (api.minimaxi.com Anthropic-compatible)."
|
|
439
|
+
},
|
|
348
440
|
ollama: {
|
|
349
441
|
provider: "ollama",
|
|
350
442
|
scheme: "none",
|
|
@@ -1185,7 +1277,7 @@ function endpointFor(model) {
|
|
|
1185
1277
|
const base = (model.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
1186
1278
|
return `${base}/v1/messages`;
|
|
1187
1279
|
}
|
|
1188
|
-
async function postMessages(url, apiKey, body, signal) {
|
|
1280
|
+
async function postMessages(url, apiKey, body, signal, provider = "anthropic") {
|
|
1189
1281
|
let response;
|
|
1190
1282
|
try {
|
|
1191
1283
|
response = await fetch(url, {
|
|
@@ -1200,24 +1292,24 @@ async function postMessages(url, apiKey, body, signal) {
|
|
|
1200
1292
|
});
|
|
1201
1293
|
} catch (cause) {
|
|
1202
1294
|
if (signal?.aborted) {
|
|
1203
|
-
throw gatewayError("aborted",
|
|
1204
|
-
provider
|
|
1295
|
+
throw gatewayError("aborted", `request canceled before ${provider} responded`, {
|
|
1296
|
+
provider,
|
|
1205
1297
|
cause
|
|
1206
1298
|
});
|
|
1207
1299
|
}
|
|
1208
|
-
throw gatewayError("transport",
|
|
1300
|
+
throw gatewayError("transport", `network call to ${provider} failed`, { provider, cause });
|
|
1209
1301
|
}
|
|
1210
1302
|
if (!response.ok) {
|
|
1211
1303
|
const detail = await readErrorBody(response);
|
|
1212
1304
|
const kind = response.status === 401 || response.status === 403 ? "auth" : response.status === 429 ? "rate_limit" : "http";
|
|
1213
|
-
throw gatewayError(kind,
|
|
1214
|
-
provider
|
|
1305
|
+
throw gatewayError(kind, `${provider} returned HTTP ${response.status}${detail}`, {
|
|
1306
|
+
provider,
|
|
1215
1307
|
status: response.status
|
|
1216
1308
|
});
|
|
1217
1309
|
}
|
|
1218
1310
|
if (response.body === null) {
|
|
1219
|
-
throw gatewayError("transport",
|
|
1220
|
-
provider
|
|
1311
|
+
throw gatewayError("transport", `${provider} response arrived with no body`, {
|
|
1312
|
+
provider,
|
|
1221
1313
|
status: response.status
|
|
1222
1314
|
});
|
|
1223
1315
|
}
|
|
@@ -1239,11 +1331,13 @@ function asGatewayError(cause) {
|
|
|
1239
1331
|
}
|
|
1240
1332
|
function createanthropicConnector(deps2) {
|
|
1241
1333
|
const api = "anthropic-messages";
|
|
1242
|
-
async function requireKey(options) {
|
|
1243
|
-
const
|
|
1334
|
+
async function requireKey(model, options) {
|
|
1335
|
+
const provider = model.provider;
|
|
1336
|
+
const key = await deps2.resolveSecret(provider, options.apiKey);
|
|
1244
1337
|
if (key === void 0 || key === "") {
|
|
1245
|
-
|
|
1246
|
-
|
|
1338
|
+
const hint = provider === "minimax" || provider === "minimax-cn" ? "set MINIMAX_API_KEY (or MINIMAX_CN_API_KEY for CN) or pass options.apiKey" : "set ANTHROPIC_API_KEY or pass options.apiKey";
|
|
1339
|
+
throw gatewayError("auth", `no API key found for provider "${provider}" (${hint})`, {
|
|
1340
|
+
provider
|
|
1247
1341
|
});
|
|
1248
1342
|
}
|
|
1249
1343
|
return key;
|
|
@@ -1252,10 +1346,16 @@ function createanthropicConnector(deps2) {
|
|
|
1252
1346
|
return channelOf(async function* run2() {
|
|
1253
1347
|
const collected = [];
|
|
1254
1348
|
try {
|
|
1255
|
-
const apiKey = await requireKey(options);
|
|
1349
|
+
const apiKey = await requireKey(model, options);
|
|
1256
1350
|
const body = toAnthropicRequest(conversation, model, options);
|
|
1257
1351
|
body.stream = true;
|
|
1258
|
-
const response = await postMessages(
|
|
1352
|
+
const response = await postMessages(
|
|
1353
|
+
endpointFor(model),
|
|
1354
|
+
apiKey,
|
|
1355
|
+
body,
|
|
1356
|
+
options.signal,
|
|
1357
|
+
model.provider
|
|
1358
|
+
);
|
|
1259
1359
|
const wire = response.body;
|
|
1260
1360
|
const state = { toolIds: /* @__PURE__ */ new Map(), usage: { inputTokens: 0, outputTokens: 0 } };
|
|
1261
1361
|
for await (const event of sseEvents(wire, options.signal)) {
|
package/dist/tracing.js
CHANGED
|
@@ -231,6 +231,43 @@ var DEFAULT_SECRET_PATTERNS = Object.freeze([
|
|
|
231
231
|
label: "private-key-block-value",
|
|
232
232
|
// a PEM-armoured private key body
|
|
233
233
|
value: /-----BEGIN(?:[A-Z ]+)?PRIVATE KEY-----/
|
|
234
|
+
},
|
|
235
|
+
// -----------------------------------------------------------------------
|
|
236
|
+
// MCP / Zoho MCP additions.
|
|
237
|
+
// -----------------------------------------------------------------------
|
|
238
|
+
{
|
|
239
|
+
label: "mcp-url-key-name",
|
|
240
|
+
// mcp_url, mcpUrl, mcp_url_secret, MCP_URL, ZOHO_MCP_URL, ZOHO_MCP_TOKEN, etc.
|
|
241
|
+
key: /(?:mcp[_-]?url|zoho[_-]?mcp|mcp[_-]?token)/i
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
label: "pkce-verifier-key-name",
|
|
245
|
+
// code_verifier, codeVerifier, pkce_verifier, etc.
|
|
246
|
+
key: /(?:code[_-]?verifier|pkce[_-]?verifier)/i
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
label: "mcp-server-url-value",
|
|
250
|
+
// Zoho MCP URLs — the host is enough to make the URL sensitive.
|
|
251
|
+
value: /\bhttps?:\/\/(?:[A-Za-z0-9-]+\.)*mcp\.zoho\.(?:com|in|eu|net|com\.au|jp)\b[^\s"'<>]*/i
|
|
252
|
+
},
|
|
253
|
+
// -----------------------------------------------------------------------
|
|
254
|
+
// Sarvam MCP additions.
|
|
255
|
+
// -----------------------------------------------------------------------
|
|
256
|
+
{
|
|
257
|
+
label: "sarvam-api-key-key-name",
|
|
258
|
+
// SARVAM_API_KEY, sarvamApiKey, sarvam_api_key
|
|
259
|
+
key: /sarvam[_-]?api[_-]?key/i
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
label: "sarvam-api-key-value",
|
|
263
|
+
// dashboard-issued key shape if Sarvam ever uses a prefix; fallback so
|
|
264
|
+
// SARVAM_API_KEY=<anything> gets redacted even if no key pattern matched.
|
|
265
|
+
value: /SARVAM_API_KEY\s*=\s*[^\s"'<>]+/i
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
label: "api-subscription-key-header",
|
|
269
|
+
// Sarvam's REST auth header name.
|
|
270
|
+
value: /\bapi-subscription-key\s*[:=]\s*[A-Za-z0-9._~+/-]{8,}=*\b/i
|
|
234
271
|
}
|
|
235
272
|
]);
|
|
236
273
|
function isContainer(value) {
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Connect to Sarvam AI via the official `uvx sarvam-mcp` stdio server.
|
|
3
|
+
*
|
|
4
|
+
* No OAuth — auth is the `SARVAM_API_KEY` env var. We spawn the subprocess
|
|
5
|
+
* with the SDK-backed {@link MCPClient} (which already supports stdio),
|
|
6
|
+
* list the remote tools, and project them into a runtime {@link ToolBox}
|
|
7
|
+
* via {@link mcpClientToToolBox} using `options.id` (default `"sarvam"`)
|
|
8
|
+
* as the tool-name prefix so two MCP servers can never collide.
|
|
9
|
+
*/
|
|
10
|
+
import type { ConnectSarvamMcpOptions, SarvamMcpConnection } from "./types.js";
|
|
11
|
+
/**
|
|
12
|
+
* Open a Sarvam MCP stdio connection and return a ready-to-use toolbox + client.
|
|
13
|
+
*/
|
|
14
|
+
export declare function connectSarvamMcp(options: ConnectSarvamMcpOptions): Promise<SarvamMcpConnection>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for {@link connectSarvamMcp}.
|
|
3
|
+
*
|
|
4
|
+
* A small `FakeMCPClient` stands in for the SDK-backed client. We use
|
|
5
|
+
* `vi.mock` to redirect the `MCPClient` import in `./connect.js` to a
|
|
6
|
+
* factory that returns our fake — no subprocess, no `uvx` download, no
|
|
7
|
+
* Sarvam network call, no monkey-patching of live modules. The mock
|
|
8
|
+
* captures every constructor invocation into a shared holder so the
|
|
9
|
+
* assertions can pin exactly what the connector passed to `new MCPClient`.
|
|
10
|
+
*
|
|
11
|
+
* Mirrors the structure of {@link ../connectors-zoho/connectors-zoho.test.ts}
|
|
12
|
+
* so the two connectors share one test idiom.
|
|
13
|
+
*/
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public barrel for the Sarvam MCP connector.
|
|
3
|
+
*
|
|
4
|
+
* - {@link connectSarvamMcp} — the high-level "give me a working toolbox"
|
|
5
|
+
* entry point that takes a Sarvam API key (or env var) and spawns
|
|
6
|
+
* `uvx sarvam-mcp` over stdio.
|
|
7
|
+
* - {@link sarvamToolBoxFromClient} — the lower-level adapter for callers
|
|
8
|
+
* who already hold a connected {@link MCPClient}.
|
|
9
|
+
* - {@link ConnectSarvamMcpOptions} / {@link SarvamMcpConnection} — the
|
|
10
|
+
* public types for those two entry points.
|
|
11
|
+
*/
|
|
12
|
+
export { connectSarvamMcp } from "./connect.js";
|
|
13
|
+
export { sarvamToolBoxFromClient } from "./toolbox.js";
|
|
14
|
+
export type { ConnectSarvamMcpOptions, SarvamMcpConnection } from "./types.js";
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thin re-export wrapper so power users can also import just the toolbox
|
|
3
|
+
* adapter without going through {@link connectSarvamMcp}.
|
|
4
|
+
*
|
|
5
|
+
* `sarvamToolBoxFromClient` is equivalent to
|
|
6
|
+
* `mcpClientToToolBox(client, { namePrefix: options.id ?? "sarvam", ... })`
|
|
7
|
+
* — it just defaults the prefix to the Sarvam id.
|
|
8
|
+
*/
|
|
9
|
+
import type { McpToToolBoxOptions } from "../facade/mcp-core/toolbox-bridge.js";
|
|
10
|
+
import type { MCPClient } from "../facade/mcp-core/client.js";
|
|
11
|
+
import type { ToolBox } from "../runtime/contract/index.js";
|
|
12
|
+
/**
|
|
13
|
+
* Wrap a connected {@link MCPClient} as a runtime {@link ToolBox} with a
|
|
14
|
+
* Sarvam-friendly prefix. Equivalent to
|
|
15
|
+
* `mcpClientToToolBox(client, { namePrefix: options.id ?? "sarvam", ... })`.
|
|
16
|
+
*/
|
|
17
|
+
export declare function sarvamToolBoxFromClient(client: MCPClient, options?: {
|
|
18
|
+
id?: string;
|
|
19
|
+
} & Omit<McpToToolBoxOptions, "namePrefix">): Promise<ToolBox>;
|