@maxceem/agw 0.15.0 → 0.16.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/dist/agw.mjs +96 -54
- 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.
|
|
9
|
+
var define_AGW_MANIFEST_default = { version: "0.16.0", wrangler: "4.96.0", upgradeFrom: ["0.16.0", "0.15.1", "0.15.0", "0.14.0", "0.13.1", "0.13.0", "0.12.1", "0.12.0", "0.11.2", "0.11.1", "0.11.0", "0.10.11", "0.10.10", "0.10.9", "0.10.8", "0.10.7", "0.10.6", "0.10.5", "0.10.4", "0.10.3", "0.10.2", "0.10.1", "0.10.0", "0.9.3", "0.9.2", "0.9.1", "0.9.0", "0.8.3", "0.8.2", "0.8.1", "0.8.0", "0.7.2", "0.7.1", "0.7.0", "0.6.4", "0.6.3", "0.6.2", "0.6.1", "0.6.0", "0.5.2", "0.5.1", "0.5.0", "0.4.0"], release: { url: "https://github.com/maxceem/app-ai-gateway/releases/download/v0.16.0/gateway-0.16.0.tar.gz", sha256: "222ce0c030268e5b1468c5d1755d8ea7d6da0ce86d9a0229e0adf5eb5eab4850", manifest: "1ecdc82e5705b259f5eed20bc58348fa9bcd36686f177d5040b3544ea09ba920" } };
|
|
10
10
|
|
|
11
11
|
// src/main.ts
|
|
12
12
|
import { Writable as Writable2 } from "node:stream";
|
|
@@ -20509,31 +20509,83 @@ var ENDPOINT_PROVIDER_TYPES = PROVIDER_TYPES.filter(
|
|
|
20509
20509
|
var APP_STATUSES = ["active", "disabled"];
|
|
20510
20510
|
|
|
20511
20511
|
// ../src/shared/token-rates.ts
|
|
20512
|
-
var
|
|
20513
|
-
|
|
20514
|
-
|
|
20515
|
-
|
|
20516
|
-
|
|
20517
|
-
|
|
20518
|
-
|
|
20519
|
-
|
|
20520
|
-
|
|
20521
|
-
|
|
20522
|
-
|
|
20523
|
-
|
|
20524
|
-
|
|
20525
|
-
|
|
20526
|
-
|
|
20527
|
-
|
|
20528
|
-
|
|
20529
|
-
|
|
20512
|
+
var TOKEN_VARIANTS = {
|
|
20513
|
+
cache_write: {
|
|
20514
|
+
// Anthropic: a write kept for an hour bills at 2x input, against 1.25x for
|
|
20515
|
+
// the default five minutes. `usage.cache_creation` splits the write by TTL.
|
|
20516
|
+
"1h": {
|
|
20517
|
+
label: "1h cache write",
|
|
20518
|
+
description: "USD per 1M tokens written to a one-hour cache, where it costs more than the default cache write.",
|
|
20519
|
+
reportedAt: ["cache_creation", "ephemeral_1h_input_tokens"]
|
|
20520
|
+
},
|
|
20521
|
+
// OpenAI (Responses API): a write kept for 12 hours bills at 2.5x input,
|
|
20522
|
+
// against 1.25x for the default 30 minutes.
|
|
20523
|
+
"12h": {
|
|
20524
|
+
label: "12h cache write",
|
|
20525
|
+
description: "USD per 1M tokens written to a 12-hour cache, where it costs more than the default cache write.",
|
|
20526
|
+
reportedAt: ["input_tokens_details", "cache_write_tokens_details", "ttl_12h_tokens"]
|
|
20527
|
+
}
|
|
20528
|
+
}
|
|
20529
|
+
};
|
|
20530
|
+
var VARIANTS = Object.entries(TOKEN_VARIANTS).flatMap(
|
|
20531
|
+
([bucket, variants]) => Object.entries(variants).map(([name, spec]) => ({
|
|
20532
|
+
...spec,
|
|
20533
|
+
bucket,
|
|
20534
|
+
name,
|
|
20535
|
+
field: `${bucket}_${name}`
|
|
20536
|
+
}))
|
|
20530
20537
|
);
|
|
20538
|
+
var BUCKETS = ["input", "cached_input", "cache_write", "output"];
|
|
20539
|
+
var MODALITY_RATES = ["image_input", "audio_input", "video_input", "image_output"];
|
|
20540
|
+
var BASE_RATES = {
|
|
20541
|
+
input: { label: "input" },
|
|
20542
|
+
cached_input: { label: "cached" },
|
|
20543
|
+
cache_write: { label: "cache write" },
|
|
20544
|
+
output: { label: "output" },
|
|
20545
|
+
image_input: {
|
|
20546
|
+
label: "image input",
|
|
20547
|
+
description: "USD per 1M image input tokens, where they are priced apart from text input."
|
|
20548
|
+
},
|
|
20549
|
+
audio_input: {
|
|
20550
|
+
label: "audio input",
|
|
20551
|
+
description: "USD per 1M audio input tokens, where they are priced apart from text input."
|
|
20552
|
+
},
|
|
20553
|
+
video_input: {
|
|
20554
|
+
label: "video input",
|
|
20555
|
+
description: "USD per 1M video input tokens, where they are priced apart from text input."
|
|
20556
|
+
},
|
|
20557
|
+
image_output: {
|
|
20558
|
+
label: "image output",
|
|
20559
|
+
description: "USD per 1M generated image tokens, where they cost more than text output."
|
|
20560
|
+
}
|
|
20561
|
+
};
|
|
20562
|
+
var BUCKET_FIELDS = BUCKETS.flatMap((bucket) => [
|
|
20563
|
+
bucket,
|
|
20564
|
+
...VARIANTS.filter((variant) => variant.bucket === bucket).map((variant) => variant.field)
|
|
20565
|
+
]);
|
|
20566
|
+
var LONG_RATE_FIELDS = BUCKET_FIELDS.map((field) => `long_${field}`);
|
|
20567
|
+
var TOKEN_RATE_FIELDS = [...BUCKET_FIELDS, ...MODALITY_RATES, ...LONG_RATE_FIELDS];
|
|
20568
|
+
var SHORT_INFO = new Map([
|
|
20569
|
+
...Object.entries(BASE_RATES),
|
|
20570
|
+
...VARIANTS.map((variant) => [variant.field, variant])
|
|
20571
|
+
]);
|
|
20572
|
+
var RATE_LABELS = Object.fromEntries(
|
|
20573
|
+
TOKEN_RATE_FIELDS.map((field) => {
|
|
20574
|
+
const short = field.startsWith("long_") ? field.slice("long_".length) : field;
|
|
20575
|
+
const label = SHORT_INFO.get(short)?.label ?? short;
|
|
20576
|
+
return [field, short === field ? label : `long ${label}`];
|
|
20577
|
+
})
|
|
20578
|
+
);
|
|
20579
|
+
function rateDescription(field) {
|
|
20580
|
+
return SHORT_INFO.get(field)?.description;
|
|
20581
|
+
}
|
|
20531
20582
|
|
|
20532
20583
|
// ../src/contracts/schemas.ts
|
|
20533
20584
|
var ISSUER_PROVIDERS = ["firebase", "supabase", "auth0", "clerk", "custom"];
|
|
20534
20585
|
var ENTITLEMENT_CHECKS = ["revenuecat", "custom"];
|
|
20535
20586
|
var APP_ATTEST_ENVIRONMENTS = ["production", "development"];
|
|
20536
20587
|
var APP_ATTEST_VERIFY_ON = ["every_request", "token_exchange"];
|
|
20588
|
+
var MAX_APP_TRANSACTION_LENGTH = 16384;
|
|
20537
20589
|
var ENDPOINT_SLUG = /^[a-z0-9-]{1,64}$/;
|
|
20538
20590
|
var PROVIDER_SLUG_PATTERN = /^[a-z0-9][a-z0-9-]{0,62}$/;
|
|
20539
20591
|
var HTTP_FIELD_NAME = /^[A-Za-z0-9!#$%&'*+.^_`|~-]+$/;
|
|
@@ -20767,11 +20819,11 @@ var LimitScopeSchema = external_exports.object({
|
|
|
20767
20819
|
}).strict(),
|
|
20768
20820
|
spending: external_exports.object({ monthly_usd: NullableSpendLimit }).strict()
|
|
20769
20821
|
}).strict();
|
|
20770
|
-
var BUDGET_SCOPES = ["install", "user"];
|
|
20822
|
+
var BUDGET_SCOPES = ["install", "user", "apple_account"];
|
|
20771
20823
|
var PerUserLimitScopeSchema = LimitScopeSchema.extend({
|
|
20772
20824
|
spending: LimitScopeSchema.shape.spending.extend({
|
|
20773
20825
|
scope: external_exports.enum(BUDGET_SCOPES).optional().meta({
|
|
20774
|
-
description: "Whose month monthly_usd is measured over:
|
|
20826
|
+
description: "Whose month monthly_usd is measured over: apple_account (the default on App Attest applications), install, or user (the default, and the only value, on server applications). apple_account counts every install of one Apple Account together, across devices and reinstalls; an install whose client sent no verifiable App Store transaction is counted on its own, as under install. user on an App Attest application needs authentication.end_user.source issuer. Filled in on every parsed configuration."
|
|
20775
20827
|
})
|
|
20776
20828
|
}).strict()
|
|
20777
20829
|
}).strict();
|
|
@@ -20850,25 +20902,25 @@ var AppConfigSchema = external_exports.object({
|
|
|
20850
20902
|
}
|
|
20851
20903
|
const budgetScope = perUser?.spending.scope;
|
|
20852
20904
|
if (authentication !== void 0 && budgetScope !== void 0) {
|
|
20853
|
-
if (authentication.type === "api_key" && budgetScope
|
|
20905
|
+
if (authentication.type === "api_key" && budgetScope !== "user") {
|
|
20854
20906
|
context.addIssue({
|
|
20855
20907
|
code: "custom",
|
|
20856
20908
|
path: ["limits", "per_user", "spending", "scope"],
|
|
20857
|
-
message:
|
|
20909
|
+
message: `cannot be ${budgetScope}: server applications have no install or Apple Account; the budget is per user`
|
|
20858
20910
|
});
|
|
20859
20911
|
}
|
|
20860
20912
|
if (authentication.type === "apple_app_attest" && budgetScope === "user" && authentication.end_user.source !== "issuer") {
|
|
20861
20913
|
context.addIssue({
|
|
20862
20914
|
code: "custom",
|
|
20863
20915
|
path: ["limits", "per_user", "spending", "scope"],
|
|
20864
|
-
message: "can be user only when authentication.end_user.source is issuer: under app_install every install is its own user, so use install"
|
|
20916
|
+
message: "can be user only when authentication.end_user.source is issuer: under app_install every install is its own user, so use apple_account to count one person's installs together, or install"
|
|
20865
20917
|
});
|
|
20866
20918
|
}
|
|
20867
20919
|
}
|
|
20868
20920
|
}).overwrite((config2) => {
|
|
20869
20921
|
const spending = config2.limits.per_user.spending;
|
|
20870
20922
|
if (spending.scope === void 0) {
|
|
20871
|
-
spending.scope = config2.authentication.type === "apple_app_attest" ? "
|
|
20923
|
+
spending.scope = config2.authentication.type === "apple_app_attest" ? "apple_account" : "user";
|
|
20872
20924
|
}
|
|
20873
20925
|
return config2;
|
|
20874
20926
|
}).meta({ id: "AppConfig" });
|
|
@@ -20910,7 +20962,10 @@ var AppAttestTokenRequestSchema = external_exports.object({
|
|
|
20910
20962
|
issuer_token: external_exports.string().min(1).optional(),
|
|
20911
20963
|
key_id: AppAttestKeyIdSchema,
|
|
20912
20964
|
assertion: external_exports.string().min(1),
|
|
20913
|
-
challenge: ChallengeSchema
|
|
20965
|
+
challenge: ChallengeSchema,
|
|
20966
|
+
app_transaction: external_exports.string().min(1).max(MAX_APP_TRANSACTION_LENGTH).optional().meta({
|
|
20967
|
+
description: "The App Store's signed AppTransaction (its JWS), which names the Apple Account the install belongs to. When present, the assertion signs client data that also carries app_transaction: the unpadded base64url SHA-256 of this string. One that does not verify against Apple's root names no account, and the install is counted on its own."
|
|
20968
|
+
})
|
|
20914
20969
|
}).meta({ id: "AppAttestTokenRequest" });
|
|
20915
20970
|
var ApiKeyTokenRequestSchema = external_exports.object({
|
|
20916
20971
|
issuer_token: external_exports.string().min(1),
|
|
@@ -22772,7 +22827,7 @@ var REJECTION_REASONS = [
|
|
|
22772
22827
|
/** An App Attest assertion whose counter the install had already used. */
|
|
22773
22828
|
"blocked_replay"
|
|
22774
22829
|
];
|
|
22775
|
-
var REJECTION_SCOPES = ["user", "install", "app", "account"];
|
|
22830
|
+
var REJECTION_SCOPES = ["user", "install", "apple_account", "app", "account"];
|
|
22776
22831
|
|
|
22777
22832
|
// ../src/contracts/billing.ts
|
|
22778
22833
|
var BillingSubscriptionStatusSchema = external_exports.enum([
|
|
@@ -22993,7 +23048,10 @@ var GoogleSignInResponseSchema = external_exports.object({
|
|
|
22993
23048
|
});
|
|
22994
23049
|
var AppAttestChallengeResponseSchema = external_exports.object({
|
|
22995
23050
|
challenge: external_exports.string(),
|
|
22996
|
-
expires_in: external_exports.number()
|
|
23051
|
+
expires_in: external_exports.number(),
|
|
23052
|
+
accepts_app_transaction: external_exports.boolean().optional().meta({
|
|
23053
|
+
description: "True when the token exchange accepts app_transaction, the App Store's signed AppTransaction. A client sends one, and signs over its hash, only when this says so: a gateway that predates it would ignore the field and then refuse the assertion."
|
|
23054
|
+
})
|
|
22997
23055
|
});
|
|
22998
23056
|
var AppAttestRegisterResponseSchema = external_exports.object({ user_id: external_exports.string() });
|
|
22999
23057
|
var GatewayTokenResponseSchema = external_exports.object({
|
|
@@ -23013,8 +23071,9 @@ var CurrentUserResponseSchema = external_exports.object({
|
|
|
23013
23071
|
requests_remaining: external_exports.number().int().nullable().meta({ description: "What is left of requests_per_day. Null when no daily limit is set." }),
|
|
23014
23072
|
requests_per_minute: external_exports.number().nullable().meta({ description: "The per-minute limit this app sets on each install (App Attest) or user (server). Null means unlimited." }),
|
|
23015
23073
|
requests_per_day: external_exports.number().nullable().meta({ description: "The per-day limit this app sets on each install (App Attest) or user (server). Null means unlimited." }),
|
|
23016
|
-
monthly_cost_usd: external_exports.number().meta({ description: "What has been spent so far in the current UTC calendar month against the budget below
|
|
23017
|
-
monthly_budget_usd: external_exports.number().nullable().meta({ description: "The monthly spending budget this app sets on each install or user, per limits.per_user.spending.scope. Null means unlimited." }),
|
|
23074
|
+
monthly_cost_usd: external_exports.number().meta({ description: "What has been spent so far in the current UTC calendar month against the budget below, by whoever budget_scope names." }),
|
|
23075
|
+
monthly_budget_usd: external_exports.number().nullable().meta({ description: "The monthly spending budget this app sets on each Apple Account, install or user, per limits.per_user.spending.scope. Null means unlimited." }),
|
|
23076
|
+
budget_scope: external_exports.enum(BUDGET_SCOPES).meta({ description: "Whose month monthly_cost_usd is: apple_account (every install of this person's Apple Account together), install (this install alone), or user (this signed-in or backend-named user). Usually the app's limits.per_user.spending.scope; install where that is apple_account but this install's client sent no verifiable App Store transaction." }),
|
|
23018
23077
|
blocked: external_exports.boolean().meta({ description: "Whether this user has been blocked in the console." })
|
|
23019
23078
|
}).meta({
|
|
23020
23079
|
description: "The limits the app sets on this user, and where the user stands against them. The account's request allowance is not reported here: it is shared by all apps, and is reported on the rejection that spends it."
|
|
@@ -23693,40 +23752,23 @@ var UsageRepriceResponseSchema = external_exports.object({
|
|
|
23693
23752
|
recalculated_cost_usd: external_exports.number(),
|
|
23694
23753
|
delta_usd: external_exports.number()
|
|
23695
23754
|
});
|
|
23755
|
+
var CATALOG_TOKEN_RATES = Object.fromEntries(
|
|
23756
|
+
TOKEN_RATE_FIELDS.map((field) => {
|
|
23757
|
+
const description = rateDescription(field);
|
|
23758
|
+
return [field, description ? external_exports.number().optional().meta({ description }) : external_exports.number().optional()];
|
|
23759
|
+
})
|
|
23760
|
+
);
|
|
23696
23761
|
var ModelPriceSchema = external_exports.object({
|
|
23697
23762
|
kind: external_exports.enum(MODEL_KINDS).meta({
|
|
23698
23763
|
description: "What the model does: text, image (generation), speech (text to speech), transcription (speech to text), embedding, or realtime (served only over a realtime session). A custom endpoint serves models of its own kind only."
|
|
23699
23764
|
}),
|
|
23700
|
-
|
|
23701
|
-
output: external_exports.number().optional(),
|
|
23702
|
-
image_input: external_exports.number().optional().meta({
|
|
23703
|
-
description: "USD per 1M image input tokens, where they are priced apart from text input."
|
|
23704
|
-
}),
|
|
23705
|
-
audio_input: external_exports.number().optional().meta({
|
|
23706
|
-
description: "USD per 1M audio input tokens, where they are priced apart from text input."
|
|
23707
|
-
}),
|
|
23708
|
-
video_input: external_exports.number().optional().meta({
|
|
23709
|
-
description: "USD per 1M video input tokens, where they are priced apart from text input."
|
|
23710
|
-
}),
|
|
23711
|
-
image_output: external_exports.number().optional().meta({
|
|
23712
|
-
description: "USD per 1M generated image tokens, where they cost more than text output."
|
|
23713
|
-
}),
|
|
23714
|
-
cached_input: external_exports.number().optional(),
|
|
23715
|
-
cache_write: external_exports.number().optional(),
|
|
23716
|
-
cache_write_1h: external_exports.number().optional().meta({
|
|
23717
|
-
description: "USD per 1M tokens written to a one-hour cache, where it costs more than the default cache write."
|
|
23718
|
-
}),
|
|
23765
|
+
...CATALOG_TOKEN_RATES,
|
|
23719
23766
|
per_minute: external_exports.number().optional(),
|
|
23720
23767
|
per_hour: external_exports.number().optional(),
|
|
23721
23768
|
per_image: external_exports.number().optional().meta({
|
|
23722
23769
|
description: "USD per generated image, for a model billed per image rather than per token."
|
|
23723
23770
|
}),
|
|
23724
23771
|
long_context_threshold: external_exports.number().optional(),
|
|
23725
|
-
long_input: external_exports.number().optional(),
|
|
23726
|
-
long_output: external_exports.number().optional(),
|
|
23727
|
-
long_cached_input: external_exports.number().optional(),
|
|
23728
|
-
long_cache_write: external_exports.number().optional(),
|
|
23729
|
-
long_cache_write_1h: external_exports.number().optional(),
|
|
23730
23772
|
retirement_date: external_exports.string().optional().meta({
|
|
23731
23773
|
description: "The day (YYYY-MM-DD) the provider stops, or stopped, serving this model. The model stays priced after it."
|
|
23732
23774
|
})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maxceem/agw",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
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.15.1",
|
|
30
|
+
"0.15.0",
|
|
29
31
|
"0.14.0",
|
|
30
32
|
"0.13.1",
|
|
31
33
|
"0.13.0",
|