openmausbot 0.1.79 → 0.1.80
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/assets/index-Cu8BkIfo.js +305 -0
- package/dist/assets/{index-C2Je5jdF.js → index-D6RZKWks.js} +1 -1
- package/dist/assets/index-tfpeJAIG.css +1 -0
- package/dist/index.html +2 -2
- package/dist-server/drivers/agents-proxy.js +21 -6
- package/dist-server/index.js +988 -544
- package/dist-server/openmausbot.js +170 -85
- package/dist-server/pair-cli.js +170 -85
- package/dist-server/server/drivers/agents-proxy.js +27 -2
- package/dist-server/server/drivers/claude.js +55 -62
- package/dist-server/server/drivers/codex.js +158 -46
- package/dist-server/server/harness/registry.js +2 -2
- package/dist-server/server/index.js +203 -12
- package/dist-server/server/managed-desktop.js +205 -0
- package/dist-server/server/model-context-window.js +20 -0
- package/dist-server/server/redact.js +1 -0
- package/dist-server/server/room-handoffs.js +16 -6
- package/dist-server/server/store.js +13 -1
- package/package.json +1 -1
- package/dist/assets/index-D_TFZLlo.js +0 -305
- package/dist/assets/index-Pbb6Ao0s.css +0 -1
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// The model's window, when the driver did not say. A conservative pattern
|
|
2
|
+
// table over the model id: a wrong window would put a wrong percentage next
|
|
3
|
+
// to the context figure, so unknown models get no window and the chip shows
|
|
4
|
+
// the absolute count alone.
|
|
5
|
+
export function modelContextWindow(model) {
|
|
6
|
+
if (!model)
|
|
7
|
+
return undefined;
|
|
8
|
+
const id = model.toLowerCase();
|
|
9
|
+
if (/claude/.test(id) || /^(opus|sonnet|haiku|fable)\b/.test(id))
|
|
10
|
+
return /\[1m\]|-1m\b|1m-context/.test(id) ? 1_000_000 : 200_000;
|
|
11
|
+
if (/^(gpt-5|o[34]\b|codex)/.test(id))
|
|
12
|
+
return 272_000;
|
|
13
|
+
if (id.startsWith("gpt-4.1"))
|
|
14
|
+
return 1_000_000;
|
|
15
|
+
if (/gemini/.test(id))
|
|
16
|
+
return 1_000_000;
|
|
17
|
+
if (id.startsWith("grok"))
|
|
18
|
+
return 256_000;
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
@@ -34,6 +34,7 @@ const mask = (value) => (REDACTION_MARKER.test(value) ? value : `«redacted ${va
|
|
|
34
34
|
// generic "long hex/base64" heuristic would rewrite real code in the
|
|
35
35
|
// transcript, so only shapes that are unmistakably credentials match.
|
|
36
36
|
const KEY_PREFIXES = [
|
|
37
|
+
/\bom[dg]_[A-Za-z0-9_-]{43}(?![A-Za-z0-9_-])/g, // desktop device and model-only credentials
|
|
37
38
|
/\bsk-(?:ant-|proj-|live-|test-)?[A-Za-z0-9_-]{16,}/g, // anthropic / openai / stripe
|
|
38
39
|
/\bxai-[A-Za-z0-9_-]{20,}/g, // xai (grok)
|
|
39
40
|
/\bgsk_[A-Za-z0-9]{40,}/g, // groq
|
|
@@ -12,7 +12,7 @@ const nodeSchema = z.object({
|
|
|
12
12
|
approvalGranted: z.boolean().default(false),
|
|
13
13
|
kind: z.enum(["work", "assignment"]).default("work"),
|
|
14
14
|
});
|
|
15
|
-
export const ROOM_HANDOFF_LIMITS = { depth: 4, requests: 24, executions: 48, lifetimeMs: 30 * 60_000, minRunwayMs: 10 * 60_000 };
|
|
15
|
+
export const ROOM_HANDOFF_LIMITS = { depth: 4, requests: 24, executions: 48, lifetimeMs: 30 * 60_000, minRunwayMs: 10 * 60_000, queueMs: 60 * 60_000 };
|
|
16
16
|
/** Renders elapsed milliseconds as whole minutes, or seconds under one minute. */
|
|
17
17
|
const duration = (ms) => ms >= 60_000 ? `${Math.floor(ms / 60_000)}m` : `${Math.floor(ms / 1000)}s`;
|
|
18
18
|
const terminal = (n) => ["completed", "failed", "cancelled"].includes(n.status);
|
|
@@ -68,10 +68,14 @@ export class RoomHandoffs {
|
|
|
68
68
|
return path;
|
|
69
69
|
}
|
|
70
70
|
/** The earliest moment this node may be failed for lifetime: the tree
|
|
71
|
-
* ceiling
|
|
71
|
+
* ceiling, a running node's own start plus a minimum runway, or, for work
|
|
72
|
+
* parked in a busy teammate's queue, its own queue window (#1238). */
|
|
72
73
|
deadline(n) {
|
|
73
74
|
const anchor = n.status === "running" ? n.startedAt ?? n.createdAt : n.createdAt;
|
|
74
|
-
|
|
75
|
+
const ceiling = n.status === "queued" && n.executions === 0
|
|
76
|
+
? anchor + ROOM_HANDOFF_LIMITS.queueMs
|
|
77
|
+
: this.root(n).createdAt + ROOM_HANDOFF_LIMITS.lifetimeMs;
|
|
78
|
+
return Math.max(ceiling, anchor + ROOM_HANDOFF_LIMITS.minRunwayMs);
|
|
75
79
|
}
|
|
76
80
|
/** An ancestor past its ceiling is not failed while a descendant is still
|
|
77
81
|
* running inside its own runway; cancelling would cascade into that work. */
|
|
@@ -79,17 +83,23 @@ export class RoomHandoffs {
|
|
|
79
83
|
return this.children(n.id).some(c => !terminal(c) && ((c.status === "running" && this.now() <= this.deadline(c)) || this.protectsRunner(c)));
|
|
80
84
|
}
|
|
81
85
|
/** A parent still owes the follow-up execution that decides on its
|
|
82
|
-
* children's results; the ceiling defers to that execution's own runway.
|
|
86
|
+
* children's results; the ceiling defers to that execution's own runway.
|
|
87
|
+
* A child parked in a queue has produced nothing to decide on yet. */
|
|
83
88
|
owesFollowUp(n) {
|
|
84
89
|
if (n.status === "resume")
|
|
85
90
|
return true;
|
|
86
91
|
if (n.status !== "waiting")
|
|
87
92
|
return false;
|
|
88
93
|
const children = this.children(n.id);
|
|
89
|
-
return (children.length > 0 && children.every(c => terminal(c))) ||
|
|
94
|
+
return (children.length > 0 && children.every(c => terminal(c))) ||
|
|
95
|
+
children.some(c => this.owesFollowUp(c) || (c.status === "queued" && c.executions === 0));
|
|
90
96
|
}
|
|
91
|
-
/** Names the budget, the node's status, and the elapsed
|
|
97
|
+
/** Names the budget, the node's status, and the elapsed time. Work that
|
|
98
|
+
* never started reports the queue window it waited out, not the tree's. */
|
|
92
99
|
lifetimeError(n) {
|
|
100
|
+
if (n.status === "queued" && n.executions === 0) {
|
|
101
|
+
return `Room handoff queue budget exhausted: never started while waiting for a busy teammate after ${duration(this.now() - n.createdAt)} of the ${duration(ROOM_HANDOFF_LIMITS.queueMs)} queue window`;
|
|
102
|
+
}
|
|
93
103
|
return `Room handoff lifetime budget exhausted: node was ${n.status} after ${duration(this.now() - this.root(n).createdAt)} of the ${duration(ROOM_HANDOFF_LIMITS.lifetimeMs)} tree lifetime`;
|
|
94
104
|
}
|
|
95
105
|
enqueue(source, generation, parentId, target, key, text, approvalGranted = false, rework = false, sourceText = "") {
|
|
@@ -26,7 +26,7 @@ export function isProjectEmoji(value) {
|
|
|
26
26
|
}
|
|
27
27
|
const TASK_PATCH_FIELDS = [
|
|
28
28
|
"title", "projectId", "modelSelection", "approvalMode", "autoApprove", "alwaysAllow",
|
|
29
|
-
"unread", "rewound", "pinnedMessageId", "resumeCursors", "lastInstanceId", "cwd",
|
|
29
|
+
"unread", "rewound", "archivedAt", "pinnedMessageId", "resumeCursors", "lastInstanceId", "cwd",
|
|
30
30
|
"routineRunId",
|
|
31
31
|
];
|
|
32
32
|
/** Everything the BOT authored is scrubbed of content-shaped secrets before
|
|
@@ -1485,12 +1485,24 @@ export class Store {
|
|
|
1485
1485
|
const turnInput = clean(turn.input);
|
|
1486
1486
|
const nextCachedInput = Math.min(clean(prev.cachedInput), prevInput)
|
|
1487
1487
|
+ Math.min(clean(turn.cachedInput), turnInput);
|
|
1488
|
+
const contextTokens = clean(turn.context?.tokens);
|
|
1489
|
+
const contextWindow = clean(turn.context?.window);
|
|
1488
1490
|
task.usage = {
|
|
1489
1491
|
input: prevInput + turnInput,
|
|
1490
1492
|
output: prev.output + clean(turn.output),
|
|
1491
1493
|
...(cachedKnown ? { cachedInput: nextCachedInput } : {}),
|
|
1492
1494
|
costUsd: cost === null ? prevCost : (prevCost ?? 0) + cost,
|
|
1493
1495
|
turns: prev.turns + 1,
|
|
1496
|
+
lastTurn: {
|
|
1497
|
+
input: turnInput, output: clean(turn.output),
|
|
1498
|
+
...(typeof turn.cachedInput === "number" ? { cachedInput: Math.min(clean(turn.cachedInput), turnInput) } : {}),
|
|
1499
|
+
costUsd: cost,
|
|
1500
|
+
},
|
|
1501
|
+
// a turn that reported no context keeps the previous reading rather
|
|
1502
|
+
// than pretending the window emptied
|
|
1503
|
+
...(contextTokens > 0
|
|
1504
|
+
? { context: { tokens: contextTokens, ...(contextWindow > 0 ? { window: contextWindow } : {}) } }
|
|
1505
|
+
: prev.context ? { context: prev.context } : {}),
|
|
1494
1506
|
};
|
|
1495
1507
|
this.saveBots();
|
|
1496
1508
|
this.emit({ type: "bot", botId });
|