@dreb/coding-agent 2.59.1 → 2.60.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/dist/core/agent-session.d.ts +4 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +43 -20
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/settings-manager.d.ts +19 -4
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +34 -6
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts +1 -3
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +1 -5
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +1 -1
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/docs/dashboard.md +12 -3
- package/docs/mach6.md +4 -4
- package/docs/models.md +6 -0
- package/docs/settings.md +50 -9
- package/package.json +1 -1
- package/skills/mach6-review/SKILL.md +11 -9
|
@@ -20,7 +20,7 @@ import { getDocsPath } from "../config.js";
|
|
|
20
20
|
import { theme } from "../modes/interactive/theme/theme.js";
|
|
21
21
|
import { sleep } from "../utils/sleep.js";
|
|
22
22
|
import { executeBash as executeBashCommand, executeBashWithOperations } from "./bash-executor.js";
|
|
23
|
-
import { calculateContextTokens, collectEntriesForBranchSummary, compact, estimateContextTokens, generateBranchSummary, prepareCompaction, shouldCompact, } from "./compaction/index.js";
|
|
23
|
+
import { calculateContextTokens, collectEntriesForBranchSummary, compact, estimateContextTokens, estimateTokens, generateBranchSummary, prepareCompaction, shouldCompact, } from "./compaction/index.js";
|
|
24
24
|
import { DEFAULT_THINKING_LEVEL } from "./defaults.js";
|
|
25
25
|
import { DispatchArbiter } from "./dispatch-arbiter.js";
|
|
26
26
|
import { exportSessionToHtml } from "./export-html/index.js";
|
|
@@ -36,7 +36,7 @@ import { PerformanceTracker } from "./performance-tracker.js";
|
|
|
36
36
|
import { expandPromptTemplate } from "./prompt-templates.js";
|
|
37
37
|
import { scrubSecrets } from "./secret-scrubber.js";
|
|
38
38
|
import { isSensitivePath } from "./sensitive-paths.js";
|
|
39
|
-
import { CURRENT_SESSION_VERSION, getLatestCompactionEntry } from "./session-manager.js";
|
|
39
|
+
import { CURRENT_SESSION_VERSION, getLatestCompactionEntry, SessionManager, } from "./session-manager.js";
|
|
40
40
|
import { DEFAULT_BG_PARENT_TURN_LIMIT, DEFAULT_MAX_CONCURRENT_SUBAGENTS, } from "./settings-manager.js";
|
|
41
41
|
import { createSyntheticSourceInfo } from "./source-info.js";
|
|
42
42
|
import { buildSystemPrompt } from "./system-prompt.js";
|
|
@@ -1233,7 +1233,15 @@ export class AgentSession {
|
|
|
1233
1233
|
}
|
|
1234
1234
|
const loaderSystemPrompt = this._resourceLoader.getSystemPrompt();
|
|
1235
1235
|
const loaderAppendSystemPrompt = this._resourceLoader.getAppendSystemPrompt();
|
|
1236
|
-
const
|
|
1236
|
+
const modelPromptSettings = this.model
|
|
1237
|
+
? this.settingsManager.getModelPromptSettings(this.model.provider, this.model.id)
|
|
1238
|
+
: undefined;
|
|
1239
|
+
const customPrompt = loaderSystemPrompt ?? modelPromptSettings?.systemPrompt;
|
|
1240
|
+
const appendPromptParts = [...loaderAppendSystemPrompt];
|
|
1241
|
+
if (modelPromptSettings?.appendSystemPrompt) {
|
|
1242
|
+
appendPromptParts.push(modelPromptSettings.appendSystemPrompt);
|
|
1243
|
+
}
|
|
1244
|
+
const appendSystemPrompt = appendPromptParts.length > 0 ? appendPromptParts.join("\n\n") : undefined;
|
|
1237
1245
|
const loadedSkills = this._getFilteredSkills();
|
|
1238
1246
|
const loadedContextFiles = this._resourceLoader.getAgentsFiles().agentsFiles;
|
|
1239
1247
|
const memoryIndexes = this._resourceLoader.getMemoryIndexes();
|
|
@@ -1242,7 +1250,7 @@ export class AgentSession {
|
|
|
1242
1250
|
skills: loadedSkills,
|
|
1243
1251
|
contextFiles: loadedContextFiles,
|
|
1244
1252
|
memoryIndexes,
|
|
1245
|
-
customPrompt
|
|
1253
|
+
customPrompt,
|
|
1246
1254
|
appendSystemPrompt,
|
|
1247
1255
|
selectedTools: validToolNames,
|
|
1248
1256
|
toolSnippets,
|
|
@@ -1723,6 +1731,7 @@ export class AgentSession {
|
|
|
1723
1731
|
if (!apiKey) {
|
|
1724
1732
|
throw new Error(`No API key for ${model.provider}/${model.id}`);
|
|
1725
1733
|
}
|
|
1734
|
+
this._validateModelPromptSettings(model);
|
|
1726
1735
|
const previousModel = this.model;
|
|
1727
1736
|
const thinkingLevel = this._getThinkingLevelForModelSwitch();
|
|
1728
1737
|
this.agent.setModel(this._applyContextTier(model));
|
|
@@ -1744,6 +1753,10 @@ export class AgentSession {
|
|
|
1744
1753
|
_refreshThinkingDisplay(model) {
|
|
1745
1754
|
this.agent.thinkingDisplay = resolveThinkingDisplay(model, this.settingsManager.getModelThinkingDisplay(model.id));
|
|
1746
1755
|
}
|
|
1756
|
+
/** Reject malformed target-model prompt settings before a model switch mutates session state. */
|
|
1757
|
+
_validateModelPromptSettings(model) {
|
|
1758
|
+
this.settingsManager.getModelPromptSettings(model.provider, model.id);
|
|
1759
|
+
}
|
|
1747
1760
|
/**
|
|
1748
1761
|
* Cycle to next/previous model.
|
|
1749
1762
|
* Uses scoped models (from --models flag) if available, otherwise all available models.
|
|
@@ -1786,6 +1799,7 @@ export class AgentSession {
|
|
|
1786
1799
|
const len = scopedModels.length;
|
|
1787
1800
|
const nextIndex = direction === "forward" ? (currentIndex + 1) % len : (currentIndex - 1 + len) % len;
|
|
1788
1801
|
const next = scopedModels[nextIndex];
|
|
1802
|
+
this._validateModelPromptSettings(next.model);
|
|
1789
1803
|
const thinkingLevel = this._getThinkingLevelForModelSwitch(next.thinkingLevel);
|
|
1790
1804
|
// Apply model
|
|
1791
1805
|
this.agent.setModel(this._applyContextTier(next.model));
|
|
@@ -1817,6 +1831,7 @@ export class AgentSession {
|
|
|
1817
1831
|
if (!apiKey) {
|
|
1818
1832
|
throw new Error(`No API key for ${nextModel.provider}/${nextModel.id}`);
|
|
1819
1833
|
}
|
|
1834
|
+
this._validateModelPromptSettings(nextModel);
|
|
1820
1835
|
const thinkingLevel = this._getThinkingLevelForModelSwitch();
|
|
1821
1836
|
this.agent.setModel(this._applyContextTier(nextModel));
|
|
1822
1837
|
this._refreshThinkingDisplay(nextModel);
|
|
@@ -2959,6 +2974,17 @@ export class AgentSession {
|
|
|
2959
2974
|
return false;
|
|
2960
2975
|
}
|
|
2961
2976
|
}
|
|
2977
|
+
// Resolve and validate the target model before disconnecting or mutating the active session.
|
|
2978
|
+
// Prompt validation can throw for malformed settings, so it belongs in this preflight phase.
|
|
2979
|
+
const targetModel = SessionManager.open(sessionPath).buildSessionContext().model;
|
|
2980
|
+
let restoredModel;
|
|
2981
|
+
if (targetModel) {
|
|
2982
|
+
const availableModels = await this._modelRegistry.getAvailable();
|
|
2983
|
+
restoredModel = availableModels.find((m) => m.provider === targetModel.provider && m.id === targetModel.modelId);
|
|
2984
|
+
if (restoredModel) {
|
|
2985
|
+
this._validateModelPromptSettings(restoredModel);
|
|
2986
|
+
}
|
|
2987
|
+
}
|
|
2962
2988
|
this._disconnectFromAgent();
|
|
2963
2989
|
await this.abort();
|
|
2964
2990
|
this._steeringMessages = [];
|
|
@@ -2980,16 +3006,12 @@ export class AgentSession {
|
|
|
2980
3006
|
}
|
|
2981
3007
|
// Emit session event to custom tools
|
|
2982
3008
|
this.agent.replaceMessages(sessionContext.messages);
|
|
2983
|
-
// Restore model if saved
|
|
2984
|
-
if (
|
|
3009
|
+
// Restore the preflighted model if the target session saved one that is still available.
|
|
3010
|
+
if (restoredModel) {
|
|
2985
3011
|
const previousModel = this.model;
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
this.agent.setModel(this._applyContextTier(match));
|
|
2990
|
-
this._refreshThinkingDisplay(match);
|
|
2991
|
-
await this._emitModelSelect(match, previousModel, "restore");
|
|
2992
|
-
}
|
|
3012
|
+
this.agent.setModel(this._applyContextTier(restoredModel));
|
|
3013
|
+
this._refreshThinkingDisplay(restoredModel);
|
|
3014
|
+
await this._emitModelSelect(restoredModel, previousModel, "restore");
|
|
2993
3015
|
}
|
|
2994
3016
|
const hasThinkingEntry = this.sessionManager.getBranch().some((entry) => entry.type === "thinking_level_change");
|
|
2995
3017
|
const defaultThinkingLevel = this.settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL;
|
|
@@ -3009,6 +3031,7 @@ export class AgentSession {
|
|
|
3009
3031
|
this._gitRepoState = getGitRepoState(this._cwd) ?? undefined;
|
|
3010
3032
|
this._resourceLoader.refreshDreamLastRun();
|
|
3011
3033
|
this._baseSystemPrompt = this._rebuildSystemPrompt(this.getActiveToolNames());
|
|
3034
|
+
this.agent.setSystemPrompt(this._baseSystemPrompt);
|
|
3012
3035
|
this._reconnectToAgent();
|
|
3013
3036
|
return true;
|
|
3014
3037
|
}
|
|
@@ -3346,11 +3369,12 @@ export class AgentSession {
|
|
|
3346
3369
|
return undefined;
|
|
3347
3370
|
// After compaction, the last assistant usage reflects pre-compaction context size.
|
|
3348
3371
|
// We can only trust usage from an assistant that responded after the latest compaction.
|
|
3349
|
-
//
|
|
3372
|
+
// Until then, estimate every rebuilt message independently so the stale kept
|
|
3373
|
+
// assistant usage cannot leak into the current context value.
|
|
3350
3374
|
const branchEntries = this.sessionManager.getBranch();
|
|
3351
3375
|
const latestCompaction = getLatestCompactionEntry(branchEntries);
|
|
3352
3376
|
if (latestCompaction) {
|
|
3353
|
-
// Check if there's a valid assistant usage after the compaction boundary
|
|
3377
|
+
// Check if there's a valid assistant usage after the compaction boundary.
|
|
3354
3378
|
const compactionIndex = branchEntries.lastIndexOf(latestCompaction);
|
|
3355
3379
|
let hasPostCompactionUsage = false;
|
|
3356
3380
|
for (let i = branchEntries.length - 1; i > compactionIndex; i--) {
|
|
@@ -3359,23 +3383,22 @@ export class AgentSession {
|
|
|
3359
3383
|
const assistant = entry.message;
|
|
3360
3384
|
if (assistant.stopReason !== "aborted" && assistant.stopReason !== "error") {
|
|
3361
3385
|
const contextTokens = calculateContextTokens(assistant.usage);
|
|
3362
|
-
if (contextTokens > 0)
|
|
3386
|
+
if (contextTokens > 0)
|
|
3363
3387
|
hasPostCompactionUsage = true;
|
|
3364
|
-
}
|
|
3365
3388
|
break;
|
|
3366
3389
|
}
|
|
3367
3390
|
}
|
|
3368
3391
|
}
|
|
3369
3392
|
if (!hasPostCompactionUsage) {
|
|
3370
|
-
|
|
3393
|
+
const tokens = this.messages.reduce((total, message) => total + estimateTokens(message), 0);
|
|
3394
|
+
return { tokens, contextWindow, percent: (tokens / contextWindow) * 100 };
|
|
3371
3395
|
}
|
|
3372
3396
|
}
|
|
3373
3397
|
const estimate = estimateContextTokens(this.messages);
|
|
3374
|
-
const percent = (estimate.tokens / contextWindow) * 100;
|
|
3375
3398
|
return {
|
|
3376
3399
|
tokens: estimate.tokens,
|
|
3377
3400
|
contextWindow,
|
|
3378
|
-
percent,
|
|
3401
|
+
percent: (estimate.tokens / contextWindow) * 100,
|
|
3379
3402
|
};
|
|
3380
3403
|
}
|
|
3381
3404
|
/**
|