mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-21 09:17:53 +00:00
fix: switch system prompt to avoid malformed tool_calls
This commit is contained in:
@@ -521,6 +521,18 @@ export class Config {
|
||||
if (this.contentGeneratorConfig) {
|
||||
this.contentGeneratorConfig.model = newModel;
|
||||
}
|
||||
|
||||
// Reinitialize chat with updated configuration while preserving history
|
||||
const geminiClient = this.getGeminiClient();
|
||||
if (geminiClient && geminiClient.isInitialized()) {
|
||||
// Use async operation but don't await to avoid blocking
|
||||
geminiClient.reinitialize().catch((error) => {
|
||||
console.error(
|
||||
'Failed to reinitialize chat with updated config:',
|
||||
error,
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
isInFallbackMode(): boolean {
|
||||
|
||||
@@ -2549,4 +2549,82 @@ ${JSON.stringify(
|
||||
expect(mockChat.setHistory).toHaveBeenCalledWith(historyWithThoughts);
|
||||
});
|
||||
});
|
||||
|
||||
describe('initialize', () => {
|
||||
it('should accept extraHistory parameter and pass it to startChat', async () => {
|
||||
const mockStartChat = vi.fn().mockResolvedValue({});
|
||||
client['startChat'] = mockStartChat;
|
||||
|
||||
const extraHistory = [
|
||||
{ role: 'user', parts: [{ text: 'Previous message' }] },
|
||||
{ role: 'model', parts: [{ text: 'Previous response' }] },
|
||||
];
|
||||
|
||||
const contentGeneratorConfig = {
|
||||
model: 'test-model',
|
||||
apiKey: 'test-key',
|
||||
vertexai: false,
|
||||
authType: AuthType.USE_GEMINI,
|
||||
};
|
||||
|
||||
await client.initialize(contentGeneratorConfig, extraHistory);
|
||||
|
||||
expect(mockStartChat).toHaveBeenCalledWith(extraHistory, 'test-model');
|
||||
});
|
||||
|
||||
it('should use empty array when no extraHistory is provided', async () => {
|
||||
const mockStartChat = vi.fn().mockResolvedValue({});
|
||||
client['startChat'] = mockStartChat;
|
||||
|
||||
const contentGeneratorConfig = {
|
||||
model: 'test-model',
|
||||
apiKey: 'test-key',
|
||||
vertexai: false,
|
||||
authType: AuthType.USE_GEMINI,
|
||||
};
|
||||
|
||||
await client.initialize(contentGeneratorConfig);
|
||||
|
||||
expect(mockStartChat).toHaveBeenCalledWith([], 'test-model');
|
||||
});
|
||||
});
|
||||
|
||||
describe('reinitialize', () => {
|
||||
it('should reinitialize with preserved user history', async () => {
|
||||
// Mock the initialize method
|
||||
const mockInitialize = vi.fn().mockResolvedValue(undefined);
|
||||
client['initialize'] = mockInitialize;
|
||||
|
||||
// Set up initial history with environment context + user messages
|
||||
const mockHistory = [
|
||||
{ role: 'user', parts: [{ text: 'Environment context' }] },
|
||||
{ role: 'model', parts: [{ text: 'Got it. Thanks for the context!' }] },
|
||||
{ role: 'user', parts: [{ text: 'User message 1' }] },
|
||||
{ role: 'model', parts: [{ text: 'Model response 1' }] },
|
||||
];
|
||||
|
||||
const mockChat = {
|
||||
getHistory: vi.fn().mockReturnValue(mockHistory),
|
||||
};
|
||||
client['chat'] = mockChat as any;
|
||||
client['getHistory'] = vi.fn().mockReturnValue(mockHistory);
|
||||
|
||||
await client.reinitialize();
|
||||
|
||||
// Should call initialize with preserved user history (excluding first 2 env messages)
|
||||
expect(mockInitialize).toHaveBeenCalledWith(
|
||||
expect.any(Object), // contentGeneratorConfig
|
||||
[
|
||||
{ role: 'user', parts: [{ text: 'User message 1' }] },
|
||||
{ role: 'model', parts: [{ text: 'Model response 1' }] },
|
||||
],
|
||||
);
|
||||
});
|
||||
|
||||
it('should not throw error when chat is not initialized', async () => {
|
||||
client['chat'] = undefined;
|
||||
|
||||
await expect(client.reinitialize()).resolves.not.toThrow();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -138,13 +138,24 @@ export class GeminiClient {
|
||||
this.lastPromptId = this.config.getSessionId();
|
||||
}
|
||||
|
||||
async initialize(contentGeneratorConfig: ContentGeneratorConfig) {
|
||||
async initialize(
|
||||
contentGeneratorConfig: ContentGeneratorConfig,
|
||||
extraHistory?: Content[],
|
||||
) {
|
||||
this.contentGenerator = await createContentGenerator(
|
||||
contentGeneratorConfig,
|
||||
this.config,
|
||||
this.config.getSessionId(),
|
||||
);
|
||||
this.chat = await this.startChat();
|
||||
/**
|
||||
* Always take the model from contentGeneratorConfig to initialize,
|
||||
* despite the `this.config.contentGeneratorConfig` is not updated yet because in
|
||||
* `Config` it will not be updated until the initialization is successful.
|
||||
*/
|
||||
this.chat = await this.startChat(
|
||||
extraHistory || [],
|
||||
contentGeneratorConfig.model,
|
||||
);
|
||||
}
|
||||
|
||||
getContentGenerator(): ContentGenerator {
|
||||
@@ -217,6 +228,28 @@ export class GeminiClient {
|
||||
this.chat = await this.startChat();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reinitializes the chat with the current contentGeneratorConfig while preserving chat history.
|
||||
* This creates a new chat object using the existing history and updated configuration.
|
||||
* Should be called when configuration changes (model, auth, etc.) to ensure consistency.
|
||||
*/
|
||||
async reinitialize(): Promise<void> {
|
||||
if (!this.chat) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Preserve the current chat history (excluding environment context)
|
||||
const currentHistory = this.getHistory();
|
||||
// Remove the initial environment context (first 2 messages: user env + model acknowledgment)
|
||||
const userHistory = currentHistory.slice(2);
|
||||
|
||||
// Get current content generator config and reinitialize with preserved history
|
||||
const contentGeneratorConfig = this.config.getContentGeneratorConfig();
|
||||
if (contentGeneratorConfig) {
|
||||
await this.initialize(contentGeneratorConfig, userHistory);
|
||||
}
|
||||
}
|
||||
|
||||
async addDirectoryContext(): Promise<void> {
|
||||
if (!this.chat) {
|
||||
return;
|
||||
@@ -228,7 +261,10 @@ export class GeminiClient {
|
||||
});
|
||||
}
|
||||
|
||||
async startChat(extraHistory?: Content[]): Promise<GeminiChat> {
|
||||
async startChat(
|
||||
extraHistory?: Content[],
|
||||
model?: string,
|
||||
): Promise<GeminiChat> {
|
||||
this.forceFullIdeContext = true;
|
||||
this.hasFailedCompressionAttempt = false;
|
||||
const envParts = await getEnvironmentContext(this.config);
|
||||
@@ -248,9 +284,13 @@ export class GeminiClient {
|
||||
];
|
||||
try {
|
||||
const userMemory = this.config.getUserMemory();
|
||||
const systemInstruction = getCoreSystemPrompt(userMemory);
|
||||
const systemInstruction = getCoreSystemPrompt(
|
||||
userMemory,
|
||||
{},
|
||||
model || this.config.getModel(),
|
||||
);
|
||||
const generateContentConfigWithThinking = isThinkingSupported(
|
||||
this.config.getModel(),
|
||||
model || this.config.getModel(),
|
||||
)
|
||||
? {
|
||||
...this.generateContentConfig,
|
||||
@@ -490,7 +530,11 @@ export class GeminiClient {
|
||||
// Get all the content that would be sent in an API call
|
||||
const currentHistory = this.getChat().getHistory(true);
|
||||
const userMemory = this.config.getUserMemory();
|
||||
const systemPrompt = getCoreSystemPrompt(userMemory);
|
||||
const systemPrompt = getCoreSystemPrompt(
|
||||
userMemory,
|
||||
{},
|
||||
this.config.getModel(),
|
||||
);
|
||||
const environment = await getEnvironmentContext(this.config);
|
||||
|
||||
// Create a mock request content to count total tokens
|
||||
@@ -644,14 +688,18 @@ export class GeminiClient {
|
||||
model?: string,
|
||||
config: GenerateContentConfig = {},
|
||||
): Promise<Record<string, unknown>> {
|
||||
// Use current model from config instead of hardcoded Flash model
|
||||
const modelToUse =
|
||||
model || this.config.getModel() || DEFAULT_GEMINI_FLASH_MODEL;
|
||||
/**
|
||||
* TODO: ensure `model` consistency among GeminiClient, GeminiChat, and ContentGenerator
|
||||
* `model` passed to generateContent is not respected as we always use contentGenerator
|
||||
* We should ignore model for now because some calls use `DEFAULT_GEMINI_FLASH_MODEL`
|
||||
* which is not available as `qwen3-coder-flash`
|
||||
*/
|
||||
const modelToUse = this.config.getModel() || DEFAULT_GEMINI_FLASH_MODEL;
|
||||
try {
|
||||
const userMemory = this.config.getUserMemory();
|
||||
const finalSystemInstruction = config.systemInstruction
|
||||
? getCustomSystemPrompt(config.systemInstruction, userMemory)
|
||||
: getCoreSystemPrompt(userMemory);
|
||||
: getCoreSystemPrompt(userMemory, {}, modelToUse);
|
||||
|
||||
const requestConfig = {
|
||||
abortSignal,
|
||||
@@ -742,7 +790,7 @@ export class GeminiClient {
|
||||
const userMemory = this.config.getUserMemory();
|
||||
const finalSystemInstruction = generationConfig.systemInstruction
|
||||
? getCustomSystemPrompt(generationConfig.systemInstruction, userMemory)
|
||||
: getCoreSystemPrompt(userMemory);
|
||||
: getCoreSystemPrompt(userMemory, {}, this.config.getModel());
|
||||
|
||||
const requestConfig: GenerateContentConfig = {
|
||||
abortSignal,
|
||||
|
||||
@@ -91,6 +91,7 @@ export function getCustomSystemPrompt(
|
||||
export function getCoreSystemPrompt(
|
||||
userMemory?: string,
|
||||
config?: SystemPromptConfig,
|
||||
model?: string,
|
||||
): string {
|
||||
// if GEMINI_SYSTEM_MD is set (and not 0|false), override system prompt from file
|
||||
// default path is .gemini/system.md but can be modified via custom path in GEMINI_SYSTEM_MD
|
||||
@@ -338,154 +339,7 @@ ${(function () {
|
||||
return '';
|
||||
})()}
|
||||
|
||||
# Examples (Illustrating Tone and Workflow)
|
||||
<example>
|
||||
user: 1 + 2
|
||||
model: 3
|
||||
</example>
|
||||
|
||||
<example>
|
||||
user: is 13 a prime number?
|
||||
model: true
|
||||
</example>
|
||||
|
||||
<example>
|
||||
user: start the server implemented in server.js
|
||||
model:
|
||||
<tool_call>
|
||||
<function=run_shell_command>
|
||||
<parameter=command>
|
||||
node server.js &
|
||||
</parameter>
|
||||
</function>
|
||||
</tool_call>
|
||||
</example>
|
||||
|
||||
<example>
|
||||
user: Refactor the auth logic in src/auth.py to use the requests library instead of urllib.
|
||||
model: Okay, I can refactor 'src/auth.py'.
|
||||
First, I'll analyze the code and check for a test safety net before planning any changes.
|
||||
<tool_call>
|
||||
<function=glob>
|
||||
<parameter=path>
|
||||
tests/test_auth.py
|
||||
</parameter>
|
||||
</function>
|
||||
</tool_call>
|
||||
<tool_call>
|
||||
<function=read_file>
|
||||
<parameter=path>
|
||||
/path/to/tests/test_auth.py
|
||||
</parameter>
|
||||
<parameter=offset>
|
||||
0
|
||||
</parameter>
|
||||
<parameter=limit>
|
||||
10
|
||||
</parameter>
|
||||
</function>
|
||||
</tool_call>
|
||||
(After analysis)
|
||||
Great, 'tests/test_auth.py' exists and covers the core authentication logic. With this safety net in place, I can safely plan the refactoring.
|
||||
I'll also confirm 'requests' is a dependency.
|
||||
<tool_call>
|
||||
<function=read_file>
|
||||
<parameter=path>
|
||||
/path/to/requirements.txt
|
||||
</parameter>
|
||||
</function>
|
||||
</tool_call>
|
||||
(After analysis)
|
||||
Looks good, 'requests' is available.
|
||||
|
||||
Here's the plan:
|
||||
1. Replace the 'urllib' calls with 'requests'.
|
||||
2. Add proper 'try...except' error handling for the new network calls.
|
||||
3. Remove the old 'urllib' import.
|
||||
4. Run the project's linter and tests to verify the changes.
|
||||
|
||||
<tool_call>
|
||||
<function=replace>
|
||||
<parameter=path>
|
||||
src/auth.py
|
||||
</parameter>
|
||||
<parameter=old_content>
|
||||
(old code content)
|
||||
</parameter>
|
||||
<parameter=new_content>
|
||||
(new code content)
|
||||
</parameter>
|
||||
</function>
|
||||
</tool_call>
|
||||
Refactoring complete. Running verification...
|
||||
<tool_call>
|
||||
<function=run_shell_command
|
||||
<parameter=command>
|
||||
ruff check src/auth.py && pytest
|
||||
</parameter>
|
||||
</function>
|
||||
</tool_call>
|
||||
(After verification passes)
|
||||
All checks passed. This is a stable checkpoint.
|
||||
Would you like me to write a commit message and commit these changes?
|
||||
</example>
|
||||
|
||||
<example>
|
||||
user: Delete the temp directory.
|
||||
model: I can run \`rm -rf /path/to/project/temp\`. This will permanently delete the directory and all its contents.
|
||||
</example>
|
||||
|
||||
<example>
|
||||
user: Write tests for someFile.ts
|
||||
model:
|
||||
Okay, I can write those tests. First, I'll read someFile.ts to understand its functionality.
|
||||
<tool_call>
|
||||
<function=read_file>
|
||||
<parameter=path>
|
||||
/path/to/someFile.ts
|
||||
</parameter>
|
||||
</function>
|
||||
</tool_call>
|
||||
Now I'll look for existing or related test files to understand current testing conventions and dependencies.
|
||||
<tool_call>
|
||||
<function>read_many_files for paths ['**/*.test.ts', 'src/**/*.spec.ts'] assuming someFile.ts is in the src directory]
|
||||
</tool_call>
|
||||
(After reviewing existing tests and the file content)
|
||||
<tool_call>
|
||||
<function=write_file>
|
||||
<parameter=path>
|
||||
/path/to/someFile.test.ts
|
||||
</parameter>
|
||||
</function>
|
||||
</tool_call>
|
||||
I've written the tests. Now I'll run the project's test command to verify them.
|
||||
<tool_call>
|
||||
<function=run_shell_command>
|
||||
<parameter=command>
|
||||
npm run test
|
||||
</parameter>
|
||||
</function>
|
||||
</tool_call>
|
||||
(After verification passes)
|
||||
All checks passed. This is a stable checkpoint.
|
||||
</example>
|
||||
|
||||
<example>
|
||||
user: Where are all the 'app.config' files in this project? I need to check their settings.
|
||||
model:
|
||||
<tool_call>
|
||||
<function=glob>
|
||||
<parameter=pattern>
|
||||
./**/app.config
|
||||
</parameter>
|
||||
</function>
|
||||
</tool_call>
|
||||
(Assuming GlobTool returns a list of paths like ['/path/to/moduleA/app.config', '/path/to/moduleB/app.config'])
|
||||
I found the following 'app.config' files:
|
||||
- /path/to/moduleA/app.config
|
||||
- /path/to/moduleB/app.config
|
||||
To help you check their settings, I can read their contents. Which one would you like to start with, or should I read all of them?
|
||||
</example>
|
||||
${getToolCallExamples(model || '')}
|
||||
|
||||
# Final Reminder
|
||||
Your core function is efficient and safe assistance. Balance extreme conciseness with the crucial need for clarity, especially regarding safety and potential system modifications. Always prioritize user control and project conventions. Never make assumptions about the contents of files; instead use '${ReadFileTool.Name}' or '${ReadManyFilesTool.Name}' to ensure you aren't making broad assumptions. Finally, you are an agent - please keep going until the user's query is completely resolved.
|
||||
@@ -615,3 +469,341 @@ You are a specialized context summarizer that creates a comprehensive markdown s
|
||||
|
||||
`.trim();
|
||||
}
|
||||
|
||||
const generatlToolCallExamples = `
|
||||
# Examples (Illustrating Tone and Workflow)
|
||||
<example>
|
||||
user: 1 + 2
|
||||
model: 3
|
||||
</example>
|
||||
|
||||
<example>
|
||||
user: is 13 a prime number?
|
||||
model: true
|
||||
</example>
|
||||
|
||||
<example>
|
||||
user: start the server implemented in server.js
|
||||
model: [tool_call: ${ShellTool.Name} for 'node server.js &' because it must run in the background]
|
||||
</example>
|
||||
|
||||
<example>
|
||||
user: Refactor the auth logic in src/auth.py to use the requests library instead of urllib.
|
||||
model: Okay, I can refactor 'src/auth.py'.
|
||||
First, I'll analyze the code and check for a test safety net before planning any changes.
|
||||
[tool_call: ${GlobTool.Name} for path 'tests/test_auth.py']
|
||||
[tool_call: ${ReadFileTool.Name} for path '/path/to/tests/test_auth.py' with offset 0 and limit 10]
|
||||
(After analysis)
|
||||
Great, 'tests/test_auth.py' exists and covers the core authentication logic. With this safety net in place, I can safely plan the refactoring.
|
||||
I'll also confirm 'requests' is a dependency.
|
||||
[tool_call: ${ReadFileTool.Name} for path '/path/to/requirements.txt']
|
||||
(After analysis)
|
||||
Looks good, 'requests' is available.
|
||||
|
||||
Here's the plan:
|
||||
1. Replace the 'urllib' calls with 'requests'.
|
||||
2. Add proper 'try...except' error handling for the new network calls.
|
||||
3. Remove the old 'urllib' import.
|
||||
4. Run the project's linter and tests to verify the changes.
|
||||
|
||||
[tool_call: ${EditTool.Name} for path 'src/auth.py' replacing old content with new content]
|
||||
Refactoring complete. Running verification...
|
||||
[tool_call: ${ShellTool.Name} for 'ruff check src/auth.py && pytest']
|
||||
(After verification passes)
|
||||
All checks passed. This is a stable checkpoint.
|
||||
Would you like me to write a commit message and commit these changes?
|
||||
</example>
|
||||
|
||||
<example>
|
||||
user: Delete the temp directory.
|
||||
model: I can run \`rm -rf /path/to/project/temp\`. This will permanently delete the directory and all its contents.
|
||||
</example>
|
||||
|
||||
<example>
|
||||
user: Write tests for someFile.ts
|
||||
model:
|
||||
Okay, I can write those tests. First, I'll read someFile.ts to understand its functionality.
|
||||
[tool_call: ${ReadFileTool.Name} for path '/path/to/someFile.ts']
|
||||
Now I'll look for existing or related test files to understand current testing conventions and dependencies.
|
||||
[tool_call: ${ReadManyFilesTool.Name} for paths ['**/*.test.ts', 'src/**/*.spec.ts']]
|
||||
(After reviewing existing tests and the file content)
|
||||
[tool_call: ${WriteFileTool.Name} for path '/path/to/someFile.test.ts']
|
||||
I've written the tests. Now I'll run the project's test command to verify them.
|
||||
[tool_call: ${ShellTool.Name} for 'npm run test']
|
||||
(After verification passes)
|
||||
All checks passed. This is a stable checkpoint.
|
||||
</example>
|
||||
|
||||
<example>
|
||||
user: Where are all the 'app.config' files in this project? I need to check their settings.
|
||||
model:
|
||||
[tool_call: ${GlobTool.Name} for pattern './**/app.config']
|
||||
(Assuming GlobTool returns a list of paths like ['/path/to/moduleA/app.config', '/path/to/moduleB/app.config'])
|
||||
I found the following 'app.config' files:
|
||||
- /path/to/moduleA/app.config
|
||||
- /path/to/moduleB/app.config
|
||||
To help you check their settings, I can read their contents. Which one would you like to start with, or should I read all of them?
|
||||
</example>
|
||||
`.trim();
|
||||
|
||||
const qwenCoderToolCallExamples = `
|
||||
# Examples (Illustrating Tone and Workflow)
|
||||
<example>
|
||||
user: 1 + 2
|
||||
model: 3
|
||||
</example>
|
||||
|
||||
<example>
|
||||
user: is 13 a prime number?
|
||||
model: true
|
||||
</example>
|
||||
|
||||
<example>
|
||||
user: start the server implemented in server.js
|
||||
model:
|
||||
<tool_call>
|
||||
<function=${ShellTool.Name}>
|
||||
<parameter=command>
|
||||
node server.js &
|
||||
</parameter>
|
||||
</function>
|
||||
</tool_call>
|
||||
</example>
|
||||
|
||||
<example>
|
||||
user: Refactor the auth logic in src/auth.py to use the requests library instead of urllib.
|
||||
model: Okay, I can refactor 'src/auth.py'.
|
||||
First, I'll analyze the code and check for a test safety net before planning any changes.
|
||||
<tool_call>
|
||||
<function=${GlobTool.Name}>
|
||||
<parameter=path>
|
||||
tests/test_auth.py
|
||||
</parameter>
|
||||
</function>
|
||||
</tool_call>
|
||||
<tool_call>
|
||||
<function=${ReadFileTool.Name}>
|
||||
<parameter=path>
|
||||
/path/to/tests/test_auth.py
|
||||
</parameter>
|
||||
<parameter=offset>
|
||||
0
|
||||
</parameter>
|
||||
<parameter=limit>
|
||||
10
|
||||
</parameter>
|
||||
</function>
|
||||
</tool_call>
|
||||
(After analysis)
|
||||
Great, 'tests/test_auth.py' exists and covers the core authentication logic. With this safety net in place, I can safely plan the refactoring.
|
||||
I'll also confirm 'requests' is a dependency.
|
||||
<tool_call>
|
||||
<function=${ReadFileTool.Name}>
|
||||
<parameter=path>
|
||||
/path/to/requirements.txt
|
||||
</parameter>
|
||||
</function>
|
||||
</tool_call>
|
||||
(After analysis)
|
||||
Looks good, 'requests' is available.
|
||||
|
||||
Here's the plan:
|
||||
1. Replace the 'urllib' calls with 'requests'.
|
||||
2. Add proper 'try...except' error handling for the new network calls.
|
||||
3. Remove the old 'urllib' import.
|
||||
4. Run the project's linter and tests to verify the changes.
|
||||
|
||||
<tool_call>
|
||||
<function=${EditTool.Name}>
|
||||
<parameter=path>
|
||||
src/auth.py
|
||||
</parameter>
|
||||
<parameter=old_content>
|
||||
(old code content)
|
||||
</parameter>
|
||||
<parameter=new_content>
|
||||
(new code content)
|
||||
</parameter>
|
||||
</function>
|
||||
</tool_call>
|
||||
Refactoring complete. Running verification...
|
||||
<tool_call>
|
||||
<function=${ShellTool.Name}>
|
||||
<parameter=command>
|
||||
ruff check src/auth.py && pytest
|
||||
</parameter>
|
||||
</function>
|
||||
</tool_call>
|
||||
(After verification passes)
|
||||
All checks passed. This is a stable checkpoint.
|
||||
Would you like me to write a commit message and commit these changes?
|
||||
</example>
|
||||
|
||||
<example>
|
||||
user: Delete the temp directory.
|
||||
model: I can run \`rm -rf /path/to/project/temp\`. This will permanently delete the directory and all its contents.
|
||||
</example>
|
||||
|
||||
<example>
|
||||
user: Write tests for someFile.ts
|
||||
model:
|
||||
Okay, I can write those tests. First, I'll read someFile.ts to understand its functionality.
|
||||
<tool_call>
|
||||
<function=${ReadFileTool.Name}>
|
||||
<parameter=path>
|
||||
/path/to/someFile.ts
|
||||
</parameter>
|
||||
</function>
|
||||
</tool_call>
|
||||
Now I'll look for existing or related test files to understand current testing conventions and dependencies.
|
||||
<tool_call>
|
||||
<function=${ReadManyFilesTool.Name}>
|
||||
<parameter=paths>
|
||||
['**/*.test.ts', 'src/**/*.spec.ts']
|
||||
</parameter>
|
||||
</function>
|
||||
</tool_call>
|
||||
(After reviewing existing tests and the file content)
|
||||
<tool_call>
|
||||
<function=${WriteFileTool.Name}>
|
||||
<parameter=path>
|
||||
/path/to/someFile.test.ts
|
||||
</parameter>
|
||||
</function>
|
||||
</tool_call>
|
||||
I've written the tests. Now I'll run the project's test command to verify them.
|
||||
<tool_call>
|
||||
<function=${ShellTool.Name}>
|
||||
<parameter=command>
|
||||
npm run test
|
||||
</parameter>
|
||||
</function>
|
||||
</tool_call>
|
||||
(After verification passes)
|
||||
All checks passed. This is a stable checkpoint.
|
||||
</example>
|
||||
|
||||
<example>
|
||||
user: Where are all the 'app.config' files in this project? I need to check their settings.
|
||||
model:
|
||||
<tool_call>
|
||||
<function=${GlobTool.Name}>
|
||||
<parameter=pattern>
|
||||
./**/app.config
|
||||
</parameter>
|
||||
</function>
|
||||
</tool_call>
|
||||
(Assuming GlobTool returns a list of paths like ['/path/to/moduleA/app.config', '/path/to/moduleB/app.config'])
|
||||
I found the following 'app.config' files:
|
||||
- /path/to/moduleA/app.config
|
||||
- /path/to/moduleB/app.config
|
||||
To help you check their settings, I can read their contents. Which one would you like to start with, or should I read all of them?
|
||||
</example>
|
||||
`.trim();
|
||||
const qwenVlToolCallExamples = `
|
||||
# Examples (Illustrating Tone and Workflow)
|
||||
<example>
|
||||
user: 1 + 2
|
||||
model: 3
|
||||
</example>
|
||||
|
||||
<example>
|
||||
user: is 13 a prime number?
|
||||
model: true
|
||||
</example>
|
||||
|
||||
<example>
|
||||
user: start the server implemented in server.js
|
||||
model:
|
||||
<tool_call>
|
||||
{"name": "${ShellTool.Name}", "arguments": {"command": "node server.js &"}}
|
||||
</tool_call>
|
||||
</example>
|
||||
|
||||
<example>
|
||||
user: Refactor the auth logic in src/auth.py to use the requests library instead of urllib.
|
||||
model: Okay, I can refactor 'src/auth.py'.
|
||||
First, I'll analyze the code and check for a test safety net before planning any changes.
|
||||
<tool_call>
|
||||
{"name": "${GlobTool.Name}", "arguments": {"path": "tests/test_auth.py"}}
|
||||
</tool_call>
|
||||
<tool_call>
|
||||
{"name": "${ReadFileTool.Name}", "arguments": {"path": "/path/to/tests/test_auth.py", "offset": 0, "limit": 10}}
|
||||
</tool_call>
|
||||
(After analysis)
|
||||
Great, 'tests/test_auth.py' exists and covers the core authentication logic. With this safety net in place, I can safely plan the refactoring.
|
||||
I'll also confirm 'requests' is a dependency.
|
||||
<tool_call>
|
||||
{"name": "${ReadFileTool.Name}", "arguments": {"path": "/path/to/requirements.txt"}}
|
||||
</tool_call>
|
||||
(After analysis)
|
||||
Looks good, 'requests' is available.
|
||||
|
||||
Here's the plan:
|
||||
1. Replace the 'urllib' calls with 'requests'.
|
||||
2. Add proper 'try...except' error handling for the new network calls.
|
||||
3. Remove the old 'urllib' import.
|
||||
4. Run the project's linter and tests to verify the changes.
|
||||
|
||||
<tool_call>
|
||||
{"name": "${EditTool.Name}", "arguments": {"path": "src/auth.py", "old_content": "(old code content)", "new_content": "(new code content)"}}
|
||||
</tool_call>
|
||||
Refactoring complete. Running verification...
|
||||
<tool_call>
|
||||
{"name": "${ShellTool.Name}", "arguments": {"command": "ruff check src/auth.py && pytest"}}
|
||||
</tool_call>
|
||||
(After verification passes)
|
||||
All checks passed. This is a stable checkpoint.
|
||||
Would you like me to write a commit message and commit these changes?
|
||||
</example>
|
||||
|
||||
<example>
|
||||
user: Delete the temp directory.
|
||||
model: I can run \`rm -rf /path/to/project/temp\`. This will permanently delete the directory and all its contents.
|
||||
</example>
|
||||
|
||||
<example>
|
||||
user: Write tests for someFile.ts
|
||||
model:
|
||||
Okay, I can write those tests. First, I'll read someFile.ts to understand its functionality.
|
||||
<tool_call>
|
||||
{"name": "${ReadFileTool.Name}", "arguments": {"path": "/path/to/someFile.ts"}}
|
||||
</tool_call>
|
||||
Now I'll look for existing or related test files to understand current testing conventions and dependencies.
|
||||
<tool_call>
|
||||
{"name": "${ReadManyFilesTool.Name}", "arguments": {"paths": ["**/*.test.ts", "src/**/*.spec.ts"]}}
|
||||
</tool_call>
|
||||
(After reviewing existing tests and the file content)
|
||||
<tool_call>
|
||||
{"name": "${WriteFileTool.Name}", "arguments": {"path": "/path/to/someFile.test.ts"}}
|
||||
</tool_call>
|
||||
I've written the tests. Now I'll run the project's test command to verify them.
|
||||
<tool_call>
|
||||
{"name": "${ShellTool.Name}", "arguments": {"command": "npm run test"}}
|
||||
</tool_call>
|
||||
(After verification passes)
|
||||
All checks passed. This is a stable checkpoint.
|
||||
</example>
|
||||
|
||||
<example>
|
||||
user: Where are all the 'app.config' files in this project? I need to check their settings.
|
||||
model:
|
||||
<tool_call>
|
||||
{"name": "${GlobTool.Name}", "arguments": {"pattern": "./**/app.config"}}
|
||||
</tool_call>
|
||||
(Assuming GlobTool returns a list of paths like ['/path/to/moduleA/app.config', '/path/to/moduleB/app.config'])
|
||||
I found the following 'app.config' files:
|
||||
- /path/to/moduleA/app.config
|
||||
- /path/to/moduleB/app.config
|
||||
To help you check their settings, I can read their contents. Which one would you like to start with, or should I read all of them?
|
||||
</example>
|
||||
`.trim();
|
||||
|
||||
function getToolCallExamples(model?: string): string {
|
||||
if (model?.includes('qwen3-coder')) {
|
||||
return qwenCoderToolCallExamples;
|
||||
} else if (model?.includes('qwen-vl')) {
|
||||
return qwenVlToolCallExamples;
|
||||
}
|
||||
return generatlToolCallExamples;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user