@audit-tools/shared 0.1.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 (113) hide show
  1. package/dist/contracts.d.ts +2 -0
  2. package/dist/contracts.d.ts.map +1 -0
  3. package/dist/contracts.js +2 -0
  4. package/dist/contracts.js.map +1 -0
  5. package/dist/index.d.ts +35 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.js +21 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/io/json.d.ts +11 -0
  10. package/dist/io/json.d.ts.map +1 -0
  11. package/dist/io/json.js +142 -0
  12. package/dist/io/json.js.map +1 -0
  13. package/dist/providers/constants.d.ts +2 -0
  14. package/dist/providers/constants.d.ts.map +1 -0
  15. package/dist/providers/constants.js +2 -0
  16. package/dist/providers/constants.js.map +1 -0
  17. package/dist/providers/types.d.ts +43 -0
  18. package/dist/providers/types.d.ts.map +1 -0
  19. package/dist/providers/types.js +2 -0
  20. package/dist/providers/types.js.map +1 -0
  21. package/dist/quota/compositeQuotaSource.d.ts +8 -0
  22. package/dist/quota/compositeQuotaSource.d.ts.map +1 -0
  23. package/dist/quota/compositeQuotaSource.js +21 -0
  24. package/dist/quota/compositeQuotaSource.js.map +1 -0
  25. package/dist/quota/errorParsers/claudeCodeErrorParser.d.ts +7 -0
  26. package/dist/quota/errorParsers/claudeCodeErrorParser.d.ts.map +1 -0
  27. package/dist/quota/errorParsers/claudeCodeErrorParser.js +40 -0
  28. package/dist/quota/errorParsers/claudeCodeErrorParser.js.map +1 -0
  29. package/dist/quota/errorParsers/genericErrorParser.d.ts +10 -0
  30. package/dist/quota/errorParsers/genericErrorParser.d.ts.map +1 -0
  31. package/dist/quota/errorParsers/genericErrorParser.js +8 -0
  32. package/dist/quota/errorParsers/genericErrorParser.js.map +1 -0
  33. package/dist/quota/errorParsers/index.d.ts +6 -0
  34. package/dist/quota/errorParsers/index.d.ts.map +1 -0
  35. package/dist/quota/errorParsers/index.js +13 -0
  36. package/dist/quota/errorParsers/index.js.map +1 -0
  37. package/dist/quota/errorParsing.d.ts +8 -0
  38. package/dist/quota/errorParsing.d.ts.map +1 -0
  39. package/dist/quota/errorParsing.js +70 -0
  40. package/dist/quota/errorParsing.js.map +1 -0
  41. package/dist/quota/fileLock.d.ts +7 -0
  42. package/dist/quota/fileLock.d.ts.map +1 -0
  43. package/dist/quota/fileLock.js +65 -0
  44. package/dist/quota/fileLock.js.map +1 -0
  45. package/dist/quota/hostLimits.d.ts +10 -0
  46. package/dist/quota/hostLimits.d.ts.map +1 -0
  47. package/dist/quota/hostLimits.js +52 -0
  48. package/dist/quota/hostLimits.js.map +1 -0
  49. package/dist/quota/learnedQuotaSource.d.ts +8 -0
  50. package/dist/quota/learnedQuotaSource.d.ts.map +1 -0
  51. package/dist/quota/learnedQuotaSource.js +26 -0
  52. package/dist/quota/learnedQuotaSource.js.map +1 -0
  53. package/dist/quota/limits.d.ts +17 -0
  54. package/dist/quota/limits.d.ts.map +1 -0
  55. package/dist/quota/limits.js +78 -0
  56. package/dist/quota/limits.js.map +1 -0
  57. package/dist/quota/quotaSource.d.ts +13 -0
  58. package/dist/quota/quotaSource.d.ts.map +1 -0
  59. package/dist/quota/quotaSource.js +2 -0
  60. package/dist/quota/quotaSource.js.map +1 -0
  61. package/dist/quota/slidingWindow.d.ts +5 -0
  62. package/dist/quota/slidingWindow.d.ts.map +1 -0
  63. package/dist/quota/slidingWindow.js +29 -0
  64. package/dist/quota/slidingWindow.js.map +1 -0
  65. package/dist/quota/state.d.ts +13 -0
  66. package/dist/quota/state.d.ts.map +1 -0
  67. package/dist/quota/state.js +153 -0
  68. package/dist/quota/state.js.map +1 -0
  69. package/dist/quota/types.d.ts +54 -0
  70. package/dist/quota/types.d.ts.map +1 -0
  71. package/dist/quota/types.js +2 -0
  72. package/dist/quota/types.js.map +1 -0
  73. package/dist/types/accessDeclaration.d.ts +6 -0
  74. package/dist/types/accessDeclaration.d.ts.map +1 -0
  75. package/dist/types/accessDeclaration.js +2 -0
  76. package/dist/types/accessDeclaration.js.map +1 -0
  77. package/dist/types/disposition.d.ts +10 -0
  78. package/dist/types/disposition.d.ts.map +1 -0
  79. package/dist/types/disposition.js +2 -0
  80. package/dist/types/disposition.js.map +1 -0
  81. package/dist/types/flows.d.ts +18 -0
  82. package/dist/types/flows.d.ts.map +1 -0
  83. package/dist/types/flows.js +2 -0
  84. package/dist/types/flows.js.map +1 -0
  85. package/dist/types/graph.d.ts +23 -0
  86. package/dist/types/graph.d.ts.map +1 -0
  87. package/dist/types/graph.js +2 -0
  88. package/dist/types/graph.js.map +1 -0
  89. package/dist/types/risk.d.ts +10 -0
  90. package/dist/types/risk.d.ts.map +1 -0
  91. package/dist/types/risk.js +2 -0
  92. package/dist/types/risk.js.map +1 -0
  93. package/dist/types/runLedger.d.ts +18 -0
  94. package/dist/types/runLedger.d.ts.map +1 -0
  95. package/dist/types/runLedger.js +7 -0
  96. package/dist/types/runLedger.js.map +1 -0
  97. package/dist/types/sessionConfig.d.ts +75 -0
  98. package/dist/types/sessionConfig.d.ts.map +1 -0
  99. package/dist/types/sessionConfig.js +16 -0
  100. package/dist/types/sessionConfig.js.map +1 -0
  101. package/dist/types/stepContract.d.ts +7 -0
  102. package/dist/types/stepContract.d.ts.map +1 -0
  103. package/dist/types/stepContract.js +2 -0
  104. package/dist/types/stepContract.js.map +1 -0
  105. package/dist/types/surfaces.d.ts +16 -0
  106. package/dist/types/surfaces.d.ts.map +1 -0
  107. package/dist/types/surfaces.js +2 -0
  108. package/dist/types/surfaces.js.map +1 -0
  109. package/dist/validation/basic.d.ts +14 -0
  110. package/dist/validation/basic.d.ts.map +1 -0
  111. package/dist/validation/basic.js +47 -0
  112. package/dist/validation/basic.js.map +1 -0
  113. package/package.json +29 -0
