@aspectlylabs/mikka 0.0.143 → 0.0.145
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/cli.js +109 -9
- package/client.js +10 -3
- package/fixtures/quota-exhausted.jsonl +5 -0
- package/http-link.js +10 -3
- package/login.js +10 -3
- package/main.js +109 -9
- package/mikka-release-manifest.json +24 -19
- package/mikka.js +109 -9
- package/npm-shrinkwrap.json +2 -2
- package/package.json +2 -2
- package/paths.js +2 -2
- package/sbom.cdx.json +7 -7
package/cli.js
CHANGED
|
@@ -3002,7 +3002,9 @@ var RUN_STOP_REASONS = [
|
|
|
3002
3002
|
"cancelled",
|
|
3003
3003
|
"error",
|
|
3004
3004
|
"timeout",
|
|
3005
|
-
"device_lost"
|
|
3005
|
+
"device_lost",
|
|
3006
|
+
/** The subscription's quota or rate limit ran out mid-run (see `resetsAt`). */
|
|
3007
|
+
"quota_exhausted"
|
|
3006
3008
|
];
|
|
3007
3009
|
var runStopReason = z9.enum(RUN_STOP_REASONS);
|
|
3008
3010
|
var shortList = z9.array(z9.string().max(1e3)).max(5e3);
|
|
@@ -3077,6 +3079,11 @@ var runReport = z9.object({
|
|
|
3077
3079
|
nextStep: z9.string().max(2e3).nullable(),
|
|
3078
3080
|
/** For `blocked`: the external condition, e.g. `quota_exhausted`. */
|
|
3079
3081
|
blockedOn: z9.string().max(500).optional(),
|
|
3082
|
+
/**
|
|
3083
|
+
* For `quota_exhausted`: when the subscription's quota resets, as the CLI
|
|
3084
|
+
* reported it; null when it gave no time. Set by the daemon only.
|
|
3085
|
+
*/
|
|
3086
|
+
resetsAt: z9.iso.datetime({ offset: true }).nullable().optional(),
|
|
3080
3087
|
/** Daemon-owned receipt for an exact, unchanged read-only candidate. */
|
|
3081
3088
|
check: z9.object({
|
|
3082
3089
|
sha: z9.string().regex(/^[a-f0-9]{40}$/),
|
|
@@ -4473,7 +4480,7 @@ import { join as join4 } from "node:path";
|
|
|
4473
4480
|
// package.json
|
|
4474
4481
|
var package_default = {
|
|
4475
4482
|
name: "@mikka/daemon",
|
|
4476
|
-
version: "0.0.
|
|
4483
|
+
version: "0.0.145",
|
|
4477
4484
|
description: "Local Mikka daemon: runs agents through the user's own CLIs",
|
|
4478
4485
|
type: "module",
|
|
4479
4486
|
private: true,
|
|
@@ -4533,7 +4540,7 @@ var package_default = {
|
|
|
4533
4540
|
engines: {
|
|
4534
4541
|
node: ">=24"
|
|
4535
4542
|
},
|
|
4536
|
-
gitHead: "
|
|
4543
|
+
gitHead: "f4c4f818ea1d78fd81b298bda2a9249c50ba6f96"
|
|
4537
4544
|
};
|
|
4538
4545
|
|
|
4539
4546
|
// src/paths.ts
|
|
@@ -7686,6 +7693,83 @@ import { arch as arch2, hostname, platform as platform3 } from "node:os";
|
|
|
7686
7693
|
import { join as join32 } from "node:path";
|
|
7687
7694
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
7688
7695
|
|
|
7696
|
+
// src/runs/quota-exhausted.ts
|
|
7697
|
+
var QUOTA_TEXT = /usage limit|hit your (?:usage )?limit|limit reached|rate limit|quota|too many requests|\b429\b/i;
|
|
7698
|
+
var fromEpochSeconds = (value) => typeof value === "number" && Number.isFinite(value) && value > 0 ? new Date(value * 1e3).toISOString() : null;
|
|
7699
|
+
function mergeQuota(previous, next) {
|
|
7700
|
+
if (!next) return previous;
|
|
7701
|
+
return previous?.resetsAt && !next.resetsAt ? previous : next;
|
|
7702
|
+
}
|
|
7703
|
+
function claudeResetFromText(text3) {
|
|
7704
|
+
const match = /\|\s*(\d{10})\b/.exec(text3);
|
|
7705
|
+
return match ? fromEpochSeconds(Number(match[1])) : null;
|
|
7706
|
+
}
|
|
7707
|
+
function textOf(content) {
|
|
7708
|
+
if (typeof content === "string") return content;
|
|
7709
|
+
if (!Array.isArray(content)) return "";
|
|
7710
|
+
return content.map((block) => block && typeof block === "object" && block.type === "text" ? String(block.text ?? "") : "").join("\n");
|
|
7711
|
+
}
|
|
7712
|
+
function claudeQuotaSignal(message) {
|
|
7713
|
+
if (!message || typeof message !== "object") return null;
|
|
7714
|
+
const value = message;
|
|
7715
|
+
if (value.type === "rate_limit_event") {
|
|
7716
|
+
const info = value.rate_limit_info;
|
|
7717
|
+
if (info?.status !== "rejected") return null;
|
|
7718
|
+
return { resetsAt: fromEpochSeconds(info.resetsAt) ?? fromEpochSeconds(info.overageResetsAt) };
|
|
7719
|
+
}
|
|
7720
|
+
if (value.type === "assistant" && value.error === "rate_limit") {
|
|
7721
|
+
const text3 = textOf(value.message?.content);
|
|
7722
|
+
return { resetsAt: claudeResetFromText(text3) };
|
|
7723
|
+
}
|
|
7724
|
+
if (value.type === "result" && value.is_error === true) {
|
|
7725
|
+
const text3 = [typeof value.result === "string" ? value.result : "", ...Array.isArray(value.errors) ? value.errors.map(String) : []].join("\n");
|
|
7726
|
+
if (!/usage limit|hit your (?:usage )?limit|limit reached/i.test(text3)) return null;
|
|
7727
|
+
return { resetsAt: claudeResetFromText(text3) };
|
|
7728
|
+
}
|
|
7729
|
+
return null;
|
|
7730
|
+
}
|
|
7731
|
+
var UNIT_MS = { day: 864e5, hour: 36e5, minute: 6e4, second: 1e3 };
|
|
7732
|
+
function codexResetFromText(text3, now) {
|
|
7733
|
+
const within = /try again in ([^.]+)/i.exec(text3);
|
|
7734
|
+
if (within) {
|
|
7735
|
+
let total = 0;
|
|
7736
|
+
for (const part of within[1].matchAll(/(\d+)\s*(day|hour|minute|second)s?/gi)) total += Number(part[1]) * UNIT_MS[part[2].toLowerCase()];
|
|
7737
|
+
return total > 0 ? new Date(now + total).toISOString() : null;
|
|
7738
|
+
}
|
|
7739
|
+
const at = /try again at ([^.]+)/i.exec(text3)?.[1]?.trim();
|
|
7740
|
+
if (!at) return null;
|
|
7741
|
+
const clock = /^(\d{1,2}):(\d{2})\s*(AM|PM)?$/i.exec(at);
|
|
7742
|
+
if (clock) {
|
|
7743
|
+
let hours = Number(clock[1]) % (clock[3] ? 12 : 24);
|
|
7744
|
+
if (clock[3]?.toUpperCase() === "PM") hours += 12;
|
|
7745
|
+
const day = new Date(now);
|
|
7746
|
+
day.setHours(hours, Number(clock[2]), 0, 0);
|
|
7747
|
+
if (day.getTime() <= now) day.setDate(day.getDate() + 1);
|
|
7748
|
+
return day.toISOString();
|
|
7749
|
+
}
|
|
7750
|
+
const parsed = Date.parse(at.replace(/(\d)(st|nd|rd|th)\b/gi, "$1"));
|
|
7751
|
+
return Number.isFinite(parsed) ? new Date(parsed).toISOString() : null;
|
|
7752
|
+
}
|
|
7753
|
+
function codexInfoIsQuota(info) {
|
|
7754
|
+
if (info === "usageLimitExceeded") return true;
|
|
7755
|
+
if (!info || typeof info !== "object") return false;
|
|
7756
|
+
return Object.values(info).some((detail) => Boolean(detail && typeof detail === "object" && detail.httpStatusCode === 429));
|
|
7757
|
+
}
|
|
7758
|
+
function codexResetFromLimits(limits) {
|
|
7759
|
+
const full = [limits?.primary, limits?.secondary].filter((window) => window && (window.usedPercent ?? 0) >= 100);
|
|
7760
|
+
const resets = full.map((window) => fromEpochSeconds(window?.resetsAt)).filter((value) => Boolean(value));
|
|
7761
|
+
return resets.sort().at(-1) ?? null;
|
|
7762
|
+
}
|
|
7763
|
+
function codexQuotaSignal(error, limits, now = Date.now()) {
|
|
7764
|
+
if (!error) return null;
|
|
7765
|
+
const message = typeof error.message === "string" ? error.message : "";
|
|
7766
|
+
if (!codexInfoIsQuota(error.codexErrorInfo) && !QUOTA_TEXT.test(message)) return null;
|
|
7767
|
+
return { resetsAt: codexResetFromText(message, now) ?? codexResetFromLimits(limits) };
|
|
7768
|
+
}
|
|
7769
|
+
function quotaStopApplies(assignment) {
|
|
7770
|
+
return !assignment.modelCredential;
|
|
7771
|
+
}
|
|
7772
|
+
|
|
7689
7773
|
// src/adapters/claude.ts
|
|
7690
7774
|
import { spawn as spawn3 } from "node:child_process";
|
|
7691
7775
|
|
|
@@ -8435,6 +8519,7 @@ var ClaudeAdapter = class {
|
|
|
8435
8519
|
let runtimeModel = null;
|
|
8436
8520
|
let ending = false;
|
|
8437
8521
|
let lastError;
|
|
8522
|
+
let quota;
|
|
8438
8523
|
let graceTimer;
|
|
8439
8524
|
let authTimer;
|
|
8440
8525
|
let stderr = "";
|
|
@@ -8551,7 +8636,7 @@ var ClaudeAdapter = class {
|
|
|
8551
8636
|
const handoff = ctx.readHandoff(log);
|
|
8552
8637
|
if (handoff) return void end(handoff);
|
|
8553
8638
|
void end(
|
|
8554
|
-
lastError ? { outcome: "failed", error: lastError } : { outcome: "succeeded" }
|
|
8639
|
+
lastError ? { outcome: "failed", error: lastError, ...quota ? { quota } : {} } : { outcome: "succeeded" }
|
|
8555
8640
|
);
|
|
8556
8641
|
};
|
|
8557
8642
|
const diedEarly = (error) => {
|
|
@@ -8560,7 +8645,8 @@ var ClaudeAdapter = class {
|
|
|
8560
8645
|
queue.exit(
|
|
8561
8646
|
handoff ?? {
|
|
8562
8647
|
outcome: "failed",
|
|
8563
|
-
error: externalAuth ? SUBSCRIPTION_EXECUTION_ERROR : `claude exited before the turn ended: ${error}
|
|
8648
|
+
error: externalAuth ? SUBSCRIPTION_EXECUTION_ERROR : `claude exited before the turn ended: ${error}`,
|
|
8649
|
+
...quota ? { quota } : {}
|
|
8564
8650
|
}
|
|
8565
8651
|
);
|
|
8566
8652
|
};
|
|
@@ -8579,11 +8665,13 @@ var ClaudeAdapter = class {
|
|
|
8579
8665
|
if (message.type === "assistant" || message.type === "user")
|
|
8580
8666
|
clearTimeout(graceTimer);
|
|
8581
8667
|
if (ending) continue;
|
|
8668
|
+
quota = mergeQuota(quota, claudeQuotaSignal(message));
|
|
8582
8669
|
if (message.type === "tool_progress" && message.session_id === sessionId) queue.progress();
|
|
8583
8670
|
if (!(externalAuth && message.type === "assistant" && message.error))
|
|
8584
8671
|
for (const chunk of claudeChunks(message)) queue.chunk(chunk);
|
|
8585
8672
|
if (message.type !== "result") continue;
|
|
8586
8673
|
results++;
|
|
8674
|
+
if (!message.is_error) quota = void 0;
|
|
8587
8675
|
lastError = message.is_error ? externalAuth ? SUBSCRIPTION_EXECUTION_ERROR : `Claude Code: ${resultError(message)}` : void 0;
|
|
8588
8676
|
if (results >= written) {
|
|
8589
8677
|
turnEnded();
|
|
@@ -8979,6 +9067,8 @@ var CodexAdapter = class {
|
|
|
8979
9067
|
let ending = false;
|
|
8980
9068
|
let cancelling = false;
|
|
8981
9069
|
let lastError;
|
|
9070
|
+
let quota;
|
|
9071
|
+
let rateLimits;
|
|
8982
9072
|
let usage = { inputTokens: 0, outputTokens: 0 };
|
|
8983
9073
|
const pendingMcp = /* @__PURE__ */ new Map();
|
|
8984
9074
|
const registeredMcpTool = (server, tool2) => server === MCP_SERVER_NAME && ["submit", "request_help", "ask_human", "report_blocked"].includes(tool2) || Boolean(computerMcp) && server === COMPUTER_MCP_SERVER_NAME && ["get_desktop_state", "click", "type_text", "press_key", "scroll"].includes(tool2) || Boolean(options.apps?.apps.some((app) => app.name === server));
|
|
@@ -9110,8 +9200,12 @@ var CodexAdapter = class {
|
|
|
9110
9200
|
};
|
|
9111
9201
|
return;
|
|
9112
9202
|
}
|
|
9203
|
+
case "account/rateLimits/updated":
|
|
9204
|
+
rateLimits = params.rateLimits;
|
|
9205
|
+
return;
|
|
9113
9206
|
case "error": {
|
|
9114
9207
|
const { error, willRetry } = params;
|
|
9208
|
+
if (!willRetry) quota = mergeQuota(quota, codexQuotaSignal(error, rateLimits));
|
|
9115
9209
|
if (!willRetry)
|
|
9116
9210
|
lastError = externalAuth ? SUBSCRIPTION_EXECUTION_ERROR2 : `Codex: ${error.message}`;
|
|
9117
9211
|
return;
|
|
@@ -9162,8 +9256,10 @@ var CodexAdapter = class {
|
|
|
9162
9256
|
return;
|
|
9163
9257
|
}
|
|
9164
9258
|
if (turn.status === "failed" || lastError) {
|
|
9259
|
+
quota = mergeQuota(quota, codexQuotaSignal(turn.error, rateLimits));
|
|
9165
9260
|
return finish({
|
|
9166
9261
|
outcome: "failed",
|
|
9262
|
+
...quota ? { quota } : {},
|
|
9167
9263
|
error: externalAuth ? SUBSCRIPTION_EXECUTION_ERROR2 : turn.error?.message ? `Codex: ${turn.error.message}` : lastError
|
|
9168
9264
|
});
|
|
9169
9265
|
}
|
|
@@ -9173,6 +9269,7 @@ var CodexAdapter = class {
|
|
|
9173
9269
|
let runtimeModel = null;
|
|
9174
9270
|
const startTurn = async (message) => {
|
|
9175
9271
|
lastError = void 0;
|
|
9272
|
+
quota = void 0;
|
|
9176
9273
|
if (externalAuth?.verify) {
|
|
9177
9274
|
try {
|
|
9178
9275
|
await externalAuth.verify();
|
|
@@ -11836,6 +11933,8 @@ var MemoryServer = class {
|
|
|
11836
11933
|
return retry("retry", MAX_CRASH_RETRIES);
|
|
11837
11934
|
case "device_lost":
|
|
11838
11935
|
return { owner: "external", reason: "device_offline" };
|
|
11936
|
+
case "quota_exhausted":
|
|
11937
|
+
return { owner: "external", reason: "quota_exhausted" };
|
|
11839
11938
|
case "cancelled":
|
|
11840
11939
|
return { owner: "human", reason: "cancelled" };
|
|
11841
11940
|
}
|
|
@@ -13102,7 +13201,7 @@ var RunSupervisor = class {
|
|
|
13102
13201
|
continue;
|
|
13103
13202
|
}
|
|
13104
13203
|
await this.closeMailbox(run3);
|
|
13105
|
-
const stopReason = stopReasonOf(event, run3);
|
|
13204
|
+
const stopReason = stopReasonOf(event, run3, assignment);
|
|
13106
13205
|
const error = event.error ?? (stopReason === "turn_ended" ? "Session ended without a submission" : stopReason === "timeout" ? "No progress before the watchdog limit" : stopReason === "device_lost" ? "Run lease expired; the server could not be reached" : void 0);
|
|
13107
13206
|
if (assignment.benchmark) {
|
|
13108
13207
|
const fixed = await fixedCheckSnapshot(repo.path, worktree, assignment.benchmark.sourceCommit);
|
|
@@ -13120,7 +13219,7 @@ var RunSupervisor = class {
|
|
|
13120
13219
|
);
|
|
13121
13220
|
if (this.stopping) return;
|
|
13122
13221
|
const { verifyError, tree } = outcome;
|
|
13123
|
-
let report = outcome.report;
|
|
13222
|
+
let report = stopReason === "quota_exhausted" ? { ...outcome.report, resetsAt: event.quota?.resetsAt ?? null } : outcome.report;
|
|
13124
13223
|
const policy = runPolicy(assignment.policy);
|
|
13125
13224
|
if (stopReason === "submitted" && report.verify.status !== "failed" && tree && // The draft-PR exception requires an explicit repository push
|
|
13126
13225
|
// approval. It must not even create a local commit without it.
|
|
@@ -13223,11 +13322,12 @@ function pickAgentReport(agent) {
|
|
|
13223
13322
|
}
|
|
13224
13323
|
return picked;
|
|
13225
13324
|
}
|
|
13226
|
-
var KEEP_WORKTREE = ["turn_ended", "asked_human"];
|
|
13227
|
-
function stopReasonOf(event, run3) {
|
|
13325
|
+
var KEEP_WORKTREE = ["turn_ended", "asked_human", "quota_exhausted"];
|
|
13326
|
+
function stopReasonOf(event, run3, assignment) {
|
|
13228
13327
|
if (run3.forcedStop) return run3.forcedStop;
|
|
13229
13328
|
if (event.outcome === "cancelled" || run3.cancelRequested) return "cancelled";
|
|
13230
13329
|
if (event.stopReason) return event.stopReason;
|
|
13330
|
+
if (event.outcome === "failed" && event.quota && quotaStopApplies(assignment)) return "quota_exhausted";
|
|
13231
13331
|
return event.outcome === "failed" ? "error" : "turn_ended";
|
|
13232
13332
|
}
|
|
13233
13333
|
async function unsandboxedVerify(run3) {
|
package/client.js
CHANGED
|
@@ -2486,7 +2486,9 @@ var RUN_STOP_REASONS = [
|
|
|
2486
2486
|
"cancelled",
|
|
2487
2487
|
"error",
|
|
2488
2488
|
"timeout",
|
|
2489
|
-
"device_lost"
|
|
2489
|
+
"device_lost",
|
|
2490
|
+
/** The subscription's quota or rate limit ran out mid-run (see `resetsAt`). */
|
|
2491
|
+
"quota_exhausted"
|
|
2490
2492
|
];
|
|
2491
2493
|
var runStopReason = z9.enum(RUN_STOP_REASONS);
|
|
2492
2494
|
var shortList = z9.array(z9.string().max(1e3)).max(5e3);
|
|
@@ -2561,6 +2563,11 @@ var runReport = z9.object({
|
|
|
2561
2563
|
nextStep: z9.string().max(2e3).nullable(),
|
|
2562
2564
|
/** For `blocked`: the external condition, e.g. `quota_exhausted`. */
|
|
2563
2565
|
blockedOn: z9.string().max(500).optional(),
|
|
2566
|
+
/**
|
|
2567
|
+
* For `quota_exhausted`: when the subscription's quota resets, as the CLI
|
|
2568
|
+
* reported it; null when it gave no time. Set by the daemon only.
|
|
2569
|
+
*/
|
|
2570
|
+
resetsAt: z9.iso.datetime({ offset: true }).nullable().optional(),
|
|
2564
2571
|
/** Daemon-owned receipt for an exact, unchanged read-only candidate. */
|
|
2565
2572
|
check: z9.object({
|
|
2566
2573
|
sha: z9.string().regex(/^[a-f0-9]{40}$/),
|
|
@@ -3734,7 +3741,7 @@ import { join } from "node:path";
|
|
|
3734
3741
|
// package.json
|
|
3735
3742
|
var package_default = {
|
|
3736
3743
|
name: "@mikka/daemon",
|
|
3737
|
-
version: "0.0.
|
|
3744
|
+
version: "0.0.145",
|
|
3738
3745
|
description: "Local Mikka daemon: runs agents through the user's own CLIs",
|
|
3739
3746
|
type: "module",
|
|
3740
3747
|
private: true,
|
|
@@ -3794,7 +3801,7 @@ var package_default = {
|
|
|
3794
3801
|
engines: {
|
|
3795
3802
|
node: ">=24"
|
|
3796
3803
|
},
|
|
3797
|
-
gitHead: "
|
|
3804
|
+
gitHead: "f4c4f818ea1d78fd81b298bda2a9249c50ba6f96"
|
|
3798
3805
|
};
|
|
3799
3806
|
|
|
3800
3807
|
// src/paths.ts
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
{"t":0,"chunk":{"type":"start","messageId":"msg-quota-exhausted-1"}}
|
|
2
|
+
{"t":100,"chunk":{"type":"text-start","id":"txt-1"}}
|
|
3
|
+
{"t":160,"chunk":{"type":"text-delta","id":"txt-1","delta":"Updating the parser."}}
|
|
4
|
+
{"t":200,"chunk":{"type":"text-end","id":"txt-1"}}
|
|
5
|
+
{"t":300,"exit":{"outcome":"failed","error":"Claude Code: Claude AI usage limit reached|1762016400","quota":{"resetsAt":"2025-11-01T17:00:00.000Z"}}}
|
package/http-link.js
CHANGED
|
@@ -3078,7 +3078,9 @@ var RUN_STOP_REASONS = [
|
|
|
3078
3078
|
"cancelled",
|
|
3079
3079
|
"error",
|
|
3080
3080
|
"timeout",
|
|
3081
|
-
"device_lost"
|
|
3081
|
+
"device_lost",
|
|
3082
|
+
/** The subscription's quota or rate limit ran out mid-run (see `resetsAt`). */
|
|
3083
|
+
"quota_exhausted"
|
|
3082
3084
|
];
|
|
3083
3085
|
var runStopReason = z16.enum(RUN_STOP_REASONS);
|
|
3084
3086
|
var shortList = z16.array(z16.string().max(1e3)).max(5e3);
|
|
@@ -3153,6 +3155,11 @@ var runReport = z16.object({
|
|
|
3153
3155
|
nextStep: z16.string().max(2e3).nullable(),
|
|
3154
3156
|
/** For `blocked`: the external condition, e.g. `quota_exhausted`. */
|
|
3155
3157
|
blockedOn: z16.string().max(500).optional(),
|
|
3158
|
+
/**
|
|
3159
|
+
* For `quota_exhausted`: when the subscription's quota resets, as the CLI
|
|
3160
|
+
* reported it; null when it gave no time. Set by the daemon only.
|
|
3161
|
+
*/
|
|
3162
|
+
resetsAt: z16.iso.datetime({ offset: true }).nullable().optional(),
|
|
3156
3163
|
/** Daemon-owned receipt for an exact, unchanged read-only candidate. */
|
|
3157
3164
|
check: z16.object({
|
|
3158
3165
|
sha: z16.string().regex(/^[a-f0-9]{40}$/),
|
|
@@ -4137,7 +4144,7 @@ var InvalidIdError = class extends DaemonError {
|
|
|
4137
4144
|
// package.json
|
|
4138
4145
|
var package_default = {
|
|
4139
4146
|
name: "@mikka/daemon",
|
|
4140
|
-
version: "0.0.
|
|
4147
|
+
version: "0.0.145",
|
|
4141
4148
|
description: "Local Mikka daemon: runs agents through the user's own CLIs",
|
|
4142
4149
|
type: "module",
|
|
4143
4150
|
private: true,
|
|
@@ -4197,7 +4204,7 @@ var package_default = {
|
|
|
4197
4204
|
engines: {
|
|
4198
4205
|
node: ">=24"
|
|
4199
4206
|
},
|
|
4200
|
-
gitHead: "
|
|
4207
|
+
gitHead: "f4c4f818ea1d78fd81b298bda2a9249c50ba6f96"
|
|
4201
4208
|
};
|
|
4202
4209
|
|
|
4203
4210
|
// src/paths.ts
|
package/login.js
CHANGED
|
@@ -2483,7 +2483,9 @@ var RUN_STOP_REASONS = [
|
|
|
2483
2483
|
"cancelled",
|
|
2484
2484
|
"error",
|
|
2485
2485
|
"timeout",
|
|
2486
|
-
"device_lost"
|
|
2486
|
+
"device_lost",
|
|
2487
|
+
/** The subscription's quota or rate limit ran out mid-run (see `resetsAt`). */
|
|
2488
|
+
"quota_exhausted"
|
|
2487
2489
|
];
|
|
2488
2490
|
var runStopReason = z9.enum(RUN_STOP_REASONS);
|
|
2489
2491
|
var shortList = z9.array(z9.string().max(1e3)).max(5e3);
|
|
@@ -2558,6 +2560,11 @@ var runReport = z9.object({
|
|
|
2558
2560
|
nextStep: z9.string().max(2e3).nullable(),
|
|
2559
2561
|
/** For `blocked`: the external condition, e.g. `quota_exhausted`. */
|
|
2560
2562
|
blockedOn: z9.string().max(500).optional(),
|
|
2563
|
+
/**
|
|
2564
|
+
* For `quota_exhausted`: when the subscription's quota resets, as the CLI
|
|
2565
|
+
* reported it; null when it gave no time. Set by the daemon only.
|
|
2566
|
+
*/
|
|
2567
|
+
resetsAt: z9.iso.datetime({ offset: true }).nullable().optional(),
|
|
2561
2568
|
/** Daemon-owned receipt for an exact, unchanged read-only candidate. */
|
|
2562
2569
|
check: z9.object({
|
|
2563
2570
|
sha: z9.string().regex(/^[a-f0-9]{40}$/),
|
|
@@ -3741,7 +3748,7 @@ var ServerUnreachableError = class extends DaemonError {
|
|
|
3741
3748
|
// package.json
|
|
3742
3749
|
var package_default = {
|
|
3743
3750
|
name: "@mikka/daemon",
|
|
3744
|
-
version: "0.0.
|
|
3751
|
+
version: "0.0.145",
|
|
3745
3752
|
description: "Local Mikka daemon: runs agents through the user's own CLIs",
|
|
3746
3753
|
type: "module",
|
|
3747
3754
|
private: true,
|
|
@@ -3801,7 +3808,7 @@ var package_default = {
|
|
|
3801
3808
|
engines: {
|
|
3802
3809
|
node: ">=24"
|
|
3803
3810
|
},
|
|
3804
|
-
gitHead: "
|
|
3811
|
+
gitHead: "f4c4f818ea1d78fd81b298bda2a9249c50ba6f96"
|
|
3805
3812
|
};
|
|
3806
3813
|
|
|
3807
3814
|
// src/paths.ts
|
package/main.js
CHANGED
|
@@ -3521,7 +3521,9 @@ var RUN_STOP_REASONS = [
|
|
|
3521
3521
|
"cancelled",
|
|
3522
3522
|
"error",
|
|
3523
3523
|
"timeout",
|
|
3524
|
-
"device_lost"
|
|
3524
|
+
"device_lost",
|
|
3525
|
+
/** The subscription's quota or rate limit ran out mid-run (see `resetsAt`). */
|
|
3526
|
+
"quota_exhausted"
|
|
3525
3527
|
];
|
|
3526
3528
|
var runStopReason = z4.enum(RUN_STOP_REASONS);
|
|
3527
3529
|
var shortList = z4.array(z4.string().max(1e3)).max(5e3);
|
|
@@ -3596,6 +3598,11 @@ var runReport = z4.object({
|
|
|
3596
3598
|
nextStep: z4.string().max(2e3).nullable(),
|
|
3597
3599
|
/** For `blocked`: the external condition, e.g. `quota_exhausted`. */
|
|
3598
3600
|
blockedOn: z4.string().max(500).optional(),
|
|
3601
|
+
/**
|
|
3602
|
+
* For `quota_exhausted`: when the subscription's quota resets, as the CLI
|
|
3603
|
+
* reported it; null when it gave no time. Set by the daemon only.
|
|
3604
|
+
*/
|
|
3605
|
+
resetsAt: z4.iso.datetime({ offset: true }).nullable().optional(),
|
|
3599
3606
|
/** Daemon-owned receipt for an exact, unchanged read-only candidate. */
|
|
3600
3607
|
check: z4.object({
|
|
3601
3608
|
sha: z4.string().regex(/^[a-f0-9]{40}$/),
|
|
@@ -3780,7 +3787,7 @@ import { join as join5 } from "node:path";
|
|
|
3780
3787
|
// package.json
|
|
3781
3788
|
var package_default = {
|
|
3782
3789
|
name: "@mikka/daemon",
|
|
3783
|
-
version: "0.0.
|
|
3790
|
+
version: "0.0.145",
|
|
3784
3791
|
description: "Local Mikka daemon: runs agents through the user's own CLIs",
|
|
3785
3792
|
type: "module",
|
|
3786
3793
|
private: true,
|
|
@@ -3840,7 +3847,7 @@ var package_default = {
|
|
|
3840
3847
|
engines: {
|
|
3841
3848
|
node: ">=24"
|
|
3842
3849
|
},
|
|
3843
|
-
gitHead: "
|
|
3850
|
+
gitHead: "f4c4f818ea1d78fd81b298bda2a9249c50ba6f96"
|
|
3844
3851
|
};
|
|
3845
3852
|
|
|
3846
3853
|
// src/paths.ts
|
|
@@ -6471,6 +6478,83 @@ import { arch as arch2, hostname, platform as platform3 } from "node:os";
|
|
|
6471
6478
|
import { join as join32 } from "node:path";
|
|
6472
6479
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
6473
6480
|
|
|
6481
|
+
// src/runs/quota-exhausted.ts
|
|
6482
|
+
var QUOTA_TEXT = /usage limit|hit your (?:usage )?limit|limit reached|rate limit|quota|too many requests|\b429\b/i;
|
|
6483
|
+
var fromEpochSeconds = (value) => typeof value === "number" && Number.isFinite(value) && value > 0 ? new Date(value * 1e3).toISOString() : null;
|
|
6484
|
+
function mergeQuota(previous, next) {
|
|
6485
|
+
if (!next) return previous;
|
|
6486
|
+
return previous?.resetsAt && !next.resetsAt ? previous : next;
|
|
6487
|
+
}
|
|
6488
|
+
function claudeResetFromText(text3) {
|
|
6489
|
+
const match = /\|\s*(\d{10})\b/.exec(text3);
|
|
6490
|
+
return match ? fromEpochSeconds(Number(match[1])) : null;
|
|
6491
|
+
}
|
|
6492
|
+
function textOf(content) {
|
|
6493
|
+
if (typeof content === "string") return content;
|
|
6494
|
+
if (!Array.isArray(content)) return "";
|
|
6495
|
+
return content.map((block) => block && typeof block === "object" && block.type === "text" ? String(block.text ?? "") : "").join("\n");
|
|
6496
|
+
}
|
|
6497
|
+
function claudeQuotaSignal(message) {
|
|
6498
|
+
if (!message || typeof message !== "object") return null;
|
|
6499
|
+
const value = message;
|
|
6500
|
+
if (value.type === "rate_limit_event") {
|
|
6501
|
+
const info = value.rate_limit_info;
|
|
6502
|
+
if (info?.status !== "rejected") return null;
|
|
6503
|
+
return { resetsAt: fromEpochSeconds(info.resetsAt) ?? fromEpochSeconds(info.overageResetsAt) };
|
|
6504
|
+
}
|
|
6505
|
+
if (value.type === "assistant" && value.error === "rate_limit") {
|
|
6506
|
+
const text3 = textOf(value.message?.content);
|
|
6507
|
+
return { resetsAt: claudeResetFromText(text3) };
|
|
6508
|
+
}
|
|
6509
|
+
if (value.type === "result" && value.is_error === true) {
|
|
6510
|
+
const text3 = [typeof value.result === "string" ? value.result : "", ...Array.isArray(value.errors) ? value.errors.map(String) : []].join("\n");
|
|
6511
|
+
if (!/usage limit|hit your (?:usage )?limit|limit reached/i.test(text3)) return null;
|
|
6512
|
+
return { resetsAt: claudeResetFromText(text3) };
|
|
6513
|
+
}
|
|
6514
|
+
return null;
|
|
6515
|
+
}
|
|
6516
|
+
var UNIT_MS = { day: 864e5, hour: 36e5, minute: 6e4, second: 1e3 };
|
|
6517
|
+
function codexResetFromText(text3, now) {
|
|
6518
|
+
const within = /try again in ([^.]+)/i.exec(text3);
|
|
6519
|
+
if (within) {
|
|
6520
|
+
let total = 0;
|
|
6521
|
+
for (const part of within[1].matchAll(/(\d+)\s*(day|hour|minute|second)s?/gi)) total += Number(part[1]) * UNIT_MS[part[2].toLowerCase()];
|
|
6522
|
+
return total > 0 ? new Date(now + total).toISOString() : null;
|
|
6523
|
+
}
|
|
6524
|
+
const at = /try again at ([^.]+)/i.exec(text3)?.[1]?.trim();
|
|
6525
|
+
if (!at) return null;
|
|
6526
|
+
const clock = /^(\d{1,2}):(\d{2})\s*(AM|PM)?$/i.exec(at);
|
|
6527
|
+
if (clock) {
|
|
6528
|
+
let hours = Number(clock[1]) % (clock[3] ? 12 : 24);
|
|
6529
|
+
if (clock[3]?.toUpperCase() === "PM") hours += 12;
|
|
6530
|
+
const day = new Date(now);
|
|
6531
|
+
day.setHours(hours, Number(clock[2]), 0, 0);
|
|
6532
|
+
if (day.getTime() <= now) day.setDate(day.getDate() + 1);
|
|
6533
|
+
return day.toISOString();
|
|
6534
|
+
}
|
|
6535
|
+
const parsed = Date.parse(at.replace(/(\d)(st|nd|rd|th)\b/gi, "$1"));
|
|
6536
|
+
return Number.isFinite(parsed) ? new Date(parsed).toISOString() : null;
|
|
6537
|
+
}
|
|
6538
|
+
function codexInfoIsQuota(info) {
|
|
6539
|
+
if (info === "usageLimitExceeded") return true;
|
|
6540
|
+
if (!info || typeof info !== "object") return false;
|
|
6541
|
+
return Object.values(info).some((detail) => Boolean(detail && typeof detail === "object" && detail.httpStatusCode === 429));
|
|
6542
|
+
}
|
|
6543
|
+
function codexResetFromLimits(limits) {
|
|
6544
|
+
const full = [limits?.primary, limits?.secondary].filter((window) => window && (window.usedPercent ?? 0) >= 100);
|
|
6545
|
+
const resets = full.map((window) => fromEpochSeconds(window?.resetsAt)).filter((value) => Boolean(value));
|
|
6546
|
+
return resets.sort().at(-1) ?? null;
|
|
6547
|
+
}
|
|
6548
|
+
function codexQuotaSignal(error, limits, now = Date.now()) {
|
|
6549
|
+
if (!error) return null;
|
|
6550
|
+
const message = typeof error.message === "string" ? error.message : "";
|
|
6551
|
+
if (!codexInfoIsQuota(error.codexErrorInfo) && !QUOTA_TEXT.test(message)) return null;
|
|
6552
|
+
return { resetsAt: codexResetFromText(message, now) ?? codexResetFromLimits(limits) };
|
|
6553
|
+
}
|
|
6554
|
+
function quotaStopApplies(assignment) {
|
|
6555
|
+
return !assignment.modelCredential;
|
|
6556
|
+
}
|
|
6557
|
+
|
|
6474
6558
|
// src/adapters/claude.ts
|
|
6475
6559
|
import { spawn as spawn3 } from "node:child_process";
|
|
6476
6560
|
|
|
@@ -7255,6 +7339,7 @@ var ClaudeAdapter = class {
|
|
|
7255
7339
|
let runtimeModel = null;
|
|
7256
7340
|
let ending = false;
|
|
7257
7341
|
let lastError;
|
|
7342
|
+
let quota;
|
|
7258
7343
|
let graceTimer;
|
|
7259
7344
|
let authTimer;
|
|
7260
7345
|
let stderr = "";
|
|
@@ -7371,7 +7456,7 @@ var ClaudeAdapter = class {
|
|
|
7371
7456
|
const handoff = ctx.readHandoff(log);
|
|
7372
7457
|
if (handoff) return void end(handoff);
|
|
7373
7458
|
void end(
|
|
7374
|
-
lastError ? { outcome: "failed", error: lastError } : { outcome: "succeeded" }
|
|
7459
|
+
lastError ? { outcome: "failed", error: lastError, ...quota ? { quota } : {} } : { outcome: "succeeded" }
|
|
7375
7460
|
);
|
|
7376
7461
|
};
|
|
7377
7462
|
const diedEarly = (error) => {
|
|
@@ -7380,7 +7465,8 @@ var ClaudeAdapter = class {
|
|
|
7380
7465
|
queue.exit(
|
|
7381
7466
|
handoff ?? {
|
|
7382
7467
|
outcome: "failed",
|
|
7383
|
-
error: externalAuth ? SUBSCRIPTION_EXECUTION_ERROR : `claude exited before the turn ended: ${error}
|
|
7468
|
+
error: externalAuth ? SUBSCRIPTION_EXECUTION_ERROR : `claude exited before the turn ended: ${error}`,
|
|
7469
|
+
...quota ? { quota } : {}
|
|
7384
7470
|
}
|
|
7385
7471
|
);
|
|
7386
7472
|
};
|
|
@@ -7399,11 +7485,13 @@ var ClaudeAdapter = class {
|
|
|
7399
7485
|
if (message.type === "assistant" || message.type === "user")
|
|
7400
7486
|
clearTimeout(graceTimer);
|
|
7401
7487
|
if (ending) continue;
|
|
7488
|
+
quota = mergeQuota(quota, claudeQuotaSignal(message));
|
|
7402
7489
|
if (message.type === "tool_progress" && message.session_id === sessionId) queue.progress();
|
|
7403
7490
|
if (!(externalAuth && message.type === "assistant" && message.error))
|
|
7404
7491
|
for (const chunk of claudeChunks(message)) queue.chunk(chunk);
|
|
7405
7492
|
if (message.type !== "result") continue;
|
|
7406
7493
|
results++;
|
|
7494
|
+
if (!message.is_error) quota = void 0;
|
|
7407
7495
|
lastError = message.is_error ? externalAuth ? SUBSCRIPTION_EXECUTION_ERROR : `Claude Code: ${resultError(message)}` : void 0;
|
|
7408
7496
|
if (results >= written) {
|
|
7409
7497
|
turnEnded();
|
|
@@ -7799,6 +7887,8 @@ var CodexAdapter = class {
|
|
|
7799
7887
|
let ending = false;
|
|
7800
7888
|
let cancelling = false;
|
|
7801
7889
|
let lastError;
|
|
7890
|
+
let quota;
|
|
7891
|
+
let rateLimits;
|
|
7802
7892
|
let usage = { inputTokens: 0, outputTokens: 0 };
|
|
7803
7893
|
const pendingMcp = /* @__PURE__ */ new Map();
|
|
7804
7894
|
const registeredMcpTool = (server, tool2) => server === MCP_SERVER_NAME && ["submit", "request_help", "ask_human", "report_blocked"].includes(tool2) || Boolean(computerMcp) && server === COMPUTER_MCP_SERVER_NAME && ["get_desktop_state", "click", "type_text", "press_key", "scroll"].includes(tool2) || Boolean(options.apps?.apps.some((app) => app.name === server));
|
|
@@ -7930,8 +8020,12 @@ var CodexAdapter = class {
|
|
|
7930
8020
|
};
|
|
7931
8021
|
return;
|
|
7932
8022
|
}
|
|
8023
|
+
case "account/rateLimits/updated":
|
|
8024
|
+
rateLimits = params.rateLimits;
|
|
8025
|
+
return;
|
|
7933
8026
|
case "error": {
|
|
7934
8027
|
const { error, willRetry } = params;
|
|
8028
|
+
if (!willRetry) quota = mergeQuota(quota, codexQuotaSignal(error, rateLimits));
|
|
7935
8029
|
if (!willRetry)
|
|
7936
8030
|
lastError = externalAuth ? SUBSCRIPTION_EXECUTION_ERROR2 : `Codex: ${error.message}`;
|
|
7937
8031
|
return;
|
|
@@ -7982,8 +8076,10 @@ var CodexAdapter = class {
|
|
|
7982
8076
|
return;
|
|
7983
8077
|
}
|
|
7984
8078
|
if (turn.status === "failed" || lastError) {
|
|
8079
|
+
quota = mergeQuota(quota, codexQuotaSignal(turn.error, rateLimits));
|
|
7985
8080
|
return finish({
|
|
7986
8081
|
outcome: "failed",
|
|
8082
|
+
...quota ? { quota } : {},
|
|
7987
8083
|
error: externalAuth ? SUBSCRIPTION_EXECUTION_ERROR2 : turn.error?.message ? `Codex: ${turn.error.message}` : lastError
|
|
7988
8084
|
});
|
|
7989
8085
|
}
|
|
@@ -7993,6 +8089,7 @@ var CodexAdapter = class {
|
|
|
7993
8089
|
let runtimeModel = null;
|
|
7994
8090
|
const startTurn = async (message) => {
|
|
7995
8091
|
lastError = void 0;
|
|
8092
|
+
quota = void 0;
|
|
7996
8093
|
if (externalAuth?.verify) {
|
|
7997
8094
|
try {
|
|
7998
8095
|
await externalAuth.verify();
|
|
@@ -10897,6 +10994,8 @@ var MemoryServer = class {
|
|
|
10897
10994
|
return retry("retry", MAX_CRASH_RETRIES);
|
|
10898
10995
|
case "device_lost":
|
|
10899
10996
|
return { owner: "external", reason: "device_offline" };
|
|
10997
|
+
case "quota_exhausted":
|
|
10998
|
+
return { owner: "external", reason: "quota_exhausted" };
|
|
10900
10999
|
case "cancelled":
|
|
10901
11000
|
return { owner: "human", reason: "cancelled" };
|
|
10902
11001
|
}
|
|
@@ -12163,7 +12262,7 @@ var RunSupervisor = class {
|
|
|
12163
12262
|
continue;
|
|
12164
12263
|
}
|
|
12165
12264
|
await this.closeMailbox(run3);
|
|
12166
|
-
const stopReason = stopReasonOf(event, run3);
|
|
12265
|
+
const stopReason = stopReasonOf(event, run3, assignment);
|
|
12167
12266
|
const error = event.error ?? (stopReason === "turn_ended" ? "Session ended without a submission" : stopReason === "timeout" ? "No progress before the watchdog limit" : stopReason === "device_lost" ? "Run lease expired; the server could not be reached" : void 0);
|
|
12168
12267
|
if (assignment.benchmark) {
|
|
12169
12268
|
const fixed = await fixedCheckSnapshot(repo.path, worktree, assignment.benchmark.sourceCommit);
|
|
@@ -12181,7 +12280,7 @@ var RunSupervisor = class {
|
|
|
12181
12280
|
);
|
|
12182
12281
|
if (this.stopping) return;
|
|
12183
12282
|
const { verifyError, tree } = outcome;
|
|
12184
|
-
let report = outcome.report;
|
|
12283
|
+
let report = stopReason === "quota_exhausted" ? { ...outcome.report, resetsAt: event.quota?.resetsAt ?? null } : outcome.report;
|
|
12185
12284
|
const policy = runPolicy(assignment.policy);
|
|
12186
12285
|
if (stopReason === "submitted" && report.verify.status !== "failed" && tree && // The draft-PR exception requires an explicit repository push
|
|
12187
12286
|
// approval. It must not even create a local commit without it.
|
|
@@ -12284,11 +12383,12 @@ function pickAgentReport(agent) {
|
|
|
12284
12383
|
}
|
|
12285
12384
|
return picked;
|
|
12286
12385
|
}
|
|
12287
|
-
var KEEP_WORKTREE = ["turn_ended", "asked_human"];
|
|
12288
|
-
function stopReasonOf(event, run3) {
|
|
12386
|
+
var KEEP_WORKTREE = ["turn_ended", "asked_human", "quota_exhausted"];
|
|
12387
|
+
function stopReasonOf(event, run3, assignment) {
|
|
12289
12388
|
if (run3.forcedStop) return run3.forcedStop;
|
|
12290
12389
|
if (event.outcome === "cancelled" || run3.cancelRequested) return "cancelled";
|
|
12291
12390
|
if (event.stopReason) return event.stopReason;
|
|
12391
|
+
if (event.outcome === "failed" && event.quota && quotaStopApplies(assignment)) return "quota_exhausted";
|
|
12292
12392
|
return event.outcome === "failed" ? "error" : "turn_ended";
|
|
12293
12393
|
}
|
|
12294
12394
|
async function unsandboxedVerify(run3) {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 1,
|
|
3
|
-
"sourceSha": "
|
|
3
|
+
"sourceSha": "f4c4f818ea1d78fd81b298bda2a9249c50ba6f96",
|
|
4
4
|
"repository": "alexj11324/Mikka",
|
|
5
|
-
"buildRunId": "
|
|
5
|
+
"buildRunId": "41279158266",
|
|
6
6
|
"buildKind": "github-actions-main",
|
|
7
7
|
"sourceLockSha256": "c99f1e4f641d8e004cfe807653478e10f91e53fcf47102add5f4c154cdc1cb57",
|
|
8
|
-
"createdAt": "2026-11-
|
|
8
|
+
"createdAt": "2026-11-01T06:03:29.691Z",
|
|
9
9
|
"sbom": "sbom.cdx.json",
|
|
10
10
|
"files": [
|
|
11
11
|
{
|
|
@@ -40,13 +40,13 @@
|
|
|
40
40
|
},
|
|
41
41
|
{
|
|
42
42
|
"path": "cli.js",
|
|
43
|
-
"size":
|
|
44
|
-
"sha256": "
|
|
43
|
+
"size": 648726,
|
|
44
|
+
"sha256": "75bb140b3934ad48cc3309c35b8af9b35dbfd51bac9c2836748a82419d18e00c"
|
|
45
45
|
},
|
|
46
46
|
{
|
|
47
47
|
"path": "client.js",
|
|
48
|
-
"size":
|
|
49
|
-
"sha256": "
|
|
48
|
+
"size": 141206,
|
|
49
|
+
"sha256": "78aa71d0aee9887bd1ed8a02fd06b72d024cc68581638c562af39fe745f82b08"
|
|
50
50
|
},
|
|
51
51
|
{
|
|
52
52
|
"path": "computer/driver.mjs",
|
|
@@ -103,6 +103,11 @@
|
|
|
103
103
|
"size": 2361,
|
|
104
104
|
"sha256": "86e5681f2aad82629db9e8a4dd7bb6dcee11c008118277d47dcf0d94c8483110"
|
|
105
105
|
},
|
|
106
|
+
{
|
|
107
|
+
"path": "fixtures/quota-exhausted.jsonl",
|
|
108
|
+
"size": 407,
|
|
109
|
+
"sha256": "d32b9fc7c6778db3cfa1612e80318fa09aef66eb827c1acee271b598ab4ef2fe"
|
|
110
|
+
},
|
|
106
111
|
{
|
|
107
112
|
"path": "fixtures/quota.jsonl",
|
|
108
113
|
"size": 594,
|
|
@@ -170,8 +175,8 @@
|
|
|
170
175
|
},
|
|
171
176
|
{
|
|
172
177
|
"path": "http-link.js",
|
|
173
|
-
"size":
|
|
174
|
-
"sha256": "
|
|
178
|
+
"size": 182550,
|
|
179
|
+
"sha256": "822fc4b32b591cf8e82b4d8ec6c128abe804e3e2759a399580ac6072bbaf88a6"
|
|
175
180
|
},
|
|
176
181
|
{
|
|
177
182
|
"path": "log.js",
|
|
@@ -180,13 +185,13 @@
|
|
|
180
185
|
},
|
|
181
186
|
{
|
|
182
187
|
"path": "login.js",
|
|
183
|
-
"size":
|
|
184
|
-
"sha256": "
|
|
188
|
+
"size": 145941,
|
|
189
|
+
"sha256": "10725733ab5d116ef38881e5d534931c1795e2ee256175cef91cc7d43f8ab375"
|
|
185
190
|
},
|
|
186
191
|
{
|
|
187
192
|
"path": "main.js",
|
|
188
|
-
"size":
|
|
189
|
-
"sha256": "
|
|
193
|
+
"size": 594252,
|
|
194
|
+
"sha256": "e861785ccb1833941c63f3763bd037ef6546a42f80da15c6164490f6ac10f8d5"
|
|
190
195
|
},
|
|
191
196
|
{
|
|
192
197
|
"path": "mikka-mcp.mjs",
|
|
@@ -195,23 +200,23 @@
|
|
|
195
200
|
},
|
|
196
201
|
{
|
|
197
202
|
"path": "mikka.js",
|
|
198
|
-
"size":
|
|
199
|
-
"sha256": "
|
|
203
|
+
"size": 648742,
|
|
204
|
+
"sha256": "6a29c5f06de35e97ba744d90e2dc787ec720a3d80cde5668b90a9c9188313b6f"
|
|
200
205
|
},
|
|
201
206
|
{
|
|
202
207
|
"path": "npm-shrinkwrap.json",
|
|
203
208
|
"size": 78117,
|
|
204
|
-
"sha256": "
|
|
209
|
+
"sha256": "1c5bbc1604bc104d95762ccf4c65e85dd51b3cfe2544bd0fdc9b67ebd9ed7b79"
|
|
205
210
|
},
|
|
206
211
|
{
|
|
207
212
|
"path": "package.json",
|
|
208
213
|
"size": 1247,
|
|
209
|
-
"sha256": "
|
|
214
|
+
"sha256": "daa3570756f78b62d93854096b5875d092b40b8546a8414669c39ace6e9c8210"
|
|
210
215
|
},
|
|
211
216
|
{
|
|
212
217
|
"path": "paths.js",
|
|
213
218
|
"size": 4138,
|
|
214
|
-
"sha256": "
|
|
219
|
+
"sha256": "aa1694df2bdc6c01884e3e6b791d77391f6fb6af8bde0b0b46489717dd3e1cbc"
|
|
215
220
|
},
|
|
216
221
|
{
|
|
217
222
|
"path": "sandbox.js",
|
|
@@ -221,7 +226,7 @@
|
|
|
221
226
|
{
|
|
222
227
|
"path": "sbom.cdx.json",
|
|
223
228
|
"size": 144314,
|
|
224
|
-
"sha256": "
|
|
229
|
+
"sha256": "0a1db55babf766e413dcab8f751c1388fdc6b15ab8001b326708678737f6c5ef"
|
|
225
230
|
}
|
|
226
231
|
]
|
|
227
232
|
}
|
package/mikka.js
CHANGED
|
@@ -3003,7 +3003,9 @@ var RUN_STOP_REASONS = [
|
|
|
3003
3003
|
"cancelled",
|
|
3004
3004
|
"error",
|
|
3005
3005
|
"timeout",
|
|
3006
|
-
"device_lost"
|
|
3006
|
+
"device_lost",
|
|
3007
|
+
/** The subscription's quota or rate limit ran out mid-run (see `resetsAt`). */
|
|
3008
|
+
"quota_exhausted"
|
|
3007
3009
|
];
|
|
3008
3010
|
var runStopReason = z9.enum(RUN_STOP_REASONS);
|
|
3009
3011
|
var shortList = z9.array(z9.string().max(1e3)).max(5e3);
|
|
@@ -3078,6 +3080,11 @@ var runReport = z9.object({
|
|
|
3078
3080
|
nextStep: z9.string().max(2e3).nullable(),
|
|
3079
3081
|
/** For `blocked`: the external condition, e.g. `quota_exhausted`. */
|
|
3080
3082
|
blockedOn: z9.string().max(500).optional(),
|
|
3083
|
+
/**
|
|
3084
|
+
* For `quota_exhausted`: when the subscription's quota resets, as the CLI
|
|
3085
|
+
* reported it; null when it gave no time. Set by the daemon only.
|
|
3086
|
+
*/
|
|
3087
|
+
resetsAt: z9.iso.datetime({ offset: true }).nullable().optional(),
|
|
3081
3088
|
/** Daemon-owned receipt for an exact, unchanged read-only candidate. */
|
|
3082
3089
|
check: z9.object({
|
|
3083
3090
|
sha: z9.string().regex(/^[a-f0-9]{40}$/),
|
|
@@ -4474,7 +4481,7 @@ import { join as join4 } from "node:path";
|
|
|
4474
4481
|
// package.json
|
|
4475
4482
|
var package_default = {
|
|
4476
4483
|
name: "@mikka/daemon",
|
|
4477
|
-
version: "0.0.
|
|
4484
|
+
version: "0.0.145",
|
|
4478
4485
|
description: "Local Mikka daemon: runs agents through the user's own CLIs",
|
|
4479
4486
|
type: "module",
|
|
4480
4487
|
private: true,
|
|
@@ -4534,7 +4541,7 @@ var package_default = {
|
|
|
4534
4541
|
engines: {
|
|
4535
4542
|
node: ">=24"
|
|
4536
4543
|
},
|
|
4537
|
-
gitHead: "
|
|
4544
|
+
gitHead: "f4c4f818ea1d78fd81b298bda2a9249c50ba6f96"
|
|
4538
4545
|
};
|
|
4539
4546
|
|
|
4540
4547
|
// src/paths.ts
|
|
@@ -7687,6 +7694,83 @@ import { arch as arch2, hostname, platform as platform3 } from "node:os";
|
|
|
7687
7694
|
import { join as join32 } from "node:path";
|
|
7688
7695
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
7689
7696
|
|
|
7697
|
+
// src/runs/quota-exhausted.ts
|
|
7698
|
+
var QUOTA_TEXT = /usage limit|hit your (?:usage )?limit|limit reached|rate limit|quota|too many requests|\b429\b/i;
|
|
7699
|
+
var fromEpochSeconds = (value) => typeof value === "number" && Number.isFinite(value) && value > 0 ? new Date(value * 1e3).toISOString() : null;
|
|
7700
|
+
function mergeQuota(previous, next) {
|
|
7701
|
+
if (!next) return previous;
|
|
7702
|
+
return previous?.resetsAt && !next.resetsAt ? previous : next;
|
|
7703
|
+
}
|
|
7704
|
+
function claudeResetFromText(text3) {
|
|
7705
|
+
const match = /\|\s*(\d{10})\b/.exec(text3);
|
|
7706
|
+
return match ? fromEpochSeconds(Number(match[1])) : null;
|
|
7707
|
+
}
|
|
7708
|
+
function textOf(content) {
|
|
7709
|
+
if (typeof content === "string") return content;
|
|
7710
|
+
if (!Array.isArray(content)) return "";
|
|
7711
|
+
return content.map((block) => block && typeof block === "object" && block.type === "text" ? String(block.text ?? "") : "").join("\n");
|
|
7712
|
+
}
|
|
7713
|
+
function claudeQuotaSignal(message) {
|
|
7714
|
+
if (!message || typeof message !== "object") return null;
|
|
7715
|
+
const value = message;
|
|
7716
|
+
if (value.type === "rate_limit_event") {
|
|
7717
|
+
const info = value.rate_limit_info;
|
|
7718
|
+
if (info?.status !== "rejected") return null;
|
|
7719
|
+
return { resetsAt: fromEpochSeconds(info.resetsAt) ?? fromEpochSeconds(info.overageResetsAt) };
|
|
7720
|
+
}
|
|
7721
|
+
if (value.type === "assistant" && value.error === "rate_limit") {
|
|
7722
|
+
const text3 = textOf(value.message?.content);
|
|
7723
|
+
return { resetsAt: claudeResetFromText(text3) };
|
|
7724
|
+
}
|
|
7725
|
+
if (value.type === "result" && value.is_error === true) {
|
|
7726
|
+
const text3 = [typeof value.result === "string" ? value.result : "", ...Array.isArray(value.errors) ? value.errors.map(String) : []].join("\n");
|
|
7727
|
+
if (!/usage limit|hit your (?:usage )?limit|limit reached/i.test(text3)) return null;
|
|
7728
|
+
return { resetsAt: claudeResetFromText(text3) };
|
|
7729
|
+
}
|
|
7730
|
+
return null;
|
|
7731
|
+
}
|
|
7732
|
+
var UNIT_MS = { day: 864e5, hour: 36e5, minute: 6e4, second: 1e3 };
|
|
7733
|
+
function codexResetFromText(text3, now) {
|
|
7734
|
+
const within = /try again in ([^.]+)/i.exec(text3);
|
|
7735
|
+
if (within) {
|
|
7736
|
+
let total = 0;
|
|
7737
|
+
for (const part of within[1].matchAll(/(\d+)\s*(day|hour|minute|second)s?/gi)) total += Number(part[1]) * UNIT_MS[part[2].toLowerCase()];
|
|
7738
|
+
return total > 0 ? new Date(now + total).toISOString() : null;
|
|
7739
|
+
}
|
|
7740
|
+
const at = /try again at ([^.]+)/i.exec(text3)?.[1]?.trim();
|
|
7741
|
+
if (!at) return null;
|
|
7742
|
+
const clock = /^(\d{1,2}):(\d{2})\s*(AM|PM)?$/i.exec(at);
|
|
7743
|
+
if (clock) {
|
|
7744
|
+
let hours = Number(clock[1]) % (clock[3] ? 12 : 24);
|
|
7745
|
+
if (clock[3]?.toUpperCase() === "PM") hours += 12;
|
|
7746
|
+
const day = new Date(now);
|
|
7747
|
+
day.setHours(hours, Number(clock[2]), 0, 0);
|
|
7748
|
+
if (day.getTime() <= now) day.setDate(day.getDate() + 1);
|
|
7749
|
+
return day.toISOString();
|
|
7750
|
+
}
|
|
7751
|
+
const parsed = Date.parse(at.replace(/(\d)(st|nd|rd|th)\b/gi, "$1"));
|
|
7752
|
+
return Number.isFinite(parsed) ? new Date(parsed).toISOString() : null;
|
|
7753
|
+
}
|
|
7754
|
+
function codexInfoIsQuota(info) {
|
|
7755
|
+
if (info === "usageLimitExceeded") return true;
|
|
7756
|
+
if (!info || typeof info !== "object") return false;
|
|
7757
|
+
return Object.values(info).some((detail) => Boolean(detail && typeof detail === "object" && detail.httpStatusCode === 429));
|
|
7758
|
+
}
|
|
7759
|
+
function codexResetFromLimits(limits) {
|
|
7760
|
+
const full = [limits?.primary, limits?.secondary].filter((window) => window && (window.usedPercent ?? 0) >= 100);
|
|
7761
|
+
const resets = full.map((window) => fromEpochSeconds(window?.resetsAt)).filter((value) => Boolean(value));
|
|
7762
|
+
return resets.sort().at(-1) ?? null;
|
|
7763
|
+
}
|
|
7764
|
+
function codexQuotaSignal(error, limits, now = Date.now()) {
|
|
7765
|
+
if (!error) return null;
|
|
7766
|
+
const message = typeof error.message === "string" ? error.message : "";
|
|
7767
|
+
if (!codexInfoIsQuota(error.codexErrorInfo) && !QUOTA_TEXT.test(message)) return null;
|
|
7768
|
+
return { resetsAt: codexResetFromText(message, now) ?? codexResetFromLimits(limits) };
|
|
7769
|
+
}
|
|
7770
|
+
function quotaStopApplies(assignment) {
|
|
7771
|
+
return !assignment.modelCredential;
|
|
7772
|
+
}
|
|
7773
|
+
|
|
7690
7774
|
// src/adapters/claude.ts
|
|
7691
7775
|
import { spawn as spawn3 } from "node:child_process";
|
|
7692
7776
|
|
|
@@ -8436,6 +8520,7 @@ var ClaudeAdapter = class {
|
|
|
8436
8520
|
let runtimeModel = null;
|
|
8437
8521
|
let ending = false;
|
|
8438
8522
|
let lastError;
|
|
8523
|
+
let quota;
|
|
8439
8524
|
let graceTimer;
|
|
8440
8525
|
let authTimer;
|
|
8441
8526
|
let stderr = "";
|
|
@@ -8552,7 +8637,7 @@ var ClaudeAdapter = class {
|
|
|
8552
8637
|
const handoff = ctx.readHandoff(log);
|
|
8553
8638
|
if (handoff) return void end(handoff);
|
|
8554
8639
|
void end(
|
|
8555
|
-
lastError ? { outcome: "failed", error: lastError } : { outcome: "succeeded" }
|
|
8640
|
+
lastError ? { outcome: "failed", error: lastError, ...quota ? { quota } : {} } : { outcome: "succeeded" }
|
|
8556
8641
|
);
|
|
8557
8642
|
};
|
|
8558
8643
|
const diedEarly = (error) => {
|
|
@@ -8561,7 +8646,8 @@ var ClaudeAdapter = class {
|
|
|
8561
8646
|
queue.exit(
|
|
8562
8647
|
handoff ?? {
|
|
8563
8648
|
outcome: "failed",
|
|
8564
|
-
error: externalAuth ? SUBSCRIPTION_EXECUTION_ERROR : `claude exited before the turn ended: ${error}
|
|
8649
|
+
error: externalAuth ? SUBSCRIPTION_EXECUTION_ERROR : `claude exited before the turn ended: ${error}`,
|
|
8650
|
+
...quota ? { quota } : {}
|
|
8565
8651
|
}
|
|
8566
8652
|
);
|
|
8567
8653
|
};
|
|
@@ -8580,11 +8666,13 @@ var ClaudeAdapter = class {
|
|
|
8580
8666
|
if (message.type === "assistant" || message.type === "user")
|
|
8581
8667
|
clearTimeout(graceTimer);
|
|
8582
8668
|
if (ending) continue;
|
|
8669
|
+
quota = mergeQuota(quota, claudeQuotaSignal(message));
|
|
8583
8670
|
if (message.type === "tool_progress" && message.session_id === sessionId) queue.progress();
|
|
8584
8671
|
if (!(externalAuth && message.type === "assistant" && message.error))
|
|
8585
8672
|
for (const chunk of claudeChunks(message)) queue.chunk(chunk);
|
|
8586
8673
|
if (message.type !== "result") continue;
|
|
8587
8674
|
results++;
|
|
8675
|
+
if (!message.is_error) quota = void 0;
|
|
8588
8676
|
lastError = message.is_error ? externalAuth ? SUBSCRIPTION_EXECUTION_ERROR : `Claude Code: ${resultError(message)}` : void 0;
|
|
8589
8677
|
if (results >= written) {
|
|
8590
8678
|
turnEnded();
|
|
@@ -8980,6 +9068,8 @@ var CodexAdapter = class {
|
|
|
8980
9068
|
let ending = false;
|
|
8981
9069
|
let cancelling = false;
|
|
8982
9070
|
let lastError;
|
|
9071
|
+
let quota;
|
|
9072
|
+
let rateLimits;
|
|
8983
9073
|
let usage = { inputTokens: 0, outputTokens: 0 };
|
|
8984
9074
|
const pendingMcp = /* @__PURE__ */ new Map();
|
|
8985
9075
|
const registeredMcpTool = (server, tool2) => server === MCP_SERVER_NAME && ["submit", "request_help", "ask_human", "report_blocked"].includes(tool2) || Boolean(computerMcp) && server === COMPUTER_MCP_SERVER_NAME && ["get_desktop_state", "click", "type_text", "press_key", "scroll"].includes(tool2) || Boolean(options.apps?.apps.some((app) => app.name === server));
|
|
@@ -9111,8 +9201,12 @@ var CodexAdapter = class {
|
|
|
9111
9201
|
};
|
|
9112
9202
|
return;
|
|
9113
9203
|
}
|
|
9204
|
+
case "account/rateLimits/updated":
|
|
9205
|
+
rateLimits = params.rateLimits;
|
|
9206
|
+
return;
|
|
9114
9207
|
case "error": {
|
|
9115
9208
|
const { error, willRetry } = params;
|
|
9209
|
+
if (!willRetry) quota = mergeQuota(quota, codexQuotaSignal(error, rateLimits));
|
|
9116
9210
|
if (!willRetry)
|
|
9117
9211
|
lastError = externalAuth ? SUBSCRIPTION_EXECUTION_ERROR2 : `Codex: ${error.message}`;
|
|
9118
9212
|
return;
|
|
@@ -9163,8 +9257,10 @@ var CodexAdapter = class {
|
|
|
9163
9257
|
return;
|
|
9164
9258
|
}
|
|
9165
9259
|
if (turn.status === "failed" || lastError) {
|
|
9260
|
+
quota = mergeQuota(quota, codexQuotaSignal(turn.error, rateLimits));
|
|
9166
9261
|
return finish({
|
|
9167
9262
|
outcome: "failed",
|
|
9263
|
+
...quota ? { quota } : {},
|
|
9168
9264
|
error: externalAuth ? SUBSCRIPTION_EXECUTION_ERROR2 : turn.error?.message ? `Codex: ${turn.error.message}` : lastError
|
|
9169
9265
|
});
|
|
9170
9266
|
}
|
|
@@ -9174,6 +9270,7 @@ var CodexAdapter = class {
|
|
|
9174
9270
|
let runtimeModel = null;
|
|
9175
9271
|
const startTurn = async (message) => {
|
|
9176
9272
|
lastError = void 0;
|
|
9273
|
+
quota = void 0;
|
|
9177
9274
|
if (externalAuth?.verify) {
|
|
9178
9275
|
try {
|
|
9179
9276
|
await externalAuth.verify();
|
|
@@ -11837,6 +11934,8 @@ var MemoryServer = class {
|
|
|
11837
11934
|
return retry("retry", MAX_CRASH_RETRIES);
|
|
11838
11935
|
case "device_lost":
|
|
11839
11936
|
return { owner: "external", reason: "device_offline" };
|
|
11937
|
+
case "quota_exhausted":
|
|
11938
|
+
return { owner: "external", reason: "quota_exhausted" };
|
|
11840
11939
|
case "cancelled":
|
|
11841
11940
|
return { owner: "human", reason: "cancelled" };
|
|
11842
11941
|
}
|
|
@@ -13103,7 +13202,7 @@ var RunSupervisor = class {
|
|
|
13103
13202
|
continue;
|
|
13104
13203
|
}
|
|
13105
13204
|
await this.closeMailbox(run3);
|
|
13106
|
-
const stopReason = stopReasonOf(event, run3);
|
|
13205
|
+
const stopReason = stopReasonOf(event, run3, assignment);
|
|
13107
13206
|
const error = event.error ?? (stopReason === "turn_ended" ? "Session ended without a submission" : stopReason === "timeout" ? "No progress before the watchdog limit" : stopReason === "device_lost" ? "Run lease expired; the server could not be reached" : void 0);
|
|
13108
13207
|
if (assignment.benchmark) {
|
|
13109
13208
|
const fixed = await fixedCheckSnapshot(repo.path, worktree, assignment.benchmark.sourceCommit);
|
|
@@ -13121,7 +13220,7 @@ var RunSupervisor = class {
|
|
|
13121
13220
|
);
|
|
13122
13221
|
if (this.stopping) return;
|
|
13123
13222
|
const { verifyError, tree } = outcome;
|
|
13124
|
-
let report = outcome.report;
|
|
13223
|
+
let report = stopReason === "quota_exhausted" ? { ...outcome.report, resetsAt: event.quota?.resetsAt ?? null } : outcome.report;
|
|
13125
13224
|
const policy = runPolicy(assignment.policy);
|
|
13126
13225
|
if (stopReason === "submitted" && report.verify.status !== "failed" && tree && // The draft-PR exception requires an explicit repository push
|
|
13127
13226
|
// approval. It must not even create a local commit without it.
|
|
@@ -13224,11 +13323,12 @@ function pickAgentReport(agent) {
|
|
|
13224
13323
|
}
|
|
13225
13324
|
return picked;
|
|
13226
13325
|
}
|
|
13227
|
-
var KEEP_WORKTREE = ["turn_ended", "asked_human"];
|
|
13228
|
-
function stopReasonOf(event, run3) {
|
|
13326
|
+
var KEEP_WORKTREE = ["turn_ended", "asked_human", "quota_exhausted"];
|
|
13327
|
+
function stopReasonOf(event, run3, assignment) {
|
|
13229
13328
|
if (run3.forcedStop) return run3.forcedStop;
|
|
13230
13329
|
if (event.outcome === "cancelled" || run3.cancelRequested) return "cancelled";
|
|
13231
13330
|
if (event.stopReason) return event.stopReason;
|
|
13331
|
+
if (event.outcome === "failed" && event.quota && quotaStopApplies(assignment)) return "quota_exhausted";
|
|
13232
13332
|
return event.outcome === "failed" ? "error" : "turn_ended";
|
|
13233
13333
|
}
|
|
13234
13334
|
async function unsandboxedVerify(run3) {
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aspectlylabs/mikka",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.145",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@aspectlylabs/mikka",
|
|
9
|
-
"version": "0.0.
|
|
9
|
+
"version": "0.0.145",
|
|
10
10
|
"license": "AGPL-3.0-only",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@agentclientprotocol/sdk": "1.9.0",
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aspectlylabs/mikka",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.145",
|
|
4
4
|
"description": "Local Mikka daemon: runs agents through the user's own CLIs",
|
|
5
|
-
"gitHead": "
|
|
5
|
+
"gitHead": "f4c4f818ea1d78fd81b298bda2a9249c50ba6f96",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"private": false,
|
|
8
8
|
"license": "AGPL-3.0-only",
|
package/paths.js
CHANGED
|
@@ -6,7 +6,7 @@ import { join } from "node:path";
|
|
|
6
6
|
// package.json
|
|
7
7
|
var package_default = {
|
|
8
8
|
name: "@mikka/daemon",
|
|
9
|
-
version: "0.0.
|
|
9
|
+
version: "0.0.145",
|
|
10
10
|
description: "Local Mikka daemon: runs agents through the user's own CLIs",
|
|
11
11
|
type: "module",
|
|
12
12
|
private: true,
|
|
@@ -66,7 +66,7 @@ var package_default = {
|
|
|
66
66
|
engines: {
|
|
67
67
|
node: ">=24"
|
|
68
68
|
},
|
|
69
|
-
gitHead: "
|
|
69
|
+
gitHead: "f4c4f818ea1d78fd81b298bda2a9249c50ba6f96"
|
|
70
70
|
};
|
|
71
71
|
|
|
72
72
|
// src/paths.ts
|
package/sbom.cdx.json
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
"$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json",
|
|
3
3
|
"bomFormat": "CycloneDX",
|
|
4
4
|
"specVersion": "1.5",
|
|
5
|
-
"serialNumber": "urn:uuid:
|
|
5
|
+
"serialNumber": "urn:uuid:8102bd92-ce90-46f0-9b6a-4ea5db0808b1",
|
|
6
6
|
"version": 1,
|
|
7
7
|
"metadata": {
|
|
8
|
-
"timestamp": "2026-11-
|
|
8
|
+
"timestamp": "2026-11-01T06:03:29.029Z",
|
|
9
9
|
"lifecycles": [
|
|
10
10
|
{
|
|
11
11
|
"phase": "pre-build"
|
|
@@ -19,13 +19,13 @@
|
|
|
19
19
|
}
|
|
20
20
|
],
|
|
21
21
|
"component": {
|
|
22
|
-
"bom-ref": "@aspectlylabs/mikka@0.0.
|
|
22
|
+
"bom-ref": "@aspectlylabs/mikka@0.0.145",
|
|
23
23
|
"type": "library",
|
|
24
|
-
"name": ".retained-build-
|
|
25
|
-
"version": "0.0.
|
|
24
|
+
"name": ".retained-build-ZjUf7M",
|
|
25
|
+
"version": "0.0.145",
|
|
26
26
|
"scope": "required",
|
|
27
27
|
"description": "Local Mikka daemon: runs agents through the user's own CLIs",
|
|
28
|
-
"purl": "pkg:npm/%40aspectlylabs/mikka@0.0.
|
|
28
|
+
"purl": "pkg:npm/%40aspectlylabs/mikka@0.0.145",
|
|
29
29
|
"properties": [],
|
|
30
30
|
"externalReferences": [
|
|
31
31
|
{
|
|
@@ -4627,7 +4627,7 @@
|
|
|
4627
4627
|
],
|
|
4628
4628
|
"dependencies": [
|
|
4629
4629
|
{
|
|
4630
|
-
"ref": "@aspectlylabs/mikka@0.0.
|
|
4630
|
+
"ref": "@aspectlylabs/mikka@0.0.145",
|
|
4631
4631
|
"dependsOn": [
|
|
4632
4632
|
"@agentclientprotocol/sdk@1.9.0",
|
|
4633
4633
|
"@anthropic-ai/claude-agent-sdk@0.3.305",
|