orkestrator 2.35.0-beta → 2.35.1-beta
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/client.js +1 -1
- package/dist/main.js +265 -92
- package/package.json +3 -3
- package/resources/acp-bridge/dist/index.js +24 -6
package/dist/client.js
CHANGED
|
@@ -8334,7 +8334,7 @@ import path5 from "path";
|
|
|
8334
8334
|
// ../../apps/backend/package.json
|
|
8335
8335
|
var package_default = {
|
|
8336
8336
|
name: "@orkestrator/backend",
|
|
8337
|
-
version: "2.35.
|
|
8337
|
+
version: "2.35.1-beta",
|
|
8338
8338
|
private: true,
|
|
8339
8339
|
type: "module",
|
|
8340
8340
|
exports: {
|
package/dist/main.js
CHANGED
|
@@ -7238,7 +7238,7 @@ var package_default;
|
|
|
7238
7238
|
var init_package = __esm(() => {
|
|
7239
7239
|
package_default = {
|
|
7240
7240
|
name: "@orkestrator/backend",
|
|
7241
|
-
version: "2.35.
|
|
7241
|
+
version: "2.35.1-beta",
|
|
7242
7242
|
private: true,
|
|
7243
7243
|
type: "module",
|
|
7244
7244
|
exports: {
|
|
@@ -11594,6 +11594,7 @@ class StorageDatabase {
|
|
|
11594
11594
|
}
|
|
11595
11595
|
const update = mutate(current);
|
|
11596
11596
|
let document2 = header.document;
|
|
11597
|
+
let nextRow = null;
|
|
11597
11598
|
if (update.delete) {
|
|
11598
11599
|
if (!existing)
|
|
11599
11600
|
return update.result;
|
|
@@ -11613,6 +11614,7 @@ class StorageDatabase {
|
|
|
11613
11614
|
VALUES (?, ?, ?, ?, ?, ?)
|
|
11614
11615
|
ON CONFLICT (store, collection, key) DO UPDATE SET
|
|
11615
11616
|
owner = excluded.owner, value = excluded.value`).run(store, collection, key, position, owner ?? null, value);
|
|
11617
|
+
nextRow = { collection, key, position, value };
|
|
11616
11618
|
if (collection && document2 !== null) {
|
|
11617
11619
|
const envelope = JSON.parse(document2);
|
|
11618
11620
|
if (envelope[collection] !== STORAGE_COLLECTION_MARKER) {
|
|
@@ -11625,7 +11627,17 @@ class StorageDatabase {
|
|
|
11625
11627
|
}
|
|
11626
11628
|
const revision = header.revision + 1;
|
|
11627
11629
|
this.db.query("UPDATE stores SET revision = ?, document = ?, updated_at = ? WHERE name = ?").run(revision, document2, Date.now(), store);
|
|
11628
|
-
this.
|
|
11630
|
+
const cached = this.pendingCache?.has(store) ? this.pendingCache.get(store) : this.cache.get(store);
|
|
11631
|
+
if (cached?.revision === header.revision && cached.mode === "rows") {
|
|
11632
|
+
const rows = new Map(cached.rows);
|
|
11633
|
+
if (nextRow)
|
|
11634
|
+
rows.set(rowId(collection, key), nextRow);
|
|
11635
|
+
else
|
|
11636
|
+
rows.delete(rowId(collection, key));
|
|
11637
|
+
this.setCache(store, { ...cached, revision, document: document2, rows });
|
|
11638
|
+
} else {
|
|
11639
|
+
this.setCache(store, null);
|
|
11640
|
+
}
|
|
11629
11641
|
return update.result;
|
|
11630
11642
|
});
|
|
11631
11643
|
}
|
|
@@ -13555,6 +13567,12 @@ class StorageContext {
|
|
|
13555
13567
|
throw error;
|
|
13556
13568
|
}
|
|
13557
13569
|
}
|
|
13570
|
+
storeHeldAsDocument(filePath) {
|
|
13571
|
+
const store = this.storeForFile(filePath);
|
|
13572
|
+
if (store === null)
|
|
13573
|
+
throw new Error("storeHeldAsDocument requires a database store");
|
|
13574
|
+
return this.database.readStoreHeader(store)?.mode === "document";
|
|
13575
|
+
}
|
|
13558
13576
|
loadStoreSerialized(filePath) {
|
|
13559
13577
|
const store = this.storeForFile(filePath);
|
|
13560
13578
|
if (store === null)
|
|
@@ -24321,7 +24339,8 @@ class DraftsRepository {
|
|
|
24321
24339
|
async getComposeDraft(draftKey) {
|
|
24322
24340
|
if (!isNonBlankString(draftKey))
|
|
24323
24341
|
throw new Error("Compose draft key must not be blank");
|
|
24324
|
-
|
|
24342
|
+
const stored = this.context.loadStoreRow(this.files.composeDraftsFile(), draftKey);
|
|
24343
|
+
return isPersistedComposeDraft(stored, draftKey) ? stored : null;
|
|
24325
24344
|
}
|
|
24326
24345
|
async listComposeDrafts(ownerType, ownerId) {
|
|
24327
24346
|
if (ownerType !== "environment" && ownerType !== "project") {
|
|
@@ -24675,8 +24694,8 @@ class DraftsRepository {
|
|
|
24675
24694
|
});
|
|
24676
24695
|
}
|
|
24677
24696
|
async getSession(sessionId) {
|
|
24678
|
-
const
|
|
24679
|
-
return
|
|
24697
|
+
const stored = this.context.loadStoreRow(this.files.sessionsFile(), sessionId);
|
|
24698
|
+
return isRecord6(stored) && stored.id === sessionId ? stored : null;
|
|
24680
24699
|
}
|
|
24681
24700
|
async getSessionsByEnvironment(environmentId) {
|
|
24682
24701
|
const sessions = this.context.loadStoreRowsByOwner(this.files.sessionsFile(), environmentId);
|
|
@@ -43989,17 +44008,25 @@ class NativeAgentSessionsRepository {
|
|
|
43989
44008
|
});
|
|
43990
44009
|
}
|
|
43991
44010
|
assertReadableNativeAgentSession(loaded, key) {
|
|
43992
|
-
if (key in loaded.opaque)
|
|
43993
|
-
throw new Error(
|
|
43994
|
-
}
|
|
44011
|
+
if (key in loaded.opaque)
|
|
44012
|
+
throw new Error(UNREADABLE_NATIVE_SESSION);
|
|
43995
44013
|
}
|
|
43996
44014
|
async getNativeAgentSession(key) {
|
|
43997
44015
|
if (!isNonBlankString(key)) {
|
|
43998
44016
|
throw new Error("Native agent session key must not be blank");
|
|
43999
44017
|
}
|
|
44000
|
-
const
|
|
44001
|
-
this.
|
|
44002
|
-
|
|
44018
|
+
const file = this.files.nativeAgentSessionsFile();
|
|
44019
|
+
const stored = this.context.loadStoreRow(file, key);
|
|
44020
|
+
if (stored === undefined) {
|
|
44021
|
+
if (!this.context.storeHeldAsDocument(file))
|
|
44022
|
+
return null;
|
|
44023
|
+
const loaded = await this.loadNativeAgentSessions();
|
|
44024
|
+
this.assertReadableNativeAgentSession(loaded, key);
|
|
44025
|
+
return loaded.sessions[key] ?? null;
|
|
44026
|
+
}
|
|
44027
|
+
if (!isPersistedNativeAgentSession(stored, key))
|
|
44028
|
+
throw new Error(UNREADABLE_NATIVE_SESSION);
|
|
44029
|
+
return stored;
|
|
44003
44030
|
}
|
|
44004
44031
|
async getNativeAgentSessionAfterMutations(key) {
|
|
44005
44032
|
return this.enqueueNativeAgentSessionMutation(key, () => this.getNativeAgentSession(key));
|
|
@@ -44543,6 +44570,7 @@ class NativeAgentSessionsRepository {
|
|
|
44543
44570
|
return environment;
|
|
44544
44571
|
}
|
|
44545
44572
|
}
|
|
44573
|
+
var UNREADABLE_NATIVE_SESSION = "Stored native agent session metadata is invalid or uses an unsupported version";
|
|
44546
44574
|
var init_storage_native = __esm(() => {
|
|
44547
44575
|
init_native_agent_session_controls();
|
|
44548
44576
|
init_models();
|
|
@@ -46206,6 +46234,14 @@ class PromptQueueStore {
|
|
|
46206
46234
|
}
|
|
46207
46235
|
return added.length === 0 ? existing : [...existing, ...added].slice(-64);
|
|
46208
46236
|
}
|
|
46237
|
+
loadPromptQueue(queueKey) {
|
|
46238
|
+
const stored = this.context.loadStoreRow(this.files.promptQueuesFile(), queueKey);
|
|
46239
|
+
if (stored === undefined)
|
|
46240
|
+
return null;
|
|
46241
|
+
const restored = restoreLegacyPromptQueueClaims({ [queueKey]: stored });
|
|
46242
|
+
const queue = restored[queueKey];
|
|
46243
|
+
return isPersistedPromptQueue(queue, queueKey) ? queue : null;
|
|
46244
|
+
}
|
|
46209
46245
|
async loadPromptQueues() {
|
|
46210
46246
|
const stored = await this.context.loadJson(this.files.promptQueuesFile(), () => ({}));
|
|
46211
46247
|
return Object.fromEntries(Object.entries(restoreLegacyPromptQueueClaims(stored)).filter(([storedKey, queue]) => isPersistedPromptQueue(queue, storedKey)));
|
|
@@ -47033,6 +47069,18 @@ function parseWorktreeMoveRecord(value) {
|
|
|
47033
47069
|
startedAt: value.startedAt
|
|
47034
47070
|
};
|
|
47035
47071
|
}
|
|
47072
|
+
function normalizeStoredEnvironment(environment) {
|
|
47073
|
+
environment.setupPhase ??= environment.setupScriptsComplete ? "ready" : "pending";
|
|
47074
|
+
environment.setupOverride ??= false;
|
|
47075
|
+
const migrated = migrateEnvironmentAgentSettings(environment);
|
|
47076
|
+
if (isEmptyAgentSettings(migrated))
|
|
47077
|
+
delete environment.agentSettings;
|
|
47078
|
+
else
|
|
47079
|
+
environment.agentSettings = migrated;
|
|
47080
|
+
for (const key of LEGACY_ENVIRONMENT_AGENT_KEYS) {
|
|
47081
|
+
delete environment[key];
|
|
47082
|
+
}
|
|
47083
|
+
}
|
|
47036
47084
|
|
|
47037
47085
|
class ProjectsRepository {
|
|
47038
47086
|
context;
|
|
@@ -47173,18 +47221,8 @@ class ProjectsRepository {
|
|
|
47173
47221
|
}
|
|
47174
47222
|
async loadEnvironments() {
|
|
47175
47223
|
const environments = await this.context.loadJsonCached(this.files.environmentsFile(), () => []);
|
|
47176
|
-
for (const environment of environments)
|
|
47177
|
-
environment
|
|
47178
|
-
environment.setupOverride ??= false;
|
|
47179
|
-
const migrated = migrateEnvironmentAgentSettings(environment);
|
|
47180
|
-
if (isEmptyAgentSettings(migrated))
|
|
47181
|
-
delete environment.agentSettings;
|
|
47182
|
-
else
|
|
47183
|
-
environment.agentSettings = migrated;
|
|
47184
|
-
for (const key of LEGACY_ENVIRONMENT_AGENT_KEYS) {
|
|
47185
|
-
delete environment[key];
|
|
47186
|
-
}
|
|
47187
|
-
}
|
|
47224
|
+
for (const environment of environments)
|
|
47225
|
+
normalizeStoredEnvironment(environment);
|
|
47188
47226
|
return environments.sort((a, b) => a.order - b.order);
|
|
47189
47227
|
}
|
|
47190
47228
|
async saveEnvironments(environments, options2 = {}) {
|
|
@@ -47208,7 +47246,12 @@ class ProjectsRepository {
|
|
|
47208
47246
|
return (await this.loadEnvironments()).filter((environment) => environment.projectId === projectId);
|
|
47209
47247
|
}
|
|
47210
47248
|
async getEnvironment(environmentId) {
|
|
47211
|
-
|
|
47249
|
+
const stored = this.context.loadStoreRow(this.files.environmentsFile(), environmentId);
|
|
47250
|
+
if (!isRecord6(stored) || stored.id !== environmentId)
|
|
47251
|
+
return null;
|
|
47252
|
+
const environment = stored;
|
|
47253
|
+
normalizeStoredEnvironment(environment);
|
|
47254
|
+
return environment;
|
|
47212
47255
|
}
|
|
47213
47256
|
projectRemovalFencesFile() {
|
|
47214
47257
|
return this.context.file("project-removal-fences.json");
|
|
@@ -48136,7 +48179,7 @@ class PromptsRepository {
|
|
|
48136
48179
|
if (!isNonBlankString(queueKey)) {
|
|
48137
48180
|
throw new Error("Prompt queue key must not be blank");
|
|
48138
48181
|
}
|
|
48139
|
-
return
|
|
48182
|
+
return this.repos.promptQueues.loadPromptQueue(queueKey);
|
|
48140
48183
|
}
|
|
48141
48184
|
async listPromptQueues(environmentId) {
|
|
48142
48185
|
if (!isNonBlankString(environmentId)) {
|
|
@@ -52535,8 +52578,8 @@ class SessionsRepository {
|
|
|
52535
52578
|
return session;
|
|
52536
52579
|
}
|
|
52537
52580
|
async getPaneLayout(environmentId) {
|
|
52538
|
-
const
|
|
52539
|
-
return
|
|
52581
|
+
const stored = this.context.loadStoreRow(this.files.paneLayoutsFile(), environmentId);
|
|
52582
|
+
return stored === undefined ? null : stored;
|
|
52540
52583
|
}
|
|
52541
52584
|
async removeMultiReviewTabs(environmentId, workflowId) {
|
|
52542
52585
|
return this.enqueuePaneLayoutMutation(async () => {
|
|
@@ -57469,7 +57512,14 @@ function executionFromState(state) {
|
|
|
57469
57512
|
};
|
|
57470
57513
|
}
|
|
57471
57514
|
async function stopEnvironmentExecWorkers(environmentId, context, options2 = {}) {
|
|
57472
|
-
|
|
57515
|
+
try {
|
|
57516
|
+
await stopGoalCheckWorkers(environmentId, context);
|
|
57517
|
+
} catch (error) {
|
|
57518
|
+
const environment = await context.storage.getEnvironment(environmentId);
|
|
57519
|
+
if (options2.requireStopped || environment?.environmentType === "local")
|
|
57520
|
+
throw error;
|
|
57521
|
+
console.warn(`[public-api] Could not stop goal checks: ${boundedMessage(error)}`);
|
|
57522
|
+
}
|
|
57473
57523
|
if (typeof context.storage.publicOperations?.listActivePublicOperations !== "function")
|
|
57474
57524
|
return;
|
|
57475
57525
|
const environment = await context.storage.getEnvironment(environmentId);
|
|
@@ -61862,11 +61912,13 @@ function parseGatewayEventData(data) {
|
|
|
61862
61912
|
return null;
|
|
61863
61913
|
return { event: parsed.event, payload: parsed.payload };
|
|
61864
61914
|
}
|
|
61865
|
-
function
|
|
61866
|
-
|
|
61867
|
-
|
|
61868
|
-
|
|
61869
|
-
|
|
61915
|
+
function isHighSurrogate(code) {
|
|
61916
|
+
return code >= 55296 && code <= 56319;
|
|
61917
|
+
}
|
|
61918
|
+
function isLowSurrogate(code) {
|
|
61919
|
+
return code >= 56320 && code <= 57343;
|
|
61920
|
+
}
|
|
61921
|
+
function utf8Bytes4(value, limit = Number.POSITIVE_INFINITY) {
|
|
61870
61922
|
let bytes = 0;
|
|
61871
61923
|
for (let index = 0;index < value.length; index += 1) {
|
|
61872
61924
|
const code = value.charCodeAt(index);
|
|
@@ -61874,25 +61926,30 @@ function exceedsUtf8Bytes(value, maxBytes) {
|
|
|
61874
61926
|
bytes += 1;
|
|
61875
61927
|
else if (code <= 2047)
|
|
61876
61928
|
bytes += 2;
|
|
61877
|
-
else if (code
|
|
61878
|
-
|
|
61879
|
-
|
|
61880
|
-
bytes += 4;
|
|
61881
|
-
index += 1;
|
|
61882
|
-
} else {
|
|
61883
|
-
bytes += 3;
|
|
61884
|
-
}
|
|
61929
|
+
else if (isHighSurrogate(code) && isLowSurrogate(value.charCodeAt(index + 1))) {
|
|
61930
|
+
bytes += 4;
|
|
61931
|
+
index += 1;
|
|
61885
61932
|
} else
|
|
61886
61933
|
bytes += 3;
|
|
61887
|
-
if (bytes >
|
|
61888
|
-
return
|
|
61934
|
+
if (bytes > limit)
|
|
61935
|
+
return bytes;
|
|
61889
61936
|
}
|
|
61890
|
-
return
|
|
61937
|
+
return bytes;
|
|
61938
|
+
}
|
|
61939
|
+
function exceedsUtf8Bytes(value, maxBytes) {
|
|
61940
|
+
if (value.length > maxBytes)
|
|
61941
|
+
return true;
|
|
61942
|
+
if (value.length * 3 <= maxBytes)
|
|
61943
|
+
return false;
|
|
61944
|
+
return utf8Bytes4(value, maxBytes) > maxBytes;
|
|
61891
61945
|
}
|
|
61892
61946
|
|
|
61893
61947
|
class SseFrameDecoder {
|
|
61894
61948
|
maxFrameBytes;
|
|
61895
|
-
|
|
61949
|
+
chunks = [];
|
|
61950
|
+
pendingLength = 0;
|
|
61951
|
+
pendingBytes = 0;
|
|
61952
|
+
tail = "";
|
|
61896
61953
|
constructor(maxFrameBytes = MAX_GATEWAY_EVENT_FRAME_BYTES) {
|
|
61897
61954
|
this.maxFrameBytes = maxFrameBytes;
|
|
61898
61955
|
if (!Number.isSafeInteger(maxFrameBytes) || maxFrameBytes < 1) {
|
|
@@ -61900,19 +61957,39 @@ class SseFrameDecoder {
|
|
|
61900
61957
|
}
|
|
61901
61958
|
}
|
|
61902
61959
|
push(chunk) {
|
|
61903
|
-
this.
|
|
61960
|
+
if (!/\r?\n\r?\n/.test(this.tail + chunk)) {
|
|
61961
|
+
this.pendingBytes += utf8Bytes4(chunk);
|
|
61962
|
+
if (isHighSurrogate(this.tail.charCodeAt(this.tail.length - 1))) {
|
|
61963
|
+
if (isLowSurrogate(chunk.charCodeAt(0)))
|
|
61964
|
+
this.pendingBytes -= 2;
|
|
61965
|
+
}
|
|
61966
|
+
this.chunks.push(chunk);
|
|
61967
|
+
this.pendingLength += chunk.length;
|
|
61968
|
+
this.tail = (this.tail + chunk).slice(-MAX_SPLIT_BOUNDARY_PREFIX);
|
|
61969
|
+
if (this.pendingBytes > this.maxFrameBytes) {
|
|
61970
|
+
throw new GatewayEventFrameTooLargeError(this.maxFrameBytes);
|
|
61971
|
+
}
|
|
61972
|
+
return [];
|
|
61973
|
+
}
|
|
61974
|
+
const text = this.chunks.join("") + chunk;
|
|
61975
|
+
const boundary = /\r?\n\r?\n/g;
|
|
61976
|
+
boundary.lastIndex = this.pendingLength - this.tail.length;
|
|
61904
61977
|
const frames = [];
|
|
61905
|
-
let
|
|
61906
|
-
|
|
61907
|
-
const block =
|
|
61908
|
-
|
|
61978
|
+
let start = 0;
|
|
61979
|
+
for (let match = boundary.exec(text);match; match = boundary.exec(text)) {
|
|
61980
|
+
const block = text.slice(start, match.index);
|
|
61981
|
+
start = match.index + match[0].length;
|
|
61909
61982
|
if (exceedsUtf8Bytes(block, this.maxFrameBytes)) {
|
|
61910
61983
|
throw new GatewayEventFrameTooLargeError(this.maxFrameBytes);
|
|
61911
61984
|
}
|
|
61912
61985
|
frames.push(parseSseBlock(block));
|
|
61913
|
-
boundary = /\r?\n\r?\n/.exec(this.pending);
|
|
61914
61986
|
}
|
|
61915
|
-
|
|
61987
|
+
const remainder = text.slice(start);
|
|
61988
|
+
this.chunks = remainder ? [remainder] : [];
|
|
61989
|
+
this.pendingLength = remainder.length;
|
|
61990
|
+
this.pendingBytes = utf8Bytes4(remainder);
|
|
61991
|
+
this.tail = remainder.slice(-MAX_SPLIT_BOUNDARY_PREFIX);
|
|
61992
|
+
if (this.pendingBytes > this.maxFrameBytes) {
|
|
61916
61993
|
throw new GatewayEventFrameTooLargeError(this.maxFrameBytes);
|
|
61917
61994
|
}
|
|
61918
61995
|
return frames;
|
|
@@ -61980,7 +62057,7 @@ class GatewayEventStreamState {
|
|
|
61980
62057
|
return { kind: "event", event: parsed.event, payload: parsed.payload };
|
|
61981
62058
|
}
|
|
61982
62059
|
}
|
|
61983
|
-
var NATIVE_EVENT_STREAM_CONNECTED_EVENT = "native-event-stream-connected", TERMINAL_EVENT_STREAM_CONNECTED_EVENT = "terminal-event-stream-connected", GATEWAY_CONNECTED_EVENT = "gateway.connected", GATEWAY_RECONCILE_REQUIRED_EVENT = "gateway.reconcile-required", GATEWAY_CURSOR_EVENT = "gateway.cursor", GATEWAY_EVENT_CURSOR_PARAM = "since", GATEWAY_KEEPALIVE_EVENTS_PARAM = "keepaliveEvents", GATEWAY_KEEPALIVE_EVENT = "gateway.keepalive", MAX_GATEWAY_EVENT_FRAME_BYTES, GatewayEventFrameTooLargeError;
|
|
62060
|
+
var NATIVE_EVENT_STREAM_CONNECTED_EVENT = "native-event-stream-connected", TERMINAL_EVENT_STREAM_CONNECTED_EVENT = "terminal-event-stream-connected", GATEWAY_CONNECTED_EVENT = "gateway.connected", GATEWAY_RECONCILE_REQUIRED_EVENT = "gateway.reconcile-required", GATEWAY_CURSOR_EVENT = "gateway.cursor", GATEWAY_EVENT_CURSOR_PARAM = "since", GATEWAY_KEEPALIVE_EVENTS_PARAM = "keepaliveEvents", GATEWAY_KEEPALIVE_EVENT = "gateway.keepalive", MAX_GATEWAY_EVENT_FRAME_BYTES, GatewayEventFrameTooLargeError, MAX_SPLIT_BOUNDARY_PREFIX = 3;
|
|
61984
62061
|
var init_gateway_event_stream = __esm(() => {
|
|
61985
62062
|
MAX_GATEWAY_EVENT_FRAME_BYTES = 8 * 1024 * 1024;
|
|
61986
62063
|
GatewayEventFrameTooLargeError = class GatewayEventFrameTooLargeError extends Error {
|
|
@@ -101206,7 +101283,7 @@ class WebAnnotationToolLimiter {
|
|
|
101206
101283
|
}
|
|
101207
101284
|
}
|
|
101208
101285
|
}
|
|
101209
|
-
function
|
|
101286
|
+
function utf8Bytes5(value) {
|
|
101210
101287
|
return Buffer.byteLength(value, "utf8");
|
|
101211
101288
|
}
|
|
101212
101289
|
function success2(value) {
|
|
@@ -101308,11 +101385,11 @@ function boundedEvidence(value) {
|
|
|
101308
101385
|
entries,
|
|
101309
101386
|
truncated
|
|
101310
101387
|
});
|
|
101311
|
-
while (
|
|
101388
|
+
while (utf8Bytes5(serialize()) > MAX_EVIDENCE_RESPONSE_BYTES2 && entries.length > 0) {
|
|
101312
101389
|
entries.pop();
|
|
101313
101390
|
truncated = true;
|
|
101314
101391
|
}
|
|
101315
|
-
if (
|
|
101392
|
+
if (utf8Bytes5(serialize()) > MAX_EVIDENCE_RESPONSE_BYTES2) {
|
|
101316
101393
|
return { ok: true, annotation: value.annotation, capture: null, entries: [], truncated: true };
|
|
101317
101394
|
}
|
|
101318
101395
|
return { ok: true, annotation: value.annotation, capture: value.capture, entries, truncated };
|
|
@@ -101333,7 +101410,7 @@ function registerWebAnnotationTools(server, host, scope, limiter) {
|
|
|
101333
101410
|
return await limiter.run(scope, async () => {
|
|
101334
101411
|
const { request, brief, latestResult } = await assigned(host, scope);
|
|
101335
101412
|
const summary = requestSummary(request, latestResult ?? null);
|
|
101336
|
-
const briefTruncated =
|
|
101413
|
+
const briefTruncated = utf8Bytes5(brief) > MAX_BRIEF_RESPONSE_BYTES;
|
|
101337
101414
|
return success2({
|
|
101338
101415
|
ok: true,
|
|
101339
101416
|
request: summary,
|
|
@@ -135283,10 +135360,10 @@ function terminalOutputPayload(data, revision, generation) {
|
|
|
135283
135360
|
function createTerminalOutputBuffer() {
|
|
135284
135361
|
return { chunks: [], headIndex: 0, headOffset: 0, length: 0 };
|
|
135285
135362
|
}
|
|
135286
|
-
function
|
|
135363
|
+
function isHighSurrogate2(codeUnit) {
|
|
135287
135364
|
return codeUnit >= 55296 && codeUnit <= 56319;
|
|
135288
135365
|
}
|
|
135289
|
-
function
|
|
135366
|
+
function isLowSurrogate2(codeUnit) {
|
|
135290
135367
|
return codeUnit >= 56320 && codeUnit <= 57343;
|
|
135291
135368
|
}
|
|
135292
135369
|
function trimOrphanedLowSurrogate(buffer) {
|
|
@@ -135295,11 +135372,11 @@ function trimOrphanedLowSurrogate(buffer) {
|
|
|
135295
135372
|
const head = buffer.chunks[buffer.headIndex];
|
|
135296
135373
|
if (head === undefined || buffer.length === 0)
|
|
135297
135374
|
return;
|
|
135298
|
-
if (!
|
|
135375
|
+
if (!isLowSurrogate2(head.charCodeAt(buffer.headOffset)))
|
|
135299
135376
|
return;
|
|
135300
135377
|
const previousChunk = buffer.chunks[buffer.headIndex - 1] ?? "";
|
|
135301
135378
|
const precedingCodeUnit = buffer.headOffset > 0 ? head.charCodeAt(buffer.headOffset - 1) : previousChunk.charCodeAt(previousChunk.length - 1);
|
|
135302
|
-
if (!
|
|
135379
|
+
if (!isHighSurrogate2(precedingCodeUnit))
|
|
135303
135380
|
return;
|
|
135304
135381
|
buffer.headOffset += 1;
|
|
135305
135382
|
buffer.length -= 1;
|
|
@@ -139823,6 +139900,9 @@ function toNodeProjectSummary(nodeId, raw, index) {
|
|
|
139823
139900
|
...icon ? { icon } : {}
|
|
139824
139901
|
};
|
|
139825
139902
|
}
|
|
139903
|
+
function isMailCount(value) {
|
|
139904
|
+
return typeof value === "number" && Number.isInteger(value) && value > 0 && value <= MAX_SUMMARY_MAIL_COUNT;
|
|
139905
|
+
}
|
|
139826
139906
|
function toNodeEnvironmentSummary(nodeId, raw, index = 0) {
|
|
139827
139907
|
if (typeof raw.id !== "string" || !raw.id || typeof raw.projectId !== "string")
|
|
139828
139908
|
return null;
|
|
@@ -139846,7 +139926,10 @@ function toNodeEnvironmentSummary(nodeId, raw, index = 0) {
|
|
|
139846
139926
|
deleting: raw.lifecycleOperation === "deleting" || typeof raw.deletionRequestedAt === "string" && raw.deletionRequestedAt.length > 0,
|
|
139847
139927
|
isProjectHome: raw.projectHome === true,
|
|
139848
139928
|
...raw.buildPipeline === true ? { buildPipeline: true } : {},
|
|
139929
|
+
...raw.buildActive === true ? { buildActive: true } : {},
|
|
139849
139930
|
...raw.autoMerge === true ? { autoMerge: true } : {},
|
|
139931
|
+
...isMailCount(raw.agentMailUnread) ? { agentMailUnread: raw.agentMailUnread } : {},
|
|
139932
|
+
...raw.agentMailFailed === true ? { agentMailFailed: true } : {},
|
|
139850
139933
|
...PR_STATES2.has(raw.prState) ? { prState: raw.prState } : {},
|
|
139851
139934
|
...typeof raw.hasMergeConflicts === "boolean" ? { prHasMergeConflicts: raw.hasMergeConflicts } : {},
|
|
139852
139935
|
...isPrMergeability(raw.prMergeability) ? { prMergeability: raw.prMergeability } : {},
|
|
@@ -139857,7 +139940,7 @@ function toNodeEnvironmentSummary(nodeId, raw, index = 0) {
|
|
|
139857
139940
|
...typeof raw.prViewerCanMerge === "boolean" ? { prViewerCanMerge: raw.prViewerCanMerge } : {}
|
|
139858
139941
|
};
|
|
139859
139942
|
}
|
|
139860
|
-
var NODE_SUMMARY_CHANGED_EVENT = "node-summary-changed", NODE_SUMMARY_ENVIRONMENT_READ_ARGS, MAX_SUMMARY_PROJECTS = 500, MAX_SUMMARY_ENVIRONMENTS_PER_PROJECT = 500, MAX_TEXT2 = 256, MAX_PATH_NAME = 128, MAX_TIMESTAMP = 64, PR_STATES2;
|
|
139943
|
+
var NODE_SUMMARY_CHANGED_EVENT = "node-summary-changed", NODE_SUMMARY_ENVIRONMENT_READ_ARGS, MAX_SUMMARY_PROJECTS = 500, MAX_SUMMARY_ENVIRONMENTS_PER_PROJECT = 500, MAX_TEXT2 = 256, MAX_PATH_NAME = 128, MAX_TIMESTAMP = 64, PR_STATES2, MAX_SUMMARY_MAIL_COUNT = 9999;
|
|
139861
139944
|
var init_node_summaries = __esm(() => {
|
|
139862
139945
|
init_federation();
|
|
139863
139946
|
init_pr_merge_readiness();
|
|
@@ -146990,7 +147073,7 @@ class NodeReadModel {
|
|
|
146990
147073
|
noteLocalEvent(event, payload) {
|
|
146991
147074
|
if (event === RESOURCE_CHANGED_EVENT) {
|
|
146992
147075
|
const resource = payload?.resource;
|
|
146993
|
-
if (resource !== "project" && resource !== "environment" && resource !== "environment-pr-health" && resource !== "build-pipeline" && resource !== "config") {
|
|
147076
|
+
if (resource !== "project" && resource !== "environment" && resource !== "environment-pr-health" && resource !== "build-pipeline" && resource !== "agent-mail-summary" && resource !== "config") {
|
|
146994
147077
|
return;
|
|
146995
147078
|
}
|
|
146996
147079
|
} else if (event !== BACKEND_PROFILE_CHANGED_EVENT) {
|
|
@@ -147173,6 +147256,10 @@ class NodeReadModel {
|
|
|
147173
147256
|
this.scheduleProjectRefresh(state, projectId);
|
|
147174
147257
|
else
|
|
147175
147258
|
this.requestHydrate(nodeId);
|
|
147259
|
+
} else if (change.resource === "agent-mail-summary") {
|
|
147260
|
+
for (const project of state.projects) {
|
|
147261
|
+
this.scheduleProjectRefresh(state, project.ref.projectId);
|
|
147262
|
+
}
|
|
147176
147263
|
}
|
|
147177
147264
|
}
|
|
147178
147265
|
projectOfEnvironment(state, environmentId) {
|
|
@@ -151459,6 +151546,41 @@ var init_node_ssh = __esm(() => {
|
|
|
151459
151546
|
init_ssh();
|
|
151460
151547
|
});
|
|
151461
151548
|
|
|
151549
|
+
// ../../apps/backend/src/core/nodes/node-summary-markers.ts
|
|
151550
|
+
function environmentMailMarkers(summary) {
|
|
151551
|
+
const totals = new Map;
|
|
151552
|
+
for (const mailbox of summary.mailboxes) {
|
|
151553
|
+
const total = totals.get(mailbox.environmentId) ?? { unread: 0, failed: false };
|
|
151554
|
+
total.unread += mailbox.userUnseenCount ?? mailbox.unreadCount;
|
|
151555
|
+
total.failed ||= mailbox.failedInjectCount > 0;
|
|
151556
|
+
totals.set(mailbox.environmentId, total);
|
|
151557
|
+
}
|
|
151558
|
+
const markers = new Map;
|
|
151559
|
+
for (const [environmentId, total] of totals) {
|
|
151560
|
+
const unread = Math.min(Math.max(0, Math.trunc(total.unread)), MAX_SUMMARY_MAIL_COUNT);
|
|
151561
|
+
if (unread === 0 && !total.failed)
|
|
151562
|
+
continue;
|
|
151563
|
+
markers.set(environmentId, {
|
|
151564
|
+
...unread > 0 ? { agentMailUnread: unread } : {},
|
|
151565
|
+
...total.failed ? { agentMailFailed: true } : {}
|
|
151566
|
+
});
|
|
151567
|
+
}
|
|
151568
|
+
return markers;
|
|
151569
|
+
}
|
|
151570
|
+
function isWorkingPipelineRecord(record) {
|
|
151571
|
+
const snapshot = record.snapshot;
|
|
151572
|
+
if (!snapshot || typeof snapshot !== "object" || typeof snapshot.phase !== "string")
|
|
151573
|
+
return false;
|
|
151574
|
+
return isWorkingBuildPipeline({
|
|
151575
|
+
phase: snapshot.phase,
|
|
151576
|
+
stallWarning: snapshot.stallWarning === undefined ? undefined : snapshot.stallWarning
|
|
151577
|
+
});
|
|
151578
|
+
}
|
|
151579
|
+
var init_node_summary_markers = __esm(() => {
|
|
151580
|
+
init_build_pipeline();
|
|
151581
|
+
init_node_summaries();
|
|
151582
|
+
});
|
|
151583
|
+
|
|
151462
151584
|
// ../../apps/backend/src/core/nodes/index.ts
|
|
151463
151585
|
var init_nodes = __esm(() => {
|
|
151464
151586
|
init_node_action_requests();
|
|
@@ -151473,6 +151595,7 @@ var init_nodes = __esm(() => {
|
|
|
151473
151595
|
init_node_seed();
|
|
151474
151596
|
init_node_service();
|
|
151475
151597
|
init_node_ssh();
|
|
151598
|
+
init_node_summary_markers();
|
|
151476
151599
|
init_project_summary_icons();
|
|
151477
151600
|
});
|
|
151478
151601
|
|
|
@@ -168453,7 +168576,7 @@ async function sendInteractiveData(data, sendLiteral, sendKeys) {
|
|
|
168453
168576
|
}
|
|
168454
168577
|
await flushLiteral();
|
|
168455
168578
|
}
|
|
168456
|
-
var CLAUDE_TMUX_EVENT = "claude-tmux:event", POLL_INTERVAL_MS = 250, TMUX_OBSERVATION_INTERVAL_MS = 3000, TMUX_BUSY_OBSERVATION_INTERVAL_MS = 500, LIVENESS_CHECK_EVERY_TICKS = 8, HOOK_TIMEOUT_SECS, HOOK_HOLD_CEILING_SECS, HOOK_COMMAND_TIMEOUT_SECS, HOOK_LIMIT_MARGIN_SECS = 60, HOOK_HOLD_PROTOCOL = "hold-v1", COMMAND_IDLE_TIMEOUT_MS = 8000, COMMAND_NO_HOOK_SETTLE_MS = 2000, COMMAND_AFTER_IDLE_SETTLE_MS = 400, PERMISSION_MODE_SWITCH_TIMEOUT_MS = 1500, PERMISSION_MODE_POLL_MS = 100, FAST_MODE_SWITCH_TIMEOUT_MS = 2500, FAST_MODE_POLL_MS = 100, FAST_MODE_TMUX_OPTION = "@orkestrator_fast_mode", BACKUP_SENTINEL_NO_ORIGINAL = "__orkestrator_no_original__", CLAUDE_SETTINGS_LOCAL_GIT_EXCLUDE_PATTERN = ".claude/settings.local.json", RUNTIME_ROOT_PREFIX = "/tmp/orkestrator-v2-claude-tmux", THINKING_MODE_ARGS, THINKING_DISPLAY_FLAG = "--thinking-display", THINKING_DISPLAY_VALUE = "summarized", THINKING_DISPLAY_PROBE_VALUE = "__orkestrator_probe__", THINKING_DISPLAY_PROBE_TIMEOUT_MS = 1e4, HOOK_EVENT_KINDS, POLL_SNAPSHOT_PENDING_MARKER = "__ork_pending__", POLL_SNAPSHOT_TIMEOUT_MARKER = "__ork_timeout__", POLL_SNAPSHOT_SIZE_MARKER = "__ork_size__", TRANSCRIPT_HEAD_MARKER = "__ork_head__", MAX_PREVIOUS_SESSIONS = 50, PREVIOUS_SESSION_STAT_CONCURRENCY = 8, INTERACTIVE_KEY_SEQUENCES;
|
|
168579
|
+
var CLAUDE_TMUX_EVENT = "claude-tmux:event", POLL_INTERVAL_MS = 250, TMUX_OBSERVATION_INTERVAL_MS = 3000, TMUX_BUSY_OBSERVATION_INTERVAL_MS = 500, LIVENESS_CHECK_EVERY_TICKS = 8, TMUX_IDLE_AFTER_QUIET_TICKS = 8, TMUX_IDLE_POLL_INTERVAL_MS = 1000, TMUX_IDLE_LIVENESS_CHECK_EVERY_TICKS = 2, TMUX_DISCOVERY_MIN_INTERVAL_MS = 2000, TMUX_DISCOVERY_MAX_INTERVAL_MS = 1e4, HOOK_TIMEOUT_SECS, HOOK_HOLD_CEILING_SECS, HOOK_COMMAND_TIMEOUT_SECS, HOOK_LIMIT_MARGIN_SECS = 60, HOOK_HOLD_PROTOCOL = "hold-v1", COMMAND_IDLE_TIMEOUT_MS = 8000, COMMAND_NO_HOOK_SETTLE_MS = 2000, COMMAND_AFTER_IDLE_SETTLE_MS = 400, PERMISSION_MODE_SWITCH_TIMEOUT_MS = 1500, PERMISSION_MODE_POLL_MS = 100, FAST_MODE_SWITCH_TIMEOUT_MS = 2500, FAST_MODE_POLL_MS = 100, FAST_MODE_TMUX_OPTION = "@orkestrator_fast_mode", BACKUP_SENTINEL_NO_ORIGINAL = "__orkestrator_no_original__", CLAUDE_SETTINGS_LOCAL_GIT_EXCLUDE_PATTERN = ".claude/settings.local.json", RUNTIME_ROOT_PREFIX = "/tmp/orkestrator-v2-claude-tmux", THINKING_MODE_ARGS, THINKING_DISPLAY_FLAG = "--thinking-display", THINKING_DISPLAY_VALUE = "summarized", THINKING_DISPLAY_PROBE_VALUE = "__orkestrator_probe__", THINKING_DISPLAY_PROBE_TIMEOUT_MS = 1e4, HOOK_EVENT_KINDS, POLL_SNAPSHOT_PENDING_MARKER = "__ork_pending__", POLL_SNAPSHOT_TIMEOUT_MARKER = "__ork_timeout__", POLL_SNAPSHOT_SIZE_MARKER = "__ork_size__", TRANSCRIPT_HEAD_MARKER = "__ork_head__", MAX_PREVIOUS_SESSIONS = 50, PREVIOUS_SESSION_STAT_CONCURRENCY = 8, INTERACTIVE_KEY_SEQUENCES;
|
|
168457
168580
|
var init_tmux_shared = __esm(() => {
|
|
168458
168581
|
init_agent_tools();
|
|
168459
168582
|
init_shell();
|
|
@@ -172987,14 +173110,19 @@ ${help.stderr}`;
|
|
|
172987
173110
|
const emittedBlockingIds = new Set;
|
|
172988
173111
|
let tail;
|
|
172989
173112
|
let tick = 0;
|
|
173113
|
+
let quietTicks = 0;
|
|
173114
|
+
let nextDiscoveryAt = 0;
|
|
173115
|
+
let discoveryInterval = TMUX_DISCOVERY_MIN_INTERVAL_MS;
|
|
172990
173116
|
(async () => {
|
|
172991
173117
|
try {
|
|
172992
173118
|
while (!this.stopRequested) {
|
|
172993
|
-
|
|
173119
|
+
const idle = !this.busy && quietTicks >= TMUX_IDLE_AFTER_QUIET_TICKS;
|
|
173120
|
+
await this.pollTick(idle ? TMUX_IDLE_POLL_INTERVAL_MS : POLL_INTERVAL_MS);
|
|
172994
173121
|
if (this.stopRequested)
|
|
172995
173122
|
break;
|
|
172996
173123
|
tick += 1;
|
|
172997
|
-
|
|
173124
|
+
quietTicks += 1;
|
|
173125
|
+
if (!tail && Date.now() >= nextDiscoveryAt) {
|
|
172998
173126
|
try {
|
|
172999
173127
|
const transcriptPath = await this.discoverTranscriptPath();
|
|
173000
173128
|
if (transcriptPath)
|
|
@@ -173002,6 +173130,8 @@ ${help.stderr}`;
|
|
|
173002
173130
|
} catch (error) {
|
|
173003
173131
|
console.warn("[tmux] transcript discovery failed", error);
|
|
173004
173132
|
}
|
|
173133
|
+
nextDiscoveryAt = Date.now() + discoveryInterval;
|
|
173134
|
+
discoveryInterval = Math.min(discoveryInterval * 2, TMUX_DISCOVERY_MAX_INTERVAL_MS);
|
|
173005
173135
|
}
|
|
173006
173136
|
let snapshot;
|
|
173007
173137
|
try {
|
|
@@ -173010,6 +173140,11 @@ ${help.stderr}`;
|
|
|
173010
173140
|
console.warn("[tmux] poll snapshot failed", error);
|
|
173011
173141
|
}
|
|
173012
173142
|
if (snapshot) {
|
|
173143
|
+
if (snapshot.pending.length > 0 || snapshot.timeouts.length > 0) {
|
|
173144
|
+
quietTicks = 0;
|
|
173145
|
+
nextDiscoveryAt = 0;
|
|
173146
|
+
discoveryInterval = TMUX_DISCOVERY_MIN_INTERVAL_MS;
|
|
173147
|
+
}
|
|
173013
173148
|
try {
|
|
173014
173149
|
const events = await drainPending(this.backend, this.sessionHookPaths, snapshot.pending, emittedBlockingIds);
|
|
173015
173150
|
for (const event of events)
|
|
@@ -173036,6 +173171,8 @@ ${help.stderr}`;
|
|
|
173036
173171
|
if (tail) {
|
|
173037
173172
|
try {
|
|
173038
173173
|
const lines = await tail.readNew(this.backend, snapshot.transcriptSize);
|
|
173174
|
+
if (lines.length > 0)
|
|
173175
|
+
quietTicks = 0;
|
|
173039
173176
|
for (const line of lines) {
|
|
173040
173177
|
const permissionMode = permissionModeFromTranscriptLine(line);
|
|
173041
173178
|
if (permissionMode)
|
|
@@ -173070,7 +173207,8 @@ ${help.stderr}`;
|
|
|
173070
173207
|
});
|
|
173071
173208
|
this.observationInFlight = observation;
|
|
173072
173209
|
}
|
|
173073
|
-
|
|
173210
|
+
const livenessEvery = idle ? TMUX_IDLE_LIVENESS_CHECK_EVERY_TICKS : LIVENESS_CHECK_EVERY_TICKS;
|
|
173211
|
+
if (tick % livenessEvery !== 0)
|
|
173074
173212
|
continue;
|
|
173075
173213
|
if (!await this.tmuxAlive().catch(() => false)) {
|
|
173076
173214
|
let removed = false;
|
|
@@ -200213,13 +200351,14 @@ async function stopEnvironmentOnce(environmentId, context, invalidateDiscovery,
|
|
|
200213
200351
|
const environment = await storage.getEnvironment(environmentId);
|
|
200214
200352
|
if (!environment)
|
|
200215
200353
|
throw new Error(`Environment not found: ${environmentId}`);
|
|
200354
|
+
if (environment.containerId)
|
|
200355
|
+
await assertDockerContainerOwned(environment.containerId, context);
|
|
200216
200356
|
await stopEnvironmentReviewValidation(environmentId, context);
|
|
200217
200357
|
await stopEnvironmentExecWorkers(environmentId, context);
|
|
200218
200358
|
invalidateDiscovery(environment.id);
|
|
200219
200359
|
context.previews?.registry.beforeEnvironmentTargetChange(environment.id);
|
|
200220
200360
|
if (environment.containerId) {
|
|
200221
200361
|
const containerId = environment.containerId;
|
|
200222
|
-
await assertDockerContainerOwned(containerId, context);
|
|
200223
200362
|
await context.nativeAgents?.runtimeStopRequested(environment.id);
|
|
200224
200363
|
const outcome = await runContainerOperation(context, environment.id, "stop", identity, async (operation) => {
|
|
200225
200364
|
const runtime = currentRuntimeIdentity(environment, context);
|
|
@@ -280152,7 +280291,7 @@ async function readRun(context, runId) {
|
|
|
280152
280291
|
function changed(run) {
|
|
280153
280292
|
return { status: "changed", run: graphRunViewSnapshot(run) };
|
|
280154
280293
|
}
|
|
280155
|
-
function
|
|
280294
|
+
function utf8Bytes6(text) {
|
|
280156
280295
|
return new TextEncoder().encode(text).byteLength;
|
|
280157
280296
|
}
|
|
280158
280297
|
async function readArtifact(context, runId, artifactId) {
|
|
@@ -280169,7 +280308,7 @@ async function readArtifact(context, runId, artifactId) {
|
|
|
280169
280308
|
return view;
|
|
280170
280309
|
let size;
|
|
280171
280310
|
try {
|
|
280172
|
-
size =
|
|
280311
|
+
size = utf8Bytes6(canonicalJson2(body.value, 128));
|
|
280173
280312
|
} catch {
|
|
280174
280313
|
size = Number.POSITIVE_INFINITY;
|
|
280175
280314
|
}
|
|
@@ -291179,6 +291318,8 @@ init_container_resources();
|
|
|
291179
291318
|
init_portable_input_status();
|
|
291180
291319
|
init_agent_settings();
|
|
291181
291320
|
init_agent_platforms();
|
|
291321
|
+
init_agent_mail();
|
|
291322
|
+
init_nodes();
|
|
291182
291323
|
init_storage();
|
|
291183
291324
|
init_docker_ownership();
|
|
291184
291325
|
init_storage_projects();
|
|
@@ -292101,11 +292242,16 @@ function registerEnvironmentCommands(register, dependencies) {
|
|
|
292101
292242
|
await runtime.prMonitor.sync(context);
|
|
292102
292243
|
const environments = await load();
|
|
292103
292244
|
const announced = runtime.prMonitor.announcedStates();
|
|
292104
|
-
const
|
|
292245
|
+
const pipelines = await storage.listBuildPipelines(asString4(args.projectId, "projectId"));
|
|
292246
|
+
const buildEnvironmentIds = new Set(pipelines.map((pipeline) => pipeline.environmentId));
|
|
292247
|
+
const activeBuildEnvironmentIds = new Set(pipelines.filter(isWorkingPipelineRecord).map((pipeline) => pipeline.environmentId));
|
|
292248
|
+
const mail = normalizeAgentMessagingSettings((await storage.loadConfig()).global.agentMessaging).enabled ? environmentMailMarkers(await storage.getAgentMailSummary()) : new Map;
|
|
292105
292249
|
return environments.map((environment) => ({
|
|
292106
292250
|
...environment,
|
|
292107
292251
|
...runtime.prMonitor.relayedHealth(environment, announced),
|
|
292108
|
-
...buildEnvironmentIds.has(environment.id) ? { buildPipeline: true } : {}
|
|
292252
|
+
...buildEnvironmentIds.has(environment.id) ? { buildPipeline: true } : {},
|
|
292253
|
+
...activeBuildEnvironmentIds.has(environment.id) ? { buildActive: true } : {},
|
|
292254
|
+
...mail.get(environment.id)
|
|
292109
292255
|
}));
|
|
292110
292256
|
});
|
|
292111
292257
|
register("get_environment_pr_health", async (args, { storage, runtime }) => {
|
|
@@ -302710,10 +302856,12 @@ import { createInterface } from "readline";
|
|
|
302710
302856
|
var MAX_TRACKED = 256;
|
|
302711
302857
|
var RESTART_MIN_MS = 1000;
|
|
302712
302858
|
var RESTART_MAX_MS = 60000;
|
|
302859
|
+
var FOLLOWED_EVENTS = ["oom", "start", "die", "stop", "destroy"];
|
|
302713
302860
|
|
|
302714
302861
|
class OomEventWatcher {
|
|
302715
302862
|
owner;
|
|
302716
302863
|
spawn;
|
|
302864
|
+
onLifecycle;
|
|
302717
302865
|
counts = new Map;
|
|
302718
302866
|
child = null;
|
|
302719
302867
|
restartTimer = null;
|
|
@@ -302722,9 +302870,13 @@ class OomEventWatcher {
|
|
|
302722
302870
|
running = false;
|
|
302723
302871
|
resumeFrom = null;
|
|
302724
302872
|
lastSeenNano = 0n;
|
|
302725
|
-
|
|
302873
|
+
lastOomNano = 0n;
|
|
302874
|
+
constructor(owner, spawn = spawnParentBoundCommand, onLifecycle = () => {
|
|
302875
|
+
return;
|
|
302876
|
+
}) {
|
|
302726
302877
|
this.owner = owner;
|
|
302727
302878
|
this.spawn = spawn;
|
|
302879
|
+
this.onLifecycle = onLifecycle;
|
|
302728
302880
|
}
|
|
302729
302881
|
start() {
|
|
302730
302882
|
if (this.stopped || this.child)
|
|
@@ -302733,13 +302885,12 @@ class OomEventWatcher {
|
|
|
302733
302885
|
"events",
|
|
302734
302886
|
"--filter",
|
|
302735
302887
|
"type=container",
|
|
302736
|
-
"--filter",
|
|
302737
|
-
"event=oom",
|
|
302888
|
+
...FOLLOWED_EVENTS.flatMap((event) => ["--filter", `event=${event}`]),
|
|
302738
302889
|
"--filter",
|
|
302739
302890
|
`label=orkestrator-owner=${this.owner}`,
|
|
302740
302891
|
...this.resumeFrom !== null ? ["--since", String(this.resumeFrom)] : [],
|
|
302741
302892
|
"--format",
|
|
302742
|
-
"{{.Actor.ID}}\t{{.TimeNano}}"
|
|
302893
|
+
"{{.Actor.ID}}\t{{.TimeNano}}\t{{.Action}}"
|
|
302743
302894
|
]);
|
|
302744
302895
|
this.child = child;
|
|
302745
302896
|
this.running = true;
|
|
@@ -302770,14 +302921,20 @@ class OomEventWatcher {
|
|
|
302770
302921
|
child.kill("SIGTERM");
|
|
302771
302922
|
}
|
|
302772
302923
|
record(line) {
|
|
302773
|
-
const [id = "", nanos = ""] = line.trim().split("\t");
|
|
302924
|
+
const [id = "", nanos = "", action = "oom"] = line.trim().split("\t");
|
|
302774
302925
|
if (!/^[0-9a-f]{12,64}$/.test(id) || !/^\d{1,20}$/.test(nanos))
|
|
302775
302926
|
return;
|
|
302776
302927
|
this.restartDelay = RESTART_MIN_MS;
|
|
302777
302928
|
const at = BigInt(nanos);
|
|
302778
|
-
if (at
|
|
302929
|
+
if (at > this.lastSeenNano)
|
|
302930
|
+
this.lastSeenNano = at;
|
|
302931
|
+
if (action !== "oom") {
|
|
302932
|
+
this.onLifecycle();
|
|
302933
|
+
return;
|
|
302934
|
+
}
|
|
302935
|
+
if (at <= this.lastOomNano)
|
|
302779
302936
|
return;
|
|
302780
|
-
this.
|
|
302937
|
+
this.lastOomNano = at;
|
|
302781
302938
|
const lastAt = new Date(Number(at / 1000000n)).toISOString();
|
|
302782
302939
|
const current = this.counts.get(id);
|
|
302783
302940
|
this.counts.delete(id);
|
|
@@ -302809,14 +302966,16 @@ class OomEventWatcher {
|
|
|
302809
302966
|
|
|
302810
302967
|
class ContainerOomEvents {
|
|
302811
302968
|
spawn;
|
|
302969
|
+
onLifecycle;
|
|
302812
302970
|
watcher = null;
|
|
302813
|
-
constructor(spawn = spawnParentBoundCommand) {
|
|
302971
|
+
constructor(spawn = spawnParentBoundCommand, onLifecycle) {
|
|
302814
302972
|
this.spawn = spawn;
|
|
302973
|
+
this.onLifecycle = onLifecycle;
|
|
302815
302974
|
}
|
|
302816
302975
|
start(owner) {
|
|
302817
302976
|
if (this.watcher)
|
|
302818
302977
|
return;
|
|
302819
|
-
this.watcher = new OomEventWatcher(owner, this.spawn);
|
|
302978
|
+
this.watcher = new OomEventWatcher(owner, this.spawn, this.onLifecycle);
|
|
302820
302979
|
this.watcher.start();
|
|
302821
302980
|
}
|
|
302822
302981
|
count(containerId) {
|
|
@@ -308269,7 +308428,7 @@ class TerminalRuntime {
|
|
|
308269
308428
|
if (available > excess) {
|
|
308270
308429
|
let trim = excess;
|
|
308271
308430
|
const boundary = buffer.headOffset + trim;
|
|
308272
|
-
if (
|
|
308431
|
+
if (isLowSurrogate2(head.charCodeAt(boundary)) && isHighSurrogate2(head.charCodeAt(boundary - 1))) {
|
|
308273
308432
|
trim += 1;
|
|
308274
308433
|
}
|
|
308275
308434
|
buffer.headOffset += trim;
|
|
@@ -308798,7 +308957,7 @@ class BackendRuntime {
|
|
|
308798
308957
|
this.prMonitor = new PrMonitorRuntime(options2.prMonitor);
|
|
308799
308958
|
this.tmux = new TmuxRuntime(options2.tmux);
|
|
308800
308959
|
this.accounts = new AgentAccountsRuntime(options2.accounts);
|
|
308801
|
-
this.containerOom = new ContainerOomEvents(options2.containerOom?.spawn);
|
|
308960
|
+
this.containerOom = new ContainerOomEvents(options2.containerOom?.spawn, () => this.containerStates.invalidate());
|
|
308802
308961
|
this.containerLogs = new ContainerLogService(options2.containerLogs?.spawn, options2.containerLogs?.now);
|
|
308803
308962
|
}
|
|
308804
308963
|
attachChangeTracking(service) {
|
|
@@ -309020,6 +309179,13 @@ function firewallDisplayName(kind) {
|
|
|
309020
309179
|
return "your firewall";
|
|
309021
309180
|
}
|
|
309022
309181
|
}
|
|
309182
|
+
function sudoForEachSource(sources, rule, then) {
|
|
309183
|
+
if (sources.length === 1) {
|
|
309184
|
+
return [`sudo ${rule(sources[0])}`, ...then ? [`sudo ${then}`] : []].join(" && ");
|
|
309185
|
+
}
|
|
309186
|
+
const loop = `for net in ${sources.join(" ")}; do ${rule("$net")} || exit 1; done`;
|
|
309187
|
+
return `sudo sh -c '${loop}${then ? ` && ${then}` : ""}'`;
|
|
309188
|
+
}
|
|
309023
309189
|
function buildContainerHostRemediation(input) {
|
|
309024
309190
|
const { firewall, port } = input;
|
|
309025
309191
|
const blocking = input.outcomes.filter(isBlockingOutcome);
|
|
@@ -309051,15 +309217,16 @@ function buildContainerHostRemediation(input) {
|
|
|
309051
309217
|
return {
|
|
309052
309218
|
title: "Allow Docker containers through ufw",
|
|
309053
309219
|
steps: [intro, scope, after],
|
|
309054
|
-
commands:
|
|
309220
|
+
commands: [
|
|
309221
|
+
sudoForEachSource(cidrs, (source) => `ufw allow proto tcp from ${source} to any port ${port} comment "Orkestrator agent tools"`)
|
|
309222
|
+
]
|
|
309055
309223
|
};
|
|
309056
309224
|
case "firewalld":
|
|
309057
309225
|
return {
|
|
309058
309226
|
title: "Allow Docker containers through firewalld",
|
|
309059
309227
|
steps: [intro, scope, after],
|
|
309060
309228
|
commands: [
|
|
309061
|
-
|
|
309062
|
-
"sudo firewall-cmd --reload"
|
|
309229
|
+
sudoForEachSource(cidrs, (source) => `firewall-cmd --permanent --add-rich-rule="rule family=ipv4 source address=${source} port port=${port} protocol=tcp accept"`, "firewall-cmd --reload")
|
|
309063
309230
|
]
|
|
309064
309231
|
};
|
|
309065
309232
|
default:
|
|
@@ -309071,7 +309238,9 @@ function buildContainerHostRemediation(input) {
|
|
|
309071
309238
|
"These iptables rules take effect immediately but are lost on reboot. Add the same rule to your firewall's saved configuration to keep it.",
|
|
309072
309239
|
after
|
|
309073
309240
|
],
|
|
309074
|
-
commands:
|
|
309241
|
+
commands: [
|
|
309242
|
+
sudoForEachSource(cidrs, (source) => `iptables -I INPUT -p tcp -s ${source} --dport ${port} -j ACCEPT`)
|
|
309243
|
+
]
|
|
309075
309244
|
};
|
|
309076
309245
|
}
|
|
309077
309246
|
}
|
|
@@ -309086,12 +309255,14 @@ function buildRootlessHostRemediation(port) {
|
|
|
309086
309255
|
`Then press \u201CCheck again\u201D. New containers reach Orkestrator through RootlessKit's host address (${ROOTLESSKIT_HOST_LOOPBACK_ADDRESS}); rebuild existing environments so their network policy includes it.`
|
|
309087
309256
|
],
|
|
309088
309257
|
commands: [
|
|
309089
|
-
|
|
309090
|
-
|
|
309258
|
+
[
|
|
309259
|
+
"mkdir -p ~/.config/systemd/user/docker.service.d",
|
|
309260
|
+
`printf '[Service]
|
|
309091
309261
|
Environment="DOCKERD_ROOTLESS_ROOTLESSKIT_DISABLE_HOST_LOOPBACK=false"
|
|
309092
309262
|
' > ${ROOTLESS_HOST_LOOPBACK_DROP_IN}`,
|
|
309093
|
-
|
|
309094
|
-
|
|
309263
|
+
"systemctl --user daemon-reload",
|
|
309264
|
+
"systemctl --user restart docker"
|
|
309265
|
+
].join(" && ")
|
|
309095
309266
|
]
|
|
309096
309267
|
};
|
|
309097
309268
|
}
|
|
@@ -327197,6 +327368,8 @@ class AgentMailService {
|
|
|
327197
327368
|
return task;
|
|
327198
327369
|
}
|
|
327199
327370
|
async refreshPresenceOnce() {
|
|
327371
|
+
if (!(await this.storage.loadConfig()).global.agentMessaging?.enabled)
|
|
327372
|
+
return;
|
|
327200
327373
|
const mailboxes = [];
|
|
327201
327374
|
let offset = 0;
|
|
327202
327375
|
while (true) {
|
|
@@ -338477,7 +338650,7 @@ function parseGatewayCompressionMode(value, source = "gateway compression mode")
|
|
|
338477
338650
|
throw new Error(`Invalid ${source}: ${value}. Expected one of off, body, on.`);
|
|
338478
338651
|
}
|
|
338479
338652
|
function resolveGatewayCompressionMode(explicit, env = process.env) {
|
|
338480
|
-
return explicit ?? parseGatewayCompressionMode(env.ORKESTRATOR_GATEWAY_COMPRESSION, "ORKESTRATOR_GATEWAY_COMPRESSION") ?? "
|
|
338653
|
+
return explicit ?? parseGatewayCompressionMode(env.ORKESTRATOR_GATEWAY_COMPRESSION, "ORKESTRATOR_GATEWAY_COMPRESSION") ?? "on";
|
|
338481
338654
|
}
|
|
338482
338655
|
function compressionModeForListener(compression, listenerKind) {
|
|
338483
338656
|
return listenerKind === "control" ? "off" : compression;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "orkestrator",
|
|
3
|
-
"version": "2.35.
|
|
3
|
+
"version": "2.35.1-beta",
|
|
4
4
|
"description": "Run the Orkestrator backend service without the desktop application",
|
|
5
5
|
"homepage": "https://orkestrator.dev",
|
|
6
6
|
"repository": {
|
|
@@ -39,8 +39,8 @@
|
|
|
39
39
|
"sharp": "0.35.5"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@orkestrator/protocol": "2.35.
|
|
43
|
-
"@orkestrator/toolchain": "2.35.
|
|
42
|
+
"@orkestrator/protocol": "2.35.1-beta",
|
|
43
|
+
"@orkestrator/toolchain": "2.35.1-beta"
|
|
44
44
|
},
|
|
45
45
|
"engines": {
|
|
46
46
|
"bun": ">=1.4.4"
|
|
@@ -10114,7 +10114,7 @@ var MAX_SESSIONS = parseBoundedInteger(process.env.ACP_MAX_SESSIONS, 256, 1, 256
|
|
|
10114
10114
|
var MAX_APPROVALS_PER_SESSION = 64;
|
|
10115
10115
|
var MAX_STRUCTURED_RESULTS = 4;
|
|
10116
10116
|
var MAX_STRUCTURED_RESULT_BYTES = 1024 * 1024;
|
|
10117
|
-
var TRANSCRIPT_CHECK_INTERVAL_BYTES =
|
|
10117
|
+
var TRANSCRIPT_CHECK_INTERVAL_BYTES = 1024 * 1024;
|
|
10118
10118
|
var MAX_PROMPT_JOURNAL = 512;
|
|
10119
10119
|
var MAX_PERSISTED_GROK_INTERJECTION_BYTES = 512 * 1024;
|
|
10120
10120
|
var MAX_STATE_FILE_BYTES = parseBoundedInteger(process.env.ACP_MAX_STATE_FILE_BYTES, 16 * 1024 * 1024, 512 * 1024, 16 * 1024 * 1024);
|
|
@@ -11279,6 +11279,24 @@ function persistedSnapshot() {
|
|
|
11279
11279
|
};
|
|
11280
11280
|
return boundPersistedSnapshot(snapshot);
|
|
11281
11281
|
}
|
|
11282
|
+
var STREAMING_PERSIST_INTERVAL_MS = 1000;
|
|
11283
|
+
var streamingPersistTimer = null;
|
|
11284
|
+
function scheduleStreamingPersist() {
|
|
11285
|
+
if (!stateFile || streamingPersistTimer)
|
|
11286
|
+
return;
|
|
11287
|
+
streamingPersistTimer = setTimeout(() => {
|
|
11288
|
+
streamingPersistTimer = null;
|
|
11289
|
+
schedulePersist();
|
|
11290
|
+
}, STREAMING_PERSIST_INTERVAL_MS);
|
|
11291
|
+
streamingPersistTimer.unref();
|
|
11292
|
+
}
|
|
11293
|
+
function flushStreamingPersist() {
|
|
11294
|
+
if (streamingPersistTimer) {
|
|
11295
|
+
clearTimeout(streamingPersistTimer);
|
|
11296
|
+
streamingPersistTimer = null;
|
|
11297
|
+
}
|
|
11298
|
+
return persistState();
|
|
11299
|
+
}
|
|
11282
11300
|
function schedulePersist() {
|
|
11283
11301
|
if (!stateFile || persistenceScheduled)
|
|
11284
11302
|
return;
|
|
@@ -12084,7 +12102,7 @@ function commitToolPartMutation(state, part, source) {
|
|
|
12084
12102
|
failTranscriptLimit(state);
|
|
12085
12103
|
return false;
|
|
12086
12104
|
}
|
|
12087
|
-
|
|
12105
|
+
scheduleStreamingPersist();
|
|
12088
12106
|
return true;
|
|
12089
12107
|
}
|
|
12090
12108
|
function activeSubagentLaunch(state, toolUseId) {
|
|
@@ -19481,7 +19499,7 @@ function applySessionUpdate(state, params) {
|
|
|
19481
19499
|
failTranscriptLimit(state);
|
|
19482
19500
|
return;
|
|
19483
19501
|
}
|
|
19484
|
-
|
|
19502
|
+
scheduleStreamingPersist();
|
|
19485
19503
|
}
|
|
19486
19504
|
function composerPatchFromSpawn(options) {
|
|
19487
19505
|
const patch = {};
|
|
@@ -22427,9 +22445,7 @@ function shutdown() {
|
|
|
22427
22445
|
...[...sessions.values()].map((state) => state.child?.close()),
|
|
22428
22446
|
...[...cursorToolReplayProcesses].map((child) => child.close())
|
|
22429
22447
|
]);
|
|
22430
|
-
await
|
|
22431
|
-
return;
|
|
22432
|
-
});
|
|
22448
|
+
await flushStreamingPersist();
|
|
22433
22449
|
await new Promise((resolvePromise) => server.close(() => resolvePromise()));
|
|
22434
22450
|
})();
|
|
22435
22451
|
return shutdownPromise;
|
|
@@ -22624,6 +22640,7 @@ export {
|
|
|
22624
22640
|
findHistoryMessage,
|
|
22625
22641
|
finishSubagentTool,
|
|
22626
22642
|
flattenedRetriableProviderTail,
|
|
22643
|
+
flushStreamingPersist,
|
|
22627
22644
|
grokBridgeGeneration,
|
|
22628
22645
|
grokInterjectionDigest,
|
|
22629
22646
|
grokQuestionTimeoutMs,
|
|
@@ -22745,6 +22762,7 @@ export {
|
|
|
22745
22762
|
saturatedText,
|
|
22746
22763
|
scheduleCursorToolMetadataReconcile,
|
|
22747
22764
|
schedulePersist,
|
|
22765
|
+
scheduleStreamingPersist,
|
|
22748
22766
|
sendJson,
|
|
22749
22767
|
server,
|
|
22750
22768
|
sessionCreations,
|