@hongmaple0820/scale-engine 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.
Files changed (78) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +64 -0
  3. package/dist/adapters/ClaudeCodeAdapter.d.ts +48 -0
  4. package/dist/adapters/ClaudeCodeAdapter.js +188 -0
  5. package/dist/adapters/ClaudeCodeAdapter.js.map +1 -0
  6. package/dist/adapters/CodexAdapter.d.ts +14 -0
  7. package/dist/adapters/CodexAdapter.js +153 -0
  8. package/dist/adapters/CodexAdapter.js.map +1 -0
  9. package/dist/api/cli.d.ts +2 -0
  10. package/dist/api/cli.js +396 -0
  11. package/dist/api/cli.js.map +1 -0
  12. package/dist/api/doctor.d.ts +28 -0
  13. package/dist/api/doctor.js +182 -0
  14. package/dist/api/doctor.js.map +1 -0
  15. package/dist/api/mcp.d.ts +32 -0
  16. package/dist/api/mcp.js +227 -0
  17. package/dist/api/mcp.js.map +1 -0
  18. package/dist/artifact/fsm.d.ts +36 -0
  19. package/dist/artifact/fsm.js +199 -0
  20. package/dist/artifact/fsm.js.map +1 -0
  21. package/dist/artifact/fsmDefinitions.d.ts +18 -0
  22. package/dist/artifact/fsmDefinitions.js +243 -0
  23. package/dist/artifact/fsmDefinitions.js.map +1 -0
  24. package/dist/artifact/sqliteStore.d.ts +61 -0
  25. package/dist/artifact/sqliteStore.js +394 -0
  26. package/dist/artifact/sqliteStore.js.map +1 -0
  27. package/dist/artifact/store.d.ts +49 -0
  28. package/dist/artifact/store.js +118 -0
  29. package/dist/artifact/store.js.map +1 -0
  30. package/dist/artifact/types.d.ts +333 -0
  31. package/dist/artifact/types.js +50 -0
  32. package/dist/artifact/types.js.map +1 -0
  33. package/dist/context/ContextBuilder.d.ts +36 -0
  34. package/dist/context/ContextBuilder.js +53 -0
  35. package/dist/context/ContextBuilder.js.map +1 -0
  36. package/dist/core/container.d.ts +14 -0
  37. package/dist/core/container.js +33 -0
  38. package/dist/core/container.js.map +1 -0
  39. package/dist/core/eventBus.d.ts +60 -0
  40. package/dist/core/eventBus.js +158 -0
  41. package/dist/core/eventBus.js.map +1 -0
  42. package/dist/core/logger.d.ts +3 -0
  43. package/dist/core/logger.js +12 -0
  44. package/dist/core/logger.js.map +1 -0
  45. package/dist/evolution/BehaviorTracker.d.ts +38 -0
  46. package/dist/evolution/BehaviorTracker.js +52 -0
  47. package/dist/evolution/BehaviorTracker.js.map +1 -0
  48. package/dist/evolution/EvolutionEngine.d.ts +99 -0
  49. package/dist/evolution/EvolutionEngine.js +321 -0
  50. package/dist/evolution/EvolutionEngine.js.map +1 -0
  51. package/dist/guardrails/Gateway.d.ts +26 -0
  52. package/dist/guardrails/Gateway.js +57 -0
  53. package/dist/guardrails/Gateway.js.map +1 -0
  54. package/dist/guardrails/advancedDetectors.d.ts +26 -0
  55. package/dist/guardrails/advancedDetectors.js +138 -0
  56. package/dist/guardrails/advancedDetectors.js.map +1 -0
  57. package/dist/guardrails/detectors.d.ts +25 -0
  58. package/dist/guardrails/detectors.js +170 -0
  59. package/dist/guardrails/detectors.js.map +1 -0
  60. package/dist/guardrails/roles.d.ts +4 -0
  61. package/dist/guardrails/roles.js +54 -0
  62. package/dist/guardrails/roles.js.map +1 -0
  63. package/dist/index.d.ts +22 -0
  64. package/dist/index.js +22 -0
  65. package/dist/index.js.map +1 -0
  66. package/dist/knowledge/KnowledgeBase.d.ts +25 -0
  67. package/dist/knowledge/KnowledgeBase.js +81 -0
  68. package/dist/knowledge/KnowledgeBase.js.map +1 -0
  69. package/dist/orchestration/EffectsWiring.d.ts +8 -0
  70. package/dist/orchestration/EffectsWiring.js +87 -0
  71. package/dist/orchestration/EffectsWiring.js.map +1 -0
  72. package/dist/routing/ModelRouter.d.ts +30 -0
  73. package/dist/routing/ModelRouter.js +69 -0
  74. package/dist/routing/ModelRouter.js.map +1 -0
  75. package/dist/tasks/TaskEngine.d.ts +97 -0
  76. package/dist/tasks/TaskEngine.js +269 -0
  77. package/dist/tasks/TaskEngine.js.map +1 -0
  78. package/package.json +48 -0
