@integrity-labs/agt-cli 0.28.528 → 0.28.529
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/agt.js +4 -4
- package/dist/{chunk-7N55RDMG.js → chunk-MKSL2EQU.js} +38 -3
- package/dist/chunk-MKSL2EQU.js.map +1 -0
- package/dist/{chunk-PR3QSOLI.js → chunk-Q4XGKOHZ.js} +229 -9
- package/dist/chunk-Q4XGKOHZ.js.map +1 -0
- package/dist/{claude-pair-runtime-KQOPJSUJ.js → claude-pair-runtime-TC2TTMIJ.js} +2 -2
- package/dist/lib/manager-worker.js +336 -137
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/mcp/augmented-help-kb.js +21231 -0
- package/dist/mcp/direct-chat-channel.js +99 -7
- package/dist/mcp/origami.js +74 -0
- package/dist/mcp/slack-channel.js +99 -7
- package/dist/mcp/telegram-channel.js +99 -7
- package/dist/{persistent-session-KAHG73SM.js → persistent-session-T4IY7AJU.js} +2 -2
- package/dist/{responsiveness-probe-MKUXLX4F.js → responsiveness-probe-WYGR4B2F.js} +22 -2
- package/dist/{responsiveness-probe-MKUXLX4F.js.map → responsiveness-probe-WYGR4B2F.js.map} +1 -1
- package/package.json +3 -2
- package/dist/chunk-7N55RDMG.js.map +0 -1
- package/dist/chunk-PR3QSOLI.js.map +0 -1
- /package/dist/{claude-pair-runtime-KQOPJSUJ.js.map → claude-pair-runtime-TC2TTMIJ.js.map} +0 -0
- /package/dist/{persistent-session-KAHG73SM.js.map → persistent-session-T4IY7AJU.js.map} +0 -0
|
@@ -5544,6 +5544,12 @@ var HTTP_PROBE_PROVIDERS = /* @__PURE__ */ new Set([
|
|
|
5544
5544
|
// includes 'github') — a narrower, honest "the token we stored is valid"
|
|
5545
5545
|
// check. Unifying the monitor onto the central probe is sub-issue C's call.
|
|
5546
5546
|
]);
|
|
5547
|
+
var BUNDLED_STDIO_PROBE_TOOLKITS = {
|
|
5548
|
+
"augmented-help-kb": {
|
|
5549
|
+
tool: "search_knowledge_base",
|
|
5550
|
+
args: { query: "connectivity probe", limit: 1 }
|
|
5551
|
+
}
|
|
5552
|
+
};
|
|
5547
5553
|
var CLI_PROBE_ARGS = {
|
|
5548
5554
|
gcloud: ["version"],
|
|
5549
5555
|
// ENG-6206: `gh --version` only proves the binary exists, not that it's
|
|
@@ -5600,6 +5606,21 @@ function resolveConnectivityProbe(input) {
|
|
|
5600
5606
|
httpProvider: definitionId
|
|
5601
5607
|
};
|
|
5602
5608
|
}
|
|
5609
|
+
const bundledStdio = BUNDLED_STDIO_PROBE_TOOLKITS[definitionId];
|
|
5610
|
+
if (bundledStdio) {
|
|
5611
|
+
const override = mcpOverrideFrom(input.connectivityTest);
|
|
5612
|
+
const probeTool = override.probeTool ?? bundledStdio.tool;
|
|
5613
|
+
const probeArgs = override.probeTool ? override.probeArgs : bundledStdio.args;
|
|
5614
|
+
return {
|
|
5615
|
+
kind: "mcp_stdio",
|
|
5616
|
+
sourceType: "mcp_server",
|
|
5617
|
+
readOnly: true,
|
|
5618
|
+
label: `${definitionId}: local-stdio MCP handshake + ${probeTool}`,
|
|
5619
|
+
centralReachable: false,
|
|
5620
|
+
probeTool,
|
|
5621
|
+
...probeArgs ? { probeArgs } : {}
|
|
5622
|
+
};
|
|
5623
|
+
}
|
|
5603
5624
|
if (getOAuthProvider(definitionId)?.mcpUrl) {
|
|
5604
5625
|
return {
|
|
5605
5626
|
kind: "mcp_tools_list",
|
|
@@ -6012,6 +6033,22 @@ var SITE_RESOLUTION_ERROR_PATTERNS = [
|
|
|
6012
6033
|
"name resolution",
|
|
6013
6034
|
"name not resolved"
|
|
6014
6035
|
];
|
|
6036
|
+
var SCOPE_DEFICIT_ERROR_PATTERNS = [
|
|
6037
|
+
"insufficient_scope",
|
|
6038
|
+
"insufficient scope",
|
|
6039
|
+
"insufficient permission",
|
|
6040
|
+
"missing scope",
|
|
6041
|
+
"required scope",
|
|
6042
|
+
"requires the scope",
|
|
6043
|
+
"requires the following scope",
|
|
6044
|
+
"scope is required",
|
|
6045
|
+
"access scope",
|
|
6046
|
+
"oauth scope",
|
|
6047
|
+
// Shopify custom-app specifics.
|
|
6048
|
+
"read_content",
|
|
6049
|
+
"write_content",
|
|
6050
|
+
"sales channel is not enabled"
|
|
6051
|
+
];
|
|
6015
6052
|
function isReadonlyToolDescriptor(t) {
|
|
6016
6053
|
if (!t?.name)
|
|
6017
6054
|
return false;
|
|
@@ -6062,9 +6099,17 @@ function isSiteResolutionError(message) {
|
|
|
6062
6099
|
const m = message.toLowerCase();
|
|
6063
6100
|
return SITE_RESOLUTION_ERROR_PATTERNS.some((p2) => m.includes(p2));
|
|
6064
6101
|
}
|
|
6102
|
+
function isScopeDeficitError(message) {
|
|
6103
|
+
const m = message.toLowerCase();
|
|
6104
|
+
if (SCOPE_DEFICIT_ERROR_PATTERNS.some((p2) => m.includes(p2)))
|
|
6105
|
+
return true;
|
|
6106
|
+
return m.includes("scope") && ["doesn't have", "does not have", "not have the", "not granted", "lacks the", "not authorized for"].some((p2) => m.includes(p2));
|
|
6107
|
+
}
|
|
6065
6108
|
function classifyToolCallFailure(text) {
|
|
6066
6109
|
if (isAccountResolutionError(text))
|
|
6067
6110
|
return "account";
|
|
6111
|
+
if (isScopeDeficitError(text))
|
|
6112
|
+
return "scope";
|
|
6068
6113
|
if (isUpstreamAuthError(text))
|
|
6069
6114
|
return "auth";
|
|
6070
6115
|
if (isSiteResolutionError(text))
|
|
@@ -6190,6 +6235,13 @@ async function probeComposioMcpToolCall(config, fetchImpl = fetch) {
|
|
|
6190
6235
|
details: baseDetails
|
|
6191
6236
|
};
|
|
6192
6237
|
}
|
|
6238
|
+
if (kind === "scope") {
|
|
6239
|
+
return {
|
|
6240
|
+
status: "degraded",
|
|
6241
|
+
message: `Live tool call '${toolName}' was refused for a missing permission \u2014 the connection is valid, but its app/token isn't granted the scope this tool needs. Grant the required scope in the provider app and re-authorise (this is NOT a reconnect): ${snippet}`,
|
|
6242
|
+
details: { ...baseDetails, reason: "scope_deficit" }
|
|
6243
|
+
};
|
|
6244
|
+
}
|
|
6193
6245
|
if (kind === "auth") {
|
|
6194
6246
|
return {
|
|
6195
6247
|
status: "down",
|
|
@@ -7389,6 +7441,45 @@ var INTEGRATION_REGISTRY = [
|
|
|
7389
7441
|
{ id: "augmented-support:propose-writes", name: "Propose Self-Remediation", description: "Propose creating an agent in your own org; executed only after a human approves a server-rendered diff.", access: "write" }
|
|
7390
7442
|
]
|
|
7391
7443
|
},
|
|
7444
|
+
{
|
|
7445
|
+
// ENG-8332: the Augmented Team HELP knowledge base, split out of
|
|
7446
|
+
// `augmented-support` so an agent can be given the docs WITHOUT also being
|
|
7447
|
+
// given a ticket-filing button, an agent-proposal button, and org-wide read
|
|
7448
|
+
// of agents, hosts, integrations, alerts, flags and the audit log. That
|
|
7449
|
+
// bundling was why "just give everyone augmented-support" was the wrong
|
|
7450
|
+
// answer, and the cost was agents answering platform questions from
|
|
7451
|
+
// inference instead of documentation (the CS-1529/CS-1530 case).
|
|
7452
|
+
//
|
|
7453
|
+
// Provisions the @integrity-labs/augmented-help-kb-mcp stdio broker, a
|
|
7454
|
+
// read-only client over /host/kb - the single enumerated carve-out from the
|
|
7455
|
+
// ADR-0032 org-lock invariant (ENG-7119). KB content is platform-curated
|
|
7456
|
+
// and org-neutral, so this grants NO view of any org's state; the client
|
|
7457
|
+
// has no POST transport at all, so writes are structurally impossible
|
|
7458
|
+
// rather than merely unregistered.
|
|
7459
|
+
//
|
|
7460
|
+
// auth `none` - no end-user OAuth, the host JWT is the credential. `beta`
|
|
7461
|
+
// while distribution widens. NOT in the Add Integration picker (no
|
|
7462
|
+
// `installable`): granted deliberately, like its two siblings.
|
|
7463
|
+
//
|
|
7464
|
+
// NAMING (ENG-7281): this is the "help knowledge base" - shared, published,
|
|
7465
|
+
// org-neutral PRODUCT help. It is NOT the org knowledge store that
|
|
7466
|
+
// `knowledge_search` / `context_search` read. Keep the two distinct in every
|
|
7467
|
+
// surface that names them.
|
|
7468
|
+
id: "augmented-help-kb",
|
|
7469
|
+
name: "Augmented Help KB",
|
|
7470
|
+
category: "knowledge",
|
|
7471
|
+
description: "The Augmented Team help knowledge base: search and read the shared, published product documentation (how-tos, common fixes, FAQs). Identical for every organization and org-neutral by design - it grants no view of your org's own state, and cannot file tickets or propose changes. Distinct from your organization's own knowledge store.",
|
|
7472
|
+
supported_auth_types: ["none"],
|
|
7473
|
+
beta: true,
|
|
7474
|
+
capabilities: [
|
|
7475
|
+
{
|
|
7476
|
+
id: "augmented-help-kb:read",
|
|
7477
|
+
name: "Read Help Docs",
|
|
7478
|
+
description: "Search and read published Augmented Team help articles (org-neutral product documentation). Read-only; no ticket filing, no agent proposals, no org-state reads.",
|
|
7479
|
+
access: "read"
|
|
7480
|
+
}
|
|
7481
|
+
]
|
|
7482
|
+
},
|
|
7392
7483
|
{
|
|
7393
7484
|
id: "firecrawl",
|
|
7394
7485
|
name: "Firecrawl",
|
|
@@ -9321,13 +9412,104 @@ function encodeClaudeProjectPath(projectDir) {
|
|
|
9321
9412
|
return "-" + projectDir.replace(/^\//, "").replace(/[/.]/g, "-");
|
|
9322
9413
|
}
|
|
9323
9414
|
|
|
9415
|
+
// ../../packages/core/dist/claude-code-usage/occupancy-qualification.js
|
|
9416
|
+
var DEFAULT_MIN_OUTPUT_TOKENS = 25;
|
|
9417
|
+
var DEFAULT_NEIGHBOURHOOD_MS = 12e4;
|
|
9418
|
+
var BUCKET_MS = 6e4;
|
|
9419
|
+
function isSyntheticOrErrorRecord(record, msg) {
|
|
9420
|
+
if (msg.model === "<synthetic>")
|
|
9421
|
+
return true;
|
|
9422
|
+
if (record.isApiErrorMessage === true)
|
|
9423
|
+
return true;
|
|
9424
|
+
if (typeof record.error === "string" && record.error)
|
|
9425
|
+
return true;
|
|
9426
|
+
if (typeof record.apiErrorStatus === "number")
|
|
9427
|
+
return true;
|
|
9428
|
+
return false;
|
|
9429
|
+
}
|
|
9430
|
+
function resolveFloor(value) {
|
|
9431
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
|
|
9432
|
+
return DEFAULT_MIN_OUTPUT_TOKENS;
|
|
9433
|
+
}
|
|
9434
|
+
return value;
|
|
9435
|
+
}
|
|
9436
|
+
function nonNegInt2(value) {
|
|
9437
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.floor(value) : 0;
|
|
9438
|
+
}
|
|
9439
|
+
function extractQualifyingTurns(jsonl, options = {}) {
|
|
9440
|
+
const floor = resolveFloor(options.minOutputTokens);
|
|
9441
|
+
const startMs = options.startMs ?? Number.NEGATIVE_INFINITY;
|
|
9442
|
+
const endMs = options.endMs ?? Number.POSITIVE_INFINITY;
|
|
9443
|
+
const byId = /* @__PURE__ */ new Map();
|
|
9444
|
+
let syntheticCounter = 0;
|
|
9445
|
+
for (const line2 of jsonl.split("\n")) {
|
|
9446
|
+
const trimmed = line2.trim();
|
|
9447
|
+
if (!trimmed)
|
|
9448
|
+
continue;
|
|
9449
|
+
let obj;
|
|
9450
|
+
try {
|
|
9451
|
+
obj = JSON.parse(trimmed);
|
|
9452
|
+
} catch {
|
|
9453
|
+
continue;
|
|
9454
|
+
}
|
|
9455
|
+
if (typeof obj !== "object" || obj === null)
|
|
9456
|
+
continue;
|
|
9457
|
+
const record = obj;
|
|
9458
|
+
if (record.type !== "assistant")
|
|
9459
|
+
continue;
|
|
9460
|
+
const message = record.message;
|
|
9461
|
+
if (typeof message !== "object" || message === null)
|
|
9462
|
+
continue;
|
|
9463
|
+
const msg = message;
|
|
9464
|
+
if (isSyntheticOrErrorRecord(record, msg))
|
|
9465
|
+
continue;
|
|
9466
|
+
const usage = msg.usage;
|
|
9467
|
+
if (typeof usage !== "object" || usage === null)
|
|
9468
|
+
continue;
|
|
9469
|
+
const ts = record.timestamp;
|
|
9470
|
+
if (typeof ts !== "string" || !ts)
|
|
9471
|
+
continue;
|
|
9472
|
+
const tsMs = new Date(ts).getTime();
|
|
9473
|
+
if (!Number.isFinite(tsMs))
|
|
9474
|
+
continue;
|
|
9475
|
+
const id = typeof msg.id === "string" && msg.id ? msg.id : `__noid_${syntheticCounter++}`;
|
|
9476
|
+
byId.set(id, {
|
|
9477
|
+
tsMs,
|
|
9478
|
+
outputTokens: nonNegInt2(usage.output_tokens)
|
|
9479
|
+
});
|
|
9480
|
+
}
|
|
9481
|
+
const out = [];
|
|
9482
|
+
for (const entry of byId.values()) {
|
|
9483
|
+
if (entry.outputTokens < floor)
|
|
9484
|
+
continue;
|
|
9485
|
+
if (entry.tsMs < startMs || entry.tsMs > endMs)
|
|
9486
|
+
continue;
|
|
9487
|
+
out.push(entry.tsMs);
|
|
9488
|
+
}
|
|
9489
|
+
out.sort((a, b) => a - b);
|
|
9490
|
+
return out;
|
|
9491
|
+
}
|
|
9492
|
+
function isBucketQualified(bucketStartMs2, turnTimes, neighbourhoodMs = DEFAULT_NEIGHBOURHOOD_MS) {
|
|
9493
|
+
const from = bucketStartMs2 - neighbourhoodMs;
|
|
9494
|
+
const to = bucketStartMs2 + BUCKET_MS + neighbourhoodMs;
|
|
9495
|
+
for (const t of turnTimes) {
|
|
9496
|
+
if (t > to)
|
|
9497
|
+
return false;
|
|
9498
|
+
if (t >= from)
|
|
9499
|
+
return true;
|
|
9500
|
+
}
|
|
9501
|
+
return false;
|
|
9502
|
+
}
|
|
9503
|
+
|
|
9324
9504
|
// ../../packages/core/dist/account-enforcement/marker.js
|
|
9325
9505
|
var ACCOUNT_ENFORCEMENT_MARKER_FILENAME = "account-enforcement.json";
|
|
9326
9506
|
var ACCOUNT_ENFORCEMENT_MARKER_VERSION = 1;
|
|
9327
|
-
function serializeAccountEnforcementMarker(level) {
|
|
9507
|
+
function serializeAccountEnforcementMarker(level, text) {
|
|
9508
|
+
const trimmed = typeof text === "string" ? text.trim() : "";
|
|
9328
9509
|
const marker = {
|
|
9329
9510
|
version: ACCOUNT_ENFORCEMENT_MARKER_VERSION,
|
|
9330
|
-
level
|
|
9511
|
+
level,
|
|
9512
|
+
...trimmed ? { text: trimmed } : {}
|
|
9331
9513
|
};
|
|
9332
9514
|
return JSON.stringify(marker);
|
|
9333
9515
|
}
|
|
@@ -10495,6 +10677,32 @@ var FLAG_REGISTRY = [
|
|
|
10495
10677
|
// Best-effort reach estimate only; not part of the schema fingerprint.
|
|
10496
10678
|
since: "0.28.504"
|
|
10497
10679
|
},
|
|
10680
|
+
{
|
|
10681
|
+
key: "utilization-occupancy-qualifier",
|
|
10682
|
+
description: "Utilization busy-minutes gate (ENG-8465): shadow = report every measured bucket exactly as before while COUNTING how many a transcript qualifier would drop; enforce = drop measured buckets that have no qualifying assistant turn (>= 25 output tokens, non-synthetic) within \xB1120s. The qualifier is the merged @augmented/core primitive (extractQualifyingTurns / isBucketQualified); the host reads a bounded transcript tail incl. <sessionId>/subagents/ at drain time and FAILS OPEN (credits ungated) when a transcript cannot be read. Read host-side via hostFlagStore (getString) in the manager; consumer ships in this PR's agt-cli auto-publish bump. Both modes emit the OccupancyQualificationClassifications shadow metric (qualified positive-control + unqualified_dropped signal + unreadable), so per-agent impact is measured before the flip.",
|
|
10683
|
+
flagType: "enum",
|
|
10684
|
+
allowedValues: ["shadow", "enforce"],
|
|
10685
|
+
// Declared safe value is `shadow`: it reproduces pre-flag billing exactly, so
|
|
10686
|
+
// rollout changes no agent's minutes while the shadow metric accrues the
|
|
10687
|
+
// enforce-flip evidence. `enforce` lowers a billing-adjacent number, so it is a
|
|
10688
|
+
// deliberate, audited flip — never a flag-DB-read-error default.
|
|
10689
|
+
defaultValue: "shadow",
|
|
10690
|
+
// Operator per-host override (ADR-0022 highest precedence). No _ENABLED/_DISABLED/
|
|
10691
|
+
// _MODE suffix, and read via hostFlagStore not a raw process.env gate, so not a
|
|
10692
|
+
// new env gate under ENG-6252. Never pinned in sst.config.ts (ENG-8303).
|
|
10693
|
+
envVar: "AGT_UTILIZATION_OCCUPANCY_QUALIFIER",
|
|
10694
|
+
// enforce lowers a billing-adjacent number, so flipping/weakening it is guarded
|
|
10695
|
+
// like the other enforcement-mode flags.
|
|
10696
|
+
sensitive: true,
|
|
10697
|
+
// Reach threshold (ENG-8465): the host reader (occupancyQualifierMode in
|
|
10698
|
+
// manager-worker.ts) lands in this PR's agt-cli auto-publish patch bump, which
|
|
10699
|
+
// is the first published version to contain it (through 0.28.528 does not). An
|
|
10700
|
+
// UNSET `since` makes classifyHostReach report `honors` (full coverage), which
|
|
10701
|
+
// would greenlight an `enforce` flip while older hosts silently stay `shadow`.
|
|
10702
|
+
// Best-effort estimate (like docker-hygiene's), in the safe direction — a
|
|
10703
|
+
// not-yet-published version reports 0% honor until hosts update. (CodeRabbit)
|
|
10704
|
+
since: "0.28.529"
|
|
10705
|
+
},
|
|
10498
10706
|
{
|
|
10499
10707
|
key: "composio-hitl-mode",
|
|
10500
10708
|
description: "Composio managed-toolkits HITL gate (ENG-6027): off = kill switch, shadow = resolve + audit the tier decision but never block, enforce = block write_high_risk+ calls and route them to Human Approval (an Approve/Deny card). Since ENG-7828 enforce ALWAYS routes to a Human Approval card by default; set hitl-approval-routing=off to make enforce a hard block with no approval instead. Per-org rollout from the admin Feature Flags page; ENG-7672 migrated this off the fleet-wide COMPOSIO_HITL_MODE env var.",
|
|
@@ -10901,6 +11109,15 @@ var FLAG_REGISTRY = [
|
|
|
10901
11109
|
// runbook gates on it. Leaving the placeholder in place is safe (nothing
|
|
10902
11110
|
// flips); shipping a guessed number is not.
|
|
10903
11111
|
since: "0.29.0"
|
|
11112
|
+
},
|
|
11113
|
+
{
|
|
11114
|
+
key: "help-kb-auto-grant",
|
|
11115
|
+
description: "Auto-grant the `augmented-help-kb` integration at ORG scope when an organization is provisioned (ENG-8542), so every agent in that org gets product-doc search without a per-agent operator action. One organization_integrations row reaches every agent in the org: POST /host/agent-integrations merges org -> team -> agent and buildMcpJson's predicate reads that merged set with no scope filter. ON: the two org-provisioning call sites write the row (status=active, created_by=the org owner). OFF (default): they write nothing - byte-for-byte today's behaviour. STAGED ROLLOUT IS THE POINT. ENG-8332 argues against widening distribution of the help KB until two things close, because distributing a corpus with wrong articles \"converts one agent's wrong answer into everyone's\": (1) a live 200 from GET /host/kb/search as the anon role has still never been observed - ENG-7260 was closed on remediation evidence, not on a live call, and the deploy seed log is SERVICE-ROLE evidence that says nothing about the anon grant; (2) the `site-structure` article is unverified against the current IA. Turning this on for ONE org and watching that org's help-kb connectivity-probe verdicts (ENG-8332 added a real mcp_stdio probe that calls search_knowledge_base) is the cheap positive control for (1) - an ENG-7260-class 500 then reports as `down` per agent instead of as silence. Widen only after it comes back healthy. REVOKING IS DELETING THE ROW, not flipping this off: the flag gates GRANTING, so an already-granted org keeps its row when the flag goes off. Evaluated API-side only, per org, inside grantHelpKbToOrg; no host-side envVar and deliberately no sst.config.ts entry (a literal default there would pin it - ENG-8303).",
|
|
11116
|
+
flagType: "boolean",
|
|
11117
|
+
// Declared safe value is `false` = grant nothing. A flag-store outage must
|
|
11118
|
+
// never auto-attach an integration nobody asked for, and both ENG-8332
|
|
11119
|
+
// prerequisites above are still open.
|
|
11120
|
+
defaultValue: false
|
|
10904
11121
|
}
|
|
10905
11122
|
];
|
|
10906
11123
|
var REGISTRY_BY_KEY = new Map(FLAG_REGISTRY.map((definition) => [definition.key, definition]));
|
|
@@ -12720,13 +12937,13 @@ var TurnOutcomeTracker = class {
|
|
|
12720
12937
|
};
|
|
12721
12938
|
|
|
12722
12939
|
// src/lib/busy-bucket-ledger.ts
|
|
12723
|
-
var
|
|
12940
|
+
var BUCKET_MS2 = 6e4;
|
|
12724
12941
|
var MAX_ACCRUAL_SPAN_MS = 10 * 6e4;
|
|
12725
12942
|
var MAX_RETAINED_BUCKETS = 240;
|
|
12726
12943
|
var BILL_WHOLE_MINUTES = true;
|
|
12727
12944
|
var MIN_BILLABLE_MS = 100;
|
|
12728
12945
|
function bucketStartMs(atMs) {
|
|
12729
|
-
return Math.floor(atMs /
|
|
12946
|
+
return Math.floor(atMs / BUCKET_MS2) * BUCKET_MS2;
|
|
12730
12947
|
}
|
|
12731
12948
|
var BusyBucketLedger = class {
|
|
12732
12949
|
state = /* @__PURE__ */ new Map();
|
|
@@ -12748,11 +12965,11 @@ var BusyBucketLedger = class {
|
|
|
12748
12965
|
if (toMs <= fromMs) return;
|
|
12749
12966
|
const start = Math.max(fromMs, toMs - MAX_ACCRUAL_SPAN_MS);
|
|
12750
12967
|
const led = this.entry(codeName);
|
|
12751
|
-
for (let b = bucketStartMs(start); b < toMs; b +=
|
|
12752
|
-
const overlap = Math.min(toMs, b +
|
|
12968
|
+
for (let b = bucketStartMs(start); b < toMs; b += BUCKET_MS2) {
|
|
12969
|
+
const overlap = Math.min(toMs, b + BUCKET_MS2) - Math.max(start, b);
|
|
12753
12970
|
if (overlap <= 0) continue;
|
|
12754
12971
|
const prev = led.buckets.get(b) ?? 0;
|
|
12755
|
-
led.buckets.set(b, Math.min(
|
|
12972
|
+
led.buckets.set(b, Math.min(BUCKET_MS2, prev + overlap));
|
|
12756
12973
|
}
|
|
12757
12974
|
this.evict(led);
|
|
12758
12975
|
}
|
|
@@ -12820,7 +13037,7 @@ var BusyBucketLedger = class {
|
|
|
12820
13037
|
if (!Number.isFinite(at)) continue;
|
|
12821
13038
|
const key = bucketStartMs(at);
|
|
12822
13039
|
const prev = led.buckets.get(key) ?? 0;
|
|
12823
|
-
led.buckets.set(key, Math.min(
|
|
13040
|
+
led.buckets.set(key, Math.min(BUCKET_MS2, prev + b.seconds * 1e3));
|
|
12824
13041
|
}
|
|
12825
13042
|
this.evict(led);
|
|
12826
13043
|
}
|
|
@@ -15320,6 +15537,9 @@ export {
|
|
|
15320
15537
|
UNKNOWN_RATE_LIMIT,
|
|
15321
15538
|
pickNewerClassification,
|
|
15322
15539
|
classifyTranscriptRateLimit,
|
|
15540
|
+
DEFAULT_NEIGHBOURHOOD_MS,
|
|
15541
|
+
extractQualifyingTurns,
|
|
15542
|
+
isBucketQualified,
|
|
15323
15543
|
ACCOUNT_ENFORCEMENT_MARKER_FILENAME,
|
|
15324
15544
|
serializeAccountEnforcementMarker,
|
|
15325
15545
|
KANBAN_CHECK_COMMAND,
|
|
@@ -15411,4 +15631,4 @@ export {
|
|
|
15411
15631
|
stopAllSessionsAndWait,
|
|
15412
15632
|
getProjectDir
|
|
15413
15633
|
};
|
|
15414
|
-
//# sourceMappingURL=chunk-
|
|
15634
|
+
//# sourceMappingURL=chunk-Q4XGKOHZ.js.map
|