@citeark/agent 0.3.20
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/LICENSE +202 -0
- package/README.md +128 -0
- package/data/dataset-source-registry.v1.json +300 -0
- package/dist/arkgraph/boot.js +6 -0
- package/dist/arkgraph/index.html +1 -0
- package/dist/arkgraph/viewer.css +1 -0
- package/dist/arkgraph/viewer.en.css +1 -0
- package/dist/arkgraph/viewer.en.js +49 -0
- package/dist/arkgraph/viewer.en.js.LEGAL.txt +56 -0
- package/dist/arkgraph/viewer.js +49 -0
- package/dist/arkgraph/viewer.js.LEGAL.txt +56 -0
- package/docker/claude-code/Dockerfile +97 -0
- package/docker/claude-code/codex-pro-relay.mjs +466 -0
- package/docker/claude-code/runtime-contract-check.mjs +79 -0
- package/docs/arkgraph-reading.md +79 -0
- package/docs/configuration.md +100 -0
- package/docs/integration.md +92 -0
- package/docs/maturity-plan.md +27 -0
- package/docs/npm-release.md +44 -0
- package/docs/paper-reading.md +40 -0
- package/docs/research-plan-granularity.md +27 -0
- package/docs/terminal.md +49 -0
- package/examples/toy-evaluation/compile-task.json +27 -0
- package/examples/toy-evaluation/paper.md +5 -0
- package/examples/toy-evaluation/repository/README.md +9 -0
- package/examples/toy-evaluation/repository/checkpoint.json +4 -0
- package/examples/toy-evaluation/repository/evaluate.py +17 -0
- package/examples/toy-evaluation/task.json +81 -0
- package/package.json +59 -0
- package/prompts/compile-research.md +58 -0
- package/prompts/execute-contract.md +72 -0
- package/prompts/execute-workspace-simple.md +51 -0
- package/prompts/execute-workspace.md +34 -0
- package/prompts/prepare-reproduction.md +82 -0
- package/prompts/repair-research.md +45 -0
- package/protocol/CAP.md +129 -0
- package/protocol/LICENSE +12 -0
- package/protocol/MAPPINGS.md +72 -0
- package/protocol/README.md +38 -0
- package/protocol/conformance-v2.0-alpha.1.json +36 -0
- package/protocol/examples/arkgraph/checkpoint-evaluation.json +309 -0
- package/protocol/examples/arkgraph/fixtures.mjs +49 -0
- package/protocol/examples/arkgraph/paper-free.json +291 -0
- package/protocol/examples/arkgraph/partial-failure.json +344 -0
- package/protocol/examples/arkgraph/training-evaluation.json +443 -0
- package/protocol/profiles/agent-trace.md +16 -0
- package/protocol/profiles/computational-run.md +16 -0
- package/protocol/profiles/core.md +15 -0
- package/protocol/profiles/public-bundle.md +18 -0
- package/protocol/profiles/reproduction.md +29 -0
- package/protocol/profiles/research-compilation.md +44 -0
- package/protocol/profiles/research-plan.md +39 -0
- package/protocol/profiles/restricted-evidence.md +15 -0
- package/runtime/bootstrap-autodl-runtime.sh +314 -0
- package/runtime/create-runtime-venv.sh +41 -0
- package/runtime/install-local-cpu-runtime.sh +23 -0
- package/runtime/install-scientific-runtime.sh +153 -0
- package/runtime/mineru/parse.py +62 -0
- package/runtime/mineru/requirements.txt +4 -0
- package/runtime/requirements-baseline.txt +38 -0
- package/schemas/cap/v2/activity.schema.json +47 -0
- package/schemas/cap/v2/agent.schema.json +32 -0
- package/schemas/cap/v2/assertion.schema.json +110 -0
- package/schemas/cap/v2/descriptor.schema.json +243 -0
- package/schemas/cap/v2/entity.schema.json +64 -0
- package/schemas/cap/v2/manifest.schema.json +67 -0
- package/schemas/cap/v2/relation.schema.json +82 -0
- package/schemas/compute-catalog.schema.json +63 -0
- package/schemas/compute-decision.schema.json +27 -0
- package/schemas/execution-contract.schema.json +1024 -0
- package/schemas/research-card.schema.json +30 -0
- package/schemas/research-inventory-draft.schema.json +366 -0
- package/schemas/research.schema.json +1044 -0
- package/schemas/result.schema.json +173 -0
- package/schemas/verification-policy.schema.json +47 -0
- package/schemas/verified-conclusion.schema.json +58 -0
- package/schemas/workspace-summary.schema.json +24 -0
- package/scripts/build-arkgraph-view.mjs +12 -0
- package/scripts/check-execution-feasibility.mjs +24 -0
- package/scripts/check-syntax.mjs +15 -0
- package/scripts/deterministic-asset-preparation.py +438 -0
- package/scripts/package-cap.mjs +23 -0
- package/scripts/package-local-agent.mjs +23 -0
- package/scripts/preview-arkgraph.mjs +25 -0
- package/scripts/replay-research-compiler-candidate.mjs +134 -0
- package/scripts/review-compiler-sources.mjs +44 -0
- package/scripts/run-asset-preparation.sh +17 -0
- package/scripts/run-research-plan.mjs +98 -0
- package/scripts/validate-asset-preparation.py +290 -0
- package/scripts/verify-local-runtime.mjs +57 -0
- package/scripts/verify-npm-package.mjs +57 -0
- package/src/adapters/paper2agent.mjs +107 -0
- package/src/assets/cache.mjs +159 -0
- package/src/assets/compute.mjs +98 -0
- package/src/assets/executor.mjs +145 -0
- package/src/assets/lifecycle.mjs +213 -0
- package/src/assets/manifest.mjs +242 -0
- package/src/assets/opportunistic-preparation.mjs +81 -0
- package/src/assets/plan.mjs +411 -0
- package/src/assets/prompts.mjs +29 -0
- package/src/assets/public-asset-probe.mjs +525 -0
- package/src/assets/qualification.mjs +119 -0
- package/src/assets/readiness.mjs +130 -0
- package/src/assets/reproduction-admission.mjs +355 -0
- package/src/assets/requirements.mjs +152 -0
- package/src/assets/source-grounding.mjs +341 -0
- package/src/assets/source-policy.mjs +118 -0
- package/src/autodl/client.mjs +260 -0
- package/src/autodl/ssh.mjs +380 -0
- package/src/autodl/tools.mjs +129 -0
- package/src/cap/redaction.mjs +38 -0
- package/src/cap/v2/archive.mjs +152 -0
- package/src/cap/v2/attestation.mjs +204 -0
- package/src/cap/v2/canonical-json.mjs +114 -0
- package/src/cap/v2/compilation-artifact.mjs +240 -0
- package/src/cap/v2/core.mjs +282 -0
- package/src/cap/v2/measurement-assessment-records.mjs +23 -0
- package/src/cap/v2/pipeline-artifact.mjs +922 -0
- package/src/cap/v2/read.mjs +41 -0
- package/src/cap/v2/reassessment-artifact.mjs +383 -0
- package/src/cap/v2/research-artifact.mjs +231 -0
- package/src/cap/v2/research-map-records.mjs +46 -0
- package/src/cap/v2/research-object-records.mjs +163 -0
- package/src/cap/v2/research-records.mjs +187 -0
- package/src/cap/v2/verify.mjs +642 -0
- package/src/cli.mjs +1146 -0
- package/src/compute/autodl-pro-compiler.mjs +347 -0
- package/src/compute/autodl-pro-executor.mjs +459 -0
- package/src/compute/autodl-pro-job.mjs +843 -0
- package/src/compute/autodl-pro-network.mjs +295 -0
- package/src/compute/autodl-pro-remote.mjs +810 -0
- package/src/compute/autodl-pro-staging.mjs +117 -0
- package/src/compute/campaign.mjs +110 -0
- package/src/compute/catalog.mjs +123 -0
- package/src/compute/checkpoint-protocol.mjs +154 -0
- package/src/compute/codex-account-lock.mjs +111 -0
- package/src/compute/codex-account-session.mjs +107 -0
- package/src/compute/compiler-profile.mjs +38 -0
- package/src/compute/compiler-router.mjs +23 -0
- package/src/compute/coordinator-recovery.mjs +210 -0
- package/src/compute/executor-router.mjs +29 -0
- package/src/compute/gcp-batch-compiler.mjs +685 -0
- package/src/compute/gcp-batch-executor.mjs +1215 -0
- package/src/compute/gcp-batch-failure.mjs +92 -0
- package/src/compute/gcp-batch-job.mjs +527 -0
- package/src/compute/gcp-batch-lifecycle.mjs +81 -0
- package/src/compute/gcp-checkpoint-worker.mjs +1633 -0
- package/src/compute/local-codex-compiler.mjs +52 -0
- package/src/compute/measurement-hardware.mjs +128 -0
- package/src/compute/remote-attempt.mjs +226 -0
- package/src/compute/requirements.mjs +124 -0
- package/src/compute/research-phases.mjs +48 -0
- package/src/compute/scheduler.mjs +452 -0
- package/src/compute/shared-workloads.mjs +26 -0
- package/src/compute/stage-archive.mjs +79 -0
- package/src/contracts/campaign-contract.mjs +52 -0
- package/src/contracts/execution-contract.mjs +819 -0
- package/src/contracts/execution-mode.mjs +19 -0
- package/src/contracts/execution-timeouts.mjs +45 -0
- package/src/contracts/execution-workload.mjs +68 -0
- package/src/contracts/preflight-schema.mjs +25 -0
- package/src/contracts/public-contract.mjs +63 -0
- package/src/contracts/subject-tags.mjs +31 -0
- package/src/dashboard/data.mjs +898 -0
- package/src/dashboard/server.mjs +79 -0
- package/src/dashboard/static/dashboard.css +366 -0
- package/src/dashboard/static/dashboard.js +560 -0
- package/src/dashboard/static/index.html +85 -0
- package/src/deployment/community-policy.mjs +9 -0
- package/src/deployment/environment.mjs +112 -0
- package/src/deployment/guided.mjs +98 -0
- package/src/deployment/handoff.mjs +102 -0
- package/src/deployment/local-contract.mjs +31 -0
- package/src/deployment/local.mjs +100 -0
- package/src/deployment/prepare.mjs +46 -0
- package/src/deployment/recipe.mjs +108 -0
- package/src/deployment/supplement.mjs +51 -0
- package/src/deployment/terminal.mjs +43 -0
- package/src/diagnosis/renderer.mjs +75 -0
- package/src/diagnosis/target-failure.mjs +46 -0
- package/src/evidence/parser-registry.mjs +54 -0
- package/src/evidence/parsers/fasttext-classification.mjs +82 -0
- package/src/evidence/parsers/json-scalar.mjs +96 -0
- package/src/evidence/parsers/simcse-senteval.mjs +104 -0
- package/src/evidence/parsers/starspace-classification.mjs +78 -0
- package/src/evidence/registry.mjs +147 -0
- package/src/execution/runner-audit.mjs +473 -0
- package/src/gcp/auth.mjs +106 -0
- package/src/gcp/batch-client.mjs +120 -0
- package/src/gcp/resource-discovery.mjs +177 -0
- package/src/gcp/rest.mjs +82 -0
- package/src/gcp/secret-manager.mjs +34 -0
- package/src/gcp/signed-url.mjs +133 -0
- package/src/gcp/storage.mjs +220 -0
- package/src/graph/command.mjs +41 -0
- package/src/graph/execution.mjs +97 -0
- package/src/graph/model.mjs +37 -0
- package/src/graph/presentation.mjs +110 -0
- package/src/graph/query.mjs +159 -0
- package/src/graph/research-relations.mjs +69 -0
- package/src/graph/source-page.mjs +12 -0
- package/src/graph/source-preview.mjs +34 -0
- package/src/graph/validate.mjs +76 -0
- package/src/job.mjs +496 -0
- package/src/network/autodl-routing-proxy.mjs +462 -0
- package/src/network/egress-proxy.mjs +158 -0
- package/src/observability/event-contract.mjs +230 -0
- package/src/observability/pipeline-monitor.mjs +166 -0
- package/src/pipeline/orchestrator.mjs +1281 -0
- package/src/pipeline/recovery-error.mjs +11 -0
- package/src/pipeline/replay.mjs +304 -0
- package/src/pipeline/shared-execution.mjs +115 -0
- package/src/pipeline/stage-checkpoint.mjs +86 -0
- package/src/pipeline/stage-recovery.mjs +101 -0
- package/src/pipeline/targets.mjs +110 -0
- package/src/process.mjs +143 -0
- package/src/protocol.mjs +312 -0
- package/src/provider/codex-account.mjs +44 -0
- package/src/provider/codex-completion.mjs +49 -0
- package/src/provider/completion.mjs +292 -0
- package/src/provider/model-client.mjs +44 -0
- package/src/provider/model-route.mjs +29 -0
- package/src/provider/openrouter-readiness.mjs +189 -0
- package/src/provider/reader-bridge.mjs +35 -0
- package/src/provider/relay.mjs +263 -0
- package/src/provider/runtime-auth.mjs +40 -0
- package/src/public/cap.d.mts +90 -0
- package/src/public/cap.mjs +12 -0
- package/src/public/contracts.d.mts +2 -0
- package/src/public/host.mjs +171 -0
- package/src/public/operations.d.mts +11 -0
- package/src/public/presentation.d.mts +4 -0
- package/src/records/views.mjs +26 -0
- package/src/remote/command.mjs +178 -0
- package/src/remote/ssh.mjs +59 -0
- package/src/repository-origin.mjs +81 -0
- package/src/reproduction/evidence-feedback.mjs +96 -0
- package/src/reproduction/incomplete-initialization.mjs +25 -0
- package/src/reproduction/lifecycle.mjs +253 -0
- package/src/reproduction/plan.mjs +132 -0
- package/src/reproduction/prompts.mjs +70 -0
- package/src/reproduction/runner.mjs +188 -0
- package/src/reproduction/summary.mjs +130 -0
- package/src/reproduction/workspace-mode.mjs +7 -0
- package/src/research/automatic-admission.mjs +156 -0
- package/src/research/compiler-coverage.mjs +85 -0
- package/src/research/compiler-failure.mjs +24 -0
- package/src/research/compiler-normalization-guards.mjs +112 -0
- package/src/research/compiler-repair.mjs +3 -0
- package/src/research/compiler.mjs +853 -0
- package/src/research/continuation-selection.mjs +26 -0
- package/src/research/execution-graph-context.mjs +43 -0
- package/src/research/experiment-importance.mjs +15 -0
- package/src/research/inventory-handoff.mjs +104 -0
- package/src/research/inventory-revisions.mjs +32 -0
- package/src/research/mineru-local.mjs +73 -0
- package/src/research/paper-command.mjs +19 -0
- package/src/research/paper-markdown.mjs +180 -0
- package/src/research/paper-source-map.mjs +69 -0
- package/src/research/planning-policy.mjs +88 -0
- package/src/research/reference-materials.mjs +11 -0
- package/src/research/reproduction-scope.mjs +30 -0
- package/src/research/research-map.mjs +94 -0
- package/src/research/research-objects.mjs +88 -0
- package/src/research/source-discovery.mjs +646 -0
- package/src/research/source-observations.mjs +75 -0
- package/src/research/source-review-cli-mcp.mjs +26 -0
- package/src/research/source-review-input.mjs +209 -0
- package/src/research/source-review-local-codex.mjs +36 -0
- package/src/research/source-review-model.mjs +70 -0
- package/src/research/source-review.mjs +173 -0
- package/src/research/structure.mjs +3163 -0
- package/src/research-card/renderer.mjs +277 -0
- package/src/research-card/verified-conclusion.mjs +143 -0
- package/src/results/output-registry.mjs +183 -0
- package/src/runtime/claude-code.mjs +52 -0
- package/src/runtime/codex-capacity-retry.mjs +87 -0
- package/src/runtime/codex.mjs +64 -0
- package/src/runtime/config.mjs +157 -0
- package/src/runtime/final-output.mjs +40 -0
- package/src/runtime/index.mjs +21 -0
- package/src/runtime/local-codex.mjs +74 -0
- package/src/runtime/opencode.mjs +95 -0
- package/src/runtime/prompt.mjs +13 -0
- package/src/sandbox/docker.mjs +363 -0
- package/src/settings/command.mjs +297 -0
- package/src/settings/store.mjs +119 -0
- package/src/telemetry/pricing.mjs +68 -0
- package/src/telemetry/usage.mjs +265 -0
- package/src/terminal/events.mjs +97 -0
- package/src/terminal/input.mjs +40 -0
- package/src/terminal/plain.mjs +40 -0
- package/src/terminal/remote-stream.mjs +22 -0
- package/src/terminal/screen.mjs +214 -0
- package/src/terminal/transcript.mjs +69 -0
- package/src/util.mjs +107 -0
- package/src/verification/ai-assessor.mjs +534 -0
- package/src/verification/claim-evaluator.mjs +242 -0
- package/src/verification/evidence-context.mjs +165 -0
- package/src/verification/evidence-reader.mjs +95 -0
- package/src/verification/integrity.mjs +570 -0
- package/src/verification/tolerance.mjs +32 -0
- package/src/workloads/cpu-research-preparation.mjs +56 -0
- package/src/workloads/definition.mjs +74 -0
- package/src/workloads/phase-aware-reproduction.mjs +46 -0
- package/src/workloads/reproduction.mjs +85 -0
- package/src/workspace/command.mjs +242 -0
- package/src/workspace/control.mjs +49 -0
- package/src/workspace/entry.mjs +28 -0
- package/src/workspace/input.mjs +93 -0
- package/src/workspace/interactive.mjs +94 -0
- package/src/workspace/jobs.mjs +418 -0
- package/src/workspace/session.mjs +97 -0
- package/src/workspace/worker.mjs +137 -0
- package/ui/arkgraph/ambient-motion.mjs +10 -0
- package/ui/arkgraph/app.jsx +153 -0
- package/ui/arkgraph/boot.js +6 -0
- package/ui/arkgraph/camera-motion.mjs +20 -0
- package/ui/arkgraph/context-reveal.mjs +39 -0
- package/ui/arkgraph/details.css +3 -0
- package/ui/arkgraph/entry.jsx +28 -0
- package/ui/arkgraph/experiment-curves.mjs +17 -0
- package/ui/arkgraph/experiment-selection.mjs +15 -0
- package/ui/arkgraph/experiment-style.css +26 -0
- package/ui/arkgraph/experiment-ui.jsx +32 -0
- package/ui/arkgraph/frame.html +1 -0
- package/ui/arkgraph/graph-gestures.mjs +62 -0
- package/ui/arkgraph/label-layout.mjs +57 -0
- package/ui/arkgraph/locales/en.json +229 -0
- package/ui/arkgraph/locales/source-types.json +15 -0
- package/ui/arkgraph/localization-build.mjs +27 -0
- package/ui/arkgraph/material-build.mjs +23 -0
- package/ui/arkgraph/material-colors.mjs +39 -0
- package/ui/arkgraph/material-style.css +15 -0
- package/ui/arkgraph/open-graph.jsx +326 -0
- package/ui/arkgraph/outline.jsx +49 -0
- package/ui/arkgraph/package-lock.json +888 -0
- package/ui/arkgraph/package.json +17 -0
- package/ui/arkgraph/reading-layout.mjs +130 -0
- package/ui/arkgraph/reading-presentation.mjs +73 -0
- package/ui/arkgraph/record-detail.css +51 -0
- package/ui/arkgraph/record-details.jsx +29 -0
- package/ui/arkgraph/research-types.mjs +31 -0
- package/ui/arkgraph/selection-mark.jsx +6 -0
- package/ui/arkgraph/soft-spine.mjs +26 -0
- package/ui/arkgraph/steering-style.css +187 -0
- package/ui/arkgraph/style.css +272 -0
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
|
|
3
|
+
import { sha256Value } from "../util.mjs";
|
|
4
|
+
import {
|
|
5
|
+
assetRequirementCoverageFailures,
|
|
6
|
+
evaluateAssetRequirementCoverage,
|
|
7
|
+
normalizeAssetRequirements,
|
|
8
|
+
} from "./requirements.mjs";
|
|
9
|
+
import { CURRENT_PREFLIGHT_SCHEMA_VERSION } from "../contracts/preflight-schema.mjs";
|
|
10
|
+
import { rankedAssetLocators } from "./source-policy.mjs";
|
|
11
|
+
|
|
12
|
+
export const ASSET_SCIENTIFIC_ROLES = new Set([
|
|
13
|
+
"execution_required",
|
|
14
|
+
"identity_only",
|
|
15
|
+
"provenance_only",
|
|
16
|
+
"optional",
|
|
17
|
+
]);
|
|
18
|
+
|
|
19
|
+
export const ASSET_ACQUISITION_MODES = new Set([
|
|
20
|
+
"auto",
|
|
21
|
+
"metadata",
|
|
22
|
+
"selective",
|
|
23
|
+
"full",
|
|
24
|
+
"stream",
|
|
25
|
+
]);
|
|
26
|
+
|
|
27
|
+
export const DEFAULT_ASSET_LIMITS = Object.freeze({
|
|
28
|
+
totalDownloadBytes: 64 * 1024 ** 3,
|
|
29
|
+
totalExpandedBytes: 256 * 1024 ** 3,
|
|
30
|
+
datasetDownloadBytes: 32 * 1024 ** 3,
|
|
31
|
+
modelDownloadBytes: 32 * 1024 ** 3,
|
|
32
|
+
repositoryDownloadBytes: 8 * 1024 ** 3,
|
|
33
|
+
otherDownloadBytes: 8 * 1024 ** 3,
|
|
34
|
+
expandedToDownloadRatio: 4,
|
|
35
|
+
minimumFreeBytesAfterPreparation: 20 * 1024 ** 3,
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
export function createAssetPreparationPlan({
|
|
39
|
+
experiment,
|
|
40
|
+
datasetRegistry,
|
|
41
|
+
limits = {},
|
|
42
|
+
now = () => new Date(),
|
|
43
|
+
}) {
|
|
44
|
+
const policy = normalizeLimits(limits);
|
|
45
|
+
const registry = registryMap(datasetRegistry);
|
|
46
|
+
const declaredAssets = Array.isArray(experiment?.protocol?.preflight?.assets)
|
|
47
|
+
? experiment.protocol.preflight.assets
|
|
48
|
+
: [];
|
|
49
|
+
const assets = declaredAssets.map((asset) => planAsset({
|
|
50
|
+
asset,
|
|
51
|
+
experimentId: experiment?.id,
|
|
52
|
+
registry: registry.get(asset?.registryDatasetId),
|
|
53
|
+
policy,
|
|
54
|
+
}));
|
|
55
|
+
const checks = assetPreparationChecks(experiment?.protocol?.preflight?.checks);
|
|
56
|
+
const requirements = normalizeAssetRequirements(
|
|
57
|
+
experiment?.protocol?.preflight?.requirements,
|
|
58
|
+
);
|
|
59
|
+
const scientificCompleteness = evaluateAssetRequirementCoverage({
|
|
60
|
+
requirements: experiment?.protocol?.preflight?.requirements,
|
|
61
|
+
assets: declaredAssets,
|
|
62
|
+
checks: experiment?.protocol?.preflight?.checks,
|
|
63
|
+
});
|
|
64
|
+
const expectedDownloadBytes = assets.reduce(
|
|
65
|
+
(sum, asset) => sum + (
|
|
66
|
+
new Set(["prepare", "inspect"]).has(asset.decision.action)
|
|
67
|
+
? asset.expectedDownloadBytes ?? 0
|
|
68
|
+
: 0
|
|
69
|
+
),
|
|
70
|
+
0,
|
|
71
|
+
);
|
|
72
|
+
const expectedExpandedBytes = assets.reduce(
|
|
73
|
+
(sum, asset) => sum + (
|
|
74
|
+
new Set(["prepare", "inspect"]).has(asset.decision.action)
|
|
75
|
+
? asset.expectedExpandedBytes ?? asset.expectedDownloadBytes ?? 0
|
|
76
|
+
: 0
|
|
77
|
+
),
|
|
78
|
+
0,
|
|
79
|
+
);
|
|
80
|
+
const failures = experiment?.protocol?.preflight?.schemaVersion === CURRENT_PREFLIGHT_SCHEMA_VERSION
|
|
81
|
+
? [...assetRequirementCoverageFailures(scientificCompleteness)]
|
|
82
|
+
: [];
|
|
83
|
+
if (expectedDownloadBytes > policy.totalDownloadBytes) {
|
|
84
|
+
failures.push({
|
|
85
|
+
assetId: null,
|
|
86
|
+
reasonCode: "asset.total_download_budget_exceeded",
|
|
87
|
+
message: `预计总下载 ${expectedDownloadBytes} 字节,超过任务总上限 ${policy.totalDownloadBytes} 字节。`,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
if (expectedExpandedBytes > policy.totalExpandedBytes) {
|
|
91
|
+
failures.push({
|
|
92
|
+
assetId: null,
|
|
93
|
+
reasonCode: "asset.total_expanded_budget_exceeded",
|
|
94
|
+
message: `预计落盘 ${expectedExpandedBytes} 字节,超过任务落盘上限 ${policy.totalExpandedBytes} 字节。`,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
const immutable = {
|
|
98
|
+
schemaVersion: "0.1",
|
|
99
|
+
policyVersion: "asset-preparation-v2",
|
|
100
|
+
experimentId: experiment?.id ?? null,
|
|
101
|
+
maxMinutes: boundedPositiveInteger(experiment?.protocol?.preflight?.maxMinutes, 120, 360),
|
|
102
|
+
assets,
|
|
103
|
+
checks,
|
|
104
|
+
requirements,
|
|
105
|
+
scientificCompleteness,
|
|
106
|
+
limits: policy,
|
|
107
|
+
failures,
|
|
108
|
+
};
|
|
109
|
+
const plan = {
|
|
110
|
+
...immutable,
|
|
111
|
+
planDigest: `sha256:${sha256Value(immutable)}`,
|
|
112
|
+
createdAt: now().toISOString(),
|
|
113
|
+
summary: {
|
|
114
|
+
assetCount: assets.length,
|
|
115
|
+
executionRequiredCount: assets.filter(
|
|
116
|
+
(asset) => asset.scientificRole === "execution_required",
|
|
117
|
+
).length,
|
|
118
|
+
metadataOnlyCount: assets.filter((asset) => asset.decision.action === "metadata").length,
|
|
119
|
+
inspectCount: assets.filter((asset) => asset.decision.action === "inspect").length,
|
|
120
|
+
prepareCount: assets.filter((asset) => asset.decision.action === "prepare").length,
|
|
121
|
+
streamCount: assets.filter((asset) => asset.decision.action === "stream").length,
|
|
122
|
+
blockedCount: assets.filter((asset) => asset.decision.action === "blocked").length,
|
|
123
|
+
expectedDownloadBytes,
|
|
124
|
+
expectedExpandedBytes,
|
|
125
|
+
expectedSizeUnknownCount: assets.filter(
|
|
126
|
+
(asset) => asset.expectedDownloadBytes === null,
|
|
127
|
+
).length,
|
|
128
|
+
},
|
|
129
|
+
};
|
|
130
|
+
return plan;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export function assetPreparationPlanFailures(plan) {
|
|
134
|
+
return [
|
|
135
|
+
...(Array.isArray(plan?.failures) ? plan.failures : []),
|
|
136
|
+
...(Array.isArray(plan?.assets) ? plan.assets : [])
|
|
137
|
+
.filter((asset) => asset?.decision?.action === "blocked")
|
|
138
|
+
.map((asset) => ({
|
|
139
|
+
assetId: asset.id,
|
|
140
|
+
reasonCode: asset.decision.reasonCode,
|
|
141
|
+
message: asset.decision.message,
|
|
142
|
+
})),
|
|
143
|
+
];
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function assetPreparationChecks(value) {
|
|
147
|
+
const kinds = new Set(["runtime", "dependencies", "dataset_loader"]);
|
|
148
|
+
return (Array.isArray(value) ? value : []).flatMap((check) => {
|
|
149
|
+
if (!check || typeof check !== "object" || !kinds.has(check.kind)) return [];
|
|
150
|
+
const id = text(check.id);
|
|
151
|
+
const successCriterion = text(check.successCriterion);
|
|
152
|
+
if (!id || !successCriterion) return [];
|
|
153
|
+
return [{
|
|
154
|
+
id,
|
|
155
|
+
kind: check.kind,
|
|
156
|
+
...(text(check.command) ? { command: check.command.trim() } : {}),
|
|
157
|
+
successCriterion,
|
|
158
|
+
}];
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function planAsset({ asset, experimentId, registry, policy }) {
|
|
163
|
+
const required = asset?.required === true;
|
|
164
|
+
const scientificRole = ASSET_SCIENTIFIC_ROLES.has(asset?.scientificRole)
|
|
165
|
+
? asset.scientificRole
|
|
166
|
+
: required
|
|
167
|
+
? "execution_required"
|
|
168
|
+
: "optional";
|
|
169
|
+
const acquisition = asset?.acquisition && typeof asset.acquisition === "object"
|
|
170
|
+
? asset.acquisition
|
|
171
|
+
: {};
|
|
172
|
+
const mode = ASSET_ACQUISITION_MODES.has(acquisition.mode)
|
|
173
|
+
? acquisition.mode
|
|
174
|
+
: "auto";
|
|
175
|
+
const kind = String(asset?.kind ?? "other");
|
|
176
|
+
const expectedDownloadBytes = nonNegativeSafeInteger(
|
|
177
|
+
acquisition.expectedDownloadBytes ?? registry?.candidateTransport?.archiveBytes,
|
|
178
|
+
);
|
|
179
|
+
const expectedExpandedBytes = nonNegativeSafeInteger(acquisition.expectedExpandedBytes);
|
|
180
|
+
const maximumDownloadBytes = positiveSafeInteger(
|
|
181
|
+
acquisition.maximumDownloadBytes,
|
|
182
|
+
defaultMaximumBytes(kind, policy),
|
|
183
|
+
);
|
|
184
|
+
const defaultMaximumExpandedBytes = Math.max(
|
|
185
|
+
maximumDownloadBytes,
|
|
186
|
+
maximumDownloadBytes * policy.expandedToDownloadRatio,
|
|
187
|
+
);
|
|
188
|
+
const maximumExpandedBytes = positiveSafeInteger(
|
|
189
|
+
acquisition.maximumExpandedBytes,
|
|
190
|
+
defaultMaximumExpandedBytes,
|
|
191
|
+
);
|
|
192
|
+
const supportsStreaming = acquisition.supportsStreaming === true;
|
|
193
|
+
const decision = acquisitionDecision({
|
|
194
|
+
required,
|
|
195
|
+
scientificRole,
|
|
196
|
+
mode,
|
|
197
|
+
expectedDownloadBytes,
|
|
198
|
+
expectedExpandedBytes,
|
|
199
|
+
maximumDownloadBytes,
|
|
200
|
+
maximumExpandedBytes,
|
|
201
|
+
supportsStreaming,
|
|
202
|
+
policy,
|
|
203
|
+
});
|
|
204
|
+
return {
|
|
205
|
+
id: String(asset?.id ?? "asset"),
|
|
206
|
+
experimentId: experimentId ?? null,
|
|
207
|
+
kind,
|
|
208
|
+
availability: String(asset?.availability ?? "unknown"),
|
|
209
|
+
identity: String(asset?.identity ?? asset?.id ?? "unknown"),
|
|
210
|
+
required,
|
|
211
|
+
scientificRole,
|
|
212
|
+
acquisitionMode: mode,
|
|
213
|
+
revision: text(acquisition.revision),
|
|
214
|
+
localPath: assetLocalPath(kind, asset?.id ?? "asset"),
|
|
215
|
+
sourceLocators: assetLocators(asset, registry),
|
|
216
|
+
sourceEvidence: normalizeSourceEvidence(asset?.sourceEvidence),
|
|
217
|
+
requiredPaths: normalizePatterns(acquisition.requiredPaths),
|
|
218
|
+
excludedPaths: normalizePatterns(acquisition.excludedPaths),
|
|
219
|
+
expectedDownloadBytes,
|
|
220
|
+
expectedExpandedBytes,
|
|
221
|
+
maximumDownloadBytes,
|
|
222
|
+
maximumExpandedBytes,
|
|
223
|
+
supportsStreaming,
|
|
224
|
+
verification: String(asset?.verification ?? "Verify identity before use."),
|
|
225
|
+
decision,
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function acquisitionDecision({
|
|
230
|
+
required,
|
|
231
|
+
scientificRole,
|
|
232
|
+
mode,
|
|
233
|
+
expectedDownloadBytes,
|
|
234
|
+
expectedExpandedBytes,
|
|
235
|
+
maximumDownloadBytes,
|
|
236
|
+
maximumExpandedBytes,
|
|
237
|
+
supportsStreaming,
|
|
238
|
+
policy,
|
|
239
|
+
}) {
|
|
240
|
+
if (!required || scientificRole !== "execution_required" || mode === "metadata") {
|
|
241
|
+
return {
|
|
242
|
+
action: "metadata",
|
|
243
|
+
reasonCode: "asset.content_not_required",
|
|
244
|
+
message: "该资产只需要来源或身份元数据,不下载正文。",
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
if (mode === "stream") {
|
|
248
|
+
return supportsStreaming
|
|
249
|
+
? {
|
|
250
|
+
action: "stream",
|
|
251
|
+
reasonCode: "asset.streaming_declared",
|
|
252
|
+
message: "资产按不可变清单流式读取,不预先完整落盘。",
|
|
253
|
+
}
|
|
254
|
+
: {
|
|
255
|
+
action: "blocked",
|
|
256
|
+
reasonCode: "asset.streaming_not_supported",
|
|
257
|
+
message: "计划要求流式读取,但没有声明可验证的流式协议。",
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
if (expectedDownloadBytes === null) {
|
|
261
|
+
return {
|
|
262
|
+
action: "inspect",
|
|
263
|
+
reasonCode: "asset.size_inventory_required",
|
|
264
|
+
message: "先读取远端文件清单与大小,再决定是否下载。",
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
if (expectedDownloadBytes > maximumDownloadBytes) {
|
|
268
|
+
return supportsStreaming
|
|
269
|
+
? {
|
|
270
|
+
action: "stream",
|
|
271
|
+
reasonCode: "asset.size_requires_streaming",
|
|
272
|
+
message: "完整下载超过单资产预算,改用声明且可验证的流式协议。",
|
|
273
|
+
}
|
|
274
|
+
: {
|
|
275
|
+
action: "blocked",
|
|
276
|
+
reasonCode: "asset.download_budget_exceeded",
|
|
277
|
+
message: `预计下载 ${expectedDownloadBytes} 字节,超过单资产上限 ${maximumDownloadBytes} 字节。`,
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
if (expectedExpandedBytes !== null && expectedExpandedBytes > maximumExpandedBytes) {
|
|
281
|
+
return {
|
|
282
|
+
action: "blocked",
|
|
283
|
+
reasonCode: "asset.expanded_size_budget_exceeded",
|
|
284
|
+
message: `预计展开后 ${expectedExpandedBytes} 字节,超过展开空间上限 ${maximumExpandedBytes} 字节。`,
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
return {
|
|
288
|
+
action: "prepare",
|
|
289
|
+
reasonCode: mode === "selective"
|
|
290
|
+
? "asset.selective_download_ready"
|
|
291
|
+
: "asset.download_ready",
|
|
292
|
+
message: mode === "selective"
|
|
293
|
+
? "只准备计划明确需要的文件。"
|
|
294
|
+
: "资产可在廉价准备阶段完整获取。",
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
function assetLocators(asset, registry) {
|
|
299
|
+
return rankedAssetLocators(asset, registry);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
function normalizeSourceEvidence(value) {
|
|
303
|
+
return (Array.isArray(value) ? value : []).flatMap((entry) => {
|
|
304
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry)) return [];
|
|
305
|
+
const source = text(entry.source);
|
|
306
|
+
const locator = text(entry.locator);
|
|
307
|
+
if (!source || !locator) return [];
|
|
308
|
+
return [{
|
|
309
|
+
source,
|
|
310
|
+
locator,
|
|
311
|
+
...(text(entry.path) ? { path: entry.path } : {}),
|
|
312
|
+
...(text(entry.commit) ? { commit: entry.commit } : {}),
|
|
313
|
+
}];
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
function normalizePatterns(value) {
|
|
318
|
+
return [...new Set((Array.isArray(value) ? value : [])
|
|
319
|
+
.map(text)
|
|
320
|
+
.filter((pattern) => pattern && safeAssetPattern(pattern)))];
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
function safeAssetPattern(value) {
|
|
324
|
+
const normalized = String(value).replaceAll("\\", "/");
|
|
325
|
+
return !path.posix.isAbsolute(normalized)
|
|
326
|
+
&& !normalized.split("/").includes("..")
|
|
327
|
+
&& !/[\u0000-\u001f]/.test(normalized);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
function normalizeLimits(value) {
|
|
331
|
+
return {
|
|
332
|
+
totalDownloadBytes: positiveSafeInteger(
|
|
333
|
+
value.totalDownloadBytes,
|
|
334
|
+
DEFAULT_ASSET_LIMITS.totalDownloadBytes,
|
|
335
|
+
),
|
|
336
|
+
totalExpandedBytes: positiveSafeInteger(
|
|
337
|
+
value.totalExpandedBytes,
|
|
338
|
+
DEFAULT_ASSET_LIMITS.totalExpandedBytes,
|
|
339
|
+
),
|
|
340
|
+
datasetDownloadBytes: positiveSafeInteger(
|
|
341
|
+
value.datasetDownloadBytes,
|
|
342
|
+
DEFAULT_ASSET_LIMITS.datasetDownloadBytes,
|
|
343
|
+
),
|
|
344
|
+
modelDownloadBytes: positiveSafeInteger(
|
|
345
|
+
value.modelDownloadBytes,
|
|
346
|
+
DEFAULT_ASSET_LIMITS.modelDownloadBytes,
|
|
347
|
+
),
|
|
348
|
+
repositoryDownloadBytes: positiveSafeInteger(
|
|
349
|
+
value.repositoryDownloadBytes,
|
|
350
|
+
DEFAULT_ASSET_LIMITS.repositoryDownloadBytes,
|
|
351
|
+
),
|
|
352
|
+
otherDownloadBytes: positiveSafeInteger(
|
|
353
|
+
value.otherDownloadBytes,
|
|
354
|
+
DEFAULT_ASSET_LIMITS.otherDownloadBytes,
|
|
355
|
+
),
|
|
356
|
+
expandedToDownloadRatio: positiveSafeInteger(
|
|
357
|
+
value.expandedToDownloadRatio,
|
|
358
|
+
DEFAULT_ASSET_LIMITS.expandedToDownloadRatio,
|
|
359
|
+
),
|
|
360
|
+
minimumFreeBytesAfterPreparation: positiveSafeInteger(
|
|
361
|
+
value.minimumFreeBytesAfterPreparation,
|
|
362
|
+
DEFAULT_ASSET_LIMITS.minimumFreeBytesAfterPreparation,
|
|
363
|
+
),
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
function defaultMaximumBytes(kind, limits) {
|
|
368
|
+
if (kind === "dataset") return limits.datasetDownloadBytes;
|
|
369
|
+
if (kind === "model" || kind === "checkpoint") return limits.modelDownloadBytes;
|
|
370
|
+
if (kind === "repository") return limits.repositoryDownloadBytes;
|
|
371
|
+
return limits.otherDownloadBytes;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
function registryMap(value) {
|
|
375
|
+
return new Map((Array.isArray(value?.datasets) ? value.datasets : [])
|
|
376
|
+
.filter((entry) => typeof entry?.id === "string")
|
|
377
|
+
.map((entry) => [entry.id, entry]));
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
export function assetLocalPath(kind, id) {
|
|
381
|
+
return `/job/assets/${safeSegment(kind)}/${safeSegment(id)}`;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
function safeSegment(value) {
|
|
385
|
+
return String(value ?? "asset")
|
|
386
|
+
.toLowerCase()
|
|
387
|
+
.replaceAll(/[^a-z0-9_.-]+/g, "-")
|
|
388
|
+
.replaceAll(/^-+|-+$/g, "")
|
|
389
|
+
.slice(0, 120) || "asset";
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
function text(value) {
|
|
393
|
+
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
function nonNegativeSafeInteger(value) {
|
|
397
|
+
const number = Number(value);
|
|
398
|
+
return Number.isSafeInteger(number) && number >= 0 ? number : null;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
function positiveSafeInteger(value, fallback) {
|
|
402
|
+
const number = Number(value);
|
|
403
|
+
return Number.isSafeInteger(number) && number > 0 ? number : fallback;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
function boundedPositiveInteger(value, fallback, maximum) {
|
|
407
|
+
const number = Number(value);
|
|
408
|
+
return Number.isSafeInteger(number) && number > 0
|
|
409
|
+
? Math.min(number, maximum)
|
|
410
|
+
: fallback;
|
|
411
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export function initialAssetPreparationPrompt(bundle) {
|
|
2
|
+
return [
|
|
3
|
+
`Run ID: ${bundle.runId}`,
|
|
4
|
+
"This is the dedicated asset-preparation phase. Do not run the full scientific experiment.",
|
|
5
|
+
"Read /job/input/asset-preparation-plan.json and /job/input/task.json. The plan is immutable.",
|
|
6
|
+
"For metadata actions, record source observations without downloading content. For selective actions, treat requiredPaths as backward-compatible download-selection hints: fetch the useful matching subset within budget, record unmatched hints, and never require every listed alternative format to exist. Always exclude excludedPaths. For inspect actions, first obtain a remote file inventory and sizes, then stay within both per-asset and total limits. For stream actions, prepare a bounded streaming descriptor and a small representative loader probe; never silently turn streaming into a full download.",
|
|
7
|
+
"Put durable asset bytes only at each plan localPath under /job/assets. Put package caches only under /job/runtime-cache. Modify dependencies only inside /job/runtime-venv; the base image is a download cache, not a version restriction.",
|
|
8
|
+
"Use resumable and retrying transfers. Preserve every URL, redirect target, status, attempt, byte count and checksum in /job/output/logs/asset-preparation. Never log credentials or signed query parameters.",
|
|
9
|
+
"Try sourceLocators in rank order. Use a lower-priority mirror only after recording each higher-priority source as failed. A mirror marked fallbackRequiresDigestMatch is forbidden unless its planned expectedDigest matches acquisition.sourceDigest. Record acquisition.sourceDigest and attemptedSources in the manifest.",
|
|
10
|
+
"The deterministic downloader already ran before this Agent. Inspect /job/output/logs/asset-preparation/deterministic and retain any valid partial downloads; repair only the ambiguity, dependency conflict, loader failure, or unsupported transport that caused the handoff.",
|
|
11
|
+
"For dependencies, inspect repository metadata and actual import errors. You may upgrade, downgrade or replace packages when evidence requires it. Record the final Python version and package inventory; do not modify the global image environment.",
|
|
12
|
+
"Run every plan check. A dataset_loader check must invoke the real evaluator or dataset loader, resolve the declared configuration and split, read representative rows, and verify schema/identity. An import-only check or web-page reachability check is not sufficient.",
|
|
13
|
+
"Never download a historical training corpus merely to evaluate a published checkpoint. If an item is unnecessary, unavailable, or over budget, record that preparation observation and leave it to the complete reproduction Agent; this cache phase must not reduce the experiment scope or decide scientific executability.",
|
|
14
|
+
"Write /job/output/asset-preparation-manifest.json using schemaVersion 0.1 and kind citeark.asset-preparation-manifest. Include planDigest; one record per planned asset with assetId, identity, revision when planned, sourceLocator, localPath, status, verification {status: passed, commands, evidence}, and for prepared/stream_ready records acquisition {downloadBytes, commands, evidence}; and one record per planned check with checkId, kind, status: passed, commands and evidence paths relative to /job/output. Every evidence path is relative to /job/output. Evidence may initially be a relative-path string or {path}; the supervisor replaces it with a canonical {path, bytes, digest} descriptor, inventories prepared files, and records the task-local environment. Do not invent manifestDigest yourself.",
|
|
15
|
+
"Before stopping, run `python3 /job/input/validate-asset-preparation.py /job/input/asset-preparation-plan.json /job/output/asset-preparation-manifest.json`. Repair any reported factual path or status error, rerun it, and stop only after it prints status passed. The runner repeats this deterministic validation independently.",
|
|
16
|
+
"Stop after the manifest and logs are complete.",
|
|
17
|
+
].join("\n");
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function resumeAssetPreparationPrompt(bundle) {
|
|
21
|
+
return [
|
|
22
|
+
`Resume asset preparation for ${bundle.runId} from the restored checkpoint.`,
|
|
23
|
+
"Inspect /job/input/asset-preparation-plan.json, the existing /job/assets, /job/runtime-cache, /job/runtime-venv, /job/execution/completion-validation.log and prior logs.",
|
|
24
|
+
"The plan is immutable. In particular, keep every assetId, sourceLocator and localPath exactly as planned; never move a prepared asset merely to make the manifest easier to write.",
|
|
25
|
+
"Continue partial downloads with content-range/resume support. Do not restart valid completed transfers or repeat already-passed loader checks unless their inputs or environment changed.",
|
|
26
|
+
"Finish /job/output/asset-preparation-manifest.json and preserve all earlier attempt evidence. Evidence paths are relative to /job/output; the supervisor fills their byte counts and digests.",
|
|
27
|
+
"Before stopping, run `python3 /job/input/validate-asset-preparation.py /job/input/asset-preparation-plan.json /job/output/asset-preparation-manifest.json`, repair any reported factual error, and stop only after it prints status passed.",
|
|
28
|
+
].join("\n");
|
|
29
|
+
}
|