Welcome back! In Deferred Tool Filtering, we organized our tools into a "Reference Desk" (immediate access) and an "Archive" (hidden/deferred).
However, we have a small problem. We put the tools in the Archive to hide them... but now they are too hidden. The AI doesn't know they exist, and it certainly doesn't know how to ask for them.
We need to hand the AI an Instruction Manual.
Imagine you buy a complicated machine. You need a manual to operate it. However, in our software, the machine works differently depending on who is using it (e.g., are we on a slow computer? Is a specific experimental feature turned on?).
If we wrote a static text file as our manual, it would be wrong half the time.
Dynamic Prompt Generation is the process of writing this manual programmatically. We don't just read a string from a file; we build the instructions on the fly to ensure they match the current environment.
This generated prompt acts as a Contract. It promises the AI three things:
select: or notebook...").
Let's look at how prompt.ts builds this manual piece by piece.
The first part of the manual never changes. It simply states the mission.
// From prompt.ts
const PROMPT_HEAD = `Fetches full schema definitions for deferred tools so they can be called.
`
Explanation: This tells the AI: "Your goal with this tool is to get the JSON schemas for tools you can't see yet."
This is where the magic happens. We need to tell the AI where to find the list of tool names (the index of the Archive).
Sometimes the system puts these names in a system-reminder. Sometimes it puts them in a user message XML block. The code must decide which instruction to give.
// From prompt.ts
function getToolLocationHint(): string {
// check if we are using the "Delta" feature or if user is 'ant'
const deltaEnabled =
process.env.USER_TYPE === 'ant' ||
getFeatureValue_CACHED_MAY_BE_STALE('tengu_glacier_2xr', false)
// Return different text based on the check
return deltaEnabled
? 'Deferred tools appear by name in <system-reminder> messages.'
: 'Deferred tools appear by name in <available-deferred-tools> messages.'
}
Explanation:
tengu_glacier...) or user type.<system-reminder>.<available-deferred-tools>.This ensures the AI never looks in the wrong place.
Finally, we explain how to use the tool. This includes specific command formats and what the output will look like.
// From prompt.ts
const PROMPT_TAIL = ` ... This tool takes a query ...
Query forms:
- "select:Read,Edit,Grep" โ fetch these exact tools by name
- "notebook jupyter" โ keyword search
- "+slack send" โ require "slack" in the name...`
Explanation:
This sets the rules. If the AI wants the Read tool, it must type select:Read. If it wants to search vaguely, it can type notebook. This syntax will be parsed in Chapter 4: Direct Selection Mode and Chapter 3: Keyword Search & Scoring.
How do we generate the final manual? We simply stick the pieces together.
// From prompt.ts
export function getPrompt(): string {
// Head + Dynamic Hint + Tail
return PROMPT_HEAD + getToolLocationHint() + PROMPT_TAIL
}
Explanation:
When the system starts, it calls getPrompt(). This function:
Here is what happens inside the code when the application asks for the tool definition.
Without Dynamic Prompt Generation, we would confuse the AI.
If the system code puts tool names in a <system-reminder>, but a static prompt told the AI to look in <available-deferred-tools>, the AI would say: "I cannot find the tools you mentioned."
By generating the prompt via code, we ensure the instructions always match the reality of the system configuration.
You now have a system that:
Now the AI knows the rules: "Type 'notebook jupyter' to search."
But what happens when the AI actually sends that string? How does our code interpret "notebook jupyter" and find the right tool?
We will explore the search engine itself in the next chapter.
Next: Chapter 3 - Keyword Search & Scoring
Generated by Code IQ