@adonis-agora/agent 0.67.0 → 0.69.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.
Files changed (55) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/dist/providers/agent_provider.d.ts.map +1 -1
  3. package/dist/providers/agent_provider.js +52 -1
  4. package/dist/providers/agent_provider.js.map +1 -1
  5. package/dist/src/agent-loop.d.ts.map +1 -1
  6. package/dist/src/agent-loop.js +19 -2
  7. package/dist/src/agent-loop.js.map +1 -1
  8. package/dist/src/ai-sdk/ai-sdk-model.d.ts +12 -1
  9. package/dist/src/ai-sdk/ai-sdk-model.d.ts.map +1 -1
  10. package/dist/src/ai-sdk/ai-sdk-model.js +87 -5
  11. package/dist/src/ai-sdk/ai-sdk-model.js.map +1 -1
  12. package/dist/src/define_config.d.ts +35 -0
  13. package/dist/src/define_config.d.ts.map +1 -1
  14. package/dist/src/define_config.js.map +1 -1
  15. package/dist/src/index.d.ts +3 -1
  16. package/dist/src/index.d.ts.map +1 -1
  17. package/dist/src/index.js +3 -1
  18. package/dist/src/index.js.map +1 -1
  19. package/dist/src/opencode/turn.js +1 -1
  20. package/dist/src/opencode/turn.js.map +1 -1
  21. package/dist/src/pricing/bedrock.d.ts +64 -0
  22. package/dist/src/pricing/bedrock.d.ts.map +1 -0
  23. package/dist/src/pricing/bedrock.js +141 -0
  24. package/dist/src/pricing/bedrock.js.map +1 -0
  25. package/dist/src/pricing/boot-pricing.d.ts +90 -0
  26. package/dist/src/pricing/boot-pricing.d.ts.map +1 -0
  27. package/dist/src/pricing/boot-pricing.js +241 -0
  28. package/dist/src/pricing/boot-pricing.js.map +1 -0
  29. package/dist/src/pricing/models-dev.d.ts +26 -11
  30. package/dist/src/pricing/models-dev.d.ts.map +1 -1
  31. package/dist/src/pricing/models-dev.js +83 -15
  32. package/dist/src/pricing/models-dev.js.map +1 -1
  33. package/dist/src/spi/agent-store.d.ts +34 -7
  34. package/dist/src/spi/agent-store.d.ts.map +1 -1
  35. package/dist/src/spi/agent-store.js +14 -0
  36. package/dist/src/spi/agent-store.js.map +1 -1
  37. package/dist/src/spi/model-provider.d.ts +16 -1
  38. package/dist/src/spi/model-provider.d.ts.map +1 -1
  39. package/dist/src/stores/ledger-quota-provider.d.ts +11 -2
  40. package/dist/src/stores/ledger-quota-provider.d.ts.map +1 -1
  41. package/dist/src/stores/ledger-quota-provider.js +11 -4
  42. package/dist/src/stores/ledger-quota-provider.js.map +1 -1
  43. package/dist/src/stores/lucid-schema.d.ts.map +1 -1
  44. package/dist/src/stores/lucid-schema.js +4 -0
  45. package/dist/src/stores/lucid-schema.js.map +1 -1
  46. package/dist/src/stores/lucid.d.ts +2 -5
  47. package/dist/src/stores/lucid.d.ts.map +1 -1
  48. package/dist/src/stores/lucid.js +9 -8
  49. package/dist/src/stores/lucid.js.map +1 -1
  50. package/dist/src/testing/in-memory-store.d.ts +6 -6
  51. package/dist/src/testing/in-memory-store.d.ts.map +1 -1
  52. package/dist/src/testing/in-memory-store.js +6 -9
  53. package/dist/src/testing/in-memory-store.js.map +1 -1
  54. package/package.json +1 -1
  55. package/skills/agent-setup/SKILL.md +16 -2
