@alisio/core 0.1.0-alpha.9 → 0.1.0
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/README.md +52 -7
- package/dist/agents/active.d.ts +99 -0
- package/dist/agents/active.js +218 -0
- package/dist/agents/capabilities.d.ts +26 -0
- package/dist/agents/capabilities.js +120 -0
- package/dist/agents/create-agent-skill.d.ts +11 -0
- package/dist/agents/create-agent-skill.js +60 -0
- package/dist/agents/definitions.d.ts +88 -0
- package/dist/agents/definitions.js +404 -0
- package/dist/agents/draft.d.ts +41 -0
- package/dist/agents/draft.js +133 -0
- package/dist/agents/service.d.ts +57 -0
- package/dist/agents/service.js +86 -0
- package/dist/agents/templates.d.ts +8 -0
- package/dist/agents/templates.js +102 -0
- package/dist/analysis/capabilities.d.ts +48 -0
- package/dist/analysis/capabilities.js +90 -0
- package/dist/analysis/data/csv.d.ts +46 -0
- package/dist/analysis/data/csv.js +240 -0
- package/dist/analysis/data/datasets.d.ts +132 -0
- package/dist/analysis/data/datasets.js +441 -0
- package/dist/analysis/data/describe.d.ts +27 -0
- package/dist/analysis/data/describe.js +103 -0
- package/dist/analysis/data/engine-client.d.ts +58 -0
- package/dist/analysis/data/engine-client.js +304 -0
- package/dist/analysis/data/engine-entry.d.ts +1 -0
- package/dist/analysis/data/engine-entry.js +59 -0
- package/dist/analysis/data/engine-source.d.ts +4 -0
- package/dist/analysis/data/engine-source.js +6 -0
- package/dist/analysis/data/engine-types.d.ts +86 -0
- package/dist/analysis/data/engine-types.js +7 -0
- package/dist/analysis/data/infer.d.ts +42 -0
- package/dist/analysis/data/infer.js +118 -0
- package/dist/analysis/data/ingest-worker.d.ts +17 -0
- package/dist/analysis/data/ingest-worker.js +365 -0
- package/dist/analysis/data/json.d.ts +19 -0
- package/dist/analysis/data/json.js +44 -0
- package/dist/analysis/data/query-worker.d.ts +12 -0
- package/dist/analysis/data/query-worker.js +75 -0
- package/dist/analysis/data/rows.d.ts +39 -0
- package/dist/analysis/data/rows.js +120 -0
- package/dist/analysis/data/sql-guard.d.ts +20 -0
- package/dist/analysis/data/sql-guard.js +129 -0
- package/dist/analysis/data/stats.d.ts +18 -0
- package/dist/analysis/data/stats.js +77 -0
- package/dist/analysis/install-hints.d.ts +33 -0
- package/dist/analysis/install-hints.js +144 -0
- package/dist/analysis/janitor.d.ts +60 -0
- package/dist/analysis/janitor.js +264 -0
- package/dist/analysis/jobs.d.ts +94 -0
- package/dist/analysis/jobs.js +165 -0
- package/dist/analysis/oci.d.ts +129 -0
- package/dist/analysis/oci.js +330 -0
- package/dist/analysis/python/sources.d.ts +2 -0
- package/dist/analysis/python/sources.js +10 -0
- package/dist/analysis/requirements.d.ts +32 -0
- package/dist/analysis/requirements.js +73 -0
- package/dist/analysis/rerun.d.ts +40 -0
- package/dist/analysis/rerun.js +136 -0
- package/dist/analysis/runtime-manager.d.ts +146 -0
- package/dist/analysis/runtime-manager.js +472 -0
- package/dist/analysis/status.d.ts +21 -0
- package/dist/analysis/status.js +52 -0
- package/dist/application.d.ts +105 -3
- package/dist/application.js +446 -18
- package/dist/artifacts/kinds.d.ts +35 -0
- package/dist/artifacts/kinds.js +177 -0
- package/dist/artifacts/publisher.d.ts +7 -0
- package/dist/artifacts/publisher.js +29 -0
- package/dist/artifacts/store.d.ts +119 -0
- package/dist/artifacts/store.js +581 -0
- package/dist/background/janitor.d.ts +22 -0
- package/dist/background/janitor.js +62 -0
- package/dist/background/mirror.d.ts +14 -0
- package/dist/background/mirror.js +41 -0
- package/dist/background/notify.d.ts +58 -0
- package/dist/background/notify.js +172 -0
- package/dist/background/output.d.ts +46 -0
- package/dist/background/output.js +179 -0
- package/dist/background/service.d.ts +137 -0
- package/dist/background/service.js +410 -0
- package/dist/background/store.d.ts +103 -0
- package/dist/background/store.js +195 -0
- package/dist/changelog/data.d.ts +6 -0
- package/dist/changelog/data.js +293 -0
- package/dist/changelog/index.d.ts +5 -0
- package/dist/changelog/index.js +7 -0
- package/dist/changelog/parse.d.ts +53 -0
- package/dist/changelog/parse.js +160 -0
- package/dist/commands/builtins.d.ts +10 -0
- package/dist/commands/builtins.js +161 -0
- package/dist/commands/catalog.d.ts +86 -0
- package/dist/commands/catalog.js +304 -0
- package/dist/config.d.ts +206 -6
- package/dist/config.js +426 -20
- package/dist/core/compaction.js +13 -2
- package/dist/core/contracts.d.ts +180 -3
- package/dist/core/opt-in.d.ts +12 -0
- package/dist/core/opt-in.js +12 -0
- package/dist/core/output-limit.d.ts +34 -0
- package/dist/core/output-limit.js +39 -0
- package/dist/core/run-stats.d.ts +16 -0
- package/dist/core/run-stats.js +8 -0
- package/dist/core/runner.d.ts +134 -4
- package/dist/core/runner.js +780 -138
- package/dist/core/timeout.d.ts +15 -0
- package/dist/core/timeout.js +61 -0
- package/dist/core/truncation.d.ts +30 -0
- package/dist/core/truncation.js +83 -0
- package/dist/goal/blockers.d.ts +45 -0
- package/dist/goal/blockers.js +51 -0
- package/dist/goal/budget.d.ts +24 -0
- package/dist/goal/budget.js +53 -0
- package/dist/goal/command.d.ts +36 -0
- package/dist/goal/command.js +98 -0
- package/dist/goal/format.d.ts +19 -0
- package/dist/goal/format.js +102 -0
- package/dist/goal/host.d.ts +29 -0
- package/dist/goal/host.js +42 -0
- package/dist/goal/index.d.ts +9 -0
- package/dist/goal/index.js +9 -0
- package/dist/goal/machine.d.ts +186 -0
- package/dist/goal/machine.js +344 -0
- package/dist/goal/prompts.d.ts +10 -0
- package/dist/goal/prompts.js +75 -0
- package/dist/goal/service.d.ts +113 -0
- package/dist/goal/service.js +273 -0
- package/dist/goal/store.d.ts +59 -0
- package/dist/goal/store.js +184 -0
- package/dist/index.d.ts +50 -5
- package/dist/index.js +49 -4
- package/dist/mcp/connector.js +38 -6
- package/dist/mcp/rich.d.ts +41 -0
- package/dist/mcp/rich.js +362 -0
- package/dist/permissions/modes.d.ts +72 -0
- package/dist/permissions/modes.js +98 -0
- package/dist/plan/exit-plan.d.ts +25 -0
- package/dist/plan/exit-plan.js +130 -0
- package/dist/plan/state.d.ts +102 -0
- package/dist/plan/state.js +165 -0
- package/dist/plugins/host.d.ts +34 -1
- package/dist/plugins/host.js +143 -9
- package/dist/providers/settings.d.ts +15 -0
- package/dist/providers/settings.js +38 -0
- package/dist/reload.d.ts +75 -0
- package/dist/reload.js +204 -0
- package/dist/resources/context.js +6 -1
- package/dist/runtime/access.d.ts +62 -0
- package/dist/runtime/access.js +115 -0
- package/dist/runtime/blobs.d.ts +51 -0
- package/dist/runtime/blobs.js +177 -0
- package/dist/runtime/diff.d.ts +23 -0
- package/dist/runtime/diff.js +154 -0
- package/dist/runtime/ids.d.ts +8 -0
- package/dist/runtime/ids.js +32 -0
- package/dist/runtime/paths.d.ts +11 -0
- package/dist/runtime/paths.js +17 -1
- package/dist/runtime/process.d.ts +22 -0
- package/dist/runtime/process.js +100 -15
- package/dist/runtime/sqlite.d.ts +2 -0
- package/dist/runtime/sqlite.js +18 -0
- package/dist/runtime/store.d.ts +91 -3
- package/dist/runtime/store.js +465 -11
- package/dist/runtime/zip.d.ts +24 -0
- package/dist/runtime/zip.js +126 -0
- package/dist/sessions/children.js +17 -1
- package/dist/sessions/side-questions.d.ts +57 -0
- package/dist/sessions/side-questions.js +161 -0
- package/dist/tools/analysis.d.ts +37 -0
- package/dist/tools/analysis.js +573 -0
- package/dist/tools/artifacts.d.ts +14 -0
- package/dist/tools/artifacts.js +143 -0
- package/dist/tools/background.d.ts +7 -0
- package/dist/tools/background.js +165 -0
- package/dist/tools/data.d.ts +7 -0
- package/dist/tools/data.js +160 -0
- package/dist/tools/execute.d.ts +5 -0
- package/dist/tools/execute.js +15 -3
- package/dist/tools/goal.d.ts +19 -0
- package/dist/tools/goal.js +126 -0
- package/dist/tools/search.d.ts +17 -3
- package/dist/tools/search.js +153 -0
- package/dist/tools/standard.d.ts +4 -1
- package/dist/tools/standard.js +99 -18
- package/dist/version.d.ts +5 -3
- package/dist/version.js +35 -6
- package/package.json +2 -2
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { ArtifactStore } from "../artifacts/store.ts";
|
|
2
|
+
import type { DatasetService } from "./data/datasets.ts";
|
|
3
|
+
import type { AnalysisJobs, JobInput } from "./jobs.ts";
|
|
4
|
+
export interface RerunInput extends JobInput {
|
|
5
|
+
/** Absolute file to copy into the new job's `input/` (verified before). */
|
|
6
|
+
source: string;
|
|
7
|
+
}
|
|
8
|
+
export interface RerunPlan {
|
|
9
|
+
/** The execution being repeated. */
|
|
10
|
+
executionId: string;
|
|
11
|
+
/** The artifact the user pointed at, when the reference was an artifact. */
|
|
12
|
+
artifactId?: string;
|
|
13
|
+
code: string;
|
|
14
|
+
scriptSha256: string;
|
|
15
|
+
inputs: RerunInput[];
|
|
16
|
+
manifest: unknown[];
|
|
17
|
+
extras: Array<"analysis" | "science">;
|
|
18
|
+
/** The runtime of the original execution (a rerun uses the configured runtime now). */
|
|
19
|
+
runtime: "managed" | "oci";
|
|
20
|
+
}
|
|
21
|
+
export type RerunPreparation = {
|
|
22
|
+
ok: true;
|
|
23
|
+
plan: RerunPlan;
|
|
24
|
+
} | {
|
|
25
|
+
ok: false;
|
|
26
|
+
problems: string[];
|
|
27
|
+
};
|
|
28
|
+
export declare function sha256OfFile(path: string): Promise<string>;
|
|
29
|
+
export declare class AnalysisRerun {
|
|
30
|
+
private options;
|
|
31
|
+
constructor(options: {
|
|
32
|
+
jobs: AnalysisJobs;
|
|
33
|
+
store: ArtifactStore;
|
|
34
|
+
datasets?: DatasetService;
|
|
35
|
+
});
|
|
36
|
+
/** The script of a saved execution as a preview (approvals show it), or undefined. */
|
|
37
|
+
script(ref: string, rootSessionId: string): Promise<string | undefined>;
|
|
38
|
+
private resolve;
|
|
39
|
+
prepare(ref: string, rootSessionId: string): Promise<RerunPreparation>;
|
|
40
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rerun of a `python_run` execution (spec §19): the same `script/main.py` and the same inputs,
|
|
3
|
+
* verified by sha256, as a NEW execution with new artifacts. Nothing of the original is touched.
|
|
4
|
+
* When the saved script, an input copy or a dataset is missing or no longer matches its recorded
|
|
5
|
+
* hash, nothing runs and every problem is reported.
|
|
6
|
+
*/
|
|
7
|
+
import { createHash } from "node:crypto";
|
|
8
|
+
import { createReadStream } from "node:fs";
|
|
9
|
+
import { readdir, readFile } from "node:fs/promises";
|
|
10
|
+
import { basename, join } from "node:path";
|
|
11
|
+
export async function sha256OfFile(path) {
|
|
12
|
+
const hash = createHash("sha256");
|
|
13
|
+
for await (const chunk of createReadStream(path))
|
|
14
|
+
hash.update(chunk);
|
|
15
|
+
return hash.digest("hex");
|
|
16
|
+
}
|
|
17
|
+
const fail = (...problems) => ({ ok: false, problems });
|
|
18
|
+
export class AnalysisRerun {
|
|
19
|
+
options;
|
|
20
|
+
constructor(options) {
|
|
21
|
+
this.options = options;
|
|
22
|
+
}
|
|
23
|
+
/** The script of a saved execution as a preview (approvals show it), or undefined. */
|
|
24
|
+
async script(ref, rootSessionId) {
|
|
25
|
+
const resolved = this.resolve(ref, rootSessionId);
|
|
26
|
+
if (!("executionId" in resolved))
|
|
27
|
+
return undefined;
|
|
28
|
+
const details = this.options.jobs.details(resolved.executionId);
|
|
29
|
+
if (!details)
|
|
30
|
+
return undefined;
|
|
31
|
+
try {
|
|
32
|
+
return await readFile(join(this.options.jobs.folder(details.relDir), "script", "main.py"), "utf8");
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
resolve(ref, rootSessionId) {
|
|
39
|
+
if (ref.startsWith("art_")) {
|
|
40
|
+
const record = this.options.store.get(ref);
|
|
41
|
+
if (!record || record.sessionId !== rootSessionId)
|
|
42
|
+
return { problem: `Artifact ${ref} was not found in this session` };
|
|
43
|
+
if (!record.executionId)
|
|
44
|
+
return {
|
|
45
|
+
problem: `${record.fileName} was not produced by python_run, so it has no script to run again`,
|
|
46
|
+
};
|
|
47
|
+
if (record.status === "deleted")
|
|
48
|
+
return {
|
|
49
|
+
problem: `${record.fileName} was deleted; run the analysis again from its script instead`,
|
|
50
|
+
};
|
|
51
|
+
return { executionId: record.executionId, artifactId: record.id };
|
|
52
|
+
}
|
|
53
|
+
if (ref.startsWith("exec_"))
|
|
54
|
+
return { executionId: ref };
|
|
55
|
+
return { problem: `${ref} is neither an artifact (art_…) nor an execution (exec_…) id` };
|
|
56
|
+
}
|
|
57
|
+
async prepare(ref, rootSessionId) {
|
|
58
|
+
const resolved = this.resolve(ref, rootSessionId);
|
|
59
|
+
if ("problem" in resolved)
|
|
60
|
+
return fail(resolved.problem);
|
|
61
|
+
const { jobs, datasets } = this.options;
|
|
62
|
+
const details = jobs.details(resolved.executionId);
|
|
63
|
+
if (!details || details.rootSessionId !== rootSessionId)
|
|
64
|
+
return fail(`Execution ${resolved.executionId} was not found in this session`);
|
|
65
|
+
let folder;
|
|
66
|
+
try {
|
|
67
|
+
folder = jobs.folder(details.relDir);
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
return fail(error instanceof Error ? error.message : String(error));
|
|
71
|
+
}
|
|
72
|
+
let code;
|
|
73
|
+
try {
|
|
74
|
+
code = await readFile(join(folder, "script", "main.py"), "utf8");
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return fail(`The script of ${details.id} is no longer available (the retention sweep removes the scripts of executions without ready artifacts)`);
|
|
78
|
+
}
|
|
79
|
+
if (createHash("sha256").update(code).digest("hex") !== details.scriptSha256)
|
|
80
|
+
return fail(`The saved script of ${details.id} does not match its recorded hash`);
|
|
81
|
+
const recorded = await jobs.recordedInputs(details.relDir);
|
|
82
|
+
const problems = [];
|
|
83
|
+
const inputs = [];
|
|
84
|
+
if (!recorded) {
|
|
85
|
+
const present = await readdir(join(folder, "input")).catch(() => []);
|
|
86
|
+
if (present.some((name) => name !== "inputs.json"))
|
|
87
|
+
problems.push(`The inputs of ${details.id} were not recorded, so they cannot be verified`);
|
|
88
|
+
}
|
|
89
|
+
else
|
|
90
|
+
for (const input of recorded.inputs) {
|
|
91
|
+
// `job.json` is internal, but a name is never trusted to leave `input/`.
|
|
92
|
+
if (typeof input.name !== "string" || basename(input.name) !== input.name) {
|
|
93
|
+
problems.push("The recorded inputs of this execution are not valid");
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
if (input.datasetId) {
|
|
97
|
+
const record = datasets?.get(input.datasetId);
|
|
98
|
+
if (!record || record.rootSessionId !== rootSessionId)
|
|
99
|
+
problems.push(`Input ${input.name}: the dataset ${input.datasetId} no longer exists`);
|
|
100
|
+
else if (record.sha256 !== input.sha256)
|
|
101
|
+
problems.push(`Input ${input.name}: the dataset ${input.datasetId} changed`);
|
|
102
|
+
else
|
|
103
|
+
inputs.push({ ...input, source: datasets?.file(record) });
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
const source = join(folder, "input", input.name);
|
|
107
|
+
let actual;
|
|
108
|
+
try {
|
|
109
|
+
actual = await sha256OfFile(source);
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
problems.push(`Input ${input.name} is missing`);
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
if (actual !== (input.copySha256 ?? input.sha256))
|
|
116
|
+
problems.push(`Input ${input.name} changed (its sha256 no longer matches the original)`);
|
|
117
|
+
else
|
|
118
|
+
inputs.push({ ...input, source });
|
|
119
|
+
}
|
|
120
|
+
if (problems.length)
|
|
121
|
+
return { ok: false, problems };
|
|
122
|
+
return {
|
|
123
|
+
ok: true,
|
|
124
|
+
plan: {
|
|
125
|
+
executionId: details.id,
|
|
126
|
+
...(resolved.artifactId ? { artifactId: resolved.artifactId } : {}),
|
|
127
|
+
code,
|
|
128
|
+
scriptSha256: details.scriptSha256,
|
|
129
|
+
inputs,
|
|
130
|
+
manifest: recorded?.manifest ?? [],
|
|
131
|
+
extras: (recorded?.extras ?? []).filter((e) => e === "analysis" || e === "science"),
|
|
132
|
+
runtime: details.runtime,
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import type { InstallPreview } from "@alisio/sdk";
|
|
2
|
+
export declare const MIN_PYTHON: readonly [number, number];
|
|
3
|
+
/** Prints `[[major, minor, micro], executable]` as JSON. */
|
|
4
|
+
export declare const PROBE_CODE = "import sys, json; print(json.dumps([list(sys.version_info[:3]), sys.executable]))";
|
|
5
|
+
export type CandidateSource = "flag" | "uv" | "py" | "python3" | "python";
|
|
6
|
+
export interface PythonCandidate {
|
|
7
|
+
source: CandidateSource;
|
|
8
|
+
/** Absolute path of the launcher or interpreter found on PATH (or the `--python` path). */
|
|
9
|
+
command: string;
|
|
10
|
+
}
|
|
11
|
+
export interface FileInfo {
|
|
12
|
+
mtimeMs: number;
|
|
13
|
+
isFile: boolean;
|
|
14
|
+
}
|
|
15
|
+
export interface DiscoveryDeps {
|
|
16
|
+
platform: NodeJS.Platform;
|
|
17
|
+
/** `PATH` of the process. */
|
|
18
|
+
path: string;
|
|
19
|
+
/** Windows `PATHEXT`. */
|
|
20
|
+
pathext?: string;
|
|
21
|
+
/** Windows `%LOCALAPPDATA%` (to skip the Microsoft Store alias). */
|
|
22
|
+
localAppData?: string;
|
|
23
|
+
stat(path: string): Promise<FileInfo | undefined>;
|
|
24
|
+
/** Runs a probe; never a shell. */
|
|
25
|
+
exec(command: string, args: string[], signal: AbortSignal): Promise<{
|
|
26
|
+
stdout: string;
|
|
27
|
+
exitCode: number;
|
|
28
|
+
}>;
|
|
29
|
+
}
|
|
30
|
+
export type PythonResolution = {
|
|
31
|
+
ok: true;
|
|
32
|
+
executable: string;
|
|
33
|
+
version: string;
|
|
34
|
+
source: CandidateSource;
|
|
35
|
+
venv?: boolean;
|
|
36
|
+
/** Arguments placed before the interpreter flags (embedders and test launchers only). */
|
|
37
|
+
prefixArgs?: string[];
|
|
38
|
+
} | {
|
|
39
|
+
ok: false;
|
|
40
|
+
/** Human-readable cause. */
|
|
41
|
+
reason: string;
|
|
42
|
+
/** A Python that was found but is too old, or the unusable `--python`. */
|
|
43
|
+
found?: {
|
|
44
|
+
version?: string;
|
|
45
|
+
path: string;
|
|
46
|
+
reason?: string;
|
|
47
|
+
};
|
|
48
|
+
/** `--python` was given (no other candidate was tried). */
|
|
49
|
+
flag?: boolean;
|
|
50
|
+
};
|
|
51
|
+
/** The interpreter of a virtual environment, built with the target platform's path rules. */
|
|
52
|
+
export declare function venvInterpreter(venv: string, platform?: NodeJS.Platform): string;
|
|
53
|
+
/** `3.10.12` → true when at least `MIN_PYTHON`. */
|
|
54
|
+
export declare function supportedVersion(version: string): boolean;
|
|
55
|
+
/** Parses the probe output; undefined when it is not ours. */
|
|
56
|
+
export declare function parseProbe(stdout: string): {
|
|
57
|
+
version: string;
|
|
58
|
+
executable: string;
|
|
59
|
+
} | undefined;
|
|
60
|
+
export declare function defaultDiscoveryDeps(): DiscoveryDeps;
|
|
61
|
+
export type Extras = "analysis" | "science";
|
|
62
|
+
/**
|
|
63
|
+
* The installation failed. `offline` means the download could not start or finish because there
|
|
64
|
+
* is no network (or the package index is unreachable): nothing was installed and the base runtime
|
|
65
|
+
* is untouched, so the message says so and how to retry.
|
|
66
|
+
*/
|
|
67
|
+
export declare class ExtrasInstallError extends Error {
|
|
68
|
+
readonly kind: "offline" | "failed";
|
|
69
|
+
constructor(message: string, kind: "offline" | "failed");
|
|
70
|
+
}
|
|
71
|
+
/** The command that installs the extras by hand (the optional, explicit route). */
|
|
72
|
+
export declare const setupCommand: (extras: Extras) => string;
|
|
73
|
+
/** What an `analysis.install` approval shows for a set of extras. */
|
|
74
|
+
export declare function installPreview(extras: Extras): InstallPreview;
|
|
75
|
+
/** Runs one installation step (replaceable in tests so no network or pip is needed). */
|
|
76
|
+
export type InstallStep = (command: string, args: string[], options: {
|
|
77
|
+
cwd: string;
|
|
78
|
+
signal: AbortSignal;
|
|
79
|
+
onOutput?: (text: string) => void;
|
|
80
|
+
}) => Promise<{
|
|
81
|
+
exitCode: number;
|
|
82
|
+
stdout: string;
|
|
83
|
+
stderr: string;
|
|
84
|
+
}>;
|
|
85
|
+
/** Persisted state of an extras environment (`runtime.json`). */
|
|
86
|
+
export interface RuntimeState {
|
|
87
|
+
runtimeVersion: string;
|
|
88
|
+
python: string;
|
|
89
|
+
pythonVersion: string;
|
|
90
|
+
extras: Extras[];
|
|
91
|
+
createdAt: number;
|
|
92
|
+
ok: boolean;
|
|
93
|
+
}
|
|
94
|
+
export declare class AnalysisRuntimeManager {
|
|
95
|
+
private options;
|
|
96
|
+
readonly deps: DiscoveryDeps;
|
|
97
|
+
private memory?;
|
|
98
|
+
constructor(options: {
|
|
99
|
+
/** State root (`stateHome()` or the folder of `--db`). */
|
|
100
|
+
stateDir: string;
|
|
101
|
+
/** `--python <path>`: pins the interpreter; nothing else is tried. */
|
|
102
|
+
python?: string;
|
|
103
|
+
deps?: Partial<DiscoveryDeps>;
|
|
104
|
+
/** Replaces the installation steps (tests: a fake pip, no network). */
|
|
105
|
+
install?: InstallStep;
|
|
106
|
+
});
|
|
107
|
+
get pythonFlag(): string | undefined;
|
|
108
|
+
private get dir();
|
|
109
|
+
private sep;
|
|
110
|
+
/** First PATH match of `name` (with `PATHEXT` on Windows), by `stat` only. */
|
|
111
|
+
private onPath;
|
|
112
|
+
/** The Microsoft Store alias opens the Store instead of running Python. */
|
|
113
|
+
private storeAlias;
|
|
114
|
+
/** Candidate executables, in discovery order (stat only; launches nothing). */
|
|
115
|
+
candidates(): Promise<PythonCandidate[]>;
|
|
116
|
+
private readCache;
|
|
117
|
+
private writeCache;
|
|
118
|
+
/** Probes one interpreter path: its version and real executable, or undefined. */
|
|
119
|
+
private probe;
|
|
120
|
+
/**
|
|
121
|
+
* The interpreter to run: the cached one while its file is unchanged, else a fresh discovery.
|
|
122
|
+
* With `--python`, only that path is considered.
|
|
123
|
+
*/
|
|
124
|
+
resolve(signal?: AbortSignal): Promise<PythonResolution>;
|
|
125
|
+
/** The interpreter `python_run` uses: an installed extras environment, else the base one. */
|
|
126
|
+
interpreter(signal?: AbortSignal): Promise<PythonResolution & {
|
|
127
|
+
extras?: Extras[];
|
|
128
|
+
runtimeVersion?: string;
|
|
129
|
+
}>;
|
|
130
|
+
/** The extras environment recorded by `alisio analysis setup --extras`, when healthy. */
|
|
131
|
+
activeRuntime(): Promise<RuntimeState | undefined>;
|
|
132
|
+
private installing;
|
|
133
|
+
/** Whether the healthy extras environment already provides `extras` (`science` includes `analysis`). */
|
|
134
|
+
hasExtras(extras: Extras): Promise<boolean>;
|
|
135
|
+
/**
|
|
136
|
+
* Creates the extras environment and installs the hash-locked wheels (`--require-hashes`,
|
|
137
|
+
* `--only-binary=:all:`; nothing is compiled). Needs network. Never called by `python_run`
|
|
138
|
+
* without an `analysis.install` approval. Failing (offline, no wheel for this platform) leaves
|
|
139
|
+
* no half-built environment and does not touch the active one. Concurrent calls share one run.
|
|
140
|
+
*/
|
|
141
|
+
installExtras(extras: Extras, options: {
|
|
142
|
+
signal: AbortSignal;
|
|
143
|
+
onOutput?: (text: string) => void;
|
|
144
|
+
}): Promise<RuntimeState>;
|
|
145
|
+
private doInstall;
|
|
146
|
+
}
|