paracosm 0.7.409 → 0.7.431
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 +79 -14
- package/dist/cli/compile.d.ts +1 -1
- package/dist/cli/compile.js +4 -4
- package/dist/cli/fetch-seed-url.d.ts +48 -0
- package/dist/cli/fetch-seed-url.d.ts.map +1 -0
- package/dist/cli/fetch-seed-url.js +109 -0
- package/dist/cli/fetch-seed-url.js.map +1 -0
- package/dist/cli/fork-preconditions.d.ts +17 -0
- package/dist/cli/fork-preconditions.d.ts.map +1 -0
- package/dist/cli/fork-preconditions.js +51 -0
- package/dist/cli/fork-preconditions.js.map +1 -0
- package/dist/cli/init-templates.d.ts +43 -0
- package/dist/cli/init-templates.d.ts.map +1 -0
- package/dist/cli/init-templates.js +141 -0
- package/dist/cli/init-templates.js.map +1 -0
- package/dist/cli/init.d.ts +46 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +207 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/pair-runner.d.ts +25 -2
- package/dist/cli/pair-runner.d.ts.map +1 -1
- package/dist/cli/pair-runner.js +141 -5
- package/dist/cli/pair-runner.js.map +1 -1
- package/dist/cli/quickstart-routes.d.ts +35 -0
- package/dist/cli/quickstart-routes.d.ts.map +1 -0
- package/dist/cli/quickstart-routes.js +100 -0
- package/dist/cli/quickstart-routes.js.map +1 -0
- package/dist/cli/run.js +8 -0
- package/dist/cli/run.js.map +1 -1
- package/dist/cli/server/enrich-run-record.d.ts +22 -0
- package/dist/cli/server/enrich-run-record.d.ts.map +1 -0
- package/dist/cli/server/enrich-run-record.js +27 -0
- package/dist/cli/server/enrich-run-record.js.map +1 -0
- package/dist/cli/server/routes/platform-api.d.ts +19 -3
- package/dist/cli/server/routes/platform-api.d.ts.map +1 -1
- package/dist/cli/server/routes/platform-api.js +174 -5
- package/dist/cli/server/routes/platform-api.js.map +1 -1
- package/dist/cli/server/run-history-store.d.ts +27 -1
- package/dist/cli/server/run-history-store.d.ts.map +1 -1
- package/dist/cli/server/run-history-store.js +5 -0
- package/dist/cli/server/run-history-store.js.map +1 -1
- package/dist/cli/server/run-record.d.ts +13 -0
- package/dist/cli/server/run-record.d.ts.map +1 -1
- package/dist/cli/server/run-record.js.map +1 -1
- package/dist/cli/server/sqlite-run-history-store.d.ts +6 -0
- package/dist/cli/server/sqlite-run-history-store.d.ts.map +1 -0
- package/dist/cli/server/sqlite-run-history-store.js +226 -0
- package/dist/cli/server/sqlite-run-history-store.js.map +1 -0
- package/dist/cli/server-app.d.ts +73 -2
- package/dist/cli/server-app.d.ts.map +1 -1
- package/dist/cli/server-app.js +409 -159
- package/dist/cli/server-app.js.map +1 -1
- package/dist/cli/session-title.js +1 -1
- package/dist/cli/sim-config.d.ts +13 -0
- package/dist/cli/sim-config.d.ts.map +1 -1
- package/dist/cli/sim-config.js +8 -1
- package/dist/cli/sim-config.js.map +1 -1
- package/dist/cli/simulate-route.d.ts +103 -0
- package/dist/cli/simulate-route.d.ts.map +1 -0
- package/dist/cli/simulate-route.js +95 -0
- package/dist/cli/simulate-route.js.map +1 -0
- package/dist/engine/compiler/cache.d.ts +2 -2
- package/dist/engine/compiler/cache.js +2 -2
- package/dist/engine/compiler/compile-from-seed.d.ts +78 -0
- package/dist/engine/compiler/compile-from-seed.d.ts.map +1 -0
- package/dist/engine/compiler/compile-from-seed.js +93 -0
- package/dist/engine/compiler/compile-from-seed.js.map +1 -0
- package/dist/engine/compiler/generate-fingerprint.d.ts.map +1 -1
- package/dist/engine/compiler/generate-fingerprint.js +3 -6
- package/dist/engine/compiler/generate-fingerprint.js.map +1 -1
- package/dist/engine/compiler/generate-politics.d.ts.map +1 -1
- package/dist/engine/compiler/generate-politics.js +3 -6
- package/dist/engine/compiler/generate-politics.js.map +1 -1
- package/dist/engine/compiler/generate-progression.d.ts +10 -1
- package/dist/engine/compiler/generate-progression.d.ts.map +1 -1
- package/dist/engine/compiler/generate-progression.js +15 -15
- package/dist/engine/compiler/generate-progression.js.map +1 -1
- package/dist/engine/compiler/generate-prompts.d.ts.map +1 -1
- package/dist/engine/compiler/generate-prompts.js +4 -7
- package/dist/engine/compiler/generate-prompts.js.map +1 -1
- package/dist/engine/compiler/generate-reactions.d.ts.map +1 -1
- package/dist/engine/compiler/generate-reactions.js +3 -6
- package/dist/engine/compiler/generate-reactions.js.map +1 -1
- package/dist/engine/compiler/index.d.ts +9 -6
- package/dist/engine/compiler/index.d.ts.map +1 -1
- package/dist/engine/compiler/index.js +9 -6
- package/dist/engine/compiler/index.js.map +1 -1
- package/dist/engine/compiler/sandbox-runner.d.ts +40 -0
- package/dist/engine/compiler/sandbox-runner.d.ts.map +1 -0
- package/dist/engine/compiler/sandbox-runner.js +278 -0
- package/dist/engine/compiler/sandbox-runner.js.map +1 -0
- package/dist/engine/compiler/scenario-fixture.d.ts +4 -4
- package/dist/engine/compiler/scenario-fixture.js +4 -4
- package/dist/engine/compiler/seed-ingestion.d.ts +2 -2
- package/dist/engine/compiler/seed-ingestion.js +2 -2
- package/dist/engine/compiler/state-shape-block.d.ts +1 -1
- package/dist/engine/compiler/state-shape-block.js +5 -5
- package/dist/engine/compiler/types.d.ts +2 -2
- package/dist/engine/compiler/types.d.ts.map +1 -1
- package/dist/engine/compiler/validate.js +1 -1
- package/dist/engine/core/kernel.d.ts +4 -4
- package/dist/engine/core/kernel.js +6 -6
- package/dist/engine/core/progression.d.ts +3 -3
- package/dist/engine/core/progression.js +21 -21
- package/dist/engine/core/state.d.ts +7 -5
- package/dist/engine/core/state.d.ts.map +1 -1
- package/dist/engine/digital-twin/index.d.ts +41 -0
- package/dist/engine/digital-twin/index.d.ts.map +1 -0
- package/dist/engine/digital-twin/index.js +40 -0
- package/dist/engine/digital-twin/index.js.map +1 -0
- package/dist/engine/index.d.ts +1 -1
- package/dist/engine/leader-presets.d.ts +39 -0
- package/dist/engine/leader-presets.d.ts.map +1 -0
- package/dist/engine/leader-presets.js +118 -0
- package/dist/engine/leader-presets.js.map +1 -0
- package/dist/engine/lunar/fingerprint.js +2 -2
- package/dist/engine/lunar/prompts.js +2 -2
- package/dist/engine/mars/fingerprint.js +1 -1
- package/dist/engine/mars/metrics.d.ts +2 -2
- package/dist/engine/mars/metrics.js +2 -2
- package/dist/engine/mars/prompts.js +3 -3
- package/dist/runtime/build-artifact.d.ts +2 -1
- package/dist/runtime/build-artifact.d.ts.map +1 -1
- package/dist/runtime/build-artifact.js +2 -1
- package/dist/runtime/build-artifact.js.map +1 -1
- package/dist/runtime/canonical-json.d.ts +25 -0
- package/dist/runtime/canonical-json.d.ts.map +1 -0
- package/dist/runtime/canonical-json.js +46 -0
- package/dist/runtime/canonical-json.js.map +1 -0
- package/dist/runtime/contracts.d.ts +1 -1
- package/dist/runtime/departments.js +1 -1
- package/dist/runtime/orchestrator.d.ts +44 -4
- package/dist/runtime/orchestrator.d.ts.map +1 -1
- package/dist/runtime/orchestrator.js +125 -33
- package/dist/runtime/orchestrator.js.map +1 -1
- package/dist/runtime/parsers.js +5 -5
- package/dist/runtime/reaction-step.js +2 -2
- package/dist/runtime/world-model/index.d.ts +172 -18
- package/dist/runtime/world-model/index.d.ts.map +1 -1
- package/dist/runtime/world-model/index.js +242 -4
- package/dist/runtime/world-model/index.js.map +1 -1
- package/dist/runtime/world-snapshot.d.ts +13 -0
- package/dist/runtime/world-snapshot.d.ts.map +1 -0
- package/dist/runtime/world-snapshot.js +19 -0
- package/dist/runtime/world-snapshot.js.map +1 -0
- package/package.json +19 -4
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure renderer functions for the files emitted by `paracosm init`.
|
|
3
|
+
* Each function takes a small input record and returns the file contents
|
|
4
|
+
* as a string. No I/O, no dependencies on the caller's environment.
|
|
5
|
+
*
|
|
6
|
+
* Kept separate from init.ts so the renderers snapshot-test trivially.
|
|
7
|
+
*
|
|
8
|
+
* @module paracosm/cli/init-templates
|
|
9
|
+
*/
|
|
10
|
+
export function renderPackageJson(input) {
|
|
11
|
+
const pkg = {
|
|
12
|
+
name: input.name,
|
|
13
|
+
version: '0.1.0',
|
|
14
|
+
private: true,
|
|
15
|
+
type: 'module',
|
|
16
|
+
scripts: {
|
|
17
|
+
start: 'node run.mjs',
|
|
18
|
+
},
|
|
19
|
+
dependencies: {
|
|
20
|
+
paracosm: `^${input.paracosmVersion}`,
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
return JSON.stringify(pkg, null, 2) + '\n';
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Render the entry script for a paracosm-init scaffolded project.
|
|
27
|
+
*
|
|
28
|
+
* The script imports `runSimulation` from `paracosm/runtime` and runs the
|
|
29
|
+
* leader at index 0 against a turn-loop simulation. Mode is intentionally
|
|
30
|
+
* NOT a runtime input: it is a property of the produced
|
|
31
|
+
* `RunArtifact.metadata`, surfaced after the run completes. Batch-trajectory
|
|
32
|
+
* and batch-point modes are produced by `runBatch` (different entry point,
|
|
33
|
+
* different config shape); a future spec adds a separate `renderRunMjsBatch`
|
|
34
|
+
* for those modes.
|
|
35
|
+
*/
|
|
36
|
+
export function renderRunMjs() {
|
|
37
|
+
return `#!/usr/bin/env node
|
|
38
|
+
/**
|
|
39
|
+
* Entry script for a paracosm-init scaffolded project.
|
|
40
|
+
*
|
|
41
|
+
* Reads scenario.json + leaders.json from this directory, runs the
|
|
42
|
+
* configured leader at index 0, and prints the resulting RunArtifact JSON.
|
|
43
|
+
* Edit the leader index, maxTurns, or seed below to explore.
|
|
44
|
+
*
|
|
45
|
+
* The "mode" of the resulting run lives on artifact.metadata.mode and is
|
|
46
|
+
* always "turn-loop" for runs produced by runSimulation. For
|
|
47
|
+
* batch-trajectory or batch-point modes, use runBatch directly.
|
|
48
|
+
*/
|
|
49
|
+
import { readFileSync } from 'node:fs';
|
|
50
|
+
import { resolve, dirname } from 'node:path';
|
|
51
|
+
import { fileURLToPath } from 'node:url';
|
|
52
|
+
import { runSimulation } from 'paracosm/runtime';
|
|
53
|
+
|
|
54
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
55
|
+
const scenario = JSON.parse(readFileSync(resolve(here, 'scenario.json'), 'utf-8'));
|
|
56
|
+
const leaders = JSON.parse(readFileSync(resolve(here, 'leaders.json'), 'utf-8'));
|
|
57
|
+
|
|
58
|
+
if (!Array.isArray(leaders) || leaders.length === 0) {
|
|
59
|
+
console.error('leaders.json is empty. Re-run \\\`paracosm init\\\` to regenerate.');
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const leader = leaders[0];
|
|
64
|
+
|
|
65
|
+
const result = await runSimulation(leader, [], {
|
|
66
|
+
scenario,
|
|
67
|
+
maxTurns: 6,
|
|
68
|
+
seed: 42,
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
console.log(JSON.stringify(result, null, 2));
|
|
72
|
+
`;
|
|
73
|
+
}
|
|
74
|
+
export function renderReadme(input) {
|
|
75
|
+
return `# ${input.name}
|
|
76
|
+
|
|
77
|
+
Scaffolded by \`paracosm init\` from the seed:
|
|
78
|
+
|
|
79
|
+
> ${input.domain.slice(0, 200)}${input.domain.length > 200 ? '...' : ''}
|
|
80
|
+
|
|
81
|
+
This project contains:
|
|
82
|
+
|
|
83
|
+
- \`scenario.json\`: compiled \`ScenarioPackage\` (LLM-generated at init time)
|
|
84
|
+
- \`leaders.json\`: ${input.leaders} HEXACO leader configs (LLM-generated)
|
|
85
|
+
- \`run.mjs\`: minimal entry script that runs leader 0 in \`${input.mode}\` mode
|
|
86
|
+
|
|
87
|
+
## Quickstart
|
|
88
|
+
|
|
89
|
+
\`\`\`bash
|
|
90
|
+
npm install
|
|
91
|
+
cp .env.example .env
|
|
92
|
+
# Set OPENAI_API_KEY (and any other provider keys you need) in .env
|
|
93
|
+
node run.mjs
|
|
94
|
+
\`\`\`
|
|
95
|
+
|
|
96
|
+
## Customizing
|
|
97
|
+
|
|
98
|
+
- Edit \`scenario.json\` to tweak departments, world state, events.
|
|
99
|
+
- Edit \`leaders.json\` to swap HEXACO traits or instructions.
|
|
100
|
+
- Edit \`run.mjs\` to change the leader index, mode, turn count, or seed.
|
|
101
|
+
|
|
102
|
+
See https://github.com/framersai/paracosm for the full API reference.
|
|
103
|
+
`;
|
|
104
|
+
}
|
|
105
|
+
export function renderEnvExample() {
|
|
106
|
+
return `# Required for compileScenario / generateText / generateObject calls.
|
|
107
|
+
OPENAI_API_KEY=
|
|
108
|
+
|
|
109
|
+
# Optional alternate providers paracosm can route to.
|
|
110
|
+
ANTHROPIC_API_KEY=
|
|
111
|
+
GOOGLE_API_KEY=
|
|
112
|
+
|
|
113
|
+
# Optional Cohere rerank for higher-accuracy retrieval.
|
|
114
|
+
COHERE_API_KEY=
|
|
115
|
+
`;
|
|
116
|
+
}
|
|
117
|
+
export function renderGitignore() {
|
|
118
|
+
return `node_modules/
|
|
119
|
+
.env
|
|
120
|
+
.paracosm/
|
|
121
|
+
dist/
|
|
122
|
+
*.log
|
|
123
|
+
.DS_Store
|
|
124
|
+
`;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Slug-normalize a project name. Lowercase ASCII, dashes between words,
|
|
128
|
+
* strips everything else, max 50 chars. If empty after stripping,
|
|
129
|
+
* returns 'paracosm-app'.
|
|
130
|
+
*/
|
|
131
|
+
export function slugifyName(raw) {
|
|
132
|
+
const slug = raw
|
|
133
|
+
.toLowerCase()
|
|
134
|
+
.normalize('NFKD')
|
|
135
|
+
.replace(/[̀-ͯ]/g, '')
|
|
136
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
137
|
+
.replace(/^-+|-+$/g, '')
|
|
138
|
+
.slice(0, 50);
|
|
139
|
+
return slug || 'paracosm-app';
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=init-templates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-templates.js","sourceRoot":"","sources":["../../src/cli/init-templates.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAOH,MAAM,UAAU,iBAAiB,CAAC,KAAuB;IACvD,MAAM,GAAG,GAAG;QACV,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,OAAO,EAAE,OAAO;QAChB,OAAO,EAAE,IAAI;QACb,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE;YACP,KAAK,EAAE,cAAc;SACtB;QACD,YAAY,EAAE;YACZ,QAAQ,EAAE,IAAI,KAAK,CAAC,eAAe,EAAE;SACtC;KACF,CAAC;IACF,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;AAC7C,CAAC;AAID;;;;;;;;;;GAUG;AACH,MAAM,UAAU,YAAY;IAC1B,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmCR,CAAC;AACF,CAAC;AASD,MAAM,UAAU,YAAY,CAAC,KAAkB;IAC7C,OAAO,KAAK,KAAK,CAAC,IAAI;;;;IAIpB,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;;;;;sBAKjD,KAAK,CAAC,OAAO;8DAC2B,KAAK,CAAC,IAAI;;;;;;;;;;;;;;;;;;CAkBvE,CAAC;AACF,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,OAAO;;;;;;;;;CASR,CAAC;AACF,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO;;;;;;CAMR,CAAC;AACF,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,MAAM,IAAI,GAAG,GAAG;SACb,WAAW,EAAE;SACb,SAAS,CAAC,MAAM,CAAC;SACjB,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;SACrB,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;SACvB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAChB,OAAO,IAAI,IAAI,cAAc,CAAC;AAChC,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { compileFromSeed } from '../engine/compiler/compile-from-seed.js';
|
|
2
|
+
import { generateQuickstartLeaders } from '../runtime/world-model/index.js';
|
|
3
|
+
import { type SimulationMode } from './init-templates.js';
|
|
4
|
+
export interface InitOptions {
|
|
5
|
+
outputDir: string;
|
|
6
|
+
domain: string;
|
|
7
|
+
mode: SimulationMode;
|
|
8
|
+
leaders: number;
|
|
9
|
+
name: string;
|
|
10
|
+
force: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface InitArgError {
|
|
13
|
+
ok: false;
|
|
14
|
+
message: string;
|
|
15
|
+
}
|
|
16
|
+
export type InitArgResult = {
|
|
17
|
+
ok: true;
|
|
18
|
+
options: InitOptions;
|
|
19
|
+
} | InitArgError;
|
|
20
|
+
/**
|
|
21
|
+
* Parse the argv slice that follows `paracosm init`. Returns either a
|
|
22
|
+
* fully-resolved InitOptions or an InitArgError with a user-facing
|
|
23
|
+
* message that includes USAGE.
|
|
24
|
+
*/
|
|
25
|
+
export declare function parseInitArgs(argv: readonly string[]): InitArgResult;
|
|
26
|
+
/**
|
|
27
|
+
* Hook seam for tests. Real implementation calls compileFromSeed +
|
|
28
|
+
* generateQuickstartLeaders + URL fetch directly. Tests pass mocks.
|
|
29
|
+
*/
|
|
30
|
+
export interface RunInitDeps {
|
|
31
|
+
fetchSeedFromUrl?: (url: string) => Promise<{
|
|
32
|
+
text: string;
|
|
33
|
+
title: string;
|
|
34
|
+
}>;
|
|
35
|
+
compileFromSeed?: typeof compileFromSeed;
|
|
36
|
+
generateQuickstartLeaders?: typeof generateQuickstartLeaders;
|
|
37
|
+
readEnv?: () => NodeJS.ProcessEnv;
|
|
38
|
+
paracosmVersion?: string;
|
|
39
|
+
log?: (msg: string) => void;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Main flow. Returns 0 on success, non-zero on user-facing error
|
|
43
|
+
* (also prints a message to stderr in the error case).
|
|
44
|
+
*/
|
|
45
|
+
export declare function runInit(argv: readonly string[], deps?: RunInitDeps): Promise<number>;
|
|
46
|
+
//# sourceMappingURL=init.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,EAAE,yBAAyB,EAAE,MAAM,iCAAiC,CAAC;AAE5E,OAAO,EAOL,KAAK,cAAc,EACpB,MAAM,qBAAqB,CAAC;AAE7B,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,cAAc,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,KAAK,CAAC;IACV,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,aAAa,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,WAAW,CAAA;CAAE,GAAG,YAAY,CAAC;AAqB9E;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,aAAa,CA0DpE;AA6BD;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7E,eAAe,CAAC,EAAE,OAAO,eAAe,CAAC;IACzC,yBAAyB,CAAC,EAAE,OAAO,yBAAyB,CAAC;IAC7D,OAAO,CAAC,EAAE,MAAM,MAAM,CAAC,UAAU,CAAC;IAClC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAED;;;GAGG;AACH,wBAAsB,OAAO,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAgF9F"}
|
package/dist/cli/init.js
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `paracosm init` subcommand. Scaffolds a runnable paracosm project
|
|
3
|
+
* from a seed text or URL via the existing compileFromSeed +
|
|
4
|
+
* generateQuickstartLeaders infrastructure.
|
|
5
|
+
*
|
|
6
|
+
* Flag-driven only (no interactive prompts) so it composes with shell
|
|
7
|
+
* scripts and CI. URL handling mirrors the server-app.ts pattern that
|
|
8
|
+
* dynamically imports AgentOS WebSearchService from the web-search subpath.
|
|
9
|
+
*
|
|
10
|
+
* @module paracosm/cli/init
|
|
11
|
+
*/
|
|
12
|
+
import { mkdirSync, readdirSync, writeFileSync, existsSync, readFileSync } from 'node:fs';
|
|
13
|
+
import { resolve, basename, dirname } from 'node:path';
|
|
14
|
+
import { fileURLToPath } from 'node:url';
|
|
15
|
+
import { compileFromSeed } from '../engine/compiler/compile-from-seed.js';
|
|
16
|
+
import { generateQuickstartLeaders } from '../runtime/world-model/index.js';
|
|
17
|
+
import { fetchSeedFromUrl as fetchSeedFromUrlViaAgentOS } from './fetch-seed-url.js';
|
|
18
|
+
import { renderPackageJson, renderRunMjs, renderReadme, renderEnvExample, renderGitignore, slugifyName, } from './init-templates.js';
|
|
19
|
+
const VALID_MODES = new Set([
|
|
20
|
+
'turn-loop',
|
|
21
|
+
'batch-trajectory',
|
|
22
|
+
'batch-point',
|
|
23
|
+
]);
|
|
24
|
+
const USAGE = `paracosm init [dir] --domain <text|url> [--mode <m>] [--leaders <n>] [--name <name>] [--force]
|
|
25
|
+
|
|
26
|
+
dir output directory (default: ./paracosm-app)
|
|
27
|
+
--domain required: seed text describing the scenario, OR a URL
|
|
28
|
+
--mode turn-loop | batch-trajectory | batch-point (default: turn-loop)
|
|
29
|
+
--leaders number of HEXACO leaders, 2-6 (default: 3)
|
|
30
|
+
--name project name, default: derived from --domain
|
|
31
|
+
--force overwrite non-empty target dir
|
|
32
|
+
|
|
33
|
+
example:
|
|
34
|
+
paracosm init my-app --domain "Submarine crew of 8 in deep ocean for 30 days" --leaders 3
|
|
35
|
+
`;
|
|
36
|
+
/**
|
|
37
|
+
* Parse the argv slice that follows `paracosm init`. Returns either a
|
|
38
|
+
* fully-resolved InitOptions or an InitArgError with a user-facing
|
|
39
|
+
* message that includes USAGE.
|
|
40
|
+
*/
|
|
41
|
+
export function parseInitArgs(argv) {
|
|
42
|
+
let outputDir;
|
|
43
|
+
let domain;
|
|
44
|
+
let mode = 'turn-loop';
|
|
45
|
+
let leaders = 3;
|
|
46
|
+
let name;
|
|
47
|
+
let force = false;
|
|
48
|
+
for (let i = 0; i < argv.length; i++) {
|
|
49
|
+
const arg = argv[i];
|
|
50
|
+
if (arg === '--domain') {
|
|
51
|
+
domain = argv[++i];
|
|
52
|
+
}
|
|
53
|
+
else if (arg === '--mode') {
|
|
54
|
+
const candidate = argv[++i];
|
|
55
|
+
if (!VALID_MODES.has(candidate)) {
|
|
56
|
+
return { ok: false, message: `Invalid --mode "${candidate}". Must be one of: turn-loop, batch-trajectory, batch-point.\n\n${USAGE}` };
|
|
57
|
+
}
|
|
58
|
+
mode = candidate;
|
|
59
|
+
}
|
|
60
|
+
else if (arg === '--leaders') {
|
|
61
|
+
const n = Number(argv[++i]);
|
|
62
|
+
if (!Number.isFinite(n) || n < 2 || n > 6 || !Number.isInteger(n)) {
|
|
63
|
+
return { ok: false, message: `Invalid --leaders "${argv[i]}". Must be an integer in [2, 6].\n\n${USAGE}` };
|
|
64
|
+
}
|
|
65
|
+
leaders = n;
|
|
66
|
+
}
|
|
67
|
+
else if (arg === '--name') {
|
|
68
|
+
name = argv[++i];
|
|
69
|
+
}
|
|
70
|
+
else if (arg === '--force') {
|
|
71
|
+
force = true;
|
|
72
|
+
}
|
|
73
|
+
else if (arg.startsWith('--')) {
|
|
74
|
+
return { ok: false, message: `Unknown flag: ${arg}\n\n${USAGE}` };
|
|
75
|
+
}
|
|
76
|
+
else if (outputDir === undefined) {
|
|
77
|
+
outputDir = arg;
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
return { ok: false, message: `Unexpected positional argument: ${arg}\n\n${USAGE}` };
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (!domain) {
|
|
84
|
+
return { ok: false, message: `--domain is required.\n\n${USAGE}` };
|
|
85
|
+
}
|
|
86
|
+
if (domain.length > 50_000) {
|
|
87
|
+
return { ok: false, message: `--domain too long (${domain.length} chars; max 50000).\n\n${USAGE}` };
|
|
88
|
+
}
|
|
89
|
+
const resolvedDir = resolve(outputDir ?? './paracosm-app');
|
|
90
|
+
const resolvedName = name ?? slugifyName(basename(resolvedDir));
|
|
91
|
+
return {
|
|
92
|
+
ok: true,
|
|
93
|
+
options: {
|
|
94
|
+
outputDir: resolvedDir,
|
|
95
|
+
domain,
|
|
96
|
+
mode,
|
|
97
|
+
leaders,
|
|
98
|
+
name: resolvedName,
|
|
99
|
+
force,
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
function isUrl(s) {
|
|
104
|
+
return /^https?:\/\//.test(s);
|
|
105
|
+
}
|
|
106
|
+
function isDirEmpty(dir) {
|
|
107
|
+
if (!existsSync(dir))
|
|
108
|
+
return true;
|
|
109
|
+
return readdirSync(dir).length === 0;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Read the paracosm package.json sitting two directories up from this
|
|
113
|
+
* module file. Works from both the tsx (src/cli/init.ts) and built
|
|
114
|
+
* (dist/cli/init.js) layouts because both mirror src/.
|
|
115
|
+
*
|
|
116
|
+
* @returns The semver version string from paracosm's package.json.
|
|
117
|
+
* @throws Error when the package.json is unreadable or missing a version.
|
|
118
|
+
*/
|
|
119
|
+
function readOwnVersion() {
|
|
120
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
121
|
+
const pkgPath = resolve(here, '../../package.json');
|
|
122
|
+
const raw = JSON.parse(readFileSync(pkgPath, 'utf-8'));
|
|
123
|
+
if (typeof raw.version !== 'string' || raw.version.length === 0) {
|
|
124
|
+
throw new Error('paracosm package.json is missing a version field');
|
|
125
|
+
}
|
|
126
|
+
return raw.version;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Main flow. Returns 0 on success, non-zero on user-facing error
|
|
130
|
+
* (also prints a message to stderr in the error case).
|
|
131
|
+
*/
|
|
132
|
+
export async function runInit(argv, deps = {}) {
|
|
133
|
+
const log = deps.log ?? ((m) => console.log(m));
|
|
134
|
+
const env = (deps.readEnv ?? (() => process.env))();
|
|
135
|
+
const parsed = parseInitArgs(argv);
|
|
136
|
+
if (!parsed.ok) {
|
|
137
|
+
process.stderr.write(parsed.message + '\n');
|
|
138
|
+
return 2;
|
|
139
|
+
}
|
|
140
|
+
const opts = parsed.options;
|
|
141
|
+
if (!env.OPENAI_API_KEY) {
|
|
142
|
+
process.stderr.write('Set OPENAI_API_KEY in your environment before running paracosm init.\n');
|
|
143
|
+
return 2;
|
|
144
|
+
}
|
|
145
|
+
if (!isDirEmpty(opts.outputDir) && !opts.force) {
|
|
146
|
+
process.stderr.write(`Target directory ${opts.outputDir} is not empty. Pass --force to overwrite.\n`);
|
|
147
|
+
return 2;
|
|
148
|
+
}
|
|
149
|
+
// Resolve seed text: URL fetch or pass-through.
|
|
150
|
+
let seedText = opts.domain;
|
|
151
|
+
if (isUrl(opts.domain)) {
|
|
152
|
+
log(`[paracosm init] Resolving URL: ${opts.domain}`);
|
|
153
|
+
try {
|
|
154
|
+
const fetcher = deps.fetchSeedFromUrl ?? fetchSeedFromUrlViaAgentOS;
|
|
155
|
+
const fetched = await fetcher(opts.domain);
|
|
156
|
+
seedText = fetched.text;
|
|
157
|
+
}
|
|
158
|
+
catch (err) {
|
|
159
|
+
process.stderr.write(`Failed to fetch URL ${opts.domain}: ${String(err)}\n`);
|
|
160
|
+
return 2;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
if (seedText.length < 200) {
|
|
164
|
+
process.stderr.write(`Seed text too short (${seedText.length} chars; minimum 200). For URLs, the fetched body must contain enough content.\n`);
|
|
165
|
+
return 2;
|
|
166
|
+
}
|
|
167
|
+
if (seedText.length > 50_000) {
|
|
168
|
+
seedText = seedText.slice(0, 50_000);
|
|
169
|
+
}
|
|
170
|
+
log(`[paracosm init] Compiling scenario...`);
|
|
171
|
+
let scenario;
|
|
172
|
+
try {
|
|
173
|
+
const compile = deps.compileFromSeed ?? compileFromSeed;
|
|
174
|
+
scenario = await compile({ seedText });
|
|
175
|
+
}
|
|
176
|
+
catch (err) {
|
|
177
|
+
process.stderr.write(`Scenario compile failed: ${String(err)}\n`);
|
|
178
|
+
return 2;
|
|
179
|
+
}
|
|
180
|
+
log(`[paracosm init] Generating ${opts.leaders} HEXACO leaders...`);
|
|
181
|
+
let leaders;
|
|
182
|
+
try {
|
|
183
|
+
const gen = deps.generateQuickstartLeaders ?? generateQuickstartLeaders;
|
|
184
|
+
leaders = await gen(scenario, opts.leaders, {});
|
|
185
|
+
}
|
|
186
|
+
catch (err) {
|
|
187
|
+
process.stderr.write(`Leader generation failed: ${String(err)}\n`);
|
|
188
|
+
return 2;
|
|
189
|
+
}
|
|
190
|
+
log(`[paracosm init] Writing files to ${opts.outputDir}/...`);
|
|
191
|
+
mkdirSync(opts.outputDir, { recursive: true });
|
|
192
|
+
const paracosmVersion = deps.paracosmVersion ?? readOwnVersion();
|
|
193
|
+
writeFileSync(`${opts.outputDir}/package.json`, renderPackageJson({ name: opts.name, paracosmVersion }));
|
|
194
|
+
writeFileSync(`${opts.outputDir}/scenario.json`, JSON.stringify(scenario, null, 2) + '\n');
|
|
195
|
+
writeFileSync(`${opts.outputDir}/leaders.json`, JSON.stringify(leaders, null, 2) + '\n');
|
|
196
|
+
writeFileSync(`${opts.outputDir}/run.mjs`, renderRunMjs());
|
|
197
|
+
writeFileSync(`${opts.outputDir}/README.md`, renderReadme({ name: opts.name, domain: opts.domain, mode: opts.mode, leaders: opts.leaders }));
|
|
198
|
+
writeFileSync(`${opts.outputDir}/.env.example`, renderEnvExample());
|
|
199
|
+
writeFileSync(`${opts.outputDir}/.gitignore`, renderGitignore());
|
|
200
|
+
log(`[paracosm init] Done. Run:`);
|
|
201
|
+
log(` cd ${basename(opts.outputDir)}`);
|
|
202
|
+
log(` npm install`);
|
|
203
|
+
log(` cp .env.example .env # edit to add your API key`);
|
|
204
|
+
log(` node run.mjs`);
|
|
205
|
+
return 0;
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC1F,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,EAAE,yBAAyB,EAAE,MAAM,iCAAiC,CAAC;AAC5E,OAAO,EAAE,gBAAgB,IAAI,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AACrF,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,WAAW,GAEZ,MAAM,qBAAqB,CAAC;AAkB7B,MAAM,WAAW,GAAgC,IAAI,GAAG,CAAC;IACvD,WAAW;IACX,kBAAkB;IAClB,aAAa;CACd,CAAC,CAAC;AAEH,MAAM,KAAK,GAAG;;;;;;;;;;;CAWb,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,IAAuB;IACnD,IAAI,SAA6B,CAAC;IAClC,IAAI,MAA0B,CAAC;IAC/B,IAAI,IAAI,GAAmB,WAAW,CAAC;IACvC,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,IAAwB,CAAC;IAC7B,IAAI,KAAK,GAAG,KAAK,CAAC;IAElB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,GAAG,KAAK,UAAU,EAAE,CAAC;YACvB,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QACrB,CAAC;aAAM,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC5B,MAAM,SAAS,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;YAC5B,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,SAA2B,CAAC,EAAE,CAAC;gBAClD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,mBAAmB,SAAS,mEAAmE,KAAK,EAAE,EAAE,CAAC;YACxI,CAAC;YACD,IAAI,GAAG,SAA2B,CAAC;QACrC,CAAC;aAAM,IAAI,GAAG,KAAK,WAAW,EAAE,CAAC;YAC/B,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAC5B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;gBAClE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,sBAAsB,IAAI,CAAC,CAAC,CAAC,uCAAuC,KAAK,EAAE,EAAE,CAAC;YAC7G,CAAC;YACD,OAAO,GAAG,CAAC,CAAC;QACd,CAAC;aAAM,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC5B,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QACnB,CAAC;aAAM,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YAC7B,KAAK,GAAG,IAAI,CAAC;QACf,CAAC;aAAM,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAChC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,KAAK,EAAE,EAAE,CAAC;QACpE,CAAC;aAAM,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YACnC,SAAS,GAAG,GAAG,CAAC;QAClB,CAAC;aAAM,CAAC;YACN,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,mCAAmC,GAAG,OAAO,KAAK,EAAE,EAAE,CAAC;QACtF,CAAC;IACH,CAAC;IAED,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,4BAA4B,KAAK,EAAE,EAAE,CAAC;IACrE,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC;QAC3B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,sBAAsB,MAAM,CAAC,MAAM,0BAA0B,KAAK,EAAE,EAAE,CAAC;IACtG,CAAC;IAED,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,IAAI,gBAAgB,CAAC,CAAC;IAC3D,MAAM,YAAY,GAAG,IAAI,IAAI,WAAW,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC;IAEhE,OAAO;QACL,EAAE,EAAE,IAAI;QACR,OAAO,EAAE;YACP,SAAS,EAAE,WAAW;YACtB,MAAM;YACN,IAAI;YACJ,OAAO;YACP,IAAI,EAAE,YAAY;YAClB,KAAK;SACN;KACF,CAAC;AACJ,CAAC;AAED,SAAS,KAAK,CAAC,CAAS;IACtB,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAChC,CAAC;AAED,SAAS,UAAU,CAAC,GAAW;IAC7B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAClC,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;AACvC,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,cAAc;IACrB,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACrD,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,oBAAoB,CAAC,CAAC;IACpD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAwB,CAAC;IAC9E,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChE,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,GAAG,CAAC,OAAO,CAAC;AACrB,CAAC;AAeD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,IAAuB,EAAE,OAAoB,EAAE;IAC3E,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;IAEpD,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IACnC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;QAC5C,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC;IAE5B,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC;QACxB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,wEAAwE,CAAC,CAAC;QAC/F,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAC/C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,IAAI,CAAC,SAAS,6CAA6C,CAAC,CAAC;QACtG,OAAO,CAAC,CAAC;IACX,CAAC;IAED,gDAAgD;IAChD,IAAI,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC;IAC3B,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACvB,GAAG,CAAC,kCAAkC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QACrD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,IAAI,0BAA0B,CAAC;YACpE,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC3C,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;QAC1B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,uBAAuB,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC7E,OAAO,CAAC,CAAC;QACX,CAAC;IACH,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;QAC1B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,wBAAwB,QAAQ,CAAC,MAAM,iFAAiF,CAAC,CAAC;QAC/I,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC;QAC7B,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IACvC,CAAC;IAED,GAAG,CAAC,uCAAuC,CAAC,CAAC;IAC7C,IAAI,QAAQ,CAAC;IACb,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,IAAI,eAAe,CAAC;QACxD,QAAQ,GAAG,MAAM,OAAO,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;IACzC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,4BAA4B,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClE,OAAO,CAAC,CAAC;IACX,CAAC;IAED,GAAG,CAAC,8BAA8B,IAAI,CAAC,OAAO,oBAAoB,CAAC,CAAC;IACpE,IAAI,OAAO,CAAC;IACZ,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,yBAAyB,IAAI,yBAAyB,CAAC;QACxE,OAAO,GAAG,MAAM,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAClD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,6BAA6B,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACnE,OAAO,CAAC,CAAC;IACX,CAAC;IAED,GAAG,CAAC,oCAAoC,IAAI,CAAC,SAAS,MAAM,CAAC,CAAC;IAC9D,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/C,MAAM,eAAe,GAAG,IAAI,CAAC,eAAe,IAAI,cAAc,EAAE,CAAC;IACjE,aAAa,CAAC,GAAG,IAAI,CAAC,SAAS,eAAe,EAAE,iBAAiB,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC;IACzG,aAAa,CAAC,GAAG,IAAI,CAAC,SAAS,gBAAgB,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAC3F,aAAa,CAAC,GAAG,IAAI,CAAC,SAAS,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACzF,aAAa,CAAC,GAAG,IAAI,CAAC,SAAS,UAAU,EAAE,YAAY,EAAE,CAAC,CAAC;IAC3D,aAAa,CAAC,GAAG,IAAI,CAAC,SAAS,YAAY,EAAE,YAAY,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAC7I,aAAa,CAAC,GAAG,IAAI,CAAC,SAAS,eAAe,EAAE,gBAAgB,EAAE,CAAC,CAAC;IACpE,aAAa,CAAC,GAAG,IAAI,CAAC,SAAS,aAAa,EAAE,eAAe,EAAE,CAAC,CAAC;IAEjE,GAAG,CAAC,4BAA4B,CAAC,CAAC;IAClC,GAAG,CAAC,wBAAwB,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IACxD,GAAG,CAAC,+BAA+B,CAAC,CAAC;IACrC,GAAG,CAAC,oEAAoE,CAAC,CAAC;IAC1E,GAAG,CAAC,gCAAgC,CAAC,CAAC;IACtC,OAAO,CAAC,CAAC;AACX,CAAC"}
|
|
@@ -19,7 +19,14 @@ signal?: AbortSignal,
|
|
|
19
19
|
* actually get their own hooks + labels run instead of silently
|
|
20
20
|
* falling back to Mars while the page title shows the custom name.
|
|
21
21
|
*/
|
|
22
|
-
scenario?: ScenarioPackage
|
|
22
|
+
scenario?: ScenarioPackage,
|
|
23
|
+
/**
|
|
24
|
+
* Optional callback fired after each leader's artifact completes.
|
|
25
|
+
* server-app uses this to insert a RunRecord per artifact into
|
|
26
|
+
* the SQLite run-history store. Failures inside the callback are
|
|
27
|
+
* caught and logged so a failing handler does not break the run.
|
|
28
|
+
*/
|
|
29
|
+
onArtifact?: (artifact: import('../engine/schema/index.js').RunArtifact, leader: import('../runtime/orchestrator.js').LeaderConfig) => void | Promise<void>): Promise<void>;
|
|
23
30
|
/**
|
|
24
31
|
* Single-leader fork dispatch (Spec 2B). When `/setup` receives a
|
|
25
32
|
* config with `forkFrom` set, the server branches here instead of
|
|
@@ -36,5 +43,21 @@ scenario?: ScenarioPackage): Promise<void>;
|
|
|
36
43
|
* snapshots, single-leader guard) happened in the `/setup` handler
|
|
37
44
|
* before this function is reached.
|
|
38
45
|
*/
|
|
39
|
-
export declare function runForkSimulation(simConfig: NormalizedSimulationConfig, broadcast: BroadcastFn, signal?: AbortSignal, scenario?: ScenarioPackage
|
|
46
|
+
export declare function runForkSimulation(simConfig: NormalizedSimulationConfig, broadcast: BroadcastFn, signal?: AbortSignal, scenario?: ScenarioPackage,
|
|
47
|
+
/** Optional callback fired after the forked artifact completes. */
|
|
48
|
+
onArtifact?: (artifact: import('../engine/schema/index.js').RunArtifact, leader: import('../runtime/orchestrator.js').LeaderConfig) => void | Promise<void>): Promise<void>;
|
|
49
|
+
/**
|
|
50
|
+
* Generalized N-leader batch runner (Tier 5 Quickstart). Three or more
|
|
51
|
+
* leaders run against the same scenario + seed in parallel, each
|
|
52
|
+
* emitting per-leader SSE events identical to the pair path. No
|
|
53
|
+
* verdict generation: verdicts compare exactly two leaders and would
|
|
54
|
+
* be ambiguous across N >= 3. The dashboard's Quickstart tab surfaces
|
|
55
|
+
* group-median deltas instead.
|
|
56
|
+
*
|
|
57
|
+
* Per-leader tags are derived from archetype (lowercased, kebab-cased).
|
|
58
|
+
* Duplicate archetype strings get trailing indices for disambiguation.
|
|
59
|
+
*/
|
|
60
|
+
export declare function runBatchSimulations(simConfig: NormalizedSimulationConfig, broadcast: BroadcastFn, signal?: AbortSignal, scenario?: ScenarioPackage,
|
|
61
|
+
/** Optional callback fired after each leader's artifact completes. */
|
|
62
|
+
onArtifact?: (artifact: import('../engine/schema/index.js').RunArtifact, leader: import('../runtime/orchestrator.js').LeaderConfig) => void | Promise<void>): Promise<void>;
|
|
40
63
|
//# sourceMappingURL=pair-runner.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pair-runner.d.ts","sourceRoot":"","sources":["../../src/cli/pair-runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyB,KAAK,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAIzF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAG1D,MAAM,MAAM,WAAW,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;AAyBjE,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,0BAA0B,EACrC,SAAS,EAAE,WAAW;AACtB;;;;;;;GAOG;AACH,MAAM,CAAC,EAAE,WAAW;AACpB;;;;;;;GAOG;AACH,QAAQ,GAAE,eAA8B,
|
|
1
|
+
{"version":3,"file":"pair-runner.d.ts","sourceRoot":"","sources":["../../src/cli/pair-runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyB,KAAK,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAIzF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAG1D,MAAM,MAAM,WAAW,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;AAyBjE,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,0BAA0B,EACrC,SAAS,EAAE,WAAW;AACtB;;;;;;;GAOG;AACH,MAAM,CAAC,EAAE,WAAW;AACpB;;;;;;;GAOG;AACH,QAAQ,GAAE,eAA8B;AACxC;;;;;GAKG;AACH,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,2BAA2B,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,4BAA4B,EAAE,YAAY,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAC1J,OAAO,CAAC,IAAI,CAAC,CAuMf;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,0BAA0B,EACrC,SAAS,EAAE,WAAW,EACtB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,GAAE,eAA8B;AACxC,mEAAmE;AACnE,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,2BAA2B,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,4BAA4B,EAAE,YAAY,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAC1J,OAAO,CAAC,IAAI,CAAC,CAwFf;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,0BAA0B,EACrC,SAAS,EAAE,WAAW,EACtB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,GAAE,eAA8B;AACxC,sEAAsE;AACtE,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,2BAA2B,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,4BAA4B,EAAE,YAAY,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAC1J,OAAO,CAAC,IAAI,CAAC,CAuFf"}
|
package/dist/cli/pair-runner.js
CHANGED
|
@@ -39,7 +39,14 @@ signal,
|
|
|
39
39
|
* actually get their own hooks + labels run instead of silently
|
|
40
40
|
* falling back to Mars while the page title shows the custom name.
|
|
41
41
|
*/
|
|
42
|
-
scenario = marsScenario
|
|
42
|
+
scenario = marsScenario,
|
|
43
|
+
/**
|
|
44
|
+
* Optional callback fired after each leader's artifact completes.
|
|
45
|
+
* server-app uses this to insert a RunRecord per artifact into
|
|
46
|
+
* the SQLite run-history store. Failures inside the callback are
|
|
47
|
+
* caught and logged so a failing handler does not break the run.
|
|
48
|
+
*/
|
|
49
|
+
onArtifact) {
|
|
43
50
|
const { leaders, turns, seed, startTime, liveSearch, customEvents } = simConfig;
|
|
44
51
|
broadcast('status', { phase: 'starting', maxTurns: turns, customEvents });
|
|
45
52
|
const { runSimulation } = await import('../runtime/orchestrator.js');
|
|
@@ -74,7 +81,8 @@ scenario = marsScenario) {
|
|
|
74
81
|
execution: simConfig.execution,
|
|
75
82
|
scenario,
|
|
76
83
|
signal,
|
|
77
|
-
|
|
84
|
+
captureSnapshots: simConfig.captureSnapshots ?? false,
|
|
85
|
+
}).then(async (result) => {
|
|
78
86
|
broadcast('result', {
|
|
79
87
|
leader: tag,
|
|
80
88
|
summary: {
|
|
@@ -84,7 +92,21 @@ scenario = marsScenario) {
|
|
|
84
92
|
citations: result.citations?.length ?? 0,
|
|
85
93
|
},
|
|
86
94
|
fingerprint: result.fingerprint ?? null,
|
|
95
|
+
// Spec 2B bridge: emit the full artifact on result when
|
|
96
|
+
// snapshot capture was on so the dashboard can fork from it
|
|
97
|
+
// without reconstructing from the event stream. Skipped when
|
|
98
|
+
// captureSnapshots is off to keep the SSE payload lean on
|
|
99
|
+
// hosted-demo runs that don't need fork capability.
|
|
100
|
+
artifact: simConfig.captureSnapshots ? result : undefined,
|
|
87
101
|
});
|
|
102
|
+
if (onArtifact) {
|
|
103
|
+
try {
|
|
104
|
+
await onArtifact(result, leader);
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
console.warn('[pair-runner] onArtifact handler failed:', err);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
88
110
|
return { tag, leader, result };
|
|
89
111
|
}, error => {
|
|
90
112
|
broadcast('sim_error', { leader: tag, error: String(error) });
|
|
@@ -107,8 +129,8 @@ scenario = marsScenario) {
|
|
|
107
129
|
if (settled.length === 2) {
|
|
108
130
|
try {
|
|
109
131
|
const [a, b] = settled;
|
|
110
|
-
const colA = a.result.finalState?.
|
|
111
|
-
const colB = b.result.finalState?.
|
|
132
|
+
const colA = a.result.finalState?.metrics;
|
|
133
|
+
const colB = b.result.finalState?.metrics;
|
|
112
134
|
const verdictModel = resolveVerdictModel(simConfig.provider || 'openai', simConfig.economics);
|
|
113
135
|
if (!verdictModel) {
|
|
114
136
|
broadcast('complete', {
|
|
@@ -238,7 +260,9 @@ Then fill out:
|
|
|
238
260
|
* snapshots, single-leader guard) happened in the `/setup` handler
|
|
239
261
|
* before this function is reached.
|
|
240
262
|
*/
|
|
241
|
-
export async function runForkSimulation(simConfig, broadcast, signal, scenario = marsScenario
|
|
263
|
+
export async function runForkSimulation(simConfig, broadcast, signal, scenario = marsScenario,
|
|
264
|
+
/** Optional callback fired after the forked artifact completes. */
|
|
265
|
+
onArtifact) {
|
|
242
266
|
if (!simConfig.forkFrom) {
|
|
243
267
|
throw new Error('runForkSimulation called without simConfig.forkFrom set');
|
|
244
268
|
}
|
|
@@ -295,7 +319,20 @@ export async function runForkSimulation(simConfig, broadcast, signal, scenario =
|
|
|
295
319
|
},
|
|
296
320
|
fingerprint: result.fingerprint ?? null,
|
|
297
321
|
forkedFrom: result.metadata.forkedFrom,
|
|
322
|
+
// Fork runs always have captureSnapshots forced on (see
|
|
323
|
+
// simulate call above); emit the full artifact so the dashboard
|
|
324
|
+
// can keep forking recursively without the event-stream
|
|
325
|
+
// reconstruction the spec originally assumed.
|
|
326
|
+
artifact: result,
|
|
298
327
|
});
|
|
328
|
+
if (onArtifact) {
|
|
329
|
+
try {
|
|
330
|
+
await onArtifact(result, leader);
|
|
331
|
+
}
|
|
332
|
+
catch (err) {
|
|
333
|
+
console.warn('[fork-runner] onArtifact handler failed:', err);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
299
336
|
}
|
|
300
337
|
catch (err) {
|
|
301
338
|
broadcast('sim_error', { leader: leader.archetype, error: String(err) });
|
|
@@ -303,4 +340,103 @@ export async function runForkSimulation(simConfig, broadcast, signal, scenario =
|
|
|
303
340
|
}
|
|
304
341
|
broadcast('complete', { timestamp: new Date().toISOString(), fork: true });
|
|
305
342
|
}
|
|
343
|
+
/**
|
|
344
|
+
* Generalized N-leader batch runner (Tier 5 Quickstart). Three or more
|
|
345
|
+
* leaders run against the same scenario + seed in parallel, each
|
|
346
|
+
* emitting per-leader SSE events identical to the pair path. No
|
|
347
|
+
* verdict generation: verdicts compare exactly two leaders and would
|
|
348
|
+
* be ambiguous across N >= 3. The dashboard's Quickstart tab surfaces
|
|
349
|
+
* group-median deltas instead.
|
|
350
|
+
*
|
|
351
|
+
* Per-leader tags are derived from archetype (lowercased, kebab-cased).
|
|
352
|
+
* Duplicate archetype strings get trailing indices for disambiguation.
|
|
353
|
+
*/
|
|
354
|
+
export async function runBatchSimulations(simConfig, broadcast, signal, scenario = marsScenario,
|
|
355
|
+
/** Optional callback fired after each leader's artifact completes. */
|
|
356
|
+
onArtifact) {
|
|
357
|
+
const { leaders, turns, seed, startTime, liveSearch, customEvents } = simConfig;
|
|
358
|
+
broadcast('status', { phase: 'starting', maxTurns: turns, customEvents, batch: true, leaderCount: leaders.length });
|
|
359
|
+
const { runSimulation } = await import('../runtime/orchestrator.js');
|
|
360
|
+
const onEvent = (event) => broadcast('sim', event);
|
|
361
|
+
broadcast('status', {
|
|
362
|
+
phase: 'parallel',
|
|
363
|
+
batch: true,
|
|
364
|
+
leaders: leaders.map(leader => ({
|
|
365
|
+
name: leader.name,
|
|
366
|
+
archetype: leader.archetype,
|
|
367
|
+
unit: leader.unit,
|
|
368
|
+
hexaco: leader.hexaco,
|
|
369
|
+
})),
|
|
370
|
+
});
|
|
371
|
+
console.log(` Running batch: ${leaders.map(l => l.name).join(' vs ')} | ${turns} turns | seed ${seed}
|
|
372
|
+
`);
|
|
373
|
+
const usedTags = new Map();
|
|
374
|
+
const leadersWithTags = leaders.map((leader, index) => {
|
|
375
|
+
const base = leader.archetype.toLowerCase().replace(/^the\s+/, '').replace(/\s+/g, '-') || `leader-${index}`;
|
|
376
|
+
const count = usedTags.get(base) ?? 0;
|
|
377
|
+
usedTags.set(base, count + 1);
|
|
378
|
+
const tag = count === 0 ? base : `${base}-${count + 1}`;
|
|
379
|
+
return { leader, index, tag };
|
|
380
|
+
});
|
|
381
|
+
const settled = await Promise.allSettled(leadersWithTags.map(({ leader, index, tag }) => {
|
|
382
|
+
return runSimulation(leader, simConfig.keyPersonnel ?? DEFAULT_KEY_PERSONNEL, {
|
|
383
|
+
maxTurns: turns,
|
|
384
|
+
seed,
|
|
385
|
+
startTime,
|
|
386
|
+
timePerTurn: simConfig.timePerTurn,
|
|
387
|
+
liveSearch,
|
|
388
|
+
activeDepartments: simConfig.activeDepartments,
|
|
389
|
+
onEvent,
|
|
390
|
+
customEvents,
|
|
391
|
+
provider: simConfig.provider,
|
|
392
|
+
models: simConfig.models,
|
|
393
|
+
economics: simConfig.economics,
|
|
394
|
+
initialPopulation: simConfig.initialPopulation,
|
|
395
|
+
startingResources: simConfig.startingResources,
|
|
396
|
+
startingPolitics: simConfig.startingPolitics,
|
|
397
|
+
execution: simConfig.execution,
|
|
398
|
+
scenario,
|
|
399
|
+
signal,
|
|
400
|
+
captureSnapshots: simConfig.captureSnapshots ?? false,
|
|
401
|
+
}).then(async (result) => {
|
|
402
|
+
broadcast('result', {
|
|
403
|
+
leader: tag,
|
|
404
|
+
leaderIndex: index,
|
|
405
|
+
summary: {
|
|
406
|
+
population: result.finalState?.metrics?.population,
|
|
407
|
+
morale: result.finalState?.metrics?.morale,
|
|
408
|
+
toolsForged: result.forgedTools?.length ?? 0,
|
|
409
|
+
citations: result.citations?.length ?? 0,
|
|
410
|
+
},
|
|
411
|
+
fingerprint: result.fingerprint ?? null,
|
|
412
|
+
artifact: simConfig.captureSnapshots ? result : undefined,
|
|
413
|
+
});
|
|
414
|
+
if (onArtifact) {
|
|
415
|
+
try {
|
|
416
|
+
await onArtifact(result, leader);
|
|
417
|
+
}
|
|
418
|
+
catch (err) {
|
|
419
|
+
console.warn('[batch-runner] onArtifact handler failed:', err);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
return result;
|
|
423
|
+
}, error => {
|
|
424
|
+
broadcast('sim_error', { leader: tag, leaderIndex: index, error: String(error) });
|
|
425
|
+
throw error;
|
|
426
|
+
});
|
|
427
|
+
}));
|
|
428
|
+
// Mirror runPairSimulations: surface aborted/provider-error at the
|
|
429
|
+
// terminal event so the dashboard can badge the session as
|
|
430
|
+
// interrupted. We consider the batch aborted when every leader
|
|
431
|
+
// failed or reported abortion; a single success still counts as
|
|
432
|
+
// a successful batch run.
|
|
433
|
+
const fulfilled = settled.filter(s => s.status === 'fulfilled')
|
|
434
|
+
.map(s => s.value);
|
|
435
|
+
const allAborted = fulfilled.length === 0 || fulfilled.every(v => v?.aborted === true || !!v?.providerError);
|
|
436
|
+
broadcast('complete', {
|
|
437
|
+
timestamp: new Date().toISOString(),
|
|
438
|
+
batch: true,
|
|
439
|
+
...(allAborted ? { aborted: true } : {}),
|
|
440
|
+
});
|
|
441
|
+
}
|
|
306
442
|
//# sourceMappingURL=pair-runner.js.map
|