@@ -0,0 +1,65 @@
1
+ import { open, unlink, stat } from "node:fs/promises";
2
+ const STALE_LOCK_MS = 30_000;
3
+ const RETRY_INTERVAL_MS = 50;
4
+ const DEFAULT_TIMEOUT_MS = 10_000;
5
+ export class FileLockTimeoutError extends Error {
6
+ constructor(lockPath) {
7
+ super(`Timed out acquiring lock: ${lockPath}`);
8
+ this.name = "FileLockTimeoutError";
9
+ }
10
+ }
11
+ async function isLockStale(lockPath) {
12
+ try {
13
+ const info = await stat(lockPath);
14
+ return Date.now() - info.mtimeMs > STALE_LOCK_MS;
15
+ }
16
+ catch {
17
+ return false;
18
+ }
19
+ }
20
+ export async function acquireLock(lockPath, timeoutMs = DEFAULT_TIMEOUT_MS) {
21
+ const deadline = Date.now() + timeoutMs;
22
+ while (true) {
23
+ try {
24
+ const fd = await open(lockPath, "wx");
25
+ await fd.close();
26
+ return;
27
+ }
28
+ catch (err) {
29
+ if (err.code !== "EEXIST")
30
+ throw err;
31
+ }
32
+ if (await isLockStale(lockPath)) {
33
+ try {
34
+ await unlink(lockPath);
35
+ continue;
36
+ }
37
+ catch {
38
+ // Another process may have already cleaned it up
39
+ }
40
+ }
41
+ if (Date.now() >= deadline) {
42
+ throw new FileLockTimeoutError(lockPath);
43
+ }
44
+ await new Promise((r) => setTimeout(r, RETRY_INTERVAL_MS));
45
+ }
46
+ }
47
+ export async function releaseLock(lockPath) {
48
+ try {
49
+ await unlink(lockPath);
50
+ }
51
+ catch (err) {
52
+ if (err.code !== "ENOENT")
53
+ throw err;
54
+ }
55
+ }
56
+ export async function withFileLock(lockPath, fn, timeoutMs) {
57
+ await acquireLock(lockPath, timeoutMs);
58
+ try {
59
+ return await fn();
60
+ }
61
+ finally {
62
+ await releaseLock(lockPath);
63
+ }
64
+ }
65
+ //# sourceMappingURL=fileLock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fileLock.js","sourceRoot":"","sources":["../../src/quota/fileLock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAEtD,MAAM,aAAa,GAAG,MAAM,CAAC;AAC7B,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAC7B,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAElC,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAC7C,YAAY,QAAgB;QAC1B,KAAK,CAAC,6BAA6B,QAAQ,EAAE,CAAC,CAAC;QAC/C,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF;AAED,KAAK,UAAU,WAAW,CAAC,QAAgB;IACzC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC;QAClC,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,GAAG,aAAa,CAAC;IACnD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,QAAgB,EAChB,YAAoB,kBAAkB;IAEtC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;IAExC,OAAO,IAAI,EAAE,CAAC;QACZ,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;YACtC,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC;YACjB,OAAO;QACT,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ;gBAAE,MAAM,GAAG,CAAC;QAClE,CAAC;QAED,IAAI,MAAM,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC;YAChC,IAAI,CAAC;gBACH,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;gBACvB,SAAS;YACX,CAAC;YAAC,MAAM,CAAC;gBACP,iDAAiD;YACnD,CAAC;QACH,CAAC;QAED,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,QAAQ,EAAE,CAAC;YAC3B,MAAM,IAAI,oBAAoB,CAAC,QAAQ,CAAC,CAAC;QAC3C,CAAC;QAED,MAAM,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,iBAAiB,CAAC,CAAC,CAAC;IACnE,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,QAAgB;IAChD,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;IACzB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ;YAAE,MAAM,GAAG,CAAC;IAClE,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,QAAgB,EAChB,EAAoB,EACpB,SAAkB;IAElB,MAAM,WAAW,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IACvC,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,EAAE,CAAC;IACpB,CAAC;YAAS,CAAC;QACT,MAAM,WAAW,CAAC,QAAQ,CAAC,CAAC;IAC9B,CAAC;AACH,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { SessionConfig } from "../types/sessionConfig.js";
2
+ import type { HostConcurrencyLimit } from "./types.js";
3
+ export declare function detectHostActiveSubagentLimit(envPrefix: string, env?: NodeJS.ProcessEnv): HostConcurrencyLimit | null;
4
+ export declare function resolveHostActiveSubagentLimit(options: {
5
+ envPrefix: string;
6
+ explicitLimit?: number | null;
7
+ sessionConfig: SessionConfig;
8
+ env?: NodeJS.ProcessEnv;
9
+ }): HostConcurrencyLimit | null;
10
+ //# sourceMappingURL=hostLimits.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hostLimits.d.ts","sourceRoot":"","sources":["../../src/quota/hostLimits.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAevD,wBAAgB,6BAA6B,CAC3C,SAAS,EAAE,MAAM,EACjB,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,oBAAoB,GAAG,IAAI,CAsB7B;AAED,wBAAgB,8BAA8B,CAAC,OAAO,EAAE;IACtD,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,aAAa,EAAE,aAAa,CAAC;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB,GAAG,oBAAoB,GAAG,IAAI,CAsB9B"}
@@ -0,0 +1,52 @@
1
+ const CODEX_DESKTOP_ACTIVE_SUBAGENT_LIMIT = 6;
2
+ function parsePositiveInteger(value) {
3
+ if (typeof value === "number") {
4
+ return Number.isInteger(value) && value > 0 ? value : null;
5
+ }
6
+ if (typeof value !== "string")
7
+ return null;
8
+ const trimmed = value.trim();
9
+ if (!/^\d+$/.test(trimmed))
10
+ return null;
11
+ const parsed = Number(trimmed);
12
+ return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : null;
13
+ }
14
+ export function detectHostActiveSubagentLimit(envPrefix, env = process.env) {
15
+ const explicitEnvLimit = parsePositiveInteger(env[`${envPrefix}_HOST_MAX_ACTIVE_SUBAGENTS`] ??
16
+ env.CODEX_MAX_ACTIVE_SUBAGENTS);
17
+ if (explicitEnvLimit !== null) {
18
+ return {
19
+ active_subagents: explicitEnvLimit,
20
+ source: "environment",
21
+ description: "Host active subagent limit from environment.",
22
+ };
23
+ }
24
+ if (env.CODEX_INTERNAL_ORIGINATOR_OVERRIDE === "Codex Desktop") {
25
+ return {
26
+ active_subagents: CODEX_DESKTOP_ACTIVE_SUBAGENT_LIMIT,
27
+ source: "environment",
28
+ description: "Codex Desktop active subagent limit.",
29
+ };
30
+ }
31
+ return null;
32
+ }
33
+ export function resolveHostActiveSubagentLimit(options) {
34
+ if (options.explicitLimit !== undefined && options.explicitLimit !== null) {
35
+ return {
36
+ active_subagents: options.explicitLimit,
37
+ source: "cli_flags",
38
+ description: "Host active subagent limit reported by the conversation host.",
39
+ };
40
+ }
41
+ const configuredLimit = parsePositiveInteger(options.sessionConfig.quota?.host_active_subagent_limit ??
42
+ options.sessionConfig.parallel_workers);
43
+ if (configuredLimit !== null) {
44
+ return {
45
+ active_subagents: configuredLimit,
46
+ source: "session_config",
47
+ description: "Host active subagent limit from session-config.",
48
+ };
49
+ }
50
+ return detectHostActiveSubagentLimit(options.envPrefix, options.env);
51
+ }
52
+ //# sourceMappingURL=hostLimits.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hostLimits.js","sourceRoot":"","sources":["../../src/quota/hostLimits.ts"],"names":[],"mappings":"AAGA,MAAM,mCAAmC,GAAG,CAAC,CAAC;AAE9C,SAAS,oBAAoB,CAAC,KAAc;IAC1C,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;IAC7D,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3C,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IACxC,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAC/B,OAAO,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,6BAA6B,CAC3C,SAAiB,EACjB,MAAyB,OAAO,CAAC,GAAG;IAEpC,MAAM,gBAAgB,GAAG,oBAAoB,CAC3C,GAAG,CAAC,GAAG,SAAS,4BAA4B,CAAC;QAC3C,GAAG,CAAC,0BAA0B,CACjC,CAAC;IACF,IAAI,gBAAgB,KAAK,IAAI,EAAE,CAAC;QAC9B,OAAO;YACL,gBAAgB,EAAE,gBAAgB;YAClC,MAAM,EAAE,aAAa;YACrB,WAAW,EAAE,8CAA8C;SAC5D,CAAC;IACJ,CAAC;IAED,IAAI,GAAG,CAAC,kCAAkC,KAAK,eAAe,EAAE,CAAC;QAC/D,OAAO;YACL,gBAAgB,EAAE,mCAAmC;YACrD,MAAM,EAAE,aAAa;YACrB,WAAW,EAAE,sCAAsC;SACpD,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,8BAA8B,CAAC,OAK9C;IACC,IAAI,OAAO,CAAC,aAAa,KAAK,SAAS,IAAI,OAAO,CAAC,aAAa,KAAK,IAAI,EAAE,CAAC;QAC1E,OAAO;YACL,gBAAgB,EAAE,OAAO,CAAC,aAAa;YACvC,MAAM,EAAE,WAAW;YACnB,WAAW,EAAE,+DAA+D;SAC7E,CAAC;IACJ,CAAC;IAED,MAAM,eAAe,GAAG,oBAAoB,CAC1C,OAAO,CAAC,aAAa,CAAC,KAAK,EAAE,0BAA0B;QACrD,OAAO,CAAC,aAAa,CAAC,gBAAgB,CACzC,CAAC;IACF,IAAI,eAAe,KAAK,IAAI,EAAE,CAAC;QAC7B,OAAO;YACL,gBAAgB,EAAE,eAAe;YACjC,MAAM,EAAE,gBAAgB;YACxB,WAAW,EAAE,iDAAiD;SAC/D,CAAC;IACJ,CAAC;IAED,OAAO,6BAA6B,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;AACvE,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { QuotaSource, QuotaUsageSnapshot } from "./quotaSource.js";
2
+ export declare class LearnedQuotaSource implements QuotaSource {
3
+ readonly name = "learned";
4
+ private halfLifeHours;
5
+ constructor(halfLifeHours?: number);
6
+ queryCurrentUsage(providerModelKey: string): Promise<QuotaUsageSnapshot | null>;
7
+ }
8
+ //# sourceMappingURL=learnedQuotaSource.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"learnedQuotaSource.d.ts","sourceRoot":"","sources":["../../src/quota/learnedQuotaSource.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAGxE,qBAAa,kBAAmB,YAAW,WAAW;IACpD,QAAQ,CAAC,IAAI,aAAa;IAE1B,OAAO,CAAC,aAAa,CAAS;gBAElB,aAAa,SAAK;IAIxB,iBAAiB,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;CAmBtF"}
@@ -0,0 +1,26 @@
1
+ import { readQuotaState, computeMaxSafeConcurrency } from "./state.js";
2
+ export class LearnedQuotaSource {
3
+ name = "learned";
4
+ halfLifeHours;
5
+ constructor(halfLifeHours = 24) {
6
+ this.halfLifeHours = halfLifeHours;
7
+ }
8
+ async queryCurrentUsage(providerModelKey) {
9
+ const state = await readQuotaState();
10
+ const entry = state.entries[providerModelKey];
11
+ if (!entry)
12
+ return null;
13
+ const maxSafe = computeMaxSafeConcurrency(entry, this.halfLifeHours);
14
+ const isInCooldown = entry.cooldown_until != null &&
15
+ new Date(entry.cooldown_until).getTime() > Date.now();
16
+ return {
17
+ remaining_pct: isInCooldown ? 0 : null,
18
+ reset_at: isInCooldown ? entry.cooldown_until : null,
19
+ requests_remaining: maxSafe,
20
+ tokens_remaining: null,
21
+ captured_at: entry.updated_at,
22
+ source: "learned",
23
+ };
24
+ }
25
+ }
26
+ //# sourceMappingURL=learnedQuotaSource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"learnedQuotaSource.js","sourceRoot":"","sources":["../../src/quota/learnedQuotaSource.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAEvE,MAAM,OAAO,kBAAkB;IACpB,IAAI,GAAG,SAAS,CAAC;IAElB,aAAa,CAAS;IAE9B,YAAY,aAAa,GAAG,EAAE;QAC5B,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;IACrC,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,gBAAwB;QAC9C,MAAM,KAAK,GAAG,MAAM,cAAc,EAAE,CAAC;QACrC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;QAC9C,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QAExB,MAAM,OAAO,GAAG,yBAAyB,CAAC,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QACrE,MAAM,YAAY,GAChB,KAAK,CAAC,cAAc,IAAI,IAAI;YAC5B,IAAI,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAExD,OAAO;YACL,aAAa,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI;YACtC,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI;YACpD,kBAAkB,EAAE,OAAO;YAC3B,gBAAgB,EAAE,IAAI;YACtB,WAAW,EAAE,KAAK,CAAC,UAAU;YAC7B,MAAM,EAAE,SAAS;SAClB,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,17 @@
1
+ import type { ResolvedProviderName, SessionConfig } from "../types/sessionConfig.js";
2
+ import type { LimitConfidence, LimitSource, ResolvedLimits } from "./types.js";
3
+ export type ProviderType = "hosted" | "local" | "unknown";
4
+ export declare function classifyProvider(providerName: ResolvedProviderName): ProviderType;
5
+ export declare function lookupKnownModel(modelKey: string): Pick<ResolvedLimits, "context_tokens" | "output_tokens"> | undefined;
6
+ export interface LimitResolutionResult {
7
+ limits: ResolvedLimits;
8
+ source: LimitSource;
9
+ confidence: LimitConfidence;
10
+ }
11
+ export interface ResolveLimitsOptions {
12
+ providerName: ResolvedProviderName;
13
+ sessionConfig: SessionConfig;
14
+ hostModel?: string | null;
15
+ }
16
+ export declare function resolveLimits(options: ResolveLimitsOptions): LimitResolutionResult;
17
+ //# sourceMappingURL=limits.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"limits.d.ts","sourceRoot":"","sources":["../../src/quota/limits.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AACrF,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAe/E,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;AAE1D,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,oBAAoB,GAAG,YAAY,CAYjF;AAED,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,GACf,IAAI,CAAC,cAAc,EAAE,gBAAgB,GAAG,eAAe,CAAC,GAAG,SAAS,CAEtE;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,WAAW,CAAC;IACpB,UAAU,EAAE,eAAe,CAAC;CAC7B;AAED,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,oBAAoB,CAAC;IACnC,aAAa,EAAE,aAAa,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAaD,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,qBAAqB,CAyClF"}
@@ -0,0 +1,78 @@
1
+ // RPM/TPM are omitted here — they are tier-dependent and must come from learning.
2
+ const KNOWN_MODEL_LIMITS = {
3
+ "anthropic/claude-opus-4-7": { context_tokens: 200_000, output_tokens: 32_000 },
4
+ "anthropic/claude-sonnet-4-6": { context_tokens: 200_000, output_tokens: 8_192 },
5
+ "anthropic/claude-haiku-4-5": { context_tokens: 200_000, output_tokens: 8_192 },
6
+ "anthropic/claude-opus-4-5": { context_tokens: 200_000, output_tokens: 8_192 },
7
+ "anthropic/claude-sonnet-4-5": { context_tokens: 200_000, output_tokens: 8_192 },
8
+ "openai/gpt-4o": { context_tokens: 128_000, output_tokens: 16_384 },
9
+ "openai/gpt-4o-mini": { context_tokens: 128_000, output_tokens: 16_384 },
10
+ "google/gemini-2.0-flash": { context_tokens: 1_048_576, output_tokens: 8_192 },
11
+ "google/gemini-1.5-pro": { context_tokens: 2_097_152, output_tokens: 8_192 },
12
+ };
13
+ export function classifyProvider(providerName) {
14
+ switch (providerName) {
15
+ case "claude-code":
16
+ return "hosted";
17
+ case "opencode":
18
+ case "local-subprocess":
19
+ return "local";
20
+ case "subprocess-template":
21
+ case "vscode-task":
22
+ default:
23
+ return "unknown";
24
+ }
25
+ }
26
+ export function lookupKnownModel(modelKey) {
27
+ return KNOWN_MODEL_LIMITS[modelKey.toLowerCase().trim()];
28
+ }
29
+ function defaultLimits(sessionConfig) {
30
+ const quota = sessionConfig.quota ?? {};
31
+ return {
32
+ context_tokens: quota.default_context_tokens ?? 32_000,
33
+ output_tokens: quota.reserved_output_tokens ?? 4_096,
34
+ requests_per_minute: null,
35
+ input_tokens_per_minute: null,
36
+ output_tokens_per_minute: null,
37
+ };
38
+ }
39
+ export function resolveLimits(options) {
40
+ const { providerName: _providerName, sessionConfig, hostModel } = options;
41
+ const quota = sessionConfig.quota ?? {};
42
+ const defaults = defaultLimits(sessionConfig);
43
+ // 1. Explicit per-model config overrides
44
+ if (hostModel && quota.models?.[hostModel]) {
45
+ const override = quota.models[hostModel];
46
+ return {
47
+ limits: {
48
+ context_tokens: override.context_tokens ?? defaults.context_tokens,
49
+ output_tokens: override.output_tokens ?? defaults.output_tokens,
50
+ requests_per_minute: override.requests_per_minute ?? null,
51
+ input_tokens_per_minute: override.input_tokens_per_minute ?? null,
52
+ output_tokens_per_minute: override.output_tokens_per_minute ?? null,
53
+ },
54
+ source: "explicit_config",
55
+ confidence: "high",
56
+ };
57
+ }
58
+ // 2. Static known-model database (context/output only; RPM/TPM from learning)
59
+ if (hostModel) {
60
+ const known = lookupKnownModel(hostModel);
61
+ if (known) {
62
+ return {
63
+ limits: {
64
+ context_tokens: known.context_tokens,
65
+ output_tokens: known.output_tokens,
66
+ requests_per_minute: null,
67
+ input_tokens_per_minute: null,
68
+ output_tokens_per_minute: null,
69
+ },
70
+ source: "known_metadata",
71
+ confidence: "medium",
72
+ };
73
+ }
74
+ }
75
+ // 3. Conservative defaults for all provider types
76
+ return { limits: defaults, source: "default", confidence: "low" };
77
+ }
78
+ //# sourceMappingURL=limits.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"limits.js","sourceRoot":"","sources":["../../src/quota/limits.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export interface QuotaUsageSnapshot {
2
+ remaining_pct: number | null;
3
+ reset_at: string | null;
4
+ requests_remaining: number | null;
5
+ tokens_remaining: number | null;
6
+ captured_at: string;
7
+ source: string;
8
+ }
9
+ export interface QuotaSource {
10
+ readonly name: string;
11
+ queryCurrentUsage(providerModelKey: string): Promise<QuotaUsageSnapshot | null>;
12
+ }
13
+ //# sourceMappingURL=quotaSource.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quotaSource.d.ts","sourceRoot":"","sources":["../../src/quota/quotaSource.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,kBAAkB;IACjC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;CACjF"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=quotaSource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quotaSource.js","sourceRoot":"","sources":["../../src/quota/quotaSource.ts"],"names":[],"mappings":""}
@@ -0,0 +1,5 @@
1
+ export interface SlidingWindowResult<T> {
2
+ results: PromiseSettledResult<T>[];
3
+ }
4
+ export declare function runSlidingWindow<T>(tasks: Array<() => Promise<T>>, concurrency: number, onComplete?: (index: number, result: PromiseSettledResult<T>) => void): Promise<SlidingWindowResult<T>>;
5
+ //# sourceMappingURL=slidingWindow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slidingWindow.d.ts","sourceRoot":"","sources":["../../src/quota/slidingWindow.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB,CAAC,CAAC;IACpC,OAAO,EAAE,oBAAoB,CAAC,CAAC,CAAC,EAAE,CAAC;CACpC;AAED,wBAAsB,gBAAgB,CAAC,CAAC,EACtC,KAAK,EAAE,KAAK,CAAC,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC,EAC9B,WAAW,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,oBAAoB,CAAC,CAAC,CAAC,KAAK,IAAI,GACpE,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CA8BjC"}
@@ -0,0 +1,29 @@
1
+ export async function runSlidingWindow(tasks, concurrency, onComplete) {
2
+ const results = new Array(tasks.length);
3
+ let nextIndex = 0;
4
+ async function runOne(index) {
5
+ let result;
6
+ try {
7
+ const value = await tasks[index]();
8
+ result = { status: "fulfilled", value };
9
+ }
10
+ catch (reason) {
11
+ result = { status: "rejected", reason };
12
+ }
13
+ results[index] = result;
14
+ onComplete?.(index, result);
15
+ if (nextIndex < tasks.length) {
16
+ const next = nextIndex++;
17
+ await runOne(next);
18
+ }
19
+ }
20
+ const initialBatch = Math.min(concurrency, tasks.length);
21
+ const runners = [];
22
+ for (let i = 0; i < initialBatch; i++) {
23
+ const idx = nextIndex++;
24
+ runners.push(runOne(idx));
25
+ }
26
+ await Promise.all(runners);
27
+ return { results };
28
+ }
29
+ //# sourceMappingURL=slidingWindow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slidingWindow.js","sourceRoot":"","sources":["../../src/quota/slidingWindow.ts"],"names":[],"mappings":"AAIA,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,KAA8B,EAC9B,WAAmB,EACnB,UAAqE;IAErE,MAAM,OAAO,GAA8B,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACnE,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,KAAK,UAAU,MAAM,CAAC,KAAa;QACjC,IAAI,MAA+B,CAAC;QACpC,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YACnC,MAAM,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;QAC1C,CAAC;QAAC,OAAO,MAAM,EAAE,CAAC;YAChB,MAAM,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;QAC1C,CAAC;QACD,OAAO,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC;QACxB,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAE5B,IAAI,SAAS,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;YAC7B,MAAM,IAAI,GAAG,SAAS,EAAE,CAAC;YACzB,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IAED,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACzD,MAAM,OAAO,GAAoB,EAAE,CAAC;IACpC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,GAAG,GAAG,SAAS,EAAE,CAAC;QACxB,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5B,CAAC;IAED,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC3B,OAAO,EAAE,OAAO,EAAE,CAAC;AACrB,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { ObservedWaveOutcome, QuotaState, QuotaStateEntry } from "./types.js";
2
+ export declare function setQuotaStateDir(dir: string): void;
3
+ export declare function getQuotaStatePath(): string;
4
+ export declare function decayWeight(weight: number, elapsedHours: number, halfLifeHours: number): number;
5
+ export declare function applyDecayToEntry(entry: QuotaStateEntry, halfLifeHours: number): QuotaStateEntry;
6
+ export declare function readQuotaState(): Promise<QuotaState>;
7
+ export declare function writeQuotaState(state: QuotaState): Promise<void>;
8
+ export declare function computeMaxSafeConcurrency(entry: QuotaStateEntry, halfLifeHours: number, maxToCheck?: number): number;
9
+ export declare function computeRampUpConcurrency(entry: QuotaStateEntry, halfLifeHours: number, maxToCheck?: number): number;
10
+ export declare function computeBackoffCooldownMs(consecutive429Count: number): number;
11
+ export declare function computeBackoffFailureWeight(consecutive429Count: number): number;
12
+ export declare function recordWaveOutcome(providerModelKey: string, outcome: ObservedWaveOutcome, halfLifeHours: number): Promise<void>;
13
+ //# sourceMappingURL=state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/quota/state.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAqB,mBAAmB,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAQtG,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAGlD;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAG1C;AAED,wBAAgB,WAAW,CACzB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,GACpB,MAAM,CAGR;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,eAAe,EACtB,aAAa,EAAE,MAAM,GACpB,eAAe,CAWjB;AASD,wBAAsB,cAAc,IAAI,OAAO,CAAC,UAAU,CAAC,CA2B1D;AAED,wBAAsB,eAAe,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAMtE;AAED,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,eAAe,EACtB,aAAa,EAAE,MAAM,EACrB,UAAU,SAAK,GACd,MAAM,CAgBR;AAID,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,eAAe,EACtB,aAAa,EAAE,MAAM,EACrB,UAAU,SAAK,GACd,MAAM,CAYR;AASD,wBAAgB,wBAAwB,CAAC,mBAAmB,EAAE,MAAM,GAAG,MAAM,CAG5E;AAED,wBAAgB,2BAA2B,CAAC,mBAAmB,EAAE,MAAM,GAAG,MAAM,CAE/E;AAED,wBAAsB,iBAAiB,CACrC,gBAAgB,EAAE,MAAM,EACxB,OAAO,EAAE,mBAAmB,EAC5B,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC,CAGf"}
@@ -0,0 +1,153 @@
1
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { withFileLock } from "./fileLock.js";
4
+ const MIN_EVIDENCE_WEIGHT = 0.5;
5
+ let _stateDir;
6
+ let _statePath;
7
+ export function setQuotaStateDir(dir) {
8
+ _stateDir = dir;
9
+ _statePath = join(dir, "quota-state.json");
10
+ }
11
+ export function getQuotaStatePath() {
12
+ if (!_statePath)
13
+ throw new Error("Quota state dir not set — call setQuotaStateDir() first.");
14
+ return _statePath;
15
+ }
16
+ export function decayWeight(weight, elapsedHours, halfLifeHours) {
17
+ if (halfLifeHours <= 0 || weight <= 0)
18
+ return 0;
19
+ return weight * Math.pow(0.5, elapsedHours / halfLifeHours);
20
+ }
21
+ export function applyDecayToEntry(entry, halfLifeHours) {
22
+ const elapsedHours = (Date.now() - new Date(entry.updated_at).getTime()) / (1000 * 60 * 60);
23
+ if (elapsedHours < 0.001)
24
+ return entry;
25
+ const decayed = {};
26
+ for (const [key, bucket] of Object.entries(entry.buckets)) {
27
+ decayed[key] = {
28
+ success_weight: decayWeight(bucket.success_weight, elapsedHours, halfLifeHours),
29
+ failure_weight: decayWeight(bucket.failure_weight, elapsedHours, halfLifeHours),
30
+ };
31
+ }
32
+ return { ...entry, buckets: decayed };
33
+ }
34
+ function isQuotaState(value) {
35
+ if (value === null || typeof value !== "object" || Array.isArray(value))
36
+ return false;
37
+ const obj = value;
38
+ const version = obj["version"];
39
+ return (version === 1 || version === 2) && typeof obj["entries"] === "object";
40
+ }
41
+ export async function readQuotaState() {
42
+ const statePath = getQuotaStatePath();
43
+ try {
44
+ const raw = await readFile(statePath, "utf8");
45
+ const parsed = JSON.parse(raw);
46
+ if (isQuotaState(parsed)) {
47
+ if (parsed.version === 1) {
48
+ for (const entry of Object.values(parsed.entries)) {
49
+ entry.consecutive_429_count ??= 0;
50
+ }
51
+ }
52
+ return parsed;
53
+ }
54
+ process.stderr.write(`[quota] ignoring invalid quota state at ${statePath}: expected { version: 1|2, entries: object }\n`);
55
+ }
56
+ catch (error) {
57
+ if (error.code === "ENOENT") {
58
+ return { version: 2, entries: {} };
59
+ }
60
+ process.stderr.write(`[quota] ignoring unreadable quota state at ${statePath}: ${error instanceof Error ? error.message : String(error)}\n`);
61
+ }
62
+ return { version: 2, entries: {} };
63
+ }
64
+ export async function writeQuotaState(state) {
65
+ const stateDir = _stateDir;
66
+ if (!stateDir)
67
+ throw new Error("Quota state dir not set — call setQuotaStateDir() first.");
68
+ await mkdir(stateDir, { recursive: true });
69
+ const normalized = { ...state, version: 2 };
70
+ await writeFile(getQuotaStatePath(), JSON.stringify(normalized, null, 2) + "\n", "utf8");
71
+ }
72
+ export function computeMaxSafeConcurrency(entry, halfLifeHours, maxToCheck = 32) {
73
+ const decayed = applyDecayToEntry(entry, halfLifeHours);
74
+ let maxSafe = 1;
75
+ for (let n = 1; n <= maxToCheck; n++) {
76
+ const bucket = decayed.buckets[String(n)];
77
+ if (!bucket)
78
+ break;
79
+ if (bucket.success_weight >= MIN_EVIDENCE_WEIGHT &&
80
+ bucket.success_weight > bucket.failure_weight) {
81
+ maxSafe = n;
82
+ }
83
+ else {
84
+ break;
85
+ }
86
+ }
87
+ return maxSafe;
88
+ }
89
+ const RAMP_UP_MIN_SUCCESSES = 2;
90
+ export function computeRampUpConcurrency(entry, halfLifeHours, maxToCheck = 32) {
91
+ const maxSafe = computeMaxSafeConcurrency(entry, halfLifeHours, maxToCheck);
92
+ const decayed = applyDecayToEntry(entry, halfLifeHours);
93
+ const bucket = decayed.buckets[String(maxSafe)];
94
+ if (bucket &&
95
+ bucket.success_weight >= RAMP_UP_MIN_SUCCESSES &&
96
+ bucket.failure_weight === 0) {
97
+ return maxSafe + 1;
98
+ }
99
+ return maxSafe;
100
+ }
101
+ function blankEntry() {
102
+ return { updated_at: new Date().toISOString(), buckets: {}, cooldown_until: null, last_429_at: null };
103
+ }
104
+ const BASE_COOLDOWN_MS = 60_000;
105
+ const MAX_COOLDOWN_MS = 15 * 60_000;
106
+ export function computeBackoffCooldownMs(consecutive429Count) {
107
+ const ms = BASE_COOLDOWN_MS * Math.pow(2, Math.max(0, consecutive429Count - 1));
108
+ return Math.min(ms, MAX_COOLDOWN_MS);
109
+ }
110
+ export function computeBackoffFailureWeight(consecutive429Count) {
111
+ return 1.0 + 0.5 * Math.max(0, consecutive429Count - 1);
112
+ }
113
+ export async function recordWaveOutcome(providerModelKey, outcome, halfLifeHours) {
114
+ const lockPath = getQuotaStatePath() + ".lock";
115
+ await withFileLock(lockPath, () => recordWaveOutcomeUnsafe(providerModelKey, outcome, halfLifeHours));
116
+ }
117
+ async function recordWaveOutcomeUnsafe(providerModelKey, outcome, halfLifeHours) {
118
+ const state = await readQuotaState();
119
+ const entry = applyDecayToEntry(state.entries[providerModelKey] ?? blankEntry(), halfLifeHours);
120
+ if (outcome.outcome === "success") {
121
+ entry.consecutive_429_count = 0;
122
+ for (let n = 1; n <= outcome.concurrency; n++) {
123
+ const bucket = entry.buckets[String(n)] ?? { success_weight: 0, failure_weight: 0 };
124
+ bucket.success_weight += 1.0;
125
+ entry.buckets[String(n)] = bucket;
126
+ }
127
+ }
128
+ else {
129
+ const prev429Count = entry.consecutive_429_count ?? 0;
130
+ const new429Count = outcome.outcome === "rate_limited" ? prev429Count + 1 : prev429Count;
131
+ entry.consecutive_429_count = new429Count;
132
+ entry.last_429_at = new Date().toISOString();
133
+ if (outcome.outcome === "rate_limited" && new429Count > 0) {
134
+ const backoffMs = computeBackoffCooldownMs(new429Count);
135
+ entry.cooldown_until = new Date(Date.now() + backoffMs).toISOString();
136
+ }
137
+ else if (outcome.cooldown_until) {
138
+ entry.cooldown_until = outcome.cooldown_until;
139
+ }
140
+ const failureWeight = outcome.outcome === "rate_limited"
141
+ ? computeBackoffFailureWeight(new429Count)
142
+ : 1.0;
143
+ for (let n = outcome.concurrency; n <= outcome.concurrency + 4; n++) {
144
+ const bucket = entry.buckets[String(n)] ?? { success_weight: 0, failure_weight: 0 };
145
+ bucket.failure_weight += failureWeight;
146
+ entry.buckets[String(n)] = bucket;
147
+ }
148
+ }
149
+ entry.updated_at = new Date().toISOString();
150
+ state.entries[providerModelKey] = entry;
151
+ await writeQuotaState(state);
152
+ }
153
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/quota/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAEhC,IAAI,SAA6B,CAAC;AAClC,IAAI,UAA8B,CAAC;AAEnC,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,SAAS,GAAG,GAAG,CAAC;IAChB,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,IAAI,CAAC,UAAU;QAAE,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;IAC7F,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,MAAM,UAAU,WAAW,CACzB,MAAc,EACd,YAAoB,EACpB,aAAqB;IAErB,IAAI,aAAa,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAChD,OAAO,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,YAAY,GAAG,aAAa,CAAC,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,KAAsB,EACtB,aAAqB;IAErB,MAAM,YAAY,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;IAC5F,IAAI,YAAY,GAAG,KAAK;QAAE,OAAO,KAAK,CAAC;IACvC,MAAM,OAAO,GAAsC,EAAE,CAAC;IACtD,KAAK,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QAC1D,OAAO,CAAC,GAAG,CAAC,GAAG;YACb,cAAc,EAAE,WAAW,CAAC,MAAM,CAAC,cAAc,EAAE,YAAY,EAAE,aAAa,CAAC;YAC/E,cAAc,EAAE,WAAW,CAAC,MAAM,CAAC,cAAc,EAAE,YAAY,EAAE,aAAa,CAAC;SAChF,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;AACxC,CAAC;AAED,SAAS,YAAY,CAAC,KAAc;IAClC,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACtF,MAAM,GAAG,GAAG,KAAgC,CAAC;IAC7C,MAAM,OAAO,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC;IAC/B,OAAO,CAAC,OAAO,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,CAAC,IAAI,OAAO,GAAG,CAAC,SAAS,CAAC,KAAK,QAAQ,CAAC;AAChF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,MAAM,SAAS,GAAG,iBAAiB,EAAE,CAAC;IACtC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QAC9C,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACxC,IAAI,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;YACzB,IAAI,MAAM,CAAC,OAAO,KAAK,CAAC,EAAE,CAAC;gBACzB,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;oBAClD,KAAK,CAAC,qBAAqB,KAAK,CAAC,CAAC;gBACpC,CAAC;YACH,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,2CAA2C,SAAS,gDAAgD,CACrG,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACvD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;QACrC,CAAC;QACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,8CAA8C,SAAS,KACrD,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CACvD,IAAI,CACL,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;AACrC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,KAAiB;IACrD,MAAM,QAAQ,GAAG,SAAS,CAAC;IAC3B,IAAI,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;IAC3F,MAAM,KAAK,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,MAAM,UAAU,GAAe,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;IACxD,MAAM,SAAS,CAAC,iBAAiB,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC;AAC3F,CAAC;AAED,MAAM,UAAU,yBAAyB,CACvC,KAAsB,EACtB,aAAqB,EACrB,UAAU,GAAG,EAAE;IAEf,MAAM,OAAO,GAAG,iBAAiB,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;IACxD,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1C,IAAI,CAAC,MAAM;YAAE,MAAM;QACnB,IACE,MAAM,CAAC,cAAc,IAAI,mBAAmB;YAC5C,MAAM,CAAC,cAAc,GAAG,MAAM,CAAC,cAAc,EAC7C,CAAC;YACD,OAAO,GAAG,CAAC,CAAC;QACd,CAAC;aAAM,CAAC;YACN,MAAM;QACR,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,qBAAqB,GAAG,CAAC,CAAC;AAEhC,MAAM,UAAU,wBAAwB,CACtC,KAAsB,EACtB,aAAqB,EACrB,UAAU,GAAG,EAAE;IAEf,MAAM,OAAO,GAAG,yBAAyB,CAAC,KAAK,EAAE,aAAa,EAAE,UAAU,CAAC,CAAC;IAC5E,MAAM,OAAO,GAAG,iBAAiB,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;IACxD,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IAChD,IACE,MAAM;QACN,MAAM,CAAC,cAAc,IAAI,qBAAqB;QAC9C,MAAM,CAAC,cAAc,KAAK,CAAC,EAC3B,CAAC;QACD,OAAO,OAAO,GAAG,CAAC,CAAC;IACrB,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,UAAU;IACjB,OAAO,EAAE,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;AACxG,CAAC;AAED,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAChC,MAAM,eAAe,GAAG,EAAE,GAAG,MAAM,CAAC;AAEpC,MAAM,UAAU,wBAAwB,CAAC,mBAA2B;IAClE,MAAM,EAAE,GAAG,gBAAgB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,mBAAmB,GAAG,CAAC,CAAC,CAAC,CAAC;IAChF,OAAO,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,eAAe,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,mBAA2B;IACrE,OAAO,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,mBAAmB,GAAG,CAAC,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,gBAAwB,EACxB,OAA4B,EAC5B,aAAqB;IAErB,MAAM,QAAQ,GAAG,iBAAiB,EAAE,GAAG,OAAO,CAAC;IAC/C,MAAM,YAAY,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,uBAAuB,CAAC,gBAAgB,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC;AACxG,CAAC;AAED,KAAK,UAAU,uBAAuB,CACpC,gBAAwB,EACxB,OAA4B,EAC5B,aAAqB;IAErB,MAAM,KAAK,GAAG,MAAM,cAAc,EAAE,CAAC;IACrC,MAAM,KAAK,GAAG,iBAAiB,CAAC,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC,IAAI,UAAU,EAAE,EAAE,aAAa,CAAC,CAAC;IAEhG,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAClC,KAAK,CAAC,qBAAqB,GAAG,CAAC,CAAC;QAChC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC;YAC9C,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,cAAc,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,CAAC;YACpF,MAAM,CAAC,cAAc,IAAI,GAAG,CAAC;YAC7B,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;QACpC,CAAC;IACH,CAAC;SAAM,CAAC;QACN,MAAM,YAAY,GAAG,KAAK,CAAC,qBAAqB,IAAI,CAAC,CAAC;QACtD,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,KAAK,cAAc,CAAC,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC;QACzF,KAAK,CAAC,qBAAqB,GAAG,WAAW,CAAC;QAC1C,KAAK,CAAC,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAE7C,IAAI,OAAO,CAAC,OAAO,KAAK,cAAc,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;YAC1D,MAAM,SAAS,GAAG,wBAAwB,CAAC,WAAW,CAAC,CAAC;YACxD,KAAK,CAAC,cAAc,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC;QACxE,CAAC;aAAM,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;YAClC,KAAK,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;QAChD,CAAC;QAED,MAAM,aAAa,GAAG,OAAO,CAAC,OAAO,KAAK,cAAc;YACtD,CAAC,CAAC,2BAA2B,CAAC,WAAW,CAAC;YAC1C,CAAC,CAAC,GAAG,CAAC;QACR,KAAK,IAAI,CAAC,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,IAAI,OAAO,CAAC,WAAW,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YACpE,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,cAAc,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,CAAC;YACpF,MAAM,CAAC,cAAc,IAAI,aAAa,CAAC;YACvC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;QACpC,CAAC;IACH,CAAC;IAED,KAAK,CAAC,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC5C,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC,GAAG,KAAK,CAAC;IACxC,MAAM,eAAe,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,54 @@
1
+ export type LimitSource = "explicit_config" | "cli_flags" | "known_metadata" | "learned" | "default";
2
+ export type LimitConfidence = "high" | "medium" | "low";
3
+ export type HostConcurrencyLimitSource = "cli_flags" | "host_reported" | "session_config" | "environment";
4
+ export interface HostConcurrencyLimit {
5
+ active_subagents: number;
6
+ source: HostConcurrencyLimitSource;
7
+ description: string;
8
+ }
9
+ export interface ResolvedLimits {
10
+ context_tokens: number;
11
+ output_tokens: number;
12
+ requests_per_minute: number | null;
13
+ input_tokens_per_minute: number | null;
14
+ output_tokens_per_minute: number | null;
15
+ }
16
+ export interface ConcurrencyBucket {
17
+ success_weight: number;
18
+ failure_weight: number;
19
+ }
20
+ export interface QuotaStateEntry {
21
+ updated_at: string;
22
+ buckets: Record<string, ConcurrencyBucket>;
23
+ cooldown_until: string | null;
24
+ last_429_at: string | null;
25
+ consecutive_429_count?: number;
26
+ }
27
+ export interface QuotaState {
28
+ version: 1 | 2;
29
+ entries: Record<string, QuotaStateEntry>;
30
+ }
31
+ export interface WaveSchedule {
32
+ wave_size: number;
33
+ estimated_wave_tokens: number;
34
+ cooldown_until: string | null;
35
+ confidence: LimitConfidence;
36
+ source: LimitSource;
37
+ resolved_limits: ResolvedLimits;
38
+ host_concurrency_limit: HostConcurrencyLimit | null;
39
+ model: string | null;
40
+ quota_source_snapshot?: import("./quotaSource.js").QuotaUsageSnapshot | null;
41
+ }
42
+ export interface BackoffState {
43
+ consecutive_429_count: number;
44
+ current_cooldown_ms: number;
45
+ current_failure_weight: number;
46
+ }
47
+ export interface ObservedWaveOutcome {
48
+ concurrency: number;
49
+ estimated_tokens: number;
50
+ outcome: "success" | "rate_limited" | "timeout";
51
+ cooldown_until?: string | null;
52
+ reset_at?: string | null;
53
+ }
54
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/quota/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GACnB,iBAAiB,GACjB,WAAW,GACX,gBAAgB,GAChB,SAAS,GACT,SAAS,CAAC;AAEd,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AAExD,MAAM,MAAM,0BAA0B,GAClC,WAAW,GACX,eAAe,GACf,gBAAgB,GAChB,aAAa,CAAC;AAElB,MAAM,WAAW,oBAAoB;IACnC,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,0BAA0B,CAAC;IACnC,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,uBAAuB,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,wBAAwB,EAAE,MAAM,GAAG,IAAI,CAAC;CACzC;AAED,MAAM,WAAW,iBAAiB;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAC3C,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,UAAU,EAAE,eAAe,CAAC;IAC5B,MAAM,EAAE,WAAW,CAAC;IACpB,eAAe,EAAE,cAAc,CAAC;IAChC,sBAAsB,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACpD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,qBAAqB,CAAC,EAAE,OAAO,kBAAkB,EAAE,kBAAkB,GAAG,IAAI,CAAC;CAC9E;AAED,MAAM,WAAW,YAAY;IAC3B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,sBAAsB,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,SAAS,GAAG,cAAc,GAAG,SAAS,CAAC;IAChD,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/quota/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,6 @@
1
+ export interface AccessDeclaration {
2
+ read_paths: string[];
3
+ write_paths: string[];
4
+ forbidden_patterns?: string[];
5
+ }
6
+ //# sourceMappingURL=accessDeclaration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accessDeclaration.d.ts","sourceRoot":"","sources":["../../src/types/accessDeclaration.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC/B"}