@@ -0,0 +1,141 @@
1
+ const ARN = /^arn:(aws|aws-us-gov|aws-cn):bedrock:([a-z0-9-]*):(\d*):(inference-profile|foundation-model|application-inference-profile)\/(.+)$/;
2
+ /** Cross-region inference profile prefixes. `us-gov` before `us`: the alternation is ordered. */
3
+ const GEO = /^(us-gov|us|eu|apac|au|jp|ca|in|global)\.(?=[a-z0-9-]+\.)/;
4
+ /** The partition an AWS region belongs to; `undefined` for an empty / missing region. */
5
+ export function awsPartitionOfRegion(region) {
6
+ if (region === undefined || region.length === 0)
7
+ return undefined;
8
+ if (region.startsWith('us-gov-'))
9
+ return 'aws-us-gov';
10
+ if (region.startsWith('cn-'))
11
+ return 'aws-cn';
12
+ return 'aws';
13
+ }
14
+ /**
15
+ * Parse a Bedrock model id: an ARN (`arn:aws[-us-gov|-cn]:bedrock:<region>:<acct>:(inference-profile|
16
+ * foundation-model|application-inference-profile)/<id>`), a geo-prefixed inference profile, or a base
17
+ * id. Returns `undefined` for an id that is not Bedrock-shaped (no ARN, no geo prefix) — a plain
18
+ * `gpt-4o-mini` is not guessed at.
19
+ */
20
+ export function parseBedrockModelId(modelId) {
21
+ const arn = ARN.exec(modelId);
22
+ const profileId = arn !== null ? arn[5] : modelId;
23
+ const geo = GEO.exec(profileId)?.[1];
24
+ if (arn === null && geo === undefined)
25
+ return undefined;
26
+ const region = arn !== null && arn[2] !== '' ? arn[2] : undefined;
27
+ const isAppProfile = arn?.[4] === 'application-inference-profile';
28
+ const baseId = isAppProfile
29
+ ? undefined
30
+ : geo !== undefined
31
+ ? profileId.slice(geo.length + 1)
32
+ : profileId;
33
+ const partition = arn?.[1] ??
34
+ awsPartitionOfRegion(region) ??
35
+ (geo === 'us-gov' ? 'aws-us-gov' : undefined);
36
+ return { modelId, profileId, baseId, geo, region, partition, isArn: arn !== null };
37
+ }
38
+ /** Whether a model is reached through Bedrock: its provider says so, or its id is Bedrock-shaped. */
39
+ export function isBedrockModel(modelId, provider) {
40
+ if (provider !== undefined && /bedrock/i.test(provider))
41
+ return true;
42
+ return parseBedrockModelId(modelId) !== undefined;
43
+ }
44
+ /**
45
+ * The ids to look a Bedrock model's price up under, most specific first: the full id, the profile id
46
+ * (the ARN's resource), then the base foundation-model id. Deduplicated. A non-Bedrock-shaped id is
47
+ * its own only candidate.
48
+ */
49
+ export function bedrockPriceCandidates(modelId) {
50
+ const parsed = parseBedrockModelId(modelId);
51
+ const out = [modelId];
52
+ if (parsed === undefined)
53
+ return out;
54
+ for (const id of [parsed.profileId, parsed.baseId]) {
55
+ if (id !== undefined && id.length > 0 && !out.includes(id))
56
+ out.push(id);
57
+ }
58
+ return out;
59
+ }
60
+ /** Where the built-in prices below come from, for the log and the docs. */
61
+ export const BEDROCK_BUILTIN_PRICES_SOURCE = 'AWS Price List, AmazonBedrockFoundationModels, us-gov-west-1, published 2026-10-08 (on-demand, standard context)';
62
+ /**
63
+ * Built-in Bedrock prices (USD per 1M tokens) for partitions models.dev does not cover, keyed by base
64
+ * foundation-model id. Small and curated on purpose — it goes stale, so an app's own
65
+ * `priceCatalog.prices` (or a row it set) always wins over it. Commercial (`aws`) is not listed: it
66
+ * comes from models.dev. China (`aws-cn`) bills in CNY and is not covered: such a model is warned
67
+ * about and left unpriced until the app supplies a price.
68
+ */
69
+ export const BEDROCK_BUILTIN_PRICES = {
70
+ 'aws-us-gov': {
71
+ 'anthropic.claude-3-haiku-20240307-v1:0': { inputPricePer1m: 0.3, outputPricePer1m: 1.5 },
72
+ 'anthropic.claude-3-5-sonnet-20240620-v1:0': { inputPricePer1m: 3.6, outputPricePer1m: 18 },
73
+ 'anthropic.claude-3-7-sonnet-20250219-v1:0': {
74
+ inputPricePer1m: 3.6,
75
+ outputPricePer1m: 18,
76
+ cacheReadPricePer1m: 0.36,
77
+ cacheWritePricePer1m: 4.5,
78
+ },
79
+ 'anthropic.claude-sonnet-4-5-20250929-v1:0': {
80
+ inputPricePer1m: 3.6,
81
+ outputPricePer1m: 18,
82
+ cacheReadPricePer1m: 0.36,
83
+ cacheWritePricePer1m: 4.5,
84
+ },
85
+ 'anthropic.claude-sonnet-5': {
86
+ inputPricePer1m: 2.4,
87
+ outputPricePer1m: 12,
88
+ cacheReadPricePer1m: 0.24,
89
+ cacheWritePricePer1m: 3,
90
+ },
91
+ 'anthropic.claude-sonnet-5-5': {
92
+ inputPricePer1m: 2.4,
93
+ outputPricePer1m: 12,
94
+ cacheReadPricePer1m: 0.12,
95
+ cacheWritePricePer1m: 3,
96
+ },
97
+ 'anthropic.claude-opus-4-8': {
98
+ inputPricePer1m: 6,
99
+ outputPricePer1m: 30,
100
+ cacheReadPricePer1m: 0.6,
101
+ cacheWritePricePer1m: 7.5,
102
+ },
103
+ 'anthropic.claude-opus-5': {
104
+ inputPricePer1m: 6,
105
+ outputPricePer1m: 30,
106
+ cacheReadPricePer1m: 0.6,
107
+ cacheWritePricePer1m: 7.5,
108
+ },
109
+ 'anthropic.claude-opus-5-5': {
110
+ inputPricePer1m: 4.8,
111
+ outputPricePer1m: 24,
112
+ cacheReadPricePer1m: 0.24,
113
+ cacheWritePricePer1m: 6,
114
+ },
115
+ 'anthropic.claude-haiku-5-5': {
116
+ inputPricePer1m: 0.12,
117
+ outputPricePer1m: 0.6,
118
+ cacheReadPricePer1m: 0.012,
119
+ cacheWritePricePer1m: 0.15,
120
+ },
121
+ 'anthropic.claude-fable-5-1': {
122
+ inputPricePer1m: 12,
123
+ outputPricePer1m: 60,
124
+ cacheReadPricePer1m: 0.3,
125
+ cacheWritePricePer1m: 15,
126
+ },
127
+ },
128
+ };
129
+ /** The built-in price for a Bedrock model in a non-commercial partition, keyed by `modelId`. */
130
+ export function builtinBedrockPrice(modelId, partition) {
131
+ const table = BEDROCK_BUILTIN_PRICES[partition];
132
+ if (table === undefined)
133
+ return undefined;
134
+ for (const candidate of bedrockPriceCandidates(modelId)) {
135
+ const price = table[candidate];
136
+ if (price !== undefined)
137
+ return { modelId, ...price };
138
+ }
139
+ return undefined;
140
+ }
141
+ //# sourceMappingURL=bedrock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bedrock.js","sourceRoot":"","sources":["../../../src/pricing/bedrock.ts"],"names":[],"mappings":"AAsCA,MAAM,GAAG,GACP,mIAAmI,CAAC;AAEtI,iGAAiG;AACjG,MAAM,GAAG,GAAG,2DAA2D,CAAC;AAExE,yFAAyF;AACzF,MAAM,UAAU,oBAAoB,CAAC,MAA0B;IAC7D,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAClE,IAAI,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,YAAY,CAAC;IACtD,IAAI,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC9C,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAe;IACjD,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9B,MAAM,SAAS,GAAG,GAAG,KAAK,IAAI,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAY,CAAC,CAAC,CAAC,OAAO,CAAC;IAC9D,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACrC,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACxD,MAAM,MAAM,GAAG,GAAG,KAAK,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAClE,MAAM,YAAY,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,+BAA+B,CAAC;IAClE,MAAM,MAAM,GAAG,YAAY;QACzB,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,GAAG,KAAK,SAAS;YACjB,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;YACjC,CAAC,CAAC,SAAS,CAAC;IAChB,MAAM,SAAS,GACZ,GAAG,EAAE,CAAC,CAAC,CAA8B;QACtC,oBAAoB,CAAC,MAAM,CAAC;QAC5B,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAChD,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,KAAK,IAAI,EAAE,CAAC;AACrF,CAAC;AAED,qGAAqG;AACrG,MAAM,UAAU,cAAc,CAAC,OAAe,EAAE,QAA4B;IAC1E,IAAI,QAAQ,KAAK,SAAS,IAAI,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IACrE,OAAO,mBAAmB,CAAC,OAAO,CAAC,KAAK,SAAS,CAAC;AACpD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,OAAe;IACpD,MAAM,MAAM,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAC5C,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC;IACtB,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,GAAG,CAAC;IACrC,KAAK,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QACnD,IAAI,EAAE,KAAK,SAAS,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAAE,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC3E,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,2EAA2E;AAC3E,MAAM,CAAC,MAAM,6BAA6B,GACxC,kHAAkH,CAAC;AAErH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAE/B;IACF,YAAY,EAAE;QACZ,wCAAwC,EAAE,EAAE,eAAe,EAAE,GAAG,EAAE,gBAAgB,EAAE,GAAG,EAAE;QACzF,2CAA2C,EAAE,EAAE,eAAe,EAAE,GAAG,EAAE,gBAAgB,EAAE,EAAE,EAAE;QAC3F,2CAA2C,EAAE;YAC3C,eAAe,EAAE,GAAG;YACpB,gBAAgB,EAAE,EAAE;YACpB,mBAAmB,EAAE,IAAI;YACzB,oBAAoB,EAAE,GAAG;SAC1B;QACD,2CAA2C,EAAE;YAC3C,eAAe,EAAE,GAAG;YACpB,gBAAgB,EAAE,EAAE;YACpB,mBAAmB,EAAE,IAAI;YACzB,oBAAoB,EAAE,GAAG;SAC1B;QACD,2BAA2B,EAAE;YAC3B,eAAe,EAAE,GAAG;YACpB,gBAAgB,EAAE,EAAE;YACpB,mBAAmB,EAAE,IAAI;YACzB,oBAAoB,EAAE,CAAC;SACxB;QACD,6BAA6B,EAAE;YAC7B,eAAe,EAAE,GAAG;YACpB,gBAAgB,EAAE,EAAE;YACpB,mBAAmB,EAAE,IAAI;YACzB,oBAAoB,EAAE,CAAC;SACxB;QACD,2BAA2B,EAAE;YAC3B,eAAe,EAAE,CAAC;YAClB,gBAAgB,EAAE,EAAE;YACpB,mBAAmB,EAAE,GAAG;YACxB,oBAAoB,EAAE,GAAG;SAC1B;QACD,yBAAyB,EAAE;YACzB,eAAe,EAAE,CAAC;YAClB,gBAAgB,EAAE,EAAE;YACpB,mBAAmB,EAAE,GAAG;YACxB,oBAAoB,EAAE,GAAG;SAC1B;QACD,2BAA2B,EAAE;YAC3B,eAAe,EAAE,GAAG;YACpB,gBAAgB,EAAE,EAAE;YACpB,mBAAmB,EAAE,IAAI;YACzB,oBAAoB,EAAE,CAAC;SACxB;QACD,4BAA4B,EAAE;YAC5B,eAAe,EAAE,IAAI;YACrB,gBAAgB,EAAE,GAAG;YACrB,mBAAmB,EAAE,KAAK;YAC1B,oBAAoB,EAAE,IAAI;SAC3B;QACD,4BAA4B,EAAE;YAC5B,eAAe,EAAE,EAAE;YACnB,gBAAgB,EAAE,EAAE;YACpB,mBAAmB,EAAE,GAAG;YACxB,oBAAoB,EAAE,EAAE;SACzB;KACF;CACF,CAAC;AAEF,gGAAgG;AAChG,MAAM,UAAU,mBAAmB,CACjC,OAAe,EACf,SAAuB;IAEvB,MAAM,KAAK,GAAG,sBAAsB,CAAC,SAAS,CAAC,CAAC;IAChD,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC1C,KAAK,MAAM,SAAS,IAAI,sBAAsB,CAAC,OAAO,CAAC,EAAE,CAAC;QACxD,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;QAC/B,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,EAAE,OAAO,EAAE,GAAG,KAAK,EAAE,CAAC;IACxD,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,90 @@
1
+ import type { DescribedModel } from '../spi/model-provider.js';
2
+ import { type AgentPricingStore, type ModelPriceInput } from '../spi/pricing-store.js';
3
+ import { type ModelsDevOptions } from './models-dev.js';
4
+ /** How long the boot check waits for the models.dev catalog when no `signal` is given. */
5
+ export declare const CATALOG_TIMEOUT_MS = 15000;
6
+ /** Where boot pricing logs. Both are one line each, at most once per boot. */
7
+ export interface BootPricingLog {
8
+ info(message: string): void;
9
+ warn(message: string): void;
10
+ }
11
+ /**
12
+ * One app-supplied price, as a rate card states it. `input`/`output`/`cacheRead`/`cacheWrite` are in
13
+ * `currency` per `unit` of tokens. Only USD is recorded (the ledger column is `cost_usd`); a row in
14
+ * another currency is refused with a warning rather than recorded as dollars.
15
+ */
16
+ export interface PriceCatalogEntry {
17
+ /**
18
+ * The model id the price is for. A Bedrock id matches by normalized candidates, so one entry for the
19
+ * base id (`anthropic.claude-sonnet-4-5-20250929-v1:0`) or the profile id (`us-gov.anthropic.…`)
20
+ * also prices the ARN a turn reports (`arn:aws-us-gov:bedrock:…:inference-profile/us-gov.anthropic.…`).
21
+ */
22
+ model: string;
23
+ input: number;
24
+ output: number;
25
+ /** Cache-read (prompt-cache hit) input tokens. Omit → priced at `input`. */
26
+ cacheRead?: number;
27
+ /** Cache-write input tokens. Omit → priced at `input`. */
28
+ cacheWrite?: number;
29
+ /** Default `'USD'`, the only one accepted. */
30
+ currency?: 'USD';
31
+ /** Default `'1M tokens'`. */
32
+ unit?: '1M tokens' | '1K tokens';
33
+ }
34
+ /** The `priceCatalog` option: where boot seeds missing price rows from. */
35
+ export interface PriceCatalogOptions extends ModelsDevOptions {
36
+ /**
37
+ * Prices the app supplies. Seeded at boot for any model that has NO row yet (an existing row is
38
+ * never overwritten), and before models.dev or the built-in Bedrock table are consulted — so they
39
+ * win over both. Use it for GovCloud / China Bedrock, negotiated rates, or a model models.dev lacks.
40
+ */
41
+ prices?: readonly PriceCatalogEntry[];
42
+ /**
43
+ * The AWS region Bedrock runs in, for a Bedrock model id that does not name one (a base or `us.`
44
+ * profile id; an ARN or a `us-gov.` id already does). Omit → `AWS_REGION` / `AWS_DEFAULT_REGION`.
45
+ * A GovCloud (`us-gov-*`) or China (`cn-*`) region is never seeded with models.dev's commercial price.
46
+ */
47
+ region?: string;
48
+ /** `false` → never fetch models.dev (app prices and the built-in Bedrock table still apply). */
49
+ modelsDev?: boolean;
50
+ }
51
+ export interface EnsureModelPricingArgs {
52
+ /** The configured models (`ModelProvider.describeModels()`). */
53
+ models: readonly DescribedModel[];
54
+ /** The bound pricing store; `undefined` → nothing to seed, every non-gateway model is unpriced. */
55
+ pricingStore: AgentPricingStore | undefined;
56
+ /** Where to seed missing rows from; `false` → no app prices, never fetch models.dev. */
57
+ catalog: PriceCatalogOptions | false;
58
+ log: BootPricingLog;
59
+ }
60
+ export interface EnsureModelPricingResult {
61
+ /** Models a price row was written for (from app prices, the built-in Bedrock table or models.dev). */
62
+ seeded: string[];
63
+ /** Models that will record a `null` cost: no gateway cost and no price row. */
64
+ unpriced: string[];
65
+ }
66
+ /**
67
+ * Make sure every configured model records a cost, and say so when one will not.
68
+ *
69
+ * A model needs nothing when its provider reports the real cost (a gateway: OpenRouter, the Vercel AI
70
+ * Gateway) — that figure always wins. Every other model is priced off the pricing store, so a model
71
+ * with no row there would record `cost_usd = NULL` on every turn, silently. For each such model a row
72
+ * is written — only when it has NONE, so a price an operator set is never overwritten — from, in order:
73
+ *
74
+ * 1. the app's `priceCatalog.prices`;
75
+ * 2. for a Bedrock model in GovCloud / China, the built-in table (`BEDROCK_BUILTIN_PRICES`) — never
76
+ * models.dev, whose Bedrock prices are the commercial ones;
77
+ * 3. models.dev's current list price.
78
+ *
79
+ * The row is keyed by the exact id the model is configured with (an ARN stays an ARN), which is the id
80
+ * a turn reports and is priced under. Gateway models are seeded too, as the estimate a call that comes
81
+ * back without a cost falls back to.
82
+ *
83
+ * A model still unpriced after that gets one warning line naming it, why, and the `priceCatalog`
84
+ * entry that fixes it. Never throws: this runs at boot, and pricing is bookkeeping, not a reason for
85
+ * the app to stay down.
86
+ */
87
+ export declare function ensureModelPricing(args: EnsureModelPricingArgs): Promise<EnsureModelPricingResult>;
88
+ /** `priceCatalog.prices` as per-1M USD rows, keyed by model. Invalid entries are warned about and skipped. */
89
+ export declare function normalizePriceEntries(entries: readonly PriceCatalogEntry[], log?: BootPricingLog): Map<string, ModelPriceInput>;
90
+ //# sourceMappingURL=boot-pricing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"boot-pricing.d.ts","sourceRoot":"","sources":["../../../src/pricing/boot-pricing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EACL,KAAK,iBAAiB,EAEtB,KAAK,eAAe,EAErB,MAAM,yBAAyB,CAAC;AASjC,OAAO,EAEL,KAAK,gBAAgB,EAEtB,MAAM,iBAAiB,CAAC;AAEzB,0FAA0F;AAC1F,eAAO,MAAM,kBAAkB,QAAS,CAAC;AAEzC,8EAA8E;AAC9E,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;;OAIG;IACH,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0DAA0D;IAC1D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,KAAK,CAAC;IACjB,6BAA6B;IAC7B,IAAI,CAAC,EAAE,WAAW,GAAG,WAAW,CAAC;CAClC;AAED,2EAA2E;AAC3E,MAAM,WAAW,mBAAoB,SAAQ,gBAAgB;IAC3D;;;;OAIG;IACH,MAAM,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACtC;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gGAAgG;IAChG,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,sBAAsB;IACrC,gEAAgE;IAChE,MAAM,EAAE,SAAS,cAAc,EAAE,CAAC;IAClC,mGAAmG;IACnG,YAAY,EAAE,iBAAiB,GAAG,SAAS,CAAC;IAC5C,wFAAwF;IACxF,OAAO,EAAE,mBAAmB,GAAG,KAAK,CAAC;IACrC,GAAG,EAAE,cAAc,CAAC;CACrB;AAED,MAAM,WAAW,wBAAwB;IACvC,sGAAsG;IACtG,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,+EAA+E;IAC/E,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAID;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,sBAAsB,GAC3B,OAAO,CAAC,wBAAwB,CAAC,CAyJnC;AA0CD,8GAA8G;AAC9G,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,SAAS,iBAAiB,EAAE,EACrC,GAAG,CAAC,EAAE,cAAc,GACnB,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAuC9B"}
@@ -0,0 +1,241 @@
1
+ import { resolveModelPrice, } from '../spi/pricing-store.js';
2
+ import { awsPartitionOfRegion, bedrockPriceCandidates, builtinBedrockPrice, isBedrockModel, parseBedrockModelId, } from './bedrock.js';
3
+ import { lookupModelsDevPricesEach, modelsDevRefsFor, } from './models-dev.js';
4
+ /** How long the boot check waits for the models.dev catalog when no `signal` is given. */
5
+ export const CATALOG_TIMEOUT_MS = 15_000;
6
+ const PREFIX = '[@adonis-agora/agent]';
7
+ /**
8
+ * Make sure every configured model records a cost, and say so when one will not.
9
+ *
10
+ * A model needs nothing when its provider reports the real cost (a gateway: OpenRouter, the Vercel AI
11
+ * Gateway) — that figure always wins. Every other model is priced off the pricing store, so a model
12
+ * with no row there would record `cost_usd = NULL` on every turn, silently. For each such model a row
13
+ * is written — only when it has NONE, so a price an operator set is never overwritten — from, in order:
14
+ *
15
+ * 1. the app's `priceCatalog.prices`;
16
+ * 2. for a Bedrock model in GovCloud / China, the built-in table (`BEDROCK_BUILTIN_PRICES`) — never
17
+ * models.dev, whose Bedrock prices are the commercial ones;
18
+ * 3. models.dev's current list price.
19
+ *
20
+ * The row is keyed by the exact id the model is configured with (an ARN stays an ARN), which is the id
21
+ * a turn reports and is priced under. Gateway models are seeded too, as the estimate a call that comes
22
+ * back without a cost falls back to.
23
+ *
24
+ * A model still unpriced after that gets one warning line naming it, why, and the `priceCatalog`
25
+ * entry that fixes it. Never throws: this runs at boot, and pricing is bookkeeping, not a reason for
26
+ * the app to stay down.
27
+ */
28
+ export async function ensureModelPricing(args) {
29
+ const models = dedupe(args.models);
30
+ const catalog = args.catalog === false ? undefined : args.catalog;
31
+ const seeded = [];
32
+ const reasons = new Map();
33
+ let current = new Map();
34
+ const store = args.pricingStore;
35
+ if (store !== undefined) {
36
+ let needing;
37
+ try {
38
+ const rows = await store.listCurrentPrices();
39
+ current = new Map(rows.map((row) => [row.modelId, row]));
40
+ needing = models.filter((model) => resolveModelPrice(current, model.modelId) === undefined);
41
+ }
42
+ catch (error) {
43
+ args.log.warn(`${PREFIX} Could not read the pricing table at boot: ${messageOf(error)}`);
44
+ needing = [];
45
+ }
46
+ const effectiveFrom = new Date().toISOString();
47
+ const write = async (price) => {
48
+ if (current.has(price.modelId))
49
+ return false;
50
+ try {
51
+ await store.upsertModelPrice(price);
52
+ }
53
+ catch (error) {
54
+ args.log.warn(`${PREFIX} Could not write the price of ${price.modelId}: ${messageOf(error)}`);
55
+ return false;
56
+ }
57
+ current.set(price.modelId, { ...price, effectiveFrom });
58
+ return true;
59
+ };
60
+ const stillNeeding = () => needing.filter((model) => resolveModelPrice(current, model.modelId) === undefined);
61
+ // 1. The app's own prices: every entry gets its row, and a configured model matching one by id.
62
+ const appPrices = normalizePriceEntries(catalog?.prices ?? [], args.log);
63
+ if (appPrices.size > 0) {
64
+ const before = stillNeeding();
65
+ for (const price of appPrices.values())
66
+ await write(price);
67
+ // Keyed by the configured id too, so the id a turn reports finds it by exact match.
68
+ for (const model of before) {
69
+ const price = matchPrice(appPrices, model.modelId);
70
+ if (price !== undefined)
71
+ await write({ ...price, modelId: model.modelId });
72
+ }
73
+ const fromApp = before
74
+ .filter((model) => resolveModelPrice(current, model.modelId) !== undefined)
75
+ .map((model) => model.modelId);
76
+ if (fromApp.length > 0) {
77
+ seeded.push(...fromApp);
78
+ args.log.info(`${PREFIX} Seeded prices from \`priceCatalog.prices\` for ${fromApp.join(', ')}.`);
79
+ }
80
+ }
81
+ // 2. Bedrock outside the commercial partition: the built-in table, never models.dev.
82
+ const region = catalog?.region ?? defaultAwsRegion();
83
+ const fromBuiltin = [];
84
+ const commercial = [];
85
+ for (const model of stillNeeding()) {
86
+ const partition = bedrockPartitionOf(model, region);
87
+ if (partition === undefined || partition === 'aws') {
88
+ commercial.push(model);
89
+ continue;
90
+ }
91
+ const price = builtinBedrockPrice(model.modelId, partition);
92
+ if (price !== undefined && (await write(price)))
93
+ fromBuiltin.push(model.modelId);
94
+ else {
95
+ reasons.set(model.modelId, `no price for AWS partition ${partition}${regionNote(model, region)} — models.dev lists commercial Bedrock prices only, and the built-in table has none for it`);
96
+ }
97
+ }
98
+ if (fromBuiltin.length > 0) {
99
+ seeded.push(...fromBuiltin);
100
+ args.log.info(`${PREFIX} Seeded built-in AWS GovCloud Bedrock prices for ${fromBuiltin.join(', ')} (from the AWS Price List; may go stale). Set \`priceCatalog.prices\` to override.`);
101
+ }
102
+ // 3. models.dev, for the rest.
103
+ if (commercial.length > 0) {
104
+ if (catalog === undefined || catalog.modelsDev === false) {
105
+ for (const model of commercial) {
106
+ reasons.set(model.modelId, 'no price row, and models.dev lookups are off');
107
+ }
108
+ }
109
+ else {
110
+ try {
111
+ const refs = commercial.map((model) => modelsDevRefsFor(model.modelId, model.provider));
112
+ const { prices: _p, region: _r, modelsDev: _m, ...modelsDev } = catalog;
113
+ const found = await lookupModelsDevPricesEach(refs,
114
+ // Bounded: a hung catalog must not hold a shutdown (which awaits this) open forever.
115
+ modelsDev.signal !== undefined
116
+ ? modelsDev
117
+ : { ...modelsDev, signal: AbortSignal.timeout(CATALOG_TIMEOUT_MS) });
118
+ const fromModelsDev = [];
119
+ for (const [i, model] of commercial.entries()) {
120
+ const price = found[i];
121
+ if (price === undefined) {
122
+ reasons.set(model.modelId, 'unknown model — models.dev does not list a price for it');
123
+ }
124
+ else if (await write({ ...price, modelId: model.modelId })) {
125
+ fromModelsDev.push(model.modelId);
126
+ }
127
+ }
128
+ if (fromModelsDev.length > 0) {
129
+ seeded.push(...fromModelsDev);
130
+ const bedrock = commercial.some((model) => isBedrockModel(model.modelId, model.provider));
131
+ args.log.info(`${PREFIX} Seeded list prices from models.dev for ${fromModelsDev.join(', ')} — an estimate, used when the provider reports no cost.${bedrock
132
+ ? ' Bedrock rows are COMMERCIAL-region prices: for GovCloud or China set `priceCatalog.region` (or `AWS_REGION`).'
133
+ : ''} Set your own with \`priceCatalog.prices\`, \`upsertModelPrice\` to override.`);
134
+ }
135
+ }
136
+ catch (error) {
137
+ args.log.warn(`${PREFIX} Could not seed prices from models.dev: ${messageOf(error)}`);
138
+ for (const model of commercial)
139
+ reasons.set(model.modelId, 'models.dev was unreachable');
140
+ }
141
+ }
142
+ }
143
+ }
144
+ const unpriced = models
145
+ .filter((model) => !model.reportsCost)
146
+ .filter((model) => resolveModelPrice(current, model.modelId) === undefined)
147
+ .map((model) => model.modelId);
148
+ if (unpriced.length > 0) {
149
+ // Grouped by reason: `a, b (unknown model …); c (no price for AWS partition …)`.
150
+ const groups = new Map();
151
+ for (const id of unpriced) {
152
+ const reason = reasons.get(id) ?? '';
153
+ groups.set(reason, [...(groups.get(reason) ?? []), id]);
154
+ }
155
+ const named = [...groups]
156
+ .map(([reason, ids]) => `${ids.join(', ')}${reason !== '' ? ` (${reason})` : ''}`)
157
+ .join('; ');
158
+ const example = exampleModelFor(unpriced[0]);
159
+ args.log.warn(`${PREFIX} No cost will be recorded for ${named}: the provider reports no cost and ${store === undefined
160
+ ? 'no `pricingStore` is configured. Configure one, then '
161
+ : 'the pricing table has no row for it. '}Add the price to \`priceCatalog.prices\`, e.g. \`{ model: '${example}', input: <USD per 1M>, output: <USD per 1M>, cacheRead?, cacheWrite? }\`, or seed a row with \`seedModelPrices(store, [...])\`, or route through a gateway that reports cost (OpenRouter, Vercel AI Gateway).`);
162
+ }
163
+ return { seeded, unpriced };
164
+ }
165
+ /** The partition a Bedrock model runs in: its id says, else the configured region; `undefined` → not Bedrock / unknown. */
166
+ function bedrockPartitionOf(model, region) {
167
+ if (!isBedrockModel(model.modelId, model.provider))
168
+ return undefined;
169
+ return parseBedrockModelId(model.modelId)?.partition ?? awsPartitionOfRegion(region);
170
+ }
171
+ function regionNote(model, region) {
172
+ const fromId = parseBedrockModelId(model.modelId);
173
+ const r = fromId?.region ?? (fromId?.partition === undefined ? region : undefined);
174
+ return r !== undefined ? ` (region ${r})` : '';
175
+ }
176
+ /** The id to put in the warning's example entry: the shortest id that still prices the model. */
177
+ function exampleModelFor(modelId) {
178
+ const parsed = parseBedrockModelId(modelId);
179
+ return parsed?.isArn ? parsed.profileId : modelId;
180
+ }
181
+ function defaultAwsRegion() {
182
+ const env = globalThis.process
183
+ ?.env;
184
+ const region = env?.AWS_REGION ?? env?.AWS_DEFAULT_REGION;
185
+ return region !== undefined && region.length > 0 ? region : undefined;
186
+ }
187
+ /** A model's app price: by its exact id, then its normalized Bedrock candidates. */
188
+ function matchPrice(prices, modelId) {
189
+ for (const candidate of bedrockPriceCandidates(modelId)) {
190
+ const price = prices.get(candidate);
191
+ if (price !== undefined)
192
+ return price;
193
+ }
194
+ return undefined;
195
+ }
196
+ /** `priceCatalog.prices` as per-1M USD rows, keyed by model. Invalid entries are warned about and skipped. */
197
+ export function normalizePriceEntries(entries, log) {
198
+ const out = new Map();
199
+ const rejected = [];
200
+ for (const entry of entries) {
201
+ const label = typeof entry?.model === 'string' && entry.model.length > 0 ? entry.model : '?';
202
+ const currency = entry?.currency ?? 'USD';
203
+ const unit = entry?.unit ?? '1M tokens';
204
+ const scale = unit === '1M tokens' ? 1 : unit === '1K tokens' ? 1000 : undefined;
205
+ const rates = [entry?.input, entry?.output, entry?.cacheRead, entry?.cacheWrite];
206
+ const bad = rates.some((rate, i) => (i < 2 || rate !== undefined) &&
207
+ (typeof rate !== 'number' || !Number.isFinite(rate) || rate < 0));
208
+ if (label === '?' || currency !== 'USD' || scale === undefined || bad) {
209
+ rejected.push(`${label} (${currency !== 'USD'
210
+ ? `currency ${String(currency)} — only USD is recorded`
211
+ : scale === undefined
212
+ ? `unit ${String(unit)} — use '1M tokens' or '1K tokens'`
213
+ : 'needs a model and non-negative numeric input/output'})`);
214
+ continue;
215
+ }
216
+ if (out.has(entry.model))
217
+ continue; // first entry for a model wins
218
+ out.set(entry.model, {
219
+ modelId: entry.model,
220
+ inputPricePer1m: entry.input * scale,
221
+ outputPricePer1m: entry.output * scale,
222
+ ...(entry.cacheRead !== undefined ? { cacheReadPricePer1m: entry.cacheRead * scale } : {}),
223
+ ...(entry.cacheWrite !== undefined ? { cacheWritePricePer1m: entry.cacheWrite * scale } : {}),
224
+ });
225
+ }
226
+ if (rejected.length > 0) {
227
+ log?.warn(`${PREFIX} Ignored \`priceCatalog.prices\` entries: ${rejected.join('; ')}.`);
228
+ }
229
+ return out;
230
+ }
231
+ function dedupe(models) {
232
+ const seen = new Map();
233
+ for (const model of models)
234
+ if (!seen.has(model.modelId))
235
+ seen.set(model.modelId, model);
236
+ return [...seen.values()];
237
+ }
238
+ function messageOf(error) {
239
+ return error instanceof Error ? error.message : String(error);
240
+ }
241
+ //# sourceMappingURL=boot-pricing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"boot-pricing.js","sourceRoot":"","sources":["../../../src/pricing/boot-pricing.ts"],"names":[],"mappings":"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"}
@@ -10,21 +10,36 @@ export interface ModelsDevOptions {
10
10
  }
