crewly 1.4.40 → 1.4.42
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/config/orchestrator_tasks/prompts/orchestrator-prompt.md +11 -11
- package/config/roles/architect/prompt.md +1 -5
- package/config/roles/backend-developer/prompt.md +1 -5
- package/config/roles/content-strategist/prompt.md +1 -5
- package/config/roles/designer/prompt.md +1 -5
- package/config/roles/developer/prompt.md +1 -7
- package/config/roles/developer/soul.md +18 -0
- package/config/roles/frontend-developer/prompt.md +1 -5
- package/config/roles/fullstack-dev/prompt.md +1 -5
- package/config/roles/generalist/prompt.md +1 -7
- package/config/roles/ops/prompt.md +1 -7
- package/config/roles/orchestrator/fragments/communication.md +117 -0
- package/config/roles/orchestrator/fragments/lifecycle.md +112 -0
- package/config/roles/orchestrator/fragments/recovery.md +47 -0
- package/config/roles/orchestrator/prompt.md +44 -44
- package/config/roles/orchestrator/soul.md +18 -0
- package/config/roles/product-manager/prompt.md +1 -5
- package/config/roles/qa/prompt.md +1 -5
- package/config/roles/qa-engineer/prompt.md +1 -5
- package/config/roles/researcher/prompt.md +1 -5
- package/config/roles/researcher/soul.md +18 -0
- package/config/roles/sales/prompt.md +1 -5
- package/config/roles/support/prompt.md +1 -5
- package/config/roles/team-leader/prompt.md +2 -6
- package/config/roles/tpm/prompt.md +1 -5
- package/config/roles/ux-designer/prompt.md +1 -5
- package/config/souls/developer.md +30 -0
- package/config/souls/orchestrator.md +30 -0
- package/config/souls/researcher.md +30 -0
- package/config/templates/agent-claude-md.md +1 -1
- package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/agent-registration.service.js +18 -7
- package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/oauth-relogin-monitor.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/oauth-relogin-monitor.service.js +16 -4
- package/dist/backend/backend/src/services/agent/oauth-relogin-monitor.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/runtime-agent.service.abstract.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/runtime-agent.service.abstract.js +11 -0
- package/dist/backend/backend/src/services/agent/runtime-agent.service.abstract.js.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-builder.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-builder.service.js +5 -0
- package/dist/backend/backend/src/services/ai/prompt-builder.service.js.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/communication.module.d.ts +46 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/communication.module.d.ts.map +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/communication.module.js +151 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/communication.module.js.map +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/context-assembly.service.d.ts +145 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/context-assembly.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/context-assembly.service.js +232 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/context-assembly.service.js.map +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/identity.module.d.ts +28 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/identity.module.d.ts.map +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/identity.module.js +47 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/identity.module.js.map +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/index.d.ts +22 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/index.d.ts.map +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/index.js +26 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/index.js.map +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/learning-reference.module.d.ts +28 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/learning-reference.module.d.ts.map +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/learning-reference.module.js +55 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/learning-reference.module.js.map +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/lifecycle.module.d.ts +44 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/lifecycle.module.d.ts.map +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/lifecycle.module.js +120 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/lifecycle.module.js.map +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/memory-reference.module.d.ts +28 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/memory-reference.module.d.ts.map +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/memory-reference.module.js +46 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/memory-reference.module.js.map +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/project-reference.module.d.ts +29 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/project-reference.module.d.ts.map +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/project-reference.module.js +50 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/project-reference.module.js.map +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/prompt-assembly.service.d.ts +103 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/prompt-assembly.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/prompt-assembly.service.js +305 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/prompt-assembly.service.js.map +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/prompt-module.interface.d.ts +135 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/prompt-module.interface.d.ts.map +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/prompt-module.interface.js +46 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/prompt-module.interface.js.map +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/recovery.module.d.ts +34 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/recovery.module.d.ts.map +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/recovery.module.js +69 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/recovery.module.js.map +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/scheduled-messages.loader.d.ts +55 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/scheduled-messages.loader.d.ts.map +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/scheduled-messages.loader.js +96 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/scheduled-messages.loader.js.map +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.d.ts +28 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.d.ts.map +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.js +65 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.js.map +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/soul.module.d.ts +70 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/soul.module.d.ts.map +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/soul.module.js +166 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/soul.module.js.map +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/team-reference.module.d.ts +54 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/team-reference.module.d.ts.map +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/team-reference.module.js +149 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/team-reference.module.js.map +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/user-profile-reference.module.d.ts +28 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/user-profile-reference.module.d.ts.map +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/user-profile-reference.module.js +53 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/user-profile-reference.module.js.map +1 -0
- package/dist/backend/backend/src/services/ai/self-improvement/attention.service.d.ts +74 -0
- package/dist/backend/backend/src/services/ai/self-improvement/attention.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/ai/self-improvement/attention.service.js +132 -0
- package/dist/backend/backend/src/services/ai/self-improvement/attention.service.js.map +1 -0
- package/dist/backend/backend/src/services/ai/self-improvement/growth-areas.service.d.ts +81 -0
- package/dist/backend/backend/src/services/ai/self-improvement/growth-areas.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/ai/self-improvement/growth-areas.service.js +135 -0
- package/dist/backend/backend/src/services/ai/self-improvement/growth-areas.service.js.map +1 -0
- package/dist/backend/backend/src/services/ai/self-improvement/index.d.ts +13 -0
- package/dist/backend/backend/src/services/ai/self-improvement/index.d.ts.map +1 -0
- package/dist/backend/backend/src/services/ai/self-improvement/index.js +13 -0
- package/dist/backend/backend/src/services/ai/self-improvement/index.js.map +1 -0
- package/dist/backend/backend/src/services/ai/self-improvement/memory-consolidation.service.d.ts +107 -0
- package/dist/backend/backend/src/services/ai/self-improvement/memory-consolidation.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/ai/self-improvement/memory-consolidation.service.js +183 -0
- package/dist/backend/backend/src/services/ai/self-improvement/memory-consolidation.service.js.map +1 -0
- package/dist/backend/backend/src/services/ai/self-improvement/prediction-calibration.service.d.ts +97 -0
- package/dist/backend/backend/src/services/ai/self-improvement/prediction-calibration.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/ai/self-improvement/prediction-calibration.service.js +128 -0
- package/dist/backend/backend/src/services/ai/self-improvement/prediction-calibration.service.js.map +1 -0
- package/dist/backend/backend/src/services/ai/self-improvement/self-model.service.d.ts +95 -0
- package/dist/backend/backend/src/services/ai/self-improvement/self-model.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/ai/self-improvement/self-model.service.js +116 -0
- package/dist/backend/backend/src/services/ai/self-improvement/self-model.service.js.map +1 -0
- package/dist/backend/backend/src/services/prompt/prompt-generator.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/prompt/prompt-generator.service.js +9 -11
- package/dist/backend/backend/src/services/prompt/prompt-generator.service.js.map +1 -1
- package/dist/backend/backend/src/services/skill/skill-catalog.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/skill/skill-catalog.service.js +3 -1
- package/dist/backend/backend/src/services/skill/skill-catalog.service.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
import { LoggerService } from '../../core/logger.service.js';
|
|
2
|
+
import { estimateTokens, } from './prompt-module.interface.js';
|
|
3
|
+
import { IdentityModule } from './identity.module.js';
|
|
4
|
+
import { SoulModule } from './soul.module.js';
|
|
5
|
+
import { SkillsReferenceModule } from './skills-reference.module.js';
|
|
6
|
+
import { MemoryReferenceModule } from './memory-reference.module.js';
|
|
7
|
+
import { TeamReferenceModule } from './team-reference.module.js';
|
|
8
|
+
import { ProjectReferenceModule } from './project-reference.module.js';
|
|
9
|
+
import { UserProfileReferenceModule } from './user-profile-reference.module.js';
|
|
10
|
+
import { LearningReferenceModule } from './learning-reference.module.js';
|
|
11
|
+
import { CommunicationModule } from './communication.module.js';
|
|
12
|
+
import { RecoveryModule } from './recovery.module.js';
|
|
13
|
+
import { LifecycleModule } from './lifecycle.module.js';
|
|
14
|
+
/**
|
|
15
|
+
* Default total token budget for all prompt modules combined.
|
|
16
|
+
* Modules exceeding this budget are truncated or skipped (compactable ones only).
|
|
17
|
+
*/
|
|
18
|
+
const DEFAULT_TOKEN_BUDGET = 25000;
|
|
19
|
+
/**
|
|
20
|
+
* Separator between prompt modules in assembled output.
|
|
21
|
+
*/
|
|
22
|
+
const MODULE_SEPARATOR = '\n\n---\n\n';
|
|
23
|
+
/**
|
|
24
|
+
* When trimming a module to fit budget, reduce to this fraction of maxTokens first.
|
|
25
|
+
*/
|
|
26
|
+
const TRIM_FRACTION = 0.5;
|
|
27
|
+
/**
|
|
28
|
+
* Service that orchestrates the assembly of prompt modules into a complete agent prompt.
|
|
29
|
+
*
|
|
30
|
+
* Responsibilities:
|
|
31
|
+
* - Registers and manages prompt modules
|
|
32
|
+
* - Assembles modules in priority order
|
|
33
|
+
* - Enforces per-module and total token budgets with 2-stage truncation:
|
|
34
|
+
* 1. First pass: build all Trusted Zone (non-compactable) + Flexible Zone modules
|
|
35
|
+
* 2. If over budget: trim lowest-priority compactable modules to 50% of maxTokens
|
|
36
|
+
* 3. If still over budget: remove lowest-priority compactable modules entirely
|
|
37
|
+
* - Returns AssemblyReport with token breakdown and truncation details
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```typescript
|
|
41
|
+
* const assembler = new PromptAssemblyService();
|
|
42
|
+
* const { prompt, report } = await assembler.assemble({
|
|
43
|
+
* sessionName: 'crewly-dev-001',
|
|
44
|
+
* memberId: 'uuid-123',
|
|
45
|
+
* role: 'developer',
|
|
46
|
+
* projectPath: '/path/to/project',
|
|
47
|
+
* agentSkillsPath: '/path/to/skills/agent',
|
|
48
|
+
* tlSkillsPath: '/path/to/skills/team-leader',
|
|
49
|
+
* projectRoot: '/path/to/project',
|
|
50
|
+
* });
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export class PromptAssemblyService {
|
|
54
|
+
logger;
|
|
55
|
+
modules = [];
|
|
56
|
+
totalTokenBudget;
|
|
57
|
+
constructor(tokenBudget = DEFAULT_TOKEN_BUDGET) {
|
|
58
|
+
this.logger = LoggerService.getInstance().createComponentLogger('PromptAssemblyService');
|
|
59
|
+
this.totalTokenBudget = tokenBudget;
|
|
60
|
+
this.registerDefaultModules();
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Register the default set of prompt modules.
|
|
64
|
+
* Called automatically in constructor. Additional modules
|
|
65
|
+
* can be added via addModule().
|
|
66
|
+
*/
|
|
67
|
+
registerDefaultModules() {
|
|
68
|
+
this.modules = [
|
|
69
|
+
new IdentityModule(),
|
|
70
|
+
new SoulModule(),
|
|
71
|
+
new MemoryReferenceModule(),
|
|
72
|
+
new SkillsReferenceModule(),
|
|
73
|
+
new TeamReferenceModule(),
|
|
74
|
+
new ProjectReferenceModule(),
|
|
75
|
+
new CommunicationModule(),
|
|
76
|
+
new UserProfileReferenceModule(),
|
|
77
|
+
new LearningReferenceModule(),
|
|
78
|
+
new RecoveryModule(),
|
|
79
|
+
new LifecycleModule(),
|
|
80
|
+
];
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Add a custom prompt module to the assembly pipeline.
|
|
84
|
+
*
|
|
85
|
+
* @param module - Module to add
|
|
86
|
+
*/
|
|
87
|
+
addModule(module) {
|
|
88
|
+
this.modules.push(module);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Remove a module by name.
|
|
92
|
+
*
|
|
93
|
+
* @param name - Name of the module to remove
|
|
94
|
+
*/
|
|
95
|
+
removeModule(name) {
|
|
96
|
+
this.modules = this.modules.filter((m) => m.name !== name);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Get all registered modules (for inspection/testing).
|
|
100
|
+
*
|
|
101
|
+
* @returns Array of registered prompt modules
|
|
102
|
+
*/
|
|
103
|
+
getModules() {
|
|
104
|
+
return [...this.modules];
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Get or set the total token budget.
|
|
108
|
+
*
|
|
109
|
+
* @param budget - Optional new budget to set
|
|
110
|
+
* @returns Current token budget
|
|
111
|
+
*/
|
|
112
|
+
tokenBudget(budget) {
|
|
113
|
+
if (budget !== undefined) {
|
|
114
|
+
this.totalTokenBudget = budget;
|
|
115
|
+
}
|
|
116
|
+
return this.totalTokenBudget;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Assemble all applicable prompt modules into a single prompt string.
|
|
120
|
+
*
|
|
121
|
+
* Uses 2-stage truncation for compactable modules when over budget:
|
|
122
|
+
* 1. Trim lowest-priority compactable modules to 50% of their content
|
|
123
|
+
* 2. Remove lowest-priority compactable modules entirely
|
|
124
|
+
*
|
|
125
|
+
* Trusted Zone (non-compactable) modules are never truncated or removed.
|
|
126
|
+
*
|
|
127
|
+
* @param config - Configuration with all context needed by modules
|
|
128
|
+
* @returns Object with assembled prompt string and budget report
|
|
129
|
+
*/
|
|
130
|
+
async assemble(config) {
|
|
131
|
+
const built = [];
|
|
132
|
+
const truncated = [];
|
|
133
|
+
// Sort modules by priority (ascending — lower number = higher priority)
|
|
134
|
+
const sorted = [...this.modules].sort((a, b) => a.priority - b.priority);
|
|
135
|
+
// Phase 1: Build all applicable modules
|
|
136
|
+
for (const module of sorted) {
|
|
137
|
+
if (!module.shouldInclude(config)) {
|
|
138
|
+
this.logger.debug(`Module '${module.name}' skipped (shouldInclude=false)`, {
|
|
139
|
+
sessionName: config.sessionName,
|
|
140
|
+
});
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
try {
|
|
144
|
+
const content = await module.build(config);
|
|
145
|
+
if (content && content.trim()) {
|
|
146
|
+
const tokens = estimateTokens(content);
|
|
147
|
+
built.push({
|
|
148
|
+
name: module.name,
|
|
149
|
+
content: content.trim(),
|
|
150
|
+
estimatedTokens: tokens,
|
|
151
|
+
compactable: module.compactable,
|
|
152
|
+
priority: module.priority,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
this.logger.error(`Module '${module.name}' failed to build`, {
|
|
158
|
+
sessionName: config.sessionName,
|
|
159
|
+
error: error instanceof Error ? error.message : String(error),
|
|
160
|
+
});
|
|
161
|
+
if (!module.compactable) {
|
|
162
|
+
throw error;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
// Phase 2: Enforce token budget via 2-stage truncation
|
|
167
|
+
let totalTokens = built.reduce((sum, r) => sum + r.estimatedTokens, 0);
|
|
168
|
+
if (totalTokens > this.totalTokenBudget) {
|
|
169
|
+
// Get compactable modules sorted by priority descending (lowest priority first to trim)
|
|
170
|
+
const compactableIndices = built
|
|
171
|
+
.map((r, i) => ({ ...r, index: i }))
|
|
172
|
+
.filter((r) => r.compactable)
|
|
173
|
+
.sort((a, b) => b.priority - a.priority);
|
|
174
|
+
// Stage 1: Trim to 50% of content (lowest priority first)
|
|
175
|
+
for (const item of compactableIndices) {
|
|
176
|
+
if (totalTokens <= this.totalTokenBudget)
|
|
177
|
+
break;
|
|
178
|
+
const original = built[item.index];
|
|
179
|
+
const trimmedContent = this.trimContent(original.content, TRIM_FRACTION);
|
|
180
|
+
const trimmedTokens = estimateTokens(trimmedContent);
|
|
181
|
+
const savings = original.estimatedTokens - trimmedTokens;
|
|
182
|
+
if (savings > 0) {
|
|
183
|
+
totalTokens -= savings;
|
|
184
|
+
built[item.index] = {
|
|
185
|
+
...original,
|
|
186
|
+
content: trimmedContent,
|
|
187
|
+
estimatedTokens: trimmedTokens,
|
|
188
|
+
};
|
|
189
|
+
truncated.push({
|
|
190
|
+
name: original.name,
|
|
191
|
+
originalTokens: original.estimatedTokens,
|
|
192
|
+
finalTokens: trimmedTokens,
|
|
193
|
+
action: 'trimmed',
|
|
194
|
+
});
|
|
195
|
+
this.logger.info(`Module '${original.name}' trimmed to 50%`, {
|
|
196
|
+
sessionName: config.sessionName,
|
|
197
|
+
originalTokens: original.estimatedTokens,
|
|
198
|
+
trimmedTokens,
|
|
199
|
+
totalTokens,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
// Stage 2: Remove entirely (lowest priority first)
|
|
204
|
+
if (totalTokens > this.totalTokenBudget) {
|
|
205
|
+
// Re-get compactable indices (some may have been trimmed)
|
|
206
|
+
const removable = built
|
|
207
|
+
.map((r, i) => ({ ...r, index: i }))
|
|
208
|
+
.filter((r) => r.compactable)
|
|
209
|
+
.sort((a, b) => b.priority - a.priority);
|
|
210
|
+
for (const item of removable) {
|
|
211
|
+
if (totalTokens <= this.totalTokenBudget)
|
|
212
|
+
break;
|
|
213
|
+
const original = built[item.index];
|
|
214
|
+
totalTokens -= original.estimatedTokens;
|
|
215
|
+
// Check if already in truncated list (was trimmed in stage 1)
|
|
216
|
+
const existingTruncIdx = truncated.findIndex((t) => t.name === original.name);
|
|
217
|
+
if (existingTruncIdx >= 0) {
|
|
218
|
+
truncated[existingTruncIdx].finalTokens = 0;
|
|
219
|
+
truncated[existingTruncIdx].action = 'removed';
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
truncated.push({
|
|
223
|
+
name: original.name,
|
|
224
|
+
originalTokens: original.estimatedTokens,
|
|
225
|
+
finalTokens: 0,
|
|
226
|
+
action: 'removed',
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
// Mark for removal by zeroing content
|
|
230
|
+
built[item.index] = { ...original, content: '', estimatedTokens: 0 };
|
|
231
|
+
this.logger.info(`Module '${original.name}' removed (budget)`, {
|
|
232
|
+
sessionName: config.sessionName,
|
|
233
|
+
freedTokens: original.estimatedTokens,
|
|
234
|
+
totalTokens,
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
// Filter out removed modules and build final output
|
|
240
|
+
const finalResults = built.filter((r) => r.content.length > 0);
|
|
241
|
+
const finalTotalTokens = finalResults.reduce((sum, r) => sum + r.estimatedTokens, 0);
|
|
242
|
+
const report = {
|
|
243
|
+
totalTokens: finalTotalTokens,
|
|
244
|
+
moduleBreakdown: finalResults.map((r) => ({
|
|
245
|
+
name: r.name,
|
|
246
|
+
content: r.content,
|
|
247
|
+
estimatedTokens: r.estimatedTokens,
|
|
248
|
+
})),
|
|
249
|
+
truncated,
|
|
250
|
+
};
|
|
251
|
+
this.logger.info('Prompt assembly complete', {
|
|
252
|
+
sessionName: config.sessionName,
|
|
253
|
+
moduleCount: finalResults.length,
|
|
254
|
+
totalTokens: finalTotalTokens,
|
|
255
|
+
budget: this.totalTokenBudget,
|
|
256
|
+
truncatedCount: truncated.length,
|
|
257
|
+
modules: finalResults.map((r) => r.name),
|
|
258
|
+
});
|
|
259
|
+
return {
|
|
260
|
+
prompt: finalResults.map((r) => r.content).join(MODULE_SEPARATOR),
|
|
261
|
+
report,
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Assemble modules and return detailed results with per-module metadata.
|
|
266
|
+
* Convenience wrapper that returns just the report (same as assemble().report).
|
|
267
|
+
*
|
|
268
|
+
* @param config - Configuration with all context needed by modules
|
|
269
|
+
* @returns Assembly details with prompt, modules, and total tokens
|
|
270
|
+
*/
|
|
271
|
+
async assembleWithDetails(config) {
|
|
272
|
+
const { prompt, report } = await this.assemble(config);
|
|
273
|
+
return {
|
|
274
|
+
prompt,
|
|
275
|
+
modules: report.moduleBreakdown,
|
|
276
|
+
totalTokens: report.totalTokens,
|
|
277
|
+
truncated: report.truncated,
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Trim content to a target fraction of its original length.
|
|
282
|
+
* Trims at line boundaries to avoid cutting mid-sentence.
|
|
283
|
+
*
|
|
284
|
+
* @param content - Original content string
|
|
285
|
+
* @param fraction - Target fraction (e.g., 0.5 for 50%)
|
|
286
|
+
* @returns Trimmed content
|
|
287
|
+
*/
|
|
288
|
+
trimContent(content, fraction) {
|
|
289
|
+
const targetLength = Math.floor(content.length * fraction);
|
|
290
|
+
if (targetLength >= content.length)
|
|
291
|
+
return content;
|
|
292
|
+
const lines = content.split('\n');
|
|
293
|
+
let accumulated = 0;
|
|
294
|
+
const kept = [];
|
|
295
|
+
for (const line of lines) {
|
|
296
|
+
if (accumulated + line.length + 1 > targetLength && kept.length > 0) {
|
|
297
|
+
break;
|
|
298
|
+
}
|
|
299
|
+
kept.push(line);
|
|
300
|
+
accumulated += line.length + 1; // +1 for newline
|
|
301
|
+
}
|
|
302
|
+
return kept.join('\n');
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
//# sourceMappingURL=prompt-assembly.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-assembly.service.js","sourceRoot":"","sources":["../../../../../../../backend/src/services/ai/prompt-modules/prompt-assembly.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interface for modular prompt components.
|
|
3
|
+
*
|
|
4
|
+
* Each module is responsible for one concern (identity, skills, team, etc.)
|
|
5
|
+
* and produces a markdown string that gets assembled into the final agent prompt.
|
|
6
|
+
*
|
|
7
|
+
* Modules are assembled in priority order (1 = highest, assembled first).
|
|
8
|
+
* Non-compactable modules are never truncated when token budget is tight.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Configuration passed to each prompt module during assembly.
|
|
12
|
+
* Contains all the context needed to build module-specific content.
|
|
13
|
+
*/
|
|
14
|
+
export interface ModuleConfig {
|
|
15
|
+
/** Agent's session name (e.g. 'crewly-product-sam-217bfbbf') */
|
|
16
|
+
sessionName: string;
|
|
17
|
+
/** Agent's member ID (UUID) */
|
|
18
|
+
memberId: string;
|
|
19
|
+
/** Agent's role (e.g. 'developer', 'orchestrator') */
|
|
20
|
+
role: string;
|
|
21
|
+
/** Team ID this agent belongs to */
|
|
22
|
+
teamId?: string;
|
|
23
|
+
/** Absolute path to the project directory */
|
|
24
|
+
projectPath?: string;
|
|
25
|
+
/** Runtime type determines formatting and injection strategy */
|
|
26
|
+
runtimeType?: 'claude-code' | 'gemini-cli' | 'codex' | 'crewly-agent';
|
|
27
|
+
/** Whether this agent can delegate tasks to subordinates */
|
|
28
|
+
canDelegate?: boolean;
|
|
29
|
+
/** Resolved subordinate details for TL agents */
|
|
30
|
+
subordinates?: SubordinateInfoCompat[];
|
|
31
|
+
/** Absolute path to agent skill scripts */
|
|
32
|
+
agentSkillsPath: string;
|
|
33
|
+
/** Absolute path to team-leader skill scripts */
|
|
34
|
+
tlSkillsPath: string;
|
|
35
|
+
/** Absolute path to the project root (where config/ lives) */
|
|
36
|
+
projectRoot: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Subordinate info compatible with the existing SubordinateInfo type
|
|
40
|
+
*/
|
|
41
|
+
export interface SubordinateInfoCompat {
|
|
42
|
+
name: string;
|
|
43
|
+
sessionName: string;
|
|
44
|
+
role: string;
|
|
45
|
+
memberId: string;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Result of building a single prompt module.
|
|
49
|
+
* Includes the content and metadata for budget tracking.
|
|
50
|
+
*/
|
|
51
|
+
export interface ModuleBuildResult {
|
|
52
|
+
/** Module name */
|
|
53
|
+
name: string;
|
|
54
|
+
/** Generated markdown content */
|
|
55
|
+
content: string;
|
|
56
|
+
/** Estimated token count of the content */
|
|
57
|
+
estimatedTokens: number;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Interface that all prompt modules must implement.
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```typescript
|
|
64
|
+
* class IdentityModule implements PromptModule {
|
|
65
|
+
* name = 'identity';
|
|
66
|
+
* priority = 1;
|
|
67
|
+
* maxTokens = 150;
|
|
68
|
+
* compactable = false;
|
|
69
|
+
*
|
|
70
|
+
* shouldInclude(_config: ModuleConfig): boolean { return true; }
|
|
71
|
+
*
|
|
72
|
+
* async build(config: ModuleConfig): Promise<string> {
|
|
73
|
+
* return `## Your Identity\n- **Session Name:** ${config.sessionName}`;
|
|
74
|
+
* }
|
|
75
|
+
* }
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
export interface PromptModule {
|
|
79
|
+
/** Module name (used for logging and debugging) */
|
|
80
|
+
name: string;
|
|
81
|
+
/** Assembly priority (1 = highest, assembled first) */
|
|
82
|
+
priority: number;
|
|
83
|
+
/** Token soft cap for this module */
|
|
84
|
+
maxTokens: number;
|
|
85
|
+
/** Whether this module can be skipped when token budget is tight */
|
|
86
|
+
compactable: boolean;
|
|
87
|
+
/** Condition check — return false to skip this module */
|
|
88
|
+
shouldInclude(config: ModuleConfig): boolean;
|
|
89
|
+
/** Build module content as markdown string */
|
|
90
|
+
build(config: ModuleConfig): Promise<string>;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Report returned by PromptAssemblyService.assemble() describing
|
|
94
|
+
* token usage and any truncation that occurred.
|
|
95
|
+
*/
|
|
96
|
+
export interface AssemblyReport {
|
|
97
|
+
/** Total estimated tokens in the final prompt */
|
|
98
|
+
totalTokens: number;
|
|
99
|
+
/** Per-module token breakdown */
|
|
100
|
+
moduleBreakdown: ModuleBuildResult[];
|
|
101
|
+
/** Modules that were truncated or removed to fit budget */
|
|
102
|
+
truncated: TruncatedModuleInfo[];
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Info about a module that was truncated or removed during assembly.
|
|
106
|
+
*/
|
|
107
|
+
export interface TruncatedModuleInfo {
|
|
108
|
+
/** Module name */
|
|
109
|
+
name: string;
|
|
110
|
+
/** Original estimated tokens before truncation */
|
|
111
|
+
originalTokens: number;
|
|
112
|
+
/** Tokens after truncation (0 if fully removed) */
|
|
113
|
+
finalTokens: number;
|
|
114
|
+
/** What happened: 'trimmed' (to 50%) or 'removed' (dropped entirely) */
|
|
115
|
+
action: 'trimmed' | 'removed';
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Load a role-specific fragment file from config/roles/{role}/fragments/{fragmentName}.md.
|
|
119
|
+
* Returns null if the file doesn't exist.
|
|
120
|
+
*
|
|
121
|
+
* @param projectRoot - Project root path (where config/ lives)
|
|
122
|
+
* @param role - Agent role (e.g. 'orchestrator')
|
|
123
|
+
* @param fragmentName - Fragment file name without .md extension
|
|
124
|
+
* @returns Fragment content string or null
|
|
125
|
+
*/
|
|
126
|
+
export declare function loadRoleFragment(projectRoot: string, role: string, fragmentName: string): string | null;
|
|
127
|
+
/**
|
|
128
|
+
* Estimate token count from a string.
|
|
129
|
+
* Uses the rough heuristic of ~4 characters per token (suitable for English/code mix).
|
|
130
|
+
*
|
|
131
|
+
* @param text - Text to estimate tokens for
|
|
132
|
+
* @returns Estimated token count
|
|
133
|
+
*/
|
|
134
|
+
export declare function estimateTokens(text: string): number;
|
|
135
|
+
//# sourceMappingURL=prompt-module.interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-module.interface.d.ts","sourceRoot":"","sources":["../../../../../../../backend/src/services/ai/prompt-modules/prompt-module.interface.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC5B,gEAAgE;IAChE,WAAW,EAAE,MAAM,CAAC;IACpB,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,oCAAoC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6CAA6C;IAC7C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gEAAgE;IAChE,WAAW,CAAC,EAAE,aAAa,GAAG,YAAY,GAAG,OAAO,GAAG,cAAc,CAAC;IACtE,4DAA4D;IAC5D,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,iDAAiD;IACjD,YAAY,CAAC,EAAE,qBAAqB,EAAE,CAAC;IACvC,2CAA2C;IAC3C,eAAe,EAAE,MAAM,CAAC;IACxB,iDAAiD;IACjD,YAAY,EAAE,MAAM,CAAC;IACrB,8DAA8D;IAC9D,WAAW,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IACjC,kBAAkB;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,iCAAiC;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,2CAA2C;IAC3C,eAAe,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,YAAY;IAC5B,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,uDAAuD;IACvD,QAAQ,EAAE,MAAM,CAAC;IACjB,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,WAAW,EAAE,OAAO,CAAC;IACrB,yDAAyD;IACzD,aAAa,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC;IAC7C,8CAA8C;IAC9C,KAAK,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC7C;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC9B,iDAAiD;IACjD,WAAW,EAAE,MAAM,CAAC;IACpB,iCAAiC;IACjC,eAAe,EAAE,iBAAiB,EAAE,CAAC;IACrC,2DAA2D;IAC3D,SAAS,EAAE,mBAAmB,EAAE,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IACnC,kBAAkB;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,kDAAkD;IAClD,cAAc,EAAE,MAAM,CAAC;IACvB,mDAAmD;IACnD,WAAW,EAAE,MAAM,CAAC;IACpB,wEAAwE;IACxE,MAAM,EAAE,SAAS,GAAG,SAAS,CAAC;CAC9B;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC/B,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,GAClB,MAAM,GAAG,IAAI,CAYf;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAInD"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interface for modular prompt components.
|
|
3
|
+
*
|
|
4
|
+
* Each module is responsible for one concern (identity, skills, team, etc.)
|
|
5
|
+
* and produces a markdown string that gets assembled into the final agent prompt.
|
|
6
|
+
*
|
|
7
|
+
* Modules are assembled in priority order (1 = highest, assembled first).
|
|
8
|
+
* Non-compactable modules are never truncated when token budget is tight.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Load a role-specific fragment file from config/roles/{role}/fragments/{fragmentName}.md.
|
|
12
|
+
* Returns null if the file doesn't exist.
|
|
13
|
+
*
|
|
14
|
+
* @param projectRoot - Project root path (where config/ lives)
|
|
15
|
+
* @param role - Agent role (e.g. 'orchestrator')
|
|
16
|
+
* @param fragmentName - Fragment file name without .md extension
|
|
17
|
+
* @returns Fragment content string or null
|
|
18
|
+
*/
|
|
19
|
+
export function loadRoleFragment(projectRoot, role, fragmentName) {
|
|
20
|
+
try {
|
|
21
|
+
const fs = require('fs');
|
|
22
|
+
const path = require('path');
|
|
23
|
+
const fragmentPath = path.join(projectRoot, 'config', 'roles', role, 'fragments', `${fragmentName}.md`);
|
|
24
|
+
if (fs.existsSync(fragmentPath)) {
|
|
25
|
+
return fs.readFileSync(fragmentPath, 'utf-8');
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
// Fragment not found — fall back to inline content
|
|
30
|
+
}
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Estimate token count from a string.
|
|
35
|
+
* Uses the rough heuristic of ~4 characters per token (suitable for English/code mix).
|
|
36
|
+
*
|
|
37
|
+
* @param text - Text to estimate tokens for
|
|
38
|
+
* @returns Estimated token count
|
|
39
|
+
*/
|
|
40
|
+
export function estimateTokens(text) {
|
|
41
|
+
if (!text)
|
|
42
|
+
return 0;
|
|
43
|
+
// ~4 chars per token is a reasonable estimate for English + code
|
|
44
|
+
return Math.ceil(text.length / 4);
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=prompt-module.interface.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-module.interface.js","sourceRoot":"","sources":["../../../../../../../backend/src/services/ai/prompt-modules/prompt-module.interface.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAmHH;;;;;;;;GAQG;AACH,MAAM,UAAU,gBAAgB,CAC/B,WAAmB,EACnB,IAAY,EACZ,YAAoB;IAEpB,IAAI,CAAC;QACJ,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QACzB,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;QAC7B,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC;QACxG,IAAI,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YACjC,OAAO,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QAC/C,CAAC;IACF,CAAC;IAAC,MAAM,CAAC;QACR,mDAAmD;IACpD,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY;IAC1C,IAAI,CAAC,IAAI;QAAE,OAAO,CAAC,CAAC;IACpB,iEAAiE;IACjE,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACnC,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { PromptModule, ModuleConfig } from './prompt-module.interface.js';
|
|
2
|
+
/**
|
|
3
|
+
* Recovery module — unified session recovery protocol.
|
|
4
|
+
*
|
|
5
|
+
* Consolidates the restart/recovery flow that was previously scattered
|
|
6
|
+
* across prompt-builder.service.ts buildSessionRecoverySection(),
|
|
7
|
+
* agent-registration.service.ts hardcoded commands, role prompts
|
|
8
|
+
* (Session Recovery Protocol), and session-handoff.service.ts.
|
|
9
|
+
*
|
|
10
|
+
* Produces the mandatory startup sequence: recall → get-my-context → assess.
|
|
11
|
+
* This module is non-compactable because skipping recovery causes
|
|
12
|
+
* duplicate work and lost context.
|
|
13
|
+
*
|
|
14
|
+
* Sources: Path A Step 9, prompt-builder buildSessionRecoverySection(),
|
|
15
|
+
* developer/prompt.md §Session Recovery Protocol.
|
|
16
|
+
*/
|
|
17
|
+
export declare class RecoveryModule implements PromptModule {
|
|
18
|
+
name: string;
|
|
19
|
+
priority: number;
|
|
20
|
+
maxTokens: number;
|
|
21
|
+
compactable: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Always included — every agent needs session recovery.
|
|
24
|
+
*/
|
|
25
|
+
shouldInclude(_config: ModuleConfig): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Build the session recovery protocol with executable bash commands.
|
|
28
|
+
*
|
|
29
|
+
* @param config - Module configuration with agent identity
|
|
30
|
+
* @returns Formatted markdown recovery section
|
|
31
|
+
*/
|
|
32
|
+
build(config: ModuleConfig): Promise<string>;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=recovery.module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recovery.module.d.ts","sourceRoot":"","sources":["../../../../../../../backend/src/services/ai/prompt-modules/recovery.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,YAAY,EAAoB,MAAM,8BAA8B,CAAC;AAE5F;;;;;;;;;;;;;;GAcG;AACH,qBAAa,cAAe,YAAW,YAAY;IAClD,IAAI,SAAc;IAClB,QAAQ,SAAK;IACb,SAAS,SAAO;IAChB,WAAW,UAAS;IAEpB;;OAEG;IACH,aAAa,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO;IAI7C;;;;;OAKG;IACG,KAAK,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;CAoClD"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { loadRoleFragment } from './prompt-module.interface.js';
|
|
2
|
+
/**
|
|
3
|
+
* Recovery module — unified session recovery protocol.
|
|
4
|
+
*
|
|
5
|
+
* Consolidates the restart/recovery flow that was previously scattered
|
|
6
|
+
* across prompt-builder.service.ts buildSessionRecoverySection(),
|
|
7
|
+
* agent-registration.service.ts hardcoded commands, role prompts
|
|
8
|
+
* (Session Recovery Protocol), and session-handoff.service.ts.
|
|
9
|
+
*
|
|
10
|
+
* Produces the mandatory startup sequence: recall → get-my-context → assess.
|
|
11
|
+
* This module is non-compactable because skipping recovery causes
|
|
12
|
+
* duplicate work and lost context.
|
|
13
|
+
*
|
|
14
|
+
* Sources: Path A Step 9, prompt-builder buildSessionRecoverySection(),
|
|
15
|
+
* developer/prompt.md §Session Recovery Protocol.
|
|
16
|
+
*/
|
|
17
|
+
export class RecoveryModule {
|
|
18
|
+
name = 'recovery';
|
|
19
|
+
priority = 2;
|
|
20
|
+
maxTokens = 600;
|
|
21
|
+
compactable = false;
|
|
22
|
+
/**
|
|
23
|
+
* Always included — every agent needs session recovery.
|
|
24
|
+
*/
|
|
25
|
+
shouldInclude(_config) {
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Build the session recovery protocol with executable bash commands.
|
|
30
|
+
*
|
|
31
|
+
* @param config - Module configuration with agent identity
|
|
32
|
+
* @returns Formatted markdown recovery section
|
|
33
|
+
*/
|
|
34
|
+
async build(config) {
|
|
35
|
+
// Try loading role-specific fragment (orchestrator has a different startup flow)
|
|
36
|
+
if (config.role === 'orchestrator') {
|
|
37
|
+
const fragment = loadRoleFragment(config.projectRoot, config.role, 'recovery');
|
|
38
|
+
if (fragment) {
|
|
39
|
+
return fragment;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
const agentId = config.sessionName;
|
|
43
|
+
const role = config.role;
|
|
44
|
+
const projectPath = config.projectPath || config.projectRoot;
|
|
45
|
+
const skillsPath = config.agentSkillsPath;
|
|
46
|
+
return `## Session Recovery Protocol (MANDATORY)
|
|
47
|
+
|
|
48
|
+
**IMMEDIATELY after registering**, you MUST execute the following context recovery steps before saying "Ready" or accepting any tasks. This ensures you recover context from previous sessions and avoid repeating work or missing ongoing tasks.
|
|
49
|
+
|
|
50
|
+
### Step 1: Recall previous knowledge
|
|
51
|
+
\`\`\`bash
|
|
52
|
+
bash ${skillsPath}/core/recall/execute.sh '{"agentId":"${agentId}","context":"${role} session startup, recent tasks, unfinished work, blockers, key decisions","projectPath":"${projectPath}"}'
|
|
53
|
+
\`\`\`
|
|
54
|
+
|
|
55
|
+
### Step 2: Load your full context
|
|
56
|
+
\`\`\`bash
|
|
57
|
+
bash ${skillsPath}/core/get-my-context/execute.sh '{"agentId":"${agentId}","agentRole":"${role}","projectPath":"${projectPath}"}'
|
|
58
|
+
\`\`\`
|
|
59
|
+
|
|
60
|
+
### Step 3: Assess and report
|
|
61
|
+
After reviewing the results from Steps 1 and 2:
|
|
62
|
+
1. **Check for unfinished work** — If you find tasks that were in progress but not completed, note them
|
|
63
|
+
2. **Check for pending blockers** — If previous sessions recorded blockers, note them
|
|
64
|
+
3. **Report status** — Include a brief summary of recovered context in your first status message
|
|
65
|
+
|
|
66
|
+
**Do NOT skip these steps.** Context recovery prevents duplicate work and ensures continuity across sessions.`;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=recovery.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recovery.module.js","sourceRoot":"","sources":["../../../../../../../backend/src/services/ai/prompt-modules/recovery.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAE5F;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,cAAc;IAC1B,IAAI,GAAG,UAAU,CAAC;IAClB,QAAQ,GAAG,CAAC,CAAC;IACb,SAAS,GAAG,GAAG,CAAC;IAChB,WAAW,GAAG,KAAK,CAAC;IAEpB;;OAEG;IACH,aAAa,CAAC,OAAqB;QAClC,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,KAAK,CAAC,MAAoB;QAC/B,iFAAiF;QACjF,IAAI,MAAM,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;YACpC,MAAM,QAAQ,GAAG,gBAAgB,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;YAC/E,IAAI,QAAQ,EAAE,CAAC;gBACd,OAAO,QAAQ,CAAC;YACjB,CAAC;QACF,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,CAAC,WAAW,CAAC;QACnC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;QACzB,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,WAAW,CAAC;QAC7D,MAAM,UAAU,GAAG,MAAM,CAAC,eAAe,CAAC;QAE1C,OAAO;;;;;;OAMF,UAAU,wCAAwC,OAAO,gBAAgB,IAAI,4FAA4F,WAAW;;;;;OAKpL,UAAU,gDAAgD,OAAO,kBAAkB,IAAI,oBAAoB,WAAW;;;;;;;;;8GASf,CAAC;IAC9G,CAAC;CACD"}
|