@dreb/coding-agent 2.30.1 → 2.31.1
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 +11 -0
- package/dist/core/agent-session.d.ts +16 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +58 -2
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/nested-context.d.ts +107 -0
- package/dist/core/nested-context.d.ts.map +1 -0
- package/dist/core/nested-context.js +485 -0
- package/dist/core/nested-context.js.map +1 -0
- package/dist/core/resource-loader.d.ts +5 -0
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +12 -12
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/settings-manager.d.ts +10 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +11 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +3 -0
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +10 -0
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +4 -0
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/docs/settings.md +18 -0
- package/package.json +1 -1
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
*
|
|
13
13
|
* Modes use this class and add their own I/O layer on top.
|
|
14
14
|
*/
|
|
15
|
-
import { copyFileSync, existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
15
|
+
import { copyFileSync, existsSync, mkdirSync, realpathSync, writeFileSync } from "node:fs";
|
|
16
16
|
import { tmpdir } from "node:os";
|
|
17
17
|
import { basename, dirname, join, resolve } from "node:path";
|
|
18
18
|
import { isContextOverflow, modelsAreEqual, resetApiProviders, supportsXhigh } from "@dreb/ai";
|
|
@@ -28,6 +28,7 @@ import { ExtensionRunner, wrapRegisteredTools, } from "./extensions/index.js";
|
|
|
28
28
|
import { checkScriptContent, extractScriptPaths, isForbiddenCommand } from "./forbidden-commands.js";
|
|
29
29
|
import { getGitRepoState } from "./git-repo-state.js";
|
|
30
30
|
import { log } from "./logger.js";
|
|
31
|
+
import { computeNestedContextBlock } from "./nested-context.js";
|
|
31
32
|
import { PerformanceTracker } from "./performance-tracker.js";
|
|
32
33
|
import { expandPromptTemplate } from "./prompt-templates.js";
|
|
33
34
|
import { scrubSecrets } from "./secret-scrubber.js";
|
|
@@ -106,6 +107,14 @@ export class AgentSession {
|
|
|
106
107
|
_customTools;
|
|
107
108
|
_baseToolDefinitions = new Map();
|
|
108
109
|
_cwd;
|
|
110
|
+
/**
|
|
111
|
+
* Per-session realpaths of context files already loaded (seeded lazily from the
|
|
112
|
+
* session-start context set). Ensures each nested AGENTS.md/CLAUDE.md is injected
|
|
113
|
+
* at most once. `undefined` until first use.
|
|
114
|
+
*/
|
|
115
|
+
_nestedContextLoaded;
|
|
116
|
+
/** Negative cache of target directories already scanned for nested context. */
|
|
117
|
+
_nestedContextScannedDirs = new Set();
|
|
109
118
|
_extensionRunnerRef;
|
|
110
119
|
_initialActiveToolNames;
|
|
111
120
|
_baseToolsOverride;
|
|
@@ -301,8 +310,16 @@ export class AgentSession {
|
|
|
301
310
|
if (totalRedactions > 0) {
|
|
302
311
|
scrubOverride = { content: scrubbedContent };
|
|
303
312
|
}
|
|
313
|
+
// Nested-context auto-load: cache-safe injection that rides on the tool result
|
|
314
|
+
// (does not rebuild the system prompt). Computed once per tool call.
|
|
315
|
+
const nestedBlock = this._computeNestedContextBlock(toolCall.name, args);
|
|
316
|
+
const scrubbedNestedBlock = nestedBlock ? scrubSecrets(nestedBlock, compiledExtras).scrubbed : null;
|
|
317
|
+
const withNested = (base) => scrubbedNestedBlock ? [...base, { type: "text", text: scrubbedNestedBlock }] : base;
|
|
304
318
|
const runner = this._extensionRunner;
|
|
305
319
|
if (!runner?.hasHandlers("tool_result")) {
|
|
320
|
+
if (nestedBlock) {
|
|
321
|
+
return { content: withNested(scrubbedContent), details: scrubOverride?.details };
|
|
322
|
+
}
|
|
306
323
|
return scrubOverride;
|
|
307
324
|
}
|
|
308
325
|
const hookResult = await runner.emitToolResult({
|
|
@@ -315,14 +332,53 @@ export class AgentSession {
|
|
|
315
332
|
isError,
|
|
316
333
|
});
|
|
317
334
|
if (!hookResult || isError) {
|
|
335
|
+
if (nestedBlock) {
|
|
336
|
+
return { content: withNested(scrubbedContent), details: scrubOverride?.details };
|
|
337
|
+
}
|
|
318
338
|
return scrubOverride;
|
|
319
339
|
}
|
|
340
|
+
const finalContent = hookResult.content ?? scrubOverride?.content;
|
|
341
|
+
if (nestedBlock) {
|
|
342
|
+
return { content: withNested(finalContent ?? scrubbedContent), details: hookResult.details };
|
|
343
|
+
}
|
|
320
344
|
return {
|
|
321
|
-
content:
|
|
345
|
+
content: finalContent,
|
|
322
346
|
details: hookResult.details,
|
|
323
347
|
};
|
|
324
348
|
});
|
|
325
349
|
}
|
|
350
|
+
/**
|
|
351
|
+
* Compute a nested-context injection block for a tool call, or `null` when nothing
|
|
352
|
+
* should be injected. Resolves the directory the tool operates in, walks up to a
|
|
353
|
+
* sensible ceiling collecting not-yet-loaded AGENTS.md/CLAUDE.md files, and formats
|
|
354
|
+
* them. Each directory is scanned at most once (negative cache) and each file is
|
|
355
|
+
* injected at most once per session (realpath dedup). Gated by `context.autoLoadNested`.
|
|
356
|
+
*/
|
|
357
|
+
_computeNestedContextBlock(toolName, args) {
|
|
358
|
+
const enabled = this.settingsManager?.getAutoLoadNestedContext() ?? true;
|
|
359
|
+
if (!enabled)
|
|
360
|
+
return null;
|
|
361
|
+
// Seed the per-session loaded set from the context files loaded at session start so
|
|
362
|
+
// ancestor files are never re-injected.
|
|
363
|
+
if (!this._nestedContextLoaded) {
|
|
364
|
+
this._nestedContextLoaded = new Set();
|
|
365
|
+
for (const file of this._resourceLoader.getAgentsFiles().agentsFiles) {
|
|
366
|
+
try {
|
|
367
|
+
this._nestedContextLoaded.add(realpathSync(file.path));
|
|
368
|
+
}
|
|
369
|
+
catch {
|
|
370
|
+
this._nestedContextLoaded.add(file.path);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
const state = {
|
|
375
|
+
enabled,
|
|
376
|
+
cwd: this._cwd,
|
|
377
|
+
loaded: this._nestedContextLoaded,
|
|
378
|
+
scannedDirs: this._nestedContextScannedDirs,
|
|
379
|
+
};
|
|
380
|
+
return computeNestedContextBlock(toolName, args, state);
|
|
381
|
+
}
|
|
326
382
|
/**
|
|
327
383
|
* Install guardrails for background agent interactions:
|
|
328
384
|
* - Layer B: Sentinel monitor — steer if the parent model generates suspicious tokens
|