11
11
  /** Um modelo no catálogo: `'<provider>/<model>'`, por exemplo `'openai/gpt-4o-mini'`. */
12
12
  export type ModelsDevRef = string;
13
+ /** The result of a lenient lookup: what the catalog priced, and what it did not. */
14
+ export interface ModelsDevLookup {
15
+ prices: ModelPriceInput[];
16
+ /** Refs with no entry, or an entry without an input/output price. */
17
+ missing: ModelsDevRef[];
18
+ }
13
19
  /**
14
- * Busca no [models.dev](https://models.dev) os preços dos modelos pedidos.
15
- *
16
- * Existe porque a alternativa é alguém copiar números de uma tabela de preços para dentro de um
17
- * seeder à mão. Um preço errado ali não quebra nada e não avisa: ele produz uma conta errada no
18
- * dashboard, que é pior do que conta nenhuma — quem lê acredita.
20
+ * The lenient twin of {@link fetchModelsDevPrices}, for boot-time seeding: a model the catalog does
21
+ * not price is reported in `missing` instead of failing the whole batch, so one unknown model does
22
+ * not leave every other one unpriced. Throws only when the catalog itself cannot be read.
19
23
  *
20
- * O que ele devolve são `ModelPriceInput` prontos para o `upsertModelPrice`, chaveados pelo NOME
21
- * DO MODELO (`gpt-4o-mini`), não pelo `provider/model` pedido. É de propósito: é assim que os
22
- * provedores publicam o preço, e a resolução do fold (ver `resolveModelPrice`) já sabe chegar do
23
- * snapshot datado que o provider reporta até esse alias.
24
+ * Each ref is a LIST of candidates, tried in order — the first one the catalog prices wins.
25
+ */
26
+ export declare function lookupModelsDevPrices(refs: readonly (readonly ModelsDevRef[])[], options?: ModelsDevOptions): Promise<ModelsDevLookup>;
27
+ /**
28
+ * {@link lookupModelsDevPrices}, one result per element of `refs` (in order): the price the first
29
+ * pricing candidate yields, or `undefined`. For callers that key the row themselves.
30
+ */
31
+ export declare function lookupModelsDevPricesEach(refs: readonly (readonly ModelsDevRef[])[], options?: ModelsDevOptions): Promise<(ModelPriceInput | undefined)[]>;
32
+ /**
33
+ * The models.dev refs to try for a model, most specific first: `<provider>/<modelId>`, then — for an
34
+ * OpenRouter-style id (`deepseek/deepseek-v4.1-flash`) reached through another SDK — the OpenRouter
35
+ * list price. `provider` is the AI SDK provider family (`openrouter`, `openai`, `vercel`, …).
24
36
  *
25
- * FALHA ALTO. Um modelo pedido que não existe no catálogo, ou existe sem preço, vira erro — e não
26
- * uma linha faltando em silêncio, que reapareceria depois como `$0.00` num painel.
37
+ * A Bedrock id is normalized first (see `parseBedrockModelId`): an ARN or a geo-prefixed inference
38
+ * profile is tried as the full id, the profile id, then the base foundation-model id — all under
39
+ * `amazon-bedrock`. An ARN is never tried as an OpenRouter id (its `/` is not a vendor separator), nor
40
+ * looked up verbatim (models.dev lists no ARNs).
27
41
  */
