@hoplogic/hopjit 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/LICENSE +21 -0
- package/README.md +99 -0
- package/dist/act-body-interpreter.d.ts +24 -0
- package/dist/act-body-interpreter.js +159 -0
- package/dist/act-body-parser.d.ts +10 -0
- package/dist/act-body-parser.js +577 -0
- package/dist/act-builtins.d.ts +12 -0
- package/dist/act-builtins.js +104 -0
- package/dist/ast-helpers.d.ts +26 -0
- package/dist/ast-helpers.js +58 -0
- package/dist/ast-runtime.d.ts +49 -0
- package/dist/ast-runtime.js +224 -0
- package/dist/ast-types.d.ts +260 -0
- package/dist/ast-types.js +4 -0
- package/dist/cli-types.d.ts +190 -0
- package/dist/cli-types.js +4 -0
- package/dist/cli.d.ts +26 -0
- package/dist/cli.js +623 -0
- package/dist/dispatcher.d.ts +92 -0
- package/dist/dispatcher.js +692 -0
- package/dist/doc-ref.d.ts +41 -0
- package/dist/doc-ref.js +214 -0
- package/dist/engine-traverse.d.ts +37 -0
- package/dist/engine-traverse.js +385 -0
- package/dist/engine.d.ts +141 -0
- package/dist/engine.js +1792 -0
- package/dist/errors.d.ts +47 -0
- package/dist/errors.js +34 -0
- package/dist/hoplog.d.ts +120 -0
- package/dist/hoplog.js +501 -0
- package/dist/parser.d.ts +7 -0
- package/dist/parser.js +802 -0
- package/dist/persistence.d.ts +60 -0
- package/dist/persistence.js +208 -0
- package/dist/prompt.d.ts +130 -0
- package/dist/prompt.js +1014 -0
- package/dist/provider-types.d.ts +134 -0
- package/dist/provider-types.js +3 -0
- package/dist/runtime-types.d.ts +84 -0
- package/dist/runtime-types.js +4 -0
- package/dist/tools.d.ts +16 -0
- package/dist/tools.js +141 -0
- package/dist/validator.d.ts +23 -0
- package/dist/validator.js +959 -0
- package/driver/codex/AGENTS.md +54 -0
- package/driver/hopskill-build/SKILL.md +137 -0
- package/driver/hopskill-build/references/spec-skeleton.md +132 -0
- package/driver/hopskill-build/references/step-type-cheatsheet.md +56 -0
- package/driver/hopskill-build/references/three-focus-rules.md +148 -0
- package/driver/hopspec-skill.md +187 -0
- package/driver/references/cli-discovery.md +36 -0
- package/driver/references/discovery.md +45 -0
- package/driver/references/driver-subagent.md +50 -0
- package/driver/references/parallel-worker.md +50 -0
- package/driver/references/step-execution-rules.md +47 -0
- package/package.json +52 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { SpecAST } from './ast-types.js';
|
|
2
|
+
import type { PersistenceProvider } from './provider-types.js';
|
|
3
|
+
import type { StateFile, VarsFile, EngineSnapshot } from './runtime-types.js';
|
|
4
|
+
/** 原子写文件:先写 `.tmp` 再 rename 覆盖,避免崩溃中途留下半截状态文件。见 design ^anc-exec-crash-recovery */
|
|
5
|
+
export declare function writeAtomic(filePath: string, data: string): void;
|
|
6
|
+
/** 确保实例状态目录 `<stateDir>/<instanceId>/` 存在(0700 权限)并返回其路径。见 design ^anc-exec-state-persistence */
|
|
7
|
+
export declare function ensureStateDir(stateDir: string, instanceId: string): string;
|
|
8
|
+
/** fan-out 时把某 child 的 params_for_child(内部真值,不 deflate)落盘到其 subinstance 目录
|
|
9
|
+
* `<parentDir>/parallel/<childId>/params.json`,供 worker init 按 cid 回填 itemVar。
|
|
10
|
+
* 见 design/parallel-execution.md ^anc-exec-parallel-foreach-worker。 // @a: anc-exec-parallel-foreach-worker */
|
|
11
|
+
export declare function writeChildParams(parentDir: string, childId: string, params: Record<string, unknown>): void;
|
|
12
|
+
/** worker init 按 cid 回读 `<workerInstanceDir>/params.json`(= 父引擎 fan-out 落盘的 child 真值)。
|
|
13
|
+
* 不存在返回 null(触发 MISSING_INPUT 硬报错)。worker 只读自己那份,不碰父/兄弟 vars。 // @a: anc-exec-parallel-foreach-worker */
|
|
14
|
+
export declare function readChildParams(workerInstanceDir: string): Record<string, unknown> | null;
|
|
15
|
+
/** 将执行状态快照原子写入实例目录下的 `state.json`。见 [[persistence#^anc-provider-persistence]] */
|
|
16
|
+
export declare function writeState(dir: string, state: StateFile): void;
|
|
17
|
+
/** 将变量快照原子写入实例目录下的 `vars.json`。见 [[persistence#^anc-provider-persistence]] */
|
|
18
|
+
export declare function writeVars(dir: string, vars: VarsFile): void;
|
|
19
|
+
/** 将运行时 AST 快照原子写入实例目录下的 `spec.json`(随 replan 演化需重写)。见 [[persistence#^anc-provider-persistence]] */
|
|
20
|
+
export declare function writeSpec(dir: string, spec: object): void;
|
|
21
|
+
/** 读取并校验实例目录下的 `state.json`(format_version + step_states 校验)。见 [[persistence#^anc-provider-persistence]] */
|
|
22
|
+
export declare function readState(dir: string): StateFile;
|
|
23
|
+
/** 读取并校验实例目录下的 `vars.json`(format_version 1|2 + variables/scopes 二者其一校验)。见 [[persistence#^anc-provider-persistence]] */
|
|
24
|
+
export declare function readVars(dir: string): VarsFile;
|
|
25
|
+
/** 把 VarsFile(v1 扁平 / v2 scope 树)摊平为 name→value 字典,供按名读取的 cli 场景(call 回填、for-each 列表长度、join merge)。
|
|
26
|
+
* v2 合并所有 scope 变量、非 root scope 覆盖 root(与旧 v1 toJSON 的合并序一致,无行为回退)。 */
|
|
27
|
+
export declare function flattenVars(vars: VarsFile): Record<string, unknown>;
|
|
28
|
+
/** 读取实例目录下的 `spec.json` 运行时 AST 快照。损坏时抛 CORRUPT_STATE_FILE(与 state/vars 同错误语义,
|
|
29
|
+
* 便于崩溃恢复定位)。SpecAST 无 format_version 字段,故不走 parseChecked。见 [[persistence#^anc-provider-persistence]] */
|
|
30
|
+
export declare function readSpec(dir: string): object;
|
|
31
|
+
/** 判断实例目录下是否已存在 `state.json`(cli 定位实例是否有状态)。见 [[persistence#^anc-provider-persistence]] */
|
|
32
|
+
export declare function stateExists(dir: string): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* 复用模式持久化:快照 ↔ .hopstate/<instance_id>/ 文件。
|
|
35
|
+
* CLI 每个命令是独立进程,状态必须外置存活。
|
|
36
|
+
*/
|
|
37
|
+
export declare class FilePersistence implements PersistenceProvider {
|
|
38
|
+
private stateDir;
|
|
39
|
+
private instanceDir;
|
|
40
|
+
constructor(stateDir: string, isInstanceDir?: boolean);
|
|
41
|
+
init(instanceId: string, spec: SpecAST): void;
|
|
42
|
+
getWorkZone(): string;
|
|
43
|
+
saveSnapshot(snapshot: EngineSnapshot): void;
|
|
44
|
+
loadSnapshot(): EngineSnapshot;
|
|
45
|
+
exists(): boolean;
|
|
46
|
+
getInstanceDir(): string | null;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* 独立模式持久化(默认):进程内快照。
|
|
50
|
+
* Dispatcher 驱动完整生命周期,无需跨进程,状态保留在内存。
|
|
51
|
+
*/
|
|
52
|
+
export declare class MemoryPersistence implements PersistenceProvider {
|
|
53
|
+
private snapshot;
|
|
54
|
+
private spec;
|
|
55
|
+
init(_instanceId: string, spec: SpecAST): void;
|
|
56
|
+
saveSnapshot(snapshot: EngineSnapshot): void;
|
|
57
|
+
loadSnapshot(): EngineSnapshot;
|
|
58
|
+
exists(): boolean;
|
|
59
|
+
getWorkZone(): string;
|
|
60
|
+
}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
// @module: persistence ^anc-provider-persistence
|
|
2
|
+
import { writeFileSync, renameSync, mkdirSync, readFileSync, existsSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
/** 原子写文件:先写 `.tmp` 再 rename 覆盖,避免崩溃中途留下半截状态文件。见 design ^anc-exec-crash-recovery */
|
|
5
|
+
export function writeAtomic(filePath, data) {
|
|
6
|
+
const tmp = filePath + '.tmp';
|
|
7
|
+
writeFileSync(tmp, data, { mode: 0o600 });
|
|
8
|
+
renameSync(tmp, filePath);
|
|
9
|
+
}
|
|
10
|
+
/** 确保实例状态目录 `<stateDir>/<instanceId>/` 存在(0700 权限)并返回其路径。见 design ^anc-exec-state-persistence */
|
|
11
|
+
export function ensureStateDir(stateDir, instanceId) {
|
|
12
|
+
const dir = join(stateDir, instanceId);
|
|
13
|
+
mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
14
|
+
return dir;
|
|
15
|
+
}
|
|
16
|
+
/** fan-out 时把某 child 的 params_for_child(内部真值,不 deflate)落盘到其 subinstance 目录
|
|
17
|
+
* `<parentDir>/parallel/<childId>/params.json`,供 worker init 按 cid 回填 itemVar。
|
|
18
|
+
* 见 design/parallel-execution.md ^anc-exec-parallel-foreach-worker。 // @a: anc-exec-parallel-foreach-worker */
|
|
19
|
+
export function writeChildParams(parentDir, childId, params) {
|
|
20
|
+
const dir = join(parentDir, 'parallel', childId);
|
|
21
|
+
mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
22
|
+
writeAtomic(join(dir, 'params.json'), JSON.stringify(params, null, 2));
|
|
23
|
+
}
|
|
24
|
+
/** worker init 按 cid 回读 `<workerInstanceDir>/params.json`(= 父引擎 fan-out 落盘的 child 真值)。
|
|
25
|
+
* 不存在返回 null(触发 MISSING_INPUT 硬报错)。worker 只读自己那份,不碰父/兄弟 vars。 // @a: anc-exec-parallel-foreach-worker */
|
|
26
|
+
export function readChildParams(workerInstanceDir) {
|
|
27
|
+
const filePath = join(workerInstanceDir, 'params.json');
|
|
28
|
+
if (!existsSync(filePath))
|
|
29
|
+
return null;
|
|
30
|
+
try {
|
|
31
|
+
return JSON.parse(readFileSync(filePath, 'utf-8'));
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/** 将执行状态快照原子写入实例目录下的 `state.json`。见 [[persistence#^anc-provider-persistence]] */
|
|
38
|
+
export function writeState(dir, state) {
|
|
39
|
+
writeAtomic(join(dir, 'state.json'), JSON.stringify(state, null, 2));
|
|
40
|
+
}
|
|
41
|
+
/** 将变量快照原子写入实例目录下的 `vars.json`。见 [[persistence#^anc-provider-persistence]] */
|
|
42
|
+
export function writeVars(dir, vars) {
|
|
43
|
+
writeAtomic(join(dir, 'vars.json'), JSON.stringify(vars, null, 2));
|
|
44
|
+
}
|
|
45
|
+
/** 将运行时 AST 快照原子写入实例目录下的 `spec.json`(随 replan 演化需重写)。见 [[persistence#^anc-provider-persistence]] */
|
|
46
|
+
export function writeSpec(dir, spec) {
|
|
47
|
+
writeAtomic(join(dir, 'spec.json'), JSON.stringify(spec, null, 2));
|
|
48
|
+
}
|
|
49
|
+
// 状态文件读取健壮性校验:format_version 必须 === 1 + 关键字段存在。
|
|
50
|
+
// 不符抛 CORRUPT_STATE_FILE:<path>(明确定位),替代裸 JSON.parse + as 断言后续的晦涩 TypeError。
|
|
51
|
+
// 见 design/exec-engine.md ^anc-exec-parallel-join-preconditions。// @a: anc-exec-parallel-join-preconditions
|
|
52
|
+
// requiredKey 可传多个候选(任一存在即合格,用于 vars.json v1 `variables` / v2 `scopes` 二者其一);
|
|
53
|
+
// allowedVersions 缺省 [1](state.json 恒 v1),vars.json 传 [1,2] 兼容旧扁平格式。
|
|
54
|
+
function parseChecked(filePath, requiredKeys, allowedVersions = [1]) {
|
|
55
|
+
let raw;
|
|
56
|
+
try {
|
|
57
|
+
raw = readFileSync(filePath, 'utf-8');
|
|
58
|
+
}
|
|
59
|
+
catch (e) {
|
|
60
|
+
throw new Error(`CORRUPT_STATE_FILE: ${filePath} 不可读 (${e instanceof Error ? e.message : String(e)})`);
|
|
61
|
+
}
|
|
62
|
+
let obj;
|
|
63
|
+
try {
|
|
64
|
+
obj = JSON.parse(raw);
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
throw new Error(`CORRUPT_STATE_FILE: ${filePath} 非合法 JSON`);
|
|
68
|
+
}
|
|
69
|
+
if (typeof obj !== 'object' || obj === null) {
|
|
70
|
+
throw new Error(`CORRUPT_STATE_FILE: ${filePath} 顶层非对象`);
|
|
71
|
+
}
|
|
72
|
+
const rec = obj;
|
|
73
|
+
if (typeof rec.format_version !== 'number' || !allowedVersions.includes(rec.format_version)) {
|
|
74
|
+
throw new Error(`CORRUPT_STATE_FILE: ${filePath} format_version=${JSON.stringify(rec.format_version)},期望 ${allowedVersions.join('|')}`);
|
|
75
|
+
}
|
|
76
|
+
const keys = Array.isArray(requiredKeys) ? requiredKeys : [requiredKeys];
|
|
77
|
+
if (!keys.some(k => typeof rec[k] === 'object' && rec[k] !== null)) {
|
|
78
|
+
throw new Error(`CORRUPT_STATE_FILE: ${filePath} 缺关键字段 "${keys.join('|')}"`);
|
|
79
|
+
}
|
|
80
|
+
return obj;
|
|
81
|
+
}
|
|
82
|
+
/** 读取并校验实例目录下的 `state.json`(format_version + step_states 校验)。见 [[persistence#^anc-provider-persistence]] */
|
|
83
|
+
export function readState(dir) {
|
|
84
|
+
return parseChecked(join(dir, 'state.json'), 'step_states');
|
|
85
|
+
}
|
|
86
|
+
/** 读取并校验实例目录下的 `vars.json`(format_version 1|2 + variables/scopes 二者其一校验)。见 [[persistence#^anc-provider-persistence]] */
|
|
87
|
+
export function readVars(dir) {
|
|
88
|
+
return parseChecked(join(dir, 'vars.json'), ['variables', 'scopes'], [1, 2]);
|
|
89
|
+
}
|
|
90
|
+
/** 把 VarsFile(v1 扁平 / v2 scope 树)摊平为 name→value 字典,供按名读取的 cli 场景(call 回填、for-each 列表长度、join merge)。
|
|
91
|
+
* v2 合并所有 scope 变量、非 root scope 覆盖 root(与旧 v1 toJSON 的合并序一致,无行为回退)。 */
|
|
92
|
+
export function flattenVars(vars) {
|
|
93
|
+
if (vars.format_version === 2 && vars.scopes) {
|
|
94
|
+
const flat = { ...(vars.scopes.root?.variables ?? {}) };
|
|
95
|
+
for (const [scopeId, data] of Object.entries(vars.scopes)) {
|
|
96
|
+
if (scopeId === 'root')
|
|
97
|
+
continue;
|
|
98
|
+
Object.assign(flat, data.variables);
|
|
99
|
+
}
|
|
100
|
+
return flat;
|
|
101
|
+
}
|
|
102
|
+
return vars.variables ?? {};
|
|
103
|
+
}
|
|
104
|
+
/** 读取实例目录下的 `spec.json` 运行时 AST 快照。损坏时抛 CORRUPT_STATE_FILE(与 state/vars 同错误语义,
|
|
105
|
+
* 便于崩溃恢复定位)。SpecAST 无 format_version 字段,故不走 parseChecked。见 [[persistence#^anc-provider-persistence]] */
|
|
106
|
+
export function readSpec(dir) {
|
|
107
|
+
const filePath = join(dir, 'spec.json');
|
|
108
|
+
let raw;
|
|
109
|
+
try {
|
|
110
|
+
raw = readFileSync(filePath, 'utf-8');
|
|
111
|
+
}
|
|
112
|
+
catch (e) {
|
|
113
|
+
throw new Error(`CORRUPT_STATE_FILE: ${filePath} 不可读 (${e instanceof Error ? e.message : String(e)})`);
|
|
114
|
+
}
|
|
115
|
+
let obj;
|
|
116
|
+
try {
|
|
117
|
+
obj = JSON.parse(raw);
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
throw new Error(`CORRUPT_STATE_FILE: ${filePath} 非合法 JSON`);
|
|
121
|
+
}
|
|
122
|
+
if (typeof obj !== 'object' || obj === null) {
|
|
123
|
+
throw new Error(`CORRUPT_STATE_FILE: ${filePath} 顶层非对象`);
|
|
124
|
+
}
|
|
125
|
+
return obj;
|
|
126
|
+
}
|
|
127
|
+
/** 判断实例目录下是否已存在 `state.json`(cli 定位实例是否有状态)。见 [[persistence#^anc-provider-persistence]] */
|
|
128
|
+
export function stateExists(dir) {
|
|
129
|
+
return existsSync(join(dir, 'state.json'));
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* 复用模式持久化:快照 ↔ .hopstate/<instance_id>/ 文件。
|
|
133
|
+
* CLI 每个命令是独立进程,状态必须外置存活。
|
|
134
|
+
*/
|
|
135
|
+
export class FilePersistence {
|
|
136
|
+
stateDir;
|
|
137
|
+
instanceDir = null;
|
|
138
|
+
// stateDir: 实例存储的根目录(.hopstate)。从已存在实例目录恢复时传 instanceDir + isInstanceDir=true。
|
|
139
|
+
constructor(stateDir, isInstanceDir = false) {
|
|
140
|
+
this.stateDir = stateDir;
|
|
141
|
+
if (isInstanceDir)
|
|
142
|
+
this.instanceDir = stateDir;
|
|
143
|
+
}
|
|
144
|
+
init(instanceId, spec) {
|
|
145
|
+
this.instanceDir = ensureStateDir(this.stateDir, instanceId);
|
|
146
|
+
writeSpec(this.instanceDir, spec);
|
|
147
|
+
// 创建 work_zone/ + work_zone/vars/(driver @file 临时文件 + deflate $file 指针存放)
|
|
148
|
+
// 见 design/exec-engine.md ^anc-exec-work-zone。// @a: anc-exec-work-zone
|
|
149
|
+
mkdirSync(join(this.instanceDir, 'work_zone', 'vars'), { recursive: true, mode: 0o700 });
|
|
150
|
+
}
|
|
151
|
+
// 返回 work_zone 工作区绝对路径,NextResponse 五形态都携带此路径。// @a: anc-exec-work-zone
|
|
152
|
+
getWorkZone() {
|
|
153
|
+
if (!this.instanceDir)
|
|
154
|
+
throw new Error('FilePersistence.getWorkZone before init');
|
|
155
|
+
return join(this.instanceDir, 'work_zone');
|
|
156
|
+
}
|
|
157
|
+
saveSnapshot(snapshot) {
|
|
158
|
+
if (!this.instanceDir)
|
|
159
|
+
throw new Error('FilePersistence.saveSnapshot before init');
|
|
160
|
+
writeVars(this.instanceDir, snapshot.vars);
|
|
161
|
+
writeState(this.instanceDir, snapshot.state);
|
|
162
|
+
// spec.json 是运行时 AST 快照,随 replan 演化必须重写——否则跨进程 load 丢失 replan
|
|
163
|
+
// 的新 children(此前真实 bug)。见 design/exec-engine.md ^anc-exec-state-persistence。
|
|
164
|
+
// v1 每次 saveSnapshot 都写(整树序列化,spec 通常不大;正确性优先、不漏写);
|
|
165
|
+
// v2 可优化为脏标记(仅 replan 改 AST 时写)。// @a: anc-exec-state-persistence
|
|
166
|
+
writeSpec(this.instanceDir, snapshot.spec);
|
|
167
|
+
}
|
|
168
|
+
loadSnapshot() {
|
|
169
|
+
if (!this.instanceDir)
|
|
170
|
+
throw new Error('FilePersistence.loadSnapshot before init');
|
|
171
|
+
return {
|
|
172
|
+
spec: readSpec(this.instanceDir),
|
|
173
|
+
vars: readVars(this.instanceDir),
|
|
174
|
+
state: readState(this.instanceDir),
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
exists() {
|
|
178
|
+
return this.instanceDir != null && stateExists(this.instanceDir);
|
|
179
|
+
}
|
|
180
|
+
getInstanceDir() {
|
|
181
|
+
return this.instanceDir;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* 独立模式持久化(默认):进程内快照。
|
|
186
|
+
* Dispatcher 驱动完整生命周期,无需跨进程,状态保留在内存。
|
|
187
|
+
*/
|
|
188
|
+
export class MemoryPersistence {
|
|
189
|
+
snapshot = null;
|
|
190
|
+
spec = null;
|
|
191
|
+
init(_instanceId, spec) {
|
|
192
|
+
this.spec = spec;
|
|
193
|
+
}
|
|
194
|
+
saveSnapshot(snapshot) {
|
|
195
|
+
this.snapshot = snapshot;
|
|
196
|
+
}
|
|
197
|
+
loadSnapshot() {
|
|
198
|
+
if (!this.snapshot)
|
|
199
|
+
throw new Error('MemoryPersistence.loadSnapshot before any saveSnapshot');
|
|
200
|
+
return this.snapshot;
|
|
201
|
+
}
|
|
202
|
+
exists() {
|
|
203
|
+
return this.snapshot != null;
|
|
204
|
+
}
|
|
205
|
+
// 独立模式不暴露 work_zone 给外部 driver(dispatcher 进程内直跑,无 @file 跨进程交换需求)。
|
|
206
|
+
// 返回空串使下游一致透传;若独立模式将来需要 work_zone,可改为 tmpdir 自建。// @a: anc-exec-work-zone
|
|
207
|
+
getWorkZone() { return ''; }
|
|
208
|
+
}
|
package/dist/prompt.d.ts
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import type { SpecAST, StepNode } from './ast-types.js';
|
|
2
|
+
import type { KnowledgeProvider, KnowledgeFragment } from './provider-types.js';
|
|
3
|
+
import type { AssembledContext, ExecEvent } from './runtime-types.js';
|
|
4
|
+
import { type VariableStore, type StepStatus } from './ast-runtime.js';
|
|
5
|
+
/** PromptAssembler↔engine 的收窄只读接口边界:engine 实现它,Assembler 据此实时取 Spec/步骤状态/变量/执行事件流组 6 层 context。见 [[prompt-assembler#^anc-struct-prompt-assembler]] */
|
|
6
|
+
export interface EngineAccessor {
|
|
7
|
+
getSpec(): SpecAST | null;
|
|
8
|
+
getStepStates(): Map<string, StepStatus>;
|
|
9
|
+
getVariableStore(): VariableStore;
|
|
10
|
+
getExecEvents(): ExecEvent[];
|
|
11
|
+
getLoopCounters(): Map<string, number>;
|
|
12
|
+
getActiveRetryFeedback(stepId: string): {
|
|
13
|
+
attempt: number;
|
|
14
|
+
reason: string;
|
|
15
|
+
} | undefined;
|
|
16
|
+
getSubtreeRoot(): string | null;
|
|
17
|
+
getWorkZone(): string;
|
|
18
|
+
getContextMode(): 'full' | 'minimal';
|
|
19
|
+
}
|
|
20
|
+
/** 上下文组装组件:按步骤类型把引擎运行时状态组成 6 层 AssembledContext(L1-L6)并做 token 预算裁剪,自身不发 API。见 [[prompt-assembler#^anc-exec-prompt-assembly]] */
|
|
21
|
+
export declare class PromptAssembler {
|
|
22
|
+
private engine;
|
|
23
|
+
private budget;
|
|
24
|
+
constructor(engine: EngineAccessor, hasKnowledgeProvider?: boolean);
|
|
25
|
+
assembleReasonContext(step: StepNode): AssembledContext;
|
|
26
|
+
assembleCheckContext(step: StepNode): AssembledContext;
|
|
27
|
+
assembleActContext(step: StepNode): AssembledContext;
|
|
28
|
+
assembleAdaptiveContext(subtaskId: string): AssembledContext;
|
|
29
|
+
reassembleAggressive(step: StepNode): AssembledContext;
|
|
30
|
+
private assembleContext;
|
|
31
|
+
private buildRetryFeedback;
|
|
32
|
+
/** 渲染骨架单节点(含容器 attr:loop max / subtask retry+adaptive / case condition)+ 递归 children。
|
|
33
|
+
* buildSpecSkeleton 与 buildSubtreeSkeleton 共用(原两处 render 逐字复制)。 */
|
|
34
|
+
private renderSkeletonNode;
|
|
35
|
+
private buildSpecSkeleton;
|
|
36
|
+
private buildSubtreeSkeleton;
|
|
37
|
+
private buildTaskContext;
|
|
38
|
+
private buildProgressSummary;
|
|
39
|
+
private buildFullDisplaySet;
|
|
40
|
+
private renderStepProgress;
|
|
41
|
+
private formatStepFull;
|
|
42
|
+
/** 把步骤输出格式化为 `name=值(截断) # desc` 列表——读 scope 变量、JSON.stringify、超长截断。
|
|
43
|
+
* formatStepFull / formatContainerOutputs 共用(原两处逐字复制)。 */
|
|
44
|
+
private formatOutputVals;
|
|
45
|
+
private formatContainerOutputs;
|
|
46
|
+
private findProducerSteps;
|
|
47
|
+
private getSiblingStepIds;
|
|
48
|
+
private buildIterationHistory;
|
|
49
|
+
private resolveInputs;
|
|
50
|
+
private buildInstruction;
|
|
51
|
+
private buildAdaptiveTaskContext;
|
|
52
|
+
private buildSubtaskProgress;
|
|
53
|
+
private applyBudgetTrimming;
|
|
54
|
+
private estimateContextTokens;
|
|
55
|
+
private estimateTokens;
|
|
56
|
+
private getAncestorChain;
|
|
57
|
+
private findNearestLoopAncestor;
|
|
58
|
+
private findStepById;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Extract @knowledge hints from text (constraints, instruction, etc.)
|
|
62
|
+
* Returns unique keywords/phrases declared via `@knowledge <term>`.
|
|
63
|
+
*/
|
|
64
|
+
export declare function extractKnowledgeHints(text: string): string[];
|
|
65
|
+
/**
|
|
66
|
+
* Collects all @knowledge hints from spec constraints and a step's instruction.
|
|
67
|
+
*/
|
|
68
|
+
export declare function collectKnowledgeHints(spec: SpecAST, step: StepNode): {
|
|
69
|
+
specHints: string[];
|
|
70
|
+
stepHints: string[];
|
|
71
|
+
};
|
|
72
|
+
/** L2 知识检索的分来源结果(Spec @knowledge / 步骤 @knowledge / 补充检索),供组装时按优先级合并裁剪。见 [[prompt-assembler#^anc-exec-knowledge-retrieval]] */
|
|
73
|
+
export interface KnowledgeRetrievalResult {
|
|
74
|
+
specKnowledge: KnowledgeFragment[];
|
|
75
|
+
stepKnowledge: KnowledgeFragment[];
|
|
76
|
+
supplementary: KnowledgeFragment[];
|
|
77
|
+
dynamic: KnowledgeFragment[];
|
|
78
|
+
}
|
|
79
|
+
export declare function retrieveKnowledge(provider: KnowledgeProvider, specHints: string[], stepHints: string[], supplementaryQuery?: string, dynamicQuery?: string): Promise<KnowledgeRetrievalResult>;
|
|
80
|
+
/**
|
|
81
|
+
* Format knowledge retrieval results into the L2 knowledge_context string.
|
|
82
|
+
* Deduplicates by source_id and applies budget trimming.
|
|
83
|
+
*/
|
|
84
|
+
export declare function formatKnowledgeContext(result: KnowledgeRetrievalResult, triggerStepId?: string, budgetChars?: number): string;
|
|
85
|
+
/**
|
|
86
|
+
* Inject L2 knowledge context into an assembled context.
|
|
87
|
+
* This is the main async entry point for the dispatcher to enrich context with knowledge.
|
|
88
|
+
*
|
|
89
|
+
* @param ctx - The assembled context (modified in place and returned)
|
|
90
|
+
* @param provider - KnowledgeProvider from HostConfig
|
|
91
|
+
* @param spec - The spec AST (for extracting constraints)
|
|
92
|
+
* @param step - The current step node (for extracting step-level hints)
|
|
93
|
+
* @param supplementaryQuery - Optional query from lack_of_info (passive path)
|
|
94
|
+
* @param triggerStepId - Step ID that triggered supplementary retrieval
|
|
95
|
+
* @returns The enriched AssembledContext
|
|
96
|
+
*/
|
|
97
|
+
export declare function injectKnowledgeContext(ctx: AssembledContext, provider: KnowledgeProvider, spec: SpecAST, step: StepNode, supplementaryQuery?: string, triggerStepId?: string): Promise<string[]>;
|
|
98
|
+
/**
|
|
99
|
+
* 把 AssembledContext 格式化为完整自包含 prompt 文本。
|
|
100
|
+
* 包含:角色说明(让任何 LLM 拿到就能正确执行)+ 6 层结构化内容。
|
|
101
|
+
* 复用模式下记录到 hoplog llm.prompt(引擎交给 CC 推理的完整 context 渲染——CC 即 llm,
|
|
102
|
+
* 见 [[spec-observability#^anc-obs-mode-boundary]])。独立模式的真实 API prompt 由 dispatcher
|
|
103
|
+
* 的 buildSystemPrompt+buildMessages 另行组装(结构不同:system + 多条 user message),
|
|
104
|
+
* 本函数不代表独立模式实际发送内容(独立模式 llm.prompt 记录属 v2)。
|
|
105
|
+
* 覆盖守护见 tests/prompt.test.ts(@v: anc-obs-debug-context)——新增 AssembledContext 字段须同步本函数。
|
|
106
|
+
*/
|
|
107
|
+
export declare function formatPromptText(ctx: AssembledContext, stepType?: string): string;
|
|
108
|
+
/** formatParallelPromptText 的入参:组 parallel worker fan-out 派活 prompt 所需的目标/输出声明/parallel 步骤标识等字段。见 [[prompt-assembler#^anc-struct-prompt-assembler]] */
|
|
109
|
+
export interface ParallelPromptParams {
|
|
110
|
+
goal: string;
|
|
111
|
+
outputs: string;
|
|
112
|
+
parallelStepId: string;
|
|
113
|
+
children: Array<{
|
|
114
|
+
child_step_id: string;
|
|
115
|
+
summary: string;
|
|
116
|
+
params_for_child: Record<string, unknown>;
|
|
117
|
+
}>;
|
|
118
|
+
maxConcurrent: number;
|
|
119
|
+
instanceId: string;
|
|
120
|
+
specPath: string;
|
|
121
|
+
cliPath: string;
|
|
122
|
+
parentLogDir: string;
|
|
123
|
+
stateDir: string;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* 组装 parallel 容器的完整自包含 fan-out 指令文本。
|
|
127
|
+
* driver agent 拿到这段文本就能完成 fan-out→驱动→join 全流程。
|
|
128
|
+
*/
|
|
129
|
+
export declare function formatParallelPromptText(p: ParallelPromptParams): string;
|
|
130
|
+
export declare function formatHumanContext(record: Record<string, unknown>, workZone: string): Record<string, unknown>;
|