replicas-engine 0.1.735 → 0.1.736
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/src/{chunk-2VCV6W5F.js → chunk-AQXSBHCI.js} +1 -1
- package/dist/src/{chunk-CZXDETV5.js → chunk-KIBFWYCG.js} +14 -8
- package/dist/src/{chunk-EZ6Z6GSU.js → chunk-NQFMLRS4.js} +115 -103
- package/dist/src/{chunk-3FHZVVPZ.js → chunk-ZQSFPKUG.js} +2 -2
- package/dist/src/command-protection-hook.js +2 -2
- package/dist/src/deepseek-command-protection-plugin.js +3 -3
- package/dist/src/headless-agent.js +2 -2
- package/dist/src/index.js +116 -49
- package/dist/src/post-tool-pr-hook.js +2 -2
- package/package.json +1 -1
|
@@ -5,15 +5,17 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
REPLICAS_RUNTIME_ENV_ALIASES,
|
|
7
7
|
agentCredentialSnapshotSchema,
|
|
8
|
-
|
|
8
|
+
createErrorResult,
|
|
9
|
+
createSuccessResult,
|
|
9
10
|
extractCommandProtectionCommandText,
|
|
11
|
+
fallbackPlanResponseSchema,
|
|
10
12
|
findGitCommitSignals,
|
|
11
13
|
findPrMergeSignals,
|
|
12
14
|
isRecord,
|
|
13
15
|
isValidAgentProvider,
|
|
14
16
|
parsePosixEnvFile,
|
|
15
17
|
readReplicasRuntimeEnv
|
|
16
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-NQFMLRS4.js";
|
|
17
19
|
|
|
18
20
|
// src/engine-env.ts
|
|
19
21
|
import { readFileSync as readFileSync2 } from "fs";
|
|
@@ -198,15 +200,19 @@ var MonolithService = class {
|
|
|
198
200
|
return null;
|
|
199
201
|
}
|
|
200
202
|
}
|
|
201
|
-
|
|
203
|
+
/** `unsupported` means an older monolith; `unavailable` means this one could not be read. */
|
|
204
|
+
async getFallbackPlan(params) {
|
|
202
205
|
const query = new URLSearchParams({ provider: params.provider, exclude: params.exclude.join(",") });
|
|
206
|
+
if (params.exhaustedMethod) query.set("exhaustedMethod", params.exhaustedMethod);
|
|
203
207
|
if (params.userId) query.set("userId", params.userId);
|
|
204
208
|
try {
|
|
205
|
-
const response = await monolithRequest(`/v1/engine/
|
|
206
|
-
if (
|
|
207
|
-
return
|
|
208
|
-
|
|
209
|
-
return
|
|
209
|
+
const response = await monolithRequest(`/v1/engine/fallback-plan?${query}`, { method: "GET" });
|
|
210
|
+
if (response.status === 404) return createErrorResult({ message: "Monolith has no fallback-plan route", code: "unsupported" });
|
|
211
|
+
if (!response.ok) return createErrorResult({ message: `Fallback plan request failed: ${response.status}`, code: "unavailable" });
|
|
212
|
+
const parsed = fallbackPlanResponseSchema.safeParse(await response.json());
|
|
213
|
+
return parsed.success ? createSuccessResult(parsed.data) : createErrorResult({ message: "Fallback plan response did not match the schema", code: "unavailable" });
|
|
214
|
+
} catch (error) {
|
|
215
|
+
return createErrorResult({ message: error instanceof Error ? error.message : String(error), code: "unavailable" });
|
|
210
216
|
}
|
|
211
217
|
}
|
|
212
218
|
async sendEvent(event) {
|
|
@@ -1268,43 +1268,54 @@ function describeAuthFallback(payload) {
|
|
|
1268
1268
|
}
|
|
1269
1269
|
|
|
1270
1270
|
// ../shared/src/chat-fork.ts
|
|
1271
|
+
import { z as z5 } from "zod";
|
|
1272
|
+
|
|
1273
|
+
// ../shared/src/fallback-chains.ts
|
|
1271
1274
|
import { z as z4 } from "zod";
|
|
1272
|
-
var
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1275
|
+
var fallbackHarnessStepSchema = z4.object({
|
|
1276
|
+
kind: z4.literal("harness"),
|
|
1277
|
+
provider: z4.enum(VALID_AGENT_PROVIDERS),
|
|
1278
|
+
model: z4.string().min(1),
|
|
1279
|
+
thinkingLevel: z4.enum(VALID_THINKING_LEVELS).optional()
|
|
1280
|
+
});
|
|
1281
|
+
var fallbackPlanStepSchema = z4.discriminatedUnion("kind", [
|
|
1282
|
+
z4.object({ kind: z4.literal("credentials"), methods: z4.array(z4.custom(isAuthMethod)).min(1) }),
|
|
1283
|
+
fallbackHarnessStepSchema
|
|
1284
|
+
]);
|
|
1285
|
+
var fallbackPlanResponseSchema = z4.object({ steps: z4.array(fallbackPlanStepSchema) });
|
|
1286
|
+
|
|
1287
|
+
// ../shared/src/chat-fork.ts
|
|
1288
|
+
var quotaLimitKindSchema = z5.enum(["rate_limit", "out_of_credits"]);
|
|
1289
|
+
var chatForkInfoSchema = z5.object({
|
|
1290
|
+
source: z5.object({
|
|
1291
|
+
chatId: z5.string().min(1),
|
|
1292
|
+
provider: z5.enum(VALID_AGENT_PROVIDERS),
|
|
1293
|
+
title: z5.string()
|
|
1278
1294
|
}),
|
|
1279
|
-
trigger:
|
|
1295
|
+
trigger: z5.enum(["manual", "auto"]),
|
|
1280
1296
|
reason: quotaLimitKindSchema.optional(),
|
|
1281
|
-
state:
|
|
1282
|
-
error:
|
|
1283
|
-
startedAt:
|
|
1284
|
-
completedAt:
|
|
1297
|
+
state: z5.enum(["preparing", "ready", "failed"]),
|
|
1298
|
+
error: z5.string().optional(),
|
|
1299
|
+
startedAt: z5.string(),
|
|
1300
|
+
completedAt: z5.string().optional()
|
|
1285
1301
|
});
|
|
1286
1302
|
function coerceChatForkInfo(value) {
|
|
1287
1303
|
const parsed = chatForkInfoSchema.safeParse(value);
|
|
1288
1304
|
return parsed.success ? parsed.data : null;
|
|
1289
1305
|
}
|
|
1290
|
-
var forkChatRequestSchema =
|
|
1291
|
-
provider:
|
|
1292
|
-
model:
|
|
1293
|
-
thinkingLevel:
|
|
1294
|
-
title:
|
|
1295
|
-
id:
|
|
1296
|
-
clientRequestId:
|
|
1297
|
-
enableInteractiveTools:
|
|
1306
|
+
var forkChatRequestSchema = z5.object({
|
|
1307
|
+
provider: z5.enum(VALID_AGENT_PROVIDERS),
|
|
1308
|
+
model: z5.string().min(1).optional(),
|
|
1309
|
+
thinkingLevel: z5.enum(VALID_THINKING_LEVELS).optional(),
|
|
1310
|
+
title: z5.string().min(1).max(200).optional(),
|
|
1311
|
+
id: z5.string().uuid().optional(),
|
|
1312
|
+
clientRequestId: z5.string().min(1).max(128).optional(),
|
|
1313
|
+
enableInteractiveTools: z5.boolean().optional(),
|
|
1298
1314
|
// Server-injected by the monolith from the authenticated request; never trusted from clients.
|
|
1299
|
-
senderUserId:
|
|
1300
|
-
senderEmail:
|
|
1301
|
-
senderDisplayName:
|
|
1302
|
-
senderAvatarUrl:
|
|
1303
|
-
});
|
|
1304
|
-
var chatForkFallbackResponseSchema = z4.object({
|
|
1305
|
-
provider: z4.enum(VALID_AGENT_PROVIDERS).nullable(),
|
|
1306
|
-
model: z4.string().min(1).optional(),
|
|
1307
|
-
thinkingLevel: z4.enum(VALID_THINKING_LEVELS).optional()
|
|
1315
|
+
senderUserId: z5.string().optional(),
|
|
1316
|
+
senderEmail: z5.string().optional(),
|
|
1317
|
+
senderDisplayName: z5.string().optional(),
|
|
1318
|
+
senderAvatarUrl: z5.string().optional()
|
|
1308
1319
|
});
|
|
1309
1320
|
function describeQuotaLimit(reason) {
|
|
1310
1321
|
return reason === "out_of_credits" ? "ran out of credits" : "hit its usage limit";
|
|
@@ -1313,10 +1324,11 @@ function describeChatForkReason(reason, provider) {
|
|
|
1313
1324
|
return reason ? `${getProviderDisplayName(provider)} ${describeQuotaLimit(reason)}` : null;
|
|
1314
1325
|
}
|
|
1315
1326
|
var AGENT_QUOTA_EXHAUSTED_EVENT_TYPE = "agent-quota-exhausted";
|
|
1316
|
-
var agentQuotaExhaustedPayloadSchema =
|
|
1317
|
-
provider:
|
|
1327
|
+
var agentQuotaExhaustedPayloadSchema = z5.object({
|
|
1328
|
+
provider: z5.enum(VALID_CODING_AGENT_PROVIDERS),
|
|
1318
1329
|
reason: quotaLimitKindSchema,
|
|
1319
|
-
detail:
|
|
1330
|
+
detail: z5.string().optional(),
|
|
1331
|
+
forkTo: fallbackHarnessStepSchema.optional()
|
|
1320
1332
|
});
|
|
1321
1333
|
function defaultForkChatTitle(source, provider) {
|
|
1322
1334
|
return isDefaultChat(source) ? `Forked from ${source.title}` : `${source.title} (${getProviderDisplayName(provider)})`;
|
|
@@ -3272,9 +3284,7 @@ var DEFAULT_USER_PREFERENCES = {
|
|
|
3272
3284
|
open_links_in_desktop_app: false,
|
|
3273
3285
|
default_fast_mode: false,
|
|
3274
3286
|
agent_defaults: { ...EMPTY_AGENT_DEFAULT_SETTINGS },
|
|
3275
|
-
|
|
3276
|
-
chat_fork_fallbacks_enabled: false,
|
|
3277
|
-
chat_fork_fallback_providers: []
|
|
3287
|
+
fallback_chains: null
|
|
3278
3288
|
};
|
|
3279
3289
|
function defaultReplicasAgentAbilities() {
|
|
3280
3290
|
const abilities = {};
|
|
@@ -5928,20 +5938,20 @@ var TEAM_PLAN = PLANS.team;
|
|
|
5928
5938
|
var ENTERPRISE_PLAN = PLANS.enterprise;
|
|
5929
5939
|
|
|
5930
5940
|
// ../shared/src/models-dev.ts
|
|
5931
|
-
import { z as
|
|
5941
|
+
import { z as z6 } from "zod";
|
|
5932
5942
|
var MODELS_DEV_API_URL = "https://models.dev/api.json";
|
|
5933
5943
|
var MODELS_DEV_CACHE_MS = 5 * 6e4;
|
|
5934
|
-
var modelsDevCatalogSchema =
|
|
5935
|
-
models:
|
|
5936
|
-
id:
|
|
5937
|
-
name:
|
|
5938
|
-
description:
|
|
5939
|
-
status:
|
|
5940
|
-
cost:
|
|
5941
|
-
input:
|
|
5942
|
-
output:
|
|
5943
|
-
cache_read:
|
|
5944
|
-
cache_write:
|
|
5944
|
+
var modelsDevCatalogSchema = z6.record(z6.string(), z6.object({
|
|
5945
|
+
models: z6.record(z6.string(), z6.object({
|
|
5946
|
+
id: z6.string().optional(),
|
|
5947
|
+
name: z6.string(),
|
|
5948
|
+
description: z6.string().optional(),
|
|
5949
|
+
status: z6.enum(["alpha", "beta", "deprecated"]).optional(),
|
|
5950
|
+
cost: z6.object({
|
|
5951
|
+
input: z6.number().finite().nonnegative().optional(),
|
|
5952
|
+
output: z6.number().finite().nonnegative().optional(),
|
|
5953
|
+
cache_read: z6.number().finite().nonnegative().optional(),
|
|
5954
|
+
cache_write: z6.number().finite().nonnegative().optional()
|
|
5945
5955
|
}).optional()
|
|
5946
5956
|
}))
|
|
5947
5957
|
}));
|
|
@@ -6873,46 +6883,46 @@ var DEFAULT_WORKSPACE_FILTERS = {
|
|
|
6873
6883
|
var ONE_DAY_MS = 24 * 60 * 60 * 1e3;
|
|
6874
6884
|
|
|
6875
6885
|
// ../shared/src/routes/workspace-events.ts
|
|
6876
|
-
import { z as
|
|
6877
|
-
var workspaceChangedEventSchema =
|
|
6878
|
-
|
|
6879
|
-
type:
|
|
6880
|
-
workspaceId:
|
|
6881
|
-
completion:
|
|
6882
|
-
workspaceName:
|
|
6883
|
-
completedAt:
|
|
6884
|
-
processing:
|
|
6886
|
+
import { z as z7 } from "zod";
|
|
6887
|
+
var workspaceChangedEventSchema = z7.discriminatedUnion("type", [
|
|
6888
|
+
z7.object({
|
|
6889
|
+
type: z7.literal("workspace.changed"),
|
|
6890
|
+
workspaceId: z7.string(),
|
|
6891
|
+
completion: z7.object({
|
|
6892
|
+
workspaceName: z7.string(),
|
|
6893
|
+
completedAt: z7.string(),
|
|
6894
|
+
processing: z7.boolean().optional()
|
|
6885
6895
|
}).optional(),
|
|
6886
|
-
ts:
|
|
6896
|
+
ts: z7.string()
|
|
6887
6897
|
}),
|
|
6888
|
-
|
|
6889
|
-
type:
|
|
6890
|
-
workspaceId:
|
|
6891
|
-
chatId:
|
|
6892
|
-
ts:
|
|
6898
|
+
z7.object({
|
|
6899
|
+
type: z7.literal("workspace.chat.changed"),
|
|
6900
|
+
workspaceId: z7.string(),
|
|
6901
|
+
chatId: z7.string(),
|
|
6902
|
+
ts: z7.string()
|
|
6893
6903
|
}),
|
|
6894
|
-
|
|
6895
|
-
|
|
6896
|
-
type:
|
|
6897
|
-
workspaceId:
|
|
6898
|
-
ts:
|
|
6904
|
+
z7.object({ type: z7.literal("presence.changed"), ts: z7.string() }),
|
|
6905
|
+
z7.object({
|
|
6906
|
+
type: z7.literal("mobile-testing.changed"),
|
|
6907
|
+
workspaceId: z7.string(),
|
|
6908
|
+
ts: z7.string()
|
|
6899
6909
|
})
|
|
6900
6910
|
]);
|
|
6901
6911
|
|
|
6902
6912
|
// ../shared/src/routes/presence.ts
|
|
6903
|
-
import { z as
|
|
6904
|
-
var presenceStatusSchema =
|
|
6905
|
-
var presenceLocationSchema =
|
|
6906
|
-
environmentId:
|
|
6907
|
-
workspaceId:
|
|
6913
|
+
import { z as z8 } from "zod";
|
|
6914
|
+
var presenceStatusSchema = z8.enum(["online", "typing"]);
|
|
6915
|
+
var presenceLocationSchema = z8.object({
|
|
6916
|
+
environmentId: z8.string().optional(),
|
|
6917
|
+
workspaceId: z8.string().optional()
|
|
6908
6918
|
});
|
|
6909
|
-
var presenceEntrySchema =
|
|
6910
|
-
userId:
|
|
6919
|
+
var presenceEntrySchema = z8.object({
|
|
6920
|
+
userId: z8.string(),
|
|
6911
6921
|
status: presenceStatusSchema,
|
|
6912
6922
|
location: presenceLocationSchema,
|
|
6913
|
-
ts:
|
|
6923
|
+
ts: z8.string()
|
|
6914
6924
|
});
|
|
6915
|
-
var updatePresenceRequestSchema =
|
|
6925
|
+
var updatePresenceRequestSchema = z8.object({
|
|
6916
6926
|
status: presenceStatusSchema,
|
|
6917
6927
|
location: presenceLocationSchema.optional()
|
|
6918
6928
|
});
|
|
@@ -7177,31 +7187,31 @@ function parseChatTranscriptArtifact(value) {
|
|
|
7177
7187
|
}
|
|
7178
7188
|
|
|
7179
7189
|
// ../shared/src/memory.ts
|
|
7180
|
-
import { z as
|
|
7190
|
+
import { z as z9 } from "zod";
|
|
7181
7191
|
var MEMORY_ROOT = `${SANDBOX_PATHS.REPLICAS_DIR}/memories`;
|
|
7182
7192
|
var MEMORY_INDEX_FILENAME = "MEMORY.md";
|
|
7183
7193
|
var MEMORY_BUNDLE_FILENAME = "memory.tar.gz";
|
|
7184
|
-
var memoryExtractionResultSchema =
|
|
7185
|
-
seatSummary:
|
|
7186
|
-
organizationSummary:
|
|
7194
|
+
var memoryExtractionResultSchema = z9.object({
|
|
7195
|
+
seatSummary: z9.string().nullable(),
|
|
7196
|
+
organizationSummary: z9.string().nullable()
|
|
7187
7197
|
});
|
|
7188
|
-
var { $schema: _, ...MEMORY_EXTRACTION_SCHEMA } =
|
|
7189
|
-
var memoryGenerationManifestSchema =
|
|
7190
|
-
domainId:
|
|
7191
|
-
generation:
|
|
7192
|
-
previousManifestKey:
|
|
7193
|
-
createdAt:
|
|
7194
|
-
promptVersion:
|
|
7195
|
-
harness:
|
|
7196
|
-
model:
|
|
7197
|
-
bundle:
|
|
7198
|
-
path:
|
|
7199
|
-
sha256:
|
|
7200
|
-
sizeBytes:
|
|
7198
|
+
var { $schema: _, ...MEMORY_EXTRACTION_SCHEMA } = z9.toJSONSchema(memoryExtractionResultSchema);
|
|
7199
|
+
var memoryGenerationManifestSchema = z9.object({
|
|
7200
|
+
domainId: z9.string(),
|
|
7201
|
+
generation: z9.number().int().nonnegative(),
|
|
7202
|
+
previousManifestKey: z9.string().nullable(),
|
|
7203
|
+
createdAt: z9.string(),
|
|
7204
|
+
promptVersion: z9.string(),
|
|
7205
|
+
harness: z9.enum(["claude", "codex", "none"]),
|
|
7206
|
+
model: z9.string(),
|
|
7207
|
+
bundle: z9.object({
|
|
7208
|
+
path: z9.literal(MEMORY_BUNDLE_FILENAME),
|
|
7209
|
+
sha256: z9.string().regex(/^[a-f0-9]{64}$/),
|
|
7210
|
+
sizeBytes: z9.number().int().positive()
|
|
7201
7211
|
}).nullable(),
|
|
7202
|
-
files:
|
|
7203
|
-
rollouts:
|
|
7204
|
-
rolloutSources:
|
|
7212
|
+
files: z9.record(z9.string(), z9.string()),
|
|
7213
|
+
rollouts: z9.record(z9.string(), z9.string()),
|
|
7214
|
+
rolloutSources: z9.record(z9.string(), z9.string()).optional()
|
|
7205
7215
|
});
|
|
7206
7216
|
|
|
7207
7217
|
// ../shared/src/skill-registry.ts
|
|
@@ -7229,8 +7239,17 @@ export {
|
|
|
7229
7239
|
isValidAgentProvider,
|
|
7230
7240
|
VALID_THINKING_LEVELS,
|
|
7231
7241
|
codexReasoningEffortForThinkingLevel,
|
|
7242
|
+
getProviderDisplayName,
|
|
7232
7243
|
detectAgentQuotaLimit,
|
|
7233
7244
|
CREDENTIAL_METHOD,
|
|
7245
|
+
agentCredentialSnapshotSchema,
|
|
7246
|
+
isAgentChatTurnActivityRecord,
|
|
7247
|
+
isAgentChatSkillActivityRecord,
|
|
7248
|
+
isAgentChatMcpActivityRecord,
|
|
7249
|
+
TOKEN_USAGE_PATH,
|
|
7250
|
+
isTokenUsageCounts,
|
|
7251
|
+
isTokenUsageUploadRecord,
|
|
7252
|
+
fallbackPlanResponseSchema,
|
|
7234
7253
|
ASTER_PROVIDER,
|
|
7235
7254
|
ASTER_BASE_URL,
|
|
7236
7255
|
ASTER_MODELS,
|
|
@@ -7275,17 +7294,10 @@ export {
|
|
|
7275
7294
|
paginateEngineLogContent,
|
|
7276
7295
|
coerceChatForkInfo,
|
|
7277
7296
|
forkChatRequestSchema,
|
|
7278
|
-
|
|
7297
|
+
describeQuotaLimit,
|
|
7279
7298
|
AGENT_QUOTA_EXHAUSTED_EVENT_TYPE,
|
|
7280
7299
|
agentQuotaExhaustedPayloadSchema,
|
|
7281
7300
|
defaultForkChatTitle,
|
|
7282
|
-
agentCredentialSnapshotSchema,
|
|
7283
|
-
isAgentChatTurnActivityRecord,
|
|
7284
|
-
isAgentChatSkillActivityRecord,
|
|
7285
|
-
isAgentChatMcpActivityRecord,
|
|
7286
|
-
TOKEN_USAGE_PATH,
|
|
7287
|
-
isTokenUsageCounts,
|
|
7288
|
-
isTokenUsageUploadRecord,
|
|
7289
7301
|
CLAUDE_PARTIAL_MESSAGE_EVENT_TYPE,
|
|
7290
7302
|
getClaudePartialMessageStreamId,
|
|
7291
7303
|
ACCEPTED_USER_MESSAGE_SOURCE,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
HOOK_EXEC_MAX_BUFFER_BYTES,
|
|
4
4
|
isVersionBelow
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-NQFMLRS4.js";
|
|
6
6
|
|
|
7
7
|
// src/utils/presigned-upload.ts
|
|
8
8
|
import { createReadStream } from "fs";
|
|
@@ -272,7 +272,7 @@ var DEFAULT_CODEX_ARGS = [
|
|
|
272
272
|
var MIN_CODEX_CLI_VERSION = "0.144.6";
|
|
273
273
|
var CODEX_UPGRADE_TIMEOUT_MS = 12e4;
|
|
274
274
|
var codexCliVersionEnsured = null;
|
|
275
|
-
var ENGINE_PACKAGE_VERSION = "0.1.
|
|
275
|
+
var ENGINE_PACKAGE_VERSION = "0.1.736";
|
|
276
276
|
var INITIALIZE_METHOD = "initialize";
|
|
277
277
|
var INITIALIZED_NOTIFICATION = "initialized";
|
|
278
278
|
var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
evaluateCommandProtection
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-KIBFWYCG.js";
|
|
5
5
|
import {
|
|
6
6
|
isRecord
|
|
7
7
|
} from "./chunk-2RB7SIP3.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-NQFMLRS4.js";
|
|
9
9
|
|
|
10
10
|
// src/command-protection-hook.ts
|
|
11
11
|
var provider = process.argv[2];
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
evaluateCommandProtection
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-KIBFWYCG.js";
|
|
5
5
|
import {
|
|
6
6
|
notifyPostToolUse
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-AQXSBHCI.js";
|
|
8
8
|
import "./chunk-2RB7SIP3.js";
|
|
9
|
-
import "./chunk-
|
|
9
|
+
import "./chunk-NQFMLRS4.js";
|
|
10
10
|
|
|
11
11
|
// src/deepseek-command-protection-plugin.ts
|
|
12
12
|
function replicasCommandProtection(context) {
|
|
@@ -4,12 +4,12 @@ import {
|
|
|
4
4
|
buildCodexAgentEnv,
|
|
5
5
|
putPresignedFile,
|
|
6
6
|
recoverCompletedTurn
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-ZQSFPKUG.js";
|
|
8
8
|
import {
|
|
9
9
|
AGENT,
|
|
10
10
|
getMemoryOutputSafetyViolation,
|
|
11
11
|
headlessAgentRequestSchema
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-NQFMLRS4.js";
|
|
13
13
|
|
|
14
14
|
// src/headless-agent.ts
|
|
15
15
|
import { createHash } from "crypto";
|
package/dist/src/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
monolithService,
|
|
9
9
|
reportCommandProtectionBlock,
|
|
10
10
|
setAgentCredentialSnapshot
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-KIBFWYCG.js";
|
|
12
12
|
import {
|
|
13
13
|
ACCOUNT_RATE_LIMITS_UPDATED_METHOD,
|
|
14
14
|
AGENT_MESSAGE_DELTA_METHOD,
|
|
@@ -36,7 +36,7 @@ import {
|
|
|
36
36
|
execFileAsync,
|
|
37
37
|
putPresignedFile,
|
|
38
38
|
recoverCompletedTurn
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-ZQSFPKUG.js";
|
|
40
40
|
import {
|
|
41
41
|
isRecord as isRecord2
|
|
42
42
|
} from "./chunk-2RB7SIP3.js";
|
|
@@ -148,6 +148,7 @@ import {
|
|
|
148
148
|
createUuidFromHex,
|
|
149
149
|
decodePathSegments,
|
|
150
150
|
defaultForkChatTitle,
|
|
151
|
+
describeQuotaLimit,
|
|
151
152
|
detectAgentQuotaLimit,
|
|
152
153
|
detectLanguageByPath,
|
|
153
154
|
extractErrorText,
|
|
@@ -168,6 +169,7 @@ import {
|
|
|
168
169
|
getFxTextChunk,
|
|
169
170
|
getGoalCommand,
|
|
170
171
|
getGoalCommandObjectiveValidationError,
|
|
172
|
+
getProviderDisplayName,
|
|
171
173
|
getSlashCommandsForProvider,
|
|
172
174
|
getUserMessage,
|
|
173
175
|
getUserMessageId,
|
|
@@ -228,7 +230,7 @@ import {
|
|
|
228
230
|
shellQuotePosix,
|
|
229
231
|
stripAgentDiagnosticErrors,
|
|
230
232
|
withTimeout
|
|
231
|
-
} from "./chunk-
|
|
233
|
+
} from "./chunk-NQFMLRS4.js";
|
|
232
234
|
|
|
233
235
|
// src/index.ts
|
|
234
236
|
import { serve } from "@hono/node-server";
|
|
@@ -323,7 +325,10 @@ var BaseRefreshManager = class {
|
|
|
323
325
|
try {
|
|
324
326
|
console.log(`[${this.managerName}] Fetching fresh credentials from monolith (${params.failureKind})...`);
|
|
325
327
|
const excludeCredentials = listExhaustedCredentials(params.provider);
|
|
326
|
-
await params.refresh(
|
|
328
|
+
await params.refresh({
|
|
329
|
+
...excludeCredentials.length > 0 ? { excludeCredentials } : {},
|
|
330
|
+
...params.allowedMethods ? { allowedMethods: [...params.allowedMethods] } : {}
|
|
331
|
+
});
|
|
327
332
|
if (params.isOauthNow()) {
|
|
328
333
|
this.start().catch((error) => {
|
|
329
334
|
console.error(`[${this.managerName}] Failed to restart OAuth refresh service after fallback:`, error);
|
|
@@ -1310,11 +1315,12 @@ var ClaudeTokenManager = class extends BaseRefreshManager {
|
|
|
1310
1315
|
}
|
|
1311
1316
|
console.log(`[ClaudeTokenManager] Credentials refreshed (method=${data.type})`);
|
|
1312
1317
|
}
|
|
1313
|
-
async fetchFreshCredentials(failureReason, failureKind = "rejected", failedCredential = ENGINE_ENV.REPLICAS_AGENT_CREDENTIALS.claude) {
|
|
1318
|
+
async fetchFreshCredentials(failureReason, failureKind = "rejected", failedCredential = ENGINE_ENV.REPLICAS_AGENT_CREDENTIALS.claude, allowedMethods) {
|
|
1314
1319
|
const failedMethod = failedCredential?.method === "oauth" || failedCredential?.method === "api_key" || failedCredential?.method === "bedrock" || failedCredential?.method === "foundry" ? failedCredential.method : ENGINE_ENV.REPLICAS_CLAUDE_AUTH_METHOD;
|
|
1315
1320
|
return this.swapCredentials({
|
|
1316
1321
|
provider: "claude",
|
|
1317
1322
|
failureKind,
|
|
1323
|
+
allowedMethods,
|
|
1318
1324
|
refresh: (exclusions) => this.refreshWithRequest(failedMethod && failedMethod !== "none" ? {
|
|
1319
1325
|
failedMethod,
|
|
1320
1326
|
...failedCredential?.method === failedMethod ? { failedCredential } : {},
|
|
@@ -1469,11 +1475,12 @@ var CodexTokenManager = class extends BaseRefreshManager {
|
|
|
1469
1475
|
});
|
|
1470
1476
|
}
|
|
1471
1477
|
}
|
|
1472
|
-
async fetchFreshCredentials(failureReason, failureKind = "rejected", failedCredential = ENGINE_ENV.REPLICAS_AGENT_CREDENTIALS.codex) {
|
|
1478
|
+
async fetchFreshCredentials(failureReason, failureKind = "rejected", failedCredential = ENGINE_ENV.REPLICAS_AGENT_CREDENTIALS.codex, allowedMethods) {
|
|
1473
1479
|
const failedMethod = failedCredential?.method === "oauth" || failedCredential?.method === "api_key" || failedCredential?.method === "foundry" ? failedCredential.method : ENGINE_ENV.REPLICAS_CODEX_AUTH_METHOD;
|
|
1474
1480
|
return this.swapCredentials({
|
|
1475
1481
|
provider: "codex",
|
|
1476
1482
|
failureKind,
|
|
1483
|
+
allowedMethods,
|
|
1477
1484
|
refresh: async (exclusions) => {
|
|
1478
1485
|
await this.refreshWithRequest(
|
|
1479
1486
|
failedMethod === "oauth" || failedMethod === "api_key" || failedMethod === "foundry" ? {
|
|
@@ -1903,6 +1910,7 @@ var EnvironmentDetailsService = class {
|
|
|
1903
1910
|
details.supportsClaudeMidTurnSteering = true;
|
|
1904
1911
|
details.supportsGoalUpdates = true;
|
|
1905
1912
|
details.supportsQueuedMessageEditing = true;
|
|
1913
|
+
details.supportsChatForking = true;
|
|
1906
1914
|
details.claudeAuthMethod = detectAgentAuthMethod(AGENT.CLAUDE);
|
|
1907
1915
|
details.codexAuthMethod = detectAgentAuthMethod(AGENT.CODEX);
|
|
1908
1916
|
details.cursorAuthMethod = detectAgentAuthMethod(AGENT.CURSOR);
|
|
@@ -3353,10 +3361,11 @@ var MuseTokenManager = class extends BaseRefreshManager {
|
|
|
3353
3361
|
doRefresh() {
|
|
3354
3362
|
return Promise.resolve();
|
|
3355
3363
|
}
|
|
3356
|
-
async fetchFreshCredentials(failureReason, failureKind = "exhausted", failedCredential = ENGINE_ENV.REPLICAS_AGENT_CREDENTIALS.muse) {
|
|
3364
|
+
async fetchFreshCredentials(failureReason, failureKind = "exhausted", failedCredential = ENGINE_ENV.REPLICAS_AGENT_CREDENTIALS.muse, allowedMethods) {
|
|
3357
3365
|
return this.swapCredentials({
|
|
3358
3366
|
provider: "muse",
|
|
3359
3367
|
failureKind,
|
|
3368
|
+
allowedMethods,
|
|
3360
3369
|
refresh: async (exclusions) => {
|
|
3361
3370
|
const request = {
|
|
3362
3371
|
failedMethod: CREDENTIAL_METHOD.MUSE_OAUTH,
|
|
@@ -3392,25 +3401,61 @@ var SWAPPABLE_AGENTS = {
|
|
|
3392
3401
|
muse: museTokenManager
|
|
3393
3402
|
};
|
|
3394
3403
|
var AuthFallbackCoordinator = class {
|
|
3395
|
-
constructor(provider, record) {
|
|
3404
|
+
constructor(provider, record, context) {
|
|
3396
3405
|
this.provider = provider;
|
|
3397
3406
|
this.record = record;
|
|
3407
|
+
this.context = context;
|
|
3398
3408
|
}
|
|
3399
3409
|
provider;
|
|
3400
3410
|
record;
|
|
3411
|
+
context;
|
|
3401
3412
|
async fallBack(reason, detail) {
|
|
3402
3413
|
const tokenManager = SWAPPABLE_AGENTS[this.provider];
|
|
3403
|
-
if (!tokenManager) return "unavailable";
|
|
3404
3414
|
const exhausted = ENGINE_ENV.REPLICAS_AGENT_CREDENTIALS[this.provider];
|
|
3405
|
-
if (
|
|
3406
|
-
|
|
3407
|
-
const
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3415
|
+
if (exhausted) recordExhaustedCredential(this.provider, exhausted);
|
|
3416
|
+
const { userId, excludeProviders, forkable } = this.context();
|
|
3417
|
+
const plan = await monolithService.getFallbackPlan({
|
|
3418
|
+
provider: this.provider,
|
|
3419
|
+
exhaustedMethod: exhausted?.method,
|
|
3420
|
+
exclude: excludeProviders,
|
|
3421
|
+
userId
|
|
3422
|
+
});
|
|
3423
|
+
if (!plan.ok && plan.error.code === "unavailable") {
|
|
3424
|
+
console.error(`[AuthFallback] ${this.provider} fallback stopped; plan unavailable:`, plan.error.message);
|
|
3425
|
+
return { outcome: "unavailable" };
|
|
3426
|
+
}
|
|
3427
|
+
const steps = plan.ok ? plan.data.steps : tokenManager && exhausted ? [{ kind: "credentials", methods: [] }] : [];
|
|
3428
|
+
let failed = false;
|
|
3429
|
+
for (const step of steps) {
|
|
3430
|
+
if (step.kind === "harness") {
|
|
3431
|
+
if (forkable && isAgentAvailable(step.provider)) return { outcome: "fork", target: step };
|
|
3432
|
+
continue;
|
|
3433
|
+
}
|
|
3434
|
+
if (!tokenManager || !exhausted) continue;
|
|
3435
|
+
const swap = await tokenManager.fetchFreshCredentials(
|
|
3436
|
+
`${this.provider} ${describeQuotaLimit(reason)}: ${detail}`,
|
|
3437
|
+
"exhausted",
|
|
3438
|
+
void 0,
|
|
3439
|
+
step.methods.length > 0 ? step.methods : void 0
|
|
3440
|
+
);
|
|
3441
|
+
if (!swap.ok) {
|
|
3442
|
+
failed ||= swap.error.code !== "no_credentials";
|
|
3443
|
+
continue;
|
|
3444
|
+
}
|
|
3445
|
+
const applied = ENGINE_ENV.REPLICAS_AGENT_CREDENTIALS[this.provider] ?? exhausted;
|
|
3446
|
+
if (applied.method === exhausted.method && applied.scope === exhausted.scope) {
|
|
3447
|
+
failed = true;
|
|
3448
|
+
continue;
|
|
3449
|
+
}
|
|
3450
|
+
this.recordNotice(reason, exhausted, applied, "switched", detail);
|
|
3451
|
+
return { outcome: "switched" };
|
|
3452
|
+
}
|
|
3453
|
+
if (!tokenManager || !exhausted) return { outcome: "unavailable" };
|
|
3454
|
+
if (!failed) return { outcome: "not_configured" };
|
|
3455
|
+
this.recordNotice(reason, exhausted, exhausted, "failed", "Replicas could not load an alternate credential.");
|
|
3456
|
+
return { outcome: "failed" };
|
|
3457
|
+
}
|
|
3458
|
+
recordNotice(reason, exhausted, applied, status, detail) {
|
|
3414
3459
|
const payload = {
|
|
3415
3460
|
provider: this.provider,
|
|
3416
3461
|
reason,
|
|
@@ -3418,13 +3463,12 @@ var AuthFallbackCoordinator = class {
|
|
|
3418
3463
|
exhaustedScope: exhausted.scope,
|
|
3419
3464
|
candidateMethod: applied.method,
|
|
3420
3465
|
candidateScope: applied.scope,
|
|
3421
|
-
status
|
|
3422
|
-
detail
|
|
3466
|
+
status,
|
|
3467
|
+
detail
|
|
3423
3468
|
};
|
|
3424
3469
|
const at = (/* @__PURE__ */ new Date()).toISOString();
|
|
3425
3470
|
this.record({ timestamp: at, type: AUTH_FALLBACK_EVENT_TYPE, payload: { ...payload } });
|
|
3426
3471
|
recordCredentialFallback({ ...payload, at });
|
|
3427
|
-
return moved ? "switched" : "failed";
|
|
3428
3472
|
}
|
|
3429
3473
|
};
|
|
3430
3474
|
|
|
@@ -3686,10 +3730,10 @@ var CodingAgentManager = class {
|
|
|
3686
3730
|
this.authFallback = options.provider ? new AuthFallbackCoordinator(options.provider, (event) => {
|
|
3687
3731
|
this.onEvent(event);
|
|
3688
3732
|
this.getHistorySink()?.append(event);
|
|
3689
|
-
}) : null;
|
|
3733
|
+
}, options.fallbackContext ?? (() => ({ excludeProviders: [], forkable: false }))) : null;
|
|
3690
3734
|
}
|
|
3691
3735
|
async fallBackCredential(reason, detail) {
|
|
3692
|
-
if (!this.authFallback) return "unavailable";
|
|
3736
|
+
if (!this.authFallback) return { outcome: "unavailable" };
|
|
3693
3737
|
return this.authFallback.fallBack(reason, detail);
|
|
3694
3738
|
}
|
|
3695
3739
|
onTurnComplete = async () => {
|
|
@@ -5001,14 +5045,14 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
5001
5045
|
const quotaKind = _ClaudeManager.quotaLimitKind(error);
|
|
5002
5046
|
if (quotaKind) {
|
|
5003
5047
|
const detail = error instanceof ClaudeQuotaError ? error.message : extractErrorText(error);
|
|
5004
|
-
const
|
|
5005
|
-
if (outcome === "switched") {
|
|
5048
|
+
const fallback = quotaFallbacks < MAX_QUOTA_FALLBACKS ? await this.fallBackCredential(quotaKind, detail) : { outcome: "unavailable" };
|
|
5049
|
+
if (fallback.outcome === "switched") {
|
|
5006
5050
|
quotaFallbacks++;
|
|
5007
5051
|
await this.tearDownSession();
|
|
5008
5052
|
attempt++;
|
|
5009
5053
|
continue;
|
|
5010
5054
|
}
|
|
5011
|
-
await this.emitQuotaExhaustedEvent(quotaKind,
|
|
5055
|
+
await this.emitQuotaExhaustedEvent(quotaKind, fallback, detail);
|
|
5012
5056
|
return;
|
|
5013
5057
|
}
|
|
5014
5058
|
if (_ClaudeManager.isAuthError(error)) {
|
|
@@ -5119,11 +5163,16 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
5119
5163
|
return "Claude authentication failed after multiple attempts. Check your Claude, Anthropic API key, or Bedrock credentials in Settings \u2192 Agents and try again.";
|
|
5120
5164
|
}
|
|
5121
5165
|
}
|
|
5122
|
-
async emitQuotaExhaustedEvent(kind,
|
|
5166
|
+
async emitQuotaExhaustedEvent(kind, fallback, detail) {
|
|
5123
5167
|
const limit = kind === "out_of_credits" ? "Claude ran out of credits on the credential this workspace is using." : "Claude hit the usage limit on the credential this workspace is using.";
|
|
5124
|
-
const next = outcome === "failed" ? "The
|
|
5168
|
+
const next = fallback.outcome === "fork" ? `Forking this chat to ${getProviderDisplayName(fallback.target.provider, "long")}.` : fallback.outcome === "failed" ? "The next credential in the fallback chain could not be used. Check it in Settings \u2192 Fallbacks and try again." : fallback.outcome === "not_configured" ? "Nothing further is configured in the fallback chain. Add a credential or harness in Settings \u2192 Fallbacks, or try again once the limit resets." : "No other credential is available for this workspace. Check Settings \u2192 Fallbacks, or try again once the limit resets.";
|
|
5125
5169
|
await this.emitTerminalErrorResult(detail, [`${limit} ${next}`]);
|
|
5126
|
-
this.emitQuotaExhausted({
|
|
5170
|
+
this.emitQuotaExhausted({
|
|
5171
|
+
provider: "claude",
|
|
5172
|
+
reason: kind,
|
|
5173
|
+
detail,
|
|
5174
|
+
...fallback.outcome === "fork" ? { forkTo: fallback.target } : {}
|
|
5175
|
+
});
|
|
5127
5176
|
}
|
|
5128
5177
|
async emitMidTurnExhaustedEvent(error) {
|
|
5129
5178
|
const detail = error instanceof Error ? error.message : String(error);
|
|
@@ -7001,11 +7050,11 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
7001
7050
|
let terminalError = error;
|
|
7002
7051
|
if (terminalError instanceof CodexQuotaError && !quotaFallbackAttempted) {
|
|
7003
7052
|
quotaFallbackAttempted = true;
|
|
7004
|
-
const
|
|
7053
|
+
const fallback = await this.fallBackCredential(
|
|
7005
7054
|
detectAgentQuotaLimit(terminalError.message) ?? "rate_limit",
|
|
7006
7055
|
terminalError.message
|
|
7007
7056
|
);
|
|
7008
|
-
if (outcome === "switched") {
|
|
7057
|
+
if (fallback.outcome === "switched") {
|
|
7009
7058
|
attemptedCredential = ENGINE_ENV.REPLICAS_AGENT_CREDENTIALS.codex;
|
|
7010
7059
|
const retryFailure = await this.restartAndRetry(dispatch);
|
|
7011
7060
|
if (!retryFailure) return;
|
|
@@ -7015,7 +7064,8 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
7015
7064
|
this.emitQuotaExhausted({
|
|
7016
7065
|
provider: "codex",
|
|
7017
7066
|
reason: outOfCredits ? "out_of_credits" : detectAgentQuotaLimit(terminalError.message) ?? "rate_limit",
|
|
7018
|
-
detail: terminalError.message
|
|
7067
|
+
detail: terminalError.message,
|
|
7068
|
+
...fallback.outcome === "fork" ? { forkTo: fallback.target } : {}
|
|
7019
7069
|
});
|
|
7020
7070
|
if (outOfCredits) return;
|
|
7021
7071
|
}
|
|
@@ -9782,8 +9832,8 @@ ${pending}
|
|
|
9782
9832
|
} catch (error) {
|
|
9783
9833
|
if (error instanceof MuseQuotaError) {
|
|
9784
9834
|
const quotaKind = detectAgentQuotaLimit(error.message);
|
|
9785
|
-
const
|
|
9786
|
-
if (outcome === "switched") {
|
|
9835
|
+
const fallback = await this.fallBackCredential(quotaKind ?? "rate_limit", error.message);
|
|
9836
|
+
if (fallback.outcome === "switched") {
|
|
9787
9837
|
this.stopProcess();
|
|
9788
9838
|
try {
|
|
9789
9839
|
await dispatch();
|
|
@@ -9794,6 +9844,8 @@ ${pending}
|
|
|
9794
9844
|
}, this.historyFile);
|
|
9795
9845
|
throw retryError;
|
|
9796
9846
|
}
|
|
9847
|
+
} else if (fallback.outcome === "fork") {
|
|
9848
|
+
this.emitQuotaExhausted({ provider: "muse", reason: quotaKind ?? "rate_limit", detail: error.message, forkTo: fallback.target });
|
|
9797
9849
|
}
|
|
9798
9850
|
return;
|
|
9799
9851
|
}
|
|
@@ -10186,7 +10238,7 @@ var OpencodeManager = class extends CodingAgentManager {
|
|
|
10186
10238
|
slashCommandsCache = null;
|
|
10187
10239
|
slashCommandsRequest = null;
|
|
10188
10240
|
constructor(options) {
|
|
10189
|
-
super(options);
|
|
10241
|
+
super({ ...options, provider: "opencode" });
|
|
10190
10242
|
this.sessionId = options.initialSessionId;
|
|
10191
10243
|
this.historyFilePath = options.historyFilePath ?? join22(ENGINE_ENV.HOME_DIR, ".replicas", "opencode", "history.jsonl");
|
|
10192
10244
|
this.historyFile = new CodexHistoryFile(this.historyFilePath);
|
|
@@ -10487,7 +10539,13 @@ var OpencodeManager = class extends CodingAgentManager {
|
|
|
10487
10539
|
this.handledAccountRateLimit = true;
|
|
10488
10540
|
const message = typeof status.message === "string" ? status.message : typeof action.message === "string" ? action.message : "OpenCode Go usage limit reached.";
|
|
10489
10541
|
this.recordHistoryEvent("opencode-error", { message, code: "account_rate_limit" }, this.historyFile);
|
|
10490
|
-
|
|
10542
|
+
const fallback = await this.fallBackCredential("rate_limit", message);
|
|
10543
|
+
this.emitQuotaExhausted({
|
|
10544
|
+
provider: "opencode",
|
|
10545
|
+
reason: "rate_limit",
|
|
10546
|
+
detail: message,
|
|
10547
|
+
...fallback.outcome === "fork" ? { forkTo: fallback.target } : {}
|
|
10548
|
+
});
|
|
10491
10549
|
await this.abortActiveTurn();
|
|
10492
10550
|
}
|
|
10493
10551
|
recordOpencodeMessageRole(payload) {
|
|
@@ -13694,7 +13752,7 @@ var ChatService = class {
|
|
|
13694
13752
|
/** Resolves once the target chat exists; the handoff and its first turn run in the background. */
|
|
13695
13753
|
async forkChat(sourceChatId, request, trigger = "manual", reason) {
|
|
13696
13754
|
const source = this.requireChat(sourceChatId);
|
|
13697
|
-
if (!isAgentAvailable(request.provider)) throw new ChatProviderUnavailableError(request.provider);
|
|
13755
|
+
if (trigger === "manual" && !isAgentAvailable(request.provider)) throw new ChatProviderUnavailableError(request.provider);
|
|
13698
13756
|
const fork = {
|
|
13699
13757
|
source: { chatId: source.persisted.id, provider: source.persisted.provider, title: source.persisted.title },
|
|
13700
13758
|
trigger,
|
|
@@ -13719,6 +13777,7 @@ var ChatService = class {
|
|
|
13719
13777
|
const fork = target?.persisted.fork;
|
|
13720
13778
|
if (!target || !fork) return;
|
|
13721
13779
|
try {
|
|
13780
|
+
if (!isAgentAvailable(request.provider)) throw new ChatProviderUnavailableError(request.provider);
|
|
13722
13781
|
const handoff = await buildForkHandoff({
|
|
13723
13782
|
sourceChatId: fork.source.chatId,
|
|
13724
13783
|
sourceProvider: fork.source.provider,
|
|
@@ -13771,20 +13830,15 @@ var ChatService = class {
|
|
|
13771
13830
|
return providers;
|
|
13772
13831
|
}
|
|
13773
13832
|
async autoForkAfterQuota(chat, exhaustion) {
|
|
13774
|
-
|
|
13833
|
+
const target = exhaustion.forkTo;
|
|
13834
|
+
if (!target || chat.persisted.deletedAt) return;
|
|
13775
13835
|
const alreadyForked = [...this.chats.values()].some((other) => other.persisted.fork?.trigger === "auto" && other.persisted.fork.source.chatId === chat.persisted.id && !other.persisted.deletedAt);
|
|
13776
13836
|
if (alreadyForked) return;
|
|
13777
13837
|
const last = chat.lastSendRequest;
|
|
13778
|
-
const fallback = await monolithService.getChatForkFallback({
|
|
13779
|
-
provider: chat.persisted.provider,
|
|
13780
|
-
exclude: this.forkChainProviders(chat),
|
|
13781
|
-
userId: last?.senderUserId
|
|
13782
|
-
});
|
|
13783
|
-
if (!fallback?.provider || !isAgentAvailable(fallback.provider)) return;
|
|
13784
13838
|
await this.forkChat(chat.persisted.id, {
|
|
13785
|
-
provider:
|
|
13786
|
-
model:
|
|
13787
|
-
thinkingLevel:
|
|
13839
|
+
provider: target.provider,
|
|
13840
|
+
model: target.model,
|
|
13841
|
+
thinkingLevel: target.thinkingLevel,
|
|
13788
13842
|
enableInteractiveTools: last?.enableInteractiveTools,
|
|
13789
13843
|
senderUserId: last?.senderUserId,
|
|
13790
13844
|
senderEmail: last?.senderEmail,
|
|
@@ -13908,6 +13962,15 @@ var ChatService = class {
|
|
|
13908
13962
|
}).catch(() => {
|
|
13909
13963
|
});
|
|
13910
13964
|
};
|
|
13965
|
+
const fallbackContext = () => {
|
|
13966
|
+
const chat = this.chats.get(persisted.id);
|
|
13967
|
+
return {
|
|
13968
|
+
userId: chat?.lastSendRequest?.senderUserId,
|
|
13969
|
+
excludeProviders: chat ? this.forkChainProviders(chat) : [persisted.provider],
|
|
13970
|
+
// A subagent thread is driven by its parent's tool call, which a sibling chat would leave hanging.
|
|
13971
|
+
forkable: (chat?.persisted ?? persisted).parentChatId === null
|
|
13972
|
+
};
|
|
13973
|
+
};
|
|
13911
13974
|
if (persisted.parentChatId === void 0) {
|
|
13912
13975
|
persisted.parentChatId = null;
|
|
13913
13976
|
}
|
|
@@ -13921,7 +13984,8 @@ var ChatService = class {
|
|
|
13921
13984
|
onTurnComplete: onProviderTurnComplete,
|
|
13922
13985
|
onEvent: onProviderEvent,
|
|
13923
13986
|
onProcessingChanged,
|
|
13924
|
-
onMessageStarted
|
|
13987
|
+
onMessageStarted,
|
|
13988
|
+
fallbackContext
|
|
13925
13989
|
});
|
|
13926
13990
|
} else if (persisted.provider === "relay") {
|
|
13927
13991
|
const getProviderAvailability = () => ({
|
|
@@ -14003,6 +14067,7 @@ var ChatService = class {
|
|
|
14003
14067
|
onEvent: onProviderEvent,
|
|
14004
14068
|
onProcessingChanged,
|
|
14005
14069
|
onMessageStarted,
|
|
14070
|
+
fallbackContext,
|
|
14006
14071
|
onUsageUpdate: onProviderUsage
|
|
14007
14072
|
});
|
|
14008
14073
|
} else if (persisted.provider === "opencode") {
|
|
@@ -14015,7 +14080,8 @@ var ChatService = class {
|
|
|
14015
14080
|
onEvent: onProviderEvent,
|
|
14016
14081
|
onProcessingChanged,
|
|
14017
14082
|
onMessageStarted,
|
|
14018
|
-
onUsageUpdate: onProviderUsage
|
|
14083
|
+
onUsageUpdate: onProviderUsage,
|
|
14084
|
+
fallbackContext
|
|
14019
14085
|
});
|
|
14020
14086
|
} else if (persisted.provider === "pi") {
|
|
14021
14087
|
provider = new PiManager({
|
|
@@ -14044,6 +14110,7 @@ var ChatService = class {
|
|
|
14044
14110
|
onEvent: onProviderEvent,
|
|
14045
14111
|
onProcessingChanged,
|
|
14046
14112
|
onMessageStarted,
|
|
14113
|
+
fallbackContext,
|
|
14047
14114
|
onCodexTurnStarted: codexTokenUsage.onTurnStarted,
|
|
14048
14115
|
onCodexTokenUsage: codexTokenUsage.onTokenUsage,
|
|
14049
14116
|
onCodexModelRerouted: codexTokenUsage.onModelRerouted,
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
notifyPostToolUse
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-AQXSBHCI.js";
|
|
5
5
|
import {
|
|
6
6
|
isRecord
|
|
7
7
|
} from "./chunk-2RB7SIP3.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-NQFMLRS4.js";
|
|
9
9
|
|
|
10
10
|
// src/post-tool-pr-hook.ts
|
|
11
11
|
async function main() {
|