replicas-cli 0.2.602 → 0.2.604
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/index.cjs +1921 -1855
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -22358,58 +22358,6 @@ function date4(params) {
|
|
|
22358
22358
|
// ../node_modules/.bun/zod@4.4.3/node_modules/zod/v4/classic/external.js
|
|
22359
22359
|
config(en_default());
|
|
22360
22360
|
|
|
22361
|
-
// ../shared/src/analytics/types.ts
|
|
22362
|
-
var agentCredentialSnapshotSchema = external_exports.object({
|
|
22363
|
-
method: external_exports.enum(CREDENTIAL_METHOD),
|
|
22364
|
-
scope: external_exports.enum(CREDENTIAL_SCOPE),
|
|
22365
|
-
revision: external_exports.string().optional()
|
|
22366
|
-
});
|
|
22367
|
-
function isAuthMethod(value) {
|
|
22368
|
-
return typeof value === "string" && Object.values(CREDENTIAL_METHOD).some((method) => method === value);
|
|
22369
|
-
}
|
|
22370
|
-
function isCredentialScope(value) {
|
|
22371
|
-
return typeof value === "string" && CREDENTIAL_SCOPES.some((scope) => scope === value);
|
|
22372
|
-
}
|
|
22373
|
-
|
|
22374
|
-
// ../shared/src/event.ts
|
|
22375
|
-
var CLAUDE_PARTIAL_MESSAGE_EVENT_TYPE = "claude-partial-message";
|
|
22376
|
-
function coerceClaudePartialMessagePayload(payload) {
|
|
22377
|
-
const streamId = payload.streamId;
|
|
22378
|
-
if (typeof streamId !== "string" || !streamId) return null;
|
|
22379
|
-
const parentToolUseId = payload.parent_tool_use_id;
|
|
22380
|
-
const text = typeof payload.text === "string" && payload.text ? payload.text : void 0;
|
|
22381
|
-
const thinking = typeof payload.thinking === "string" && payload.thinking ? payload.thinking : void 0;
|
|
22382
|
-
if (!text && !thinking) return null;
|
|
22383
|
-
return {
|
|
22384
|
-
streamId,
|
|
22385
|
-
parent_tool_use_id: typeof parentToolUseId === "string" ? parentToolUseId : null,
|
|
22386
|
-
...text ? { text } : {},
|
|
22387
|
-
...thinking ? { thinking } : {},
|
|
22388
|
-
status: payload.status === "completed" ? "completed" : "in_progress"
|
|
22389
|
-
};
|
|
22390
|
-
}
|
|
22391
|
-
var USER_MESSAGE_ID_PAYLOAD_KEY = "replicasMessageId";
|
|
22392
|
-
var CODEX_ASP_ITEM_ID_PAYLOAD_KEY = "codexAspItemId";
|
|
22393
|
-
var CODEX_QUOTA_STATUS_EVENT_TYPE = "codex-quota-status";
|
|
22394
|
-
var CHAT_INTERRUPTED_EVENT_TYPE = "replicas-interrupted";
|
|
22395
|
-
var AUTH_FALLBACK_EVENT_TYPE = "auth-fallback";
|
|
22396
|
-
function coerceAuthFallbackPayload(payload) {
|
|
22397
|
-
const { provider, reason, exhaustedMethod, exhaustedScope, candidateMethod, candidateScope, status, detail } = payload;
|
|
22398
|
-
if (typeof provider !== "string" || !isValidCodingAgentProvider(provider) || reason !== "rate_limit" && reason !== "out_of_credits" || !isAuthMethod(exhaustedMethod) || !isAuthMethod(candidateMethod) || !isCredentialScope(candidateScope) || status !== "switched" && status !== "failed") {
|
|
22399
|
-
return null;
|
|
22400
|
-
}
|
|
22401
|
-
return {
|
|
22402
|
-
provider,
|
|
22403
|
-
reason,
|
|
22404
|
-
exhaustedMethod,
|
|
22405
|
-
...isCredentialScope(exhaustedScope) ? { exhaustedScope } : {},
|
|
22406
|
-
candidateMethod,
|
|
22407
|
-
candidateScope,
|
|
22408
|
-
status,
|
|
22409
|
-
...typeof detail === "string" && detail ? { detail } : {}
|
|
22410
|
-
};
|
|
22411
|
-
}
|
|
22412
|
-
|
|
22413
22361
|
// ../shared/src/aster.ts
|
|
22414
22362
|
var ASTER_MODELS = [
|
|
22415
22363
|
"kimi-k3",
|
|
@@ -22663,319 +22611,529 @@ function classifyCanvasFilename(filename) {
|
|
|
22663
22611
|
return CANVAS_KIND_BY_EXTENSION[ext] ?? { kind: "other", mimeType: "application/octet-stream" };
|
|
22664
22612
|
}
|
|
22665
22613
|
|
|
22666
|
-
// ../shared/src/
|
|
22667
|
-
var
|
|
22668
|
-
var
|
|
22669
|
-
|
|
22670
|
-
|
|
22671
|
-
|
|
22672
|
-
|
|
22673
|
-
|
|
22674
|
-
|
|
22675
|
-
|
|
22676
|
-
|
|
22677
|
-
|
|
22678
|
-
|
|
22679
|
-
|
|
22680
|
-
|
|
22681
|
-
|
|
22682
|
-
|
|
22683
|
-
|
|
22684
|
-
|
|
22685
|
-
|
|
22686
|
-
|
|
22687
|
-
|
|
22688
|
-
|
|
22689
|
-
|
|
22690
|
-
|
|
22691
|
-
|
|
22692
|
-
|
|
22693
|
-
|
|
22694
|
-
|
|
22695
|
-
|
|
22696
|
-
|
|
22697
|
-
|
|
22698
|
-
|
|
22699
|
-
|
|
22700
|
-
|
|
22701
|
-
|
|
22702
|
-
|
|
22703
|
-
|
|
22704
|
-
|
|
22705
|
-
seatPriceCents: 3e4,
|
|
22706
|
-
features: [
|
|
22707
|
-
"Unlimited manual workspace minutes",
|
|
22708
|
-
"15,000 automated workspace minutes per month",
|
|
22709
|
-
"Unlimited repositories",
|
|
22710
|
-
"Unlimited automations",
|
|
22711
|
-
"Warm pools and warm hooks",
|
|
22712
|
-
"Higher API rate limits",
|
|
22713
|
-
"Access to a static egress IP",
|
|
22714
|
-
"Auto-upgraded sandbox resources (4 vCPU, 32 GB disk, 16 GB memory)",
|
|
22715
|
-
"Shared Slack support channel"
|
|
22716
|
-
]
|
|
22717
|
-
},
|
|
22718
|
-
enterprise: {
|
|
22719
|
-
id: "enterprise",
|
|
22720
|
-
name: "Enterprise",
|
|
22721
|
-
monthlyPrice: 0,
|
|
22722
|
-
seatPriceCents: 0,
|
|
22723
|
-
features: [
|
|
22724
|
-
"Unlimited manual workspace minutes",
|
|
22725
|
-
"Unlimited automated workspace minutes",
|
|
22726
|
-
"Unlimited automations",
|
|
22727
|
-
"Custom warm hooks and pools",
|
|
22728
|
-
"Custom API rates",
|
|
22729
|
-
"Custom rate limits",
|
|
22730
|
-
"Shared Slack support channel",
|
|
22731
|
-
"SOC 2",
|
|
22732
|
-
"Data Processing Agreement (DPA)",
|
|
22733
|
-
"SCIM user provisioning",
|
|
22734
|
-
"Custom security and privacy settings"
|
|
22735
|
-
]
|
|
22736
|
-
}
|
|
22737
|
-
};
|
|
22738
|
-
var TEAM_PLAN = PLANS.team;
|
|
22739
|
-
var ENTERPRISE_PLAN = PLANS.enterprise;
|
|
22614
|
+
// ../shared/src/chat-fork.ts
|
|
22615
|
+
var quotaLimitKindSchema = external_exports.enum(["rate_limit", "out_of_credits"]);
|
|
22616
|
+
var chatForkInfoSchema = external_exports.object({
|
|
22617
|
+
source: external_exports.object({
|
|
22618
|
+
chatId: external_exports.string().min(1),
|
|
22619
|
+
provider: external_exports.enum(VALID_AGENT_PROVIDERS),
|
|
22620
|
+
title: external_exports.string()
|
|
22621
|
+
}),
|
|
22622
|
+
trigger: external_exports.enum(["manual", "auto"]),
|
|
22623
|
+
reason: quotaLimitKindSchema.optional(),
|
|
22624
|
+
state: external_exports.enum(["preparing", "ready", "failed"]),
|
|
22625
|
+
error: external_exports.string().optional(),
|
|
22626
|
+
startedAt: external_exports.string(),
|
|
22627
|
+
completedAt: external_exports.string().optional()
|
|
22628
|
+
});
|
|
22629
|
+
var forkChatRequestSchema = external_exports.object({
|
|
22630
|
+
provider: external_exports.enum(VALID_AGENT_PROVIDERS),
|
|
22631
|
+
model: external_exports.string().min(1).optional(),
|
|
22632
|
+
thinkingLevel: external_exports.enum(VALID_THINKING_LEVELS).optional(),
|
|
22633
|
+
title: external_exports.string().min(1).max(200).optional(),
|
|
22634
|
+
id: external_exports.string().uuid().optional(),
|
|
22635
|
+
clientRequestId: external_exports.string().min(1).max(128).optional(),
|
|
22636
|
+
enableInteractiveTools: external_exports.boolean().optional(),
|
|
22637
|
+
// Server-injected by the monolith from the authenticated request; never trusted from clients.
|
|
22638
|
+
senderUserId: external_exports.string().optional(),
|
|
22639
|
+
senderEmail: external_exports.string().optional(),
|
|
22640
|
+
senderDisplayName: external_exports.string().optional(),
|
|
22641
|
+
senderAvatarUrl: external_exports.string().optional()
|
|
22642
|
+
});
|
|
22643
|
+
var chatForkFallbackResponseSchema = external_exports.object({
|
|
22644
|
+
provider: external_exports.enum(VALID_AGENT_PROVIDERS).nullable(),
|
|
22645
|
+
model: external_exports.string().min(1).optional(),
|
|
22646
|
+
thinkingLevel: external_exports.enum(VALID_THINKING_LEVELS).optional()
|
|
22647
|
+
});
|
|
22648
|
+
var agentQuotaExhaustedPayloadSchema = external_exports.object({
|
|
22649
|
+
provider: external_exports.enum(VALID_CODING_AGENT_PROVIDERS),
|
|
22650
|
+
reason: quotaLimitKindSchema,
|
|
22651
|
+
detail: external_exports.string().optional()
|
|
22652
|
+
});
|
|
22740
22653
|
|
|
22741
|
-
// ../shared/src/
|
|
22742
|
-
|
|
22743
|
-
|
|
22654
|
+
// ../shared/src/analytics/types.ts
|
|
22655
|
+
var agentCredentialSnapshotSchema = external_exports.object({
|
|
22656
|
+
method: external_exports.enum(CREDENTIAL_METHOD),
|
|
22657
|
+
scope: external_exports.enum(CREDENTIAL_SCOPE),
|
|
22658
|
+
revision: external_exports.string().optional()
|
|
22659
|
+
});
|
|
22660
|
+
function isAuthMethod(value) {
|
|
22661
|
+
return typeof value === "string" && Object.values(CREDENTIAL_METHOD).some((method) => method === value);
|
|
22744
22662
|
}
|
|
22745
|
-
function
|
|
22746
|
-
|
|
22747
|
-
const portNumber = Number(port);
|
|
22748
|
-
if (!isValidPort(portNumber)) throw new Error("Port must be a number between 1 and 65535");
|
|
22749
|
-
return portNumber;
|
|
22663
|
+
function isCredentialScope(value) {
|
|
22664
|
+
return typeof value === "string" && CREDENTIAL_SCOPES.some((scope) => scope === value);
|
|
22750
22665
|
}
|
|
22751
22666
|
|
|
22752
|
-
// ../shared/src/
|
|
22753
|
-
var
|
|
22754
|
-
|
|
22755
|
-
|
|
22756
|
-
|
|
22757
|
-
|
|
22758
|
-
|
|
22759
|
-
|
|
22760
|
-
|
|
22761
|
-
|
|
22762
|
-
|
|
22763
|
-
|
|
22764
|
-
|
|
22765
|
-
}
|
|
22766
|
-
|
|
22767
|
-
}
|
|
22768
|
-
|
|
22769
|
-
|
|
22770
|
-
var
|
|
22771
|
-
|
|
22772
|
-
|
|
22773
|
-
|
|
22774
|
-
|
|
22775
|
-
};
|
|
22776
|
-
|
|
22777
|
-
|
|
22778
|
-
|
|
22779
|
-
|
|
22780
|
-
|
|
22781
|
-
|
|
22782
|
-
|
|
22783
|
-
}
|
|
22784
|
-
|
|
22785
|
-
|
|
22667
|
+
// ../shared/src/event.ts
|
|
22668
|
+
var CLAUDE_PARTIAL_MESSAGE_EVENT_TYPE = "claude-partial-message";
|
|
22669
|
+
function coerceClaudePartialMessagePayload(payload) {
|
|
22670
|
+
const streamId = payload.streamId;
|
|
22671
|
+
if (typeof streamId !== "string" || !streamId) return null;
|
|
22672
|
+
const parentToolUseId = payload.parent_tool_use_id;
|
|
22673
|
+
const text = typeof payload.text === "string" && payload.text ? payload.text : void 0;
|
|
22674
|
+
const thinking = typeof payload.thinking === "string" && payload.thinking ? payload.thinking : void 0;
|
|
22675
|
+
if (!text && !thinking) return null;
|
|
22676
|
+
return {
|
|
22677
|
+
streamId,
|
|
22678
|
+
parent_tool_use_id: typeof parentToolUseId === "string" ? parentToolUseId : null,
|
|
22679
|
+
...text ? { text } : {},
|
|
22680
|
+
...thinking ? { thinking } : {},
|
|
22681
|
+
status: payload.status === "completed" ? "completed" : "in_progress"
|
|
22682
|
+
};
|
|
22683
|
+
}
|
|
22684
|
+
var USER_MESSAGE_ID_PAYLOAD_KEY = "replicasMessageId";
|
|
22685
|
+
var CODEX_ASP_ITEM_ID_PAYLOAD_KEY = "codexAspItemId";
|
|
22686
|
+
var CODEX_QUOTA_STATUS_EVENT_TYPE = "codex-quota-status";
|
|
22687
|
+
var CHAT_INTERRUPTED_EVENT_TYPE = "replicas-interrupted";
|
|
22688
|
+
var AUTH_FALLBACK_EVENT_TYPE = "auth-fallback";
|
|
22689
|
+
function coerceAuthFallbackPayload(payload) {
|
|
22690
|
+
const { provider, reason, exhaustedMethod, exhaustedScope, candidateMethod, candidateScope, status, detail } = payload;
|
|
22691
|
+
if (typeof provider !== "string" || !isValidCodingAgentProvider(provider) || reason !== "rate_limit" && reason !== "out_of_credits" || !isAuthMethod(exhaustedMethod) || !isAuthMethod(candidateMethod) || !isCredentialScope(candidateScope) || status !== "switched" && status !== "failed") {
|
|
22692
|
+
return null;
|
|
22693
|
+
}
|
|
22694
|
+
return {
|
|
22695
|
+
provider,
|
|
22696
|
+
reason,
|
|
22697
|
+
exhaustedMethod,
|
|
22698
|
+
...isCredentialScope(exhaustedScope) ? { exhaustedScope } : {},
|
|
22699
|
+
candidateMethod,
|
|
22700
|
+
candidateScope,
|
|
22701
|
+
status,
|
|
22702
|
+
...typeof detail === "string" && detail ? { detail } : {}
|
|
22703
|
+
};
|
|
22704
|
+
}
|
|
22786
22705
|
|
|
22787
|
-
// ../shared/src/
|
|
22788
|
-
var
|
|
22789
|
-
|
|
22790
|
-
|
|
22791
|
-
|
|
22792
|
-
|
|
22793
|
-
|
|
22794
|
-
|
|
22795
|
-
|
|
22796
|
-
|
|
22797
|
-
|
|
22798
|
-
|
|
22799
|
-
|
|
22800
|
-
|
|
22801
|
-
|
|
22802
|
-
|
|
22803
|
-
|
|
22804
|
-
|
|
22805
|
-
|
|
22806
|
-
|
|
22807
|
-
|
|
22808
|
-
|
|
22809
|
-
|
|
22810
|
-
|
|
22811
|
-
|
|
22812
|
-
|
|
22813
|
-
|
|
22814
|
-
|
|
22815
|
-
|
|
22816
|
-
|
|
22817
|
-
|
|
22818
|
-
|
|
22819
|
-
|
|
22820
|
-
|
|
22821
|
-
|
|
22822
|
-
|
|
22823
|
-
|
|
22824
|
-
|
|
22825
|
-
|
|
22826
|
-
|
|
22827
|
-
|
|
22828
|
-
|
|
22829
|
-
|
|
22830
|
-
|
|
22831
|
-
|
|
22832
|
-
|
|
22833
|
-
|
|
22834
|
-
|
|
22835
|
-
|
|
22836
|
-
|
|
22837
|
-
|
|
22838
|
-
|
|
22839
|
-
|
|
22840
|
-
|
|
22841
|
-
|
|
22842
|
-
|
|
22843
|
-
|
|
22844
|
-
|
|
22845
|
-
|
|
22846
|
-
|
|
22847
|
-
|
|
22848
|
-
UP_SCRIPT: "/usr/local/lib/replicas-egress-up",
|
|
22849
|
-
DOWN_SCRIPT: "/usr/local/lib/replicas-egress-down"
|
|
22850
|
-
};
|
|
22851
|
-
var EGRESS_WORKSPACE_CONFIG_FILE = "/opt/replicas/egress-config.env";
|
|
22852
|
-
var EGRESS_WORKSPACE_SHELL_VARS = {
|
|
22853
|
-
EGRESS_WORKSPACE_CONFIG_FILE,
|
|
22854
|
-
EGRESS_TUNNEL_SERVICE,
|
|
22855
|
-
EGRESS_TUNNEL_INTERFACE,
|
|
22856
|
-
EGRESS_DNS_SERVERS: EGRESS_DNS_SERVERS.join(" "),
|
|
22857
|
-
EGRESS_EXIT_IP_ENDPOINTS: EGRESS_EXIT_IP_ENDPOINTS.join(" ")
|
|
22858
|
-
};
|
|
22706
|
+
// ../shared/src/engine/v1.ts
|
|
22707
|
+
var createChatRequestSchema = external_exports.object({
|
|
22708
|
+
id: external_exports.string().uuid().optional(),
|
|
22709
|
+
createdAt: external_exports.string().datetime().optional(),
|
|
22710
|
+
provider: external_exports.enum(VALID_AGENT_PROVIDERS),
|
|
22711
|
+
title: external_exports.string().min(1).optional(),
|
|
22712
|
+
parentChatId: external_exports.string().uuid().optional(),
|
|
22713
|
+
clientRequestId: external_exports.string().min(1).max(128).optional()
|
|
22714
|
+
});
|
|
22715
|
+
var sendChatMessageRequestSchema = external_exports.object({
|
|
22716
|
+
messageId: external_exports.string().min(1).optional(),
|
|
22717
|
+
submittedAt: external_exports.string().datetime().optional(),
|
|
22718
|
+
message: external_exports.string().min(1),
|
|
22719
|
+
model: external_exports.string().optional(),
|
|
22720
|
+
customInstructions: external_exports.string().optional(),
|
|
22721
|
+
planMode: external_exports.boolean().optional(),
|
|
22722
|
+
images: external_exports.array(external_exports.object({
|
|
22723
|
+
type: external_exports.literal("image"),
|
|
22724
|
+
source: external_exports.discriminatedUnion("type", [
|
|
22725
|
+
external_exports.object({ type: external_exports.literal("base64"), media_type: external_exports.enum(IMAGE_MEDIA_TYPES), data: external_exports.string().min(1) }),
|
|
22726
|
+
external_exports.object({ type: external_exports.literal("url"), url: external_exports.string().url() })
|
|
22727
|
+
])
|
|
22728
|
+
})).optional(),
|
|
22729
|
+
canvasUploadIds: external_exports.array(external_exports.string().min(1)).optional(),
|
|
22730
|
+
thinkingLevel: external_exports.enum(VALID_THINKING_LEVELS).optional(),
|
|
22731
|
+
goalMode: external_exports.boolean().optional(),
|
|
22732
|
+
fastMode: external_exports.boolean().optional(),
|
|
22733
|
+
enableInteractiveTools: external_exports.boolean().optional(),
|
|
22734
|
+
type: external_exports.string().min(1).optional(),
|
|
22735
|
+
merge: external_exports.boolean().optional(),
|
|
22736
|
+
idempotencyKey: external_exports.string().min(1).max(128).optional(),
|
|
22737
|
+
automationId: external_exports.string().optional(),
|
|
22738
|
+
environmentId: external_exports.string().min(1).optional(),
|
|
22739
|
+
senderUserId: external_exports.string().optional(),
|
|
22740
|
+
senderEmail: external_exports.string().optional(),
|
|
22741
|
+
senderDisplayName: external_exports.string().optional(),
|
|
22742
|
+
senderAvatarUrl: external_exports.string().optional(),
|
|
22743
|
+
errorNotificationTarget: external_exports.discriminatedUnion("type", [
|
|
22744
|
+
external_exports.object({ type: external_exports.literal("slack") }),
|
|
22745
|
+
external_exports.object({ type: external_exports.literal("linear"), sessionId: external_exports.string().min(1) }),
|
|
22746
|
+
external_exports.object({
|
|
22747
|
+
type: external_exports.literal("code_host"),
|
|
22748
|
+
provider: external_exports.enum(["github", "gitlab"]),
|
|
22749
|
+
resource: external_exports.enum(["issue", "pull_request"]),
|
|
22750
|
+
repositoryId: external_exports.string().min(1),
|
|
22751
|
+
resourceNumber: external_exports.number().int().positive()
|
|
22752
|
+
}),
|
|
22753
|
+
external_exports.object({ type: external_exports.literal("automation"), executionId: external_exports.string().min(1) })
|
|
22754
|
+
]).optional()
|
|
22755
|
+
}).passthrough();
|
|
22756
|
+
function normalizeCodexAspTranscriptStatus(status, failed = false) {
|
|
22757
|
+
if (failed || status === "failed" || status === "declined") return "failed";
|
|
22758
|
+
if (status === "completed") return "completed";
|
|
22759
|
+
return "in_progress";
|
|
22760
|
+
}
|
|
22761
|
+
function getCodexAspTurnResponse(turn) {
|
|
22762
|
+
const finalAnswer = turn.items.find((item) => item.type === "agentMessage" && item.phase === "final_answer");
|
|
22763
|
+
if (finalAnswer) return finalAnswer;
|
|
22764
|
+
if (normalizeCodexAspTranscriptStatus(turn.status) === "in_progress") return null;
|
|
22765
|
+
return turn.items.findLast((item) => item.type === "agentMessage") ?? null;
|
|
22766
|
+
}
|
|
22859
22767
|
|
|
22860
|
-
// ../shared/src/
|
|
22861
|
-
var
|
|
22862
|
-
|
|
22863
|
-
|
|
22864
|
-
|
|
22865
|
-
|
|
22866
|
-
|
|
22867
|
-
|
|
22868
|
-
|
|
22869
|
-
environment: `${HOME_PATH}/environment`,
|
|
22870
|
-
analytics: `${HOME_PATH}/analytics`,
|
|
22871
|
-
memory: `${HOME_PATH}/memory`,
|
|
22872
|
-
dashboard: DASHBOARD_PATH,
|
|
22873
|
-
agents: `${DASHBOARD_PATH}/agents`,
|
|
22874
|
-
integrations: `${DASHBOARD_PATH}/integrations`,
|
|
22875
|
-
integrationsGithub: `${DASHBOARD_PATH}/integrations/github`,
|
|
22876
|
-
integrationsGitlab: `${DASHBOARD_PATH}/integrations/gitlab`,
|
|
22877
|
-
settings: `${DASHBOARD_PATH}/settings`,
|
|
22878
|
-
billing: `${DASHBOARD_PATH}/billing`,
|
|
22879
|
-
members: `${DASHBOARD_PATH}/members`,
|
|
22880
|
-
"audit-logs": `${DASHBOARD_PATH}/audit-logs`,
|
|
22881
|
-
accountAgents: `${DASHBOARD_PATH}/account/agents`,
|
|
22882
|
-
accountProfile: `${DASHBOARD_PATH}/account/profile`,
|
|
22883
|
-
accountConnections: `${DASHBOARD_PATH}/account/connections`,
|
|
22884
|
-
accountIntegrations: `${DASHBOARD_PATH}/account/integrations`,
|
|
22885
|
-
accountApiKeys: `${DASHBOARD_PATH}/account/api-keys`,
|
|
22886
|
-
accountPreferences: `${DASHBOARD_PATH}/account/preferences`,
|
|
22887
|
-
fullscreenWorkspaces: "/workspaces"
|
|
22888
|
-
};
|
|
22889
|
-
var LEGACY_WEB_APP_PATHS = {
|
|
22890
|
-
app: "/app",
|
|
22891
|
-
dashboardWorkspaces: `${DASHBOARD_PATH}/workspaces`
|
|
22892
|
-
};
|
|
22893
|
-
function getWorkspaceDashboardUrl(workspaceId, options = {}) {
|
|
22894
|
-
const { encodeWorkspaceId = true, mode, mediaId } = options;
|
|
22895
|
-
const workspaceIdValue = encodeWorkspaceId ? encodeURIComponent(workspaceId) : workspaceId;
|
|
22896
|
-
const params = [];
|
|
22897
|
-
if (mode) params.push(`mode=${encodeURIComponent(mode)}`);
|
|
22898
|
-
if (mediaId) params.push(`media=${encodeURIComponent(mediaId)}`);
|
|
22899
|
-
const query = params.length > 0 ? `?${params.join("&")}` : "";
|
|
22900
|
-
return `${DEFAULT_WEB_APP_URL}${WEB_APP_PATHS.fullscreenWorkspaces}/${workspaceIdValue}${query}`;
|
|
22768
|
+
// ../shared/src/display-message/types.ts
|
|
22769
|
+
var BACKGROUND_TASK_SUBTYPES = /* @__PURE__ */ new Set([
|
|
22770
|
+
"task_started",
|
|
22771
|
+
"task_progress",
|
|
22772
|
+
"task_updated",
|
|
22773
|
+
"task_notification"
|
|
22774
|
+
]);
|
|
22775
|
+
function isBackgroundTaskSubtype(subtype) {
|
|
22776
|
+
return typeof subtype === "string" && BACKGROUND_TASK_SUBTYPES.has(subtype);
|
|
22901
22777
|
}
|
|
22902
|
-
function
|
|
22903
|
-
return
|
|
22778
|
+
function optionalString(value) {
|
|
22779
|
+
return typeof value === "string" ? value : void 0;
|
|
22904
22780
|
}
|
|
22905
|
-
function
|
|
22906
|
-
|
|
22781
|
+
function coerceBackgroundTaskPayload(payload) {
|
|
22782
|
+
if (!isRecord(payload)) return null;
|
|
22783
|
+
const subtype = payload.subtype;
|
|
22784
|
+
if (!isBackgroundTaskSubtype(subtype)) return null;
|
|
22785
|
+
const taskId = payload.task_id;
|
|
22786
|
+
if (typeof taskId !== "string" || !taskId) return null;
|
|
22787
|
+
const patch = isRecord(payload.patch) ? {
|
|
22788
|
+
status: optionalString(payload.patch.status),
|
|
22789
|
+
description: optionalString(payload.patch.description),
|
|
22790
|
+
error: optionalString(payload.patch.error),
|
|
22791
|
+
isBackgrounded: optionalBoolean(payload.patch.is_backgrounded)
|
|
22792
|
+
} : void 0;
|
|
22793
|
+
const usage = isRecord(payload.usage) ? {
|
|
22794
|
+
totalTokens: optionalNumber(payload.usage.total_tokens),
|
|
22795
|
+
toolUses: optionalNumber(payload.usage.tool_uses),
|
|
22796
|
+
durationMs: optionalNumber(payload.usage.duration_ms)
|
|
22797
|
+
} : void 0;
|
|
22798
|
+
return {
|
|
22799
|
+
subtype,
|
|
22800
|
+
taskId,
|
|
22801
|
+
description: optionalString(payload.description),
|
|
22802
|
+
summary: optionalString(payload.summary),
|
|
22803
|
+
outputFile: optionalString(payload.output_file),
|
|
22804
|
+
status: optionalString(payload.status),
|
|
22805
|
+
taskType: optionalString(payload.task_type),
|
|
22806
|
+
workflowName: optionalString(payload.workflow_name),
|
|
22807
|
+
prompt: optionalString(payload.prompt),
|
|
22808
|
+
lastToolName: optionalString(payload.last_tool_name),
|
|
22809
|
+
usage,
|
|
22810
|
+
ambient: optionalBoolean(payload.ambient),
|
|
22811
|
+
patch
|
|
22812
|
+
};
|
|
22813
|
+
}
|
|
22814
|
+
function optionalNumber(value) {
|
|
22815
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
22816
|
+
}
|
|
22817
|
+
function optionalBoolean(value) {
|
|
22818
|
+
return typeof value === "boolean" ? value : void 0;
|
|
22819
|
+
}
|
|
22820
|
+
function normalizeBackgroundTaskStatus(status) {
|
|
22821
|
+
if (status === "completed" || status === "failed" || status === "stopped") {
|
|
22822
|
+
return status;
|
|
22823
|
+
}
|
|
22824
|
+
if (status === "killed") {
|
|
22825
|
+
return "stopped";
|
|
22826
|
+
}
|
|
22827
|
+
return "in_progress";
|
|
22907
22828
|
}
|
|
22908
22829
|
|
|
22909
|
-
// ../shared/src/
|
|
22910
|
-
var
|
|
22911
|
-
Drive the workspace's Linux desktop - open a browser, click, type, scroll, screenshot, record - via the \`replicas computer\` CLI. Every Replicas workspace boots with a live H.264 and Opus stream published as an authenticated preview, so a \`Desktop\` tab is always available in the dashboard. Use \`replicas computer info\` to get the viewer URL when you want to share it (e.g. point a user on Slack at the live stream).
|
|
22912
|
-
|
|
22913
|
-
**Reference:** \`references/COMPUTER-USE.md\`
|
|
22914
|
-
|
|
22915
|
-
Use this when:
|
|
22916
|
-
- A task requires interacting with a website, web app, or desktop application that has no usable API
|
|
22917
|
-
- You want the user to watch the agent work - they can open the \`Desktop\` tab, or you can share the URL from \`replicas computer info\`
|
|
22918
|
-
- You're testing UI changes in a browser before reporting them as done
|
|
22919
|
-
- You want to record a screen capture of a task as proof to share back`;
|
|
22920
|
-
var REFERENCE = `# Computer use (Linux desktop control)
|
|
22921
|
-
|
|
22922
|
-
Every Replicas workspace boots with a full Linux desktop stack - Xvfb (1920\xD71080), openbox, tint2, PulseAudio, ffmpeg, and Google Chrome. The engine auto-registers the H.264 and Opus viewer (port 6080) as an authenticated preview at startup, so the dashboard \`Desktop\` tab is live the moment the workspace is up. You drive the desktop through the \`replicas computer\` CLI.
|
|
22923
|
-
|
|
22924
|
-
Use this for anything the user can't reasonably do via an API - clicking around web apps, filling forms, testing UI changes, dragging files between desktop apps, recording a walkthrough.
|
|
22925
|
-
|
|
22926
|
-
## When to use it
|
|
22927
|
-
|
|
22928
|
-
- **Prefer real APIs first.** If a task has a CLI or HTTP API (GitHub, Linear, Slack, Replicas itself), use that. Driving a UI is slower, flakier, and less auditable.
|
|
22929
|
-
- **Use it when there's no API**: testing a frontend you just changed, navigating a vendor portal, demonstrating a flow on video.
|
|
22930
|
-
- **Use it when the user wants to watch.** The dashboard already shows a \`Desktop\` tab. If you're talking to the user somewhere else (e.g. Slack), call \`replicas computer info\` to get the viewer URL and paste it in.
|
|
22931
|
-
|
|
22932
|
-
## Never use raw \`xdotool\` / \`scrot\` / \`ffmpeg\` directly
|
|
22933
|
-
|
|
22934
|
-
The CLI is the canonical surface. Chat transcripts that show \`DISPLAY=:99 xdotool key Return\` are noisy and break when the underlying stack changes. Always call the CLI:
|
|
22935
|
-
|
|
22936
|
-
\`\`\`bash
|
|
22937
|
-
# DO
|
|
22938
|
-
replicas computer key Return
|
|
22939
|
-
replicas computer observe /tmp/state.png
|
|
22940
|
-
|
|
22941
|
-
# DON'T
|
|
22942
|
-
DISPLAY=:99 xdotool key Return
|
|
22943
|
-
scrot /tmp/state.png
|
|
22944
|
-
\`\`\`
|
|
22830
|
+
// ../shared/src/display-message/constants.ts
|
|
22831
|
+
var USER_MESSAGE_MATCH_GRACE_PERIOD_MS = 3e4;
|
|
22945
22832
|
|
|
22946
|
-
|
|
22833
|
+
// ../shared/src/json.ts
|
|
22834
|
+
function safeJsonParse(str, fallback) {
|
|
22835
|
+
try {
|
|
22836
|
+
return JSON.parse(str);
|
|
22837
|
+
} catch {
|
|
22838
|
+
return fallback;
|
|
22839
|
+
}
|
|
22840
|
+
}
|
|
22947
22841
|
|
|
22948
|
-
|
|
22949
|
-
|
|
22950
|
-
|
|
22951
|
-
|
|
22952
|
-
|
|
22842
|
+
// ../shared/src/display-message/parsers/utils.ts
|
|
22843
|
+
var INTERRUPTED_MESSAGE_REGEX = /^\[Request interrupted by user.*\]$/;
|
|
22844
|
+
function userMessageImages(value) {
|
|
22845
|
+
if (!Array.isArray(value)) return void 0;
|
|
22846
|
+
const images = value.filter((item) => isRecord(item) && item.type === "image" && typeof item.mediaType === "string" && typeof item.data === "string");
|
|
22847
|
+
return images.length > 0 ? images : void 0;
|
|
22848
|
+
}
|
|
22849
|
+
function stringifyDisplayValue(value) {
|
|
22850
|
+
if (value === void 0 || value === null) return void 0;
|
|
22851
|
+
if (typeof value === "string") return value;
|
|
22852
|
+
try {
|
|
22853
|
+
return JSON.stringify(value, null, 2);
|
|
22854
|
+
} catch {
|
|
22855
|
+
return String(value);
|
|
22856
|
+
}
|
|
22857
|
+
}
|
|
22858
|
+
function upsertDisplayMessage(messages, message) {
|
|
22859
|
+
const index = messages.findIndex((candidate) => candidate.id === message.id);
|
|
22860
|
+
if (index === -1) messages.push(message);
|
|
22861
|
+
else messages[index] = message;
|
|
22862
|
+
}
|
|
22863
|
+
function applyToolInputEvent(event, messages, provider, state, questionFilter) {
|
|
22864
|
+
if (event.type === "replicas-tool-input-request" && typeof event.payload.toolUseId === "string" && typeof event.payload.requestId === "string" && (Array.isArray(event.payload.options) || Array.isArray(event.payload.questions))) {
|
|
22865
|
+
const resolved = state.resolutions.get(event.payload.toolUseId);
|
|
22866
|
+
const inputRequest = {
|
|
22867
|
+
requestId: event.payload.requestId,
|
|
22868
|
+
status: resolved?.selectionId === "aborted" || resolved?.selectionId === "declined" ? "aborted" : resolved ? "resolved" : "pending",
|
|
22869
|
+
...Array.isArray(event.payload.options) ? { options: event.payload.options } : {},
|
|
22870
|
+
...Array.isArray(event.payload.questions) ? { questions: questionFilter ? event.payload.questions.filter(questionFilter) : event.payload.questions } : {},
|
|
22871
|
+
...resolved ? { selectionId: resolved.selectionId } : {},
|
|
22872
|
+
...resolved?.selectionSummary ? { selectionSummary: resolved.selectionSummary } : {}
|
|
22873
|
+
};
|
|
22874
|
+
state.requests.set(event.payload.toolUseId, inputRequest);
|
|
22875
|
+
const message = messages.find((candidate) => candidate.type === "tool_call" && candidate.id === `${provider}-tool-${event.payload.toolUseId}`);
|
|
22876
|
+
if (message) message.inputRequest = inputRequest;
|
|
22877
|
+
return true;
|
|
22878
|
+
}
|
|
22879
|
+
if (event.type === "replicas-tool-input-resolved" && typeof event.payload.toolUseId === "string" && typeof event.payload.selectionId === "string") {
|
|
22880
|
+
const resolved = {
|
|
22881
|
+
selectionId: event.payload.selectionId,
|
|
22882
|
+
...typeof event.payload.selectionSummary === "string" ? { selectionSummary: event.payload.selectionSummary } : {}
|
|
22883
|
+
};
|
|
22884
|
+
state.resolutions.set(event.payload.toolUseId, resolved);
|
|
22885
|
+
const inputRequest = state.requests.get(event.payload.toolUseId);
|
|
22886
|
+
if (inputRequest) {
|
|
22887
|
+
inputRequest.status = resolved.selectionId === "aborted" || resolved.selectionId === "declined" ? "aborted" : "resolved";
|
|
22888
|
+
inputRequest.selectionId = resolved.selectionId;
|
|
22889
|
+
if (resolved.selectionSummary) inputRequest.selectionSummary = resolved.selectionSummary;
|
|
22890
|
+
}
|
|
22891
|
+
return true;
|
|
22892
|
+
}
|
|
22893
|
+
return false;
|
|
22894
|
+
}
|
|
22895
|
+
function parseSkillName(tool, input) {
|
|
22896
|
+
if (typeof tool !== "string") return null;
|
|
22897
|
+
const normalizedTool = tool.toLowerCase();
|
|
22898
|
+
if (normalizedTool.startsWith("skill.")) return tool.slice("skill.".length) || null;
|
|
22899
|
+
if (normalizedTool !== "skill") return null;
|
|
22900
|
+
const parsedInput = typeof input === "string" ? safeJsonParse(input, null) : input;
|
|
22901
|
+
if (!isRecord(parsedInput)) return null;
|
|
22902
|
+
const skillName = parsedInput.skill ?? parsedInput.name;
|
|
22903
|
+
return typeof skillName === "string" && skillName ? skillName : null;
|
|
22904
|
+
}
|
|
22905
|
+
function skillNameFromFilePath(path6) {
|
|
22906
|
+
const skillName = skillNameFromSkillRootPath(path6);
|
|
22907
|
+
if (skillName) return skillName;
|
|
22908
|
+
const parts = path6.split(/[\\/]+/).filter(Boolean);
|
|
22909
|
+
if (parts.length < 2 || parts[parts.length - 1].toLowerCase() !== "skill.md") return null;
|
|
22910
|
+
const fallbackSkillName = parts[parts.length - 2];
|
|
22911
|
+
return fallbackSkillName && fallbackSkillName.toLowerCase() !== "skills" ? fallbackSkillName : null;
|
|
22912
|
+
}
|
|
22913
|
+
function skillNameFromSkillRootPath(path6) {
|
|
22914
|
+
const parts = path6.split(/[\\/]+/).filter(Boolean);
|
|
22915
|
+
const skillsIndex = parts.findLastIndex((part) => part.toLowerCase() === "skills");
|
|
22916
|
+
if (skillsIndex === -1) return null;
|
|
22917
|
+
const firstSkillPart = parts[skillsIndex + 1];
|
|
22918
|
+
const skillName = firstSkillPart?.toLowerCase() === ".system" ? parts[skillsIndex + 2] : firstSkillPart;
|
|
22919
|
+
return skillName && skillName.toLowerCase() !== "skill.md" ? skillName : null;
|
|
22920
|
+
}
|
|
22921
|
+
function parseSkillFilePath(input) {
|
|
22922
|
+
const parsedInput = typeof input === "string" ? safeJsonParse(input, null) : input;
|
|
22923
|
+
if (!isRecord(parsedInput)) return null;
|
|
22924
|
+
const path6 = [parsedInput.path, parsedInput.filePath, parsedInput.file_path].find((value) => typeof value === "string" && value.length > 0);
|
|
22925
|
+
if (!path6) return null;
|
|
22926
|
+
return skillNameFromFilePath(path6);
|
|
22927
|
+
}
|
|
22928
|
+
function skillNameFromToolCall(tool, input) {
|
|
22929
|
+
const directSkillName = parseSkillName(tool, input);
|
|
22930
|
+
if (directSkillName) return directSkillName;
|
|
22931
|
+
if (typeof tool !== "string" || !["read", "read_file", "readfile"].includes(tool.toLowerCase())) return null;
|
|
22932
|
+
return parseSkillFilePath(input);
|
|
22933
|
+
}
|
|
22934
|
+
function createCallDisplayMessage(message) {
|
|
22935
|
+
const skillName = message.server.toLowerCase() === "skills" ? message.tool : skillNameFromToolCall(message.tool, message.input);
|
|
22936
|
+
if (skillName === null) return { ...message, type: "tool_call" };
|
|
22937
|
+
return {
|
|
22938
|
+
id: message.id,
|
|
22939
|
+
type: "skill",
|
|
22940
|
+
skillName,
|
|
22941
|
+
status: message.status,
|
|
22942
|
+
timestamp: message.timestamp
|
|
22943
|
+
};
|
|
22944
|
+
}
|
|
22945
|
+
function insertDisplayMessageByTimestamp(messages, message) {
|
|
22946
|
+
const messageMs = parseTimestampMs(message.timestamp);
|
|
22947
|
+
let index = messages.length;
|
|
22948
|
+
while (index > 0 && parseTimestampMs(messages[index - 1].timestamp) > messageMs) index--;
|
|
22949
|
+
messages.splice(index, 0, message);
|
|
22950
|
+
}
|
|
22953
22951
|
|
|
22954
|
-
|
|
22955
|
-
|
|
22952
|
+
// ../shared/src/display-message/format.ts
|
|
22953
|
+
function unquoteShellArg(value) {
|
|
22954
|
+
const trimmed = value.trim();
|
|
22955
|
+
if (trimmed.length < 2) return trimmed;
|
|
22956
|
+
if (trimmed[0] === "'" && trimmed[trimmed.length - 1] === "'") {
|
|
22957
|
+
return trimmed.slice(1, -1).replace(/'\\''/g, "'");
|
|
22958
|
+
}
|
|
22959
|
+
if (trimmed[0] === '"' && trimmed[trimmed.length - 1] === '"') {
|
|
22960
|
+
return trimmed.slice(1, -1).replace(/\\(["\\$`])/g, "$1");
|
|
22961
|
+
}
|
|
22962
|
+
return trimmed;
|
|
22963
|
+
}
|
|
22964
|
+
function shellPayload(command) {
|
|
22965
|
+
const match = command.trim().match(/^(?:\S*\/)?(?:ba|z|c|fi)?sh\s+-(?:[a-zA-Z]*c[a-zA-Z]*|c)\s+([\s\S]+)$/);
|
|
22966
|
+
return match ? unquoteShellArg(match[1]) : command.trim();
|
|
22967
|
+
}
|
|
22968
|
+
function splitShellWords(command) {
|
|
22969
|
+
const words = [];
|
|
22970
|
+
let word = "";
|
|
22971
|
+
let quote = null;
|
|
22972
|
+
let escaped = false;
|
|
22973
|
+
for (const char of command) {
|
|
22974
|
+
if (escaped) {
|
|
22975
|
+
word += char;
|
|
22976
|
+
escaped = false;
|
|
22977
|
+
continue;
|
|
22978
|
+
}
|
|
22979
|
+
if (char === "\\" && quote !== "'") {
|
|
22980
|
+
escaped = true;
|
|
22981
|
+
continue;
|
|
22982
|
+
}
|
|
22983
|
+
if (quote) {
|
|
22984
|
+
if (char === quote) quote = null;
|
|
22985
|
+
else word += char;
|
|
22986
|
+
continue;
|
|
22987
|
+
}
|
|
22988
|
+
if (char === '"' || char === "'") {
|
|
22989
|
+
quote = char;
|
|
22990
|
+
continue;
|
|
22991
|
+
}
|
|
22992
|
+
if (/\s/.test(char)) {
|
|
22993
|
+
if (word) {
|
|
22994
|
+
words.push(word);
|
|
22995
|
+
word = "";
|
|
22996
|
+
}
|
|
22997
|
+
continue;
|
|
22998
|
+
}
|
|
22999
|
+
word += char;
|
|
23000
|
+
}
|
|
23001
|
+
if (word) words.push(word);
|
|
23002
|
+
return words;
|
|
23003
|
+
}
|
|
23004
|
+
function commandWords(command) {
|
|
23005
|
+
const payload = shellPayload(command);
|
|
23006
|
+
if (!payload || /[;|<>]|&&/.test(payload)) return null;
|
|
23007
|
+
return splitShellWords(payload);
|
|
23008
|
+
}
|
|
23009
|
+
function skillNamesFromCommand(command) {
|
|
23010
|
+
const words = commandWords(command);
|
|
23011
|
+
if (!words) return [];
|
|
23012
|
+
return Array.from(new Set(words.flatMap((word) => {
|
|
23013
|
+
const skillName = skillNameFromSkillRootPath(word);
|
|
23014
|
+
return skillName ? [skillName] : [];
|
|
23015
|
+
})));
|
|
23016
|
+
}
|
|
22956
23017
|
|
|
22957
|
-
|
|
22958
|
-
|
|
23018
|
+
// ../shared/src/urls.ts
|
|
23019
|
+
var DEFAULT_WEB_APP_URL = "https://replicas.dev";
|
|
23020
|
+
var HOME_PATH = "/home";
|
|
23021
|
+
var DASHBOARD_PATH = "/dashboard";
|
|
23022
|
+
var WEB_APP_PATHS = {
|
|
23023
|
+
home: HOME_PATH,
|
|
23024
|
+
onboarding: `${HOME_PATH}/onboarding`,
|
|
23025
|
+
workspaces: `${HOME_PATH}/workspace`,
|
|
23026
|
+
automations: `${HOME_PATH}/automations`,
|
|
23027
|
+
environment: `${HOME_PATH}/environment`,
|
|
23028
|
+
analytics: `${HOME_PATH}/analytics`,
|
|
23029
|
+
memory: `${HOME_PATH}/memory`,
|
|
23030
|
+
dashboard: DASHBOARD_PATH,
|
|
23031
|
+
agents: `${DASHBOARD_PATH}/agents`,
|
|
23032
|
+
integrations: `${DASHBOARD_PATH}/integrations`,
|
|
23033
|
+
integrationsGithub: `${DASHBOARD_PATH}/integrations/github`,
|
|
23034
|
+
integrationsGitlab: `${DASHBOARD_PATH}/integrations/gitlab`,
|
|
23035
|
+
settings: `${DASHBOARD_PATH}/settings`,
|
|
23036
|
+
billing: `${DASHBOARD_PATH}/billing`,
|
|
23037
|
+
members: `${DASHBOARD_PATH}/members`,
|
|
23038
|
+
"audit-logs": `${DASHBOARD_PATH}/audit-logs`,
|
|
23039
|
+
accountAgents: `${DASHBOARD_PATH}/account/agents`,
|
|
23040
|
+
accountProfile: `${DASHBOARD_PATH}/account/profile`,
|
|
23041
|
+
accountConnections: `${DASHBOARD_PATH}/account/connections`,
|
|
23042
|
+
accountIntegrations: `${DASHBOARD_PATH}/account/integrations`,
|
|
23043
|
+
accountApiKeys: `${DASHBOARD_PATH}/account/api-keys`,
|
|
23044
|
+
accountPreferences: `${DASHBOARD_PATH}/account/preferences`,
|
|
23045
|
+
fullscreenWorkspaces: "/workspaces"
|
|
23046
|
+
};
|
|
23047
|
+
var LEGACY_WEB_APP_PATHS = {
|
|
23048
|
+
app: "/app",
|
|
23049
|
+
dashboardWorkspaces: `${DASHBOARD_PATH}/workspaces`
|
|
23050
|
+
};
|
|
23051
|
+
function getWorkspaceDashboardUrl(workspaceId, options = {}) {
|
|
23052
|
+
const { encodeWorkspaceId = true, mode, mediaId } = options;
|
|
23053
|
+
const workspaceIdValue = encodeWorkspaceId ? encodeURIComponent(workspaceId) : workspaceId;
|
|
23054
|
+
const params = [];
|
|
23055
|
+
if (mode) params.push(`mode=${encodeURIComponent(mode)}`);
|
|
23056
|
+
if (mediaId) params.push(`media=${encodeURIComponent(mediaId)}`);
|
|
23057
|
+
const query = params.length > 0 ? `?${params.join("&")}` : "";
|
|
23058
|
+
return `${DEFAULT_WEB_APP_URL}${WEB_APP_PATHS.fullscreenWorkspaces}/${workspaceIdValue}${query}`;
|
|
23059
|
+
}
|
|
23060
|
+
function getOrganizationMediaPath(organizationId, mediaId) {
|
|
23061
|
+
return `/organizations/${encodeURIComponent(organizationId)}/media/${encodeURIComponent(mediaId)}`;
|
|
23062
|
+
}
|
|
23063
|
+
function getOrganizationMediaUrl(organizationId, mediaId, webAppUrl = DEFAULT_WEB_APP_URL) {
|
|
23064
|
+
return `${webAppUrl}${getOrganizationMediaPath(organizationId, mediaId)}`;
|
|
23065
|
+
}
|
|
22959
23066
|
|
|
22960
|
-
|
|
22961
|
-
|
|
22962
|
-
|
|
23067
|
+
// ../shared/src/default-skills/replicas-agent/abilities/computer.ts
|
|
23068
|
+
var SECTION = `### Computer use (Linux desktop control)
|
|
23069
|
+
Drive the workspace's Linux desktop - open a browser, click, type, scroll, screenshot, record - via the \`replicas computer\` CLI. Every Replicas workspace boots with a live H.264 and Opus stream published as an authenticated preview, so a \`Desktop\` tab is always available in the dashboard. Use \`replicas computer info\` to get the viewer URL when you want to share it (e.g. point a user on Slack at the live stream).
|
|
22963
23070
|
|
|
22964
|
-
|
|
22965
|
-
replicas computer record start /tmp/demo.mp4 --fps 60
|
|
22966
|
-
# ... do stuff ...
|
|
22967
|
-
replicas computer record stop
|
|
22968
|
-
replicas media upload /tmp/demo.mp4 --name "Demo recording"
|
|
22969
|
-
\`\`\`
|
|
23071
|
+
**Reference:** \`references/COMPUTER-USE.md\`
|
|
22970
23072
|
|
|
22971
|
-
|
|
23073
|
+
Use this when:
|
|
23074
|
+
- A task requires interacting with a website, web app, or desktop application that has no usable API
|
|
23075
|
+
- You want the user to watch the agent work - they can open the \`Desktop\` tab, or you can share the URL from \`replicas computer info\`
|
|
23076
|
+
- You're testing UI changes in a browser before reporting them as done
|
|
23077
|
+
- You want to record a screen capture of a task as proof to share back`;
|
|
23078
|
+
var REFERENCE = `# Computer use (Linux desktop control)
|
|
22972
23079
|
|
|
22973
|
-
|
|
23080
|
+
Every Replicas workspace boots with a full Linux desktop stack - Xvfb (1920\xD71080), openbox, tint2, PulseAudio, ffmpeg, and Google Chrome. The engine auto-registers the H.264 and Opus viewer (port 6080) as an authenticated preview at startup, so the dashboard \`Desktop\` tab is live the moment the workspace is up. You drive the desktop through the \`replicas computer\` CLI.
|
|
22974
23081
|
|
|
22975
|
-
|
|
22976
|
-
Prints the live desktop viewer URL (\`https://6080-<hash>.replicas.dev/\`). The engine auto-registers this authenticated preview on startup; \`info\` just looks it up. Use it when you want to share the live stream URL with the user out-of-band (e.g. in a Slack reply) - the dashboard \`Desktop\` tab already points at the same URL automatically.
|
|
23082
|
+
Use this for anything the user can't reasonably do via an API - clicking around web apps, filling forms, testing UI changes, dragging files between desktop apps, recording a walkthrough.
|
|
22977
23083
|
|
|
22978
|
-
|
|
23084
|
+
## When to use it
|
|
23085
|
+
|
|
23086
|
+
- **Prefer real APIs first.** If a task has a CLI or HTTP API (GitHub, Linear, Slack, Replicas itself), use that. Driving a UI is slower, flakier, and less auditable.
|
|
23087
|
+
- **Use it when there's no API**: testing a frontend you just changed, navigating a vendor portal, demonstrating a flow on video.
|
|
23088
|
+
- **Use it when the user wants to watch.** The dashboard already shows a \`Desktop\` tab. If you're talking to the user somewhere else (e.g. Slack), call \`replicas computer info\` to get the viewer URL and paste it in.
|
|
23089
|
+
|
|
23090
|
+
## Never use raw \`xdotool\` / \`scrot\` / \`ffmpeg\` directly
|
|
23091
|
+
|
|
23092
|
+
The CLI is the canonical surface. Chat transcripts that show \`DISPLAY=:99 xdotool key Return\` are noisy and break when the underlying stack changes. Always call the CLI:
|
|
23093
|
+
|
|
23094
|
+
\`\`\`bash
|
|
23095
|
+
# DO
|
|
23096
|
+
replicas computer key Return
|
|
23097
|
+
replicas computer observe /tmp/state.png
|
|
23098
|
+
|
|
23099
|
+
# DON'T
|
|
23100
|
+
DISPLAY=:99 xdotool key Return
|
|
23101
|
+
scrot /tmp/state.png
|
|
23102
|
+
\`\`\`
|
|
23103
|
+
|
|
23104
|
+
## Quickstart
|
|
23105
|
+
|
|
23106
|
+
\`\`\`bash
|
|
23107
|
+
# 1) (Optional) Get the live viewer URL so you can share it with the user.
|
|
23108
|
+
# The desktop is already running and the preview is already registered -
|
|
23109
|
+
# this just looks up the URL.
|
|
23110
|
+
replicas computer info
|
|
23111
|
+
|
|
23112
|
+
# 2) Launch a browser on the workspace display.
|
|
23113
|
+
replicas computer launch chrome https://news.ycombinator.com
|
|
23114
|
+
|
|
23115
|
+
# 3) Capture the settled viewport and native accessibility tree together.
|
|
23116
|
+
replicas computer browser-state /tmp/state.png --full
|
|
23117
|
+
|
|
23118
|
+
# 4) Batch actions that use refs from the same state, then capture the semantic diff.
|
|
23119
|
+
replicas computer browser-batch '[{"action":"fill","ref":17,"value":"hello"},{"action":"click","ref":42}]'
|
|
23120
|
+
replicas computer browser-state /tmp/after-click.png
|
|
23121
|
+
|
|
23122
|
+
# 5) (Optional) Record a screencap to share back.
|
|
23123
|
+
replicas computer record start /tmp/demo.mp4 --fps 60
|
|
23124
|
+
# ... do stuff ...
|
|
23125
|
+
replicas computer record stop
|
|
23126
|
+
replicas media upload /tmp/demo.mp4 --name "Demo recording"
|
|
23127
|
+
\`\`\`
|
|
23128
|
+
|
|
23129
|
+
For any external destination, continue with the required delivery flow in \`MEDIA.md\`.
|
|
23130
|
+
|
|
23131
|
+
## Command reference
|
|
23132
|
+
|
|
23133
|
+
### \`replicas computer info\`
|
|
23134
|
+
Prints the live desktop viewer URL (\`https://6080-<hash>.replicas.dev/\`). The engine auto-registers this authenticated preview on startup; \`info\` just looks it up. Use it when you want to share the live stream URL with the user out-of-band (e.g. in a Slack reply) - the dashboard \`Desktop\` tab already points at the same URL automatically.
|
|
23135
|
+
|
|
23136
|
+
If invoked very early in the workspace lifecycle, \`info\` will poll briefly while the engine finishes registering the preview, then error if it's still not available.
|
|
22979
23137
|
|
|
22980
23138
|
### \`replicas computer status\`
|
|
22981
23139
|
Checks and repairs the desktop bridge, then prints which desktop services are running and the active preview URL (if any). Useful for debugging when a tool call seems to be doing nothing.
|
|
@@ -23490,7 +23648,7 @@ If none of these apply, don't upload.
|
|
|
23490
23648
|
| Slack | \`files.getUploadURLExternal\` \u2192 raw-byte POST \u2192 \`files.completeUploadExternal\` | Uploaded file in the channel or thread |
|
|
23491
23649
|
| Linear | \`fileUpload\` mutation \u2192 presigned upload \u2192 issue/comment mutation | Returned \`assetUrl\` in Markdown |
|
|
23492
23650
|
| GitLab | Project \`/uploads\` endpoint with the original bytes | Returned GitLab Markdown |
|
|
23493
|
-
| GitHub |
|
|
23651
|
+
| GitHub | \`gh\` v2.99.0+ \`--attach\` for images and videos; use a Replicas public forge share as the fallback | Native GitHub attachment URL, or a Forge embed fallback |
|
|
23494
23652
|
|
|
23495
23653
|
The dashboard link is the subtitle and jump-back path. It is never a substitute for the destination upload.
|
|
23496
23654
|
|
|
@@ -23521,7 +23679,7 @@ Names are normalized to hyphen-case (spaces become hyphens, e.g. \`Login page\`
|
|
|
23521
23679
|
For each media file, the CLI prints an embed line and a dashboard link:
|
|
23522
23680
|
|
|
23523
23681
|
1. Default and organization access print \`Replicas chat embed: \`; this authenticated URL renders inline in Replicas chat **only** \u2014 see below.
|
|
23524
|
-
2. Public access (\`--access public\` or \`--share\`) prints \`\` as the Forge embed instead. This is the public, stable bearer URL
|
|
23682
|
+
2. Public access (\`--access public\` or \`--share\`) prints \`\` as the Forge embed instead. This is the public, stable bearer URL for GitHub fallback embeds when native \`--attach\` is unavailable and sharing is authorized.
|
|
23525
23683
|
3. \`View in Replicas: <deep-link>\` is a per-file dashboard URL of the form \`https://replicas.dev/workspaces/<workspace-id>?media=<media-id>\` that opens directly to that specific file.
|
|
23526
23684
|
|
|
23527
23685
|
Match each "View in Replicas" line to the embed line directly above it \u2014 that's the deep link for that file.
|
|
@@ -23550,7 +23708,7 @@ replicas media upload screenshot.png --name "Login page" --access public
|
|
|
23550
23708
|
|---|---|---|
|
|
23551
23709
|
| \`https://api.replicas.dev/v1/media/<id>\` (inside \`\`) | Authenticated API redirect to a presigned blob \u2014 requires the Replicas chat session | **Only** in the Replicas chat reply. Nowhere else. |
|
|
23552
23710
|
| \`https://replicas.dev/organizations/<organization-id>/media/<media-id>\` | Organization-only page printed by \`--access organization\` | Pull requests and other places where every viewer belongs to the Replicas organization. |
|
|
23553
|
-
| \`https://api.replicas.dev/v1/media/public/<id>/<token>\` | Opt-in public bearer URL printed by \`--access public\` or \`--share\` | The Replicas chat reply and GitHub embeds, for image, video, or audio media. |
|
|
23711
|
+
| \`https://api.replicas.dev/v1/media/public/<id>/<token>\` | Opt-in public bearer URL printed by \`--access public\` or \`--share\` | The Replicas chat reply and GitHub fallback embeds, for image, video, or audio media. |
|
|
23554
23712
|
| \`https://replicas.dev/workspaces/<workspace-id>?media=<media-id>\` | Authenticated dashboard deep link that opens the media file in the workspace | Everywhere external: Slack, GitHub, GitLab, Linear, PR bodies, comments, emails. |
|
|
23555
23713
|
|
|
23556
23714
|
### NEVER link the API redirect URL outside the Replicas chat reply
|
|
@@ -23594,7 +23752,7 @@ After \`replicas media upload\` succeeds, external delivery has two required fol
|
|
|
23594
23752
|
|
|
23595
23753
|
A link alone is not enough. An upload without the dashboard link is not enough. Do both.
|
|
23596
23754
|
|
|
23597
|
-
Slack, Linear, and GitLab receive the original bytes through their native upload APIs. GitHub
|
|
23755
|
+
Slack, Linear, and GitLab receive the original bytes through their native upload APIs. GitHub image and video attachments use \`gh --attach\` when the installed CLI and host support it; use an explicit Replicas public share only as the fallback.
|
|
23598
23756
|
|
|
23599
23757
|
### Slack \u2014 embed natively via the 3-step external file upload flow
|
|
23600
23758
|
|
|
@@ -23706,26 +23864,50 @@ The same flow works for issue bodies (use \`issueCreate\` / \`issueUpdate\` with
|
|
|
23706
23864
|
|
|
23707
23865
|
Never paste the \`api.replicas.dev/v1/media/<id>\` URL into a Linear body or comment \u2014 it will render as a broken image to anyone outside your Replicas chat.
|
|
23708
23866
|
|
|
23709
|
-
### GitHub:
|
|
23867
|
+
### GitHub: native image and video attachments
|
|
23868
|
+
|
|
23869
|
+
GitHub CLI v2.99.0+ supports a repeatable \`--attach\` flag on \`gh pr create\`, \`gh pr edit\`, and \`gh pr comment\` for GitHub.com and GitHub Enterprise Cloud. It uploads local images and videos to GitHub and writes the resulting attachment URL into the PR body or comment; it requires push access to the repository. GitHub Enterprise Server and unsupported media kinds are not covered by this path. See [GitHub's attachment guide](https://docs.github.com/en/github-cli/github-cli/attaching-files-with-github-cli).
|
|
23870
|
+
|
|
23871
|
+
Check \`gh --version\` before choosing the delivery path. On a supported host with v2.99.0 or later:
|
|
23872
|
+
|
|
23873
|
+
1. Run \`replicas media upload\` with the original file first, without \`--share\`. Keep the matching **View in Replicas** dashboard link for the PR.
|
|
23874
|
+
2. Put each local file path in the Markdown body where the attachment should appear, and place its dashboard link next to it.
|
|
23875
|
+
3. Pass the same original path once with \`--attach\`. GitHub CLI rewrites a matching local reference in place, preserving its alt text; an unreferenced attachment is appended to the body.
|
|
23876
|
+
|
|
23877
|
+
\`\`\`markdown
|
|
23878
|
+
Before the change:
|
|
23710
23879
|
|
|
23711
|
-
|
|
23880
|
+

|
|
23881
|
+
[View in Replicas](https://replicas.dev/workspaces/<workspace-id>?media=<before-media-id>)
|
|
23882
|
+
\`\`\`
|
|
23712
23883
|
|
|
23713
23884
|
\`\`\`bash
|
|
23714
|
-
|
|
23885
|
+
gh pr create \\
|
|
23886
|
+
--title "Describe the change" \\
|
|
23887
|
+
--body-file /tmp/pr-body.md \\
|
|
23888
|
+
--attach /tmp/before.png
|
|
23889
|
+
|
|
23890
|
+
gh pr edit 456 --body-file /tmp/pr-body.md --attach /tmp/after.png
|
|
23891
|
+
gh pr comment 456 --body-file /tmp/comment.md --attach /tmp/result.mp4
|
|
23715
23892
|
\`\`\`
|
|
23716
23893
|
|
|
23717
|
-
|
|
23894
|
+
Repeat \`--attach\` for multiple files, up to 50 per command. For an appended image, add alt text after the path with \`#\`, for example \`--attach './error.png#Error state'\`. To render a video as a player, its local Markdown reference must be the only content in its paragraph. Do not paste a Replicas authenticated API URL into the body, and do not emulate GitHub's undocumented browser upload endpoint.
|
|
23895
|
+
|
|
23896
|
+
### GitHub attachment fallback
|
|
23897
|
+
|
|
23898
|
+
If \`--attach\` is unavailable, the target is GitHub Enterprise Server, the file is not an image or video, or the native upload fails, keep the Replicas dashboard link and report the limitation. For an inline screenshot or video poster, create a Replicas public forge share only for a public repository or after explicit consent to publish media from a private repository, then use the printed \`Forge embed\` Markdown:
|
|
23899
|
+
|
|
23900
|
+
\`\`\`bash
|
|
23901
|
+
replicas media upload /tmp/screenshot.png --name "PR screenshot" --share
|
|
23902
|
+
\`\`\`
|
|
23718
23903
|
|
|
23719
|
-
|
|
23720
|
-
2. Generate a poster image from the recording: \`ffmpeg -i /tmp/demo.mp4 -frames:v 1 /tmp/demo-poster.png\`.
|
|
23721
|
-
3. Upload the poster with \`--share\`.
|
|
23722
|
-
4. Wrap the poster embed in a link to the recording's **View in Replicas** URL.
|
|
23904
|
+
For a fallback recording preview, upload the MP4 normally, generate a poster with \`ffmpeg -i /tmp/demo.mp4 -frames:v 1 /tmp/demo-poster.png\`, share the poster, and link its embed to the recording's **View in Replicas** URL:
|
|
23723
23905
|
|
|
23724
23906
|
\`\`\`markdown
|
|
23725
23907
|
[](<recording-dashboard-url>)
|
|
23726
23908
|
\`\`\`
|
|
23727
23909
|
|
|
23728
|
-
Public forge shares are unauthenticated bearer capabilities.
|
|
23910
|
+
Public forge shares are unauthenticated bearer capabilities. Revoke with \`replicas media revoke <media-id>\` **only** when the user asks or the media should intentionally stop rendering; never as routine post-task cleanup, since revoking breaks every embed already posted on the PR.
|
|
23729
23911
|
|
|
23730
23912
|
For a self-contained HTML report, upload it with \`--access organization\` and put the printed \`Forge link\` Markdown in the PR body or comment. GitHub cannot render the page inline, so use the normal link rather than image syntax. HTML pages cannot be shared publicly.
|
|
23731
23913
|
|
|
@@ -24500,7 +24682,9 @@ var DEFAULT_USER_PREFERENCES = {
|
|
|
24500
24682
|
open_links_in_desktop_app: false,
|
|
24501
24683
|
default_fast_mode: false,
|
|
24502
24684
|
agent_defaults: { ...EMPTY_AGENT_DEFAULT_SETTINGS },
|
|
24503
|
-
credential_priority: null
|
|
24685
|
+
credential_priority: null,
|
|
24686
|
+
chat_fork_fallbacks_enabled: false,
|
|
24687
|
+
chat_fork_fallback_providers: []
|
|
24504
24688
|
};
|
|
24505
24689
|
function defaultReplicasAgentAbilities() {
|
|
24506
24690
|
const abilities = {};
|
|
@@ -24530,980 +24714,24 @@ function removeReplicasInstructions(text) {
|
|
|
24530
24714
|
return removeTag(text, REPLICAS_INSTRUCTIONS_TAG);
|
|
24531
24715
|
}
|
|
24532
24716
|
|
|
24533
|
-
// ../shared/src/
|
|
24534
|
-
|
|
24535
|
-
|
|
24536
|
-
// ../shared/src/warm-hooks.ts
|
|
24537
|
-
var DEFAULT_WARM_HOOK_TIMEOUT_MS = 60 * 60 * 1e3;
|
|
24538
|
-
var MAX_WARM_HOOK_TIMEOUT_MS = 120 * 60 * 1e3;
|
|
24539
|
-
var DEFAULT_START_HOOK_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
24540
|
-
var HOOK_EXEC_MAX_BUFFER_BYTES = 10 * 1024 * 1024;
|
|
24541
|
-
|
|
24542
|
-
// ../shared/src/replicas-config.ts
|
|
24543
|
-
var REPLICAS_CONFIG_FILENAMES = ["replicas.json", "replicas.yaml", "replicas.yml"];
|
|
24544
|
-
|
|
24545
|
-
// ../shared/src/headless-agent.ts
|
|
24546
|
-
var headlessAgentRequestBaseSchema = external_exports.object({
|
|
24547
|
-
agent: external_exports.custom(
|
|
24548
|
-
(value) => typeof value === "string" && isValidCodingAgentProvider(value)
|
|
24549
|
-
),
|
|
24550
|
-
model: external_exports.string().min(1),
|
|
24551
|
-
prompt: external_exports.string(),
|
|
24552
|
-
workingDirectory: external_exports.string().min(1),
|
|
24553
|
-
timeoutSeconds: external_exports.number().int().min(1).max(1800).default(300),
|
|
24554
|
-
codexOauthTokens: external_exports.object({ accessToken: external_exports.string(), accountId: external_exports.string() }).optional()
|
|
24555
|
-
});
|
|
24556
|
-
var headlessAgentInputFileSchema = external_exports.object({
|
|
24557
|
-
path: external_exports.string().min(1),
|
|
24558
|
-
downloadUrl: external_exports.url()
|
|
24559
|
-
});
|
|
24560
|
-
var headlessAgentOutputFileSchema = external_exports.object({
|
|
24561
|
-
path: external_exports.string().min(1),
|
|
24562
|
-
uploadUrl: external_exports.url(),
|
|
24563
|
-
contentType: external_exports.string().min(1),
|
|
24564
|
-
minChars: external_exports.number().int().positive().optional(),
|
|
24565
|
-
maxChars: external_exports.number().int().positive().optional()
|
|
24566
|
-
});
|
|
24567
|
-
var headlessAgentRequestSchema = external_exports.discriminatedUnion("mode", [
|
|
24568
|
-
headlessAgentRequestBaseSchema.extend({
|
|
24569
|
-
mode: external_exports.literal("structured"),
|
|
24570
|
-
outputSchema: external_exports.record(external_exports.string(), external_exports.json())
|
|
24571
|
-
}),
|
|
24572
|
-
headlessAgentRequestBaseSchema.extend({
|
|
24573
|
-
mode: external_exports.literal("filesystem"),
|
|
24574
|
-
inputFiles: external_exports.array(headlessAgentInputFileSchema),
|
|
24575
|
-
outputFiles: external_exports.array(headlessAgentOutputFileSchema),
|
|
24576
|
-
sensitiveValues: external_exports.array(external_exports.string())
|
|
24577
|
-
})
|
|
24578
|
-
]);
|
|
24579
|
-
var headlessFilesystemAgentResultSchema = external_exports.object({
|
|
24580
|
-
message: external_exports.string(),
|
|
24581
|
-
files: external_exports.record(external_exports.string(), external_exports.object({
|
|
24582
|
-
sha256: external_exports.string().regex(/^[a-f0-9]{64}$/),
|
|
24583
|
-
sizeBytes: external_exports.number().int().nonnegative()
|
|
24584
|
-
}))
|
|
24585
|
-
});
|
|
24586
|
-
|
|
24587
|
-
// ../shared/src/errors.ts
|
|
24588
|
-
var TRANSIENT_NETWORK_ERROR_PATTERNS = [
|
|
24589
|
-
/socket connection was closed unexpectedly/,
|
|
24590
|
-
/fetch failed/,
|
|
24591
|
-
/network error/,
|
|
24592
|
-
/network request failed/,
|
|
24593
|
-
/econnreset/,
|
|
24594
|
-
/econnrefused/,
|
|
24595
|
-
/etimedout/,
|
|
24596
|
-
/enotfound/,
|
|
24597
|
-
/eai_again/,
|
|
24598
|
-
/und_err_socket/,
|
|
24599
|
-
/und_err_connect_timeout/,
|
|
24600
|
-
/headers timeout/,
|
|
24601
|
-
/body timeout/,
|
|
24602
|
-
/connection reset/,
|
|
24603
|
-
/connection closed/,
|
|
24604
|
-
/closed unexpectedly/
|
|
24605
|
-
];
|
|
24606
|
-
var HTTP_CONTEXT_PATTERN = /(api error|request|response|status|http)/;
|
|
24607
|
-
var HTTP_STATUS_PATTERN = /(^|[^0-9])([1-5][0-9]{2})(?=$|[^0-9])/g;
|
|
24608
|
-
function isTransientErrorText(text, options = {}) {
|
|
24609
|
-
const normalized = text.toLowerCase();
|
|
24610
|
-
if (!normalized) return false;
|
|
24611
|
-
if (TRANSIENT_NETWORK_ERROR_PATTERNS.some((pattern) => pattern.test(normalized))) return true;
|
|
24612
|
-
if (options.includeRateLimit && /rate limit/.test(normalized)) return true;
|
|
24613
|
-
if (options.extraPatterns?.some((pattern) => pattern.test(normalized))) return true;
|
|
24614
|
-
const httpStatuses = new Set(options.httpStatuses ?? []);
|
|
24615
|
-
const httpStatusClasses = new Set(options.httpStatusClasses ?? []);
|
|
24616
|
-
if (httpStatuses.size === 0 && httpStatusClasses.size === 0) return false;
|
|
24617
|
-
if (options.requireHttpContext !== false && !HTTP_CONTEXT_PATTERN.test(normalized)) return false;
|
|
24618
|
-
for (const match of normalized.matchAll(HTTP_STATUS_PATTERN)) {
|
|
24619
|
-
const status = Number(match[2]);
|
|
24620
|
-
if (httpStatuses.has(status) || httpStatusClasses.has(Math.floor(status / 100))) return true;
|
|
24621
|
-
}
|
|
24622
|
-
return false;
|
|
24717
|
+
// ../shared/src/display-message/parsers/codex-parser.ts
|
|
24718
|
+
function getStatusFromExitCode(exitCode) {
|
|
24719
|
+
return exitCode === 0 ? "completed" : "failed";
|
|
24623
24720
|
}
|
|
24624
|
-
|
|
24625
|
-
|
|
24626
|
-
|
|
24627
|
-
|
|
24628
|
-
// ../shared/src/version.ts
|
|
24629
|
-
function compareVersions(v1, v2) {
|
|
24630
|
-
const parts1 = v1.split(".").map(Number);
|
|
24631
|
-
const parts2 = v2.split(".").map(Number);
|
|
24632
|
-
for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {
|
|
24633
|
-
const num1 = parts1[i] || 0;
|
|
24634
|
-
const num2 = parts2[i] || 0;
|
|
24635
|
-
if (num1 > num2) return 1;
|
|
24636
|
-
if (num1 < num2) return -1;
|
|
24637
|
-
}
|
|
24638
|
-
return 0;
|
|
24721
|
+
function getPayloadString(event, key) {
|
|
24722
|
+
const value = event.payload?.[key];
|
|
24723
|
+
return typeof value === "string" ? value : null;
|
|
24639
24724
|
}
|
|
24640
|
-
|
|
24641
|
-
|
|
24642
|
-
|
|
24643
|
-
id: external_exports.string().uuid().optional(),
|
|
24644
|
-
createdAt: external_exports.string().datetime().optional(),
|
|
24645
|
-
provider: external_exports.enum(VALID_AGENT_PROVIDERS),
|
|
24646
|
-
title: external_exports.string().min(1).optional(),
|
|
24647
|
-
parentChatId: external_exports.string().uuid().optional(),
|
|
24648
|
-
clientRequestId: external_exports.string().min(1).max(128).optional()
|
|
24649
|
-
});
|
|
24650
|
-
var sendChatMessageRequestSchema = external_exports.object({
|
|
24651
|
-
messageId: external_exports.string().min(1).optional(),
|
|
24652
|
-
submittedAt: external_exports.string().datetime().optional(),
|
|
24653
|
-
message: external_exports.string().min(1),
|
|
24654
|
-
model: external_exports.string().optional(),
|
|
24655
|
-
customInstructions: external_exports.string().optional(),
|
|
24656
|
-
planMode: external_exports.boolean().optional(),
|
|
24657
|
-
images: external_exports.array(external_exports.object({
|
|
24658
|
-
type: external_exports.literal("image"),
|
|
24659
|
-
source: external_exports.discriminatedUnion("type", [
|
|
24660
|
-
external_exports.object({ type: external_exports.literal("base64"), media_type: external_exports.enum(IMAGE_MEDIA_TYPES), data: external_exports.string().min(1) }),
|
|
24661
|
-
external_exports.object({ type: external_exports.literal("url"), url: external_exports.string().url() })
|
|
24662
|
-
])
|
|
24663
|
-
})).optional(),
|
|
24664
|
-
canvasUploadIds: external_exports.array(external_exports.string().min(1)).optional(),
|
|
24665
|
-
thinkingLevel: external_exports.enum(VALID_THINKING_LEVELS).optional(),
|
|
24666
|
-
goalMode: external_exports.boolean().optional(),
|
|
24667
|
-
fastMode: external_exports.boolean().optional(),
|
|
24668
|
-
enableInteractiveTools: external_exports.boolean().optional(),
|
|
24669
|
-
type: external_exports.string().min(1).optional(),
|
|
24670
|
-
merge: external_exports.boolean().optional(),
|
|
24671
|
-
idempotencyKey: external_exports.string().min(1).max(128).optional(),
|
|
24672
|
-
automationId: external_exports.string().optional(),
|
|
24673
|
-
environmentId: external_exports.string().min(1).optional(),
|
|
24674
|
-
senderUserId: external_exports.string().optional(),
|
|
24675
|
-
senderEmail: external_exports.string().optional(),
|
|
24676
|
-
senderDisplayName: external_exports.string().optional(),
|
|
24677
|
-
senderAvatarUrl: external_exports.string().optional(),
|
|
24678
|
-
errorNotificationTarget: external_exports.discriminatedUnion("type", [
|
|
24679
|
-
external_exports.object({ type: external_exports.literal("slack") }),
|
|
24680
|
-
external_exports.object({ type: external_exports.literal("linear"), sessionId: external_exports.string().min(1) }),
|
|
24681
|
-
external_exports.object({
|
|
24682
|
-
type: external_exports.literal("code_host"),
|
|
24683
|
-
provider: external_exports.enum(["github", "gitlab"]),
|
|
24684
|
-
resource: external_exports.enum(["issue", "pull_request"]),
|
|
24685
|
-
repositoryId: external_exports.string().min(1),
|
|
24686
|
-
resourceNumber: external_exports.number().int().positive()
|
|
24687
|
-
}),
|
|
24688
|
-
external_exports.object({ type: external_exports.literal("automation"), executionId: external_exports.string().min(1) })
|
|
24689
|
-
]).optional()
|
|
24690
|
-
}).passthrough();
|
|
24691
|
-
function normalizeCodexAspTranscriptStatus(status, failed = false) {
|
|
24692
|
-
if (failed || status === "failed" || status === "declined") return "failed";
|
|
24693
|
-
if (status === "completed") return "completed";
|
|
24694
|
-
return "in_progress";
|
|
24725
|
+
function displayId(event, eventIndex, prefix) {
|
|
24726
|
+
const stableId = getPayloadString(event, USER_MESSAGE_ID_PAYLOAD_KEY) ?? getPayloadString(event, CODEX_ASP_ITEM_ID_PAYLOAD_KEY);
|
|
24727
|
+
return stableId ? `${prefix}-${stableId}` : `${prefix}-${event.timestamp}-${eventIndex}`;
|
|
24695
24728
|
}
|
|
24696
|
-
function
|
|
24697
|
-
const
|
|
24698
|
-
|
|
24699
|
-
|
|
24700
|
-
|
|
24701
|
-
}
|
|
24702
|
-
|
|
24703
|
-
// ../shared/src/routes/plugin-catalog.ts
|
|
24704
|
-
var EXPLICIT_PLUGIN_CATALOG = [
|
|
24705
|
-
{
|
|
24706
|
-
id: "attio",
|
|
24707
|
-
backend: "composio",
|
|
24708
|
-
toolkit: "attio",
|
|
24709
|
-
authType: "oauth",
|
|
24710
|
-
category: "business",
|
|
24711
|
-
name: "Attio",
|
|
24712
|
-
description: "Manage CRM records, people, companies, lists, and notes."
|
|
24713
|
-
},
|
|
24714
|
-
{
|
|
24715
|
-
id: "calendly",
|
|
24716
|
-
backend: "composio",
|
|
24717
|
-
toolkit: "calendly",
|
|
24718
|
-
authType: "oauth",
|
|
24719
|
-
category: "productivity",
|
|
24720
|
-
name: "Calendly",
|
|
24721
|
-
description: "Manage event types, scheduled events, invitees, and scheduling links."
|
|
24722
|
-
},
|
|
24723
|
-
{
|
|
24724
|
-
id: "clickhouse",
|
|
24725
|
-
backend: "composio",
|
|
24726
|
-
toolkit: "clickhouse",
|
|
24727
|
-
authType: "basic",
|
|
24728
|
-
category: "data",
|
|
24729
|
-
name: "ClickHouse",
|
|
24730
|
-
description: "Manage databases, tables, schemas, and queries."
|
|
24731
|
-
},
|
|
24732
|
-
{
|
|
24733
|
-
id: "cloudflare",
|
|
24734
|
-
backend: "composio",
|
|
24735
|
-
toolkit: "cloudflare_api_key",
|
|
24736
|
-
authType: "api_key",
|
|
24737
|
-
category: "data",
|
|
24738
|
-
name: "Cloudflare",
|
|
24739
|
-
description: "Manage zones, DNS records, analytics, and security settings."
|
|
24740
|
-
},
|
|
24741
|
-
{
|
|
24742
|
-
id: "e2b",
|
|
24743
|
-
toolkit: "e2b",
|
|
24744
|
-
backend: "native",
|
|
24745
|
-
authType: "api_key",
|
|
24746
|
-
category: "data",
|
|
24747
|
-
name: "E2B",
|
|
24748
|
-
description: "Create secure cloud sandboxes and run commands in them."
|
|
24749
|
-
},
|
|
24750
|
-
{
|
|
24751
|
-
id: "gmail",
|
|
24752
|
-
backend: "composio",
|
|
24753
|
-
toolkit: "gmail",
|
|
24754
|
-
authType: "oauth",
|
|
24755
|
-
category: "productivity",
|
|
24756
|
-
name: "Gmail",
|
|
24757
|
-
description: "Manage messages, threads, attachments, labels, and mailbox settings."
|
|
24758
|
-
},
|
|
24759
|
-
{
|
|
24760
|
-
id: "googleads",
|
|
24761
|
-
backend: "composio",
|
|
24762
|
-
toolkit: "googleads",
|
|
24763
|
-
authType: "oauth",
|
|
24764
|
-
category: "data",
|
|
24765
|
-
name: "Google Ads",
|
|
24766
|
-
description: "Manage campaigns, customers, accounts, and reporting data."
|
|
24767
|
-
},
|
|
24768
|
-
{
|
|
24769
|
-
id: "googledocs",
|
|
24770
|
-
backend: "composio",
|
|
24771
|
-
toolkit: "googledocs",
|
|
24772
|
-
authType: "oauth",
|
|
24773
|
-
category: "productivity",
|
|
24774
|
-
name: "Google Docs",
|
|
24775
|
-
description: "Manage documents, structure, comments, and exported content."
|
|
24776
|
-
},
|
|
24777
|
-
{
|
|
24778
|
-
id: "googledrive",
|
|
24779
|
-
backend: "composio",
|
|
24780
|
-
toolkit: "googledrive",
|
|
24781
|
-
authType: "oauth",
|
|
24782
|
-
category: "productivity",
|
|
24783
|
-
name: "Google Drive",
|
|
24784
|
-
description: "Manage files, folders, metadata, permissions, and shared drives."
|
|
24785
|
-
},
|
|
24786
|
-
{
|
|
24787
|
-
id: "googlesearch",
|
|
24788
|
-
backend: "composio",
|
|
24789
|
-
toolkit: "google_search_console",
|
|
24790
|
-
authType: "oauth",
|
|
24791
|
-
category: "data",
|
|
24792
|
-
name: "Google Search",
|
|
24793
|
-
description: "Manage Search Console performance, indexing, sites, and sitemaps."
|
|
24794
|
-
},
|
|
24795
|
-
{
|
|
24796
|
-
id: "googlesheets",
|
|
24797
|
-
backend: "composio",
|
|
24798
|
-
toolkit: "googlesheets",
|
|
24799
|
-
authType: "oauth",
|
|
24800
|
-
category: "productivity",
|
|
24801
|
-
name: "Google Sheets",
|
|
24802
|
-
description: "Manage spreadsheets, worksheets, ranges, tables, and charts."
|
|
24803
|
-
},
|
|
24804
|
-
{
|
|
24805
|
-
id: "linkedin",
|
|
24806
|
-
backend: "composio",
|
|
24807
|
-
toolkit: "linkedin",
|
|
24808
|
-
authType: "oauth",
|
|
24809
|
-
category: "business",
|
|
24810
|
-
name: "LinkedIn",
|
|
24811
|
-
description: "Manage profiles, organizations, posts, and professional activity."
|
|
24812
|
-
},
|
|
24813
|
-
{
|
|
24814
|
-
id: "modal",
|
|
24815
|
-
backend: "native",
|
|
24816
|
-
toolkit: "modal",
|
|
24817
|
-
authType: "basic",
|
|
24818
|
-
category: "data",
|
|
24819
|
-
name: "Modal",
|
|
24820
|
-
description: "Invoke deployed functions through Modal compute."
|
|
24821
|
-
},
|
|
24822
|
-
{
|
|
24823
|
-
id: "posthog",
|
|
24824
|
-
backend: "composio",
|
|
24825
|
-
toolkit: "posthog",
|
|
24826
|
-
authType: "api_key",
|
|
24827
|
-
category: "data",
|
|
24828
|
-
name: "PostHog",
|
|
24829
|
-
description: "Manage projects, events, insights, dashboards, flags, and recordings."
|
|
24830
|
-
},
|
|
24831
|
-
{
|
|
24832
|
-
id: "planetscale",
|
|
24833
|
-
toolkit: "planetscale",
|
|
24834
|
-
backend: "native",
|
|
24835
|
-
authType: "oauth",
|
|
24836
|
-
category: "data",
|
|
24837
|
-
name: "PlanetScale",
|
|
24838
|
-
description: "Manage organizations, databases, branches, deploy requests, and Insights."
|
|
24839
|
-
},
|
|
24840
|
-
{
|
|
24841
|
-
id: "stripe",
|
|
24842
|
-
backend: "composio",
|
|
24843
|
-
toolkit: "stripe",
|
|
24844
|
-
authType: "oauth",
|
|
24845
|
-
category: "business",
|
|
24846
|
-
name: "Stripe",
|
|
24847
|
-
description: "Manage customers, payments, invoices, subscriptions, and balances."
|
|
24848
|
-
},
|
|
24849
|
-
{
|
|
24850
|
-
id: "pangram",
|
|
24851
|
-
backend: "native",
|
|
24852
|
-
toolkit: "pangram",
|
|
24853
|
-
authType: "api_key",
|
|
24854
|
-
category: "data",
|
|
24855
|
-
name: "Pangram",
|
|
24856
|
-
description: "Analyze text for AI generation and plagiarism signals."
|
|
24857
|
-
},
|
|
24858
|
-
{
|
|
24859
|
-
id: "vercel",
|
|
24860
|
-
backend: "native",
|
|
24861
|
-
toolkit: "vercel",
|
|
24862
|
-
authType: "api_key",
|
|
24863
|
-
category: "data",
|
|
24864
|
-
name: "Vercel",
|
|
24865
|
-
description: "Manage projects, deployments, logs, domains, and infrastructure."
|
|
24866
|
-
},
|
|
24867
|
-
{
|
|
24868
|
-
id: "turbopuffer",
|
|
24869
|
-
backend: "native",
|
|
24870
|
-
toolkit: "turbopuffer",
|
|
24871
|
-
authType: "api_key",
|
|
24872
|
-
category: "data",
|
|
24873
|
-
name: "turbopuffer",
|
|
24874
|
-
description: "Query and manage turbopuffer namespaces."
|
|
24875
|
-
},
|
|
24876
|
-
{
|
|
24877
|
-
id: "vanta",
|
|
24878
|
-
backend: "native",
|
|
24879
|
-
toolkit: "vanta",
|
|
24880
|
-
authType: "credentials",
|
|
24881
|
-
category: "data",
|
|
24882
|
-
name: "Vanta",
|
|
24883
|
-
description: "Review and manage controls, tests, evidence, vendors, risks, and compliance data.",
|
|
24884
|
-
scopes: ["environment"]
|
|
24885
|
-
}
|
|
24886
|
-
];
|
|
24887
|
-
var HOSTED_COMPOSIO_PLUGIN_DEFINITIONS = [
|
|
24888
|
-
["notion", "notion", "OAUTH2", true, "productivity", "Notion"],
|
|
24889
|
-
["jira", "jira", "OAUTH2", true, "productivity", "Jira"],
|
|
24890
|
-
["confluence", "confluence", "OAUTH2", true, "productivity", "Confluence"],
|
|
24891
|
-
["googlecalendar", "googlecalendar", "OAUTH2", true, "productivity", "Google Calendar"],
|
|
24892
|
-
["microsoftteams", "microsoft_teams", "OAUTH2", true, "productivity", "Microsoft Teams"],
|
|
24893
|
-
["outlook", "outlook", "OAUTH2", true, "productivity", "Outlook"],
|
|
24894
|
-
["bitbucket", "bitbucket", "OAUTH2", true, "data", "Bitbucket"],
|
|
24895
|
-
["datadog", "datadog", "API_KEY", false, "data", "Datadog"],
|
|
24896
|
-
["pagerduty", "pagerduty", "OAUTH2", true, "data", "PagerDuty"],
|
|
24897
|
-
["intercom", "intercom", "OAUTH2", true, "business", "Intercom"],
|
|
24898
|
-
["zendesk", "zendesk", "OAUTH2", true, "business", "Zendesk"],
|
|
24899
|
-
["hubspot", "hubspot", "OAUTH2", true, "business", "HubSpot"],
|
|
24900
|
-
["supabase", "supabase", "OAUTH2", true, "data", "Supabase"],
|
|
24901
|
-
["figma", "figma", "OAUTH2", true, "productivity", "Figma"],
|
|
24902
|
-
["launchdarkly", "launch_darkly", "API_KEY", false, "data", "LaunchDarkly"],
|
|
24903
|
-
["asana", "asana", "OAUTH2", true, "productivity", "Asana"],
|
|
24904
|
-
["clickup", "clickup", "OAUTH2", true, "productivity", "ClickUp"],
|
|
24905
|
-
["trello", "trello", "OAUTH1", true, "productivity", "Trello"],
|
|
24906
|
-
["todoist", "todoist", "OAUTH2", true, "productivity", "Todoist"],
|
|
24907
|
-
["airtable", "airtable", "OAUTH2", true, "productivity", "Airtable"],
|
|
24908
|
-
["coda", "coda", "API_KEY", false, "productivity", "Coda"],
|
|
24909
|
-
["miro", "miro", "OAUTH2", true, "productivity", "Miro"],
|
|
24910
|
-
["sharepoint", "share_point", "OAUTH2", true, "productivity", "SharePoint"],
|
|
24911
|
-
["onedrive", "one_drive", "OAUTH2", true, "productivity", "OneDrive"],
|
|
24912
|
-
["googleslides", "googleslides", "OAUTH2", true, "productivity", "Google Slides"],
|
|
24913
|
-
["googlemeet", "googlemeet", "OAUTH2", true, "productivity", "Google Meet"],
|
|
24914
|
-
["googletasks", "googletasks", "OAUTH2", true, "productivity", "Google Tasks"],
|
|
24915
|
-
["dropbox", "dropbox", "OAUTH2", true, "productivity", "Dropbox"],
|
|
24916
|
-
["box", "box", "OAUTH2", true, "productivity", "Box"],
|
|
24917
|
-
["discord", "discord", "OAUTH2", true, "productivity", "Discord"],
|
|
24918
|
-
["discordbot", "discordbot", "OAUTH2", true, "productivity", "Discord Bot"],
|
|
24919
|
-
["zoom", "zoom", "OAUTH2", true, "productivity", "Zoom"],
|
|
24920
|
-
["googlechat", "google_chat", "OAUTH2", false, "productivity", "Google Chat"],
|
|
24921
|
-
["newrelic", "new_relic", "API_KEY", false, "data", "New Relic"],
|
|
24922
|
-
["betterstack", "better_stack", "API_KEY", false, "data", "Better Stack"],
|
|
24923
|
-
["incidentio", "incident_io", "API_KEY", false, "data", "incident.io"],
|
|
24924
|
-
["grafana", "grafana", "BEARER_TOKEN", false, "data", "Grafana"],
|
|
24925
|
-
["honeycomb", "honeycomb_mcp", "DCR_OAUTH", false, "data", "Honeycomb MCP"],
|
|
24926
|
-
["bugsnag", "bugsnag", "API_KEY", false, "data", "Bugsnag"],
|
|
24927
|
-
["circleci", "circleci", "API_KEY", false, "data", "CircleCI"],
|
|
24928
|
-
["buildkite", "buildkite", "API_KEY", false, "data", "Buildkite"],
|
|
24929
|
-
["dockerhub", "docker_hub", "API_KEY", false, "data", "Docker Hub"],
|
|
24930
|
-
["digitalocean", "digital_ocean", "OAUTH2", true, "data", "DigitalOcean"],
|
|
24931
|
-
["railway", "railway", "API_KEY", false, "data", "Railway"],
|
|
24932
|
-
["render", "render", "API_KEY", false, "data", "Render"],
|
|
24933
|
-
["firebase", "firebase", "API_KEY", false, "data", "Firebase"],
|
|
24934
|
-
["cloudinary", "cloudinary", "API_KEY", false, "data", "Cloudinary"],
|
|
24935
|
-
["configcat", "configcat", "API_KEY", false, "data", "ConfigCat"],
|
|
24936
|
-
["contextdev", "context_dev", "API_KEY", false, "data", "Context.dev"],
|
|
24937
|
-
["googleanalytics", "google_analytics", "OAUTH2", true, "data", "Google Analytics"],
|
|
24938
|
-
["googlebigquery", "googlebigquery", "OAUTH2", true, "data", "Google BigQuery"],
|
|
24939
|
-
["amplitude", "amplitude", "API_KEY", false, "data", "Amplitude"],
|
|
24940
|
-
["mixpanel", "mixpanel", "BASIC", false, "data", "Mixpanel"],
|
|
24941
|
-
["segment", "segment", "API_KEY", false, "data", "Segment"],
|
|
24942
|
-
["databricks", "databricks", "API_KEY", false, "data", "Databricks"],
|
|
24943
|
-
["snowflake", "snowflake", "OAUTH2", false, "data", "Snowflake"],
|
|
24944
|
-
["algolia", "algolia", "API_KEY", false, "data", "Algolia"],
|
|
24945
|
-
["elasticsearch", "elasticsearch", "API_KEY", false, "data", "Elasticsearch"],
|
|
24946
|
-
["salesforce", "salesforce", "OAUTH2", true, "business", "Salesforce"],
|
|
24947
|
-
["pipedrive", "pipedrive", "API_KEY", false, "business", "Pipedrive"],
|
|
24948
|
-
["close", "close", "API_KEY", false, "business", "Close"],
|
|
24949
|
-
["apollo", "apollo", "API_KEY", false, "business", "Apollo"],
|
|
24950
|
-
["gong", "gong", "OAUTH2", true, "business", "Gong"],
|
|
24951
|
-
["freshdesk", "freshdesk", "API_KEY", false, "business", "Freshdesk"],
|
|
24952
|
-
["helpscout", "help_scout", "OAUTH2", false, "business", "Help Scout"],
|
|
24953
|
-
["servicenow", "servicenow", "BASIC", false, "business", "ServiceNow"],
|
|
24954
|
-
["mailchimp", "mailchimp", "OAUTH2", true, "business", "Mailchimp"],
|
|
24955
|
-
["customerio", "customerio", "API_KEY", false, "business", "Customer.io"],
|
|
24956
|
-
["klaviyo", "klaviyo", "API_KEY", false, "business", "Klaviyo"],
|
|
24957
|
-
["shopify", "shopify", "API_KEY", false, "business", "Shopify"],
|
|
24958
|
-
["quickbooks", "quickbooks", "OAUTH2", true, "business", "QuickBooks"],
|
|
24959
|
-
["xero", "xero", "OAUTH2", false, "business", "Xero"],
|
|
24960
|
-
["brex", "brex", "API_KEY", false, "business", "Brex"],
|
|
24961
|
-
["buffer", "buffer", "OAUTH2", false, "business", "Buffer"],
|
|
24962
|
-
["canva", "canva", "OAUTH2", true, "productivity", "Canva"],
|
|
24963
|
-
["webflow", "webflow", "API_KEY", false, "business", "Webflow"],
|
|
24964
|
-
["firecrawl", "firecrawl", "API_KEY", false, "data", "Firecrawl"],
|
|
24965
|
-
["browserbase", "browserbase_tool", "API_KEY", false, "data", "Browserbase"],
|
|
24966
|
-
["exa", "exa", "API_KEY", false, "data", "Exa"],
|
|
24967
|
-
["youtube", "youtube", "OAUTH2", true, "business", "YouTube"],
|
|
24968
|
-
["twitter", "twitter", "OAUTH2", false, "business", "Twitter/X"],
|
|
24969
|
-
["instagram", "instagram", "OAUTH2", true, "business", "Instagram"],
|
|
24970
|
-
["facebook", "facebook", "OAUTH2", true, "business", "Facebook"]
|
|
24971
|
-
];
|
|
24972
|
-
var HOSTED_COMPOSIO_PLUGINS = HOSTED_COMPOSIO_PLUGIN_DEFINITIONS.map(
|
|
24973
|
-
([id, toolkit, authScheme, managedAuth, category, name]) => ({
|
|
24974
|
-
id,
|
|
24975
|
-
backend: "composio",
|
|
24976
|
-
toolkit,
|
|
24977
|
-
authType: "hosted",
|
|
24978
|
-
authScheme,
|
|
24979
|
-
managedAuth,
|
|
24980
|
-
category,
|
|
24981
|
-
name,
|
|
24982
|
-
description: `Use ${name} tools from workspace agents.`
|
|
24983
|
-
})
|
|
24984
|
-
);
|
|
24985
|
-
var PLUGIN_CATALOG = [
|
|
24986
|
-
...EXPLICIT_PLUGIN_CATALOG,
|
|
24987
|
-
...HOSTED_COMPOSIO_PLUGINS
|
|
24988
|
-
];
|
|
24989
|
-
|
|
24990
|
-
// ../shared/src/routes/user.ts
|
|
24991
|
-
var PROFILE_AVATAR_MAX_SIZE_BYTES = 5 * 1024 * 1024;
|
|
24992
|
-
|
|
24993
|
-
// ../shared/src/routes/client-state.ts
|
|
24994
|
-
var MAX_CLIENT_STATE_REQUEST_BYTES = 5 * 1024 * 1024;
|
|
24995
|
-
var MAX_CLIENT_STATE_BYTES_PER_USER = 10 * 1024 * 1024;
|
|
24996
|
-
|
|
24997
|
-
// ../shared/src/routes/workspaces.ts
|
|
24998
|
-
var WORKSPACE_STATUSES = ["active", "sleeping", "archived", "preparing", "error"];
|
|
24999
|
-
function isWorkspaceSuspendedStatus(status) {
|
|
25000
|
-
return status === "sleeping" || status === "archived";
|
|
25001
|
-
}
|
|
25002
|
-
function workspaceConfigWithCapabilities(config3, capabilities = {}) {
|
|
25003
|
-
const mergedCapabilities = {
|
|
25004
|
-
...config3?.capabilities,
|
|
25005
|
-
...capabilities
|
|
25006
|
-
};
|
|
25007
|
-
return {
|
|
25008
|
-
...config3,
|
|
25009
|
-
capabilities: {
|
|
25010
|
-
...mergedCapabilities,
|
|
25011
|
-
pr_followups: mergedCapabilities.pr_followups === true
|
|
25012
|
-
}
|
|
25013
|
-
};
|
|
25014
|
-
}
|
|
25015
|
-
function workspaceConfigWithPrFollowups(config3, prFollowups = config3?.capabilities?.pr_followups === true) {
|
|
25016
|
-
return workspaceConfigWithCapabilities(config3, { pr_followups: prFollowups });
|
|
25017
|
-
}
|
|
25018
|
-
var WORKSPACE_STATUS_FILTERS = WORKSPACE_STATUSES.map((status) => status === "error" ? "failed" : status);
|
|
25019
|
-
var WORKSPACE_SORT_CHOICES = [
|
|
25020
|
-
["manual", "Custom"],
|
|
25021
|
-
["activity", "Last activity"],
|
|
25022
|
-
["created", "Created date"]
|
|
25023
|
-
];
|
|
25024
|
-
var WORKSPACE_SORT_OPTIONS = WORKSPACE_SORT_CHOICES.map(([option]) => option);
|
|
25025
|
-
var WORKSPACE_SORT_LABELS = Object.fromEntries(WORKSPACE_SORT_CHOICES);
|
|
25026
|
-
var WORKSPACE_SIDEBAR_ORGANIZATION_CHOICES = [
|
|
25027
|
-
["chronological", "Chronological"],
|
|
25028
|
-
["environments", "Environments"],
|
|
25029
|
-
["recent", "Recent environments"]
|
|
25030
|
-
];
|
|
25031
|
-
var WORKSPACE_SIDEBAR_ORGANIZATIONS = WORKSPACE_SIDEBAR_ORGANIZATION_CHOICES.map(([organization]) => organization);
|
|
25032
|
-
var WORKSPACE_SIDEBAR_ORGANIZATION_LABELS = Object.fromEntries(WORKSPACE_SIDEBAR_ORGANIZATION_CHOICES);
|
|
25033
|
-
var DEFAULT_STATUS_FILTERS = [...WORKSPACE_STATUS_FILTERS];
|
|
25034
|
-
var DEFAULT_WORKSPACE_FILTERS = {
|
|
25035
|
-
statuses: [...DEFAULT_STATUS_FILTERS],
|
|
25036
|
-
ownerIds: [],
|
|
25037
|
-
activity: "any"
|
|
25038
|
-
};
|
|
25039
|
-
var ONE_DAY_MS = 24 * 60 * 60 * 1e3;
|
|
25040
|
-
|
|
25041
|
-
// ../shared/src/routes/workspace-events.ts
|
|
25042
|
-
var workspaceChangedEventSchema = external_exports.discriminatedUnion("type", [
|
|
25043
|
-
external_exports.object({
|
|
25044
|
-
type: external_exports.literal("workspace.changed"),
|
|
25045
|
-
workspaceId: external_exports.string(),
|
|
25046
|
-
completion: external_exports.object({
|
|
25047
|
-
workspaceName: external_exports.string(),
|
|
25048
|
-
completedAt: external_exports.string(),
|
|
25049
|
-
processing: external_exports.boolean().optional()
|
|
25050
|
-
}).optional(),
|
|
25051
|
-
ts: external_exports.string()
|
|
25052
|
-
}),
|
|
25053
|
-
external_exports.object({
|
|
25054
|
-
type: external_exports.literal("workspace.chat.changed"),
|
|
25055
|
-
workspaceId: external_exports.string(),
|
|
25056
|
-
chatId: external_exports.string(),
|
|
25057
|
-
ts: external_exports.string()
|
|
25058
|
-
}),
|
|
25059
|
-
external_exports.object({ type: external_exports.literal("presence.changed"), ts: external_exports.string() }),
|
|
25060
|
-
external_exports.object({
|
|
25061
|
-
type: external_exports.literal("mobile-testing.changed"),
|
|
25062
|
-
workspaceId: external_exports.string(),
|
|
25063
|
-
ts: external_exports.string()
|
|
25064
|
-
})
|
|
25065
|
-
]);
|
|
25066
|
-
|
|
25067
|
-
// ../shared/src/routes/presence.ts
|
|
25068
|
-
var presenceStatusSchema = external_exports.enum(["online", "typing"]);
|
|
25069
|
-
var presenceLocationSchema = external_exports.object({
|
|
25070
|
-
environmentId: external_exports.string().optional(),
|
|
25071
|
-
workspaceId: external_exports.string().optional()
|
|
25072
|
-
});
|
|
25073
|
-
var presenceEntrySchema = external_exports.object({
|
|
25074
|
-
userId: external_exports.string(),
|
|
25075
|
-
status: presenceStatusSchema,
|
|
25076
|
-
location: presenceLocationSchema,
|
|
25077
|
-
ts: external_exports.string()
|
|
25078
|
-
});
|
|
25079
|
-
var updatePresenceRequestSchema = external_exports.object({
|
|
25080
|
-
status: presenceStatusSchema,
|
|
25081
|
-
location: presenceLocationSchema.optional()
|
|
25082
|
-
});
|
|
25083
|
-
|
|
25084
|
-
// ../shared/src/audit-log.ts
|
|
25085
|
-
var AUDIT_LOG_ACTION = {
|
|
25086
|
-
CREATE: "create",
|
|
25087
|
-
UPDATE: "update",
|
|
25088
|
-
DELETE: "delete",
|
|
25089
|
-
CONNECT: "connect",
|
|
25090
|
-
DISCONNECT: "disconnect"
|
|
25091
|
-
};
|
|
25092
|
-
var AUDIT_LOG_ACTIONS = Object.values(AUDIT_LOG_ACTION);
|
|
25093
|
-
|
|
25094
|
-
// ../shared/src/automations/types.ts
|
|
25095
|
-
var AUTOMATION_DEBOUNCE_MAX_SECONDS = 24 * 60 * 60;
|
|
25096
|
-
var AUTOMATION_LIFECYCLE_POLICIES = ["default", "archive_when_done", "sleep_when_done"];
|
|
25097
|
-
function toAutomationLifecyclePolicy(policy) {
|
|
25098
|
-
if (!policy) return "default";
|
|
25099
|
-
if (policy === "default" || policy === "archive_when_done" || policy === "sleep_when_done") return policy;
|
|
25100
|
-
return "archive_when_done";
|
|
25101
|
-
}
|
|
25102
|
-
function lifecyclePolicySupportsAutoStop(policy) {
|
|
25103
|
-
return policy === "default";
|
|
25104
|
-
}
|
|
25105
|
-
|
|
25106
|
-
// ../shared/src/automations/github-checks.ts
|
|
25107
|
-
var AUTOMATION_CHECK_CONCLUSIONS = ["success", "failure"];
|
|
25108
|
-
function isAutomationCheckConclusion(value) {
|
|
25109
|
-
return AUTOMATION_CHECK_CONCLUSIONS.some((conclusion) => conclusion === value);
|
|
25110
|
-
}
|
|
25111
|
-
function normalizeAutomationGithubCheckNames(names) {
|
|
25112
|
-
return names.map((name) => name.trim()).filter(Boolean);
|
|
25113
|
-
}
|
|
25114
|
-
|
|
25115
|
-
// ../shared/src/automations/agent-validation.ts
|
|
25116
|
-
function validateAgentSelection(body, existing, modelCatalogs = {}) {
|
|
25117
|
-
const agentProvider = body.agent_provider;
|
|
25118
|
-
if (agentProvider !== void 0 && agentProvider !== null) {
|
|
25119
|
-
if (!isValidAgentProvider(agentProvider)) {
|
|
25120
|
-
return createErrorResult({ message: `Invalid agent_provider: must be one of ${VALID_AGENT_PROVIDERS.join(", ")}` });
|
|
25121
|
-
}
|
|
25122
|
-
}
|
|
25123
|
-
const effectiveAgent = agentProvider !== void 0 ? agentProvider : existing.agentProvider;
|
|
25124
|
-
const agentChanged = agentProvider !== void 0 && agentProvider !== existing.agentProvider;
|
|
25125
|
-
let model = body.model;
|
|
25126
|
-
if (agentChanged && model === void 0 && existing.model) {
|
|
25127
|
-
model = null;
|
|
25128
|
-
}
|
|
25129
|
-
if (model !== void 0 && model !== null) {
|
|
25130
|
-
if (typeof model !== "string" || model.trim().length === 0) {
|
|
25131
|
-
return createErrorResult({ message: "model must be a non-empty string" });
|
|
25132
|
-
}
|
|
25133
|
-
model = normalizeClaudeModel(model) ?? model;
|
|
25134
|
-
if (!effectiveAgent) {
|
|
25135
|
-
return createErrorResult({ message: "Cannot set model without an agent_provider (the model would be applied against the org default agent and may not be valid for it)" });
|
|
25136
|
-
}
|
|
25137
|
-
const allowed = getAgentModelOptions(effectiveAgent, modelCatalogs);
|
|
25138
|
-
if (!isAgentModelAllowed(effectiveAgent, model, modelCatalogs)) {
|
|
25139
|
-
return createErrorResult({ message: `Invalid model "${model}" for agent ${effectiveAgent}. Valid models: ${allowed.join(", ")}` });
|
|
25140
|
-
}
|
|
25141
|
-
}
|
|
25142
|
-
const thinkingLevel = body.thinking_level;
|
|
25143
|
-
if (thinkingLevel !== void 0 && thinkingLevel !== null) {
|
|
25144
|
-
if (!effectiveAgent && isProviderSpecificThinkingLevel(thinkingLevel)) {
|
|
25145
|
-
return createErrorResult({ message: `Cannot set ${thinkingLevel} without an agent_provider` });
|
|
25146
|
-
}
|
|
25147
|
-
if (!isValidThinkingLevel(thinkingLevel) || effectiveAgent && !getThinkingLevelOptions(effectiveAgent).includes(thinkingLevel)) {
|
|
25148
|
-
const validLevels = effectiveAgent ? getThinkingLevelOptions(effectiveAgent) : VALID_THINKING_LEVELS;
|
|
25149
|
-
return createErrorResult({ message: `Invalid thinking_level: must be one of ${validLevels.join(", ")}` });
|
|
25150
|
-
}
|
|
25151
|
-
}
|
|
25152
|
-
return createSuccessResult({ agentProvider, model, thinkingLevel });
|
|
25153
|
-
}
|
|
25154
|
-
|
|
25155
|
-
// ../shared/src/automations/github/index.ts
|
|
25156
|
-
var REPO_FILTER_PARAM = {
|
|
25157
|
-
id: "repository_ids",
|
|
25158
|
-
label: "Filter by repository",
|
|
25159
|
-
type: "repository_ids"
|
|
25160
|
-
};
|
|
25161
|
-
var EXCLUDED_ACTORS_PARAM = {
|
|
25162
|
-
id: "excluded_actors",
|
|
25163
|
-
label: "Exclude users",
|
|
25164
|
-
type: "excluded_actors"
|
|
25165
|
-
};
|
|
25166
|
-
var GROUP_PR_EVENTS_PARAM = {
|
|
25167
|
-
id: "group_pr_events",
|
|
25168
|
-
label: "Group PR events to same workspace",
|
|
25169
|
-
type: "boolean"
|
|
25170
|
-
};
|
|
25171
|
-
var GITHUB_TRIGGER = {
|
|
25172
|
-
type: "github",
|
|
25173
|
-
label: "GitHub",
|
|
25174
|
-
description: "Trigger on repository events",
|
|
25175
|
-
icon: "github",
|
|
25176
|
-
events: [
|
|
25177
|
-
{ id: "pull_request.opened", label: "PR opened", parameters: [REPO_FILTER_PARAM, EXCLUDED_ACTORS_PARAM, GROUP_PR_EVENTS_PARAM] },
|
|
25178
|
-
{ id: "pull_request.synchronize", label: "PR updated (new commits)", parameters: [REPO_FILTER_PARAM, EXCLUDED_ACTORS_PARAM, GROUP_PR_EVENTS_PARAM] },
|
|
25179
|
-
{ id: "pull_request.merged", label: "PR merged", parameters: [REPO_FILTER_PARAM, EXCLUDED_ACTORS_PARAM] },
|
|
25180
|
-
{ id: "pull_request.closed", label: "PR closed", parameters: [REPO_FILTER_PARAM, EXCLUDED_ACTORS_PARAM] },
|
|
25181
|
-
{ id: "pull_request.command", label: "PR command (/replicas run)", parameters: [REPO_FILTER_PARAM, EXCLUDED_ACTORS_PARAM, GROUP_PR_EVENTS_PARAM] }
|
|
25182
|
-
]
|
|
25183
|
-
};
|
|
25184
|
-
|
|
25185
|
-
// ../shared/src/automations/gitlab/index.ts
|
|
25186
|
-
var REPO_FILTER_PARAM2 = {
|
|
25187
|
-
id: "repository_ids",
|
|
25188
|
-
label: "Filter by project",
|
|
25189
|
-
type: "repository_ids"
|
|
25190
|
-
};
|
|
25191
|
-
var EXCLUDED_ACTORS_PARAM2 = {
|
|
25192
|
-
id: "excluded_actors",
|
|
25193
|
-
label: "Exclude users",
|
|
25194
|
-
type: "excluded_actors"
|
|
25195
|
-
};
|
|
25196
|
-
var GROUP_MR_EVENTS_PARAM = {
|
|
25197
|
-
id: "group_pr_events",
|
|
25198
|
-
label: "Group MR events to same workspace",
|
|
25199
|
-
type: "boolean"
|
|
25200
|
-
};
|
|
25201
|
-
var GITLAB_TRIGGER = {
|
|
25202
|
-
type: "gitlab",
|
|
25203
|
-
label: "GitLab",
|
|
25204
|
-
description: "Trigger on project events",
|
|
25205
|
-
icon: "gitlab",
|
|
25206
|
-
events: [
|
|
25207
|
-
{ id: "merge_request.opened", label: "MR opened", parameters: [REPO_FILTER_PARAM2, EXCLUDED_ACTORS_PARAM2, GROUP_MR_EVENTS_PARAM] },
|
|
25208
|
-
{ id: "merge_request.updated", label: "MR updated (new commits)", parameters: [REPO_FILTER_PARAM2, EXCLUDED_ACTORS_PARAM2, GROUP_MR_EVENTS_PARAM] },
|
|
25209
|
-
{ id: "merge_request.merged", label: "MR merged", parameters: [REPO_FILTER_PARAM2, EXCLUDED_ACTORS_PARAM2] },
|
|
25210
|
-
{ id: "merge_request.closed", label: "MR closed", parameters: [REPO_FILTER_PARAM2, EXCLUDED_ACTORS_PARAM2] }
|
|
25211
|
-
]
|
|
25212
|
-
};
|
|
25213
|
-
|
|
25214
|
-
// ../shared/src/routes/repo-files.ts
|
|
25215
|
-
var MAX_REPO_FILE_CONTENT_BYTES = 256 * 1024;
|
|
25216
|
-
|
|
25217
|
-
// ../shared/src/routes/admin.ts
|
|
25218
|
-
var WEBHOOK_PROVIDERS = ["linear", "github", "gitlab", "slack", "e2b", "stripe", "sentry"];
|
|
25219
|
-
var WEBHOOK_PROVIDER_SET = new Set(WEBHOOK_PROVIDERS);
|
|
25220
|
-
|
|
25221
|
-
// ../shared/src/display-message/types.ts
|
|
25222
|
-
var BACKGROUND_TASK_SUBTYPES = /* @__PURE__ */ new Set([
|
|
25223
|
-
"task_started",
|
|
25224
|
-
"task_progress",
|
|
25225
|
-
"task_updated",
|
|
25226
|
-
"task_notification"
|
|
25227
|
-
]);
|
|
25228
|
-
function isBackgroundTaskSubtype(subtype) {
|
|
25229
|
-
return typeof subtype === "string" && BACKGROUND_TASK_SUBTYPES.has(subtype);
|
|
25230
|
-
}
|
|
25231
|
-
function optionalString(value) {
|
|
25232
|
-
return typeof value === "string" ? value : void 0;
|
|
25233
|
-
}
|
|
25234
|
-
function coerceBackgroundTaskPayload(payload) {
|
|
25235
|
-
if (!isRecord(payload)) return null;
|
|
25236
|
-
const subtype = payload.subtype;
|
|
25237
|
-
if (!isBackgroundTaskSubtype(subtype)) return null;
|
|
25238
|
-
const taskId = payload.task_id;
|
|
25239
|
-
if (typeof taskId !== "string" || !taskId) return null;
|
|
25240
|
-
const patch = isRecord(payload.patch) ? {
|
|
25241
|
-
status: optionalString(payload.patch.status),
|
|
25242
|
-
description: optionalString(payload.patch.description),
|
|
25243
|
-
error: optionalString(payload.patch.error),
|
|
25244
|
-
isBackgrounded: optionalBoolean(payload.patch.is_backgrounded)
|
|
25245
|
-
} : void 0;
|
|
25246
|
-
const usage = isRecord(payload.usage) ? {
|
|
25247
|
-
totalTokens: optionalNumber(payload.usage.total_tokens),
|
|
25248
|
-
toolUses: optionalNumber(payload.usage.tool_uses),
|
|
25249
|
-
durationMs: optionalNumber(payload.usage.duration_ms)
|
|
25250
|
-
} : void 0;
|
|
25251
|
-
return {
|
|
25252
|
-
subtype,
|
|
25253
|
-
taskId,
|
|
25254
|
-
description: optionalString(payload.description),
|
|
25255
|
-
summary: optionalString(payload.summary),
|
|
25256
|
-
outputFile: optionalString(payload.output_file),
|
|
25257
|
-
status: optionalString(payload.status),
|
|
25258
|
-
taskType: optionalString(payload.task_type),
|
|
25259
|
-
workflowName: optionalString(payload.workflow_name),
|
|
25260
|
-
prompt: optionalString(payload.prompt),
|
|
25261
|
-
lastToolName: optionalString(payload.last_tool_name),
|
|
25262
|
-
usage,
|
|
25263
|
-
ambient: optionalBoolean(payload.ambient),
|
|
25264
|
-
patch
|
|
25265
|
-
};
|
|
25266
|
-
}
|
|
25267
|
-
function optionalNumber(value) {
|
|
25268
|
-
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
25269
|
-
}
|
|
25270
|
-
function optionalBoolean(value) {
|
|
25271
|
-
return typeof value === "boolean" ? value : void 0;
|
|
25272
|
-
}
|
|
25273
|
-
function normalizeBackgroundTaskStatus(status) {
|
|
25274
|
-
if (status === "completed" || status === "failed" || status === "stopped") {
|
|
25275
|
-
return status;
|
|
25276
|
-
}
|
|
25277
|
-
if (status === "killed") {
|
|
25278
|
-
return "stopped";
|
|
25279
|
-
}
|
|
25280
|
-
return "in_progress";
|
|
25281
|
-
}
|
|
25282
|
-
|
|
25283
|
-
// ../shared/src/display-message/constants.ts
|
|
25284
|
-
var USER_MESSAGE_MATCH_GRACE_PERIOD_MS = 3e4;
|
|
25285
|
-
|
|
25286
|
-
// ../shared/src/user-message-matching.ts
|
|
25287
|
-
function parseTimestampMs(timestamp) {
|
|
25288
|
-
const value = Date.parse(timestamp);
|
|
25289
|
-
return Number.isFinite(value) ? value : 0;
|
|
25290
|
-
}
|
|
25291
|
-
function areUserMessagesWithinMatchWindow(a, b) {
|
|
25292
|
-
return a.content === b.content && Math.abs(parseTimestampMs(a.timestamp) - parseTimestampMs(b.timestamp)) <= USER_MESSAGE_MATCH_GRACE_PERIOD_MS;
|
|
25293
|
-
}
|
|
25294
|
-
|
|
25295
|
-
// ../shared/src/agent-event-utils.ts
|
|
25296
|
-
function getUserMessage(event) {
|
|
25297
|
-
return event.type === "event_msg" && event.payload.type === "user_message" && typeof event.payload.message === "string" ? event.payload.message : null;
|
|
25298
|
-
}
|
|
25299
|
-
function getUserMessageId(event) {
|
|
25300
|
-
const messageId = event.payload[USER_MESSAGE_ID_PAYLOAD_KEY];
|
|
25301
|
-
return typeof messageId === "string" ? messageId : null;
|
|
25302
|
-
}
|
|
25303
|
-
|
|
25304
|
-
// ../shared/src/json.ts
|
|
25305
|
-
function safeJsonParse(str, fallback) {
|
|
25306
|
-
try {
|
|
25307
|
-
return JSON.parse(str);
|
|
25308
|
-
} catch {
|
|
25309
|
-
return fallback;
|
|
25310
|
-
}
|
|
25311
|
-
}
|
|
25312
|
-
|
|
25313
|
-
// ../shared/src/display-message/parsers/utils.ts
|
|
25314
|
-
var INTERRUPTED_MESSAGE_REGEX = /^\[Request interrupted by user.*\]$/;
|
|
25315
|
-
function userMessageImages(value) {
|
|
25316
|
-
if (!Array.isArray(value)) return void 0;
|
|
25317
|
-
const images = value.filter((item) => isRecord(item) && item.type === "image" && typeof item.mediaType === "string" && typeof item.data === "string");
|
|
25318
|
-
return images.length > 0 ? images : void 0;
|
|
25319
|
-
}
|
|
25320
|
-
function stringifyDisplayValue(value) {
|
|
25321
|
-
if (value === void 0 || value === null) return void 0;
|
|
25322
|
-
if (typeof value === "string") return value;
|
|
25323
|
-
try {
|
|
25324
|
-
return JSON.stringify(value, null, 2);
|
|
25325
|
-
} catch {
|
|
25326
|
-
return String(value);
|
|
25327
|
-
}
|
|
25328
|
-
}
|
|
25329
|
-
function upsertDisplayMessage(messages, message) {
|
|
25330
|
-
const index = messages.findIndex((candidate) => candidate.id === message.id);
|
|
25331
|
-
if (index === -1) messages.push(message);
|
|
25332
|
-
else messages[index] = message;
|
|
25333
|
-
}
|
|
25334
|
-
function applyToolInputEvent(event, messages, provider, state, questionFilter) {
|
|
25335
|
-
if (event.type === "replicas-tool-input-request" && typeof event.payload.toolUseId === "string" && typeof event.payload.requestId === "string" && (Array.isArray(event.payload.options) || Array.isArray(event.payload.questions))) {
|
|
25336
|
-
const resolved = state.resolutions.get(event.payload.toolUseId);
|
|
25337
|
-
const inputRequest = {
|
|
25338
|
-
requestId: event.payload.requestId,
|
|
25339
|
-
status: resolved?.selectionId === "aborted" || resolved?.selectionId === "declined" ? "aborted" : resolved ? "resolved" : "pending",
|
|
25340
|
-
...Array.isArray(event.payload.options) ? { options: event.payload.options } : {},
|
|
25341
|
-
...Array.isArray(event.payload.questions) ? { questions: questionFilter ? event.payload.questions.filter(questionFilter) : event.payload.questions } : {},
|
|
25342
|
-
...resolved ? { selectionId: resolved.selectionId } : {},
|
|
25343
|
-
...resolved?.selectionSummary ? { selectionSummary: resolved.selectionSummary } : {}
|
|
25344
|
-
};
|
|
25345
|
-
state.requests.set(event.payload.toolUseId, inputRequest);
|
|
25346
|
-
const message = messages.find((candidate) => candidate.type === "tool_call" && candidate.id === `${provider}-tool-${event.payload.toolUseId}`);
|
|
25347
|
-
if (message) message.inputRequest = inputRequest;
|
|
25348
|
-
return true;
|
|
25349
|
-
}
|
|
25350
|
-
if (event.type === "replicas-tool-input-resolved" && typeof event.payload.toolUseId === "string" && typeof event.payload.selectionId === "string") {
|
|
25351
|
-
const resolved = {
|
|
25352
|
-
selectionId: event.payload.selectionId,
|
|
25353
|
-
...typeof event.payload.selectionSummary === "string" ? { selectionSummary: event.payload.selectionSummary } : {}
|
|
25354
|
-
};
|
|
25355
|
-
state.resolutions.set(event.payload.toolUseId, resolved);
|
|
25356
|
-
const inputRequest = state.requests.get(event.payload.toolUseId);
|
|
25357
|
-
if (inputRequest) {
|
|
25358
|
-
inputRequest.status = resolved.selectionId === "aborted" || resolved.selectionId === "declined" ? "aborted" : "resolved";
|
|
25359
|
-
inputRequest.selectionId = resolved.selectionId;
|
|
25360
|
-
if (resolved.selectionSummary) inputRequest.selectionSummary = resolved.selectionSummary;
|
|
25361
|
-
}
|
|
25362
|
-
return true;
|
|
25363
|
-
}
|
|
25364
|
-
return false;
|
|
25365
|
-
}
|
|
25366
|
-
function parseSkillName(tool, input) {
|
|
25367
|
-
if (typeof tool !== "string") return null;
|
|
25368
|
-
const normalizedTool = tool.toLowerCase();
|
|
25369
|
-
if (normalizedTool.startsWith("skill.")) return tool.slice("skill.".length) || null;
|
|
25370
|
-
if (normalizedTool !== "skill") return null;
|
|
25371
|
-
const parsedInput = typeof input === "string" ? safeJsonParse(input, null) : input;
|
|
25372
|
-
if (!isRecord(parsedInput)) return null;
|
|
25373
|
-
const skillName = parsedInput.skill ?? parsedInput.name;
|
|
25374
|
-
return typeof skillName === "string" && skillName ? skillName : null;
|
|
25375
|
-
}
|
|
25376
|
-
function skillNameFromFilePath(path6) {
|
|
25377
|
-
const skillName = skillNameFromSkillRootPath(path6);
|
|
25378
|
-
if (skillName) return skillName;
|
|
25379
|
-
const parts = path6.split(/[\\/]+/).filter(Boolean);
|
|
25380
|
-
if (parts.length < 2 || parts[parts.length - 1].toLowerCase() !== "skill.md") return null;
|
|
25381
|
-
const fallbackSkillName = parts[parts.length - 2];
|
|
25382
|
-
return fallbackSkillName && fallbackSkillName.toLowerCase() !== "skills" ? fallbackSkillName : null;
|
|
25383
|
-
}
|
|
25384
|
-
function skillNameFromSkillRootPath(path6) {
|
|
25385
|
-
const parts = path6.split(/[\\/]+/).filter(Boolean);
|
|
25386
|
-
const skillsIndex = parts.findLastIndex((part) => part.toLowerCase() === "skills");
|
|
25387
|
-
if (skillsIndex === -1) return null;
|
|
25388
|
-
const firstSkillPart = parts[skillsIndex + 1];
|
|
25389
|
-
const skillName = firstSkillPart?.toLowerCase() === ".system" ? parts[skillsIndex + 2] : firstSkillPart;
|
|
25390
|
-
return skillName && skillName.toLowerCase() !== "skill.md" ? skillName : null;
|
|
25391
|
-
}
|
|
25392
|
-
function parseSkillFilePath(input) {
|
|
25393
|
-
const parsedInput = typeof input === "string" ? safeJsonParse(input, null) : input;
|
|
25394
|
-
if (!isRecord(parsedInput)) return null;
|
|
25395
|
-
const path6 = [parsedInput.path, parsedInput.filePath, parsedInput.file_path].find((value) => typeof value === "string" && value.length > 0);
|
|
25396
|
-
if (!path6) return null;
|
|
25397
|
-
return skillNameFromFilePath(path6);
|
|
25398
|
-
}
|
|
25399
|
-
function skillNameFromToolCall(tool, input) {
|
|
25400
|
-
const directSkillName = parseSkillName(tool, input);
|
|
25401
|
-
if (directSkillName) return directSkillName;
|
|
25402
|
-
if (typeof tool !== "string" || !["read", "read_file", "readfile"].includes(tool.toLowerCase())) return null;
|
|
25403
|
-
return parseSkillFilePath(input);
|
|
25404
|
-
}
|
|
25405
|
-
function createCallDisplayMessage(message) {
|
|
25406
|
-
const skillName = message.server.toLowerCase() === "skills" ? message.tool : skillNameFromToolCall(message.tool, message.input);
|
|
25407
|
-
if (skillName === null) return { ...message, type: "tool_call" };
|
|
25408
|
-
return {
|
|
25409
|
-
id: message.id,
|
|
25410
|
-
type: "skill",
|
|
25411
|
-
skillName,
|
|
25412
|
-
status: message.status,
|
|
25413
|
-
timestamp: message.timestamp
|
|
25414
|
-
};
|
|
25415
|
-
}
|
|
25416
|
-
function insertDisplayMessageByTimestamp(messages, message) {
|
|
25417
|
-
const messageMs = parseTimestampMs(message.timestamp);
|
|
25418
|
-
let index = messages.length;
|
|
25419
|
-
while (index > 0 && parseTimestampMs(messages[index - 1].timestamp) > messageMs) index--;
|
|
25420
|
-
messages.splice(index, 0, message);
|
|
25421
|
-
}
|
|
25422
|
-
|
|
25423
|
-
// ../shared/src/display-message/format.ts
|
|
25424
|
-
function unquoteShellArg(value) {
|
|
25425
|
-
const trimmed = value.trim();
|
|
25426
|
-
if (trimmed.length < 2) return trimmed;
|
|
25427
|
-
if (trimmed[0] === "'" && trimmed[trimmed.length - 1] === "'") {
|
|
25428
|
-
return trimmed.slice(1, -1).replace(/'\\''/g, "'");
|
|
25429
|
-
}
|
|
25430
|
-
if (trimmed[0] === '"' && trimmed[trimmed.length - 1] === '"') {
|
|
25431
|
-
return trimmed.slice(1, -1).replace(/\\(["\\$`])/g, "$1");
|
|
25432
|
-
}
|
|
25433
|
-
return trimmed;
|
|
25434
|
-
}
|
|
25435
|
-
function shellPayload(command) {
|
|
25436
|
-
const match = command.trim().match(/^(?:\S*\/)?(?:ba|z|c|fi)?sh\s+-(?:[a-zA-Z]*c[a-zA-Z]*|c)\s+([\s\S]+)$/);
|
|
25437
|
-
return match ? unquoteShellArg(match[1]) : command.trim();
|
|
25438
|
-
}
|
|
25439
|
-
function splitShellWords(command) {
|
|
25440
|
-
const words = [];
|
|
25441
|
-
let word = "";
|
|
25442
|
-
let quote = null;
|
|
25443
|
-
let escaped = false;
|
|
25444
|
-
for (const char of command) {
|
|
25445
|
-
if (escaped) {
|
|
25446
|
-
word += char;
|
|
25447
|
-
escaped = false;
|
|
25448
|
-
continue;
|
|
25449
|
-
}
|
|
25450
|
-
if (char === "\\" && quote !== "'") {
|
|
25451
|
-
escaped = true;
|
|
25452
|
-
continue;
|
|
25453
|
-
}
|
|
25454
|
-
if (quote) {
|
|
25455
|
-
if (char === quote) quote = null;
|
|
25456
|
-
else word += char;
|
|
25457
|
-
continue;
|
|
25458
|
-
}
|
|
25459
|
-
if (char === '"' || char === "'") {
|
|
25460
|
-
quote = char;
|
|
25461
|
-
continue;
|
|
25462
|
-
}
|
|
25463
|
-
if (/\s/.test(char)) {
|
|
25464
|
-
if (word) {
|
|
25465
|
-
words.push(word);
|
|
25466
|
-
word = "";
|
|
25467
|
-
}
|
|
25468
|
-
continue;
|
|
25469
|
-
}
|
|
25470
|
-
word += char;
|
|
25471
|
-
}
|
|
25472
|
-
if (word) words.push(word);
|
|
25473
|
-
return words;
|
|
25474
|
-
}
|
|
25475
|
-
function commandWords(command) {
|
|
25476
|
-
const payload = shellPayload(command);
|
|
25477
|
-
if (!payload || /[;|<>]|&&/.test(payload)) return null;
|
|
25478
|
-
return splitShellWords(payload);
|
|
25479
|
-
}
|
|
25480
|
-
function skillNamesFromCommand(command) {
|
|
25481
|
-
const words = commandWords(command);
|
|
25482
|
-
if (!words) return [];
|
|
25483
|
-
return Array.from(new Set(words.flatMap((word) => {
|
|
25484
|
-
const skillName = skillNameFromSkillRootPath(word);
|
|
25485
|
-
return skillName ? [skillName] : [];
|
|
25486
|
-
})));
|
|
25487
|
-
}
|
|
25488
|
-
|
|
25489
|
-
// ../shared/src/display-message/parsers/codex-parser.ts
|
|
25490
|
-
function getStatusFromExitCode(exitCode) {
|
|
25491
|
-
return exitCode === 0 ? "completed" : "failed";
|
|
25492
|
-
}
|
|
25493
|
-
function getPayloadString(event, key) {
|
|
25494
|
-
const value = event.payload?.[key];
|
|
25495
|
-
return typeof value === "string" ? value : null;
|
|
25496
|
-
}
|
|
25497
|
-
function displayId(event, eventIndex, prefix) {
|
|
25498
|
-
const stableId = getPayloadString(event, USER_MESSAGE_ID_PAYLOAD_KEY) ?? getPayloadString(event, CODEX_ASP_ITEM_ID_PAYLOAD_KEY);
|
|
25499
|
-
return stableId ? `${prefix}-${stableId}` : `${prefix}-${event.timestamp}-${eventIndex}`;
|
|
25500
|
-
}
|
|
25501
|
-
function parseShellOutput(raw) {
|
|
25502
|
-
const exitCodeMatch = raw.match(/^Exit code: (\d+)/m) || raw.match(/Process exited with code (\d+)/);
|
|
25503
|
-
const exitCode = exitCodeMatch ? parseInt(exitCodeMatch[1], 10) : 0;
|
|
25504
|
-
const outputIndex = raw.indexOf("Output:\n");
|
|
25505
|
-
const output = outputIndex >= 0 ? raw.slice(outputIndex + "Output:\n".length) : raw;
|
|
25506
|
-
return { exitCode, output };
|
|
24729
|
+
function parseShellOutput(raw) {
|
|
24730
|
+
const exitCodeMatch = raw.match(/^Exit code: (\d+)/m) || raw.match(/Process exited with code (\d+)/);
|
|
24731
|
+
const exitCode = exitCodeMatch ? parseInt(exitCodeMatch[1], 10) : 0;
|
|
24732
|
+
const outputIndex = raw.indexOf("Output:\n");
|
|
24733
|
+
const output = outputIndex >= 0 ? raw.slice(outputIndex + "Output:\n".length) : raw;
|
|
24734
|
+
return { exitCode, output };
|
|
25507
24735
|
}
|
|
25508
24736
|
function parsePatch(input) {
|
|
25509
24737
|
const operations = [];
|
|
@@ -26180,6 +25408,44 @@ function parseFxEvents(events) {
|
|
|
26180
25408
|
return parseAcpEvents(events, "fx");
|
|
26181
25409
|
}
|
|
26182
25410
|
|
|
25411
|
+
// ../shared/src/errors.ts
|
|
25412
|
+
var TRANSIENT_NETWORK_ERROR_PATTERNS = [
|
|
25413
|
+
/socket connection was closed unexpectedly/,
|
|
25414
|
+
/fetch failed/,
|
|
25415
|
+
/network error/,
|
|
25416
|
+
/network request failed/,
|
|
25417
|
+
/econnreset/,
|
|
25418
|
+
/econnrefused/,
|
|
25419
|
+
/etimedout/,
|
|
25420
|
+
/enotfound/,
|
|
25421
|
+
/eai_again/,
|
|
25422
|
+
/und_err_socket/,
|
|
25423
|
+
/und_err_connect_timeout/,
|
|
25424
|
+
/headers timeout/,
|
|
25425
|
+
/body timeout/,
|
|
25426
|
+
/connection reset/,
|
|
25427
|
+
/connection closed/,
|
|
25428
|
+
/closed unexpectedly/
|
|
25429
|
+
];
|
|
25430
|
+
var HTTP_CONTEXT_PATTERN = /(api error|request|response|status|http)/;
|
|
25431
|
+
var HTTP_STATUS_PATTERN = /(^|[^0-9])([1-5][0-9]{2})(?=$|[^0-9])/g;
|
|
25432
|
+
function isTransientErrorText(text, options = {}) {
|
|
25433
|
+
const normalized = text.toLowerCase();
|
|
25434
|
+
if (!normalized) return false;
|
|
25435
|
+
if (TRANSIENT_NETWORK_ERROR_PATTERNS.some((pattern) => pattern.test(normalized))) return true;
|
|
25436
|
+
if (options.includeRateLimit && /rate limit/.test(normalized)) return true;
|
|
25437
|
+
if (options.extraPatterns?.some((pattern) => pattern.test(normalized))) return true;
|
|
25438
|
+
const httpStatuses = new Set(options.httpStatuses ?? []);
|
|
25439
|
+
const httpStatusClasses = new Set(options.httpStatusClasses ?? []);
|
|
25440
|
+
if (httpStatuses.size === 0 && httpStatusClasses.size === 0) return false;
|
|
25441
|
+
if (options.requireHttpContext !== false && !HTTP_CONTEXT_PATTERN.test(normalized)) return false;
|
|
25442
|
+
for (const match of normalized.matchAll(HTTP_STATUS_PATTERN)) {
|
|
25443
|
+
const status = Number(match[2]);
|
|
25444
|
+
if (httpStatuses.has(status) || httpStatusClasses.has(Math.floor(status / 100))) return true;
|
|
25445
|
+
}
|
|
25446
|
+
return false;
|
|
25447
|
+
}
|
|
25448
|
+
|
|
26183
25449
|
// ../shared/src/display-message/parsers/inference-error.ts
|
|
26184
25450
|
var TRANSIENT_HTTP_STATUSES = [408, 429, 500, 502, 503, 504, 529];
|
|
26185
25451
|
var SERVER_ERROR_TEXT_PATTERN = /internal ?server ?error|server ?error|service unavailable|bad gateway|gateway timeout|overloaded|too many requests/i;
|
|
@@ -26670,6 +25936,15 @@ function parseMcpToolName(name) {
|
|
|
26670
25936
|
return { server, tool };
|
|
26671
25937
|
}
|
|
26672
25938
|
|
|
25939
|
+
// ../shared/src/user-message-matching.ts
|
|
25940
|
+
function parseTimestampMs(timestamp) {
|
|
25941
|
+
const value = Date.parse(timestamp);
|
|
25942
|
+
return Number.isFinite(value) ? value : 0;
|
|
25943
|
+
}
|
|
25944
|
+
function areUserMessagesWithinMatchWindow(a, b) {
|
|
25945
|
+
return a.content === b.content && Math.abs(parseTimestampMs(a.timestamp) - parseTimestampMs(b.timestamp)) <= USER_MESSAGE_MATCH_GRACE_PERIOD_MS;
|
|
25946
|
+
}
|
|
25947
|
+
|
|
26673
25948
|
// ../shared/src/display-message/parsers/claude-parser.ts
|
|
26674
25949
|
var ABORTED_TERMINAL_REASONS = /* @__PURE__ */ new Set(["aborted_streaming", "aborted_tools"]);
|
|
26675
25950
|
function coerceClaudeResultPayload(payload) {
|
|
@@ -27036,577 +26311,1368 @@ function parseClaudeEvents(events, parentToolUseId) {
|
|
|
27036
26311
|
timestamp: event.timestamp
|
|
27037
26312
|
});
|
|
27038
26313
|
} else {
|
|
27039
|
-
messages.push({
|
|
27040
|
-
id: `toolcall-${event.timestamp}-${messages.length}`,
|
|
27041
|
-
type: "tool_call",
|
|
27042
|
-
server: "claude",
|
|
27043
|
-
tool: toolName,
|
|
27044
|
-
input: toolInput,
|
|
27045
|
-
status: "in_progress",
|
|
27046
|
-
timestamp: event.timestamp
|
|
27047
|
-
});
|
|
26314
|
+
messages.push({
|
|
26315
|
+
id: `toolcall-${event.timestamp}-${messages.length}`,
|
|
26316
|
+
type: "tool_call",
|
|
26317
|
+
server: "claude",
|
|
26318
|
+
tool: toolName,
|
|
26319
|
+
input: toolInput,
|
|
26320
|
+
status: "in_progress",
|
|
26321
|
+
timestamp: event.timestamp
|
|
26322
|
+
});
|
|
26323
|
+
}
|
|
26324
|
+
}
|
|
26325
|
+
});
|
|
26326
|
+
}
|
|
26327
|
+
if (event.type === "claude-result") {
|
|
26328
|
+
const payload = coerceClaudeResultPayload(event.payload);
|
|
26329
|
+
if (isClaudeResultError(payload)) {
|
|
26330
|
+
const genuineErrors = stripAgentDiagnosticErrors(payload.errors ?? []);
|
|
26331
|
+
messages.push({
|
|
26332
|
+
id: `error-${event.timestamp}`,
|
|
26333
|
+
type: "error",
|
|
26334
|
+
message: genuineErrors.length > 0 ? genuineErrors.join("\n") : "Claude session encountered an unexpected error.",
|
|
26335
|
+
timestamp: event.timestamp
|
|
26336
|
+
});
|
|
26337
|
+
}
|
|
26338
|
+
}
|
|
26339
|
+
if (event.type === "claude-system") {
|
|
26340
|
+
const payload = coerceBackgroundTaskPayload(event.payload);
|
|
26341
|
+
if (payload?.ambient) ambientTaskIds.add(payload.taskId);
|
|
26342
|
+
if (payload && !ambientTaskIds.has(payload.taskId)) {
|
|
26343
|
+
const existing = taskMessageMap.get(payload.taskId);
|
|
26344
|
+
const nextStatus = payload.subtype === "task_notification" ? normalizeBackgroundTaskStatus(payload.status) : payload.subtype === "task_updated" ? normalizeBackgroundTaskStatus(payload.patch?.status) : existing?.status ?? "in_progress";
|
|
26345
|
+
const nextMessage = {
|
|
26346
|
+
id: existing?.id ?? `task-${event.timestamp}-${messages.length}`,
|
|
26347
|
+
type: "background_task",
|
|
26348
|
+
taskId: payload.taskId,
|
|
26349
|
+
status: nextStatus,
|
|
26350
|
+
description: payload.description ?? payload.patch?.description ?? existing?.description,
|
|
26351
|
+
summary: payload.summary ?? existing?.summary,
|
|
26352
|
+
outputFile: payload.outputFile ?? existing?.outputFile,
|
|
26353
|
+
taskType: payload.taskType ?? existing?.taskType,
|
|
26354
|
+
workflowName: payload.workflowName ?? existing?.workflowName,
|
|
26355
|
+
prompt: payload.prompt ?? existing?.prompt,
|
|
26356
|
+
lastToolName: payload.lastToolName ?? existing?.lastToolName,
|
|
26357
|
+
usage: payload.usage ?? existing?.usage,
|
|
26358
|
+
error: payload.patch?.error ?? existing?.error,
|
|
26359
|
+
isBackgrounded: payload.patch?.isBackgrounded ?? existing?.isBackgrounded,
|
|
26360
|
+
timestamp: existing?.timestamp ?? event.timestamp
|
|
26361
|
+
};
|
|
26362
|
+
if (existing) {
|
|
26363
|
+
Object.assign(existing, nextMessage);
|
|
26364
|
+
} else {
|
|
26365
|
+
taskMessageMap.set(payload.taskId, nextMessage);
|
|
26366
|
+
messages.push(nextMessage);
|
|
26367
|
+
}
|
|
26368
|
+
}
|
|
26369
|
+
}
|
|
26370
|
+
});
|
|
26371
|
+
filteredEvents.forEach((event) => {
|
|
26372
|
+
if (event.type === "replicas-tool-input-request") {
|
|
26373
|
+
const payload = event.payload;
|
|
26374
|
+
if (!payload.toolUseId || !payload.requestId) return;
|
|
26375
|
+
if (!Array.isArray(payload.options) && !Array.isArray(payload.questions)) return;
|
|
26376
|
+
const toolInfo = toolCallMap.get(payload.toolUseId);
|
|
26377
|
+
if (!toolInfo) return;
|
|
26378
|
+
const message = messages[toolInfo.messageIndex];
|
|
26379
|
+
if (!message || message.type !== "tool_call") return;
|
|
26380
|
+
message.inputRequest = {
|
|
26381
|
+
requestId: payload.requestId,
|
|
26382
|
+
status: "pending",
|
|
26383
|
+
options: payload.options,
|
|
26384
|
+
questions: payload.questions
|
|
26385
|
+
};
|
|
26386
|
+
}
|
|
26387
|
+
if (event.type === "replicas-tool-input-resolved") {
|
|
26388
|
+
const payload = event.payload;
|
|
26389
|
+
if (!payload.toolUseId || !payload.selectionId) return;
|
|
26390
|
+
const toolInfo = toolCallMap.get(payload.toolUseId);
|
|
26391
|
+
if (!toolInfo) return;
|
|
26392
|
+
const message = messages[toolInfo.messageIndex];
|
|
26393
|
+
if (!message || message.type !== "tool_call" || !message.inputRequest) return;
|
|
26394
|
+
message.inputRequest = {
|
|
26395
|
+
...message.inputRequest,
|
|
26396
|
+
status: payload.selectionId === "aborted" ? "aborted" : "resolved",
|
|
26397
|
+
selectionId: payload.selectionId,
|
|
26398
|
+
selectionSummary: payload.selectionSummary
|
|
26399
|
+
};
|
|
26400
|
+
}
|
|
26401
|
+
});
|
|
26402
|
+
filteredEvents.forEach((event) => {
|
|
26403
|
+
if (event.type === "claude-user") {
|
|
26404
|
+
const content = normalizeContentBlocks(event.payload.message?.content);
|
|
26405
|
+
const toolResult = content.find((c) => c.type === "tool_result");
|
|
26406
|
+
if (toolResult && toolResult.tool_use_id) {
|
|
26407
|
+
const toolInfo = toolCallMap.get(toolResult.tool_use_id);
|
|
26408
|
+
if (!toolInfo) return;
|
|
26409
|
+
const resultContent = extractToolResultText(toolResult.content);
|
|
26410
|
+
const isError = toolResult.is_error || false;
|
|
26411
|
+
const status = isError ? "failed" : "completed";
|
|
26412
|
+
if (toolInfo.toolName === "TaskCreate" && !isError) {
|
|
26413
|
+
taskAccumulator.processContentBlock(toolResult);
|
|
26414
|
+
}
|
|
26415
|
+
const message = messages[toolInfo.messageIndex];
|
|
26416
|
+
if (!message) return;
|
|
26417
|
+
if (message.type === "command") {
|
|
26418
|
+
message.output = resultContent;
|
|
26419
|
+
message.status = status;
|
|
26420
|
+
const exitCodeMatch = resultContent.match(/exit code:?\s*(\d+)/i);
|
|
26421
|
+
if (exitCodeMatch) {
|
|
26422
|
+
message.exitCode = parseInt(exitCodeMatch[1], 10);
|
|
26423
|
+
} else {
|
|
26424
|
+
message.exitCode = isError ? 1 : 0;
|
|
26425
|
+
}
|
|
26426
|
+
} else if (message.type === "patch") {
|
|
26427
|
+
message.status = status;
|
|
26428
|
+
} else if (message.type === "web_search") {
|
|
26429
|
+
message.status = status;
|
|
26430
|
+
} else if (message.type === "tool_call") {
|
|
26431
|
+
message.output = resultContent;
|
|
26432
|
+
message.status = status;
|
|
26433
|
+
} else if (message.type === "skill") {
|
|
26434
|
+
message.status = status;
|
|
26435
|
+
} else if (message.type === "subagent") {
|
|
26436
|
+
message.output = resultContent;
|
|
26437
|
+
message.status = status;
|
|
26438
|
+
if (!message.chatId && resultContent) {
|
|
26439
|
+
const parsed = safeJsonParse(resultContent, {});
|
|
26440
|
+
if (parsed.chatId) {
|
|
26441
|
+
message.chatId = parsed.chatId;
|
|
26442
|
+
}
|
|
26443
|
+
}
|
|
26444
|
+
} else if (message.type === "subagent_followup") {
|
|
26445
|
+
message.output = resultContent;
|
|
26446
|
+
message.status = status;
|
|
26447
|
+
}
|
|
26448
|
+
}
|
|
26449
|
+
}
|
|
26450
|
+
});
|
|
26451
|
+
for (const message of messages) {
|
|
26452
|
+
if (message.type !== "subagent_followup") continue;
|
|
26453
|
+
const target = messages.find((candidate) => candidate.type === "subagent" && candidate.chatId === message.chatId);
|
|
26454
|
+
if (target?.type === "subagent") {
|
|
26455
|
+
message.targetTitle = target.description;
|
|
26456
|
+
message.targetProvider = target.subagentType;
|
|
26457
|
+
}
|
|
26458
|
+
}
|
|
26459
|
+
const staleIndexes = new Set(supersededUserMessageIndexes);
|
|
26460
|
+
for (const streamId of [...completedStreamIds, ...supersededStreamIds]) {
|
|
26461
|
+
const refs = partialIndexes.get(streamId);
|
|
26462
|
+
if (refs?.reasoning !== void 0) staleIndexes.add(refs.reasoning);
|
|
26463
|
+
if (refs?.agent !== void 0) staleIndexes.add(refs.agent);
|
|
26464
|
+
}
|
|
26465
|
+
if (staleIndexes.size === 0) return messages;
|
|
26466
|
+
return messages.filter((_2, index) => !staleIndexes.has(index));
|
|
26467
|
+
}
|
|
26468
|
+
|
|
26469
|
+
// ../shared/src/display-message/parsers/codex-asp-parser.ts
|
|
26470
|
+
var DUPLICATE_WINDOW_MS = 5 * 60 * 1e3;
|
|
26471
|
+
function nearTimestamp(a, b) {
|
|
26472
|
+
return Math.abs(parseTimestampMs(a) - parseTimestampMs(b)) <= DUPLICATE_WINDOW_MS;
|
|
26473
|
+
}
|
|
26474
|
+
function inputForDisplay(input) {
|
|
26475
|
+
if (input === void 0 || input === null) return void 0;
|
|
26476
|
+
if (typeof input === "string") return input;
|
|
26477
|
+
if (isRecord(input)) return input;
|
|
26478
|
+
return String(input);
|
|
26479
|
+
}
|
|
26480
|
+
function isInternalUserMessage(content) {
|
|
26481
|
+
const trimmed = content.trim();
|
|
26482
|
+
return trimmed.startsWith("<environment_context>") || trimmed.startsWith("<goal_context>");
|
|
26483
|
+
}
|
|
26484
|
+
function messageForItem(item) {
|
|
26485
|
+
if (item.type === "userMessage") {
|
|
26486
|
+
if (isInternalUserMessage(item.content)) return null;
|
|
26487
|
+
return {
|
|
26488
|
+
id: `user-${item.id}`,
|
|
26489
|
+
type: "user",
|
|
26490
|
+
content: item.content,
|
|
26491
|
+
images: item.images,
|
|
26492
|
+
timestamp: item.timestamp
|
|
26493
|
+
};
|
|
26494
|
+
}
|
|
26495
|
+
if (item.type === "agentMessage") {
|
|
26496
|
+
if (!item.text) return null;
|
|
26497
|
+
return {
|
|
26498
|
+
id: `agent-${item.id}`,
|
|
26499
|
+
type: "agent",
|
|
26500
|
+
content: item.text,
|
|
26501
|
+
timestamp: item.timestamp
|
|
26502
|
+
};
|
|
26503
|
+
}
|
|
26504
|
+
if (item.type === "reasoning") {
|
|
26505
|
+
if (!item.text) return null;
|
|
26506
|
+
return {
|
|
26507
|
+
id: `reasoning-${item.id}`,
|
|
26508
|
+
type: "reasoning",
|
|
26509
|
+
content: item.text,
|
|
26510
|
+
status: normalizeCodexAspTranscriptStatus(item.status),
|
|
26511
|
+
timestamp: item.timestamp,
|
|
26512
|
+
...item.sourceTimestamp ? { sourceTimestamp: item.sourceTimestamp } : {}
|
|
26513
|
+
};
|
|
26514
|
+
}
|
|
26515
|
+
if (item.type === "commandExecution") {
|
|
26516
|
+
const skillNames = skillNamesFromCommand(item.command);
|
|
26517
|
+
return {
|
|
26518
|
+
id: `command-${item.id}`,
|
|
26519
|
+
type: "command",
|
|
26520
|
+
command: item.command,
|
|
26521
|
+
...skillNames.length > 0 ? { skillNames } : {},
|
|
26522
|
+
output: item.output,
|
|
26523
|
+
exitCode: item.exitCode ?? void 0,
|
|
26524
|
+
status: normalizeCodexAspTranscriptStatus(item.status),
|
|
26525
|
+
timestamp: item.timestamp
|
|
26526
|
+
};
|
|
26527
|
+
}
|
|
26528
|
+
if (item.type === "fileChange") {
|
|
26529
|
+
return {
|
|
26530
|
+
id: `patch-${item.id}`,
|
|
26531
|
+
type: "patch",
|
|
26532
|
+
operations: item.operations,
|
|
26533
|
+
output: item.output,
|
|
26534
|
+
exitCode: item.exitCode ?? void 0,
|
|
26535
|
+
status: normalizeCodexAspTranscriptStatus(item.status),
|
|
26536
|
+
timestamp: item.timestamp
|
|
26537
|
+
};
|
|
26538
|
+
}
|
|
26539
|
+
if (item.type === "toolCall") {
|
|
26540
|
+
return createCallDisplayMessage({
|
|
26541
|
+
id: `toolcall-${item.id}`,
|
|
26542
|
+
server: item.server,
|
|
26543
|
+
tool: item.tool,
|
|
26544
|
+
input: inputForDisplay(item.input),
|
|
26545
|
+
output: item.output,
|
|
26546
|
+
status: normalizeCodexAspTranscriptStatus(item.status),
|
|
26547
|
+
timestamp: item.timestamp
|
|
26548
|
+
});
|
|
26549
|
+
}
|
|
26550
|
+
if (item.type === "subagent") {
|
|
26551
|
+
return {
|
|
26552
|
+
id: `subagent-${item.id}`,
|
|
26553
|
+
type: "subagent",
|
|
26554
|
+
toolUseId: item.id,
|
|
26555
|
+
description: item.description,
|
|
26556
|
+
prompt: item.prompt,
|
|
26557
|
+
subagentType: item.subagentType,
|
|
26558
|
+
...item.receiverThreadIds ? { receiverThreadIds: item.receiverThreadIds } : {},
|
|
26559
|
+
...item.model ? { model: item.model } : {},
|
|
26560
|
+
status: normalizeCodexAspTranscriptStatus(item.status),
|
|
26561
|
+
...item.output ? { output: item.output } : {},
|
|
26562
|
+
nestedEvents: [],
|
|
26563
|
+
timestamp: item.timestamp
|
|
26564
|
+
};
|
|
26565
|
+
}
|
|
26566
|
+
if (item.type === "webSearch") {
|
|
26567
|
+
return {
|
|
26568
|
+
id: `web-search-${item.id}`,
|
|
26569
|
+
type: "web_search",
|
|
26570
|
+
query: item.query,
|
|
26571
|
+
status: normalizeCodexAspTranscriptStatus(item.status),
|
|
26572
|
+
timestamp: item.timestamp
|
|
26573
|
+
};
|
|
26574
|
+
}
|
|
26575
|
+
if (item.type === "plan") {
|
|
26576
|
+
if (!item.text) return null;
|
|
26577
|
+
return {
|
|
26578
|
+
id: `todo-${item.id}`,
|
|
26579
|
+
type: "todo_list",
|
|
26580
|
+
items: item.text.split("\n").map((line) => line.trim()).filter(Boolean).map((text) => ({ text, completed: item.status === "completed" })),
|
|
26581
|
+
status: normalizeCodexAspTranscriptStatus(item.status),
|
|
26582
|
+
timestamp: item.timestamp
|
|
26583
|
+
};
|
|
26584
|
+
}
|
|
26585
|
+
if (item.type === "contextCompaction") {
|
|
26586
|
+
return {
|
|
26587
|
+
id: `reasoning-${item.id}`,
|
|
26588
|
+
type: "reasoning",
|
|
26589
|
+
content: "Context compacted",
|
|
26590
|
+
status: normalizeCodexAspTranscriptStatus(item.status),
|
|
26591
|
+
timestamp: item.timestamp
|
|
26592
|
+
};
|
|
26593
|
+
}
|
|
26594
|
+
return {
|
|
26595
|
+
id: `error-${item.id}`,
|
|
26596
|
+
type: "error",
|
|
26597
|
+
message: item.message,
|
|
26598
|
+
timestamp: item.timestamp
|
|
26599
|
+
};
|
|
26600
|
+
}
|
|
26601
|
+
function skillMessagesForItem(item) {
|
|
26602
|
+
if (item.type !== "userMessage" || !item.skillNames) return [];
|
|
26603
|
+
return item.skillNames.filter((skillName) => skillName.trim().length > 0).map((skillName, index) => ({
|
|
26604
|
+
id: `skill-${item.id}-${index}`,
|
|
26605
|
+
type: "skill",
|
|
26606
|
+
skillName,
|
|
26607
|
+
status: "completed",
|
|
26608
|
+
timestamp: item.timestamp
|
|
26609
|
+
}));
|
|
26610
|
+
}
|
|
26611
|
+
function stableString(value) {
|
|
26612
|
+
if (value === void 0) return "";
|
|
26613
|
+
if (typeof value !== "object" || value === null) return String(value);
|
|
26614
|
+
try {
|
|
26615
|
+
return JSON.stringify(value, Object.keys(value).sort());
|
|
26616
|
+
} catch {
|
|
26617
|
+
return String(value);
|
|
26618
|
+
}
|
|
26619
|
+
}
|
|
26620
|
+
function duplicateKey(message) {
|
|
26621
|
+
if (message.type === "user" || message.type === "agent" || message.type === "reasoning") {
|
|
26622
|
+
return JSON.stringify([message.type, message.content]);
|
|
26623
|
+
}
|
|
26624
|
+
if (message.type === "command") return JSON.stringify([message.type, message.command]);
|
|
26625
|
+
if (message.type === "web_search") return JSON.stringify([message.type, message.query]);
|
|
26626
|
+
if (message.type === "subagent") {
|
|
26627
|
+
return JSON.stringify([
|
|
26628
|
+
message.type,
|
|
26629
|
+
message.description,
|
|
26630
|
+
message.prompt,
|
|
26631
|
+
message.subagentType,
|
|
26632
|
+
message.model
|
|
26633
|
+
]);
|
|
26634
|
+
}
|
|
26635
|
+
if (message.type === "todo_list") {
|
|
26636
|
+
return JSON.stringify([message.type, stableString(message.items)]);
|
|
26637
|
+
}
|
|
26638
|
+
if (message.type === "patch") {
|
|
26639
|
+
return JSON.stringify([message.type, stableString(message.operations)]);
|
|
26640
|
+
}
|
|
26641
|
+
if (message.type === "tool_call") {
|
|
26642
|
+
return JSON.stringify([
|
|
26643
|
+
message.type,
|
|
26644
|
+
message.server,
|
|
26645
|
+
message.tool,
|
|
26646
|
+
stableString(message.input)
|
|
26647
|
+
]);
|
|
26648
|
+
}
|
|
26649
|
+
return null;
|
|
26650
|
+
}
|
|
26651
|
+
function duplicateBucketKey(message, bucketOffset = 0) {
|
|
26652
|
+
const key = duplicateKey(message);
|
|
26653
|
+
if (key === null) return null;
|
|
26654
|
+
const bucket = Math.floor(parseTimestampMs(message.timestamp) / DUPLICATE_WINDOW_MS) + bucketOffset;
|
|
26655
|
+
return JSON.stringify([bucket, key]);
|
|
26656
|
+
}
|
|
26657
|
+
function mergeCodexAspDisplayMessages(primary, supplemental) {
|
|
26658
|
+
const merged = [...primary];
|
|
26659
|
+
const primaryCount = primary.length;
|
|
26660
|
+
const firstIndexById = /* @__PURE__ */ new Map();
|
|
26661
|
+
const indexesByDuplicateBucket = /* @__PURE__ */ new Map();
|
|
26662
|
+
const indexMessage = (message, index) => {
|
|
26663
|
+
if (!firstIndexById.has(message.id)) firstIndexById.set(message.id, index);
|
|
26664
|
+
const key = duplicateBucketKey(message);
|
|
26665
|
+
if (key === null) return;
|
|
26666
|
+
const indexes = indexesByDuplicateBucket.get(key) ?? /* @__PURE__ */ new Set();
|
|
26667
|
+
indexes.add(index);
|
|
26668
|
+
indexesByDuplicateBucket.set(key, indexes);
|
|
26669
|
+
};
|
|
26670
|
+
const unindexMessage = (message, index) => {
|
|
26671
|
+
const key = duplicateBucketKey(message);
|
|
26672
|
+
if (key === null) return;
|
|
26673
|
+
const indexes = indexesByDuplicateBucket.get(key);
|
|
26674
|
+
indexes?.delete(index);
|
|
26675
|
+
if (indexes?.size === 0) indexesByDuplicateBucket.delete(key);
|
|
26676
|
+
};
|
|
26677
|
+
merged.forEach(indexMessage);
|
|
26678
|
+
for (const message of supplemental) {
|
|
26679
|
+
let duplicateIndex = firstIndexById.get(message.id);
|
|
26680
|
+
if (duplicateIndex === void 0) {
|
|
26681
|
+
for (let bucketOffset = -1; bucketOffset <= 1; bucketOffset += 1) {
|
|
26682
|
+
const key = duplicateBucketKey(message, bucketOffset);
|
|
26683
|
+
for (const index of (key === null ? void 0 : indexesByDuplicateBucket.get(key)) ?? []) {
|
|
26684
|
+
if (nearTimestamp(merged[index].timestamp, message.timestamp) && (duplicateIndex === void 0 || index < duplicateIndex)) {
|
|
26685
|
+
duplicateIndex = index;
|
|
27048
26686
|
}
|
|
27049
26687
|
}
|
|
27050
|
-
});
|
|
27051
|
-
}
|
|
27052
|
-
if (event.type === "claude-result") {
|
|
27053
|
-
const payload = coerceClaudeResultPayload(event.payload);
|
|
27054
|
-
if (isClaudeResultError(payload)) {
|
|
27055
|
-
const genuineErrors = stripAgentDiagnosticErrors(payload.errors ?? []);
|
|
27056
|
-
messages.push({
|
|
27057
|
-
id: `error-${event.timestamp}`,
|
|
27058
|
-
type: "error",
|
|
27059
|
-
message: genuineErrors.length > 0 ? genuineErrors.join("\n") : "Claude session encountered an unexpected error.",
|
|
27060
|
-
timestamp: event.timestamp
|
|
27061
|
-
});
|
|
27062
|
-
}
|
|
27063
|
-
}
|
|
27064
|
-
if (event.type === "claude-system") {
|
|
27065
|
-
const payload = coerceBackgroundTaskPayload(event.payload);
|
|
27066
|
-
if (payload?.ambient) ambientTaskIds.add(payload.taskId);
|
|
27067
|
-
if (payload && !ambientTaskIds.has(payload.taskId)) {
|
|
27068
|
-
const existing = taskMessageMap.get(payload.taskId);
|
|
27069
|
-
const nextStatus = payload.subtype === "task_notification" ? normalizeBackgroundTaskStatus(payload.status) : payload.subtype === "task_updated" ? normalizeBackgroundTaskStatus(payload.patch?.status) : existing?.status ?? "in_progress";
|
|
27070
|
-
const nextMessage = {
|
|
27071
|
-
id: existing?.id ?? `task-${event.timestamp}-${messages.length}`,
|
|
27072
|
-
type: "background_task",
|
|
27073
|
-
taskId: payload.taskId,
|
|
27074
|
-
status: nextStatus,
|
|
27075
|
-
description: payload.description ?? payload.patch?.description ?? existing?.description,
|
|
27076
|
-
summary: payload.summary ?? existing?.summary,
|
|
27077
|
-
outputFile: payload.outputFile ?? existing?.outputFile,
|
|
27078
|
-
taskType: payload.taskType ?? existing?.taskType,
|
|
27079
|
-
workflowName: payload.workflowName ?? existing?.workflowName,
|
|
27080
|
-
prompt: payload.prompt ?? existing?.prompt,
|
|
27081
|
-
lastToolName: payload.lastToolName ?? existing?.lastToolName,
|
|
27082
|
-
usage: payload.usage ?? existing?.usage,
|
|
27083
|
-
error: payload.patch?.error ?? existing?.error,
|
|
27084
|
-
isBackgrounded: payload.patch?.isBackgrounded ?? existing?.isBackgrounded,
|
|
27085
|
-
timestamp: existing?.timestamp ?? event.timestamp
|
|
27086
|
-
};
|
|
27087
|
-
if (existing) {
|
|
27088
|
-
Object.assign(existing, nextMessage);
|
|
27089
|
-
} else {
|
|
27090
|
-
taskMessageMap.set(payload.taskId, nextMessage);
|
|
27091
|
-
messages.push(nextMessage);
|
|
27092
|
-
}
|
|
27093
26688
|
}
|
|
27094
26689
|
}
|
|
27095
|
-
|
|
27096
|
-
|
|
27097
|
-
if (
|
|
27098
|
-
|
|
27099
|
-
|
|
27100
|
-
|
|
27101
|
-
|
|
27102
|
-
if (!toolInfo) return;
|
|
27103
|
-
const message = messages[toolInfo.messageIndex];
|
|
27104
|
-
if (!message || message.type !== "tool_call") return;
|
|
27105
|
-
message.inputRequest = {
|
|
27106
|
-
requestId: payload.requestId,
|
|
27107
|
-
status: "pending",
|
|
27108
|
-
options: payload.options,
|
|
27109
|
-
questions: payload.questions
|
|
27110
|
-
};
|
|
27111
|
-
}
|
|
27112
|
-
if (event.type === "replicas-tool-input-resolved") {
|
|
27113
|
-
const payload = event.payload;
|
|
27114
|
-
if (!payload.toolUseId || !payload.selectionId) return;
|
|
27115
|
-
const toolInfo = toolCallMap.get(payload.toolUseId);
|
|
27116
|
-
if (!toolInfo) return;
|
|
27117
|
-
const message = messages[toolInfo.messageIndex];
|
|
27118
|
-
if (!message || message.type !== "tool_call" || !message.inputRequest) return;
|
|
27119
|
-
message.inputRequest = {
|
|
27120
|
-
...message.inputRequest,
|
|
27121
|
-
status: payload.selectionId === "aborted" ? "aborted" : "resolved",
|
|
27122
|
-
selectionId: payload.selectionId,
|
|
27123
|
-
selectionSummary: payload.selectionSummary
|
|
26690
|
+
if (duplicateIndex === void 0) {
|
|
26691
|
+
indexMessage(message, merged.push(message) - 1);
|
|
26692
|
+
} else if (message.type === "user") {
|
|
26693
|
+
unindexMessage(merged[duplicateIndex], duplicateIndex);
|
|
26694
|
+
merged[duplicateIndex] = {
|
|
26695
|
+
...merged[duplicateIndex],
|
|
26696
|
+
id: message.id
|
|
27124
26697
|
};
|
|
26698
|
+
firstIndexById.set(message.id, duplicateIndex);
|
|
26699
|
+
indexMessage(merged[duplicateIndex], duplicateIndex);
|
|
27125
26700
|
}
|
|
26701
|
+
}
|
|
26702
|
+
const ordered = merged.slice(0, primaryCount);
|
|
26703
|
+
const supplementalOnly = merged.slice(primaryCount).map((message, index) => ({ message, index })).sort((a, b) => parseTimestampMs(a.message.timestamp) - parseTimestampMs(b.message.timestamp) || a.index - b.index);
|
|
26704
|
+
for (const { message } of supplementalOnly) {
|
|
26705
|
+
insertDisplayMessageByTimestamp(ordered, message);
|
|
26706
|
+
}
|
|
26707
|
+
return ordered;
|
|
26708
|
+
}
|
|
26709
|
+
function parseCodexAspTranscript(transcript) {
|
|
26710
|
+
const messages = [];
|
|
26711
|
+
const orderedItems = transcript.turns.map((turn, turnIndex) => ({ turn, turnIndex })).flatMap(({ turn, turnIndex }) => turn.items.map((item, itemIndex) => ({ item, turn, turnIndex, itemIndex }))).sort((a, b) => {
|
|
26712
|
+
const aSequence = a.item.sequence ?? Number.MAX_SAFE_INTEGER;
|
|
26713
|
+
const bSequence = b.item.sequence ?? Number.MAX_SAFE_INTEGER;
|
|
26714
|
+
return aSequence - bSequence || parseTimestampMs(a.item.timestamp) - parseTimestampMs(b.item.timestamp) || a.turnIndex - b.turnIndex || a.itemIndex - b.itemIndex;
|
|
27126
26715
|
});
|
|
27127
|
-
|
|
27128
|
-
|
|
27129
|
-
|
|
27130
|
-
|
|
27131
|
-
|
|
27132
|
-
|
|
27133
|
-
|
|
27134
|
-
|
|
27135
|
-
|
|
27136
|
-
|
|
27137
|
-
|
|
27138
|
-
|
|
27139
|
-
|
|
27140
|
-
|
|
27141
|
-
|
|
27142
|
-
|
|
27143
|
-
|
|
27144
|
-
|
|
27145
|
-
|
|
27146
|
-
|
|
27147
|
-
|
|
27148
|
-
|
|
27149
|
-
|
|
27150
|
-
}
|
|
27151
|
-
} else if (message.type === "patch") {
|
|
27152
|
-
message.status = status;
|
|
27153
|
-
} else if (message.type === "web_search") {
|
|
27154
|
-
message.status = status;
|
|
27155
|
-
} else if (message.type === "tool_call") {
|
|
27156
|
-
message.output = resultContent;
|
|
27157
|
-
message.status = status;
|
|
27158
|
-
} else if (message.type === "skill") {
|
|
27159
|
-
message.status = status;
|
|
27160
|
-
} else if (message.type === "subagent") {
|
|
27161
|
-
message.output = resultContent;
|
|
27162
|
-
message.status = status;
|
|
27163
|
-
if (!message.chatId && resultContent) {
|
|
27164
|
-
const parsed = safeJsonParse(resultContent, {});
|
|
27165
|
-
if (parsed.chatId) {
|
|
27166
|
-
message.chatId = parsed.chatId;
|
|
27167
|
-
}
|
|
27168
|
-
}
|
|
27169
|
-
} else if (message.type === "subagent_followup") {
|
|
27170
|
-
message.output = resultContent;
|
|
27171
|
-
message.status = status;
|
|
27172
|
-
}
|
|
26716
|
+
const reasoningByTurnId = /* @__PURE__ */ new Map();
|
|
26717
|
+
for (const { item, turn } of orderedItems) {
|
|
26718
|
+
if (item.type !== "reasoning" || !item.text.trim()) continue;
|
|
26719
|
+
const reasoning = reasoningByTurnId.get(turn.id) ?? [];
|
|
26720
|
+
reasoning.push(item);
|
|
26721
|
+
reasoningByTurnId.set(turn.id, reasoning);
|
|
26722
|
+
}
|
|
26723
|
+
const emittedReasoningTurnIds = /* @__PURE__ */ new Set();
|
|
26724
|
+
const coalescedItems = orderedItems.flatMap((entry) => {
|
|
26725
|
+
if (entry.item.type !== "reasoning") return [entry];
|
|
26726
|
+
const reasoning = reasoningByTurnId.get(entry.turn.id);
|
|
26727
|
+
if (!reasoning || emittedReasoningTurnIds.has(entry.turn.id)) return [];
|
|
26728
|
+
emittedReasoningTurnIds.add(entry.turn.id);
|
|
26729
|
+
return [{
|
|
26730
|
+
...entry,
|
|
26731
|
+
item: {
|
|
26732
|
+
type: "reasoning",
|
|
26733
|
+
id: entry.turn.id,
|
|
26734
|
+
text: reasoning.map(({ text }) => text.trim()).join("\n\n"),
|
|
26735
|
+
timestamp: entry.turn.startedAt,
|
|
26736
|
+
...reasoning[0] ? { sourceTimestamp: reasoning[0].timestamp } : {},
|
|
26737
|
+
status: reasoning.at(-1)?.status ?? "completed",
|
|
26738
|
+
sequence: entry.item.sequence
|
|
27173
26739
|
}
|
|
27174
|
-
}
|
|
26740
|
+
}];
|
|
27175
26741
|
});
|
|
27176
|
-
for (const
|
|
27177
|
-
|
|
27178
|
-
|
|
27179
|
-
|
|
27180
|
-
|
|
27181
|
-
|
|
27182
|
-
}
|
|
26742
|
+
for (const turn of transcript.turns) {
|
|
26743
|
+
const reasoningIndex = coalescedItems.findIndex(({ item, turn: itemTurn }) => itemTurn.id === turn.id && item.type === "reasoning");
|
|
26744
|
+
if (reasoningIndex === -1) continue;
|
|
26745
|
+
const responseItem = getCodexAspTurnResponse({
|
|
26746
|
+
status: turn.status,
|
|
26747
|
+
items: coalescedItems.filter(({ turn: itemTurn }) => itemTurn.id === turn.id).map(({ item }) => item)
|
|
26748
|
+
});
|
|
26749
|
+
const finalAnswerIndex = responseItem ? coalescedItems.findIndex(({ item }) => item === responseItem) : -1;
|
|
26750
|
+
if (finalAnswerIndex === -1 || reasoningIndex < finalAnswerIndex) continue;
|
|
26751
|
+
const [reasoning] = coalescedItems.splice(reasoningIndex, 1);
|
|
26752
|
+
coalescedItems.splice(finalAnswerIndex, 0, reasoning);
|
|
27183
26753
|
}
|
|
27184
|
-
const
|
|
27185
|
-
|
|
27186
|
-
|
|
27187
|
-
|
|
27188
|
-
|
|
26754
|
+
for (const { item } of coalescedItems) {
|
|
26755
|
+
const message = messageForItem(item);
|
|
26756
|
+
if (message) {
|
|
26757
|
+
messages.push(message);
|
|
26758
|
+
}
|
|
26759
|
+
messages.push(...skillMessagesForItem(item));
|
|
27189
26760
|
}
|
|
27190
|
-
|
|
27191
|
-
return messages.filter((_2, index) => !staleIndexes.has(index));
|
|
26761
|
+
return messages;
|
|
27192
26762
|
}
|
|
27193
26763
|
|
|
27194
|
-
// ../shared/src/display-message/parsers/
|
|
27195
|
-
var
|
|
27196
|
-
function
|
|
27197
|
-
|
|
27198
|
-
|
|
27199
|
-
function inputForDisplay(input) {
|
|
27200
|
-
if (input === void 0 || input === null) return void 0;
|
|
27201
|
-
if (typeof input === "string") return input;
|
|
27202
|
-
if (isRecord(input)) return input;
|
|
27203
|
-
return String(input);
|
|
27204
|
-
}
|
|
27205
|
-
function isInternalUserMessage(content) {
|
|
27206
|
-
const trimmed = content.trim();
|
|
27207
|
-
return trimmed.startsWith("<environment_context>") || trimmed.startsWith("<goal_context>");
|
|
27208
|
-
}
|
|
27209
|
-
function messageForItem(item) {
|
|
27210
|
-
if (item.type === "userMessage") {
|
|
27211
|
-
if (isInternalUserMessage(item.content)) return null;
|
|
27212
|
-
return {
|
|
27213
|
-
id: `user-${item.id}`,
|
|
27214
|
-
type: "user",
|
|
27215
|
-
content: item.content,
|
|
27216
|
-
images: item.images,
|
|
27217
|
-
timestamp: item.timestamp
|
|
27218
|
-
};
|
|
26764
|
+
// ../shared/src/display-message/parsers/index.ts
|
|
26765
|
+
var INTERRUPTION_DEDUP_WINDOW_MS = 15e3;
|
|
26766
|
+
function parseAgentEvents(events, agentType) {
|
|
26767
|
+
if (agentType === "codex") {
|
|
26768
|
+
return parseCodexEvents(events);
|
|
27219
26769
|
}
|
|
27220
|
-
if (
|
|
27221
|
-
|
|
27222
|
-
return {
|
|
27223
|
-
id: `agent-${item.id}`,
|
|
27224
|
-
type: "agent",
|
|
27225
|
-
content: item.text,
|
|
27226
|
-
timestamp: item.timestamp
|
|
27227
|
-
};
|
|
26770
|
+
if (agentType === "cursor") {
|
|
26771
|
+
return parseCursorEvents(events);
|
|
27228
26772
|
}
|
|
27229
|
-
if (
|
|
27230
|
-
|
|
27231
|
-
return {
|
|
27232
|
-
id: `reasoning-${item.id}`,
|
|
27233
|
-
type: "reasoning",
|
|
27234
|
-
content: item.text,
|
|
27235
|
-
status: normalizeCodexAspTranscriptStatus(item.status),
|
|
27236
|
-
timestamp: item.timestamp,
|
|
27237
|
-
...item.sourceTimestamp ? { sourceTimestamp: item.sourceTimestamp } : {}
|
|
27238
|
-
};
|
|
26773
|
+
if (agentType === "deepseek") {
|
|
26774
|
+
return parseDeepseekEvents(events);
|
|
27239
26775
|
}
|
|
27240
|
-
if (
|
|
27241
|
-
|
|
27242
|
-
return {
|
|
27243
|
-
id: `command-${item.id}`,
|
|
27244
|
-
type: "command",
|
|
27245
|
-
command: item.command,
|
|
27246
|
-
...skillNames.length > 0 ? { skillNames } : {},
|
|
27247
|
-
output: item.output,
|
|
27248
|
-
exitCode: item.exitCode ?? void 0,
|
|
27249
|
-
status: normalizeCodexAspTranscriptStatus(item.status),
|
|
27250
|
-
timestamp: item.timestamp
|
|
27251
|
-
};
|
|
26776
|
+
if (agentType === "fx") {
|
|
26777
|
+
return parseFxEvents(events);
|
|
27252
26778
|
}
|
|
27253
|
-
if (
|
|
27254
|
-
return
|
|
27255
|
-
id: `patch-${item.id}`,
|
|
27256
|
-
type: "patch",
|
|
27257
|
-
operations: item.operations,
|
|
27258
|
-
output: item.output,
|
|
27259
|
-
exitCode: item.exitCode ?? void 0,
|
|
27260
|
-
status: normalizeCodexAspTranscriptStatus(item.status),
|
|
27261
|
-
timestamp: item.timestamp
|
|
27262
|
-
};
|
|
26779
|
+
if (agentType === "kimi") {
|
|
26780
|
+
return parseAcpEvents(events, "kimi");
|
|
27263
26781
|
}
|
|
27264
|
-
if (
|
|
27265
|
-
return
|
|
27266
|
-
id: `toolcall-${item.id}`,
|
|
27267
|
-
server: item.server,
|
|
27268
|
-
tool: item.tool,
|
|
27269
|
-
input: inputForDisplay(item.input),
|
|
27270
|
-
output: item.output,
|
|
27271
|
-
status: normalizeCodexAspTranscriptStatus(item.status),
|
|
27272
|
-
timestamp: item.timestamp
|
|
27273
|
-
});
|
|
26782
|
+
if (agentType === "muse") {
|
|
26783
|
+
return parseMuseEvents(events);
|
|
27274
26784
|
}
|
|
27275
|
-
if (
|
|
27276
|
-
return
|
|
27277
|
-
id: `subagent-${item.id}`,
|
|
27278
|
-
type: "subagent",
|
|
27279
|
-
toolUseId: item.id,
|
|
27280
|
-
description: item.description,
|
|
27281
|
-
prompt: item.prompt,
|
|
27282
|
-
subagentType: item.subagentType,
|
|
27283
|
-
...item.receiverThreadIds ? { receiverThreadIds: item.receiverThreadIds } : {},
|
|
27284
|
-
...item.model ? { model: item.model } : {},
|
|
27285
|
-
status: normalizeCodexAspTranscriptStatus(item.status),
|
|
27286
|
-
...item.output ? { output: item.output } : {},
|
|
27287
|
-
nestedEvents: [],
|
|
27288
|
-
timestamp: item.timestamp
|
|
27289
|
-
};
|
|
26785
|
+
if (agentType === "opencode") {
|
|
26786
|
+
return parseOpencodeEvents(events);
|
|
27290
26787
|
}
|
|
27291
|
-
if (
|
|
27292
|
-
return
|
|
27293
|
-
id: `web-search-${item.id}`,
|
|
27294
|
-
type: "web_search",
|
|
27295
|
-
query: item.query,
|
|
27296
|
-
status: normalizeCodexAspTranscriptStatus(item.status),
|
|
27297
|
-
timestamp: item.timestamp
|
|
27298
|
-
};
|
|
26788
|
+
if (agentType === "pi") {
|
|
26789
|
+
return parsePiEvents(events);
|
|
27299
26790
|
}
|
|
27300
|
-
|
|
27301
|
-
|
|
27302
|
-
|
|
27303
|
-
|
|
27304
|
-
|
|
27305
|
-
|
|
27306
|
-
|
|
27307
|
-
|
|
27308
|
-
|
|
26791
|
+
return parseClaudeEvents(events);
|
|
26792
|
+
}
|
|
26793
|
+
function parseDisplayMessages(events, agentType, codexAspTranscript, options = {}) {
|
|
26794
|
+
const shouldFilter = options.filter ?? true;
|
|
26795
|
+
const parsedEvents = agentType === "claude" || agentType === "relay" ? parseClaudeEvents(events, options.parentToolUseId) : parseAgentEvents(events, agentType);
|
|
26796
|
+
const reconciledEvents = [];
|
|
26797
|
+
for (const message of parsedEvents) {
|
|
26798
|
+
if (message.type === "user") upsertDisplayMessage(reconciledEvents, message);
|
|
26799
|
+
else reconciledEvents.push(message);
|
|
27309
26800
|
}
|
|
27310
|
-
|
|
27311
|
-
|
|
27312
|
-
|
|
27313
|
-
|
|
27314
|
-
|
|
27315
|
-
|
|
27316
|
-
|
|
26801
|
+
const legacyMessages = shouldFilter ? filterDisplayMessages(reconciledEvents, agentType) : reconciledEvents;
|
|
26802
|
+
const applySyntheticNotices = (messages) => shouldFilter ? applyAuthFallbackNotices(applyInterruptions(messages, events), events) : messages;
|
|
26803
|
+
if (agentType !== "codex" || !codexAspTranscript) {
|
|
26804
|
+
return applySyntheticNotices(legacyMessages);
|
|
26805
|
+
}
|
|
26806
|
+
const nativeCodexMessages = shouldFilter ? filterDisplayMessages(parseCodexAspTranscript(codexAspTranscript), agentType) : parseCodexAspTranscript(codexAspTranscript);
|
|
26807
|
+
return applySyntheticNotices(mergeCodexAspDisplayMessages(nativeCodexMessages, legacyMessages));
|
|
26808
|
+
}
|
|
26809
|
+
function applyInterruptions(messages, events) {
|
|
26810
|
+
const result = [...messages];
|
|
26811
|
+
for (const event of events) {
|
|
26812
|
+
if (event.type !== CHAT_INTERRUPTED_EVENT_TYPE) continue;
|
|
26813
|
+
insertDisplayMessageByTimestamp(result, {
|
|
26814
|
+
id: `interruption-${event.timestamp}`,
|
|
26815
|
+
type: "interruption",
|
|
26816
|
+
timestamp: event.timestamp
|
|
26817
|
+
});
|
|
26818
|
+
}
|
|
26819
|
+
let lastUserMs = null;
|
|
26820
|
+
let lastInterruption = null;
|
|
26821
|
+
const finalized = [];
|
|
26822
|
+
for (const msg of result) {
|
|
26823
|
+
if (msg.type === "user") {
|
|
26824
|
+
lastUserMs = parseTimestampMs(msg.timestamp);
|
|
26825
|
+
lastInterruption = null;
|
|
26826
|
+
finalized.push(msg);
|
|
26827
|
+
continue;
|
|
26828
|
+
}
|
|
26829
|
+
if (msg.type !== "interruption") {
|
|
26830
|
+
finalized.push(msg);
|
|
26831
|
+
continue;
|
|
26832
|
+
}
|
|
26833
|
+
const ms = parseTimestampMs(msg.timestamp);
|
|
26834
|
+
if (lastInterruption && ms - parseTimestampMs(lastInterruption.timestamp) <= INTERRUPTION_DEDUP_WINDOW_MS) {
|
|
26835
|
+
continue;
|
|
26836
|
+
}
|
|
26837
|
+
lastInterruption = {
|
|
26838
|
+
...msg,
|
|
26839
|
+
...lastUserMs !== null && ms >= lastUserMs ? { durationMs: ms - lastUserMs } : {}
|
|
27317
26840
|
};
|
|
26841
|
+
finalized.push(lastInterruption);
|
|
26842
|
+
}
|
|
26843
|
+
return finalized;
|
|
26844
|
+
}
|
|
26845
|
+
function applyAuthFallbackNotices(messages, events) {
|
|
26846
|
+
const notices = [];
|
|
26847
|
+
events.forEach((event, index) => {
|
|
26848
|
+
if (event.type !== AUTH_FALLBACK_EVENT_TYPE) return;
|
|
26849
|
+
const payload = coerceAuthFallbackPayload(event.payload);
|
|
26850
|
+
if (!payload) return;
|
|
26851
|
+
notices.push({
|
|
26852
|
+
...payload,
|
|
26853
|
+
id: `auth-fallback-${event.timestamp}-${index}`,
|
|
26854
|
+
type: "auth_fallback",
|
|
26855
|
+
timestamp: event.timestamp
|
|
26856
|
+
});
|
|
26857
|
+
});
|
|
26858
|
+
if (notices.length === 0) return messages;
|
|
26859
|
+
const result = [...messages];
|
|
26860
|
+
for (const notice of notices) insertDisplayMessageByTimestamp(result, notice);
|
|
26861
|
+
return result;
|
|
26862
|
+
}
|
|
26863
|
+
function isCodexInitializationPrompt(message) {
|
|
26864
|
+
return message.type === "user" && removeReplicasInstructions(message.content).trim() === "Hello";
|
|
26865
|
+
}
|
|
26866
|
+
function filterDisplayMessages(messages, provider) {
|
|
26867
|
+
let result = messages;
|
|
26868
|
+
if (provider === "codex") {
|
|
26869
|
+
const userMessages = result.map((msg, index) => ({ msg, index })).filter(({ msg }) => msg.type === "user");
|
|
26870
|
+
if (userMessages.length >= 2 && isCodexInitializationPrompt(userMessages[0].msg)) {
|
|
26871
|
+
result = result.slice(userMessages[1].index);
|
|
26872
|
+
}
|
|
26873
|
+
}
|
|
26874
|
+
result = result.map((msg) => {
|
|
26875
|
+
if (msg.type !== "user") return msg;
|
|
26876
|
+
const cleaned = removeReplicasInstructions(msg.content).trim();
|
|
26877
|
+
if (INTERRUPTED_MESSAGE_REGEX.test(cleaned)) {
|
|
26878
|
+
return { id: msg.id, type: "interruption", timestamp: msg.timestamp };
|
|
26879
|
+
}
|
|
26880
|
+
return cleaned !== msg.content ? { ...msg, content: cleaned } : msg;
|
|
26881
|
+
});
|
|
26882
|
+
return result;
|
|
26883
|
+
}
|
|
26884
|
+
|
|
26885
|
+
// ../shared/src/agent-event-utils.ts
|
|
26886
|
+
function getUserMessage(event) {
|
|
26887
|
+
return event.type === "event_msg" && event.payload.type === "user_message" && typeof event.payload.message === "string" ? event.payload.message : null;
|
|
26888
|
+
}
|
|
26889
|
+
function getUserMessageId(event) {
|
|
26890
|
+
const messageId = event.payload[USER_MESSAGE_ID_PAYLOAD_KEY];
|
|
26891
|
+
return typeof messageId === "string" ? messageId : null;
|
|
26892
|
+
}
|
|
26893
|
+
|
|
26894
|
+
// ../shared/src/pricing.ts
|
|
26895
|
+
var AUTOMATED_SOURCES = ["api", "automation"];
|
|
26896
|
+
var AUTOMATED_SOURCES_SQL = AUTOMATED_SOURCES.map((s) => `'${s}'`).join(", ");
|
|
26897
|
+
var PLANS = {
|
|
26898
|
+
trial: {
|
|
26899
|
+
id: "trial",
|
|
26900
|
+
name: "Free Trial",
|
|
26901
|
+
monthlyPrice: 0,
|
|
26902
|
+
seatPriceCents: 0,
|
|
26903
|
+
features: [
|
|
26904
|
+
"14 days free, no credit card required",
|
|
26905
|
+
"Unlimited manual workspace minutes",
|
|
26906
|
+
"15,000 automated workspace minutes",
|
|
26907
|
+
"Unlimited repositories and environments",
|
|
26908
|
+
"Unlimited automations",
|
|
26909
|
+
"Warm pools and warm hooks",
|
|
26910
|
+
"API access"
|
|
26911
|
+
]
|
|
26912
|
+
},
|
|
26913
|
+
developer: {
|
|
26914
|
+
id: "developer",
|
|
26915
|
+
name: "Developer",
|
|
26916
|
+
monthlyPrice: 120,
|
|
26917
|
+
seatPriceCents: 12e3,
|
|
26918
|
+
features: [
|
|
26919
|
+
"Unlimited manual workspace minutes",
|
|
26920
|
+
"5,000 automated workspace minutes per month",
|
|
26921
|
+
"Up to 10 repositories",
|
|
26922
|
+
"Up to 15 environments",
|
|
26923
|
+
"Up to 5 automations",
|
|
26924
|
+
"Warm pools and warm hooks",
|
|
26925
|
+
"API access",
|
|
26926
|
+
"Mobile app"
|
|
26927
|
+
]
|
|
26928
|
+
},
|
|
26929
|
+
team: {
|
|
26930
|
+
id: "team",
|
|
26931
|
+
name: "Team",
|
|
26932
|
+
monthlyPrice: 300,
|
|
26933
|
+
seatPriceCents: 3e4,
|
|
26934
|
+
features: [
|
|
26935
|
+
"Unlimited manual workspace minutes",
|
|
26936
|
+
"15,000 automated workspace minutes per month",
|
|
26937
|
+
"Unlimited repositories",
|
|
26938
|
+
"Unlimited automations",
|
|
26939
|
+
"Warm pools and warm hooks",
|
|
26940
|
+
"Higher API rate limits",
|
|
26941
|
+
"Access to a static egress IP",
|
|
26942
|
+
"Auto-upgraded sandbox resources (4 vCPU, 32 GB disk, 16 GB memory)",
|
|
26943
|
+
"Shared Slack support channel"
|
|
26944
|
+
]
|
|
26945
|
+
},
|
|
26946
|
+
enterprise: {
|
|
26947
|
+
id: "enterprise",
|
|
26948
|
+
name: "Enterprise",
|
|
26949
|
+
monthlyPrice: 0,
|
|
26950
|
+
seatPriceCents: 0,
|
|
26951
|
+
features: [
|
|
26952
|
+
"Unlimited manual workspace minutes",
|
|
26953
|
+
"Unlimited automated workspace minutes",
|
|
26954
|
+
"Unlimited automations",
|
|
26955
|
+
"Custom warm hooks and pools",
|
|
26956
|
+
"Custom API rates",
|
|
26957
|
+
"Custom rate limits",
|
|
26958
|
+
"Shared Slack support channel",
|
|
26959
|
+
"SOC 2",
|
|
26960
|
+
"Data Processing Agreement (DPA)",
|
|
26961
|
+
"SCIM user provisioning",
|
|
26962
|
+
"Custom security and privacy settings"
|
|
26963
|
+
]
|
|
27318
26964
|
}
|
|
27319
|
-
|
|
27320
|
-
|
|
27321
|
-
|
|
27322
|
-
|
|
27323
|
-
|
|
27324
|
-
|
|
26965
|
+
};
|
|
26966
|
+
var TEAM_PLAN = PLANS.team;
|
|
26967
|
+
var ENTERPRISE_PLAN = PLANS.enterprise;
|
|
26968
|
+
|
|
26969
|
+
// ../shared/src/port.ts
|
|
26970
|
+
function isValidPort(port) {
|
|
26971
|
+
return Number.isInteger(port) && Number(port) >= 1 && Number(port) <= 65535;
|
|
27325
26972
|
}
|
|
27326
|
-
function
|
|
27327
|
-
if (
|
|
27328
|
-
|
|
27329
|
-
|
|
27330
|
-
|
|
27331
|
-
skillName,
|
|
27332
|
-
status: "completed",
|
|
27333
|
-
timestamp: item.timestamp
|
|
27334
|
-
}));
|
|
26973
|
+
function parsePort(port) {
|
|
26974
|
+
if (!/^\d+$/.test(port)) throw new Error("Port must be a number between 1 and 65535");
|
|
26975
|
+
const portNumber = Number(port);
|
|
26976
|
+
if (!isValidPort(portNumber)) throw new Error("Port must be a number between 1 and 65535");
|
|
26977
|
+
return portNumber;
|
|
27335
26978
|
}
|
|
27336
|
-
|
|
27337
|
-
|
|
27338
|
-
|
|
27339
|
-
|
|
27340
|
-
|
|
27341
|
-
|
|
27342
|
-
|
|
26979
|
+
|
|
26980
|
+
// ../shared/src/models-dev.ts
|
|
26981
|
+
var MODELS_DEV_CACHE_MS = 5 * 6e4;
|
|
26982
|
+
var modelsDevCatalogSchema = external_exports.record(external_exports.string(), external_exports.object({
|
|
26983
|
+
models: external_exports.record(external_exports.string(), external_exports.object({
|
|
26984
|
+
id: external_exports.string().optional(),
|
|
26985
|
+
name: external_exports.string(),
|
|
26986
|
+
description: external_exports.string().optional(),
|
|
26987
|
+
status: external_exports.enum(["alpha", "beta", "deprecated"]).optional(),
|
|
26988
|
+
cost: external_exports.object({
|
|
26989
|
+
input: external_exports.number().finite().nonnegative().optional(),
|
|
26990
|
+
output: external_exports.number().finite().nonnegative().optional(),
|
|
26991
|
+
cache_read: external_exports.number().finite().nonnegative().optional(),
|
|
26992
|
+
cache_write: external_exports.number().finite().nonnegative().optional()
|
|
26993
|
+
}).optional()
|
|
26994
|
+
}))
|
|
26995
|
+
}));
|
|
26996
|
+
|
|
26997
|
+
// ../shared/src/sandbox.ts
|
|
26998
|
+
var SANDBOX_LIFECYCLE = {
|
|
26999
|
+
AUTO_STOP_MINUTES: 60,
|
|
27000
|
+
AUTO_ARCHIVE_MINUTES: 60 * 24 * 7,
|
|
27001
|
+
AUTO_DELETE_MINUTES: -1,
|
|
27002
|
+
SSH_TOKEN_EXPIRATION_MINUTES: 3 * 60
|
|
27003
|
+
};
|
|
27004
|
+
var SANDBOX_PATHS = {
|
|
27005
|
+
HOME_DIR: "/home/user",
|
|
27006
|
+
WORKSPACES_DIR: "/home/user/workspaces",
|
|
27007
|
+
REPLICAS_DIR: "/home/user/.replicas",
|
|
27008
|
+
ENGINE_INIT_GATE: "/home/user/.replicas/engine-init-gate",
|
|
27009
|
+
REPLICAS_CANVAS_DIR: "/home/user/.replicas/canvas",
|
|
27010
|
+
REPLICAS_RUNTIME_ENV_FILE: "/home/user/.replicas/runtime-env.sh"
|
|
27011
|
+
};
|
|
27012
|
+
var WORKSPACE_SIZES = ["small", "large"];
|
|
27013
|
+
var INVALID_WORKSPACE_SIZE_ERROR = `Invalid size: must be one of ${WORKSPACE_SIZES.join(", ")}`;
|
|
27014
|
+
|
|
27015
|
+
// ../shared/src/egress.ts
|
|
27016
|
+
var EGRESS_CIPHER = "2022-blake3-aes-256-gcm";
|
|
27017
|
+
var EGRESS_KEY_BYTES = 32;
|
|
27018
|
+
var EGRESS_SHADOWSOCKS_MODE = "tcp_and_udp";
|
|
27019
|
+
var EGRESS_SHADOWSOCKS_VERSION = "1.24.0";
|
|
27020
|
+
var EGRESS_SHADOWSOCKS_SHA256 = "0d84f5f350ec99396867d718f146fc3810975b2a7cd06192f158d96bdef460e7";
|
|
27021
|
+
var EGRESS_PORT_RANGE_START = 8400;
|
|
27022
|
+
var EGRESS_PORT_RANGE_END = 8499;
|
|
27023
|
+
var EGRESS_EXIT_IP_ENDPOINTS = [
|
|
27024
|
+
"https://checkip.amazonaws.com",
|
|
27025
|
+
"https://api.ipify.org",
|
|
27026
|
+
"https://icanhazip.com"
|
|
27027
|
+
];
|
|
27028
|
+
var EGRESS_DIRECT_ROUTES = [
|
|
27029
|
+
"10.0.0.0/8",
|
|
27030
|
+
"172.16.0.0/12",
|
|
27031
|
+
"192.168.0.0/16",
|
|
27032
|
+
"169.254.0.0/16",
|
|
27033
|
+
"100.64.0.0/10"
|
|
27034
|
+
];
|
|
27035
|
+
var EGRESS_NEW_CONN_RATE = 100;
|
|
27036
|
+
var EGRESS_NEW_CONN_BURST = 200;
|
|
27037
|
+
var EGRESS_UDP_RATE = 500;
|
|
27038
|
+
var EGRESS_UDP_BURST = 1e3;
|
|
27039
|
+
var EGRESS_OUT_CONN_RATE = 1e3;
|
|
27040
|
+
var EGRESS_OUT_CONN_BURST = 2e3;
|
|
27041
|
+
var EGRESS_DNS_SERVERS = ["1.1.1.1", "8.8.8.8"];
|
|
27042
|
+
var EGRESS_SHELL_CONFIG = [
|
|
27043
|
+
`EGRESS_PORT_RANGE_START=${EGRESS_PORT_RANGE_START}`,
|
|
27044
|
+
`EGRESS_PORT_RANGE_END=${EGRESS_PORT_RANGE_END}`,
|
|
27045
|
+
`EGRESS_SHADOWSOCKS_VERSION=${EGRESS_SHADOWSOCKS_VERSION}`,
|
|
27046
|
+
`EGRESS_SHADOWSOCKS_SHA256=${EGRESS_SHADOWSOCKS_SHA256}`,
|
|
27047
|
+
`EGRESS_CIPHER=${EGRESS_CIPHER}`,
|
|
27048
|
+
`EGRESS_KEY_BYTES=${EGRESS_KEY_BYTES}`,
|
|
27049
|
+
`EGRESS_MODE=${EGRESS_SHADOWSOCKS_MODE}`,
|
|
27050
|
+
`EGRESS_DNS_SERVERS="${EGRESS_DNS_SERVERS.join(" ")}"`,
|
|
27051
|
+
`EGRESS_EXIT_IP_ENDPOINTS="${EGRESS_EXIT_IP_ENDPOINTS.join(" ")}"`,
|
|
27052
|
+
`EGRESS_DIRECT_ROUTES="${EGRESS_DIRECT_ROUTES.join(" ")}"`,
|
|
27053
|
+
`EGRESS_NEW_CONN_RATE=${EGRESS_NEW_CONN_RATE}`,
|
|
27054
|
+
`EGRESS_NEW_CONN_BURST=${EGRESS_NEW_CONN_BURST}`,
|
|
27055
|
+
`EGRESS_UDP_RATE=${EGRESS_UDP_RATE}`,
|
|
27056
|
+
`EGRESS_UDP_BURST=${EGRESS_UDP_BURST}`,
|
|
27057
|
+
`EGRESS_OUT_CONN_RATE=${EGRESS_OUT_CONN_RATE}`,
|
|
27058
|
+
`EGRESS_OUT_CONN_BURST=${EGRESS_OUT_CONN_BURST}`
|
|
27059
|
+
].join("\n");
|
|
27060
|
+
var EGRESS_TUNNEL_SERVICE = "replicas-egress.service";
|
|
27061
|
+
var EGRESS_TUNNEL_INTERFACE = "rpxtun0";
|
|
27062
|
+
var EGRESS_PATHS = {
|
|
27063
|
+
/**
|
|
27064
|
+
* Under /run, which is tmpfs. The key therefore never touches disk and cannot
|
|
27065
|
+
* be carried into a filesystem snapshot or a paused sandbox's disk image. It
|
|
27066
|
+
* does not survive a reboot either. A full-memory resume can reuse it only
|
|
27067
|
+
* while the root-owned revision still matches the current profile and the
|
|
27068
|
+
* running service and route are healthy.
|
|
27069
|
+
*/
|
|
27070
|
+
CONFIG_DIR: "/run/replicas-egress",
|
|
27071
|
+
CONFIG_FILE: "/run/replicas-egress/config.json",
|
|
27072
|
+
REVISION_FILE: "/run/replicas-egress/revision",
|
|
27073
|
+
/** Persistent: this records the workspace's original resolver so the tunnel can put it back, and must outlive a reboot. */
|
|
27074
|
+
RESOLV_BACKUP: "/var/lib/replicas-egress-resolv.conf.orig",
|
|
27075
|
+
UNIT_FILE: `/etc/systemd/system/${EGRESS_TUNNEL_SERVICE}`,
|
|
27076
|
+
UP_SCRIPT: "/usr/local/lib/replicas-egress-up",
|
|
27077
|
+
DOWN_SCRIPT: "/usr/local/lib/replicas-egress-down"
|
|
27078
|
+
};
|
|
27079
|
+
var EGRESS_WORKSPACE_CONFIG_FILE = "/opt/replicas/egress-config.env";
|
|
27080
|
+
var EGRESS_WORKSPACE_SHELL_VARS = {
|
|
27081
|
+
EGRESS_WORKSPACE_CONFIG_FILE,
|
|
27082
|
+
EGRESS_TUNNEL_SERVICE,
|
|
27083
|
+
EGRESS_TUNNEL_INTERFACE,
|
|
27084
|
+
EGRESS_DNS_SERVERS: EGRESS_DNS_SERVERS.join(" "),
|
|
27085
|
+
EGRESS_EXIT_IP_ENDPOINTS: EGRESS_EXIT_IP_ENDPOINTS.join(" ")
|
|
27086
|
+
};
|
|
27087
|
+
|
|
27088
|
+
// ../shared/src/replicas-config.ts
|
|
27089
|
+
var import_yaml = __toESM(require_dist());
|
|
27090
|
+
|
|
27091
|
+
// ../shared/src/warm-hooks.ts
|
|
27092
|
+
var DEFAULT_WARM_HOOK_TIMEOUT_MS = 60 * 60 * 1e3;
|
|
27093
|
+
var MAX_WARM_HOOK_TIMEOUT_MS = 120 * 60 * 1e3;
|
|
27094
|
+
var DEFAULT_START_HOOK_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
27095
|
+
var HOOK_EXEC_MAX_BUFFER_BYTES = 10 * 1024 * 1024;
|
|
27096
|
+
|
|
27097
|
+
// ../shared/src/replicas-config.ts
|
|
27098
|
+
var REPLICAS_CONFIG_FILENAMES = ["replicas.json", "replicas.yaml", "replicas.yml"];
|
|
27099
|
+
|
|
27100
|
+
// ../shared/src/headless-agent.ts
|
|
27101
|
+
var headlessAgentRequestBaseSchema = external_exports.object({
|
|
27102
|
+
agent: external_exports.custom(
|
|
27103
|
+
(value) => typeof value === "string" && isValidCodingAgentProvider(value)
|
|
27104
|
+
),
|
|
27105
|
+
model: external_exports.string().min(1),
|
|
27106
|
+
prompt: external_exports.string(),
|
|
27107
|
+
workingDirectory: external_exports.string().min(1),
|
|
27108
|
+
timeoutSeconds: external_exports.number().int().min(1).max(1800).default(300),
|
|
27109
|
+
codexOauthTokens: external_exports.object({ accessToken: external_exports.string(), accountId: external_exports.string() }).optional()
|
|
27110
|
+
});
|
|
27111
|
+
var headlessAgentInputFileSchema = external_exports.object({
|
|
27112
|
+
path: external_exports.string().min(1),
|
|
27113
|
+
downloadUrl: external_exports.url()
|
|
27114
|
+
});
|
|
27115
|
+
var headlessAgentOutputFileSchema = external_exports.object({
|
|
27116
|
+
path: external_exports.string().min(1),
|
|
27117
|
+
uploadUrl: external_exports.url(),
|
|
27118
|
+
contentType: external_exports.string().min(1),
|
|
27119
|
+
minChars: external_exports.number().int().positive().optional(),
|
|
27120
|
+
maxChars: external_exports.number().int().positive().optional()
|
|
27121
|
+
});
|
|
27122
|
+
var headlessAgentRequestSchema = external_exports.discriminatedUnion("mode", [
|
|
27123
|
+
headlessAgentRequestBaseSchema.extend({
|
|
27124
|
+
mode: external_exports.literal("structured"),
|
|
27125
|
+
outputSchema: external_exports.record(external_exports.string(), external_exports.json())
|
|
27126
|
+
}),
|
|
27127
|
+
headlessAgentRequestBaseSchema.extend({
|
|
27128
|
+
mode: external_exports.literal("filesystem"),
|
|
27129
|
+
inputFiles: external_exports.array(headlessAgentInputFileSchema),
|
|
27130
|
+
outputFiles: external_exports.array(headlessAgentOutputFileSchema),
|
|
27131
|
+
sensitiveValues: external_exports.array(external_exports.string())
|
|
27132
|
+
})
|
|
27133
|
+
]);
|
|
27134
|
+
var headlessFilesystemAgentResultSchema = external_exports.object({
|
|
27135
|
+
message: external_exports.string(),
|
|
27136
|
+
files: external_exports.record(external_exports.string(), external_exports.object({
|
|
27137
|
+
sha256: external_exports.string().regex(/^[a-f0-9]{64}$/),
|
|
27138
|
+
sizeBytes: external_exports.number().int().nonnegative()
|
|
27139
|
+
}))
|
|
27140
|
+
});
|
|
27141
|
+
|
|
27142
|
+
// ../shared/src/cli-version.ts
|
|
27143
|
+
var CLI_VERSION = "0.2.604";
|
|
27144
|
+
|
|
27145
|
+
// ../shared/src/version.ts
|
|
27146
|
+
function compareVersions(v1, v2) {
|
|
27147
|
+
const parts1 = v1.split(".").map(Number);
|
|
27148
|
+
const parts2 = v2.split(".").map(Number);
|
|
27149
|
+
for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {
|
|
27150
|
+
const num1 = parts1[i] || 0;
|
|
27151
|
+
const num2 = parts2[i] || 0;
|
|
27152
|
+
if (num1 > num2) return 1;
|
|
27153
|
+
if (num1 < num2) return -1;
|
|
27343
27154
|
}
|
|
27155
|
+
return 0;
|
|
27344
27156
|
}
|
|
27345
|
-
|
|
27346
|
-
|
|
27347
|
-
|
|
27348
|
-
|
|
27349
|
-
|
|
27350
|
-
|
|
27351
|
-
|
|
27352
|
-
|
|
27353
|
-
|
|
27354
|
-
|
|
27355
|
-
|
|
27356
|
-
|
|
27357
|
-
|
|
27358
|
-
|
|
27359
|
-
|
|
27360
|
-
|
|
27361
|
-
|
|
27362
|
-
|
|
27363
|
-
|
|
27364
|
-
|
|
27365
|
-
}
|
|
27366
|
-
|
|
27367
|
-
|
|
27368
|
-
|
|
27369
|
-
|
|
27370
|
-
|
|
27371
|
-
|
|
27372
|
-
|
|
27157
|
+
|
|
27158
|
+
// ../shared/src/routes/plugin-catalog.ts
|
|
27159
|
+
var EXPLICIT_PLUGIN_CATALOG = [
|
|
27160
|
+
{
|
|
27161
|
+
id: "attio",
|
|
27162
|
+
backend: "composio",
|
|
27163
|
+
toolkit: "attio",
|
|
27164
|
+
authType: "oauth",
|
|
27165
|
+
category: "business",
|
|
27166
|
+
name: "Attio",
|
|
27167
|
+
description: "Manage CRM records, people, companies, lists, and notes."
|
|
27168
|
+
},
|
|
27169
|
+
{
|
|
27170
|
+
id: "calendly",
|
|
27171
|
+
backend: "composio",
|
|
27172
|
+
toolkit: "calendly",
|
|
27173
|
+
authType: "oauth",
|
|
27174
|
+
category: "productivity",
|
|
27175
|
+
name: "Calendly",
|
|
27176
|
+
description: "Manage event types, scheduled events, invitees, and scheduling links."
|
|
27177
|
+
},
|
|
27178
|
+
{
|
|
27179
|
+
id: "clickhouse",
|
|
27180
|
+
backend: "composio",
|
|
27181
|
+
toolkit: "clickhouse",
|
|
27182
|
+
authType: "basic",
|
|
27183
|
+
category: "data",
|
|
27184
|
+
name: "ClickHouse",
|
|
27185
|
+
description: "Manage databases, tables, schemas, and queries."
|
|
27186
|
+
},
|
|
27187
|
+
{
|
|
27188
|
+
id: "cloudflare",
|
|
27189
|
+
backend: "composio",
|
|
27190
|
+
toolkit: "cloudflare_api_key",
|
|
27191
|
+
authType: "api_key",
|
|
27192
|
+
category: "data",
|
|
27193
|
+
name: "Cloudflare",
|
|
27194
|
+
description: "Manage zones, DNS records, analytics, and security settings."
|
|
27195
|
+
},
|
|
27196
|
+
{
|
|
27197
|
+
id: "e2b",
|
|
27198
|
+
toolkit: "e2b",
|
|
27199
|
+
backend: "native",
|
|
27200
|
+
authType: "api_key",
|
|
27201
|
+
category: "data",
|
|
27202
|
+
name: "E2B",
|
|
27203
|
+
description: "Create secure cloud sandboxes and run commands in them."
|
|
27204
|
+
},
|
|
27205
|
+
{
|
|
27206
|
+
id: "gmail",
|
|
27207
|
+
backend: "composio",
|
|
27208
|
+
toolkit: "gmail",
|
|
27209
|
+
authType: "oauth",
|
|
27210
|
+
category: "productivity",
|
|
27211
|
+
name: "Gmail",
|
|
27212
|
+
description: "Manage messages, threads, attachments, labels, and mailbox settings."
|
|
27213
|
+
},
|
|
27214
|
+
{
|
|
27215
|
+
id: "googleads",
|
|
27216
|
+
backend: "composio",
|
|
27217
|
+
toolkit: "googleads",
|
|
27218
|
+
authType: "oauth",
|
|
27219
|
+
category: "data",
|
|
27220
|
+
name: "Google Ads",
|
|
27221
|
+
description: "Manage campaigns, customers, accounts, and reporting data."
|
|
27222
|
+
},
|
|
27223
|
+
{
|
|
27224
|
+
id: "googledocs",
|
|
27225
|
+
backend: "composio",
|
|
27226
|
+
toolkit: "googledocs",
|
|
27227
|
+
authType: "oauth",
|
|
27228
|
+
category: "productivity",
|
|
27229
|
+
name: "Google Docs",
|
|
27230
|
+
description: "Manage documents, structure, comments, and exported content."
|
|
27231
|
+
},
|
|
27232
|
+
{
|
|
27233
|
+
id: "googledrive",
|
|
27234
|
+
backend: "composio",
|
|
27235
|
+
toolkit: "googledrive",
|
|
27236
|
+
authType: "oauth",
|
|
27237
|
+
category: "productivity",
|
|
27238
|
+
name: "Google Drive",
|
|
27239
|
+
description: "Manage files, folders, metadata, permissions, and shared drives."
|
|
27240
|
+
},
|
|
27241
|
+
{
|
|
27242
|
+
id: "googlesearch",
|
|
27243
|
+
backend: "composio",
|
|
27244
|
+
toolkit: "google_search_console",
|
|
27245
|
+
authType: "oauth",
|
|
27246
|
+
category: "data",
|
|
27247
|
+
name: "Google Search",
|
|
27248
|
+
description: "Manage Search Console performance, indexing, sites, and sitemaps."
|
|
27249
|
+
},
|
|
27250
|
+
{
|
|
27251
|
+
id: "googlesheets",
|
|
27252
|
+
backend: "composio",
|
|
27253
|
+
toolkit: "googlesheets",
|
|
27254
|
+
authType: "oauth",
|
|
27255
|
+
category: "productivity",
|
|
27256
|
+
name: "Google Sheets",
|
|
27257
|
+
description: "Manage spreadsheets, worksheets, ranges, tables, and charts."
|
|
27258
|
+
},
|
|
27259
|
+
{
|
|
27260
|
+
id: "linkedin",
|
|
27261
|
+
backend: "composio",
|
|
27262
|
+
toolkit: "linkedin",
|
|
27263
|
+
authType: "oauth",
|
|
27264
|
+
category: "business",
|
|
27265
|
+
name: "LinkedIn",
|
|
27266
|
+
description: "Manage profiles, organizations, posts, and professional activity."
|
|
27267
|
+
},
|
|
27268
|
+
{
|
|
27269
|
+
id: "modal",
|
|
27270
|
+
backend: "native",
|
|
27271
|
+
toolkit: "modal",
|
|
27272
|
+
authType: "basic",
|
|
27273
|
+
category: "data",
|
|
27274
|
+
name: "Modal",
|
|
27275
|
+
description: "Invoke deployed functions through Modal compute."
|
|
27276
|
+
},
|
|
27277
|
+
{
|
|
27278
|
+
id: "posthog",
|
|
27279
|
+
backend: "composio",
|
|
27280
|
+
toolkit: "posthog",
|
|
27281
|
+
authType: "api_key",
|
|
27282
|
+
category: "data",
|
|
27283
|
+
name: "PostHog",
|
|
27284
|
+
description: "Manage projects, events, insights, dashboards, flags, and recordings."
|
|
27285
|
+
},
|
|
27286
|
+
{
|
|
27287
|
+
id: "planetscale",
|
|
27288
|
+
toolkit: "planetscale",
|
|
27289
|
+
backend: "native",
|
|
27290
|
+
authType: "oauth",
|
|
27291
|
+
category: "data",
|
|
27292
|
+
name: "PlanetScale",
|
|
27293
|
+
description: "Manage organizations, databases, branches, deploy requests, and Insights."
|
|
27294
|
+
},
|
|
27295
|
+
{
|
|
27296
|
+
id: "stripe",
|
|
27297
|
+
backend: "composio",
|
|
27298
|
+
toolkit: "stripe",
|
|
27299
|
+
authType: "oauth",
|
|
27300
|
+
category: "business",
|
|
27301
|
+
name: "Stripe",
|
|
27302
|
+
description: "Manage customers, payments, invoices, subscriptions, and balances."
|
|
27303
|
+
},
|
|
27304
|
+
{
|
|
27305
|
+
id: "pangram",
|
|
27306
|
+
backend: "native",
|
|
27307
|
+
toolkit: "pangram",
|
|
27308
|
+
authType: "api_key",
|
|
27309
|
+
category: "data",
|
|
27310
|
+
name: "Pangram",
|
|
27311
|
+
description: "Analyze text for AI generation and plagiarism signals."
|
|
27312
|
+
},
|
|
27313
|
+
{
|
|
27314
|
+
id: "vercel",
|
|
27315
|
+
backend: "native",
|
|
27316
|
+
toolkit: "vercel",
|
|
27317
|
+
authType: "api_key",
|
|
27318
|
+
category: "data",
|
|
27319
|
+
name: "Vercel",
|
|
27320
|
+
description: "Manage projects, deployments, logs, domains, and infrastructure."
|
|
27321
|
+
},
|
|
27322
|
+
{
|
|
27323
|
+
id: "turbopuffer",
|
|
27324
|
+
backend: "native",
|
|
27325
|
+
toolkit: "turbopuffer",
|
|
27326
|
+
authType: "api_key",
|
|
27327
|
+
category: "data",
|
|
27328
|
+
name: "turbopuffer",
|
|
27329
|
+
description: "Query and manage turbopuffer namespaces."
|
|
27330
|
+
},
|
|
27331
|
+
{
|
|
27332
|
+
id: "vanta",
|
|
27333
|
+
backend: "native",
|
|
27334
|
+
toolkit: "vanta",
|
|
27335
|
+
authType: "credentials",
|
|
27336
|
+
category: "data",
|
|
27337
|
+
name: "Vanta",
|
|
27338
|
+
description: "Review and manage controls, tests, evidence, vendors, risks, and compliance data.",
|
|
27339
|
+
scopes: ["environment"]
|
|
27373
27340
|
}
|
|
27374
|
-
|
|
27375
|
-
|
|
27376
|
-
|
|
27377
|
-
|
|
27378
|
-
|
|
27379
|
-
|
|
27380
|
-
|
|
27341
|
+
];
|
|
27342
|
+
var HOSTED_COMPOSIO_PLUGIN_DEFINITIONS = [
|
|
27343
|
+
["notion", "notion", "OAUTH2", true, "productivity", "Notion"],
|
|
27344
|
+
["jira", "jira", "OAUTH2", true, "productivity", "Jira"],
|
|
27345
|
+
["confluence", "confluence", "OAUTH2", true, "productivity", "Confluence"],
|
|
27346
|
+
["googlecalendar", "googlecalendar", "OAUTH2", true, "productivity", "Google Calendar"],
|
|
27347
|
+
["microsoftteams", "microsoft_teams", "OAUTH2", true, "productivity", "Microsoft Teams"],
|
|
27348
|
+
["outlook", "outlook", "OAUTH2", true, "productivity", "Outlook"],
|
|
27349
|
+
["bitbucket", "bitbucket", "OAUTH2", true, "data", "Bitbucket"],
|
|
27350
|
+
["datadog", "datadog", "API_KEY", false, "data", "Datadog"],
|
|
27351
|
+
["pagerduty", "pagerduty", "OAUTH2", true, "data", "PagerDuty"],
|
|
27352
|
+
["intercom", "intercom", "OAUTH2", true, "business", "Intercom"],
|
|
27353
|
+
["zendesk", "zendesk", "OAUTH2", true, "business", "Zendesk"],
|
|
27354
|
+
["hubspot", "hubspot", "OAUTH2", true, "business", "HubSpot"],
|
|
27355
|
+
["supabase", "supabase", "OAUTH2", true, "data", "Supabase"],
|
|
27356
|
+
["figma", "figma", "OAUTH2", true, "productivity", "Figma"],
|
|
27357
|
+
["launchdarkly", "launch_darkly", "API_KEY", false, "data", "LaunchDarkly"],
|
|
27358
|
+
["asana", "asana", "OAUTH2", true, "productivity", "Asana"],
|
|
27359
|
+
["clickup", "clickup", "OAUTH2", true, "productivity", "ClickUp"],
|
|
27360
|
+
["trello", "trello", "OAUTH1", true, "productivity", "Trello"],
|
|
27361
|
+
["todoist", "todoist", "OAUTH2", true, "productivity", "Todoist"],
|
|
27362
|
+
["airtable", "airtable", "OAUTH2", true, "productivity", "Airtable"],
|
|
27363
|
+
["coda", "coda", "API_KEY", false, "productivity", "Coda"],
|
|
27364
|
+
["miro", "miro", "OAUTH2", true, "productivity", "Miro"],
|
|
27365
|
+
["sharepoint", "share_point", "OAUTH2", true, "productivity", "SharePoint"],
|
|
27366
|
+
["onedrive", "one_drive", "OAUTH2", true, "productivity", "OneDrive"],
|
|
27367
|
+
["googleslides", "googleslides", "OAUTH2", true, "productivity", "Google Slides"],
|
|
27368
|
+
["googlemeet", "googlemeet", "OAUTH2", true, "productivity", "Google Meet"],
|
|
27369
|
+
["googletasks", "googletasks", "OAUTH2", true, "productivity", "Google Tasks"],
|
|
27370
|
+
["dropbox", "dropbox", "OAUTH2", true, "productivity", "Dropbox"],
|
|
27371
|
+
["box", "box", "OAUTH2", true, "productivity", "Box"],
|
|
27372
|
+
["discord", "discord", "OAUTH2", true, "productivity", "Discord"],
|
|
27373
|
+
["discordbot", "discordbot", "OAUTH2", true, "productivity", "Discord Bot"],
|
|
27374
|
+
["zoom", "zoom", "OAUTH2", true, "productivity", "Zoom"],
|
|
27375
|
+
["googlechat", "google_chat", "OAUTH2", false, "productivity", "Google Chat"],
|
|
27376
|
+
["newrelic", "new_relic", "API_KEY", false, "data", "New Relic"],
|
|
27377
|
+
["betterstack", "better_stack", "API_KEY", false, "data", "Better Stack"],
|
|
27378
|
+
["incidentio", "incident_io", "API_KEY", false, "data", "incident.io"],
|
|
27379
|
+
["grafana", "grafana", "BEARER_TOKEN", false, "data", "Grafana"],
|
|
27380
|
+
["honeycomb", "honeycomb_mcp", "DCR_OAUTH", false, "data", "Honeycomb MCP"],
|
|
27381
|
+
["bugsnag", "bugsnag", "API_KEY", false, "data", "Bugsnag"],
|
|
27382
|
+
["circleci", "circleci", "API_KEY", false, "data", "CircleCI"],
|
|
27383
|
+
["buildkite", "buildkite", "API_KEY", false, "data", "Buildkite"],
|
|
27384
|
+
["dockerhub", "docker_hub", "API_KEY", false, "data", "Docker Hub"],
|
|
27385
|
+
["digitalocean", "digital_ocean", "OAUTH2", true, "data", "DigitalOcean"],
|
|
27386
|
+
["railway", "railway", "API_KEY", false, "data", "Railway"],
|
|
27387
|
+
["render", "render", "API_KEY", false, "data", "Render"],
|
|
27388
|
+
["firebase", "firebase", "API_KEY", false, "data", "Firebase"],
|
|
27389
|
+
["cloudinary", "cloudinary", "API_KEY", false, "data", "Cloudinary"],
|
|
27390
|
+
["configcat", "configcat", "API_KEY", false, "data", "ConfigCat"],
|
|
27391
|
+
["contextdev", "context_dev", "API_KEY", false, "data", "Context.dev"],
|
|
27392
|
+
["googleanalytics", "google_analytics", "OAUTH2", true, "data", "Google Analytics"],
|
|
27393
|
+
["googlebigquery", "googlebigquery", "OAUTH2", true, "data", "Google BigQuery"],
|
|
27394
|
+
["amplitude", "amplitude", "API_KEY", false, "data", "Amplitude"],
|
|
27395
|
+
["mixpanel", "mixpanel", "BASIC", false, "data", "Mixpanel"],
|
|
27396
|
+
["segment", "segment", "API_KEY", false, "data", "Segment"],
|
|
27397
|
+
["databricks", "databricks", "API_KEY", false, "data", "Databricks"],
|
|
27398
|
+
["snowflake", "snowflake", "OAUTH2", false, "data", "Snowflake"],
|
|
27399
|
+
["algolia", "algolia", "API_KEY", false, "data", "Algolia"],
|
|
27400
|
+
["elasticsearch", "elasticsearch", "API_KEY", false, "data", "Elasticsearch"],
|
|
27401
|
+
["salesforce", "salesforce", "OAUTH2", true, "business", "Salesforce"],
|
|
27402
|
+
["pipedrive", "pipedrive", "API_KEY", false, "business", "Pipedrive"],
|
|
27403
|
+
["close", "close", "API_KEY", false, "business", "Close"],
|
|
27404
|
+
["apollo", "apollo", "API_KEY", false, "business", "Apollo"],
|
|
27405
|
+
["gong", "gong", "OAUTH2", true, "business", "Gong"],
|
|
27406
|
+
["freshdesk", "freshdesk", "API_KEY", false, "business", "Freshdesk"],
|
|
27407
|
+
["helpscout", "help_scout", "OAUTH2", false, "business", "Help Scout"],
|
|
27408
|
+
["servicenow", "servicenow", "BASIC", false, "business", "ServiceNow"],
|
|
27409
|
+
["mailchimp", "mailchimp", "OAUTH2", true, "business", "Mailchimp"],
|
|
27410
|
+
["customerio", "customerio", "API_KEY", false, "business", "Customer.io"],
|
|
27411
|
+
["klaviyo", "klaviyo", "API_KEY", false, "business", "Klaviyo"],
|
|
27412
|
+
["shopify", "shopify", "API_KEY", false, "business", "Shopify"],
|
|
27413
|
+
["quickbooks", "quickbooks", "OAUTH2", true, "business", "QuickBooks"],
|
|
27414
|
+
["xero", "xero", "OAUTH2", false, "business", "Xero"],
|
|
27415
|
+
["brex", "brex", "API_KEY", false, "business", "Brex"],
|
|
27416
|
+
["buffer", "buffer", "OAUTH2", false, "business", "Buffer"],
|
|
27417
|
+
["canva", "canva", "OAUTH2", true, "productivity", "Canva"],
|
|
27418
|
+
["webflow", "webflow", "API_KEY", false, "business", "Webflow"],
|
|
27419
|
+
["firecrawl", "firecrawl", "API_KEY", false, "data", "Firecrawl"],
|
|
27420
|
+
["browserbase", "browserbase_tool", "API_KEY", false, "data", "Browserbase"],
|
|
27421
|
+
["exa", "exa", "API_KEY", false, "data", "Exa"],
|
|
27422
|
+
["youtube", "youtube", "OAUTH2", true, "business", "YouTube"],
|
|
27423
|
+
["twitter", "twitter", "OAUTH2", false, "business", "Twitter/X"],
|
|
27424
|
+
["instagram", "instagram", "OAUTH2", true, "business", "Instagram"],
|
|
27425
|
+
["facebook", "facebook", "OAUTH2", true, "business", "Facebook"]
|
|
27426
|
+
];
|
|
27427
|
+
var HOSTED_COMPOSIO_PLUGINS = HOSTED_COMPOSIO_PLUGIN_DEFINITIONS.map(
|
|
27428
|
+
([id, toolkit, authScheme, managedAuth, category, name]) => ({
|
|
27429
|
+
id,
|
|
27430
|
+
backend: "composio",
|
|
27431
|
+
toolkit,
|
|
27432
|
+
authType: "hosted",
|
|
27433
|
+
authScheme,
|
|
27434
|
+
managedAuth,
|
|
27435
|
+
category,
|
|
27436
|
+
name,
|
|
27437
|
+
description: `Use ${name} tools from workspace agents.`
|
|
27438
|
+
})
|
|
27439
|
+
);
|
|
27440
|
+
var PLUGIN_CATALOG = [
|
|
27441
|
+
...EXPLICIT_PLUGIN_CATALOG,
|
|
27442
|
+
...HOSTED_COMPOSIO_PLUGINS
|
|
27443
|
+
];
|
|
27444
|
+
|
|
27445
|
+
// ../shared/src/routes/user.ts
|
|
27446
|
+
var PROFILE_AVATAR_MAX_SIZE_BYTES = 5 * 1024 * 1024;
|
|
27447
|
+
|
|
27448
|
+
// ../shared/src/routes/client-state.ts
|
|
27449
|
+
var MAX_CLIENT_STATE_REQUEST_BYTES = 5 * 1024 * 1024;
|
|
27450
|
+
var MAX_CLIENT_STATE_BYTES_PER_USER = 10 * 1024 * 1024;
|
|
27451
|
+
|
|
27452
|
+
// ../shared/src/routes/workspaces.ts
|
|
27453
|
+
var WORKSPACE_STATUSES = ["active", "sleeping", "archived", "preparing", "error"];
|
|
27454
|
+
function isWorkspaceSuspendedStatus(status) {
|
|
27455
|
+
return status === "sleeping" || status === "archived";
|
|
27381
27456
|
}
|
|
27382
|
-
function
|
|
27383
|
-
const
|
|
27384
|
-
|
|
27385
|
-
|
|
27386
|
-
const indexesByDuplicateBucket = /* @__PURE__ */ new Map();
|
|
27387
|
-
const indexMessage = (message, index) => {
|
|
27388
|
-
if (!firstIndexById.has(message.id)) firstIndexById.set(message.id, index);
|
|
27389
|
-
const key = duplicateBucketKey(message);
|
|
27390
|
-
if (key === null) return;
|
|
27391
|
-
const indexes = indexesByDuplicateBucket.get(key) ?? /* @__PURE__ */ new Set();
|
|
27392
|
-
indexes.add(index);
|
|
27393
|
-
indexesByDuplicateBucket.set(key, indexes);
|
|
27394
|
-
};
|
|
27395
|
-
const unindexMessage = (message, index) => {
|
|
27396
|
-
const key = duplicateBucketKey(message);
|
|
27397
|
-
if (key === null) return;
|
|
27398
|
-
const indexes = indexesByDuplicateBucket.get(key);
|
|
27399
|
-
indexes?.delete(index);
|
|
27400
|
-
if (indexes?.size === 0) indexesByDuplicateBucket.delete(key);
|
|
27457
|
+
function workspaceConfigWithCapabilities(config3, capabilities = {}) {
|
|
27458
|
+
const mergedCapabilities = {
|
|
27459
|
+
...config3?.capabilities,
|
|
27460
|
+
...capabilities
|
|
27401
27461
|
};
|
|
27402
|
-
|
|
27403
|
-
|
|
27404
|
-
|
|
27405
|
-
|
|
27406
|
-
|
|
27407
|
-
const key = duplicateBucketKey(message, bucketOffset);
|
|
27408
|
-
for (const index of (key === null ? void 0 : indexesByDuplicateBucket.get(key)) ?? []) {
|
|
27409
|
-
if (nearTimestamp(merged[index].timestamp, message.timestamp) && (duplicateIndex === void 0 || index < duplicateIndex)) {
|
|
27410
|
-
duplicateIndex = index;
|
|
27411
|
-
}
|
|
27412
|
-
}
|
|
27413
|
-
}
|
|
27414
|
-
}
|
|
27415
|
-
if (duplicateIndex === void 0) {
|
|
27416
|
-
indexMessage(message, merged.push(message) - 1);
|
|
27417
|
-
} else if (message.type === "user") {
|
|
27418
|
-
unindexMessage(merged[duplicateIndex], duplicateIndex);
|
|
27419
|
-
merged[duplicateIndex] = {
|
|
27420
|
-
...merged[duplicateIndex],
|
|
27421
|
-
id: message.id
|
|
27422
|
-
};
|
|
27423
|
-
firstIndexById.set(message.id, duplicateIndex);
|
|
27424
|
-
indexMessage(merged[duplicateIndex], duplicateIndex);
|
|
27462
|
+
return {
|
|
27463
|
+
...config3,
|
|
27464
|
+
capabilities: {
|
|
27465
|
+
...mergedCapabilities,
|
|
27466
|
+
pr_followups: mergedCapabilities.pr_followups === true
|
|
27425
27467
|
}
|
|
27426
|
-
}
|
|
27427
|
-
const ordered = merged.slice(0, primaryCount);
|
|
27428
|
-
const supplementalOnly = merged.slice(primaryCount).map((message, index) => ({ message, index })).sort((a, b) => parseTimestampMs(a.message.timestamp) - parseTimestampMs(b.message.timestamp) || a.index - b.index);
|
|
27429
|
-
for (const { message } of supplementalOnly) {
|
|
27430
|
-
insertDisplayMessageByTimestamp(ordered, message);
|
|
27431
|
-
}
|
|
27432
|
-
return ordered;
|
|
27468
|
+
};
|
|
27433
27469
|
}
|
|
27434
|
-
function
|
|
27435
|
-
|
|
27436
|
-
|
|
27437
|
-
|
|
27438
|
-
|
|
27439
|
-
|
|
27440
|
-
|
|
27441
|
-
|
|
27442
|
-
|
|
27443
|
-
|
|
27444
|
-
|
|
27445
|
-
|
|
27446
|
-
|
|
27447
|
-
|
|
27448
|
-
|
|
27449
|
-
|
|
27450
|
-
|
|
27451
|
-
|
|
27452
|
-
|
|
27453
|
-
|
|
27454
|
-
|
|
27455
|
-
|
|
27456
|
-
|
|
27457
|
-
|
|
27458
|
-
|
|
27459
|
-
|
|
27460
|
-
|
|
27461
|
-
|
|
27462
|
-
|
|
27463
|
-
|
|
27464
|
-
|
|
27465
|
-
|
|
27466
|
-
|
|
27467
|
-
|
|
27468
|
-
|
|
27469
|
-
|
|
27470
|
-
|
|
27471
|
-
|
|
27472
|
-
|
|
27473
|
-
|
|
27474
|
-
|
|
27475
|
-
|
|
27476
|
-
|
|
27477
|
-
|
|
27478
|
-
}
|
|
27479
|
-
|
|
27480
|
-
|
|
27481
|
-
|
|
27482
|
-
|
|
27483
|
-
|
|
27484
|
-
|
|
27485
|
-
|
|
27486
|
-
|
|
27470
|
+
function workspaceConfigWithPrFollowups(config3, prFollowups = config3?.capabilities?.pr_followups === true) {
|
|
27471
|
+
return workspaceConfigWithCapabilities(config3, { pr_followups: prFollowups });
|
|
27472
|
+
}
|
|
27473
|
+
var WORKSPACE_STATUS_FILTERS = WORKSPACE_STATUSES.map((status) => status === "error" ? "failed" : status);
|
|
27474
|
+
var WORKSPACE_SORT_CHOICES = [
|
|
27475
|
+
["manual", "Custom"],
|
|
27476
|
+
["activity", "Last activity"],
|
|
27477
|
+
["created", "Created date"]
|
|
27478
|
+
];
|
|
27479
|
+
var WORKSPACE_SORT_OPTIONS = WORKSPACE_SORT_CHOICES.map(([option]) => option);
|
|
27480
|
+
var WORKSPACE_SORT_LABELS = Object.fromEntries(WORKSPACE_SORT_CHOICES);
|
|
27481
|
+
var WORKSPACE_SIDEBAR_ORGANIZATION_CHOICES = [
|
|
27482
|
+
["chronological", "Chronological"],
|
|
27483
|
+
["environments", "Environments"],
|
|
27484
|
+
["recent", "Recent environments"]
|
|
27485
|
+
];
|
|
27486
|
+
var WORKSPACE_SIDEBAR_ORGANIZATIONS = WORKSPACE_SIDEBAR_ORGANIZATION_CHOICES.map(([organization]) => organization);
|
|
27487
|
+
var WORKSPACE_SIDEBAR_ORGANIZATION_LABELS = Object.fromEntries(WORKSPACE_SIDEBAR_ORGANIZATION_CHOICES);
|
|
27488
|
+
var DEFAULT_STATUS_FILTERS = [...WORKSPACE_STATUS_FILTERS];
|
|
27489
|
+
var DEFAULT_WORKSPACE_FILTERS = {
|
|
27490
|
+
statuses: [...DEFAULT_STATUS_FILTERS],
|
|
27491
|
+
ownerIds: [],
|
|
27492
|
+
activity: "any"
|
|
27493
|
+
};
|
|
27494
|
+
var ONE_DAY_MS = 24 * 60 * 60 * 1e3;
|
|
27495
|
+
|
|
27496
|
+
// ../shared/src/routes/workspace-events.ts
|
|
27497
|
+
var workspaceChangedEventSchema = external_exports.discriminatedUnion("type", [
|
|
27498
|
+
external_exports.object({
|
|
27499
|
+
type: external_exports.literal("workspace.changed"),
|
|
27500
|
+
workspaceId: external_exports.string(),
|
|
27501
|
+
completion: external_exports.object({
|
|
27502
|
+
workspaceName: external_exports.string(),
|
|
27503
|
+
completedAt: external_exports.string(),
|
|
27504
|
+
processing: external_exports.boolean().optional()
|
|
27505
|
+
}).optional(),
|
|
27506
|
+
ts: external_exports.string()
|
|
27507
|
+
}),
|
|
27508
|
+
external_exports.object({
|
|
27509
|
+
type: external_exports.literal("workspace.chat.changed"),
|
|
27510
|
+
workspaceId: external_exports.string(),
|
|
27511
|
+
chatId: external_exports.string(),
|
|
27512
|
+
ts: external_exports.string()
|
|
27513
|
+
}),
|
|
27514
|
+
external_exports.object({ type: external_exports.literal("presence.changed"), ts: external_exports.string() }),
|
|
27515
|
+
external_exports.object({
|
|
27516
|
+
type: external_exports.literal("mobile-testing.changed"),
|
|
27517
|
+
workspaceId: external_exports.string(),
|
|
27518
|
+
ts: external_exports.string()
|
|
27519
|
+
})
|
|
27520
|
+
]);
|
|
27521
|
+
|
|
27522
|
+
// ../shared/src/routes/presence.ts
|
|
27523
|
+
var presenceStatusSchema = external_exports.enum(["online", "typing"]);
|
|
27524
|
+
var presenceLocationSchema = external_exports.object({
|
|
27525
|
+
environmentId: external_exports.string().optional(),
|
|
27526
|
+
workspaceId: external_exports.string().optional()
|
|
27527
|
+
});
|
|
27528
|
+
var presenceEntrySchema = external_exports.object({
|
|
27529
|
+
userId: external_exports.string(),
|
|
27530
|
+
status: presenceStatusSchema,
|
|
27531
|
+
location: presenceLocationSchema,
|
|
27532
|
+
ts: external_exports.string()
|
|
27533
|
+
});
|
|
27534
|
+
var updatePresenceRequestSchema = external_exports.object({
|
|
27535
|
+
status: presenceStatusSchema,
|
|
27536
|
+
location: presenceLocationSchema.optional()
|
|
27537
|
+
});
|
|
27538
|
+
|
|
27539
|
+
// ../shared/src/audit-log.ts
|
|
27540
|
+
var AUDIT_LOG_ACTION = {
|
|
27541
|
+
CREATE: "create",
|
|
27542
|
+
UPDATE: "update",
|
|
27543
|
+
DELETE: "delete",
|
|
27544
|
+
CONNECT: "connect",
|
|
27545
|
+
DISCONNECT: "disconnect"
|
|
27546
|
+
};
|
|
27547
|
+
var AUDIT_LOG_ACTIONS = Object.values(AUDIT_LOG_ACTION);
|
|
27548
|
+
|
|
27549
|
+
// ../shared/src/automations/types.ts
|
|
27550
|
+
var AUTOMATION_DEBOUNCE_MAX_SECONDS = 24 * 60 * 60;
|
|
27551
|
+
var AUTOMATION_LIFECYCLE_POLICIES = ["default", "archive_when_done", "sleep_when_done"];
|
|
27552
|
+
function toAutomationLifecyclePolicy(policy) {
|
|
27553
|
+
if (!policy) return "default";
|
|
27554
|
+
if (policy === "default" || policy === "archive_when_done" || policy === "sleep_when_done") return policy;
|
|
27555
|
+
return "archive_when_done";
|
|
27556
|
+
}
|
|
27557
|
+
function lifecyclePolicySupportsAutoStop(policy) {
|
|
27558
|
+
return policy === "default";
|
|
27487
27559
|
}
|
|
27488
27560
|
|
|
27489
|
-
// ../shared/src/
|
|
27490
|
-
var
|
|
27491
|
-
function
|
|
27492
|
-
|
|
27493
|
-
return parseCodexEvents(events);
|
|
27494
|
-
}
|
|
27495
|
-
if (agentType === "cursor") {
|
|
27496
|
-
return parseCursorEvents(events);
|
|
27497
|
-
}
|
|
27498
|
-
if (agentType === "deepseek") {
|
|
27499
|
-
return parseDeepseekEvents(events);
|
|
27500
|
-
}
|
|
27501
|
-
if (agentType === "fx") {
|
|
27502
|
-
return parseFxEvents(events);
|
|
27503
|
-
}
|
|
27504
|
-
if (agentType === "kimi") {
|
|
27505
|
-
return parseAcpEvents(events, "kimi");
|
|
27506
|
-
}
|
|
27507
|
-
if (agentType === "muse") {
|
|
27508
|
-
return parseMuseEvents(events);
|
|
27509
|
-
}
|
|
27510
|
-
if (agentType === "opencode") {
|
|
27511
|
-
return parseOpencodeEvents(events);
|
|
27512
|
-
}
|
|
27513
|
-
if (agentType === "pi") {
|
|
27514
|
-
return parsePiEvents(events);
|
|
27515
|
-
}
|
|
27516
|
-
return parseClaudeEvents(events);
|
|
27561
|
+
// ../shared/src/automations/github-checks.ts
|
|
27562
|
+
var AUTOMATION_CHECK_CONCLUSIONS = ["success", "failure"];
|
|
27563
|
+
function isAutomationCheckConclusion(value) {
|
|
27564
|
+
return AUTOMATION_CHECK_CONCLUSIONS.some((conclusion) => conclusion === value);
|
|
27517
27565
|
}
|
|
27518
|
-
function
|
|
27519
|
-
|
|
27520
|
-
const parsedEvents = agentType === "claude" || agentType === "relay" ? parseClaudeEvents(events, options.parentToolUseId) : parseAgentEvents(events, agentType);
|
|
27521
|
-
const reconciledEvents = [];
|
|
27522
|
-
for (const message of parsedEvents) {
|
|
27523
|
-
if (message.type === "user") upsertDisplayMessage(reconciledEvents, message);
|
|
27524
|
-
else reconciledEvents.push(message);
|
|
27525
|
-
}
|
|
27526
|
-
const legacyMessages = shouldFilter ? filterDisplayMessages(reconciledEvents, agentType) : reconciledEvents;
|
|
27527
|
-
const applySyntheticNotices = (messages) => shouldFilter ? applyAuthFallbackNotices(applyInterruptions(messages, events), events) : messages;
|
|
27528
|
-
if (agentType !== "codex" || !codexAspTranscript) {
|
|
27529
|
-
return applySyntheticNotices(legacyMessages);
|
|
27530
|
-
}
|
|
27531
|
-
const nativeCodexMessages = shouldFilter ? filterDisplayMessages(parseCodexAspTranscript(codexAspTranscript), agentType) : parseCodexAspTranscript(codexAspTranscript);
|
|
27532
|
-
return applySyntheticNotices(mergeCodexAspDisplayMessages(nativeCodexMessages, legacyMessages));
|
|
27566
|
+
function normalizeAutomationGithubCheckNames(names) {
|
|
27567
|
+
return names.map((name) => name.trim()).filter(Boolean);
|
|
27533
27568
|
}
|
|
27534
|
-
|
|
27535
|
-
|
|
27536
|
-
|
|
27537
|
-
|
|
27538
|
-
|
|
27539
|
-
|
|
27540
|
-
|
|
27541
|
-
|
|
27542
|
-
});
|
|
27569
|
+
|
|
27570
|
+
// ../shared/src/automations/agent-validation.ts
|
|
27571
|
+
function validateAgentSelection(body, existing, modelCatalogs = {}) {
|
|
27572
|
+
const agentProvider = body.agent_provider;
|
|
27573
|
+
if (agentProvider !== void 0 && agentProvider !== null) {
|
|
27574
|
+
if (!isValidAgentProvider(agentProvider)) {
|
|
27575
|
+
return createErrorResult({ message: `Invalid agent_provider: must be one of ${VALID_AGENT_PROVIDERS.join(", ")}` });
|
|
27576
|
+
}
|
|
27543
27577
|
}
|
|
27544
|
-
|
|
27545
|
-
|
|
27546
|
-
|
|
27547
|
-
|
|
27548
|
-
|
|
27549
|
-
|
|
27550
|
-
|
|
27551
|
-
|
|
27552
|
-
|
|
27578
|
+
const effectiveAgent = agentProvider !== void 0 ? agentProvider : existing.agentProvider;
|
|
27579
|
+
const agentChanged = agentProvider !== void 0 && agentProvider !== existing.agentProvider;
|
|
27580
|
+
let model = body.model;
|
|
27581
|
+
if (agentChanged && model === void 0 && existing.model) {
|
|
27582
|
+
model = null;
|
|
27583
|
+
}
|
|
27584
|
+
if (model !== void 0 && model !== null) {
|
|
27585
|
+
if (typeof model !== "string" || model.trim().length === 0) {
|
|
27586
|
+
return createErrorResult({ message: "model must be a non-empty string" });
|
|
27553
27587
|
}
|
|
27554
|
-
|
|
27555
|
-
|
|
27556
|
-
|
|
27588
|
+
model = normalizeClaudeModel(model) ?? model;
|
|
27589
|
+
if (!effectiveAgent) {
|
|
27590
|
+
return createErrorResult({ message: "Cannot set model without an agent_provider (the model would be applied against the org default agent and may not be valid for it)" });
|
|
27557
27591
|
}
|
|
27558
|
-
const
|
|
27559
|
-
if (
|
|
27560
|
-
|
|
27592
|
+
const allowed = getAgentModelOptions(effectiveAgent, modelCatalogs);
|
|
27593
|
+
if (!isAgentModelAllowed(effectiveAgent, model, modelCatalogs)) {
|
|
27594
|
+
return createErrorResult({ message: `Invalid model "${model}" for agent ${effectiveAgent}. Valid models: ${allowed.join(", ")}` });
|
|
27561
27595
|
}
|
|
27562
|
-
lastInterruption = {
|
|
27563
|
-
...msg,
|
|
27564
|
-
...lastUserMs !== null && ms >= lastUserMs ? { durationMs: ms - lastUserMs } : {}
|
|
27565
|
-
};
|
|
27566
|
-
finalized.push(lastInterruption);
|
|
27567
27596
|
}
|
|
27568
|
-
|
|
27569
|
-
|
|
27570
|
-
|
|
27571
|
-
|
|
27572
|
-
events.forEach((event, index) => {
|
|
27573
|
-
if (event.type !== AUTH_FALLBACK_EVENT_TYPE) return;
|
|
27574
|
-
const payload = coerceAuthFallbackPayload(event.payload);
|
|
27575
|
-
if (!payload) return;
|
|
27576
|
-
notices.push({
|
|
27577
|
-
...payload,
|
|
27578
|
-
id: `auth-fallback-${event.timestamp}-${index}`,
|
|
27579
|
-
type: "auth_fallback",
|
|
27580
|
-
timestamp: event.timestamp
|
|
27581
|
-
});
|
|
27582
|
-
});
|
|
27583
|
-
if (notices.length === 0) return messages;
|
|
27584
|
-
const result = [...messages];
|
|
27585
|
-
for (const notice of notices) insertDisplayMessageByTimestamp(result, notice);
|
|
27586
|
-
return result;
|
|
27587
|
-
}
|
|
27588
|
-
function isCodexInitializationPrompt(message) {
|
|
27589
|
-
return message.type === "user" && removeReplicasInstructions(message.content).trim() === "Hello";
|
|
27590
|
-
}
|
|
27591
|
-
function filterDisplayMessages(messages, provider) {
|
|
27592
|
-
let result = messages;
|
|
27593
|
-
if (provider === "codex") {
|
|
27594
|
-
const userMessages = result.map((msg, index) => ({ msg, index })).filter(({ msg }) => msg.type === "user");
|
|
27595
|
-
if (userMessages.length >= 2 && isCodexInitializationPrompt(userMessages[0].msg)) {
|
|
27596
|
-
result = result.slice(userMessages[1].index);
|
|
27597
|
+
const thinkingLevel = body.thinking_level;
|
|
27598
|
+
if (thinkingLevel !== void 0 && thinkingLevel !== null) {
|
|
27599
|
+
if (!effectiveAgent && isProviderSpecificThinkingLevel(thinkingLevel)) {
|
|
27600
|
+
return createErrorResult({ message: `Cannot set ${thinkingLevel} without an agent_provider` });
|
|
27597
27601
|
}
|
|
27598
|
-
|
|
27599
|
-
|
|
27600
|
-
|
|
27601
|
-
const cleaned = removeReplicasInstructions(msg.content).trim();
|
|
27602
|
-
if (INTERRUPTED_MESSAGE_REGEX.test(cleaned)) {
|
|
27603
|
-
return { id: msg.id, type: "interruption", timestamp: msg.timestamp };
|
|
27602
|
+
if (!isValidThinkingLevel(thinkingLevel) || effectiveAgent && !getThinkingLevelOptions(effectiveAgent).includes(thinkingLevel)) {
|
|
27603
|
+
const validLevels = effectiveAgent ? getThinkingLevelOptions(effectiveAgent) : VALID_THINKING_LEVELS;
|
|
27604
|
+
return createErrorResult({ message: `Invalid thinking_level: must be one of ${validLevels.join(", ")}` });
|
|
27604
27605
|
}
|
|
27605
|
-
|
|
27606
|
-
});
|
|
27607
|
-
return result;
|
|
27606
|
+
}
|
|
27607
|
+
return createSuccessResult({ agentProvider, model, thinkingLevel });
|
|
27608
27608
|
}
|
|
27609
27609
|
|
|
27610
|
+
// ../shared/src/automations/github/index.ts
|
|
27611
|
+
var REPO_FILTER_PARAM = {
|
|
27612
|
+
id: "repository_ids",
|
|
27613
|
+
label: "Filter by repository",
|
|
27614
|
+
type: "repository_ids"
|
|
27615
|
+
};
|
|
27616
|
+
var EXCLUDED_ACTORS_PARAM = {
|
|
27617
|
+
id: "excluded_actors",
|
|
27618
|
+
label: "Exclude users",
|
|
27619
|
+
type: "excluded_actors"
|
|
27620
|
+
};
|
|
27621
|
+
var GROUP_PR_EVENTS_PARAM = {
|
|
27622
|
+
id: "group_pr_events",
|
|
27623
|
+
label: "Group PR events to same workspace",
|
|
27624
|
+
type: "boolean"
|
|
27625
|
+
};
|
|
27626
|
+
var GITHUB_TRIGGER = {
|
|
27627
|
+
type: "github",
|
|
27628
|
+
label: "GitHub",
|
|
27629
|
+
description: "Trigger on repository events",
|
|
27630
|
+
icon: "github",
|
|
27631
|
+
events: [
|
|
27632
|
+
{ id: "pull_request.opened", label: "PR opened", parameters: [REPO_FILTER_PARAM, EXCLUDED_ACTORS_PARAM, GROUP_PR_EVENTS_PARAM] },
|
|
27633
|
+
{ id: "pull_request.synchronize", label: "PR updated (new commits)", parameters: [REPO_FILTER_PARAM, EXCLUDED_ACTORS_PARAM, GROUP_PR_EVENTS_PARAM] },
|
|
27634
|
+
{ id: "pull_request.merged", label: "PR merged", parameters: [REPO_FILTER_PARAM, EXCLUDED_ACTORS_PARAM] },
|
|
27635
|
+
{ id: "pull_request.closed", label: "PR closed", parameters: [REPO_FILTER_PARAM, EXCLUDED_ACTORS_PARAM] },
|
|
27636
|
+
{ id: "pull_request.command", label: "PR command (/replicas run)", parameters: [REPO_FILTER_PARAM, EXCLUDED_ACTORS_PARAM, GROUP_PR_EVENTS_PARAM] }
|
|
27637
|
+
]
|
|
27638
|
+
};
|
|
27639
|
+
|
|
27640
|
+
// ../shared/src/automations/gitlab/index.ts
|
|
27641
|
+
var REPO_FILTER_PARAM2 = {
|
|
27642
|
+
id: "repository_ids",
|
|
27643
|
+
label: "Filter by project",
|
|
27644
|
+
type: "repository_ids"
|
|
27645
|
+
};
|
|
27646
|
+
var EXCLUDED_ACTORS_PARAM2 = {
|
|
27647
|
+
id: "excluded_actors",
|
|
27648
|
+
label: "Exclude users",
|
|
27649
|
+
type: "excluded_actors"
|
|
27650
|
+
};
|
|
27651
|
+
var GROUP_MR_EVENTS_PARAM = {
|
|
27652
|
+
id: "group_pr_events",
|
|
27653
|
+
label: "Group MR events to same workspace",
|
|
27654
|
+
type: "boolean"
|
|
27655
|
+
};
|
|
27656
|
+
var GITLAB_TRIGGER = {
|
|
27657
|
+
type: "gitlab",
|
|
27658
|
+
label: "GitLab",
|
|
27659
|
+
description: "Trigger on project events",
|
|
27660
|
+
icon: "gitlab",
|
|
27661
|
+
events: [
|
|
27662
|
+
{ id: "merge_request.opened", label: "MR opened", parameters: [REPO_FILTER_PARAM2, EXCLUDED_ACTORS_PARAM2, GROUP_MR_EVENTS_PARAM] },
|
|
27663
|
+
{ id: "merge_request.updated", label: "MR updated (new commits)", parameters: [REPO_FILTER_PARAM2, EXCLUDED_ACTORS_PARAM2, GROUP_MR_EVENTS_PARAM] },
|
|
27664
|
+
{ id: "merge_request.merged", label: "MR merged", parameters: [REPO_FILTER_PARAM2, EXCLUDED_ACTORS_PARAM2] },
|
|
27665
|
+
{ id: "merge_request.closed", label: "MR closed", parameters: [REPO_FILTER_PARAM2, EXCLUDED_ACTORS_PARAM2] }
|
|
27666
|
+
]
|
|
27667
|
+
};
|
|
27668
|
+
|
|
27669
|
+
// ../shared/src/routes/repo-files.ts
|
|
27670
|
+
var MAX_REPO_FILE_CONTENT_BYTES = 256 * 1024;
|
|
27671
|
+
|
|
27672
|
+
// ../shared/src/routes/admin.ts
|
|
27673
|
+
var WEBHOOK_PROVIDERS = ["linear", "github", "gitlab", "slack", "e2b", "stripe", "sentry"];
|
|
27674
|
+
var WEBHOOK_PROVIDER_SET = new Set(WEBHOOK_PROVIDERS);
|
|
27675
|
+
|
|
27610
27676
|
// ../shared/src/onboarding-emails.ts
|
|
27611
27677
|
var EMAIL_KEYS = [
|
|
27612
27678
|
"welcome",
|