@@ -0,0 +1,333 @@
1
+ /**
2
+ * SCALE Engine — Core Types
3
+ *
4
+ * 这是整个系统的"灵魂"。
5
+ * 所有 Artifact、Event、FSM 类型都在这里定义。
6
+ * 修改这个文件需要 W4 末的"数据模型冻结评审"通过。
7
+ *
8
+ * 设计参考:docs/02-DATA-MODEL.md
9
+ */
10
+ /** 行为者:可以是 AI、人类或系统 */
11
+ export type Actor = {
12
+ kind: 'ai';
13
+ role: string;
14
+ model?: string;
15
+ } | {
16
+ kind: 'human';
17
+ userId: string;
18
+ } | {
19
+ kind: 'system';
20
+ component: string;
21
+ };
22
+ /** 时间戳(毫秒) */
23
+ export type Timestamp = number;
24
+ /** 通用 ID 字符串。格式:{TYPE}-{YYYYMMDD}-{SEQ},例如 SPEC-20260421-0007 */
25
+ export type ArtifactId = string;
26
+ export type EventId = string;
27
+ export type SessionId = string;
28
+ /** 11 种 Artifact 类型 */
29
+ export type ArtifactType = 'Need' | 'Insight' | 'Spec' | 'Plan' | 'TestPlan' | 'Task' | 'Change' | 'Evidence' | 'Defect' | 'Lesson' | 'Release';
30
+ export interface Artifact<TPayload = unknown> {
31
+ id: ArtifactId;
32
+ type: ArtifactType;
33
+ version: number;
34
+ status: string;
35
+ statusHistory: StatusChange[];
36
+ parents: ArtifactId[];
37
+ children: ArtifactId[];
38
+ supersedes?: ArtifactId;
39
+ title: string;
40
+ contentRef: string;
41
+ payload: TPayload;
42
+ gates: Gate[];
43
+ createdBy: Actor;
44
+ createdAt: Timestamp;
45
+ updatedAt: Timestamp;
46
+ closedAt?: Timestamp;
47
+ tags: string[];
48
+ labels: Record<string, string>;
49
+ }
50
+ export interface StatusChange {
51
+ from: string;
52
+ to: string;
53
+ at: Timestamp;
54
+ by: Actor;
55
+ reason?: string;
56
+ eventId: EventId;
57
+ }
58
+ export interface Gate {
59
+ name: string;
60
+ required: boolean;
61
+ threshold?: string;
62
+ actual?: unknown;
63
+ passed: boolean;
64
+ checkedAt?: Timestamp;
65
+ checkedBy?: Actor;
66
+ }
67
+ /** Need —— 用户原始诉求 */
68
+ export interface NeedPayload {
69
+ rawText: string;
70
+ ambiguityScore?: number;
71
+ stakeholders: string[];
72
+ }
73
+ /** Insight —— 探索学习产出 */
74
+ export interface InsightPayload {
75
+ category: 'fact' | 'constraint' | 'risk' | 'opportunity';
76
+ evidence: Array<{
77
+ type: 'file' | 'doc' | 'test' | 'log';
78
+ ref: string;
79
+ }>;
80
+ confidence: number;
81
+ contradictsArtifact?: ArtifactId;
82
+ }
83
+ /** Spec —— 需求契约 (WHAT) */
84
+ export interface SpecPayload {
85
+ what: string;
86
+ successCriteria: string[];
87
+ outOfScope: string[];
88
+ edgeCases: string[];
89
+ northStar: string;
90
+ }
91
+ /** Plan —— 技术方案 (HOW) */
92
+ export interface PlanPayload {
93
+ approach: string;
94
+ techChoices: Array<{
95
+ decision: string;
96
+ rationale: string;
97
+ alternatives: string[];
98
+ }>;
99
+ modules: Array<{
100
+ path: string;
101
+ action: 'create' | 'modify' | 'delete';
102
+ reason: string;
103
+ }>;
104
+ rollbackStrategy: string;
105
+ estimatedComplexity: number;
106
+ }
107
+ /** TestPlan —— 验证方案 */
108
+ export interface TestPlanPayload {
109
+ unitTests: TestSpec[];
110
+ integrationTests: TestSpec[];
111
+ manualChecks: string[];
112
+ perfBudgets?: Array<{
113
+ metric: string;
114
+ target: string;
115
+ }>;
116
+ }
117
+ export interface TestSpec {
118
+ name: string;
119
+ given: string;
120
+ when: string;
121
+ then: string;
122
+ command?: string;
123
+ }
124
+ /** Task —— 原子可执行单元 */
125
+ export interface TaskPayload {
126
+ description: string;
127
+ estimatedTokens?: number;
128
+ estimatedDurationMs?: number;
129
+ filesInvolved: string[];
130
+ dependsOn: ArtifactId[];
131
+ requiredRole: string;
132
+ requiredCapabilities: string[];
133
+ }
134
+ /** Change —— 实际代码变更 */
135
+ export interface ChangePayload {
136
+ commitSha?: string;
137
+ prUrl?: string;
138
+ filesChanged: Array<{
139
+ path: string;
140
+ additions: number;
141
+ deletions: number;
142
+ }>;
143
+ diffSummary: string;
144
+ reverted?: boolean;
145
+ }
146
+ /** Evidence —— 验证证据 */
147
+ export interface EvidencePayload {
148
+ testPlanId: ArtifactId;
149
+ toolUsed: string;
150
+ passed: boolean;
151
+ output: string;
152
+ duration: number;
153
+ artifacts: string[];
154
+ }
155
+ /** Defect —— 缺陷 */
156
+ export interface DefectPayload {
157
+ symptom: string;
158
+ rootCauseCategory: 'requirement_ambiguity' | 'design_flaw' | 'implementation_bug' | 'test_gap' | 'environment_issue' | 'unknown';
159
+ rootCauseDetail: string;
160
+ fixChangeIds: ArtifactId[];
161
+ similarTo: ArtifactId[];
162
+ lesson?: ArtifactId;
163
+ }
164
+ /** Lesson —— 沉淀经验 */
165
+ export interface LessonPayload {
166
+ type: 'lesson' | 'pattern' | 'best_practice' | 'anti_pattern' | 'decision' | 'troubleshooting' | 'workflow' | 'reference';
167
+ problem: string;
168
+ solution: string;
169
+ prevention: string;
170
+ sourceDefects: ArtifactId[];
171
+ applicableContexts: string[];
172
+ verified: boolean;
173
+ promotedToRule?: string;
174
+ }
175
+ /** Release —— 发布单 */
176
+ export interface ReleasePayload {
177
+ version: string;
178
+ includesSpecs: ArtifactId[];
179
+ includesChanges: ArtifactId[];
180
+ rolloutStrategy: 'canary' | 'blue_green' | 'rolling' | 'all_at_once';
181
+ rolledBack?: boolean;
182
+ rollbackReason?: string;
183
+ }
184
+ /** 类型映射:根据 ArtifactType 推断 Payload 类型 */
185
+ export type PayloadOf<T extends ArtifactType> = T extends 'Need' ? NeedPayload : T extends 'Insight' ? InsightPayload : T extends 'Spec' ? SpecPayload : T extends 'Plan' ? PlanPayload : T extends 'TestPlan' ? TestPlanPayload : T extends 'Task' ? TaskPayload : T extends 'Change' ? ChangePayload : T extends 'Evidence' ? EvidencePayload : T extends 'Defect' ? DefectPayload : T extends 'Lesson' ? LessonPayload : T extends 'Release' ? ReleasePayload : never;
186
+ export type EventType = 'artifact.created' | 'artifact.updated' | 'artifact.transitioned' | 'artifact.gate_checked' | 'artifact.deleted' | 'tool.called' | 'tool.completed' | 'tool.failed' | 'tool.blocked' | 'gate.checked' | 'gate.passed' | 'gate.failed' | 'behavior.brute_retry' | 'behavior.idle_tool' | 'behavior.busy_loop' | 'behavior.premature_done' | 'behavior.blame_shift' | 'role.activated' | 'role.denied' | 'session.started' | 'session.ended' | 'session.compacted' | 'session.cleared' | 'lesson.proposed' | 'lesson.approved' | 'lesson.rejected' | 'lesson.recalled' | 'lesson.helpful' | 'lesson.useless' | 'task.scheduled' | 'task.started' | 'task.checkpointed' | 'task.paused' | 'task.resumed' | 'task.restored' | 'task.completed' | 'task.failed' | 'task.cancelled' | 'task.drift_detected' | 'task.step_started' | 'task.step_completed' | 'task.step_failed' | 'task.step_retrying' | 'task.decomposed' | `task.custom.${string}` | 'rule.proposed' | 'rule.enforced' | 'hook.generated' | 'evolution.cycle_completed' | 'context.built';
187
+ export interface Event<TPayload = unknown> {
188
+ id: EventId;
189
+ type: EventType;
190
+ timestamp: Timestamp;
191
+ sessionId: SessionId;
192
+ actor: Actor;
193
+ artifactId?: ArtifactId;
194
+ payload: TPayload;
195
+ causedBy?: EventId;
196
+ correlationId?: string;
197
+ }
198
+ export interface FSMDefinition<S extends string = string, A extends string = string> {
199
+ type: ArtifactType;
200
+ states: readonly S[];
201
+ initial: S;
202
+ terminal: readonly S[];
203
+ transitions: ReadonlyArray<TransitionDef<S, A>>;
204
+ }
205
+ export interface TransitionDef<S extends string, A extends string> {
206
+ from: S;
207
+ action: A;
208
+ to: S;
209
+ guards?: Guard[];
210
+ effects?: Effect[];
211
+ }
212
+ export interface Guard {
213
+ name: string;
214
+ check: (artifact: Artifact, context: TransitionContext) => boolean | Promise<boolean>;
215
+ errorMessage: string;
216
+ }
217
+ export interface Effect {
218
+ name: string;
219
+ run: (artifact: Artifact, context: TransitionContext) => void | Promise<void>;
220
+ }
221
+ export interface TransitionContext {
222
+ actor: Actor;
223
+ reason?: string;
224
+ payload?: Record<string, unknown>;
225
+ }
226
+ export interface TransitionResult {
227
+ success: boolean;
228
+ artifact?: Artifact;
229
+ blockedBy?: GuardFailure[];
230
+ effectsExecuted: string[];
231
+ }
232
+ export interface GuardFailure {
233
+ guard: string;
234
+ message: string;
235
+ }
236
+ export interface Session {
237
+ id: SessionId;
238
+ agent: 'claude-code' | 'codex' | 'cursor' | 'gemini' | 'opencode' | 'unknown';
239
+ startedAt: Timestamp;
240
+ endedAt?: Timestamp;
241
+ activeRole?: string;
242
+ metadata: Record<string, unknown>;
243
+ }
244
+ export interface ToolUseInput {
245
+ sessionId: SessionId;
246
+ tool: string;
247
+ args: Record<string, unknown>;
248
+ timestamp?: Timestamp;
249
+ }
250
+ export interface ToolResultInput {
251
+ sessionId: SessionId;
252
+ tool: string;
253
+ args: Record<string, unknown>;
254
+ exitCode?: number;
255
+ output?: string;
256
+ duration?: number;
257
+ timestamp?: Timestamp;
258
+ }
259
+ export interface StopInput {
260
+ sessionId: SessionId;
261
+ aiOutput?: string;
262
+ projectType?: string;
263
+ }
264
+ export interface GateDecision {
265
+ allow: boolean;
266
+ reason?: string;
267
+ suggestion?: string;
268
+ injectContext?: string[];
269
+ }
270
+ export interface DetectorResult {
271
+ triggered: boolean;
272
+ severity?: 'warn' | 'block' | 'deny';
273
+ reason?: string;
274
+ suggestion?: string;
275
+ }
276
+ export interface KnowledgeEntry {
277
+ id: string;
278
+ type: LessonPayload['type'];
279
+ title: string;
280
+ tags: string[];
281
+ contentRef: string;
282
+ embeddingId?: string;
283
+ relevance: number;
284
+ accessCount: number;
285
+ lastAccessed?: Timestamp;
286
+ verified: boolean;
287
+ verifiedBy?: string;
288
+ verifiedAt?: Timestamp;
289
+ createdAt: Timestamp;
290
+ sourceArtifact?: ArtifactId;
291
+ }
292
+ export interface KnowledgeQuery {
293
+ type?: LessonPayload['type'] | LessonPayload['type'][];
294
+ tags?: string[];
295
+ minRelevance?: number;
296
+ verifiedOnly?: boolean;
297
+ limit?: number;
298
+ }
299
+ export interface RoleDefinition {
300
+ name: string;
301
+ canCreateArtifacts: ArtifactType[];
302
+ canModifyArtifacts?: Array<{
303
+ type: ArtifactType;
304
+ statuses: string[];
305
+ }>;
306
+ canReadArtifacts?: ArtifactType[];
307
+ allowedTools: string[];
308
+ deniedTools?: string[];
309
+ requiresUpstream?: Array<{
310
+ type: ArtifactType;
311
+ status?: string;
312
+ allMatch?: string;
313
+ }>;
314
+ mustRunAfterEdit?: string[];
315
+ }
316
+ export declare class ScaleError extends Error {
317
+ code: string;
318
+ details?: unknown | undefined;
319
+ constructor(message: string, code: string, details?: unknown | undefined);
320
+ }
321
+ export declare class InvalidTransitionError extends ScaleError {
322
+ constructor(from: string, action: string);
323
+ }
324
+ export declare class GuardFailedError extends ScaleError {
325
+ failures: GuardFailure[];
326
+ constructor(failures: GuardFailure[]);
327
+ }
328
+ export declare class RoleDeniedError extends ScaleError {
329
+ constructor(role: string, reason: string);
330
+ }
331
+ export declare class ArtifactNotFoundError extends ScaleError {
332
+ constructor(id: string);
333
+ }
@@ -0,0 +1,50 @@
1
+ /**
2
+ * SCALE Engine — Core Types
3
+ *
4
+ * 这是整个系统的"灵魂"。
5
+ * 所有 Artifact、Event、FSM 类型都在这里定义。
6
+ * 修改这个文件需要 W4 末的"数据模型冻结评审"通过。
7
+ *
8
+ * 设计参考:docs/02-DATA-MODEL.md
9
+ */
10
+ // ============================================================================
11
+ // 11. 错误类型
12
+ // ============================================================================
13
+ export class ScaleError extends Error {
14
+ code;
15
+ details;
16
+ constructor(message, code, details) {
17
+ super(message);
18
+ this.code = code;
19
+ this.details = details;
20
+ this.name = 'ScaleError';
21
+ }
22
+ }
23
+ export class InvalidTransitionError extends ScaleError {
24
+ constructor(from, action) {
25
+ super(`State '${from}' does not support action '${action}'`, 'INVALID_TRANSITION', {
26
+ from,
27
+ action,
28
+ });
29
+ }
30
+ }
31
+ export class GuardFailedError extends ScaleError {
32
+ failures;
33
+ constructor(failures) {
34
+ super(`Transition blocked by guards: ${failures.map((f) => f.guard).join(', ')}`, 'GUARD_FAILED', {
35
+ failures,
36
+ });
37
+ this.failures = failures;
38
+ }
39
+ }
40
+ export class RoleDeniedError extends ScaleError {
41
+ constructor(role, reason) {
42
+ super(`Role '${role}' denied: ${reason}`, 'ROLE_DENIED', { role, reason });
43
+ }
44
+ }
45
+ export class ArtifactNotFoundError extends ScaleError {
46
+ constructor(id) {
47
+ super(`Artifact '${id}' not found`, 'ARTIFACT_NOT_FOUND', { id });
48
+ }
49
+ }
50
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/artifact/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAgeH,+EAA+E;AAC/E,WAAW;AACX,+EAA+E;AAE/E,MAAM,OAAO,UAAW,SAAQ,KAAK;IACC;IAAqB;IAAzD,YAAY,OAAe,EAAS,IAAY,EAAS,OAAiB;QACxE,KAAK,CAAC,OAAO,CAAC,CAAA;QADoB,SAAI,GAAJ,IAAI,CAAQ;QAAS,YAAO,GAAP,OAAO,CAAU;QAExE,IAAI,CAAC,IAAI,GAAG,YAAY,CAAA;IAC1B,CAAC;CACF;AAED,MAAM,OAAO,sBAAuB,SAAQ,UAAU;IACpD,YAAY,IAAY,EAAE,MAAc;QACtC,KAAK,CAAC,UAAU,IAAI,8BAA8B,MAAM,GAAG,EAAE,oBAAoB,EAAE;YACjF,IAAI;YACJ,MAAM;SACP,CAAC,CAAA;IACJ,CAAC;CACF;AAED,MAAM,OAAO,gBAAiB,SAAQ,UAAU;IAC3B;IAAnB,YAAmB,QAAwB;QACzC,KAAK,CAAC,iCAAiC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,cAAc,EAAE;YAChG,QAAQ;SACT,CAAC,CAAA;QAHe,aAAQ,GAAR,QAAQ,CAAgB;IAI3C,CAAC;CACF;AAED,MAAM,OAAO,eAAgB,SAAQ,UAAU;IAC7C,YAAY,IAAY,EAAE,MAAc;QACtC,KAAK,CAAC,SAAS,IAAI,aAAa,MAAM,EAAE,EAAE,aAAa,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAA;IAC5E,CAAC;CACF;AAED,MAAM,OAAO,qBAAsB,SAAQ,UAAU;IACnD,YAAY,EAAU;QACpB,KAAK,CAAC,aAAa,EAAE,aAAa,EAAE,oBAAoB,EAAE,EAAE,EAAE,EAAE,CAAC,CAAA;IACnE,CAAC;CACF"}
@@ -0,0 +1,36 @@
1
+ import type { ArtifactId, SessionId } from '../artifact/types.js';
2
+ import type { IArtifactStore } from '../artifact/store.js';
3
+ import type { IKnowledgeBase } from '../knowledge/KnowledgeBase.js';
4
+ import type { IEventBus } from '../core/eventBus.js';
5
+ export interface ContextLayer {
6
+ name: string;
7
+ content: string;
8
+ priority: number;
9
+ estimatedTokens: number;
10
+ }
11
+ export interface BuiltContext {
12
+ system: string;
13
+ metadata: {
14
+ totalTokens: number;
15
+ layers: string[];
16
+ };
17
+ }
18
+ export interface IContextBuilder {
19
+ build(opts: {
20
+ roleId?: string;
21
+ currentArtifactId?: ArtifactId;
22
+ sessionId: SessionId;
23
+ }): Promise<BuiltContext>;
24
+ }
25
+ export declare class ContextBuilder implements IContextBuilder {
26
+ private store;
27
+ private kb;
28
+ private eventBus;
29
+ private budget;
30
+ constructor(store: IArtifactStore, kb: IKnowledgeBase, eventBus: IEventBus);
31
+ build(opts: {
32
+ roleId?: string;
33
+ currentArtifactId?: ArtifactId;
34
+ sessionId: SessionId;
35
+ }): Promise<BuiltContext>;
36
+ }
@@ -0,0 +1,53 @@
1
+ // SCALE Engine — Context Builder (W6 完整实现)
2
+ // 分层上下文加载 + Token 预算
3
+ // 设计参考:docs/03-CORE-MODULES.md §3.6
4
+ export class ContextBuilder {
5
+ store;
6
+ kb;
7
+ eventBus;
8
+ budget = { total: 200_000, reserved: 30_000 };
9
+ constructor(store, kb, eventBus) {
10
+ this.store = store;
11
+ this.kb = kb;
12
+ this.eventBus = eventBus;
13
+ }
14
+ async build(opts) {
15
+ const layers = [];
16
+ layers.push({ name: 'system_rules', content: '## SCALE Core Rules\n...', priority: 1, estimatedTokens: 3000 });
17
+ if (opts.roleId) {
18
+ layers.push({ name: 'role_prompt', content: `## Active Role: ${opts.roleId}\n...`, priority: 2, estimatedTokens: 1500 });
19
+ }
20
+ if (opts.currentArtifactId) {
21
+ const artifact = await this.store.get(opts.currentArtifactId);
22
+ if (artifact) {
23
+ layers.push({ name: 'current_artifact', content: `## ${artifact.title}\n${JSON.stringify(artifact.payload, null, 2)}`, priority: 3, estimatedTokens: 5000 });
24
+ }
25
+ }
26
+ // P5: 召回 lessons (W7 集成)
27
+ if (opts.currentArtifactId) {
28
+ const artifact = await this.store.get(opts.currentArtifactId);
29
+ if (artifact) {
30
+ const lessons = await this.kb.recallByVector(artifact.title, 3);
31
+ if (lessons.length > 0) {
32
+ const content = '## 相关历史经验\n' + lessons.map((l) => `- ${l.title}`).join('\n');
33
+ layers.push({ name: 'recalled_lessons', content, priority: 5, estimatedTokens: 1500 });
34
+ }
35
+ }
36
+ }
37
+ const available = this.budget.total - this.budget.reserved;
38
+ const selected = [];
39
+ let used = 0;
40
+ for (const layer of layers.sort((a, b) => a.priority - b.priority)) {
41
+ if (used + layer.estimatedTokens > available)
42
+ break;
43
+ selected.push(layer);
44
+ used += layer.estimatedTokens;
45
+ }
46
+ this.eventBus.emit('context.built', { layers: selected.map((l) => l.name), totalTokens: used }, { sessionId: opts.sessionId });
47
+ return {
48
+ system: selected.map((l) => l.content).join('\n\n---\n\n'),
49
+ metadata: { totalTokens: used, layers: selected.map((l) => l.name) },
50
+ };
51
+ }
52
+ }
53
+ //# sourceMappingURL=ContextBuilder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ContextBuilder.js","sourceRoot":"","sources":["../../src/context/ContextBuilder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export type Token<T> = symbol & {
2
+ __type__?: T;
3
+ };
4
+ export declare function createToken<T>(name: string): Token<T>;
5
+ export declare class Container {
6
+ private instances;
7
+ private factories;
8
+ register<T>(token: Token<T>, factory: () => T): void;
9
+ registerInstance<T>(token: Token<T>, instance: T): void;
10
+ resolve<T>(token: Token<T>): T;
11
+ has(token: symbol): boolean;
12
+ reset(): void;
13
+ }
14
+ export declare const container: Container;
@@ -0,0 +1,33 @@
1
+ // SCALE Engine — Dependency Injection
2
+ // 极简 DI:避免循环依赖,方便测试时替换实现
3
+ export function createToken(name) {
4
+ return Symbol(name);
5
+ }
6
+ export class Container {
7
+ instances = new Map();
8
+ factories = new Map();
9
+ register(token, factory) {
10
+ this.factories.set(token, factory);
11
+ }
12
+ registerInstance(token, instance) {
13
+ this.instances.set(token, instance);
14
+ }
15
+ resolve(token) {
16
+ if (this.instances.has(token))
17
+ return this.instances.get(token);
18
+ const factory = this.factories.get(token);
19
+ if (!factory)
20
+ throw new Error(`No registration for token: ${token.toString()}`);
21
+ const instance = factory();
22
+ this.instances.set(token, instance);
23
+ return instance;
24
+ }
25
+ has(token) {
26
+ return this.instances.has(token) || this.factories.has(token);
27
+ }
28
+ reset() {
29
+ this.instances.clear();
30
+ }
31
+ }
32
+ export const container = new Container();
33
+ //# sourceMappingURL=container.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"container.js","sourceRoot":"","sources":["../../src/core/container.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,yBAAyB;AAIzB,MAAM,UAAU,WAAW,CAAI,IAAY;IACzC,OAAO,MAAM,CAAC,IAAI,CAAa,CAAA;AACjC,CAAC;AAED,MAAM,OAAO,SAAS;IACZ,SAAS,GAAG,IAAI,GAAG,EAAmB,CAAA;IACtC,SAAS,GAAG,IAAI,GAAG,EAAyB,CAAA;IAEpD,QAAQ,CAAI,KAAe,EAAE,OAAgB;QAC3C,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;IACpC,CAAC;IAED,gBAAgB,CAAI,KAAe,EAAE,QAAW;QAC9C,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;IACrC,CAAC;IAED,OAAO,CAAI,KAAe;QACxB,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAM,CAAA;QACpE,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QACzC,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;QAC/E,MAAM,QAAQ,GAAG,OAAO,EAAO,CAAA;QAC/B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;QACnC,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED,GAAG,CAAC,KAAa;QACf,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;IAC/D,CAAC;IAED,KAAK;QACH,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAA;IACxB,CAAC;CACF;AAED,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,SAAS,EAAE,CAAA"}
@@ -0,0 +1,60 @@
1
+ import type { Event, EventType, EventId, Actor, ArtifactId, SessionId, Timestamp } from '../artifact/types.js';
2
+ export type EventHandler<T = unknown> = (event: Event<T>) => void | Promise<void>;
3
+ export interface Subscription {
4
+ unsubscribe(): void;
5
+ }
6
+ export interface EmitOptions {
7
+ sessionId?: SessionId;
8
+ actor?: Actor;
9
+ artifactId?: ArtifactId;
10
+ causedBy?: EventId;
11
+ correlationId?: string;
12
+ }
13
+ export interface ReplayFilter {
14
+ fromTimestamp?: Timestamp;
15
+ toTimestamp?: Timestamp;
16
+ types?: EventType[];
17
+ sessionId?: SessionId;
18
+ artifactId?: ArtifactId;
19
+ }
20
+ export interface QueryFilter extends ReplayFilter {
21
+ limit?: number;
22
+ filter?: (event: Event) => boolean;
23
+ }
24
+ export type EventMiddleware = (event: Event) => Event | null;
25
+ export interface IEventBus {
26
+ on<T = unknown>(type: EventType | '*', handler: EventHandler<T>): Subscription;
27
+ once<T = unknown>(type: EventType, handler: EventHandler<T>): void;
28
+ emit<T = unknown>(type: EventType, payload: T, opts?: EmitOptions): Event<T>;
29
+ emitAsync<T = unknown>(type: EventType, payload: T, opts?: EmitOptions): Promise<Event<T>>;
30
+ use(middleware: EventMiddleware): void;
31
+ replay(filter: ReplayFilter, handler: EventHandler): Promise<void>;
32
+ query(filter: QueryFilter): Promise<Event[]>;
33
+ flush(): Promise<void>;
34
+ }
35
+ export declare class EventBus implements IEventBus {
36
+ private handlers;
37
+ private middlewares;
38
+ private memoryRing;
39
+ private maxRingSize;
40
+ private seq;
41
+ private eventsDir;
42
+ constructor(opts?: {
43
+ eventsDir?: string;
44
+ });
45
+ on<T>(type: EventType | '*', handler: EventHandler<T>): Subscription;
46
+ once<T>(type: EventType, handler: EventHandler<T>): void;
47
+ use(mw: EventMiddleware): void;
48
+ emit<T>(type: EventType, payload: T, opts?: EmitOptions): Event<T>;
49
+ emitAsync<T>(type: EventType, payload: T, opts?: EmitOptions): Promise<Event<T>>;
50
+ replay(filter: ReplayFilter, handler: EventHandler): Promise<void>;
51
+ query(filter: QueryFilter): Promise<Event[]>;
52
+ flush(): Promise<void>;
53
+ private generateId;
54
+ private persist;
55
+ private pushToRing;
56
+ private dispatchAsync;
57
+ private dispatchSync;
58
+ private getEventFiles;
59
+ private matchesFilter;
60
+ }