@mutagent/cli 0.1.227 → 0.1.229
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/dist/bin/cli.js +553 -18
- package/dist/bin/cli.js.map +8 -5
- package/dist/index.js +102 -17
- package/dist/index.js.map +5 -4
- package/package.json +1 -1
package/dist/bin/cli.js
CHANGED
|
@@ -344,6 +344,91 @@ function buildCreateProviderBody(data) {
|
|
|
344
344
|
return body;
|
|
345
345
|
}
|
|
346
346
|
|
|
347
|
+
// src/lib/sdk-mappers.ts
|
|
348
|
+
import { Provider as SDKProviderEnum } from "@mutagent/sdk/models";
|
|
349
|
+
function isProviderType(value) {
|
|
350
|
+
return PROVIDER_TYPES.includes(value);
|
|
351
|
+
}
|
|
352
|
+
function narrowProviderType(value) {
|
|
353
|
+
return isProviderType(value) ? value : value;
|
|
354
|
+
}
|
|
355
|
+
function toIsoString(value) {
|
|
356
|
+
if (value === null || value === undefined)
|
|
357
|
+
return null;
|
|
358
|
+
return value instanceof Date ? value.toISOString() : value;
|
|
359
|
+
}
|
|
360
|
+
function toAgent(sdk) {
|
|
361
|
+
return {
|
|
362
|
+
id: sdk.id,
|
|
363
|
+
name: sdk.name,
|
|
364
|
+
slug: sdk.slug,
|
|
365
|
+
description: sdk.description,
|
|
366
|
+
systemPrompt: sdk.systemPrompt,
|
|
367
|
+
model: sdk.model,
|
|
368
|
+
maxTurns: sdk.maxTurns,
|
|
369
|
+
permissionMode: sdk.permissionMode,
|
|
370
|
+
allowedTools: sdk.allowedTools,
|
|
371
|
+
disallowedTools: sdk.disallowedTools,
|
|
372
|
+
status: sdk.status,
|
|
373
|
+
isPublic: sdk.isPublic,
|
|
374
|
+
metadata: sdk.metadata,
|
|
375
|
+
tags: sdk.tags,
|
|
376
|
+
createdBy: sdk.createdBy,
|
|
377
|
+
createdAt: toIsoString(sdk.createdAt),
|
|
378
|
+
updatedAt: toIsoString(sdk.updatedAt)
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
function toAgentList(sdk) {
|
|
382
|
+
return sdk.map(toAgent);
|
|
383
|
+
}
|
|
384
|
+
function toWorkspace(sdk) {
|
|
385
|
+
return {
|
|
386
|
+
id: sdk.id,
|
|
387
|
+
name: sdk.name,
|
|
388
|
+
description: sdk.description,
|
|
389
|
+
slug: sdk.slug,
|
|
390
|
+
isDefault: sdk.isDefault,
|
|
391
|
+
metadata: sdk.metadata,
|
|
392
|
+
createdBy: sdk.createdBy,
|
|
393
|
+
createdAt: toIsoString(sdk.createdAt),
|
|
394
|
+
updatedAt: toIsoString(sdk.updatedAt)
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
function toWorkspaceList(sdk) {
|
|
398
|
+
return sdk.map(toWorkspace);
|
|
399
|
+
}
|
|
400
|
+
function toProvider(sdk) {
|
|
401
|
+
return {
|
|
402
|
+
id: sdk.id,
|
|
403
|
+
name: sdk.name,
|
|
404
|
+
provider: narrowProviderType(sdk.provider),
|
|
405
|
+
hostedFamily: sdk.hostedFamily ?? null,
|
|
406
|
+
baseUrl: sdk.baseUrl,
|
|
407
|
+
isActive: sdk.isActive,
|
|
408
|
+
metadata: sdk.metadata,
|
|
409
|
+
createdBy: sdk.createdBy,
|
|
410
|
+
createdAt: toIsoString(sdk.createdAt),
|
|
411
|
+
updatedAt: toIsoString(sdk.updatedAt)
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
function toProviderList(sdk) {
|
|
415
|
+
return sdk.map(toProvider);
|
|
416
|
+
}
|
|
417
|
+
function toProviderTestResult(sdk) {
|
|
418
|
+
return {
|
|
419
|
+
success: sdk.success,
|
|
420
|
+
provider: sdk.provider ?? undefined,
|
|
421
|
+
latencyMs: sdk.latencyMs ?? undefined,
|
|
422
|
+
message: sdk.message,
|
|
423
|
+
error: sdk.error ?? undefined,
|
|
424
|
+
models: sdk.models ?? undefined
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
var PROVIDER_TYPES;
|
|
428
|
+
var init_sdk_mappers = __esm(() => {
|
|
429
|
+
PROVIDER_TYPES = Object.values(SDKProviderEnum);
|
|
430
|
+
});
|
|
431
|
+
|
|
347
432
|
// src/lib/sdk-client.ts
|
|
348
433
|
var exports_sdk_client = {};
|
|
349
434
|
__export(exports_sdk_client, {
|
|
@@ -467,7 +552,7 @@ class SDKClientWrapper {
|
|
|
467
552
|
status: filters?.status
|
|
468
553
|
});
|
|
469
554
|
return {
|
|
470
|
-
data: response.result.data,
|
|
555
|
+
data: toAgentList(response.result.data),
|
|
471
556
|
total: response.result.total
|
|
472
557
|
};
|
|
473
558
|
} catch (error) {
|
|
@@ -479,7 +564,7 @@ class SDKClientWrapper {
|
|
|
479
564
|
const response = await this.sdk.agents.getAgent({
|
|
480
565
|
id: parseInt(id, 10)
|
|
481
566
|
});
|
|
482
|
-
return response;
|
|
567
|
+
return toAgent(response);
|
|
483
568
|
} catch (error) {
|
|
484
569
|
this.handleError(error);
|
|
485
570
|
}
|
|
@@ -501,7 +586,7 @@ class SDKClientWrapper {
|
|
|
501
586
|
metadata: data.metadata ?? undefined,
|
|
502
587
|
tags: data.tags ?? undefined
|
|
503
588
|
});
|
|
504
|
-
return response;
|
|
589
|
+
return toAgent(response);
|
|
505
590
|
} catch (error) {
|
|
506
591
|
this.handleError(error);
|
|
507
592
|
}
|
|
@@ -525,7 +610,7 @@ class SDKClientWrapper {
|
|
|
525
610
|
tags: data.tags ?? undefined
|
|
526
611
|
}
|
|
527
612
|
});
|
|
528
|
-
return response;
|
|
613
|
+
return toAgent(response);
|
|
529
614
|
} catch (error) {
|
|
530
615
|
this.handleError(error);
|
|
531
616
|
}
|
|
@@ -544,7 +629,7 @@ class SDKClientWrapper {
|
|
|
544
629
|
const response = await this.sdk.workspaces.listWorkspaces({
|
|
545
630
|
includeInactive: false
|
|
546
631
|
});
|
|
547
|
-
const workspaces = response.workspaces;
|
|
632
|
+
const workspaces = toWorkspaceList(response.workspaces);
|
|
548
633
|
const offset = filters?.offset ?? 0;
|
|
549
634
|
const limit = filters?.limit ?? workspaces.length;
|
|
550
635
|
return {
|
|
@@ -560,7 +645,7 @@ class SDKClientWrapper {
|
|
|
560
645
|
const response = await this.sdk.workspaces.getWorkspace({
|
|
561
646
|
wsId: id
|
|
562
647
|
});
|
|
563
|
-
return response;
|
|
648
|
+
return toWorkspace(response);
|
|
564
649
|
} catch (error) {
|
|
565
650
|
this.handleError(error);
|
|
566
651
|
}
|
|
@@ -571,9 +656,8 @@ class SDKClientWrapper {
|
|
|
571
656
|
provider: filters?.type,
|
|
572
657
|
includeInactive: true
|
|
573
658
|
});
|
|
574
|
-
const
|
|
575
|
-
const
|
|
576
|
-
const total = raw.result?.total ?? raw.total ?? configs.length;
|
|
659
|
+
const configs = toProviderList(response.configs);
|
|
660
|
+
const total = response.total;
|
|
577
661
|
const offset = filters?.offset ?? 0;
|
|
578
662
|
const limit = filters?.limit ?? configs.length;
|
|
579
663
|
return {
|
|
@@ -589,7 +673,7 @@ class SDKClientWrapper {
|
|
|
589
673
|
const response = await this.sdk.providerConfigs.getProvider({
|
|
590
674
|
id
|
|
591
675
|
});
|
|
592
|
-
return response;
|
|
676
|
+
return toProvider(response);
|
|
593
677
|
} catch (error) {
|
|
594
678
|
this.handleError(error);
|
|
595
679
|
}
|
|
@@ -628,19 +712,19 @@ class SDKClientWrapper {
|
|
|
628
712
|
if (this.workspaceResolution === "none" && this.organizationId) {
|
|
629
713
|
try {
|
|
630
714
|
const response = await this.sdk.workspaces.listWorkspaces({ includeInactive: false });
|
|
631
|
-
const workspaces = response.workspaces;
|
|
715
|
+
const workspaces = toWorkspaceList(response.workspaces);
|
|
632
716
|
if (workspaces.length === 1 && workspaces[0]) {
|
|
633
|
-
this.workspaceId =
|
|
717
|
+
this.workspaceId = workspaces[0].id;
|
|
634
718
|
this.workspaceResolution = "sole";
|
|
635
719
|
} else if (workspaces.length > 1) {
|
|
636
720
|
const defaultWs = workspaces.find((ws) => ws.isDefault);
|
|
637
721
|
if (defaultWs) {
|
|
638
|
-
this.workspaceId =
|
|
722
|
+
this.workspaceId = defaultWs.id;
|
|
639
723
|
this.workspaceResolution = "configured";
|
|
640
724
|
} else {
|
|
641
725
|
const first = workspaces[0] ?? undefined;
|
|
642
726
|
if (first) {
|
|
643
|
-
this.workspaceId = this.workspaceId ??
|
|
727
|
+
this.workspaceId = this.workspaceId ?? first.id;
|
|
644
728
|
this.workspaceResolution = "ambiguous";
|
|
645
729
|
}
|
|
646
730
|
}
|
|
@@ -665,7 +749,7 @@ class SDKClientWrapper {
|
|
|
665
749
|
const response = await this.sdk.providerConfigs.testProvider({
|
|
666
750
|
id
|
|
667
751
|
});
|
|
668
|
-
return response;
|
|
752
|
+
return toProviderTestResult(response);
|
|
669
753
|
} catch (error) {
|
|
670
754
|
this.handleError(error);
|
|
671
755
|
}
|
|
@@ -696,7 +780,7 @@ class SDKClientWrapper {
|
|
|
696
780
|
baseUrl: data.baseUrl
|
|
697
781
|
}
|
|
698
782
|
});
|
|
699
|
-
return { ...response, workspaceId };
|
|
783
|
+
return { ...toProvider(response), workspaceId };
|
|
700
784
|
} catch (error) {
|
|
701
785
|
this.handleError(error);
|
|
702
786
|
}
|
|
@@ -778,6 +862,7 @@ var sdkClient = null;
|
|
|
778
862
|
var init_sdk_client = __esm(() => {
|
|
779
863
|
init_errors();
|
|
780
864
|
init_config();
|
|
865
|
+
init_sdk_mappers();
|
|
781
866
|
});
|
|
782
867
|
|
|
783
868
|
// src/bin/cli.ts
|
|
@@ -2253,6 +2338,442 @@ import { Provider as ProviderCatalogId } from "@mutagent/sdk/models";
|
|
|
2253
2338
|
init_sdk_client();
|
|
2254
2339
|
import chalk8 from "chalk";
|
|
2255
2340
|
init_errors();
|
|
2341
|
+
|
|
2342
|
+
// src/lib/api-format.ts
|
|
2343
|
+
init_errors();
|
|
2344
|
+
|
|
2345
|
+
// ../mutagent/src/modules/tenancy/providers/catalog.ts
|
|
2346
|
+
var apiKeyField = (description) => ({
|
|
2347
|
+
name: "apiKey",
|
|
2348
|
+
label: "API key",
|
|
2349
|
+
required: true,
|
|
2350
|
+
treatment: "secret",
|
|
2351
|
+
validation: { rule: "non-empty-string", minLength: 8 },
|
|
2352
|
+
description
|
|
2353
|
+
});
|
|
2354
|
+
var baseUrlOverrideField = {
|
|
2355
|
+
name: "baseUrl",
|
|
2356
|
+
label: "Base URL override",
|
|
2357
|
+
required: false,
|
|
2358
|
+
treatment: "plain",
|
|
2359
|
+
validation: { rule: "https-url" },
|
|
2360
|
+
description: "Route requests through a proxy or a regional endpoint instead of the default one."
|
|
2361
|
+
};
|
|
2362
|
+
var modelAllowListField = {
|
|
2363
|
+
name: "modelAllowList",
|
|
2364
|
+
label: "Model allow-list",
|
|
2365
|
+
required: false,
|
|
2366
|
+
treatment: "plain",
|
|
2367
|
+
validation: { rule: "string-list" },
|
|
2368
|
+
description: "Narrow the models this configuration offers. Entries outside the provider policy are ignored."
|
|
2369
|
+
};
|
|
2370
|
+
var directApiKeyFields = (keyDescription) => [
|
|
2371
|
+
apiKeyField(keyDescription),
|
|
2372
|
+
baseUrlOverrideField,
|
|
2373
|
+
modelAllowListField
|
|
2374
|
+
];
|
|
2375
|
+
var azureFields = [
|
|
2376
|
+
{
|
|
2377
|
+
name: "resourceEndpoint",
|
|
2378
|
+
label: "Resource endpoint",
|
|
2379
|
+
required: true,
|
|
2380
|
+
treatment: "plain",
|
|
2381
|
+
validation: { rule: "https-url" },
|
|
2382
|
+
description: "The Azure resource endpoint, e.g. https://my-resource.openai.azure.com."
|
|
2383
|
+
},
|
|
2384
|
+
apiKeyField("The key issued for the Azure resource."),
|
|
2385
|
+
{
|
|
2386
|
+
name: "deploymentName",
|
|
2387
|
+
label: "Deployment name",
|
|
2388
|
+
required: true,
|
|
2389
|
+
treatment: "plain",
|
|
2390
|
+
validation: { rule: "non-empty-string", minLength: 1 },
|
|
2391
|
+
description: "Azure addresses a model by the name given to its deployment, not by model id."
|
|
2392
|
+
},
|
|
2393
|
+
{
|
|
2394
|
+
name: "apiVersion",
|
|
2395
|
+
label: "API version",
|
|
2396
|
+
required: false,
|
|
2397
|
+
treatment: "plain",
|
|
2398
|
+
validation: {
|
|
2399
|
+
rule: "pattern",
|
|
2400
|
+
pattern: "^\\d{4}-\\d{2}-\\d{2}(-preview)?$",
|
|
2401
|
+
hint: "An ISO date, optionally suffixed -preview.",
|
|
2402
|
+
examples: ["2024-08-01-preview", "2023-06-01", "2025-01-01"],
|
|
2403
|
+
counterExamples: ["2024-8-1", "24-08-01", "2024-08-01-beta", "latest"]
|
|
2404
|
+
},
|
|
2405
|
+
description: "Pin the Azure API version. Defaults to the current stable version when omitted."
|
|
2406
|
+
}
|
|
2407
|
+
];
|
|
2408
|
+
var vertexFields = [
|
|
2409
|
+
{
|
|
2410
|
+
name: "projectId",
|
|
2411
|
+
label: "Project ID",
|
|
2412
|
+
required: true,
|
|
2413
|
+
treatment: "plain",
|
|
2414
|
+
validation: {
|
|
2415
|
+
rule: "pattern",
|
|
2416
|
+
pattern: "^[a-z][a-z0-9-]{4,28}[a-z0-9]$",
|
|
2417
|
+
hint: "A Google Cloud project ID: 6 to 30 lowercase characters, starting with a letter.",
|
|
2418
|
+
examples: ["my-project-123", "abcdef", "my-gcp-project"],
|
|
2419
|
+
counterExamples: ["ab", "My-Project", "1project", "my_project"]
|
|
2420
|
+
},
|
|
2421
|
+
description: "The Google Cloud project that holds the Vertex AI entitlement."
|
|
2422
|
+
},
|
|
2423
|
+
{
|
|
2424
|
+
name: "region",
|
|
2425
|
+
label: "Region",
|
|
2426
|
+
required: true,
|
|
2427
|
+
treatment: "plain",
|
|
2428
|
+
validation: {
|
|
2429
|
+
rule: "pattern",
|
|
2430
|
+
pattern: "^(global|(?:us|europe|asia|australia|northamerica|southamerica|africa|me)-[a-z]+\\d+)$",
|
|
2431
|
+
hint: "A Vertex location: a continent prefix, a direction and an index — or `global`.",
|
|
2432
|
+
examples: [
|
|
2433
|
+
"us-central1",
|
|
2434
|
+
"europe-west4",
|
|
2435
|
+
"europe-west12",
|
|
2436
|
+
"asia-northeast1",
|
|
2437
|
+
"northamerica-northeast1",
|
|
2438
|
+
"southamerica-east1",
|
|
2439
|
+
"australia-southeast1",
|
|
2440
|
+
"africa-south1",
|
|
2441
|
+
"me-central2",
|
|
2442
|
+
"global"
|
|
2443
|
+
],
|
|
2444
|
+
counterExamples: ["zz-qqqqqq9", "us-central", "US-CENTRAL1", "us_central1", "1-west1"]
|
|
2445
|
+
},
|
|
2446
|
+
description: "The Vertex location the models are served from."
|
|
2447
|
+
},
|
|
2448
|
+
{
|
|
2449
|
+
name: "serviceAccountKey",
|
|
2450
|
+
label: "Service-account credential",
|
|
2451
|
+
required: true,
|
|
2452
|
+
treatment: "secret",
|
|
2453
|
+
validation: { rule: "json-object" },
|
|
2454
|
+
description: "The service-account key JSON granting Vertex AI access to the project."
|
|
2455
|
+
},
|
|
2456
|
+
modelAllowListField
|
|
2457
|
+
];
|
|
2458
|
+
var PROVIDER_CATALOG = [
|
|
2459
|
+
{
|
|
2460
|
+
id: "openai",
|
|
2461
|
+
label: "OpenAI",
|
|
2462
|
+
kind: "direct",
|
|
2463
|
+
credentialFields: directApiKeyFields("An OpenAI API key, issued from the OpenAI platform."),
|
|
2464
|
+
modelPolicy: {
|
|
2465
|
+
mode: "floor",
|
|
2466
|
+
floor: "5.5",
|
|
2467
|
+
knownMembers: ["gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna", "gpt-5.5"],
|
|
2468
|
+
summary: "GPT models at or above 5.5. FR-CORE-008 states the floor and then enumerates the members current at writing; the floor is the rule, the enumeration is the snapshot."
|
|
2469
|
+
},
|
|
2470
|
+
description: "GPT models served directly by OpenAI."
|
|
2471
|
+
},
|
|
2472
|
+
{
|
|
2473
|
+
id: "anthropic",
|
|
2474
|
+
label: "Anthropic",
|
|
2475
|
+
kind: "direct",
|
|
2476
|
+
credentialFields: directApiKeyFields("An Anthropic API key, issued from the Anthropic console."),
|
|
2477
|
+
modelPolicy: {
|
|
2478
|
+
mode: "explicit",
|
|
2479
|
+
models: [
|
|
2480
|
+
"claude-opus-5",
|
|
2481
|
+
"claude-sonnet-5",
|
|
2482
|
+
"claude-fable-5",
|
|
2483
|
+
"claude-opus-4-8",
|
|
2484
|
+
"claude-haiku-4-5"
|
|
2485
|
+
],
|
|
2486
|
+
summary: "The Claude 5 family, plus Opus 4.8 and Haiku 4.5."
|
|
2487
|
+
},
|
|
2488
|
+
description: "Claude models served directly by Anthropic."
|
|
2489
|
+
},
|
|
2490
|
+
{
|
|
2491
|
+
id: "google",
|
|
2492
|
+
label: "Google Gemini",
|
|
2493
|
+
kind: "direct",
|
|
2494
|
+
credentialFields: directApiKeyFields("A Google AI Studio API key."),
|
|
2495
|
+
modelPolicy: {
|
|
2496
|
+
mode: "floor",
|
|
2497
|
+
floor: "3.1",
|
|
2498
|
+
summary: "Gemini 3.1 Pro and above. The floor is 3.1; nothing older is offered."
|
|
2499
|
+
},
|
|
2500
|
+
description: "Gemini models served directly by Google AI Studio."
|
|
2501
|
+
},
|
|
2502
|
+
{
|
|
2503
|
+
id: "moonshot",
|
|
2504
|
+
label: "Moonshot AI",
|
|
2505
|
+
kind: "direct",
|
|
2506
|
+
credentialFields: directApiKeyFields("A Moonshot AI platform API key."),
|
|
2507
|
+
modelPolicy: {
|
|
2508
|
+
mode: "explicit",
|
|
2509
|
+
models: ["kimi-k3"],
|
|
2510
|
+
summary: "Kimi K3, the 1M-context model. The 256K models are all K2-generation and are not offered."
|
|
2511
|
+
},
|
|
2512
|
+
description: "Kimi models served directly by Moonshot AI."
|
|
2513
|
+
},
|
|
2514
|
+
{
|
|
2515
|
+
id: "glm",
|
|
2516
|
+
label: "z.ai (GLM)",
|
|
2517
|
+
kind: "direct",
|
|
2518
|
+
credentialFields: directApiKeyFields("A z.ai API key."),
|
|
2519
|
+
modelPolicy: {
|
|
2520
|
+
mode: "explicit",
|
|
2521
|
+
models: ["glm-5.2"],
|
|
2522
|
+
summary: "GLM-5.2."
|
|
2523
|
+
},
|
|
2524
|
+
description: "GLM models served directly by z.ai."
|
|
2525
|
+
},
|
|
2526
|
+
{
|
|
2527
|
+
id: "deepseek",
|
|
2528
|
+
label: "DeepSeek",
|
|
2529
|
+
kind: "direct",
|
|
2530
|
+
credentialFields: directApiKeyFields("A DeepSeek platform API key."),
|
|
2531
|
+
modelPolicy: {
|
|
2532
|
+
mode: "explicit",
|
|
2533
|
+
models: ["deepseek-v4-flash", "deepseek-v4-pro"],
|
|
2534
|
+
summary: "The DeepSeek V4 pair — Flash and Pro."
|
|
2535
|
+
},
|
|
2536
|
+
description: "DeepSeek models served directly by DeepSeek."
|
|
2537
|
+
},
|
|
2538
|
+
{
|
|
2539
|
+
id: "xai",
|
|
2540
|
+
label: "xAI",
|
|
2541
|
+
kind: "direct",
|
|
2542
|
+
credentialFields: directApiKeyFields("An xAI API key."),
|
|
2543
|
+
modelPolicy: {
|
|
2544
|
+
mode: "floor",
|
|
2545
|
+
floor: "4.5",
|
|
2546
|
+
summary: "Grok 4.5 and above. The floor is 4.5; nothing older is offered."
|
|
2547
|
+
},
|
|
2548
|
+
description: "Grok models served directly by xAI."
|
|
2549
|
+
},
|
|
2550
|
+
{
|
|
2551
|
+
id: "azure",
|
|
2552
|
+
label: "Azure",
|
|
2553
|
+
kind: "gateway",
|
|
2554
|
+
hostedFamilies: ["openai", "anthropic"],
|
|
2555
|
+
credentialFields: azureFields,
|
|
2556
|
+
modelPolicy: {
|
|
2557
|
+
mode: "derived",
|
|
2558
|
+
from: ["openai", "anthropic"],
|
|
2559
|
+
addressing: {
|
|
2560
|
+
openai: {
|
|
2561
|
+
scheme: "deployment-name",
|
|
2562
|
+
pattern: "^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$",
|
|
2563
|
+
examples: ["my-gpt-5-6-deployment", "prod_gpt", "gpt56sol"],
|
|
2564
|
+
counterExamples: ["gpt-5.6-sol", "claude-opus-5@20260115", "has space", ""]
|
|
2565
|
+
},
|
|
2566
|
+
anthropic: {
|
|
2567
|
+
scheme: "deployment-name",
|
|
2568
|
+
pattern: "^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$",
|
|
2569
|
+
examples: ["my-claude-deployment", "prod_claude"],
|
|
2570
|
+
counterExamples: ["claude-opus-5@20260115", "gpt-5.6-sol", "has space", ""]
|
|
2571
|
+
}
|
|
2572
|
+
},
|
|
2573
|
+
summary: "The OpenAI and Anthropic rosters, each model addressed by the name of its Azure deployment."
|
|
2574
|
+
},
|
|
2575
|
+
description: "Azure AI Foundry, hosting OpenAI and Anthropic models. One configuration per hosted family."
|
|
2576
|
+
},
|
|
2577
|
+
{
|
|
2578
|
+
id: "vertex",
|
|
2579
|
+
label: "Google Vertex",
|
|
2580
|
+
kind: "gateway",
|
|
2581
|
+
hostedFamilies: ["gemini", "anthropic"],
|
|
2582
|
+
credentialFields: vertexFields,
|
|
2583
|
+
modelPolicy: {
|
|
2584
|
+
mode: "derived",
|
|
2585
|
+
from: ["gemini", "anthropic"],
|
|
2586
|
+
addressing: {
|
|
2587
|
+
gemini: {
|
|
2588
|
+
scheme: "plain",
|
|
2589
|
+
pattern: "^(?!.*@)[a-zA-Z0-9][a-zA-Z0-9.\\-]*$",
|
|
2590
|
+
examples: ["gemini-3.1-pro", "gemini-3.1-flash", "gemini-3.1-pro-preview"],
|
|
2591
|
+
counterExamples: [
|
|
2592
|
+
"gemini-3.1-pro@20260115",
|
|
2593
|
+
"us.anthropic.claude-opus-5-v1:0",
|
|
2594
|
+
"has space",
|
|
2595
|
+
""
|
|
2596
|
+
]
|
|
2597
|
+
},
|
|
2598
|
+
anthropic: {
|
|
2599
|
+
scheme: "dated",
|
|
2600
|
+
pattern: "^[a-zA-Z0-9][a-zA-Z0-9.\\-]*@\\d{8}$",
|
|
2601
|
+
examples: ["claude-opus-5@20260115", "claude-sonnet-5@20251022"],
|
|
2602
|
+
counterExamples: [
|
|
2603
|
+
"claude-opus-5",
|
|
2604
|
+
"claude-opus-5@",
|
|
2605
|
+
"claude-opus-5@2026",
|
|
2606
|
+
"gemini-3.1-pro"
|
|
2607
|
+
]
|
|
2608
|
+
}
|
|
2609
|
+
},
|
|
2610
|
+
summary: "The Gemini and Anthropic rosters. Anthropic models are @-dated on Vertex; Gemini models are not."
|
|
2611
|
+
},
|
|
2612
|
+
description: "Google Vertex AI, hosting Gemini and Anthropic models. One configuration per hosted family."
|
|
2613
|
+
},
|
|
2614
|
+
{
|
|
2615
|
+
id: "bedrock",
|
|
2616
|
+
label: "AWS Bedrock",
|
|
2617
|
+
kind: "gateway",
|
|
2618
|
+
hostedFamilies: ["anthropic"],
|
|
2619
|
+
credentialFields: [
|
|
2620
|
+
{
|
|
2621
|
+
name: "region",
|
|
2622
|
+
label: "Region",
|
|
2623
|
+
required: true,
|
|
2624
|
+
treatment: "plain",
|
|
2625
|
+
validation: {
|
|
2626
|
+
rule: "pattern",
|
|
2627
|
+
pattern: "^[a-z]{2}(-gov)?-[a-z]+-\\d+$",
|
|
2628
|
+
hint: "An AWS region: a two-letter geography, a direction and an index.",
|
|
2629
|
+
examples: [
|
|
2630
|
+
"us-east-1",
|
|
2631
|
+
"eu-central-1",
|
|
2632
|
+
"ap-southeast-1",
|
|
2633
|
+
"sa-east-1",
|
|
2634
|
+
"me-south-1",
|
|
2635
|
+
"af-south-1",
|
|
2636
|
+
"il-central-1",
|
|
2637
|
+
"mx-central-1",
|
|
2638
|
+
"us-gov-west-1"
|
|
2639
|
+
],
|
|
2640
|
+
counterExamples: ["us-east", "US-EAST-1", "useast1", "europe-west4"]
|
|
2641
|
+
},
|
|
2642
|
+
description: "The AWS region the Bedrock models are invoked in."
|
|
2643
|
+
},
|
|
2644
|
+
{
|
|
2645
|
+
name: "apiKey",
|
|
2646
|
+
label: "Bearer API key",
|
|
2647
|
+
required: true,
|
|
2648
|
+
treatment: "secret",
|
|
2649
|
+
validation: {
|
|
2650
|
+
rule: "pattern",
|
|
2651
|
+
pattern: "^(?!AKIA)[^\\s:]+$",
|
|
2652
|
+
hint: "A single opaque bearer token. Long-lived AWS access key and secret pairs are not accepted.",
|
|
2653
|
+
examples: ["bedrock-api-key-abc123", "ABSKQmVkcm9ja0FQSUtleQ=="],
|
|
2654
|
+
counterExamples: [
|
|
2655
|
+
"AKIAIOSFODNN7EXAMPLE",
|
|
2656
|
+
"AKIAIOSFODNN7EXAMPLE:wJalrXUtnFEMI/K7MDENG",
|
|
2657
|
+
"someid:somesecret",
|
|
2658
|
+
"has space"
|
|
2659
|
+
]
|
|
2660
|
+
},
|
|
2661
|
+
description: "A Bedrock bearer API key. This is the only credential type Bedrock accepts here."
|
|
2662
|
+
},
|
|
2663
|
+
{
|
|
2664
|
+
name: "inferenceProfile",
|
|
2665
|
+
label: "Inference profile",
|
|
2666
|
+
required: false,
|
|
2667
|
+
treatment: "plain",
|
|
2668
|
+
validation: { rule: "non-empty-string", minLength: 1 },
|
|
2669
|
+
description: "Pin a cross-region inference profile. Defaults to the profile for the configured region."
|
|
2670
|
+
}
|
|
2671
|
+
],
|
|
2672
|
+
modelPolicy: {
|
|
2673
|
+
mode: "derived",
|
|
2674
|
+
from: ["anthropic"],
|
|
2675
|
+
addressing: {
|
|
2676
|
+
anthropic: {
|
|
2677
|
+
scheme: "inference-profile",
|
|
2678
|
+
pattern: "^(us|eu|apac)\\.[a-z0-9-]+\\.[a-zA-Z0-9.\\-]+(:\\d+)?$",
|
|
2679
|
+
examples: [
|
|
2680
|
+
"us.anthropic.claude-opus-5-v1:0",
|
|
2681
|
+
"eu.anthropic.claude-sonnet-5-v1:0",
|
|
2682
|
+
"apac.anthropic.claude-haiku-4-5-v1:0"
|
|
2683
|
+
],
|
|
2684
|
+
counterExamples: [
|
|
2685
|
+
"anthropic.claude-opus-5-v1:0",
|
|
2686
|
+
"claude-opus-5",
|
|
2687
|
+
"claude-opus-5@20260115"
|
|
2688
|
+
]
|
|
2689
|
+
}
|
|
2690
|
+
},
|
|
2691
|
+
summary: "The Anthropic roster, addressed as region-prefixed inference-profile IDs."
|
|
2692
|
+
},
|
|
2693
|
+
description: "AWS Bedrock, hosting Anthropic models. Bearer API key only."
|
|
2694
|
+
},
|
|
2695
|
+
{
|
|
2696
|
+
id: "custom",
|
|
2697
|
+
label: "Custom (OpenAI or Anthropic compatible)",
|
|
2698
|
+
kind: "direct",
|
|
2699
|
+
credentialFields: [
|
|
2700
|
+
{
|
|
2701
|
+
name: "baseUrl",
|
|
2702
|
+
label: "Base URL",
|
|
2703
|
+
required: true,
|
|
2704
|
+
treatment: "plain",
|
|
2705
|
+
validation: { rule: "https-url" },
|
|
2706
|
+
description: "The endpoint serving the API. Pick its wire format below."
|
|
2707
|
+
},
|
|
2708
|
+
apiKeyField("The key the endpoint expects, sent as a bearer token."),
|
|
2709
|
+
{
|
|
2710
|
+
name: "wireFormat",
|
|
2711
|
+
label: "Wire format",
|
|
2712
|
+
required: false,
|
|
2713
|
+
treatment: "plain",
|
|
2714
|
+
validation: { rule: "one-of", values: ["openai", "anthropic"] },
|
|
2715
|
+
description: "Whether the endpoint speaks the OpenAI or the Anthropic request shape. Defaults to OpenAI when left unset — an endpoint that expects Anthropic's shape needs this set to 'anthropic'."
|
|
2716
|
+
},
|
|
2717
|
+
modelAllowListField
|
|
2718
|
+
],
|
|
2719
|
+
modelPolicy: {
|
|
2720
|
+
mode: "open",
|
|
2721
|
+
summary: "Whatever the configured endpoint publishes."
|
|
2722
|
+
},
|
|
2723
|
+
description: "Any endpoint speaking an OpenAI-compatible or Anthropic-compatible API — self-hosted or third-party."
|
|
2724
|
+
}
|
|
2725
|
+
];
|
|
2726
|
+
var CATALOG_BY_ID = new Map(PROVIDER_CATALOG.map((entry) => [entry.id, entry]));
|
|
2727
|
+
function getProviderCatalogEntry(id) {
|
|
2728
|
+
return CATALOG_BY_ID.get(id);
|
|
2729
|
+
}
|
|
2730
|
+
function getCredentialField(entry, name) {
|
|
2731
|
+
return entry.credentialFields.find((field) => field.name === name);
|
|
2732
|
+
}
|
|
2733
|
+
// src/lib/api-format.ts
|
|
2734
|
+
var API_FORMAT_WIRE_NAME = "wireFormat";
|
|
2735
|
+
function apiFormatValuesFor(providerType) {
|
|
2736
|
+
const entry = getProviderCatalogEntry(providerType);
|
|
2737
|
+
if (!entry)
|
|
2738
|
+
return;
|
|
2739
|
+
const field = getCredentialField(entry, API_FORMAT_WIRE_NAME);
|
|
2740
|
+
if (!field)
|
|
2741
|
+
return;
|
|
2742
|
+
return field.validation.rule === "one-of" ? field.validation.values : undefined;
|
|
2743
|
+
}
|
|
2744
|
+
function providerAcceptsApiFormat(providerType) {
|
|
2745
|
+
const entry = getProviderCatalogEntry(providerType);
|
|
2746
|
+
return entry !== undefined && entryAcceptsApiFormat(entry);
|
|
2747
|
+
}
|
|
2748
|
+
function entryAcceptsApiFormat(entry) {
|
|
2749
|
+
return getCredentialField(entry, API_FORMAT_WIRE_NAME) !== undefined;
|
|
2750
|
+
}
|
|
2751
|
+
function providersAcceptingApiFormat(catalog = PROVIDER_CATALOG) {
|
|
2752
|
+
return catalog.filter(entryAcceptsApiFormat).map((entry) => entry.id);
|
|
2753
|
+
}
|
|
2754
|
+
function apiFormatHelpText() {
|
|
2755
|
+
const accepting = providersAcceptingApiFormat();
|
|
2756
|
+
if (accepting.length === 0) {
|
|
2757
|
+
return "API format spoken by the endpoint (no catalog entry currently declares one)";
|
|
2758
|
+
}
|
|
2759
|
+
const values = [...new Set(accepting.flatMap((id) => apiFormatValuesFor(id) ?? []))];
|
|
2760
|
+
const scope = `${accepting.join(", ")} only`;
|
|
2761
|
+
return values.length > 0 ? `API format the endpoint speaks — ${scope}: ${values.join(", ")}` : `API format the endpoint speaks — ${scope}`;
|
|
2762
|
+
}
|
|
2763
|
+
function validateApiFormat(providerType, value) {
|
|
2764
|
+
if (!providerAcceptsApiFormat(providerType)) {
|
|
2765
|
+
const accepting = providersAcceptingApiFormat();
|
|
2766
|
+
throw new MutagentError("API_FORMAT_NOT_APPLICABLE", accepting.length > 0 ? `--api-format applies only to ${accepting.join(", ")}. '${providerType}' speaks its own API.` : `--api-format applies to no provider in the catalog. '${providerType}' speaks its own API.`, accepting.length > 0 ? `Remove --api-format, or use --provider ${accepting.join(" | ")}` : "Remove --api-format");
|
|
2767
|
+
}
|
|
2768
|
+
const values = apiFormatValuesFor(providerType);
|
|
2769
|
+
if (!values)
|
|
2770
|
+
return;
|
|
2771
|
+
if (!values.includes(value)) {
|
|
2772
|
+
throw new MutagentError("INVALID_API_FORMAT", `'${value}' is not an API format that '${providerType}' speaks.`, `${providerType} accepts: ${values.join(", ")}`);
|
|
2773
|
+
}
|
|
2774
|
+
}
|
|
2775
|
+
|
|
2776
|
+
// src/commands/providers/add.ts
|
|
2256
2777
|
var GATEWAY_HOSTED_FAMILIES = {
|
|
2257
2778
|
azure: ["openai", "anthropic"],
|
|
2258
2779
|
vertex: ["gemini", "anthropic"],
|
|
@@ -2277,10 +2798,12 @@ function collectCredentialFields(options) {
|
|
|
2277
2798
|
fields.projectId = options.projectId;
|
|
2278
2799
|
if (options.region)
|
|
2279
2800
|
fields.region = options.region;
|
|
2801
|
+
if (options.apiFormat)
|
|
2802
|
+
fields[API_FORMAT_WIRE_NAME] = options.apiFormat;
|
|
2280
2803
|
return fields;
|
|
2281
2804
|
}
|
|
2282
2805
|
function registerAddCommand(parent) {
|
|
2283
|
-
parent.command("add").description("Add a new provider configuration").requiredOption("-p, --provider <type>", "Provider type (openai, anthropic, azure, ...)").requiredOption("-n, --name <name>", "Display name for this provider").option("-k, --api-key <key>", "API key for the provider (every entry except Google Vertex)").option("--service-account-key <json>", "Google Vertex service-account credential JSON").option("--hosted-family <family>", `Hosted model family for gateway providers: ${HOSTED_FAMILIES.join(", ")}`).option("--base-url <url>", "Custom base URL for the provider API").option("--resource-endpoint <url>", "Azure resource endpoint").option("--deployment-name <name>", "Azure deployment name").option("--api-version <version>", "Azure API version (e.g. 2024-08-01-preview)").option("--project-id <id>", "Google Vertex project ID").option("--region <region>", "Region (Vertex location, or AWS Bedrock region)").option("--set-default", "Set as the default provider of its kind").addHelpText("after", `
|
|
2806
|
+
parent.command("add").description("Add a new provider configuration").requiredOption("-p, --provider <type>", "Provider type (openai, anthropic, azure, ...)").requiredOption("-n, --name <name>", "Display name for this provider").option("-k, --api-key <key>", "API key for the provider (every entry except Google Vertex)").option("--service-account-key <json>", "Google Vertex service-account credential JSON").option("--hosted-family <family>", `Hosted model family for gateway providers: ${HOSTED_FAMILIES.join(", ")}`).option("--base-url <url>", "Custom base URL for the provider API").option("--api-format <format>", apiFormatHelpText()).option("--resource-endpoint <url>", "Azure resource endpoint").option("--deployment-name <name>", "Azure deployment name").option("--api-version <version>", "Azure API version (e.g. 2024-08-01-preview)").option("--project-id <id>", "Google Vertex project ID").option("--region <region>", "Region (Vertex location, or AWS Bedrock region)").option("--set-default", "Set as the default provider of its kind").addHelpText("after", `
|
|
2284
2807
|
Examples:
|
|
2285
2808
|
${chalk8.dim("$")} mutagent providers add --provider openai --name "My OpenAI" --api-key $OPENAI_API_KEY
|
|
2286
2809
|
${chalk8.dim("$")} mutagent providers add --provider azure --name "Azure GPT" --api-key $KEY \\
|
|
@@ -2288,10 +2811,16 @@ Examples:
|
|
|
2288
2811
|
${chalk8.dim("$")} mutagent providers add --provider bedrock --name "Bedrock Claude" --api-key $KEY \\
|
|
2289
2812
|
--hosted-family anthropic --region us-east-1
|
|
2290
2813
|
${chalk8.dim("$")} mutagent providers add --provider custom --name "Ollama" --api-key none --base-url https://ollama.internal --json
|
|
2814
|
+
${chalk8.dim("$")} mutagent providers add --provider custom --name "Claude-compatible" --api-key $KEY \\
|
|
2815
|
+
--base-url https://llm.internal --api-format anthropic
|
|
2291
2816
|
|
|
2292
2817
|
Gateway providers (${[...GATEWAY_PROVIDERS].join(", ")}) serve another vendor's models and
|
|
2293
2818
|
require --hosted-family. Direct providers must not set it.
|
|
2294
2819
|
|
|
2820
|
+
${apiFormatHelpText()}. An endpoint speaking the Anthropic request shape needs
|
|
2821
|
+
--api-format anthropic; left unset, the server's default applies. Passing it to a
|
|
2822
|
+
provider that speaks its own API is an error, not a silent no-op.
|
|
2823
|
+
|
|
2295
2824
|
Providers are configured for your workspace. Set the target with:
|
|
2296
2825
|
${chalk8.dim("$")} mutagent config set workspace <workspace-id>
|
|
2297
2826
|
|
|
@@ -2326,6 +2855,9 @@ AI Agent Directive:
|
|
|
2326
2855
|
} else if (isGateway && allowedFamilies.length > 1) {
|
|
2327
2856
|
throw new MutagentError("MISSING_HOSTED_FAMILY", `'${providerType}' is a gateway and needs to know which model family it serves.`, `Add --hosted-family <${allowedFamilies.join("|")}>`);
|
|
2328
2857
|
}
|
|
2858
|
+
if (options.apiFormat) {
|
|
2859
|
+
validateApiFormat(providerType, options.apiFormat);
|
|
2860
|
+
}
|
|
2329
2861
|
const client = await getSDKClient();
|
|
2330
2862
|
const workspaceId = client.requireUnambiguousWorkspace();
|
|
2331
2863
|
const credentialFields = collectCredentialFields(options);
|
|
@@ -2357,6 +2889,9 @@ AI Agent Directive:
|
|
|
2357
2889
|
if (options.hostedFamily) {
|
|
2358
2890
|
console.log(` Serves: ${options.hostedFamily}`);
|
|
2359
2891
|
}
|
|
2892
|
+
if (options.apiFormat) {
|
|
2893
|
+
console.log(` API format: ${options.apiFormat}`);
|
|
2894
|
+
}
|
|
2360
2895
|
console.log(` Workspace: ${workspaceId}`);
|
|
2361
2896
|
console.log(` URL: ${providerLink(created.id)}`);
|
|
2362
2897
|
if (options.setDefault) {
|
|
@@ -5134,5 +5669,5 @@ program.addCommand(createInstallCommand());
|
|
|
5134
5669
|
program.addCommand(createFeedbackCommand());
|
|
5135
5670
|
program.parse();
|
|
5136
5671
|
|
|
5137
|
-
//# debugId=
|
|
5672
|
+
//# debugId=A14DCC239481ABD264756E2164756E21
|
|
5138
5673
|
//# sourceMappingURL=cli.js.map
|