@nowcrew/daemon 0.6.79 → 0.6.80-beta.1
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/agent-ability/resolver.js +7 -10
- package/dist/execution-protocol.js +0 -1
- package/dist/execution-runner.js +3 -9
- package/dist/local-execution-prompt.js +2 -3
- package/dist/local-executor.js +35 -59
- package/dist/machine-info.js +0 -3
- package/dist/main.js +0 -0
- package/dist/package-manager-env.js +75 -0
- package/dist/provider-env.js +3 -21
- package/dist/runner.js +1 -1
- package/dist/runtime-env.js +21 -0
- package/dist/runtimes/codex-app-server-runner.js +1 -9
- package/dist/runtimes/codex-deepseek-config.js +7 -17
- package/dist/runtimes/codex.js +0 -3
- package/dist/supervised-runtime.js +0 -1
- package/dist/workspace.js +10 -13
- package/package.json +10 -9
- package/dist/project-skills/capability.js +0 -109
- package/dist/project-skills/controller-convergence.js +0 -57
- package/dist/project-skills/projection-set-switch.js +0 -419
- package/dist/project-skills/projection-state-domain.js +0 -170
- package/dist/project-skills/projection-state-store.js +0 -842
- package/dist/project-skills/projection-state-transaction.js +0 -322
- package/dist/project-skills/projection-state.js +0 -3
- package/dist/project-skills/runtime-root-bootstrap.js +0 -53
- package/dist/project-skills/runtime-root-domain.js +0 -268
- package/dist/project-skills/runtime-root-gc.js +0 -293
- package/dist/project-skills/runtime-root-lease-artifact.js +0 -46
- package/dist/project-skills/runtime-root-leases.js +0 -487
- package/dist/project-skills/runtime-root-source-identity.js +0 -60
- package/dist/project-skills/runtime-root-startup.js +0 -50
- package/dist/project-skills/runtime-root-state-artifact-domain.js +0 -143
- package/dist/project-skills/runtime-root-state-index.js +0 -356
- package/dist/project-skills/runtime-root-store.js +0 -722
- package/dist/project-skills/serve-capability.js +0 -28
- package/dist/project-skills/serve-startup.js +0 -60
- package/dist/self-training-workspace.js +0 -15
|
@@ -10,8 +10,8 @@ import { PROJECT_MANIFEST_SOURCE_PATH, ProjectDependencyManifestSchema, } from "
|
|
|
10
10
|
import { normalizeRepositoryIdentity } from "../repository-identity.js";
|
|
11
11
|
const runFile = promisify(execFile);
|
|
12
12
|
const MAX_FILES = 5_000;
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
const MAX_TOTAL_BYTES = 25 * 1024 * 1024;
|
|
14
|
+
const MAX_FILE_BYTES = 2 * 1024 * 1024;
|
|
15
15
|
const MAX_INSTRUCTIONS_BYTES = 96 * 1024;
|
|
16
16
|
const MAX_MEMORY_BYTES = 64 * 1024;
|
|
17
17
|
const AUTHORING_ONLY_ROOTS = new Set([".claude"]);
|
|
@@ -125,11 +125,10 @@ export const collectAbilityFiles = async (root) => {
|
|
|
125
125
|
if (info.isDirectory())
|
|
126
126
|
await visit(absolute);
|
|
127
127
|
else if (info.isFile()) {
|
|
128
|
-
if (info.size >
|
|
128
|
+
if (info.size > MAX_FILE_BYTES)
|
|
129
129
|
throw new Error(`ability_file_size_exceeded:${relative(root, absolute)}`);
|
|
130
|
-
}
|
|
131
130
|
totalBytes += info.size;
|
|
132
|
-
if (totalBytes >
|
|
131
|
+
if (totalBytes > MAX_TOTAL_BYTES)
|
|
133
132
|
throw new Error("ability_total_size_exceeded");
|
|
134
133
|
if (files.length >= MAX_FILES)
|
|
135
134
|
throw new Error("ability_file_count_exceeded");
|
|
@@ -263,7 +262,7 @@ export const validateAbilityDependencyDeclarations = (manifest, lock) => {
|
|
|
263
262
|
throw new Error("ability_lock_has_undeclared_dependency");
|
|
264
263
|
}
|
|
265
264
|
};
|
|
266
|
-
|
|
265
|
+
const scan = (files, manifest) => {
|
|
267
266
|
const findings = [];
|
|
268
267
|
const secrets = [
|
|
269
268
|
/-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/u,
|
|
@@ -271,9 +270,7 @@ export const scanAbilityFiles = (files, manifest) => {
|
|
|
271
270
|
/\bAK(?:ID|IA)[A-Z0-9]{12,}\b/u,
|
|
272
271
|
];
|
|
273
272
|
const executable = new Set([".exe", ".dll", ".dylib", ".so", ".bin", ".class", ".jar"]);
|
|
274
|
-
const allowedBinaryDocuments = new Set([
|
|
275
|
-
".pdf", ".png", ".jpg", ".jpeg", ".gif", ".webp", ".xlsx", ".xls", ".docx", ".pptx", ".ttf", ".otf",
|
|
276
|
-
]);
|
|
273
|
+
const allowedBinaryDocuments = new Set([".pdf", ".png", ".jpg", ".jpeg", ".gif", ".webp", ".xlsx", ".xls", ".docx", ".pptx"]);
|
|
277
274
|
for (const file of files) {
|
|
278
275
|
let text;
|
|
279
276
|
try {
|
|
@@ -399,7 +396,7 @@ export async function resolveAbilityRelease(agentsRoot, command) {
|
|
|
399
396
|
}
|
|
400
397
|
const externalPaths = await verifyExternalDependencies(cacheRoot, resolved.root, lock);
|
|
401
398
|
files = await collectAbilityFiles(resolved.root);
|
|
402
|
-
const security =
|
|
399
|
+
const security = scan(files, manifest);
|
|
403
400
|
const kinds = new Set(lock.assets.map((asset) => asset.kind));
|
|
404
401
|
const memory = [];
|
|
405
402
|
for (const [layer, mounts] of [["release-policy", manifest.spec.memory.policy], ["release-seed", manifest.spec.memory.seeds]]) {
|
|
@@ -200,7 +200,6 @@ export const ExecutionStartSchema = z.object({
|
|
|
200
200
|
language: z.enum(["zh", "en"]),
|
|
201
201
|
systemPrompt: z.string(),
|
|
202
202
|
wakePrompt: z.string(),
|
|
203
|
-
maintenancePurpose: z.literal("self_training").optional(),
|
|
204
203
|
}).strict(),
|
|
205
204
|
runtime: z.object({
|
|
206
205
|
name: RuntimeSchema,
|
package/dist/execution-runner.js
CHANGED
|
@@ -567,9 +567,8 @@ export async function runExecution(config, input, dependencies) {
|
|
|
567
567
|
projectContext = await cancellable(resolveProjectContext(projectSnapshot, projectWorkspaceRegistry), dependencies.cancellation);
|
|
568
568
|
sessionContextFingerprint = projectSessionContextFingerprint(spec.runtime.name, projectSnapshot);
|
|
569
569
|
}
|
|
570
|
-
const selfTraining = spec.instructions.maintenancePurpose === "self_training";
|
|
571
570
|
let recalledMemory = "";
|
|
572
|
-
if (
|
|
571
|
+
if (spec.agent.memoryEnabled === true && dependencies.agentMemory !== undefined) {
|
|
573
572
|
try {
|
|
574
573
|
recalledMemory = await cancellable(dependencies.agentMemory.recall(spec.agent.handle, spec.instructions.wakePrompt, spec.executionId, spec.agent.memoryAgentId ?? null), dependencies.cancellation);
|
|
575
574
|
}
|
|
@@ -828,10 +827,7 @@ export async function runExecution(config, input, dependencies) {
|
|
|
828
827
|
const baseSystemPromptBudget = spec.agent.abilityRelease === undefined
|
|
829
828
|
? systemPromptBudget
|
|
830
829
|
: Math.max(0, Math.min(systemPromptBudget, Math.max(32 * 1024, systemPromptBudget - 168 * 1024)));
|
|
831
|
-
const systemPromptWithLocalFacts = withLocalExecutionFacts(spec.instructions.systemPrompt, baseSystemPromptBudget, {
|
|
832
|
-
...(selfTraining ? { isolateLocalMemory: true } : {}),
|
|
833
|
-
collaborationTools: config.codexCollaborationTools && spec.runtime.name === "codex",
|
|
834
|
-
});
|
|
830
|
+
const systemPromptWithLocalFacts = withLocalExecutionFacts(spec.instructions.systemPrompt, baseSystemPromptBudget, { collaborationTools: config.codexCollaborationTools && spec.runtime.name === "codex" });
|
|
835
831
|
const boundedSystemPrompt = (context) => appendAgentMemoryContext(typeof systemPromptWithLocalFacts === "string"
|
|
836
832
|
? systemPromptWithLocalFacts
|
|
837
833
|
: systemPromptWithLocalFacts(context), recalledMemory, baseSystemPromptBudget);
|
|
@@ -880,13 +876,12 @@ export async function runExecution(config, input, dependencies) {
|
|
|
880
876
|
} : {}),
|
|
881
877
|
},
|
|
882
878
|
session: {
|
|
883
|
-
enabled:
|
|
879
|
+
enabled: config.resume,
|
|
884
880
|
warmMs: config.resumeWarmMs,
|
|
885
881
|
budgetTokens: config.sessionBudgetTokens,
|
|
886
882
|
softTokens: config.sessionSoftTokens,
|
|
887
883
|
maxTurns: config.sessionMaxTurns,
|
|
888
884
|
},
|
|
889
|
-
...(selfTraining ? { maintenancePurpose: "self_training" } : {}),
|
|
890
885
|
localMemoryV2Enabled: config.localMemoryV2Handles?.has(spec.agent.handle) === true,
|
|
891
886
|
};
|
|
892
887
|
const result = await Promise.race([
|
|
@@ -1053,7 +1048,6 @@ export async function runExecution(config, input, dependencies) {
|
|
|
1053
1048
|
}
|
|
1054
1049
|
await dependencies.journal.complete(spec.executionId, completion);
|
|
1055
1050
|
if (completion.outcome === "succeeded"
|
|
1056
|
-
&& spec.instructions.maintenancePurpose !== "self_training"
|
|
1057
1051
|
&& spec.agent.memoryEnabled === true
|
|
1058
1052
|
&& memoryCaptureFinalText !== null
|
|
1059
1053
|
&& dependencies.agentMemory !== undefined) {
|
|
@@ -47,13 +47,12 @@ function takeCompletePromptSections(sections, maxBytes) {
|
|
|
47
47
|
/** v1 server instructions opt in to daemon-owned paths and bounded local workspace context. */
|
|
48
48
|
export function withLocalExecutionFacts(serverPrompt, maxBytes, options = {}) {
|
|
49
49
|
return ({ workspace, resuming, projectContext, trainingProjectContext }) => {
|
|
50
|
-
const memory =
|
|
50
|
+
const memory = capMemoryForInject(workspace.memory);
|
|
51
51
|
const workLog = resuming ? "" : capWorkLogForInject(workspace.workLog);
|
|
52
52
|
const collaborationPrompt = options.collaborationTools === true ? buildCollaborationToolsPrompt() : "";
|
|
53
53
|
const mandatoryWorkspacePrompt = `${buildRuntimeWorkspacePrompt(projectContext)}${buildTrainingGitProjectPrompt(trainingProjectContext)}`;
|
|
54
|
-
const crewHome = options.isolateLocalMemory ? workspace.runDir : workspace.dir;
|
|
55
54
|
const localFactSections = [`\n\n## Local execution facts
|
|
56
|
-
- $CREW_HOME: ${
|
|
55
|
+
- $CREW_HOME: ${workspace.dir}
|
|
57
56
|
- $CREW_TASK_LOG: ${workspace.workLogPath}`,
|
|
58
57
|
...(memory ? [`\n\n## Injected MEMORY.md (bounded local context)\n${memory}`] : []),
|
|
59
58
|
...(workLog ? [`\n\n## Injected work-log (bounded local context)\n${workLog}`] : []),
|
package/dist/local-executor.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { createInterface } from "node:readline";
|
|
2
2
|
import { readFile, rm, writeFile } from "node:fs/promises";
|
|
3
3
|
import { delimiter, join } from "node:path";
|
|
4
|
-
import { cleanupSelfTrainingRunDir } from "./self-training-workspace.js";
|
|
5
4
|
import { prepareWorkspace, rotateAgentSession, safeKey, } from "./workspace.js";
|
|
6
5
|
import { CLAUDE_ADDITIONAL_DIRECTORY_INSTRUCTIONS_ENV, isClaudeAdditionalDirectoryInstructionsSupported, probeClaudeVersion, spawnClaude, } from "./runtimes/claude.js";
|
|
7
6
|
import { spawnCodex } from "./runtimes/codex.js";
|
|
@@ -9,7 +8,7 @@ import { DEEPSEEK_CODEX_MODEL, DEEPSEEK_CODEX_REASONING_LEVELS, materializeDeepS
|
|
|
9
8
|
import { materializeDefaultCodexHome } from "./runtimes/codex-home.js";
|
|
10
9
|
import { materializePrivateCodexHome } from "./codex-home-launch.js";
|
|
11
10
|
import { spawnKimi, KIMI_EFFORT_LEVELS } from "./runtimes/kimi.js";
|
|
12
|
-
import { applyDeepSeekHarnessMachineEnv, applyProviderEnv, providerFingerprint,
|
|
11
|
+
import { applyDeepSeekHarnessMachineEnv, applyProviderEnv, providerFingerprint, } from "./provider-env.js";
|
|
13
12
|
import { augmentedPath } from "./runtime-path.js";
|
|
14
13
|
import { extractFinalText, extractRunMeta, normalizeEvent, parseLine, } from "./normalize.js";
|
|
15
14
|
import { readSession, writeSession, pickResumeId, isNearBudget } from "./session.js";
|
|
@@ -33,6 +32,8 @@ import { diffMemoryPruneNotes, evaluateMemoryPrunePostcondition, inspectMemoryPr
|
|
|
33
32
|
import { createLocalMemoryTelemetry, logLocalMemoryContextPrepareFailure, logLocalMemoryDiagnosticsFailure, } from "./local-memory-telemetry.js";
|
|
34
33
|
import { CodexStartupStageParser } from "./codex-startup-stage.js";
|
|
35
34
|
import { formatRuntimeStartupError } from "./runtime-startup-error.js";
|
|
35
|
+
import { machinePackageManagerEnv, packageManagerEnvFacts } from "./package-manager-env.js";
|
|
36
|
+
import { sanitizeEnvVars } from "./runtime-env.js";
|
|
36
37
|
import { commitLocalMemoryResultAfterExit, initializeLocalMemoryV2ForWorkspace, isLocalMemoryV2Eligible, localMemoryResultPath as makeLocalMemoryResultPath, renderLocalMemoryResultInstructions, } from "./local-memory/runtime.js";
|
|
37
38
|
export class RuntimeRunningCallbackTimeoutError extends Error {
|
|
38
39
|
constructor(runtime, timeoutMs) {
|
|
@@ -50,15 +51,6 @@ const MEMORY_PRUNE_DIAGNOSTICS_TIMEOUT_MS = 2_000;
|
|
|
50
51
|
const LOCAL_MEMORY_DIAGNOSTICS_TIMEOUT_MS = 250;
|
|
51
52
|
const CLAUDE_INSTRUCTION_WARNING = "claude_additional_directory_instructions_unverified";
|
|
52
53
|
const CODEX_COLLABORATION_EXEC_WARNING = "codex_collaboration_disabled_on_exec";
|
|
53
|
-
const ENV_KEY_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
54
|
-
const RESERVED_ENV = new Set([
|
|
55
|
-
"PATH",
|
|
56
|
-
"XDG_CONFIG_HOME",
|
|
57
|
-
"XDG_DATA_HOME",
|
|
58
|
-
"XDG_CACHE_HOME",
|
|
59
|
-
"GH_CONFIG_DIR",
|
|
60
|
-
"CLOUDSDK_CONFIG",
|
|
61
|
-
]);
|
|
62
54
|
function withoutClaudeInstructionFlag(env) {
|
|
63
55
|
if (!(CLAUDE_ADDITIONAL_DIRECTORY_INSTRUCTIONS_ENV in env))
|
|
64
56
|
return env;
|
|
@@ -119,7 +111,6 @@ async function launchLegacyRuntime(request) {
|
|
|
119
111
|
effectivePermission: request.effectivePermission,
|
|
120
112
|
...(request.model === undefined ? {} : { model: request.model }),
|
|
121
113
|
...(request.reasoning === undefined ? {} : { reasoning: request.reasoning }),
|
|
122
|
-
...(request.networkAccess === undefined ? {} : { networkAccess: request.networkAccess }),
|
|
123
114
|
};
|
|
124
115
|
if (request.runtime === "claude") {
|
|
125
116
|
const additionalDirectories = request.claudeAdditionalDirectories
|
|
@@ -209,7 +200,6 @@ export async function executeLocal(input, callbacks = {}, dependencies = {}) {
|
|
|
209
200
|
async function executeLocalUnlocked(input, callbacks, dependencies) {
|
|
210
201
|
const providerConfig = input.launch.providerConfig ?? {};
|
|
211
202
|
const { runtime } = input;
|
|
212
|
-
const isolatedMaintenance = input.maintenancePurpose === "self_training";
|
|
213
203
|
const isDeepSeekCodex = runtime.name === "codex" && providerConfig.provider === "deepseek";
|
|
214
204
|
const currentModel = isDeepSeekCodex ? DEEPSEEK_CODEX_MODEL : runtime.model ?? null;
|
|
215
205
|
const launchModel = isDeepSeekCodex ? DEEPSEEK_CODEX_MODEL : runtime.model;
|
|
@@ -234,7 +224,6 @@ async function executeLocalUnlocked(input, callbacks, dependencies) {
|
|
|
234
224
|
? {}
|
|
235
225
|
: { sessionContextFingerprint: input.sessionContextFingerprint }),
|
|
236
226
|
...(input.launch.description ? { description: input.launch.description } : {}),
|
|
237
|
-
...(isolatedMaintenance ? { skipLocalMemory: true } : {}),
|
|
238
227
|
}), dependencies.cancellation);
|
|
239
228
|
}
|
|
240
229
|
catch (error) {
|
|
@@ -265,23 +254,12 @@ async function executeLocalUnlocked(input, callbacks, dependencies) {
|
|
|
265
254
|
}
|
|
266
255
|
const sourceCodexHome = inheritedEnv.CODEX_HOME
|
|
267
256
|
?? (inheritedEnv.HOME === undefined ? undefined : join(inheritedEnv.HOME, ".codex"));
|
|
268
|
-
let materializedDeepSeekHome;
|
|
269
257
|
try {
|
|
270
258
|
if (isDeepSeekCodex && !providerConfig.providerApiKey) {
|
|
271
259
|
throw new Error("DeepSeek API key is not configured for this Agent");
|
|
272
260
|
}
|
|
273
261
|
if (isDeepSeekCodex) {
|
|
274
|
-
|
|
275
|
-
? new URL(providerConfig.providerBaseUrl, input.launch.serverUrl).toString()
|
|
276
|
-
: undefined;
|
|
277
|
-
const materialize = dependencies.materializeDeepSeekCodexHome ?? materializeDeepSeekCodexHome;
|
|
278
|
-
const materializeOptions = {
|
|
279
|
-
...(providerBaseUrl === undefined ? {} : { baseUrl: providerBaseUrl }),
|
|
280
|
-
...(isolatedMaintenance ? { selfTraining: true } : {}),
|
|
281
|
-
};
|
|
282
|
-
materializedDeepSeekHome = await awaitWithCancellation(providerBaseUrl === undefined && !isolatedMaintenance
|
|
283
|
-
? materialize(workspace.homeDir)
|
|
284
|
-
: materialize(workspace.homeDir, materializeOptions), dependencies.cancellation);
|
|
262
|
+
await awaitWithCancellation((dependencies.materializeDeepSeekCodexHome ?? materializeDeepSeekCodexHome)(workspace.homeDir), dependencies.cancellation);
|
|
285
263
|
}
|
|
286
264
|
const supportsNativeResume = runtime.name === "claude"
|
|
287
265
|
|| (dependencies.launchRuntime !== undefined && runtimeCapability(runtime.name).nativeResume);
|
|
@@ -409,30 +387,29 @@ async function executeLocalUnlocked(input, callbacks, dependencies) {
|
|
|
409
387
|
const systemPrompt = localMemoryResultPath === null
|
|
410
388
|
? baseSystemPrompt
|
|
411
389
|
: `${baseSystemPrompt}${structuredMemoryInstructions ?? ""}`;
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
}
|
|
390
|
+
try {
|
|
391
|
+
localMemoryTelemetry = createLocalMemoryTelemetry({
|
|
392
|
+
executionId: input.executionId,
|
|
393
|
+
agentHandle: input.handle,
|
|
394
|
+
...(input.taskKey === undefined ? {} : { taskKey: input.taskKey }),
|
|
395
|
+
runtime: runtime.name,
|
|
396
|
+
stableProtocolRuntime: dependencies.launchRuntime !== undefined,
|
|
397
|
+
agentDir: executionWorkspace.dir,
|
|
398
|
+
runDir: executionWorkspace.runDir,
|
|
399
|
+
isMemoryPrune: memoryPruneTraceId !== null,
|
|
400
|
+
diagnosticsTimeoutMs: dependencies.localMemoryDiagnosticsTimeoutMs
|
|
401
|
+
?? LOCAL_MEMORY_DIAGNOSTICS_TIMEOUT_MS,
|
|
402
|
+
});
|
|
403
|
+
await localMemoryTelemetry.captureBefore();
|
|
404
|
+
}
|
|
405
|
+
catch (error) {
|
|
406
|
+
localMemoryTelemetry = null;
|
|
407
|
+
logLocalMemoryDiagnosticsFailure({
|
|
408
|
+
executionId: input.executionId,
|
|
409
|
+
agentHandle: input.handle,
|
|
410
|
+
...(input.taskKey === undefined ? {} : { taskKey: input.taskKey }),
|
|
411
|
+
}, "initialize", error);
|
|
412
|
+
}
|
|
436
413
|
if (memoryPruneTraceId !== null) {
|
|
437
414
|
memoryPruneSharedWriteKey = JSON.stringify([input.launch.agentsRoot, input.handle]);
|
|
438
415
|
const activePruneCount = (activeMemoryPrunes.get(memoryPruneSharedWriteKey) ?? 0) + 1;
|
|
@@ -466,16 +443,18 @@ async function executeLocalUnlocked(input, callbacks, dependencies) {
|
|
|
466
443
|
}
|
|
467
444
|
}
|
|
468
445
|
memoryPruneFailurePhase = "runtime_prepare";
|
|
469
|
-
const crewHome = isolatedMaintenance ? executionWorkspace.runDir : workspace.dir;
|
|
470
446
|
const baseEnv = {
|
|
471
447
|
...inheritedEnv,
|
|
472
448
|
...sanitizeEnvVars(providerConfig.envVars),
|
|
449
|
+
...(input.trainingProjectContext === undefined
|
|
450
|
+
? {}
|
|
451
|
+
: machinePackageManagerEnv(inheritedEnv)),
|
|
473
452
|
...input.launch.systemEnv,
|
|
474
453
|
PATH: `${workspace.crewDir}${delimiter}${augmentedPath()}`,
|
|
475
454
|
CREW_SERVER_URL: input.launch.serverUrl,
|
|
476
455
|
CREW_TOKEN: input.launch.token,
|
|
477
456
|
CREW_CHANNEL: input.channelId,
|
|
478
|
-
CREW_HOME:
|
|
457
|
+
CREW_HOME: workspace.dir,
|
|
479
458
|
// Keep the daemon-selected storage root authoritative for runtimes.
|
|
480
459
|
// In profile-backed NowWork sessions the daemon config may differ from
|
|
481
460
|
// the daemon process environment, so inheriting CREW_AGENTS_ROOT is not
|
|
@@ -485,7 +464,7 @@ async function executeLocalUnlocked(input, callbacks, dependencies) {
|
|
|
485
464
|
...(input.launch.qaReportRoot === undefined ? {} : { QA_REPORT_HUB: input.launch.qaReportRoot }),
|
|
486
465
|
// Expose only the training root; ability-specific workspace layout stays
|
|
487
466
|
// owned by the training package rather than the NowWork daemon.
|
|
488
|
-
QA_RUNTIME_ROOT: join(
|
|
467
|
+
QA_RUNTIME_ROOT: join(workspace.dir, "training"),
|
|
489
468
|
CREW_TASK_DIR: executionWorkspace.runDir,
|
|
490
469
|
CREW_TASK_LOG: executionWorkspace.workLogPath,
|
|
491
470
|
...(input.wakeMessageId ? { CREW_WAKE_MESSAGE_ID: input.wakeMessageId } : {}),
|
|
@@ -501,7 +480,7 @@ async function executeLocalUnlocked(input, callbacks, dependencies) {
|
|
|
501
480
|
};
|
|
502
481
|
const providerEnv = applyProviderEnv(baseEnv, runtime.name, input.launch.codexHomeMode === undefined
|
|
503
482
|
? providerConfig
|
|
504
|
-
: { ...providerConfig, codexHomeMode: input.launch.codexHomeMode }, workspace.homeDir
|
|
483
|
+
: { ...providerConfig, codexHomeMode: input.launch.codexHomeMode }, workspace.homeDir);
|
|
505
484
|
const childEnv = runtime.name === "deepseek-harness"
|
|
506
485
|
? applyDeepSeekHarnessMachineEnv(providerEnv, inheritedEnv)
|
|
507
486
|
: providerEnv;
|
|
@@ -512,7 +491,8 @@ async function executeLocalUnlocked(input, callbacks, dependencies) {
|
|
|
512
491
|
qa_runtime_root: childEnv.QA_RUNTIME_ROOT ?? null,
|
|
513
492
|
qa_runtime_root_present: childEnv.QA_RUNTIME_ROOT !== undefined,
|
|
514
493
|
inherited_qa_runtime_root_present: inheritedEnv.QA_RUNTIME_ROOT !== undefined,
|
|
515
|
-
|
|
494
|
+
...packageManagerEnvFacts(childEnv),
|
|
495
|
+
training_root: join(workspace.dir, "training"),
|
|
516
496
|
project_context_present: input.projectContext !== undefined,
|
|
517
497
|
project_ids: JSON.stringify(input.projectContext === undefined
|
|
518
498
|
? []
|
|
@@ -644,7 +624,6 @@ async function executeLocalUnlocked(input, callbacks, dependencies) {
|
|
|
644
624
|
...(input.projectContext === undefined ? {} : {
|
|
645
625
|
projectContext: input.projectContext,
|
|
646
626
|
}),
|
|
647
|
-
...(isolatedMaintenance && runtime.name === "codex" ? { networkAccess: true } : {}),
|
|
648
627
|
...(input.projectContext === undefined && workspaceRoots.length === 0
|
|
649
628
|
? {}
|
|
650
629
|
: { workspaceRoots: Object.freeze(workspaceRoots) }),
|
|
@@ -1128,8 +1107,5 @@ async function executeLocalUnlocked(input, callbacks, dependencies) {
|
|
|
1128
1107
|
const detail = error instanceof Error ? error.message : String(error);
|
|
1129
1108
|
process.stderr.write(`[execution] failed to remove prompt ${workspace.systemPromptPath}: ${detail}\n`);
|
|
1130
1109
|
}
|
|
1131
|
-
if (isolatedMaintenance) {
|
|
1132
|
-
await cleanupSelfTrainingRunDir(join(workspace.dir, "tasks"), executionWorkspace.runDir);
|
|
1133
|
-
}
|
|
1134
1110
|
}
|
|
1135
1111
|
}
|
package/dist/machine-info.js
CHANGED
|
@@ -25,9 +25,7 @@ export { executableRuntimes } from "./runtime-capabilities.js";
|
|
|
25
25
|
const execFileP = promisify(execFile);
|
|
26
26
|
export const PROJECT_WORKSPACES_CAPABILITY = "project_workspaces_v1";
|
|
27
27
|
export const TRAINING_PROJECT_DEPENDENCIES_CAPABILITY = "training_project_dependencies_v1";
|
|
28
|
-
export const SELF_TRAINING_EXECUTION_CAPABILITY = "self_training_execution_v1";
|
|
29
28
|
export const EXECUTION_LARGE_ATTACHMENTS_CAPABILITY = "execution_attachments_300m_v1";
|
|
30
|
-
export const PROJECT_SKILL_PROJECTION_CAPABILITY = "project_skill_projection_v2";
|
|
31
29
|
export const NATIVE_PROJECT_WORKSPACE_READINESS = Object.freeze({
|
|
32
30
|
resolverReady: true,
|
|
33
31
|
nativeRuntimeAdaptersReady: true,
|
|
@@ -44,7 +42,6 @@ export const DAEMON_CAPABILITIES = Object.freeze([
|
|
|
44
42
|
"execution_machine_queue_v1",
|
|
45
43
|
"execution_agent_memory_policy_v1",
|
|
46
44
|
"execution_agent_memory_mapping_v1",
|
|
47
|
-
SELF_TRAINING_EXECUTION_CAPABILITY,
|
|
48
45
|
"project_skills_v1",
|
|
49
46
|
"project_skill_projection_v2",
|
|
50
47
|
PROJECT_WORKSPACES_CAPABILITY,
|
package/dist/main.js
CHANGED
|
File without changes
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
function nonEmpty(value) {
|
|
3
|
+
const normalized = value?.trim();
|
|
4
|
+
return normalized === undefined || normalized === "" ? undefined : normalized;
|
|
5
|
+
}
|
|
6
|
+
function registryUrl(value) {
|
|
7
|
+
const normalized = nonEmpty(value);
|
|
8
|
+
if (normalized === undefined)
|
|
9
|
+
return undefined;
|
|
10
|
+
try {
|
|
11
|
+
const protocol = new URL(normalized).protocol;
|
|
12
|
+
return protocol === "http:" || protocol === "https:" ? normalized : undefined;
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function configuredPath(env) {
|
|
19
|
+
const explicit = env.CREW_PACKAGE_MANAGER_USERCONFIG?.trim();
|
|
20
|
+
if (explicit !== undefined && explicit !== "")
|
|
21
|
+
return explicit;
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
function registryFromNpmrc(path) {
|
|
25
|
+
if (path === undefined)
|
|
26
|
+
return undefined;
|
|
27
|
+
try {
|
|
28
|
+
const line = readFileSync(path, "utf8")
|
|
29
|
+
.split(/\r?\n/u)
|
|
30
|
+
.find((entry) => /^\s*registry\s*=/u.test(entry));
|
|
31
|
+
return registryUrl(line?.replace(/^\s*registry\s*=\s*/u, ""));
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function npmrcHasAuth(path) {
|
|
38
|
+
if (path === undefined)
|
|
39
|
+
return false;
|
|
40
|
+
try {
|
|
41
|
+
return /^\s*(?:(?:\/\/[^=\s]+:)?_(?:auth|authToken|password))\s*=/imu.test(readFileSync(path, "utf8"));
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Keep machine-owned npm credentials available for explicitly authorized
|
|
49
|
+
* training dependency installs. The daemon must opt in with
|
|
50
|
+
* CREW_PACKAGE_MANAGER_USERCONFIG; Agent env cannot reach this path.
|
|
51
|
+
*/
|
|
52
|
+
export function machinePackageManagerEnv(env = process.env) {
|
|
53
|
+
const npmUserConfig = configuredPath(env);
|
|
54
|
+
const yarnRegistry = npmUserConfig === undefined
|
|
55
|
+
? undefined
|
|
56
|
+
: registryUrl(env.YARN_REGISTRY) ?? registryFromNpmrc(npmUserConfig);
|
|
57
|
+
const entries = npmUserConfig === undefined
|
|
58
|
+
? []
|
|
59
|
+
: [["NPM_CONFIG_USERCONFIG", npmUserConfig]];
|
|
60
|
+
const alwaysAuth = npmrcHasAuth(npmUserConfig) ? "true" : undefined;
|
|
61
|
+
return Object.fromEntries(yarnRegistry === undefined && alwaysAuth === undefined
|
|
62
|
+
? entries
|
|
63
|
+
: [
|
|
64
|
+
...entries,
|
|
65
|
+
...(yarnRegistry === undefined ? [] : [["YARN_REGISTRY", yarnRegistry]]),
|
|
66
|
+
...(alwaysAuth === undefined ? [] : [["NPM_CONFIG_ALWAYS_AUTH", alwaysAuth]]),
|
|
67
|
+
]);
|
|
68
|
+
}
|
|
69
|
+
export function packageManagerEnvFacts(env) {
|
|
70
|
+
return {
|
|
71
|
+
npm_userconfig_present: Boolean(env.NPM_CONFIG_USERCONFIG?.trim()),
|
|
72
|
+
yarn_registry_present: Boolean(env.YARN_REGISTRY?.trim()),
|
|
73
|
+
npm_always_auth_present: Boolean(env.NPM_CONFIG_ALWAYS_AUTH?.trim()),
|
|
74
|
+
};
|
|
75
|
+
}
|
package/dist/provider-env.js
CHANGED
|
@@ -11,24 +11,6 @@
|
|
|
11
11
|
import { join } from "node:path";
|
|
12
12
|
import { DEEPSEEK_CODEX_KEY_ENV, deepSeekCodexHome, } from "./runtimes/codex-deepseek-config.js";
|
|
13
13
|
import { DEEPSEEK_HARNESS_CONFIG_ENV } from "./runtimes/deepseek-harness.js";
|
|
14
|
-
const ENV_KEY_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
15
|
-
const RESERVED_ENV = new Set([
|
|
16
|
-
"PATH",
|
|
17
|
-
"XDG_CONFIG_HOME",
|
|
18
|
-
"XDG_DATA_HOME",
|
|
19
|
-
"XDG_CACHE_HOME",
|
|
20
|
-
"GH_CONFIG_DIR",
|
|
21
|
-
"CLOUDSDK_CONFIG",
|
|
22
|
-
]);
|
|
23
|
-
/** Keep user-provided variables away from daemon-owned runtime and credential fields. */
|
|
24
|
-
export function sanitizeEnvVars(raw) {
|
|
25
|
-
if (!raw)
|
|
26
|
-
return {};
|
|
27
|
-
return Object.fromEntries(Object.entries(raw).filter(([key, value]) => typeof value === "string"
|
|
28
|
-
&& ENV_KEY_RE.test(key)
|
|
29
|
-
&& !key.toUpperCase().startsWith("CREW_")
|
|
30
|
-
&& !RESERVED_ENV.has(key.toUpperCase())));
|
|
31
|
-
}
|
|
32
14
|
/** custom 模式下必须从继承 env 中剔除的全局路由/凭证变量(避免与注入值叠加或抢优先级)。 */
|
|
33
15
|
const CONFLICTING_ENV = [
|
|
34
16
|
"ANTHROPIC_BASE_URL",
|
|
@@ -57,12 +39,12 @@ const CONFLICTING_CODEX_ENV = [
|
|
|
57
39
|
DEEPSEEK_CODEX_KEY_ENV,
|
|
58
40
|
];
|
|
59
41
|
/** 返回叠加了 provider 隔离的新 env(不改入参);不支持的 runtime/provider 组合原样返回。 */
|
|
60
|
-
export function applyProviderEnv(base, runtime, cfg, homeDir
|
|
42
|
+
export function applyProviderEnv(base, runtime, cfg, homeDir) {
|
|
61
43
|
if (runtime === "codex" && cfg.provider === "deepseek") {
|
|
62
44
|
const env = { ...base };
|
|
63
45
|
for (const key of CONFLICTING_CODEX_ENV)
|
|
64
46
|
delete env[key];
|
|
65
|
-
env.CODEX_HOME =
|
|
47
|
+
env.CODEX_HOME = deepSeekCodexHome(homeDir);
|
|
66
48
|
if (cfg.providerApiKey)
|
|
67
49
|
env[DEEPSEEK_CODEX_KEY_ENV] = cfg.providerApiKey;
|
|
68
50
|
return env;
|
|
@@ -118,7 +100,7 @@ export function applyDeepSeekHarnessMachineEnv(base, machineEnv) {
|
|
|
118
100
|
*/
|
|
119
101
|
export function providerFingerprint(runtime, cfg) {
|
|
120
102
|
if (runtime === "codex" && cfg.provider === "deepseek") {
|
|
121
|
-
return `deepseek|${cfg.
|
|
103
|
+
return `deepseek|${cfg.providerApiKey ? "key" : "nokey"}`;
|
|
122
104
|
}
|
|
123
105
|
if (runtime !== "claude" || cfg.provider !== "custom")
|
|
124
106
|
return null;
|
package/dist/runner.js
CHANGED
|
@@ -12,7 +12,7 @@ import { readBoundImDecisionFile, resetBoundImDecisionFile } from "./bound-im-de
|
|
|
12
12
|
import { launchSupervisedRuntime } from "./supervised-runtime.js";
|
|
13
13
|
import { awaitWithCancellation, } from "./runtime-cancellation.js";
|
|
14
14
|
export { awaitExit, exitActivity } from "./local-executor.js";
|
|
15
|
-
export { sanitizeEnvVars } from "./
|
|
15
|
+
export { sanitizeEnvVars } from "./runtime-env.js";
|
|
16
16
|
const ICON = {
|
|
17
17
|
init: "🟢", text: "💬", reading: "📖", sending: "📨", checking: "🔎",
|
|
18
18
|
claiming: "📌", crew: "⚙️", tool: "🛠️", tool_result: "↩️", done: "✅", error: "❌",
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
const ENV_KEY_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
2
|
+
export const RESERVED_ENV = new Set([
|
|
3
|
+
"PATH",
|
|
4
|
+
"XDG_CONFIG_HOME",
|
|
5
|
+
"XDG_DATA_HOME",
|
|
6
|
+
"XDG_CACHE_HOME",
|
|
7
|
+
"GH_CONFIG_DIR",
|
|
8
|
+
"CLOUDSDK_CONFIG",
|
|
9
|
+
"NPM_CONFIG_USERCONFIG",
|
|
10
|
+
"YARN_REGISTRY",
|
|
11
|
+
"NPM_CONFIG_ALWAYS_AUTH",
|
|
12
|
+
]);
|
|
13
|
+
/** 用户自定义环境只能补充普通变量,不能覆盖 daemon 维护的运行时契约。 */
|
|
14
|
+
export function sanitizeEnvVars(raw) {
|
|
15
|
+
if (!raw)
|
|
16
|
+
return {};
|
|
17
|
+
return Object.fromEntries(Object.entries(raw).filter(([key, value]) => typeof value === "string"
|
|
18
|
+
&& ENV_KEY_RE.test(key)
|
|
19
|
+
&& !key.toUpperCase().startsWith("CREW_")
|
|
20
|
+
&& !RESERVED_ENV.has(key.toUpperCase())));
|
|
21
|
+
}
|
|
@@ -21,14 +21,9 @@ const RunnerInputSchema = z.object({
|
|
|
21
21
|
cwd: z.string().min(1).optional(),
|
|
22
22
|
workspaceRoots: z.array(z.string().min(1)).optional(),
|
|
23
23
|
skillRoots: z.array(z.string().min(1)).optional(),
|
|
24
|
-
networkAccess: z.boolean().optional(),
|
|
25
24
|
codexCollaborationTools: z.boolean().optional(),
|
|
26
25
|
resume: z.boolean(),
|
|
27
|
-
}).strict()
|
|
28
|
-
if (input.networkAccess === true && input.effectivePermission !== "workspace_write") {
|
|
29
|
-
ctx.addIssue({ code: "custom", message: "network_access_requires_workspace_write" });
|
|
30
|
-
}
|
|
31
|
-
});
|
|
26
|
+
}).strict();
|
|
32
27
|
const RPC_TIMEOUT_MS = 30_000;
|
|
33
28
|
const INITIALIZE_RPC_TIMEOUT_MS = 60_000;
|
|
34
29
|
const ERROR_MESSAGE_CAP = 2_000;
|
|
@@ -618,9 +613,6 @@ async function runCodexAppServerAttempt(bin, input, attempt, initializeTimeoutMs
|
|
|
618
613
|
...(input.reasoning === undefined || input.reasoning === "default"
|
|
619
614
|
? {}
|
|
620
615
|
: { effort: input.reasoning }),
|
|
621
|
-
...(input.networkAccess === true ? {
|
|
622
|
-
sandboxPolicy: { type: "workspaceWrite", networkAccess: true },
|
|
623
|
-
} : {}),
|
|
624
616
|
});
|
|
625
617
|
logStage(activeStage, "ok", attempt, stageStartedAt);
|
|
626
618
|
turnId = started.turn.id;
|
|
@@ -7,20 +7,10 @@ export const DEEPSEEK_CODEX_BASE_URL = "https://api.deepseek.com/";
|
|
|
7
7
|
export const DEEPSEEK_CODEX_KEY_ENV = "NOWCREW_DEEPSEEK_API_KEY";
|
|
8
8
|
export const DEEPSEEK_CODEX_REASONING_LEVELS = ["low", "high", "max"];
|
|
9
9
|
const PRIVATE_CODEX_HOME = ".codex-deepseek";
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
return resolve(homeDir, selfTraining ? SELF_TRAINING_PRIVATE_CODEX_HOME : PRIVATE_CODEX_HOME);
|
|
10
|
+
export function deepSeekCodexHome(homeDir) {
|
|
11
|
+
return resolve(homeDir, PRIVATE_CODEX_HOME);
|
|
13
12
|
}
|
|
14
|
-
function
|
|
15
|
-
const url = new URL(value);
|
|
16
|
-
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
17
|
-
throw new Error("DeepSeek provider base URL must use HTTP(S)");
|
|
18
|
-
}
|
|
19
|
-
if (!url.pathname.endsWith("/"))
|
|
20
|
-
url.pathname = `${url.pathname}/`;
|
|
21
|
-
return url.toString();
|
|
22
|
-
}
|
|
23
|
-
export function renderDeepSeekConfig(codexHome, baseUrl = DEEPSEEK_CODEX_BASE_URL) {
|
|
13
|
+
export function renderDeepSeekConfig(codexHome) {
|
|
24
14
|
const catalogPath = join(codexHome, "models.json");
|
|
25
15
|
return [
|
|
26
16
|
`model = ${JSON.stringify(DEEPSEEK_CODEX_MODEL)}`,
|
|
@@ -30,7 +20,7 @@ export function renderDeepSeekConfig(codexHome, baseUrl = DEEPSEEK_CODEX_BASE_UR
|
|
|
30
20
|
"",
|
|
31
21
|
"[model_providers.deepseek]",
|
|
32
22
|
'name = "deepseek"',
|
|
33
|
-
`base_url = ${JSON.stringify(
|
|
23
|
+
`base_url = ${JSON.stringify(DEEPSEEK_CODEX_BASE_URL)}`,
|
|
34
24
|
'wire_api = "responses"',
|
|
35
25
|
`env_key = ${JSON.stringify(DEEPSEEK_CODEX_KEY_ENV)}`,
|
|
36
26
|
"",
|
|
@@ -50,11 +40,11 @@ async function writePrivateAtomic(path, content) {
|
|
|
50
40
|
await rm(temporary, { force: true });
|
|
51
41
|
}
|
|
52
42
|
}
|
|
53
|
-
export async function materializeDeepSeekCodexHome(homeDir
|
|
54
|
-
const codexHome = deepSeekCodexHome(homeDir
|
|
43
|
+
export async function materializeDeepSeekCodexHome(homeDir) {
|
|
44
|
+
const codexHome = deepSeekCodexHome(homeDir);
|
|
55
45
|
await mkdir(codexHome, { recursive: true, mode: 0o700 });
|
|
56
46
|
await chmod(codexHome, 0o700);
|
|
57
47
|
await writePrivateAtomic(join(codexHome, "models.json"), DEEPSEEK_CODEX_CATALOG);
|
|
58
|
-
await writePrivateAtomic(join(codexHome, "config.toml"), renderDeepSeekConfig(codexHome
|
|
48
|
+
await writePrivateAtomic(join(codexHome, "config.toml"), renderDeepSeekConfig(codexHome));
|
|
59
49
|
return codexHome;
|
|
60
50
|
}
|
package/dist/runtimes/codex.js
CHANGED
|
@@ -36,9 +36,6 @@ export function buildCodexArgs(input) {
|
|
|
36
36
|
else if (input.effectivePermission === "full_access" || (input.effectivePermission === undefined && input.dangerous)) {
|
|
37
37
|
args.push("--dangerously-bypass-approvals-and-sandbox");
|
|
38
38
|
}
|
|
39
|
-
if (input.effectivePermission === "workspace_write" && input.networkAccess === true) {
|
|
40
|
-
args.push("-c", "sandbox_workspace_write.network_access=true");
|
|
41
|
-
}
|
|
42
39
|
for (const imagePath of input.imagePaths ?? [])
|
|
43
40
|
args.push("--image", imagePath);
|
|
44
41
|
// `-` instructs codex exec to read the prompt from stdin. Keeping the complete prompt out of argv
|
|
@@ -46,7 +46,6 @@ export function supervisorLaunch(request) {
|
|
|
46
46
|
effectivePermission: request.effectivePermission,
|
|
47
47
|
...(request.model === undefined ? {} : { model: request.model }),
|
|
48
48
|
...(request.reasoning === undefined ? {} : { reasoning: request.reasoning }),
|
|
49
|
-
...(request.networkAccess === undefined ? {} : { networkAccess: request.networkAccess }),
|
|
50
49
|
...(request.sessionId === undefined ? {} : { sessionId: request.sessionId }),
|
|
51
50
|
...(request.imagePaths === undefined ? {} : { imagePaths: request.imagePaths }),
|
|
52
51
|
...(request.agentRoot === undefined ? {} : {
|
package/dist/workspace.js
CHANGED
|
@@ -59,13 +59,12 @@ export async function prepareWorkspace(input) {
|
|
|
59
59
|
const crewDir = join(dir, ".crew");
|
|
60
60
|
await mkdir(crewDir, { recursive: true });
|
|
61
61
|
// 预先创建明细目录,让收尾流程可以按功能创建 notes/<topic>.md。
|
|
62
|
-
|
|
63
|
-
await mkdir(join(dir, "notes"), { recursive: true });
|
|
62
|
+
await mkdir(join(dir, "notes"), { recursive: true });
|
|
64
63
|
// MEMORY.md:首次创建"持久身份 + 知识索引"骨架,之后由 agent 自己维护
|
|
65
64
|
const memoryPath = join(dir, "MEMORY.md");
|
|
66
|
-
const memorySeedCreated = !
|
|
65
|
+
const memorySeedCreated = !(await exists(memoryPath));
|
|
67
66
|
const localMemoryV2Initialized = await hasLocalMemoryV2Marker(dir);
|
|
68
|
-
if (
|
|
67
|
+
if (memorySeedCreated) {
|
|
69
68
|
try {
|
|
70
69
|
await writeFile(memoryPath, memorySeed(input.handle, input.description), "utf8");
|
|
71
70
|
}
|
|
@@ -74,15 +73,13 @@ export async function prepareWorkspace(input) {
|
|
|
74
73
|
throw error;
|
|
75
74
|
}
|
|
76
75
|
}
|
|
77
|
-
let memory
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
throw error;
|
|
85
|
-
}
|
|
76
|
+
let memory;
|
|
77
|
+
try {
|
|
78
|
+
memory = await readFile(memoryPath, "utf8");
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
logMemoryPrepareFailure(input, "memory_read", error);
|
|
82
|
+
throw error;
|
|
86
83
|
}
|
|
87
84
|
// 系统提示词按 execution 隔离;省略 identity 的兼容调用每次使用随机路径。
|
|
88
85
|
const promptDir = join(crewDir, "prompts");
|