@maxceem/agw 0.1.13 → 0.2.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.
- package/dist/agw.mjs +248 -16
- package/package.json +3 -1
package/dist/agw.mjs
CHANGED
|
@@ -6,7 +6,7 @@ var __export = (target, all) => {
|
|
|
6
6
|
};
|
|
7
7
|
|
|
8
8
|
// <define:__AGW_MANIFEST__>
|
|
9
|
-
var define_AGW_MANIFEST_default = { version: "0.1
|
|
9
|
+
var define_AGW_MANIFEST_default = { version: "0.2.1", wrangler: "4.96.0", upgradeFrom: ["0.2.1", "0.2.0", "0.1.13", "0.1.12", "0.1.11", "0.1.10", "0.1.9", "0.1.8", "0.1.7", "0.1.6", "0.1.5", "0.1.4", "0.1.3", "0.1.2", "0.1.1", "0.1.0"], release: { url: "https://github.com/maxceem/app-ai-gateway/releases/download/v0.2.1/gateway-0.2.1.tar.gz", sha256: "09d5d34a924dedf99ca6268d2b699e3d524b72d07a6c6853629dc6c8c9a42307", manifest: "f0a1e385150b39c24707296f9618dea4bb21b73822bb976a58ac03a1482408a0" } };
|
|
10
10
|
|
|
11
11
|
// src/main.ts
|
|
12
12
|
import { Writable as Writable2 } from "node:stream";
|
|
@@ -14525,6 +14525,99 @@ function date4(params) {
|
|
|
14525
14525
|
// ../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/external.js
|
|
14526
14526
|
config(en_default());
|
|
14527
14527
|
|
|
14528
|
+
// ../src/core/records.ts
|
|
14529
|
+
function asRecord(value) {
|
|
14530
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
|
|
14531
|
+
}
|
|
14532
|
+
|
|
14533
|
+
// ../src/core/cost-report.ts
|
|
14534
|
+
function finiteNumber(value) {
|
|
14535
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
14536
|
+
}
|
|
14537
|
+
function nonEmptyString(value) {
|
|
14538
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
14539
|
+
}
|
|
14540
|
+
function servedProviderOf(root) {
|
|
14541
|
+
const available = asRecord(asRecord(root.openrouter_metadata)?.endpoints)?.available;
|
|
14542
|
+
if (Array.isArray(available)) {
|
|
14543
|
+
for (const entry of available) {
|
|
14544
|
+
const endpoint = asRecord(entry);
|
|
14545
|
+
if (endpoint?.selected === true) {
|
|
14546
|
+
const named = nonEmptyString(endpoint.provider);
|
|
14547
|
+
if (named) return named;
|
|
14548
|
+
}
|
|
14549
|
+
}
|
|
14550
|
+
}
|
|
14551
|
+
return nonEmptyString(root.provider);
|
|
14552
|
+
}
|
|
14553
|
+
function upstreamInferenceCost(usage2) {
|
|
14554
|
+
const upstream = finiteNumber(asRecord(usage2?.cost_details)?.upstream_inference_cost);
|
|
14555
|
+
return upstream !== null && upstream > 0 ? upstream : null;
|
|
14556
|
+
}
|
|
14557
|
+
function reportedByok(root, usage2) {
|
|
14558
|
+
if (usage2?.is_byok === true) return true;
|
|
14559
|
+
if (asRecord(root.openrouter_metadata)?.is_byok === true) return true;
|
|
14560
|
+
return upstreamInferenceCost(usage2) !== null;
|
|
14561
|
+
}
|
|
14562
|
+
var OPENROUTER_COST_REPORT = {
|
|
14563
|
+
// Which host actually served a request is opt-in per request; without this
|
|
14564
|
+
// header the response names no serving provider at all.
|
|
14565
|
+
requestHeaders: { "x-openrouter-metadata": "enabled" },
|
|
14566
|
+
read(root, report) {
|
|
14567
|
+
let said = false;
|
|
14568
|
+
const usage2 = asRecord(root.usage);
|
|
14569
|
+
if (report.costUsd === null) {
|
|
14570
|
+
const cost = usage2 ? finiteNumber(usage2.cost) : null;
|
|
14571
|
+
if (cost !== null && cost >= 0) {
|
|
14572
|
+
report.costUsd = cost + (upstreamInferenceCost(usage2) ?? 0);
|
|
14573
|
+
said = true;
|
|
14574
|
+
}
|
|
14575
|
+
}
|
|
14576
|
+
if (report.servedProvider === null) {
|
|
14577
|
+
const served = servedProviderOf(root);
|
|
14578
|
+
if (served !== null) {
|
|
14579
|
+
report.servedProvider = served;
|
|
14580
|
+
said = true;
|
|
14581
|
+
}
|
|
14582
|
+
}
|
|
14583
|
+
if (report.servedModel === null) {
|
|
14584
|
+
const model = nonEmptyString(root.model);
|
|
14585
|
+
if (model !== null) {
|
|
14586
|
+
report.servedModel = model;
|
|
14587
|
+
said = true;
|
|
14588
|
+
}
|
|
14589
|
+
}
|
|
14590
|
+
if (report.credentialSource === null && reportedByok(root, usage2)) {
|
|
14591
|
+
report.credentialSource = "byok";
|
|
14592
|
+
said = true;
|
|
14593
|
+
}
|
|
14594
|
+
return said;
|
|
14595
|
+
}
|
|
14596
|
+
};
|
|
14597
|
+
|
|
14598
|
+
// ../src/shared/provider-auth.ts
|
|
14599
|
+
var PROVIDER_AUTH = {
|
|
14600
|
+
openai: { header: "authorization", scheme: "Bearer " },
|
|
14601
|
+
anthropic: { header: "x-api-key" },
|
|
14602
|
+
xai: { header: "authorization", scheme: "Bearer " },
|
|
14603
|
+
gemini: { header: "x-goog-api-key" },
|
|
14604
|
+
perplexity: { header: "authorization", scheme: "Bearer " },
|
|
14605
|
+
deepseek: { header: "authorization", scheme: "Bearer " },
|
|
14606
|
+
groq: { header: "authorization", scheme: "Bearer " },
|
|
14607
|
+
mistral: { header: "authorization", scheme: "Bearer " },
|
|
14608
|
+
together: { header: "authorization", scheme: "Bearer " },
|
|
14609
|
+
fireworks: { header: "authorization", scheme: "Bearer " },
|
|
14610
|
+
cerebras: { header: "authorization", scheme: "Bearer " },
|
|
14611
|
+
moonshot: { header: "authorization", scheme: "Bearer " },
|
|
14612
|
+
huggingface: { header: "authorization", scheme: "Bearer " },
|
|
14613
|
+
baseten: { header: "authorization", scheme: "Bearer " },
|
|
14614
|
+
bytedance: { header: "authorization", scheme: "Bearer " },
|
|
14615
|
+
openrouter: { header: "authorization", scheme: "Bearer " }
|
|
14616
|
+
};
|
|
14617
|
+
var PROVIDER_CREDENTIAL_HEADERS = [
|
|
14618
|
+
...new Set(Object.values(PROVIDER_AUTH).map((auth) => auth.header.toLowerCase()))
|
|
14619
|
+
];
|
|
14620
|
+
|
|
14528
14621
|
// ../src/shared/capabilities.ts
|
|
14529
14622
|
var PROVIDER_TYPES = [
|
|
14530
14623
|
"openai",
|
|
@@ -14604,8 +14697,143 @@ var VERCEL_ROUTES = {
|
|
|
14604
14697
|
moonshot: vercelRoute("moonshotai/")
|
|
14605
14698
|
};
|
|
14606
14699
|
|
|
14607
|
-
// ../src/
|
|
14700
|
+
// ../src/shared/app-config.ts
|
|
14701
|
+
var ISSUER_PROVIDERS = ["firebase", "supabase", "auth0", "clerk", "custom"];
|
|
14702
|
+
var ENTITLEMENT_CHECKS = ["revenuecat", "custom"];
|
|
14703
|
+
var ENDPOINT_SLUG = /^[a-z0-9-]{1,64}$/;
|
|
14608
14704
|
var PROVIDER_SLUG_PATTERN = /^[a-z0-9][a-z0-9-]{0,62}$/;
|
|
14705
|
+
var HTTP_FIELD_NAME = /^[A-Za-z0-9!#$%&'*+.^_`|~-]+$/;
|
|
14706
|
+
var RESERVED_END_USER_HEADERS = /* @__PURE__ */ new Set([
|
|
14707
|
+
"authorization",
|
|
14708
|
+
...PROVIDER_CREDENTIAL_HEADERS,
|
|
14709
|
+
"x-app-version",
|
|
14710
|
+
"content-type",
|
|
14711
|
+
"content-length",
|
|
14712
|
+
"host"
|
|
14713
|
+
]);
|
|
14714
|
+
|
|
14715
|
+
// ../src/core/providers.ts
|
|
14716
|
+
var PROVIDER_REGISTRY = {
|
|
14717
|
+
openai: {
|
|
14718
|
+
directBaseUrl: "https://api.openai.com/",
|
|
14719
|
+
auth: PROVIDER_AUTH.openai,
|
|
14720
|
+
modelAuthor: "OpenAI"
|
|
14721
|
+
},
|
|
14722
|
+
anthropic: {
|
|
14723
|
+
directBaseUrl: "https://api.anthropic.com/",
|
|
14724
|
+
auth: PROVIDER_AUTH.anthropic,
|
|
14725
|
+
modelAuthor: "Anthropic",
|
|
14726
|
+
// Anthropic refuses any request without a version header, probe included —
|
|
14727
|
+
// and a probe has no client to send one for it. Deliberately not a
|
|
14728
|
+
// `requestHeaders` entry: on live traffic this is the *client's* API version,
|
|
14729
|
+
// set by every Anthropic SDK, and pinning it server-side would strip that
|
|
14730
|
+
// choice and silently downgrade every request to the oldest version.
|
|
14731
|
+
probeHeaders: { "anthropic-version": "2023-06-01" }
|
|
14732
|
+
},
|
|
14733
|
+
xai: {
|
|
14734
|
+
directBaseUrl: "https://api.x.ai/",
|
|
14735
|
+
auth: PROVIDER_AUTH.xai,
|
|
14736
|
+
modelAuthor: "xAI"
|
|
14737
|
+
},
|
|
14738
|
+
gemini: {
|
|
14739
|
+
directBaseUrl: "https://generativelanguage.googleapis.com/",
|
|
14740
|
+
auth: PROVIDER_AUTH.gemini,
|
|
14741
|
+
modelAuthor: "Google"
|
|
14742
|
+
},
|
|
14743
|
+
perplexity: {
|
|
14744
|
+
directBaseUrl: "https://api.perplexity.ai/",
|
|
14745
|
+
auth: PROVIDER_AUTH.perplexity,
|
|
14746
|
+
modelAuthor: "Perplexity"
|
|
14747
|
+
},
|
|
14748
|
+
// OpenAI-compatible chat-completions services. `modelAuthor` is set only
|
|
14749
|
+
// where one answer is right for every model the type serves; the hosts below
|
|
14750
|
+
// that carry no author serve other labs' open-weight models, and authorship
|
|
14751
|
+
// comes from the catalog entry per model instead.
|
|
14752
|
+
deepseek: {
|
|
14753
|
+
// No `v1` segment: DeepSeek documents the bare origin as its OpenAI base
|
|
14754
|
+
// URL, and `https://api.deepseek.com/anthropic` for the Anthropic format.
|
|
14755
|
+
directBaseUrl: "https://api.deepseek.com/",
|
|
14756
|
+
auth: PROVIDER_AUTH.deepseek,
|
|
14757
|
+
modelAuthor: "DeepSeek"
|
|
14758
|
+
},
|
|
14759
|
+
groq: {
|
|
14760
|
+
// Groq's OpenAI-compatible surface lives under `openai/v1/`, so the client
|
|
14761
|
+
// path is `openai/v1/chat/completions` rather than `v1/chat/completions`.
|
|
14762
|
+
directBaseUrl: "https://api.groq.com/",
|
|
14763
|
+
auth: PROVIDER_AUTH.groq
|
|
14764
|
+
},
|
|
14765
|
+
mistral: {
|
|
14766
|
+
directBaseUrl: "https://api.mistral.ai/",
|
|
14767
|
+
auth: PROVIDER_AUTH.mistral,
|
|
14768
|
+
modelAuthor: "Mistral"
|
|
14769
|
+
},
|
|
14770
|
+
together: {
|
|
14771
|
+
// `api.together.ai`, not the `.xyz` host older SDKs default to: the current
|
|
14772
|
+
// OpenAI-compatibility guide names this one and warns against the other.
|
|
14773
|
+
directBaseUrl: "https://api.together.ai/",
|
|
14774
|
+
auth: PROVIDER_AUTH.together
|
|
14775
|
+
},
|
|
14776
|
+
fireworks: {
|
|
14777
|
+
// The inference plane is `/inference/v1`; `/v1` on the same host is the
|
|
14778
|
+
// control plane, so the client path is `inference/v1/chat/completions`.
|
|
14779
|
+
directBaseUrl: "https://api.fireworks.ai/",
|
|
14780
|
+
auth: PROVIDER_AUTH.fireworks
|
|
14781
|
+
},
|
|
14782
|
+
cerebras: {
|
|
14783
|
+
directBaseUrl: "https://api.cerebras.ai/",
|
|
14784
|
+
auth: PROVIDER_AUTH.cerebras
|
|
14785
|
+
},
|
|
14786
|
+
moonshot: {
|
|
14787
|
+
// The international host. `api.moonshot.cn` is the separate China platform
|
|
14788
|
+
// and is not reachable with a key issued for this one.
|
|
14789
|
+
directBaseUrl: "https://api.moonshot.ai/",
|
|
14790
|
+
auth: PROVIDER_AUTH.moonshot,
|
|
14791
|
+
modelAuthor: "Moonshot AI"
|
|
14792
|
+
},
|
|
14793
|
+
huggingface: {
|
|
14794
|
+
// The Inference Providers router: one OpenAI-compatible surface in front of
|
|
14795
|
+
// many upstreams, so it has no author of its own and no stable per-model
|
|
14796
|
+
// price — the router picks the upstream, and the same model ID costs an
|
|
14797
|
+
// order of magnitude more on some of them than others. It ships with no
|
|
14798
|
+
// catalog section for that reason; see `catalogPrice` in usage.ts.
|
|
14799
|
+
directBaseUrl: "https://router.huggingface.co/",
|
|
14800
|
+
auth: PROVIDER_AUTH.huggingface
|
|
14801
|
+
},
|
|
14802
|
+
baseten: {
|
|
14803
|
+
// The Model APIs inference host. `api.baseten.co` is the management plane
|
|
14804
|
+
// for dedicated deployments and answers to different paths entirely.
|
|
14805
|
+
directBaseUrl: "https://inference.baseten.co/",
|
|
14806
|
+
auth: PROVIDER_AUTH.baseten
|
|
14807
|
+
},
|
|
14808
|
+
bytedance: {
|
|
14809
|
+
// BytePlus ModelArk, the international edition: `/api/v3` is its version
|
|
14810
|
+
// segment, so client paths carry no `v1`. `ark.cn-beijing.volces.com` is
|
|
14811
|
+
// the separate China platform, and `ark.eu-west.bytepluses.com` is a second
|
|
14812
|
+
// region — keys and catalogs are region-isolated, so reaching either needs
|
|
14813
|
+
// the per-row base URL override that Stage 6 introduces.
|
|
14814
|
+
directBaseUrl: "https://ark.ap-southeast.bytepluses.com/api/v3/",
|
|
14815
|
+
auth: PROVIDER_AUTH.bytedance
|
|
14816
|
+
},
|
|
14817
|
+
openrouter: {
|
|
14818
|
+
// An aggregator treated as a provider type: it is the counterparty that
|
|
14819
|
+
// bills the organization, and its slugs (`google/gemini-3.6-flash`) are the
|
|
14820
|
+
// canonical model IDs here — there is no underlying ID to translate to.
|
|
14821
|
+
// `/api/v1` is its documented server URL, so the client path is
|
|
14822
|
+
// `v1/chat/completions` under this origin.
|
|
14823
|
+
directBaseUrl: "https://openrouter.ai/api/",
|
|
14824
|
+
auth: PROVIDER_AUTH.openrouter,
|
|
14825
|
+
// Every chat-completions response carries `usage.cost`: what OpenRouter
|
|
14826
|
+
// actually charged for that request, which beats any local estimate of a
|
|
14827
|
+
// catalog this deployment does not track. It is also the only way to bill
|
|
14828
|
+
// the type at all, since no static price list covers 400 models across
|
|
14829
|
+
// every lab. The declaration owns the parsing and the header that asks for
|
|
14830
|
+
// the routing metadata — see `src/core/cost-report.ts`.
|
|
14831
|
+
costReport: OPENROUTER_COST_REPORT,
|
|
14832
|
+
// No `modelAuthor`: an aggregator serves everyone's models, and the slug
|
|
14833
|
+
// namespace answers per model instead.
|
|
14834
|
+
authorNamespacedModels: true
|
|
14835
|
+
}
|
|
14836
|
+
};
|
|
14609
14837
|
|
|
14610
14838
|
// ../src/core/origin-guard.ts
|
|
14611
14839
|
var MAX_BASE_URL_LENGTH = 200;
|
|
@@ -14714,10 +14942,6 @@ function checkOperatorBaseUrl(input) {
|
|
|
14714
14942
|
return { ok: true, baseUrl };
|
|
14715
14943
|
}
|
|
14716
14944
|
|
|
14717
|
-
// ../src/core/types.ts
|
|
14718
|
-
var ISSUER_PROVIDERS = ["firebase", "supabase", "auth0", "clerk", "custom"];
|
|
14719
|
-
var ENTITLEMENT_CHECKS = ["revenuecat", "custom"];
|
|
14720
|
-
|
|
14721
14945
|
// ../src/contracts/schemas.ts
|
|
14722
14946
|
var ProviderTypeSchema = external_exports.enum(PROVIDER_TYPES);
|
|
14723
14947
|
var NullableRequestLimit = external_exports.number().int().positive().nullable();
|
|
@@ -14751,7 +14975,7 @@ var IssuerAuthenticationSchema = external_exports.object({
|
|
|
14751
14975
|
provider: external_exports.enum(ISSUER_PROVIDERS).optional(),
|
|
14752
14976
|
entitlement: external_exports.enum(ENTITLEMENT_CHECKS).optional()
|
|
14753
14977
|
}).strict();
|
|
14754
|
-
var EndUserHeaderSchema = external_exports.string().trim().min(1).max(64).regex(
|
|
14978
|
+
var EndUserHeaderSchema = external_exports.string().trim().min(1).max(64).regex(HTTP_FIELD_NAME, { error: "header must be a valid HTTP header name" });
|
|
14755
14979
|
var HeaderEndUserSchema = external_exports.object({
|
|
14756
14980
|
source: external_exports.literal("header"),
|
|
14757
14981
|
header: EndUserHeaderSchema
|
|
@@ -14849,7 +15073,7 @@ var AppConfigSchema = external_exports.object({
|
|
|
14849
15073
|
per_user: LimitScopeSchema,
|
|
14850
15074
|
per_app: LimitScopeSchema
|
|
14851
15075
|
}).optional(),
|
|
14852
|
-
endpoints: external_exports.record(external_exports.string().regex(
|
|
15076
|
+
endpoints: external_exports.record(external_exports.string().regex(ENDPOINT_SLUG), EndpointSchema).optional()
|
|
14853
15077
|
}).meta({ id: "AppConfig" });
|
|
14854
15078
|
var AppWriteSchema = external_exports.object({
|
|
14855
15079
|
name: external_exports.string().min(1).max(100),
|
|
@@ -14972,13 +15196,16 @@ var ProviderGatewayTestRequestSchema = external_exports.discriminatedUnion("type
|
|
|
14972
15196
|
error: "Provider gateway type must be one of cf_aig, vercel"
|
|
14973
15197
|
}).meta({ id: "ProviderGatewayTestRequest" });
|
|
14974
15198
|
var ProviderGatewayUpdateRequestSchema = external_exports.object({
|
|
14975
|
-
name: ProviderNameSchema
|
|
15199
|
+
name: ProviderNameSchema,
|
|
15200
|
+
revision: external_exports.number().int().positive().meta({ description: "The gateway revision returned by the read this edit is based on." })
|
|
14976
15201
|
}).strict().meta({ id: "ProviderGatewayUpdateRequest" });
|
|
14977
15202
|
var ProviderGatewayRotateRequestSchema = external_exports.object({
|
|
14978
|
-
token: ProviderSecretSchema
|
|
15203
|
+
token: ProviderSecretSchema,
|
|
15204
|
+
revision: external_exports.number().int().positive().meta({ description: "The gateway revision returned by the read this rotation is based on." })
|
|
14979
15205
|
}).strict().meta({ id: "ProviderGatewayRotateRequest" });
|
|
14980
15206
|
var BASE_URL_REQUIRES_SECRET = "Changing the base URL requires re-supplying the provider key, because the stored key is never sent to a new origin";
|
|
14981
15207
|
var ProviderUpdateRequestSchema = external_exports.object({
|
|
15208
|
+
revision: external_exports.number().int().positive().meta({ description: "The provider revision returned by the read this update is based on." }),
|
|
14982
15209
|
name: ProviderNameSchema.optional(),
|
|
14983
15210
|
secret: ProviderSecretSchema.optional(),
|
|
14984
15211
|
/** A full replace; `null` clears the row's routing configuration. */
|
|
@@ -15222,6 +15449,7 @@ var ProviderSummarySchema = external_exports.object({
|
|
|
15222
15449
|
example: "https://my-resource.openai.azure.com/openai/v1/"
|
|
15223
15450
|
}),
|
|
15224
15451
|
pricing: ProviderPricingSchema.nullable(),
|
|
15452
|
+
revision: external_exports.number().int().positive(),
|
|
15225
15453
|
status: external_exports.enum(["active", "disabled"]).meta({
|
|
15226
15454
|
description: "disabled is a reversible pause: the row keeps its secret, its pricing and its slug, and requests to it fail with provider_disabled until it is enabled again."
|
|
15227
15455
|
}),
|
|
@@ -15262,6 +15490,7 @@ var providerGatewayFields = {
|
|
|
15262
15490
|
referencedCount: external_exports.number().int().nonnegative().meta({
|
|
15263
15491
|
description: "All provider instances referencing this gateway, including disabled rows retained for re-enabling. Deletion is refused while this is above zero."
|
|
15264
15492
|
}),
|
|
15493
|
+
revision: external_exports.number().int().positive(),
|
|
15265
15494
|
status: external_exports.enum(["active", "revoked"]),
|
|
15266
15495
|
createdAt: external_exports.string(),
|
|
15267
15496
|
updatedAt: external_exports.string(),
|
|
@@ -16477,9 +16706,9 @@ async function resourceCommand(ctx, command, args, flags) {
|
|
|
16477
16706
|
if (!existingGateway) fail("invalid_arguments", "Supply the gateway to rotate.");
|
|
16478
16707
|
const value2 = await secret(flags, "Gateway token");
|
|
16479
16708
|
if (flags.browser)
|
|
16480
|
-
return ctx.operation("provider-gateway.rotate-key", { id: existingGateway.id });
|
|
16709
|
+
return ctx.operation("provider-gateway.rotate-key", { id: existingGateway.id, revision: existingGateway.revision });
|
|
16481
16710
|
return (await ctx.call("rotateProviderGateway", [existingGateway.id], {
|
|
16482
|
-
body: { token: value2 }
|
|
16711
|
+
body: { token: value2, revision: existingGateway.revision }
|
|
16483
16712
|
})).data;
|
|
16484
16713
|
}
|
|
16485
16714
|
if (!existingProvider) fail("invalid_arguments", "Supply the provider to rotate.");
|
|
@@ -16490,16 +16719,17 @@ async function resourceCommand(ctx, command, args, flags) {
|
|
|
16490
16719
|
);
|
|
16491
16720
|
const value = await secret(flags, "Provider API key");
|
|
16492
16721
|
if (flags.browser)
|
|
16493
|
-
return ctx.operation("provider.rotate-key", { id: existingProvider.id });
|
|
16722
|
+
return ctx.operation("provider.rotate-key", { id: existingProvider.id, revision: existingProvider.revision });
|
|
16494
16723
|
return (await ctx.call("updateProvider", [existingProvider.id], {
|
|
16495
|
-
body: { secret: value }
|
|
16724
|
+
body: { secret: value, revision: existingProvider.revision }
|
|
16496
16725
|
})).data;
|
|
16497
16726
|
}
|
|
16498
16727
|
if (action === "update") {
|
|
16499
16728
|
if (gateway) {
|
|
16500
16729
|
if (!existingGateway) fail("invalid_arguments", "Supply the gateway to update.");
|
|
16501
16730
|
const body2 = validate(ProviderGatewayUpdateRequestSchema, {
|
|
16502
|
-
name: await required2(flags, "name")
|
|
16731
|
+
name: await required2(flags, "name"),
|
|
16732
|
+
revision: existingGateway.revision
|
|
16503
16733
|
});
|
|
16504
16734
|
return (await ctx.call("updateProviderGateway", [existingGateway.id], { body: body2 })).data;
|
|
16505
16735
|
}
|
|
@@ -16532,6 +16762,7 @@ async function resourceCommand(ctx, command, args, flags) {
|
|
|
16532
16762
|
if (flags["base-url"] || flags["clear-base-url"]) {
|
|
16533
16763
|
validate(ProviderUpdateRequestSchema, {
|
|
16534
16764
|
...draft,
|
|
16765
|
+
revision: existingProvider.revision,
|
|
16535
16766
|
secret: "validation-placeholder"
|
|
16536
16767
|
});
|
|
16537
16768
|
const value = await secret(flags, "Provider API key");
|
|
@@ -16539,10 +16770,11 @@ async function resourceCommand(ctx, command, args, flags) {
|
|
|
16539
16770
|
}
|
|
16540
16771
|
const body = validate(ProviderUpdateRequestSchema, {
|
|
16541
16772
|
...draft,
|
|
16773
|
+
revision: existingProvider.revision,
|
|
16542
16774
|
...flags.browser ? { secret: "validation-placeholder" } : {}
|
|
16543
16775
|
});
|
|
16544
16776
|
if (flags.browser)
|
|
16545
|
-
return ctx.operation("provider.update", { id: existingProvider.id, ...draft });
|
|
16777
|
+
return ctx.operation("provider.update", { id: existingProvider.id, revision: existingProvider.revision, ...draft });
|
|
16546
16778
|
return (await ctx.call("updateProvider", [existingProvider.id], { body })).data;
|
|
16547
16779
|
}
|
|
16548
16780
|
fail("unknown_command", "Unknown command.");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maxceem/agw",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Manage App AI Gateway from a terminal or coding agent: providers, iOS and server apps, usage, and self-hosted deployment on Cloudflare",
|
|
6
6
|
"keywords": [
|
|
@@ -26,6 +26,8 @@
|
|
|
26
26
|
},
|
|
27
27
|
"bugs": "https://github.com/maxceem/app-ai-gateway/issues",
|
|
28
28
|
"upgradeFrom": [
|
|
29
|
+
"0.2.0",
|
|
30
|
+
"0.1.13",
|
|
29
31
|
"0.1.12",
|
|
30
32
|
"0.1.11",
|
|
31
33
|
"0.1.10",
|