orkestrator 2.26.3-beta → 2.28.0-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 +508 -209
- package/dist/main.js +16148 -10171
- package/package.json +4 -4
- package/resources/claude-bridge/dist/index.js +132 -25
- package/resources/codex-bridge/dist/index.js +266 -31
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "orkestrator",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.28.0-beta",
|
|
4
4
|
"description": "Run the Orkestrator backend service without the desktop application",
|
|
5
5
|
"homepage": "https://orkestrator.dev",
|
|
6
6
|
"repository": {
|
|
@@ -34,13 +34,13 @@
|
|
|
34
34
|
"typecheck": "bunx tsc --noEmit -p tsconfig.json"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@anthropic-ai/claude-agent-sdk": "0.3.
|
|
37
|
+
"@anthropic-ai/claude-agent-sdk": "0.3.309",
|
|
38
38
|
"playwright-core": "1.64.0",
|
|
39
39
|
"sharp": "0.35.5"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@orkestrator/protocol": "2.
|
|
43
|
-
"@orkestrator/toolchain": "2.
|
|
42
|
+
"@orkestrator/protocol": "2.28.0-beta",
|
|
43
|
+
"@orkestrator/toolchain": "2.28.0-beta"
|
|
44
44
|
},
|
|
45
45
|
"engines": {
|
|
46
46
|
"bun": ">=1.4.3"
|
|
@@ -3344,6 +3344,24 @@ function createStructuredUsageRefreshCoordinator(session, queryControl) {
|
|
|
3344
3344
|
}
|
|
3345
3345
|
};
|
|
3346
3346
|
}
|
|
3347
|
+
var CLAUDE_CONTEXT_CATEGORY_IDS = {
|
|
3348
|
+
system_prompt: "system-prompt",
|
|
3349
|
+
system_tools: "tools",
|
|
3350
|
+
system_tools_deferred: "deferred-tools",
|
|
3351
|
+
mcp_tools: "mcp-tools",
|
|
3352
|
+
mcp_tools_deferred: "deferred-mcp-tools",
|
|
3353
|
+
mcp_instructions: "mcp-instructions",
|
|
3354
|
+
custom_agents: "agents",
|
|
3355
|
+
memory_files: "memory",
|
|
3356
|
+
skills: "skills",
|
|
3357
|
+
messages: "messages",
|
|
3358
|
+
autocompact_buffer: "reserved",
|
|
3359
|
+
compact_buffer: "reserved",
|
|
3360
|
+
free_space: "free-space"
|
|
3361
|
+
};
|
|
3362
|
+
function claudeContextCategoryId(value) {
|
|
3363
|
+
return typeof value === "string" && Object.hasOwn(CLAUDE_CONTEXT_CATEGORY_IDS, value) ? CLAUDE_CONTEXT_CATEGORY_IDS[value] : undefined;
|
|
3364
|
+
}
|
|
3347
3365
|
function parseClaudeContextUsage(raw) {
|
|
3348
3366
|
if (!raw || typeof raw !== "object")
|
|
3349
3367
|
return;
|
|
@@ -3361,8 +3379,10 @@ function parseClaudeContextUsage(raw) {
|
|
|
3361
3379
|
const tokens = parseTokenValue(item.tokens);
|
|
3362
3380
|
if (!name || tokens === undefined)
|
|
3363
3381
|
return [];
|
|
3382
|
+
const id = claudeContextCategoryId(item.id);
|
|
3364
3383
|
return [
|
|
3365
3384
|
{
|
|
3385
|
+
...id ? { id } : {},
|
|
3366
3386
|
name,
|
|
3367
3387
|
tokens,
|
|
3368
3388
|
color: typeof item.color === "string" ? item.color : undefined
|
|
@@ -3502,6 +3522,7 @@ async function buildClaudeUsageSnapshot(session, result, queryControl, fallbackM
|
|
|
3502
3522
|
const turnId = typeof result.user_message_uuid === "string" && result.user_message_uuid.trim() || typeof result.uuid === "string" && result.uuid.trim() || `claude-turn-${session.latestTurnGeneration ?? updatedAt}`;
|
|
3503
3523
|
const turn = {
|
|
3504
3524
|
turnId,
|
|
3525
|
+
at: updatedAt,
|
|
3505
3526
|
costUsd: totals.cost,
|
|
3506
3527
|
inputTokens: totals.input,
|
|
3507
3528
|
outputTokens: totals.output,
|
|
@@ -4243,6 +4264,7 @@ var NATIVE_AGENT_APPROVAL_MODES = Object.freeze({
|
|
|
4243
4264
|
]
|
|
4244
4265
|
});
|
|
4245
4266
|
var DISPATCH_OUTCOME_LOST_KIND = "dispatch-outcome-lost";
|
|
4267
|
+
var NATIVE_AGENT_RETIRED_DISPATCH_TTL_MS = 24 * 60 * 60 * 1000;
|
|
4246
4268
|
var SUPPRESSED_COMPOSER_PARAMETERS = Object.freeze({
|
|
4247
4269
|
claude: Object.freeze(["parameter:thinking", "parameter:context1m"]),
|
|
4248
4270
|
codex: Object.freeze(["parameter:summary"]),
|
|
@@ -4358,6 +4380,7 @@ var PROJECTION_FIELD_SET = new Set([
|
|
|
4358
4380
|
"runtimeHealthAuthoritative",
|
|
4359
4381
|
"notices",
|
|
4360
4382
|
"recoverableDispatch",
|
|
4383
|
+
"retiredDispatch",
|
|
4361
4384
|
"backgroundTasks",
|
|
4362
4385
|
"suggestedPrompt",
|
|
4363
4386
|
"completionBlockedByBackgroundTasks",
|
|
@@ -4381,6 +4404,7 @@ var OPTIONAL_PROJECTION_FIELD_SET = new Set([
|
|
|
4381
4404
|
"runtimeHealthAuthoritative",
|
|
4382
4405
|
"notices",
|
|
4383
4406
|
"recoverableDispatch",
|
|
4407
|
+
"retiredDispatch",
|
|
4384
4408
|
"backgroundTasks",
|
|
4385
4409
|
"suggestedPrompt",
|
|
4386
4410
|
"completionBlockedByBackgroundTasks",
|
|
@@ -4389,6 +4413,15 @@ var OPTIONAL_PROJECTION_FIELD_SET = new Set([
|
|
|
4389
4413
|
"slashCommandCatalogue"
|
|
4390
4414
|
]);
|
|
4391
4415
|
|
|
4416
|
+
// ../../bridges/claude-bridge/src/services/mcp-tool-prefix.ts
|
|
4417
|
+
function claudeMcpToolPrefix(name) {
|
|
4418
|
+
let normalized = name.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
4419
|
+
if (name.startsWith("claude.ai ")) {
|
|
4420
|
+
normalized = normalized.replace(/_+/g, "_").replace(/^_|_$/g, "");
|
|
4421
|
+
}
|
|
4422
|
+
return `mcp__${normalized}__`;
|
|
4423
|
+
}
|
|
4424
|
+
|
|
4392
4425
|
// ../../bridges/claude-bridge/src/services/read-only-policy.ts
|
|
4393
4426
|
var CAPABILITY_TOOLS = new Map([
|
|
4394
4427
|
["file.write", ["Write", "NotebookEdit"]],
|
|
@@ -4414,8 +4447,7 @@ var WAITING_TOOLS = new Set([
|
|
|
4414
4447
|
"CronCreate",
|
|
4415
4448
|
"CronList",
|
|
4416
4449
|
"CronDelete",
|
|
4417
|
-
"SendMessage"
|
|
4418
|
-
"TaskOutput"
|
|
4450
|
+
"SendMessage"
|
|
4419
4451
|
]);
|
|
4420
4452
|
var READ_ONLY_COMMANDS = Object.freeze(new Set([
|
|
4421
4453
|
"awk",
|
|
@@ -4604,8 +4636,8 @@ function claudeReadOnlyAllowedTools(options) {
|
|
|
4604
4636
|
return [
|
|
4605
4637
|
...READ_ONLY_TOOLS,
|
|
4606
4638
|
...options.policy && !nativeAgentPolicyDeniesWebSearch(options.policy) ? ["WebSearch"] : [],
|
|
4607
|
-
...(options.agentMcpServerNames ?? []).map((name) =>
|
|
4608
|
-
...(options.researchMcpServerNames ?? []).map((name) =>
|
|
4639
|
+
...(options.agentMcpServerNames ?? []).map((name) => `${claudeMcpToolPrefix(name)}*`),
|
|
4640
|
+
...(options.researchMcpServerNames ?? []).map((name) => `${claudeMcpToolPrefix(name)}*`)
|
|
4609
4641
|
];
|
|
4610
4642
|
}
|
|
4611
4643
|
function claudeReadOnlySandbox(policy) {
|
|
@@ -4676,8 +4708,8 @@ function deny(reason) {
|
|
|
4676
4708
|
function createCoordinatorReadOnlyHook(policy, researchMcpServerNames = coordinatorResearchMcpServersFromEnv(process.env).map((server) => server.name)) {
|
|
4677
4709
|
const deniedTools = new Set(claudeDeniedTools(policy));
|
|
4678
4710
|
const allowedMcpPrefixes = [
|
|
4679
|
-
"
|
|
4680
|
-
...researchMcpServerNames.map(
|
|
4711
|
+
claudeMcpToolPrefix("orkestrator"),
|
|
4712
|
+
...researchMcpServerNames.map(claudeMcpToolPrefix)
|
|
4681
4713
|
];
|
|
4682
4714
|
return async (input) => {
|
|
4683
4715
|
if (input.hook_event_name !== "PreToolUse")
|
|
@@ -5160,7 +5192,15 @@ async function stopBackgroundTask(sessionId, taskId) {
|
|
|
5160
5192
|
}
|
|
5161
5193
|
return { ok: true };
|
|
5162
5194
|
}
|
|
5195
|
+
var backgroundTaskRevisions = new WeakMap;
|
|
5196
|
+
function noteBackgroundTasksChanged(session) {
|
|
5197
|
+
backgroundTaskRevisions.set(session, (backgroundTaskRevisions.get(session) ?? 0) + 1);
|
|
5198
|
+
}
|
|
5199
|
+
function backgroundTaskRevision(session) {
|
|
5200
|
+
return backgroundTaskRevisions.get(session) ?? 0;
|
|
5201
|
+
}
|
|
5163
5202
|
function emitBackgroundTaskSnapshot(session) {
|
|
5203
|
+
noteBackgroundTasksChanged(session);
|
|
5164
5204
|
eventEmitter.emit({
|
|
5165
5205
|
type: "session.updated",
|
|
5166
5206
|
sessionId: session.id,
|
|
@@ -6771,6 +6811,34 @@ function getPromptDispatchState(sessionId, requestId) {
|
|
|
6771
6811
|
}
|
|
6772
6812
|
return "new";
|
|
6773
6813
|
}
|
|
6814
|
+
function idleSteerUserMessageId(requestId) {
|
|
6815
|
+
return `idle-steer:${requestId}`;
|
|
6816
|
+
}
|
|
6817
|
+
function restoredDispatchClaimLost(session, requestId) {
|
|
6818
|
+
if (!session?.restoredDispatchedRequestIds?.has(requestId))
|
|
6819
|
+
return false;
|
|
6820
|
+
const localReplyId = idleSteerUserMessageId(requestId);
|
|
6821
|
+
return !session.localTranscript?.some((message) => message.id === localReplyId);
|
|
6822
|
+
}
|
|
6823
|
+
async function persistedDispatchClaimLost(sessionId, requestId) {
|
|
6824
|
+
if (sessions.has(sessionId))
|
|
6825
|
+
return false;
|
|
6826
|
+
const sdkSessionId = sdkSessionIdFromBridgeId(sessionId);
|
|
6827
|
+
if (!sdkSessionId)
|
|
6828
|
+
return false;
|
|
6829
|
+
let preferences;
|
|
6830
|
+
try {
|
|
6831
|
+
preferences = await readSessionPreferences(sdkSessionId);
|
|
6832
|
+
} catch {
|
|
6833
|
+
return false;
|
|
6834
|
+
}
|
|
6835
|
+
if (!preferences || sessionPreferencesUnavailable(preferences))
|
|
6836
|
+
return false;
|
|
6837
|
+
if (!preferences.dispatchedRequestIds?.includes(requestId))
|
|
6838
|
+
return false;
|
|
6839
|
+
const localReplyId = idleSteerUserMessageId(requestId);
|
|
6840
|
+
return !preferences.localTranscript?.some((entry) => entry.id === localReplyId);
|
|
6841
|
+
}
|
|
6774
6842
|
async function claimPromptDispatch(sessionId, requestId, startDispatch, testHooks) {
|
|
6775
6843
|
const session = sessions.get(sessionId);
|
|
6776
6844
|
if (!session)
|
|
@@ -12179,7 +12247,7 @@ function displayCommandName(name) {
|
|
|
12179
12247
|
function normalizeAvailability(value) {
|
|
12180
12248
|
if (!isRecord(value))
|
|
12181
12249
|
return;
|
|
12182
|
-
if (
|
|
12250
|
+
if (typeof value.state !== "string")
|
|
12183
12251
|
return;
|
|
12184
12252
|
const reason = typeof value.reason === "string" && UNAVAILABLE_REASONS.has(value.reason) ? value.reason : undefined;
|
|
12185
12253
|
const message = boundedText(value.message, COMMAND_CATALOGUE_LIMITS.maxAvailabilityMessageBytes);
|
|
@@ -12696,7 +12764,10 @@ function idleSteerMessageIds(requestId) {
|
|
|
12696
12764
|
if (!requestId) {
|
|
12697
12765
|
return { userId: generateMessageId(), assistantId: generateMessageId() };
|
|
12698
12766
|
}
|
|
12699
|
-
return {
|
|
12767
|
+
return {
|
|
12768
|
+
userId: idleSteerUserMessageId(requestId),
|
|
12769
|
+
assistantId: `idle-steer-reply:${requestId}`
|
|
12770
|
+
};
|
|
12700
12771
|
}
|
|
12701
12772
|
async function answerIdleSteerPrompt(session, prompt, requestId) {
|
|
12702
12773
|
const reply = idleSteerPromptReply(prompt, "Claude");
|
|
@@ -13609,9 +13680,6 @@ function reportedStaleServers(mcp) {
|
|
|
13609
13680
|
return;
|
|
13610
13681
|
return Array.from(mcp.stale).sort().slice(0, MAX_REPORTED_STALE_SERVERS);
|
|
13611
13682
|
}
|
|
13612
|
-
function claudeMcpToolPrefix(name) {
|
|
13613
|
-
return `mcp__${name.replace(/[^a-zA-Z0-9_-]/g, "_")}__`;
|
|
13614
|
-
}
|
|
13615
13683
|
function staleMcpServerFor(mcp, toolName, toolInput) {
|
|
13616
13684
|
if (!mcp.stale.size)
|
|
13617
13685
|
return;
|
|
@@ -15405,6 +15473,7 @@ async function handleResultMessage(turn, message) {
|
|
|
15405
15473
|
|
|
15406
15474
|
// ../../bridges/claude-bridge/src/services/session-manager-prompt-handlers/system-tasks.ts
|
|
15407
15475
|
function emitBackgroundTasks(turn) {
|
|
15476
|
+
noteBackgroundTasksChanged(turn.session);
|
|
15408
15477
|
eventEmitter.emit({
|
|
15409
15478
|
type: "session.updated",
|
|
15410
15479
|
sessionId: turn.sessionId,
|
|
@@ -16871,7 +16940,9 @@ var MCP_MANAGEMENT_LIMITS = {
|
|
|
16871
16940
|
operationStoreMaxBytes: 4 * 1024 * 1024,
|
|
16872
16941
|
runtimesPerOperation: 64,
|
|
16873
16942
|
runtimesTrackedPerOperation: 256,
|
|
16874
|
-
queuedApplyTargets: 32
|
|
16943
|
+
queuedApplyTargets: 32,
|
|
16944
|
+
overlayRecordMaxBytes: 3 * 1024 * 1024,
|
|
16945
|
+
containerPathProbesMax: 32
|
|
16875
16946
|
};
|
|
16876
16947
|
var MCP_SCOPE_LABELS = Object.freeze({
|
|
16877
16948
|
"backend-user": "Backend user",
|
|
@@ -17015,6 +17086,7 @@ var SESSION_ACTIVITY_BATCH_LIMITS = {
|
|
|
17015
17086
|
maxResponseBytes: 512 * 1024,
|
|
17016
17087
|
maxAsyncQuestionItemIds: 64,
|
|
17017
17088
|
maxAsyncQuestionItemIdLength: 2048,
|
|
17089
|
+
maxContentRevisionLength: 256,
|
|
17018
17090
|
readConcurrency: 4
|
|
17019
17091
|
};
|
|
17020
17092
|
var SESSION_ACTIVITY_STATES = new Set(["idle", "working", "waiting", "missing"]);
|
|
@@ -17029,6 +17101,7 @@ function parseSessionActivityObservation(value) {
|
|
|
17029
17101
|
if (!isRecord3(value))
|
|
17030
17102
|
return;
|
|
17031
17103
|
const { activity, readyForInput, completionPending, asyncQuestionItemIds, closing } = value;
|
|
17104
|
+
const { contentRevision } = value;
|
|
17032
17105
|
if (typeof activity !== "string" || !SESSION_ACTIVITY_STATES.has(activity))
|
|
17033
17106
|
return;
|
|
17034
17107
|
if (readyForInput !== undefined && typeof readyForInput !== "boolean")
|
|
@@ -17037,6 +17110,8 @@ function parseSessionActivityObservation(value) {
|
|
|
17037
17110
|
return;
|
|
17038
17111
|
if (closing !== undefined && typeof closing !== "boolean")
|
|
17039
17112
|
return;
|
|
17113
|
+
if (contentRevision !== undefined && !isContentRevision(contentRevision))
|
|
17114
|
+
return;
|
|
17040
17115
|
let itemIds;
|
|
17041
17116
|
if (asyncQuestionItemIds !== undefined) {
|
|
17042
17117
|
if (!Array.isArray(asyncQuestionItemIds) || asyncQuestionItemIds.length > SESSION_ACTIVITY_BATCH_LIMITS.maxAsyncQuestionItemIds || !asyncQuestionItemIds.every((itemId) => typeof itemId === "string" && itemId.length > 0 && itemId.length <= SESSION_ACTIVITY_BATCH_LIMITS.maxAsyncQuestionItemIdLength)) {
|
|
@@ -17049,9 +17124,13 @@ function parseSessionActivityObservation(value) {
|
|
|
17049
17124
|
...readyForInput !== undefined ? { readyForInput } : {},
|
|
17050
17125
|
...completionPending !== undefined ? { completionPending } : {},
|
|
17051
17126
|
...itemIds !== undefined ? { asyncQuestionItemIds: itemIds } : {},
|
|
17052
|
-
...closing !== undefined ? { closing } : {}
|
|
17127
|
+
...closing !== undefined ? { closing } : {},
|
|
17128
|
+
...contentRevision !== undefined ? { contentRevision } : {}
|
|
17053
17129
|
};
|
|
17054
17130
|
}
|
|
17131
|
+
function isContentRevision(value) {
|
|
17132
|
+
return typeof value === "string" && value.length > 0 && value.length <= SESSION_ACTIVITY_BATCH_LIMITS.maxContentRevisionLength;
|
|
17133
|
+
}
|
|
17055
17134
|
function parseSessionActivityBatchRequest(value) {
|
|
17056
17135
|
if (!isRecord3(value))
|
|
17057
17136
|
return { ok: false, error: "Expected a JSON object" };
|
|
@@ -17176,9 +17255,23 @@ async function readSessionActivityObservation(sessionId) {
|
|
|
17176
17255
|
const completionPending = resident ? sessionCompletionPending(resident) : undefined;
|
|
17177
17256
|
return {
|
|
17178
17257
|
activity: activity === "idle" && completionPending ? "working" : activity,
|
|
17179
|
-
...resident?.status === "idle" ? { readyForInput: true, completionPending } : {}
|
|
17258
|
+
...resident?.status === "idle" ? { readyForInput: true, completionPending } : {},
|
|
17259
|
+
...activity === "missing" ? {} : contentRevisionField(resident)
|
|
17180
17260
|
};
|
|
17181
17261
|
}
|
|
17262
|
+
function contentRevisionField(resident) {
|
|
17263
|
+
try {
|
|
17264
|
+
return { contentRevision: sessionContentRevision(resident) };
|
|
17265
|
+
} catch {
|
|
17266
|
+
return {};
|
|
17267
|
+
}
|
|
17268
|
+
}
|
|
17269
|
+
function sessionContentRevision(resident) {
|
|
17270
|
+
if (!resident)
|
|
17271
|
+
return eventEmitter.generation;
|
|
17272
|
+
const transcript = readTranscriptVersion(resident);
|
|
17273
|
+
return `${eventEmitter.generation}:${transcript.epoch}.${transcript.revision}:${backgroundTaskRevision(resident)}`;
|
|
17274
|
+
}
|
|
17182
17275
|
var sessionActivityBatch = new Hono2;
|
|
17183
17276
|
sessionActivityBatch.post(SESSION_ACTIVITY_BATCH_PATH, async (c) => {
|
|
17184
17277
|
const answer = await answerSessionActivityBatch(c.req.raw.body, readSessionActivityObservation, {
|
|
@@ -18449,13 +18542,20 @@ session.get("/:id/activity", async (c) => {
|
|
|
18449
18542
|
session.get("/:id/runtime-health", (c) => {
|
|
18450
18543
|
return c.json(sessionRuntimeHealthBody(peekSession(c.req.param("id"))));
|
|
18451
18544
|
});
|
|
18452
|
-
session.get("/:id/dispatch", (c) => {
|
|
18545
|
+
session.get("/:id/dispatch", async (c) => {
|
|
18546
|
+
const answer = (dispatch) => c.json({ dispatch });
|
|
18453
18547
|
const requestId = c.req.query("requestId")?.trim();
|
|
18454
18548
|
if (!requestId)
|
|
18455
|
-
return
|
|
18456
|
-
const
|
|
18457
|
-
const
|
|
18458
|
-
|
|
18549
|
+
return answer("unknown");
|
|
18550
|
+
const id = c.req.param("id");
|
|
18551
|
+
const state = getPromptDispatchState(id, requestId);
|
|
18552
|
+
if (state === "processing" || state === "already-processed")
|
|
18553
|
+
return answer("dispatched");
|
|
18554
|
+
if (state === "new") {
|
|
18555
|
+
return answer(restoredDispatchClaimLost(peekSession(id), requestId) ? "lost" : "unknown");
|
|
18556
|
+
}
|
|
18557
|
+
const lost = await persistedDispatchClaimLost(id, requestId).catch(() => false);
|
|
18558
|
+
return answer(lost ? "lost" : "unknown");
|
|
18459
18559
|
});
|
|
18460
18560
|
session.get("/:id/questions", (c) => {
|
|
18461
18561
|
const id = c.req.param("id");
|
|
@@ -18869,6 +18969,9 @@ function serializeEventData(event) {
|
|
|
18869
18969
|
}
|
|
18870
18970
|
var MAX_PENDING_SSE_FRAMES = 1000;
|
|
18871
18971
|
var MAX_PENDING_SSE_BYTES = 16 * 1024 * 1024;
|
|
18972
|
+
function observationFrameData(sessionId) {
|
|
18973
|
+
return JSON.stringify(sessionId === undefined ? {} : { sessionId });
|
|
18974
|
+
}
|
|
18872
18975
|
var MAX_REPLAY_SSE_FRAMES = 512;
|
|
18873
18976
|
var MAX_REPLAY_SSE_BYTES = 4 * 1024 * 1024;
|
|
18874
18977
|
var REPLAY_IDLE_RETENTION_MS = 60000;
|
|
@@ -18885,7 +18988,8 @@ function createReplayBuffer(limits = {}) {
|
|
|
18885
18988
|
id: `${generation}:${revision}`,
|
|
18886
18989
|
event: event.type,
|
|
18887
18990
|
data,
|
|
18888
|
-
bytes: Buffer.byteLength(data) + Buffer.byteLength(event.type)
|
|
18991
|
+
bytes: Buffer.byteLength(data) + Buffer.byteLength(event.type),
|
|
18992
|
+
...event.sessionId === undefined ? {} : { sessionId: event.sessionId }
|
|
18889
18993
|
};
|
|
18890
18994
|
frames.push(frame);
|
|
18891
18995
|
bytes += frame.bytes;
|
|
@@ -19063,6 +19167,7 @@ function createEventsRouter(limits = {}) {
|
|
|
19063
19167
|
if (!isOpen)
|
|
19064
19168
|
throw new Error("SSE request aborted");
|
|
19065
19169
|
}, () => closeConnection("write backlog exceeded its cap"), { maxPendingFrames, maxPendingBytes });
|
|
19170
|
+
const observe = c.req.query("observe") === "1";
|
|
19066
19171
|
const requestedCursorValue = c.req.header("last-event-id") ?? c.req.query("since");
|
|
19067
19172
|
const requestedCursor = parseReplayCursor(requestedCursorValue);
|
|
19068
19173
|
const cursorWasSupplied = requestedCursorValue !== undefined;
|
|
@@ -19071,12 +19176,12 @@ function createEventsRouter(limits = {}) {
|
|
|
19071
19176
|
let replaying = true;
|
|
19072
19177
|
let keepaliveInterval;
|
|
19073
19178
|
let unsubscribe = () => {};
|
|
19074
|
-
const releaseReplayRetention = replayRetention.acquire();
|
|
19179
|
+
const releaseReplayRetention = observe ? () => {} : replayRetention.acquire();
|
|
19075
19180
|
try {
|
|
19076
19181
|
unsubscribe = eventEmitter.subscribe((event, revision) => {
|
|
19077
19182
|
if (!isOpen)
|
|
19078
19183
|
return;
|
|
19079
|
-
const data = serializeEventData(event);
|
|
19184
|
+
const data = observe ? observationFrameData(event.sessionId) : serializeEventData(event);
|
|
19080
19185
|
const frame = {
|
|
19081
19186
|
revision,
|
|
19082
19187
|
id: formatReplayCursor(revision),
|
|
@@ -19113,7 +19218,8 @@ function createEventsRouter(limits = {}) {
|
|
|
19113
19218
|
status: "connected",
|
|
19114
19219
|
timestamp: connectedAt,
|
|
19115
19220
|
replayed: replay.frames.length,
|
|
19116
|
-
resetRequired: replay.resetRequired
|
|
19221
|
+
resetRequired: replay.resetRequired,
|
|
19222
|
+
...observe ? { observe: true } : {}
|
|
19117
19223
|
})
|
|
19118
19224
|
});
|
|
19119
19225
|
if (replay.resetRequired) {
|
|
@@ -19123,8 +19229,9 @@ function createEventsRouter(limits = {}) {
|
|
|
19123
19229
|
data: JSON.stringify({ through: formatReplayCursor(replayCeiling) })
|
|
19124
19230
|
});
|
|
19125
19231
|
} else {
|
|
19126
|
-
for (const frame of replay.frames)
|
|
19127
|
-
await writeFrame(frame);
|
|
19232
|
+
for (const frame of replay.frames) {
|
|
19233
|
+
await writeFrame(observe ? { ...frame, data: observationFrameData(frame.sessionId) } : frame);
|
|
19234
|
+
}
|
|
19128
19235
|
}
|
|
19129
19236
|
const drained = pendingLiveFrames.splice(0);
|
|
19130
19237
|
pendingLiveBytes = 0;
|