# @cmcconomy/pi-qwen-tool-parser

[![CI/CD Pipeline](https://github.com/cmcconomy/pi-qwen-tool-parser/actions/workflows/ci.yml/badge.svg)](https://github.com/cmcconomy/pi-qwen-tool-parser/actions/workflows/ci.yml)
[![npm version](https://badge.fury.io/js/@cmcconomy%2Fpi-qwen-tool-parser.svg)](https://www.npmjs.com/package/@cmcconomy/pi-qwen-tool-parser)

A pi-mono extension that provides tools to parse and execute Qwen XML formatted tool calls.

## Features

- **Qwen Tool Parser**: A custom tool (`qwen_tool_parser`) that parses Qwen XML formatted responses
- **Auto-detection**: Detects Qwen XML patterns in assistant messages during turns
- **Manual Parsing**: `/parse-qwen` command to parse and execute Qwen tools from recent messages
- **Clean Output**: Automatically removes Qwen XML blocks from response content

## Installation

### Install globally:
```bash
pi install npm:@cmcconomy/pi-qwen-tool-parser@1.0.0
```

### Install in project:
```bash
pi install -l npm:@cmcconomy/pi-qwen-tool-parser@1.0.0
```

## Usage

### Method 1: Using the qwen_tool_parser tool (Recommended)

Configure your system prompt to instruct Qwen models to use the `qwen_tool_parser` tool when they need to execute tools:

**System Prompt Addition:**
```
When you need to execute a tool, wrap it in XML format and pass it to the 
'qwen_tool_parser' tool. For example:

<LLM response text>
🔧TOOL_CALL_START_9f8e7d6c5b4a3210<function_name>bash</function_name><parameters>{"command": "ls"}</parameters>🔚TOOL_CALL_END_9f8e7d6c5b4a3210
<more response text>

Then call qwen_tool_parser with the complete response text.
```

### Method 2: Manual parsing with /parse-qwen

After Qwen responds with XML tool calls, use the `/parse-qwen` command to parse and execute them:

```bash
# After Qwen sends a response with XML tools
/parse-qwen
```

The extension will:
1. Find the most recent assistant message
2. Parse any Qwen XML formatted tool calls
3. Execute each tool using pi's standard tool execution
4. Display results and show a cleaned version of the response (without XML blocks)

### Method 3: Auto-detection notifications

The extension automatically detects when assistant messages contain Qwen XML patterns and notifies you:

```
Detected X Qwen XML tool call(s). Use /parse-qwen to execute them, or configure system prompt to use qwen_tool_parser.
```

## How It Works

### `qwen_tool_parser` Tool

This custom tool accepts a complete LLM response text containing Qwen XML formatted tool calls:

**Parameters:**
- `qwen_response_text`: The full assistant message that may contain Qwen XML blocks

**Example Usage:**
```typescript
// When the model responds with XML tools in its message
await ctx.tools.execute('qwen_tool_parser', {
  qwen_response_text: "Here's what I found:\n🔧TOOL_CALL_START_9f8e7d6c5b4a3210<function_name>bash</function_name><parameters>{\"command\": \"ls -la\"}</parameters>🔚TOOL_CALL_END_9f8e7d6c5b4a3210\nLet me know if you need more."
});
```

**Returns:**
```json
{
  "success": true,
  "message": "Successfully parsed and executed X Qwen tool(s)",
  "parsed_count": 1,
  "tools_executed": ["bash: {...}"],
  "cleaned_response": "Here's what I found:\n\nLet me know if you need more."
}
```

### `/parse-qwen` Command

A command-line tool that automatically finds and parses the most recent assistant message:

```typescript
pi.registerCommand('parse-qwen', {
  description: 'Parse and execute Qwen XML tool calls from the last assistant message',
  handler: async (args, ctx) => {
    // Finds latest assistant message
    // Parses Qwen XML tool calls
    // Executes each tool
    // Displays results
  }
});
```

### Auto-detection in `turn_end`

The extension listens to the `turn_end` event and automatically detects Qwen XML patterns:

```typescript
pi.on('turn_end', async (event, ctx) => {
  for (const msg of event.messages) {
    if (msg.role === 'assistant') {
      const parsed = parseQwenXML(msg.content);
      if (parsed.toolCalls.length > 0) {
        ctx.ui.notify(`Detected ${parsed.toolCalls.length} Qwen XML tool call(s)...`, 'info');
      }
    }
  }
});
```

## Example Workflow

1. **Install the extension:**
   ```bash
   pi install npm:@cmcconomy/pi-qwen-tool-parser@1.0.0
   ```

2. **Configure your system prompt** to instruct Qwen to use XML format (optional)

3. **Ask a question** that requires tool execution:
   ```
   What files are in the current directory?
   ```

4. **Qwen responds with XML:**
   ```
   Let me check the files for you:
   
   🔧TOOL_CALL_START_9f8e7d6c5b4a3210<function_name>bash</function_name><parameters>{"command": "ls"}</parameters>🔚TOOL_CALL_END_9f8e7d6c5b4a3210
   
   I'll execute that command now.
   ```

5. **Execute the tools:**
   - Use `/parse-qwen` to parse and execute, OR
   - Call `qwen_tool_parser` tool with the response text

## Qwen XML Format

The extension recognizes this format:

```xml
🔧TOOL_CALL_START_<unique_id><function_name>tool_name</function_name><parameters>{"key": "value"}</parameters>🔚TOOL_CALL_END_<same_unique_id>
```

Where:
- `<unique_id>` is a hex string (e.g., `9f8e7d6c5b4a3210`)
- `<function_name>` is the tool name to execute
- `<parameters>` contains JSON with the tool arguments

## Development

### Prerequisites

- Node.js 20+ 
- npm 9+

### Setup

```bash
npm install
```

### Build:
```bash
npm run build
```

### Lint:
```bash
npm run lint
```

### Type Check:
```bash
npm run typecheck
```

### Run Tests:
```bash
npm test
```

### Local testing:
```bash
pi install ./path/to/package
```

## CI/CD

This project uses GitHub Actions for automated testing and publishing. See the `.github/workflows/ci.yml` file for details.

Running locally (equivalent to CI):

```bash
npm run prepublishOnly
# or individually:
npm run lint && npm run typecheck && npm run build && npm test
```

## License

MIT
