fix(agent): inject tool inventory note when tools change mid-session
Stale session history can cause the model to follow old "I can't do that" patterns even when new tools are available. NativeAgent now tracks a tool fingerprint and appends a system prompt note listing current tools when the inventory changes, resetting on session reset. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -52,6 +52,7 @@ export class NativeAgent {
|
||||
private _toolPolicyContext?: ToolPolicyContext;
|
||||
private _attachmentCollector?: OutboundAttachmentCollector;
|
||||
private _thinking: boolean = false;
|
||||
private _lastToolFingerprint?: string;
|
||||
|
||||
constructor(config: NativeAgentConfig) {
|
||||
this.modelClient = config.modelClient;
|
||||
@@ -122,6 +123,19 @@ export class NativeAgent {
|
||||
private async toolLoop(): Promise<string> {
|
||||
const tools = this.toolRegistry!.filteredToAnthropicFormat(this._toolPolicyContext);
|
||||
|
||||
// Detect tool inventory changes to combat conversational inertia in long sessions.
|
||||
// When tools change (e.g. new tools added between restarts), the model's prior messages
|
||||
// saying "I can't do that" can override tool definitions. Injecting a system note fixes this.
|
||||
const currentFingerprint = tools.map(t => t.name).sort().join(',');
|
||||
const hasHistory = this.history.length > 1; // more than just the current user message
|
||||
let effectiveSystem = this.systemPrompt;
|
||||
|
||||
if (hasHistory && this._lastToolFingerprint !== currentFingerprint) {
|
||||
const toolNames = tools.map(t => t.name).join(', ');
|
||||
effectiveSystem += `\n\n[Tool inventory updated — available tools: ${toolNames}. Use these tools directly; do not attempt workarounds for functionality that a tool already provides.]`;
|
||||
}
|
||||
this._lastToolFingerprint = currentFingerprint;
|
||||
|
||||
// Build the loop messages from existing history.
|
||||
// These are the messages sent to the model, including any structured tool blocks.
|
||||
const loopMessages: LoopMessage[] = this.history.map(m => ({
|
||||
@@ -134,7 +148,7 @@ export class NativeAgent {
|
||||
// model client will pass them through to the API which accepts structured content.
|
||||
const request = {
|
||||
messages: loopMessages as unknown as Message[],
|
||||
system: this.systemPrompt,
|
||||
system: effectiveSystem,
|
||||
tools,
|
||||
...(this._thinking ? { thinking: true } : {}),
|
||||
};
|
||||
@@ -221,6 +235,7 @@ export class NativeAgent {
|
||||
} else {
|
||||
this.inMemoryHistory = [];
|
||||
}
|
||||
this._lastToolFingerprint = undefined;
|
||||
this.resetUsage();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user