wave-agent-sdk 0.14.0 → 0.14.2
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/builtin/skills/settings/HOOKS.md +69 -0
- package/builtin/skills/settings/PLUGINS.md +171 -0
- package/builtin/skills/settings/SKILL.md +8 -3
- package/dist/agent.d.ts +2 -2
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +12 -3
- package/dist/core/plugin.d.ts +2 -2
- package/dist/core/plugin.d.ts.map +1 -1
- package/dist/core/plugin.js +7 -7
- package/dist/managers/aiManager.d.ts +6 -6
- package/dist/managers/aiManager.d.ts.map +1 -1
- package/dist/managers/aiManager.js +122 -59
- package/dist/managers/backgroundTaskManager.d.ts.map +1 -1
- package/dist/managers/backgroundTaskManager.js +28 -30
- package/dist/managers/hookManager.d.ts +16 -1
- package/dist/managers/hookManager.d.ts.map +1 -1
- package/dist/managers/hookManager.js +97 -8
- package/dist/managers/messageManager.d.ts +19 -4
- package/dist/managers/messageManager.d.ts.map +1 -1
- package/dist/managers/messageManager.js +63 -18
- package/dist/managers/pluginManager.d.ts.map +1 -1
- package/dist/managers/pluginManager.js +1 -1
- package/dist/prompts/index.d.ts +1 -1
- package/dist/prompts/index.d.ts.map +1 -1
- package/dist/prompts/index.js +1 -1
- package/dist/services/MarketplaceService.d.ts +42 -12
- package/dist/services/MarketplaceService.d.ts.map +1 -1
- package/dist/services/MarketplaceService.js +225 -105
- package/dist/services/aiService.d.ts +3 -3
- package/dist/services/aiService.d.ts.map +1 -1
- package/dist/services/aiService.js +7 -7
- package/dist/services/configurationService.d.ts +17 -1
- package/dist/services/configurationService.d.ts.map +1 -1
- package/dist/services/configurationService.js +104 -0
- package/dist/services/hook.d.ts.map +1 -1
- package/dist/services/hook.js +15 -0
- package/dist/services/initializationService.d.ts.map +1 -1
- package/dist/services/initializationService.js +24 -1
- package/dist/services/interactionService.js +1 -1
- package/dist/services/pluginLoader.d.ts.map +1 -1
- package/dist/services/pluginLoader.js +7 -1
- package/dist/services/session.d.ts +1 -1
- package/dist/services/session.js +7 -7
- package/dist/services/taskManager.d.ts +1 -1
- package/dist/services/taskManager.js +1 -1
- package/dist/types/configuration.d.ts +7 -0
- package/dist/types/configuration.d.ts.map +1 -1
- package/dist/types/core.d.ts +1 -1
- package/dist/types/core.d.ts.map +1 -1
- package/dist/types/hooks.d.ts +9 -1
- package/dist/types/hooks.d.ts.map +1 -1
- package/dist/types/hooks.js +2 -0
- package/dist/types/marketplace.d.ts +2 -0
- package/dist/types/marketplace.d.ts.map +1 -1
- package/dist/types/messaging.d.ts +3 -3
- package/dist/types/messaging.d.ts.map +1 -1
- package/dist/utils/convertMessagesForAPI.d.ts +1 -1
- package/dist/utils/convertMessagesForAPI.js +7 -7
- package/dist/utils/groupMessagesByApiRound.d.ts +1 -1
- package/dist/utils/groupMessagesByApiRound.js +6 -6
- package/dist/utils/messageOperations.d.ts.map +1 -1
- package/dist/utils/messageOperations.js +3 -3
- package/package.json +1 -1
- package/src/agent.ts +16 -3
- package/src/core/plugin.ts +13 -7
- package/src/managers/aiManager.ts +142 -63
- package/src/managers/backgroundTaskManager.ts +33 -42
- package/src/managers/hookManager.ts +125 -10
- package/src/managers/messageManager.ts +76 -22
- package/src/managers/pluginManager.ts +4 -1
- package/src/prompts/index.ts +1 -1
- package/src/services/MarketplaceService.ts +301 -111
- package/src/services/aiService.ts +11 -11
- package/src/services/configurationService.ts +131 -0
- package/src/services/hook.ts +17 -0
- package/src/services/initializationService.ts +33 -1
- package/src/services/interactionService.ts +1 -1
- package/src/services/pluginLoader.ts +7 -1
- package/src/services/session.ts +7 -7
- package/src/services/taskManager.ts +1 -1
- package/src/types/configuration.ts +8 -0
- package/src/types/core.ts +1 -1
- package/src/types/hooks.ts +16 -2
- package/src/types/marketplace.ts +2 -0
- package/src/types/messaging.ts +3 -3
- package/src/utils/convertMessagesForAPI.ts +8 -8
- package/src/utils/groupMessagesByApiRound.ts +6 -6
- package/src/utils/messageOperations.ts +3 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messageOperations.d.ts","sourceRoot":"","sources":["../../src/utils/messageOperations.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"messageOperations.d.ts","sourceRoot":"","sources":["../../src/utils/messageOperations.ts"],"names":[],"mappings":"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"}
|
|
@@ -423,9 +423,9 @@ export function getMessageContent(message) {
|
|
|
423
423
|
if (bangBlock && "command" in bangBlock) {
|
|
424
424
|
return `!${bangBlock.command}`;
|
|
425
425
|
}
|
|
426
|
-
const
|
|
427
|
-
if (
|
|
428
|
-
return
|
|
426
|
+
const compactBlock = message.blocks.find((block) => block.type === "compact");
|
|
427
|
+
if (compactBlock && "content" in compactBlock) {
|
|
428
|
+
return compactBlock.content;
|
|
429
429
|
}
|
|
430
430
|
return "";
|
|
431
431
|
}
|
package/package.json
CHANGED
package/src/agent.ts
CHANGED
|
@@ -317,9 +317,9 @@ export class Agent {
|
|
|
317
317
|
return this.aiManager.isLoading;
|
|
318
318
|
}
|
|
319
319
|
|
|
320
|
-
/** Get message
|
|
321
|
-
public get
|
|
322
|
-
return this.aiManager.
|
|
320
|
+
/** Get message compaction status */
|
|
321
|
+
public get isCompacting(): boolean {
|
|
322
|
+
return this.aiManager.getIsCompacting();
|
|
323
323
|
}
|
|
324
324
|
|
|
325
325
|
/** Get bash command execution status */
|
|
@@ -633,6 +633,19 @@ export class Agent {
|
|
|
633
633
|
this.pendingNotificationPromises = [];
|
|
634
634
|
}
|
|
635
635
|
|
|
636
|
+
// Fire SessionEnd hooks (fire-and-forget, don't block shutdown)
|
|
637
|
+
try {
|
|
638
|
+
const sessionId = this.messageManager.getSessionId();
|
|
639
|
+
const transcriptPath = this.messageManager.getTranscriptPath();
|
|
640
|
+
await this.hookManager.executeSessionEndHooks(
|
|
641
|
+
"stop",
|
|
642
|
+
sessionId,
|
|
643
|
+
transcriptPath,
|
|
644
|
+
);
|
|
645
|
+
} catch (error) {
|
|
646
|
+
this.logger?.warn(`SessionEnd hooks failed: ${(error as Error).message}`);
|
|
647
|
+
}
|
|
648
|
+
|
|
636
649
|
await this.messageManager.saveSession();
|
|
637
650
|
this.abortAIMessage(); // This will abort tools including Agent tool (subagents)
|
|
638
651
|
this.abortBashCommand();
|
package/src/core/plugin.ts
CHANGED
|
@@ -30,7 +30,10 @@ export class PluginCore {
|
|
|
30
30
|
this.workdir = workdir;
|
|
31
31
|
this.container = new Container();
|
|
32
32
|
this.configurationService = new ConfigurationService();
|
|
33
|
-
this.marketplaceService = new MarketplaceService(
|
|
33
|
+
this.marketplaceService = new MarketplaceService(
|
|
34
|
+
this.workdir,
|
|
35
|
+
this.configurationService,
|
|
36
|
+
);
|
|
34
37
|
|
|
35
38
|
// Wire up ConfigurationService in the container for PluginManager to use
|
|
36
39
|
this.container.register("ConfigurationService", this.configurationService);
|
|
@@ -122,7 +125,7 @@ export class PluginCore {
|
|
|
122
125
|
for (const m of marketplaces) {
|
|
123
126
|
try {
|
|
124
127
|
const manifest = await this.marketplaceService.loadMarketplaceManifest(
|
|
125
|
-
this.marketplaceService.getMarketplacePath(m),
|
|
128
|
+
this.marketplaceService.getMarketplacePath(m.source),
|
|
126
129
|
);
|
|
127
130
|
manifest.plugins.forEach((p) => {
|
|
128
131
|
const pluginId = `${p.name}@${m.name}`;
|
|
@@ -154,15 +157,18 @@ export class PluginCore {
|
|
|
154
157
|
/**
|
|
155
158
|
* Adds a new marketplace
|
|
156
159
|
*/
|
|
157
|
-
async addMarketplace(
|
|
158
|
-
|
|
160
|
+
async addMarketplace(
|
|
161
|
+
input: string,
|
|
162
|
+
scope: Scope = "user",
|
|
163
|
+
): Promise<KnownMarketplace> {
|
|
164
|
+
return await this.marketplaceService.addMarketplace(input, scope);
|
|
159
165
|
}
|
|
160
166
|
|
|
161
167
|
/**
|
|
162
168
|
* Removes a marketplace by name
|
|
163
169
|
*/
|
|
164
|
-
async removeMarketplace(name: string): Promise<void> {
|
|
165
|
-
await this.marketplaceService.removeMarketplace(name);
|
|
170
|
+
async removeMarketplace(name: string, scope?: Scope): Promise<void> {
|
|
171
|
+
await this.marketplaceService.removeMarketplace(name, scope);
|
|
166
172
|
}
|
|
167
173
|
|
|
168
174
|
/**
|
|
@@ -208,7 +214,7 @@ export class PluginCore {
|
|
|
208
214
|
* Resolves the local path for a marketplace
|
|
209
215
|
*/
|
|
210
216
|
getMarketplacePath(marketplace: KnownMarketplace): string {
|
|
211
|
-
return this.marketplaceService.getMarketplacePath(marketplace);
|
|
217
|
+
return this.marketplaceService.getMarketplacePath(marketplace.source);
|
|
212
218
|
}
|
|
213
219
|
|
|
214
220
|
/**
|
|
@@ -30,7 +30,7 @@ import type { NotificationQueue } from "./notificationQueue.js";
|
|
|
30
30
|
import { logger } from "../utils/globalLogger.js";
|
|
31
31
|
|
|
32
32
|
export interface AIManagerCallbacks {
|
|
33
|
-
|
|
33
|
+
onCompactionStateChange?: (isCompacting: boolean) => void;
|
|
34
34
|
onUsageAdded?: (usage: Usage) => void;
|
|
35
35
|
onCwdChange?: (newCwd: string) => void;
|
|
36
36
|
}
|
|
@@ -58,7 +58,7 @@ export class AIManager {
|
|
|
58
58
|
private stream: boolean; // Streaming mode flag
|
|
59
59
|
private modelOverride?: string;
|
|
60
60
|
private _onCwdChange?: (newCwd: string) => void; // Store callback for CWD changes
|
|
61
|
-
private
|
|
61
|
+
private consecutiveCompactionFailures: number = 0;
|
|
62
62
|
|
|
63
63
|
// Service overrides
|
|
64
64
|
constructor(
|
|
@@ -177,7 +177,7 @@ export class AIManager {
|
|
|
177
177
|
this._onCwdChange = callback;
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
-
private
|
|
180
|
+
private isCompacting: boolean = false;
|
|
181
181
|
private callbacks: AIManagerCallbacks;
|
|
182
182
|
|
|
183
183
|
/**
|
|
@@ -253,8 +253,8 @@ export class AIManager {
|
|
|
253
253
|
return "";
|
|
254
254
|
}
|
|
255
255
|
|
|
256
|
-
// Private method to handle token statistics and message
|
|
257
|
-
private async
|
|
256
|
+
// Private method to handle token statistics and message compaction
|
|
257
|
+
private async handleTokenUsageAndCompaction(
|
|
258
258
|
usage: Usage | undefined,
|
|
259
259
|
abortController: AbortController,
|
|
260
260
|
): Promise<void> {
|
|
@@ -272,30 +272,30 @@ export class AIManager {
|
|
|
272
272
|
this.getMaxInputTokens()
|
|
273
273
|
) {
|
|
274
274
|
logger?.debug(
|
|
275
|
-
`Token usage exceeded ${this.getMaxInputTokens()},
|
|
275
|
+
`Token usage exceeded ${this.getMaxInputTokens()}, compacting messages...`,
|
|
276
276
|
);
|
|
277
277
|
|
|
278
|
-
// Check if messages need
|
|
279
|
-
const
|
|
278
|
+
// Check if messages need compaction
|
|
279
|
+
const messagesToCompact = this.messageManager.getMessages();
|
|
280
280
|
|
|
281
|
-
// If there are messages to
|
|
282
|
-
if (
|
|
283
|
-
// Circuit breaker: skip
|
|
284
|
-
if (this.
|
|
281
|
+
// If there are messages to compact, perform compaction
|
|
282
|
+
if (messagesToCompact.length > 0) {
|
|
283
|
+
// Circuit breaker: skip compaction after 3 consecutive failures
|
|
284
|
+
if (this.consecutiveCompactionFailures >= 3) {
|
|
285
285
|
logger?.warn(
|
|
286
|
-
`Skipping
|
|
286
|
+
`Skipping compaction: ${this.consecutiveCompactionFailures} consecutive failures`,
|
|
287
287
|
);
|
|
288
288
|
return;
|
|
289
289
|
}
|
|
290
290
|
|
|
291
|
-
const recentChatMessages = convertMessagesForAPI(
|
|
291
|
+
const recentChatMessages = convertMessagesForAPI(messagesToCompact);
|
|
292
292
|
|
|
293
|
-
// Save session before
|
|
293
|
+
// Save session before compaction to preserve original messages
|
|
294
294
|
await this.messageManager.saveSession();
|
|
295
295
|
|
|
296
|
-
this.
|
|
296
|
+
this.setIsCompacting(true);
|
|
297
297
|
try {
|
|
298
|
-
const
|
|
298
|
+
const compactResult = await aiService.compactMessages({
|
|
299
299
|
gatewayConfig: this.getGatewayConfig(),
|
|
300
300
|
modelConfig: this.getModelConfig(),
|
|
301
301
|
messages: recentChatMessages,
|
|
@@ -303,15 +303,15 @@ export class AIManager {
|
|
|
303
303
|
model: this.getModelConfig().fastModel,
|
|
304
304
|
});
|
|
305
305
|
|
|
306
|
-
// Handle usage tracking for
|
|
307
|
-
let
|
|
308
|
-
if (
|
|
309
|
-
|
|
310
|
-
prompt_tokens:
|
|
311
|
-
completion_tokens:
|
|
312
|
-
total_tokens:
|
|
306
|
+
// Handle usage tracking for compaction operations
|
|
307
|
+
let compactUsage: Usage | undefined;
|
|
308
|
+
if (compactResult.usage) {
|
|
309
|
+
compactUsage = {
|
|
310
|
+
prompt_tokens: compactResult.usage.prompt_tokens,
|
|
311
|
+
completion_tokens: compactResult.usage.completion_tokens,
|
|
312
|
+
total_tokens: compactResult.usage.total_tokens,
|
|
313
313
|
model: this.getModelConfig().fastModel,
|
|
314
|
-
operation_type: "
|
|
314
|
+
operation_type: "compact",
|
|
315
315
|
};
|
|
316
316
|
}
|
|
317
317
|
|
|
@@ -364,73 +364,152 @@ export class AIManager {
|
|
|
364
364
|
}
|
|
365
365
|
}
|
|
366
366
|
|
|
367
|
-
// 4.
|
|
368
|
-
const
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
if (
|
|
373
|
-
const
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
367
|
+
// 4. Invoked skills context (with token budget, matching Claude Code)
|
|
368
|
+
const POST_COMPACT_SKILLS_TOKEN_BUDGET = 25_000;
|
|
369
|
+
const POST_COMPACT_MAX_TOKENS_PER_SKILL = 5_000;
|
|
370
|
+
const invokedSkillNames =
|
|
371
|
+
this.messageManager.getInvokedSkillNames(10);
|
|
372
|
+
if (invokedSkillNames.length > 0 && this.skillManager) {
|
|
373
|
+
const invokedSkillParts: string[] = [];
|
|
374
|
+
let skillsUsedTokens = 0;
|
|
375
|
+
for (const skillName of invokedSkillNames) {
|
|
376
|
+
try {
|
|
377
|
+
const skill = await this.skillManager.loadSkill(skillName);
|
|
378
|
+
if (!skill) continue;
|
|
379
|
+
|
|
380
|
+
// Extract content after frontmatter (matching prepareSkillContent pattern)
|
|
381
|
+
const contentMatch = skill.content.match(
|
|
382
|
+
/^---\n[\s\S]*?\n---\n([\s\S]*)$/,
|
|
383
|
+
);
|
|
384
|
+
let skillContent = contentMatch
|
|
385
|
+
? contentMatch[1].trim()
|
|
386
|
+
: skill.content;
|
|
387
|
+
|
|
388
|
+
// Per-skill token budget enforcement (~4 chars per token)
|
|
389
|
+
const maxSkillChars = POST_COMPACT_MAX_TOKENS_PER_SKILL * 4;
|
|
390
|
+
if (skillContent.length > maxSkillChars) {
|
|
391
|
+
skillContent =
|
|
392
|
+
skillContent.slice(0, maxSkillChars) +
|
|
393
|
+
"\n\n...[truncated]...";
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
const skillTokens = Math.ceil(skillContent.length / 4);
|
|
397
|
+
if (
|
|
398
|
+
skillsUsedTokens + skillTokens >
|
|
399
|
+
POST_COMPACT_SKILLS_TOKEN_BUDGET
|
|
400
|
+
)
|
|
401
|
+
break;
|
|
402
|
+
skillsUsedTokens += skillTokens;
|
|
403
|
+
|
|
404
|
+
invokedSkillParts.push(
|
|
405
|
+
`\n\n## ${skill.name}\n${skill.description ? `*${skill.description}*\n\n` : ""}\`\`\`\n${skillContent}\n\`\`\``,
|
|
406
|
+
);
|
|
407
|
+
} catch {
|
|
408
|
+
// Skip skills that can't be loaded
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
if (invokedSkillParts.length > 0) {
|
|
412
|
+
contextParts.push(
|
|
413
|
+
`\n\n[Invoked Skills]\n${invokedSkillParts.join("")}`,
|
|
414
|
+
);
|
|
415
|
+
}
|
|
377
416
|
}
|
|
378
417
|
|
|
379
|
-
// 5. Background
|
|
380
|
-
const agents =
|
|
418
|
+
// 5. Background subagent status (shell tasks excluded, matching Claude Code's createAsyncAgentAttachmentsIfNeeded)
|
|
419
|
+
const agents =
|
|
420
|
+
this.backgroundTaskManager
|
|
421
|
+
?.getAllTasks()
|
|
422
|
+
.filter((a) => a.type === "subagent") || [];
|
|
381
423
|
if (agents.length > 0) {
|
|
382
|
-
const
|
|
383
|
-
|
|
384
|
-
.
|
|
385
|
-
|
|
424
|
+
const agentParts: string[] = [];
|
|
425
|
+
for (const a of agents) {
|
|
426
|
+
if (a.status === "killed") {
|
|
427
|
+
agentParts.push(
|
|
428
|
+
`Task "${a.description}" (${a.id}) was stopped by the user.`,
|
|
429
|
+
);
|
|
430
|
+
} else if (a.status === "running") {
|
|
431
|
+
const parts = [
|
|
432
|
+
`Background agent "${a.description}" (${a.id}) is still running.`,
|
|
433
|
+
`Do NOT spawn a duplicate. You will be notified when it completes.`,
|
|
434
|
+
];
|
|
435
|
+
if (a.outputPath) {
|
|
436
|
+
parts.push(`You can read partial output at ${a.outputPath}.`);
|
|
437
|
+
}
|
|
438
|
+
agentParts.push(parts.join(" "));
|
|
439
|
+
} else {
|
|
440
|
+
// completed or failed
|
|
441
|
+
const parts = [
|
|
442
|
+
`Task ${a.id} (status: ${a.status}) (description: ${a.description}).`,
|
|
443
|
+
];
|
|
444
|
+
const deltaText = a.status === "failed" ? a.stderr : a.stdout;
|
|
445
|
+
if (deltaText && deltaText.length > 0) {
|
|
446
|
+
const summary =
|
|
447
|
+
deltaText.length > 500
|
|
448
|
+
? deltaText.slice(0, 500) + "..."
|
|
449
|
+
: deltaText;
|
|
450
|
+
parts.push(`Delta: ${summary}`);
|
|
451
|
+
}
|
|
452
|
+
if (a.outputPath) {
|
|
453
|
+
parts.push(
|
|
454
|
+
`Read the output file to retrieve the result: ${a.outputPath}.`,
|
|
455
|
+
);
|
|
456
|
+
}
|
|
457
|
+
agentParts.push(parts.join(" "));
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
if (agentParts.length > 0) {
|
|
461
|
+
contextParts.push(
|
|
462
|
+
`\n\n[Background Tasks]\n${agentParts.join("\n")}`,
|
|
463
|
+
);
|
|
464
|
+
}
|
|
386
465
|
}
|
|
387
466
|
|
|
388
467
|
// Merge context restoration into summary
|
|
389
468
|
const enhancedSummary =
|
|
390
|
-
|
|
469
|
+
compactResult.content +
|
|
391
470
|
(contextParts.length > 0
|
|
392
471
|
? `\n\n[Context Restoration]` + contextParts.join("")
|
|
393
472
|
: "");
|
|
394
473
|
|
|
395
|
-
// Execute message reconstruction and sessionId update after
|
|
396
|
-
this.messageManager.
|
|
474
|
+
// Execute message reconstruction and sessionId update after compaction
|
|
475
|
+
this.messageManager.compactMessagesAndUpdateSession(
|
|
397
476
|
enhancedSummary,
|
|
398
|
-
|
|
477
|
+
compactUsage,
|
|
399
478
|
);
|
|
400
479
|
|
|
401
480
|
// Notify Agent to add to usage tracking
|
|
402
|
-
if (
|
|
403
|
-
this.callbacks.onUsageAdded(
|
|
481
|
+
if (compactUsage && this.callbacks?.onUsageAdded) {
|
|
482
|
+
this.callbacks.onUsageAdded(compactUsage);
|
|
404
483
|
}
|
|
405
484
|
|
|
406
485
|
logger?.debug(
|
|
407
|
-
`Successfully
|
|
486
|
+
`Successfully compacted ${messagesToCompact.length} messages and updated session`,
|
|
408
487
|
);
|
|
409
|
-
this.
|
|
410
|
-
} catch (
|
|
411
|
-
this.
|
|
488
|
+
this.consecutiveCompactionFailures = 0;
|
|
489
|
+
} catch (compactError) {
|
|
490
|
+
this.consecutiveCompactionFailures++;
|
|
412
491
|
logger?.error(
|
|
413
|
-
`Failed to
|
|
414
|
-
|
|
492
|
+
`Failed to compact messages (${this.consecutiveCompactionFailures} consecutive):`,
|
|
493
|
+
compactError,
|
|
415
494
|
);
|
|
416
495
|
this.messageManager.addErrorBlock(
|
|
417
|
-
`Failed to
|
|
496
|
+
`Failed to compact conversation history: ${compactError instanceof Error ? compactError.message : String(compactError)}. You may encounter context limit issues.`,
|
|
418
497
|
);
|
|
419
498
|
} finally {
|
|
420
|
-
this.
|
|
499
|
+
this.setIsCompacting(false);
|
|
421
500
|
}
|
|
422
501
|
}
|
|
423
502
|
}
|
|
424
503
|
}
|
|
425
504
|
|
|
426
|
-
public
|
|
427
|
-
return this.
|
|
505
|
+
public getIsCompacting(): boolean {
|
|
506
|
+
return this.isCompacting;
|
|
428
507
|
}
|
|
429
508
|
|
|
430
|
-
public
|
|
431
|
-
if (this.
|
|
432
|
-
this.
|
|
433
|
-
this.callbacks.
|
|
509
|
+
public setIsCompacting(isCompacting: boolean): void {
|
|
510
|
+
if (this.isCompacting !== isCompacting) {
|
|
511
|
+
this.isCompacting = isCompacting;
|
|
512
|
+
this.callbacks.onCompactionStateChange?.(isCompacting);
|
|
434
513
|
}
|
|
435
514
|
}
|
|
436
515
|
|
|
@@ -914,8 +993,8 @@ export class AIManager {
|
|
|
914
993
|
await Promise.all(toolExecutionPromises);
|
|
915
994
|
}
|
|
916
995
|
|
|
917
|
-
// Handle token statistics and message
|
|
918
|
-
await this.
|
|
996
|
+
// Handle token statistics and message compaction
|
|
997
|
+
await this.handleTokenUsageAndCompaction(result.usage, abortController);
|
|
919
998
|
|
|
920
999
|
// Finalize text/reasoning blocks for the final response (no tools)
|
|
921
1000
|
this.messageManager.finalizeStreamingBlocks();
|
|
@@ -2,11 +2,7 @@ import { spawn, type ChildProcess } from "child_process";
|
|
|
2
2
|
import * as os from "os";
|
|
3
3
|
import * as fs from "fs";
|
|
4
4
|
import * as path from "path";
|
|
5
|
-
import {
|
|
6
|
-
BackgroundTask,
|
|
7
|
-
BackgroundShell,
|
|
8
|
-
BackgroundSubagent,
|
|
9
|
-
} from "../types/processes.js";
|
|
5
|
+
import { BackgroundTask, BackgroundShell } from "../types/processes.js";
|
|
10
6
|
import { stripAnsiColors } from "../utils/stringUtils.js";
|
|
11
7
|
import { logger } from "../utils/globalLogger.js";
|
|
12
8
|
import { Container } from "../utils/container.js";
|
|
@@ -157,22 +153,27 @@ export class BackgroundTaskManager {
|
|
|
157
153
|
if (logStream.writable) {
|
|
158
154
|
logStream.end();
|
|
159
155
|
}
|
|
160
|
-
shell.status
|
|
156
|
+
const wasKilled = shell.status === "killed";
|
|
157
|
+
if (!wasKilled) {
|
|
158
|
+
shell.status = code === 0 ? "completed" : "failed";
|
|
159
|
+
}
|
|
161
160
|
shell.exitCode = code ?? 0;
|
|
162
161
|
shell.endTime = Date.now();
|
|
163
162
|
shell.runtime = shell.endTime - startTime;
|
|
164
163
|
this.notifyTasksChange();
|
|
165
164
|
|
|
166
|
-
//
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
165
|
+
// Skip notification if task was manually killed (user/agent-initiated stop)
|
|
166
|
+
if (!wasKilled) {
|
|
167
|
+
const notificationQueue = this.container.has("NotificationQueue")
|
|
168
|
+
? this.container.get<NotificationQueue>("NotificationQueue")
|
|
169
|
+
: undefined;
|
|
170
|
+
if (notificationQueue) {
|
|
171
|
+
const statusStr = shell.status;
|
|
172
|
+
const summary = `Command "${command}" ${statusStr} with exit code ${code ?? 0}`;
|
|
173
|
+
notificationQueue.enqueue(
|
|
174
|
+
`<task-notification>\n<task-id>${id}</task-id>\n<task-type>shell</task-type>\n<output-file>${logPath}</output-file>\n<status>${statusStr}</status>\n<summary>${summary}</summary>\n</task-notification>`,
|
|
175
|
+
);
|
|
176
|
+
}
|
|
176
177
|
}
|
|
177
178
|
};
|
|
178
179
|
|
|
@@ -305,22 +306,27 @@ export class BackgroundTaskManager {
|
|
|
305
306
|
if (logStream.writable) {
|
|
306
307
|
logStream.end();
|
|
307
308
|
}
|
|
308
|
-
shell.status
|
|
309
|
+
const wasKilled = shell.status === "killed";
|
|
310
|
+
if (!wasKilled) {
|
|
311
|
+
shell.status = code === 0 ? "completed" : "failed";
|
|
312
|
+
}
|
|
309
313
|
shell.exitCode = code ?? 0;
|
|
310
314
|
shell.endTime = Date.now();
|
|
311
315
|
shell.runtime = shell.endTime - startTime;
|
|
312
316
|
this.notifyTasksChange();
|
|
313
317
|
|
|
314
|
-
//
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
318
|
+
// Skip notification if task was manually killed (user/agent-initiated stop)
|
|
319
|
+
if (!wasKilled) {
|
|
320
|
+
const notificationQueue = this.container.has("NotificationQueue")
|
|
321
|
+
? this.container.get<NotificationQueue>("NotificationQueue")
|
|
322
|
+
: undefined;
|
|
323
|
+
if (notificationQueue) {
|
|
324
|
+
const statusStr = shell.status;
|
|
325
|
+
const summary = `Command "${command}" ${statusStr} with exit code ${code ?? 0}`;
|
|
326
|
+
notificationQueue.enqueue(
|
|
327
|
+
`<task-notification>\n<task-id>${id}</task-id>\n<task-type>shell</task-type>\n<output-file>${logPath}</output-file>\n<status>${statusStr}</status>\n<summary>${summary}</summary>\n</task-notification>`,
|
|
328
|
+
);
|
|
329
|
+
}
|
|
324
330
|
}
|
|
325
331
|
});
|
|
326
332
|
|
|
@@ -427,21 +433,6 @@ export class BackgroundTaskManager {
|
|
|
427
433
|
task.runtime = task.endTime - task.startTime;
|
|
428
434
|
this.notifyTasksChange();
|
|
429
435
|
|
|
430
|
-
// Enqueue killed notification
|
|
431
|
-
const notificationQueue = this.container.has("NotificationQueue")
|
|
432
|
-
? this.container.get<NotificationQueue>("NotificationQueue")
|
|
433
|
-
: undefined;
|
|
434
|
-
if (notificationQueue) {
|
|
435
|
-
const description = (task as BackgroundSubagent).description || "";
|
|
436
|
-
const command = (task as BackgroundShell).command || "";
|
|
437
|
-
const summary =
|
|
438
|
-
task.type === "subagent"
|
|
439
|
-
? `Agent task "${description}" was stopped`
|
|
440
|
-
: `Command "${command}" was stopped`;
|
|
441
|
-
notificationQueue.enqueue(
|
|
442
|
-
`<task-notification>\n<task-id>${id}</task-id>\n<task-type>${task.type}</task-type>\n<status>killed</status>\n<summary>${summary}</summary>\n</task-notification>`,
|
|
443
|
-
);
|
|
444
|
-
}
|
|
445
436
|
return true;
|
|
446
437
|
}
|
|
447
438
|
|