42
+ export declare function modelsDevRefsFor(modelId: string, provider: string | undefined): ModelsDevRef[];
28
43
  export declare function fetchModelsDevPrices(models: readonly ModelsDevRef[], options?: ModelsDevOptions): Promise<ModelPriceInput[]>;
29
44
  /**
30
45
  * Busca no models.dev e grava no store. O atalho de uma linha para um comando de seed.
@@ -1 +1 @@
1
- {"version":3,"file":"models-dev.d.ts","sourceRoot":"","sources":["../../../src/pricing/models-dev.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAElF,6DAA6D;AAC7D,eAAO,MAAM,cAAc,gCAAgC,CAAC;AAkB5D,MAAM,WAAW,gBAAgB;IAC/B,gGAAgG;IAChG,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,gGAAgG;IAChG,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IAChC,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,yFAAyF;AACzF,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC;AAclC;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,SAAS,YAAY,EAAE,EAC/B,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,eAAe,EAAE,CAAC,CAqC5B;AAED;;;;;;;;GAQG;AACH,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,iBAAiB,EACxB,MAAM,EAAE,SAAS,YAAY,EAAE,EAC/B,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,eAAe,EAAE,CAAC,CAM5B"}
1
+ {"version":3,"file":"models-dev.d.ts","sourceRoot":"","sources":["../../../src/pricing/models-dev.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAGlF,6DAA6D;AAC7D,eAAO,MAAM,cAAc,gCAAgC,CAAC;AAkB5D,MAAM,WAAW,gBAAgB;IAC/B,gGAAgG;IAChG,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,gGAAgG;IAChG,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IAChC,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,yFAAyF;AACzF,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC;AA0DlC,oFAAoF;AACpF,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,qEAAqE;IACrE,OAAO,EAAE,YAAY,EAAE,CAAC;CACzB;AAED;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,SAAS,CAAC,SAAS,YAAY,EAAE,CAAC,EAAE,EAC1C,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,eAAe,CAAC,CAS1B;AAED;;;GAGG;AACH,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,SAAS,CAAC,SAAS,YAAY,EAAE,CAAC,EAAE,EAC1C,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,CAAC,eAAe,GAAG,SAAS,CAAC,EAAE,CAAC,CAM1C;AAKD;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,YAAY,EAAE,CAa9F;AAED,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,SAAS,YAAY,EAAE,EAC/B,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,eAAe,EAAE,CAAC,CAoB5B;AAED;;;;;;;;GAQG;AACH,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,iBAAiB,EACxB,MAAM,EAAE,SAAS,YAAY,EAAE,EAC/B,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,eAAe,EAAE,CAAC,CAM5B"}