func name & xml_tag_name

This commit is contained in:
marko-kraemer 2025-04-05 17:38:55 +01:00
parent 308c31e25f
commit c1d7c82f82
4 changed files with 388 additions and 521 deletions

View File

@ -3,493 +3,52 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Minecraft Clone</title>
<style>
/* Previous CSS styles remain the same */
body { margin: 0; overflow: hidden; }
canvas { display: block; image-rendering: pixelated; }
.crosshair {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: white;
font-size: 24px;
pointer-events: none;
text-shadow: 2px 2px #000;
}
.inventory {
position: fixed;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
display: flex;
gap: 5px;
background: rgba(0, 0, 0, 0.5);
padding: 10px;
border-radius: 5px;
}
.inventory-slot {
width: 50px;
height: 50px;
background: rgba(255, 255, 255, 0.2);
border: 2px solid #fff;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
color: white;
image-rendering: pixelated;
}
.inventory-slot.selected {
background: rgba(255, 255, 255, 0.4);
border-color: #ffff00;
}
.hud {
position: fixed;
top: 20px;
left: 20px;
color: white;
font-family: 'Minecraft', monospace;
text-shadow: 2px 2px #000;
}
</style>
<title>AGI Interface</title>
<link rel="stylesheet" href="styles.css">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
</head>
<body>
<div class="crosshair">+</div>
<div class="hud">
<div id="coordinates"></div>
<div id="selected-block"></div>
<div class="container">
<header>
<h1>AGI Interface</h1>
<div class="status-indicator">
<span class="pulse"></span>
<span>System Active</span>
</div>
</header>
<main>
<section class="interaction-panel">
<div class="chat-interface">
<div id="chat-messages" class="messages"></div>
<div class="input-area">
<input type="text" id="user-input" placeholder="Enter your query...">
<button id="send-btn"><i class="fas fa-paper-plane"></i></button>
</div>
</div>
</section>
<section class="visualization-panel">
<div class="neural-network">
<canvas id="neural-canvas"></canvas>
</div>
<div class="metrics">
<div class="metric">
<h3>Processing Power</h3>
<div class="progress-bar">
<div class="progress" id="processing-power"></div>
</div>
</div>
<div class="metric">
<h3>Learning Rate</h3>
<div class="progress-bar">
<div class="progress" id="learning-rate"></div>
</div>
</div>
</div>
</section>
</main>
</div>
<div class="inventory" id="inventory"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/controls/PointerLockControls.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/simplex-noise/2.4.0/simplex-noise.min.js"></script>
<script>
// Initialize Three.js with Minecraft-style settings
const scene = new THREE.Scene();
scene.fog = new THREE.Fog(0x8CB4DB, 30, 100); // Minecraft-style fog distance
scene.background = new THREE.Color(0x8CB4DB); // Minecraft sky blue
const camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({
antialias: false,
logarithmicDepthBuffer: true,
physicallyCorrectLights: true
});
const clock = new THREE.Clock(); // Disable antialiasing for pixelated look
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(1); // Force pixel ratio to 1 for sharp pixels
renderer.shadowMap.enabled = true;
document.body.appendChild(renderer.domElement);
// Minecraft-style textures
const textureLoader = new THREE.TextureLoader();
const texturePaths = {
grass_top: 'https://raw.githubusercontent.com/mrdoob/three.js/dev/examples/textures/minecraft/grass_top.png',
grass_side: 'https://raw.githubusercontent.com/mrdoob/three.js/dev/examples/textures/minecraft/grass_side.png',
dirt: 'https://raw.githubusercontent.com/mrdoob/three.js/dev/examples/textures/minecraft/dirt.png',
stone: 'https://raw.githubusercontent.com/mrdoob/three.js/dev/examples/textures/minecraft/stone.png',
wood: 'https://raw.githubusercontent.com/mrdoob/three.js/dev/examples/textures/minecraft/wood.png',
wood_top: 'https://raw.githubusercontent.com/mrdoob/three.js/dev/examples/textures/minecraft/wood.png',
leaves: 'https://raw.githubusercontent.com/mrdoob/three.js/dev/examples/textures/minecraft/leaves.png',
bedrock: 'https://raw.githubusercontent.com/mrdoob/three.js/dev/examples/textures/minecraft/stone.png'
};
// Configure texture settings for pixelated look
function loadMinecraftTexture(path) {
const texture = textureLoader.load(path);
texture.magFilter = THREE.NearestFilter;
texture.minFilter = THREE.NearestFilter;
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
return texture;
}
// Load all textures with Minecraft settings
const blockTextures = {};
for (const [key, path] of Object.entries(texturePaths)) {
blockTextures[key] = loadMinecraftTexture(path);
}
// Create materials with Minecraft-style shading
const materialSettings = {
transparent: false,
side: THREE.FrontSide,
shadowSide: THREE.FrontSide,
depthWrite: true,
depthTest: true
};
const blockMaterials = {
grass: [
new THREE.MeshBasicMaterial({ map: blockTextures.grass_side }),
new THREE.MeshBasicMaterial({ map: blockTextures.grass_side }),
new THREE.MeshBasicMaterial({ map: blockTextures.grass_top }),
new THREE.MeshBasicMaterial({ map: blockTextures.dirt }),
new THREE.MeshBasicMaterial({ map: blockTextures.grass_side }),
new THREE.MeshBasicMaterial({ map: blockTextures.grass_side })
],
dirt: Array(6).fill(new THREE.MeshBasicMaterial({ map: blockTextures.dirt })),
stone: Array(6).fill(new THREE.MeshBasicMaterial({ map: blockTextures.stone })),
wood: [
new THREE.MeshBasicMaterial({ map: blockTextures.wood }),
new THREE.MeshBasicMaterial({ map: blockTextures.wood }),
new THREE.MeshBasicMaterial({ map: blockTextures.wood_top }),
new THREE.MeshBasicMaterial({ map: blockTextures.wood_top }),
new THREE.MeshBasicMaterial({ map: blockTextures.wood }),
new THREE.MeshBasicMaterial({ map: blockTextures.wood })
],
leaves: Array(6).fill(new THREE.MeshBasicMaterial({
map: blockTextures.leaves,
transparent: true,
alphaTest: 0.5
})),
bedrock: Array(6).fill(new THREE.MeshBasicMaterial({ map: blockTextures.bedrock }))
};
// Simple lighting for Minecraft-style rendering
const ambientLight = new THREE.AmbientLight(0xffffff, 1.0);
scene.add(ambientLight);
// Enhanced block creation with Minecraft materials
function createBlock(x, y, z, type = 'grass') {
const geometry = new THREE.BoxGeometry(1, 1, 1);
const materials = blockMaterials[type];
const cube = new THREE.Mesh(geometry, materials);
cube.position.set(x, y, z);
cube.castShadow = true;
cube.receiveShadow = true;
cube.userData.type = type;
scene.add(cube);
blocks.set(`${x},${y},${z}`, cube);
return cube;
}
// Improved terrain generation with more Minecraft-like features
const noise = new SimplexNoise();
const worldSize = 32;
const blocks = new Map();
function generateTerrain() {
// Generate bedrock layer
for (let x = -worldSize/2; x < worldSize/2; x++) {
for (let z = -worldSize/2; z < worldSize/2; z++) {
createBlock(x, 0, z, 'bedrock');
}
}
// Generate terrain
for (let x = -worldSize/2; x < worldSize/2; x++) {
for (let z = -worldSize/2; z < worldSize/2; z++) {
const height = Math.floor(
(noise.noise2D(x * 0.1, z * 0.1) + 1) * 5 + 5
);
// Generate layers
for (let y = 1; y < height; y++) {
const blockType = y === height - 1 ? 'grass' :
y > height - 4 ? 'dirt' : 'stone';
createBlock(x, y, z, blockType);
}
// Generate trees with better distribution
if (Math.random() < 0.02 && height > 3) {
const treeHeight = 4 + Math.floor(Math.random() * 3);
// Tree trunk
for (let y = height; y < height + treeHeight; y++) {
createBlock(x, y, z, 'wood');
}
// Tree leaves
for (let lx = -2; lx <= 2; lx++) {
for (let ly = -2; ly <= 2; ly++) {
for (let lz = -2; lz <= 2; lz++) {
if (Math.abs(lx) + Math.abs(ly) + Math.abs(lz) <= 4 && Math.random() < 0.7) {
createBlock(
x + lx,
height + treeHeight + ly,
z + lz,
'leaves'
);
}
}
}
}
}
}
}
}
// Player Controls and Physics
const controls = new THREE.PointerLockControls(camera, document.body);
let canJump = false;
let velocity = new THREE.Vector3();
let moveForward = false;
let moveBackward = false;
let moveLeft = false;
let moveRight = false;
let playerHeight = 1.6;
camera.position.set(0, playerHeight + 20, 20); // Move camera back for better initial view
// Click to start
document.addEventListener('click', () => {
controls.lock();
});
controls.addEventListener('lock', () => {
document.getElementById('inventory').style.display = 'flex';
});
controls.addEventListener('unlock', () => {
document.getElementById('inventory').style.display = 'none';
});
// Keyboard controls
const onKeyDown = function(event) {
switch (event.code) {
case 'ArrowUp':
case 'KeyW':
moveForward = true;
break;
case 'ArrowDown':
case 'KeyS':
moveBackward = true;
break;
case 'ArrowLeft':
case 'KeyA':
moveLeft = true;
break;
case 'ArrowRight':
case 'KeyD':
moveRight = true;
break;
case 'Space':
if (canJump) {
velocity.y = 8;
canJump = false;
}
break;
}
};
const onKeyUp = function(event) {
switch (event.code) {
case 'ArrowUp':
case 'KeyW':
moveForward = false;
break;
case 'ArrowDown':
case 'KeyS':
moveBackward = false;
break;
case 'ArrowLeft':
case 'KeyA':
moveLeft = false;
break;
case 'ArrowRight':
case 'KeyD':
moveRight = false;
break;
}
};
document.addEventListener('keydown', onKeyDown);
document.addEventListener('keyup', onKeyUp);
// Inventory system
const inventory = {
selectedSlot: 0,
slots: [
{ type: 'grass', count: Infinity },
{ type: 'dirt', count: Infinity },
{ type: 'stone', count: Infinity },
{ type: 'wood', count: Infinity },
{ type: 'leaves', count: Infinity },
{ type: 'bedrock', count: Infinity }
]
};
function updateInventoryUI() {
const inventoryEl = document.getElementById('inventory');
inventoryEl.innerHTML = '';
inventory.slots.forEach((slot, index) => {
const slotEl = document.createElement('div');
slotEl.className = `inventory-slot ${index === inventory.selectedSlot ? 'selected' : ''}`;
slotEl.textContent = slot.type;
slotEl.onclick = () => {
inventory.selectedSlot = index;
updateInventoryUI();
};
inventoryEl.appendChild(slotEl);
});
}
// Mouse wheel to change selected slot
document.addEventListener('wheel', (event) => {
if (controls.isLocked) {
inventory.selectedSlot = (inventory.selectedSlot + (event.deltaY > 0 ? 1 : -1) + inventory.slots.length) % inventory.slots.length;
updateInventoryUI();
}
});
// Block interaction
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();
// Place block
document.addEventListener('contextmenu', (event) => {
event.preventDefault();
if (controls.isLocked) {
raycaster.setFromCamera(mouse, camera);
const intersects = raycaster.intersectObjects(scene.children);
if (intersects.length > 0) {
const intersect = intersects[0];
const position = intersect.point.add(intersect.face.normal);
const roundedPos = position.round();
// Check if block placement is not too close to player
const playerPos = camera.position.clone();
if (playerPos.distanceTo(roundedPos) > 2) {
const selectedType = inventory.slots[inventory.selectedSlot].type;
createBlock(
roundedPos.x,
roundedPos.y,
roundedPos.z,
selectedType
);
}
}
}
});
// Break block
document.addEventListener('click', (event) => {
if (controls.isLocked) {
raycaster.setFromCamera(mouse, camera);
const intersects = raycaster.intersectObjects(scene.children);
if (intersects.length > 0) {
const intersect = intersects[0];
const block = intersect.object;
// Prevent breaking bedrock
if (block.userData.type !== 'bedrock') {
scene.remove(block);
blocks.delete(`${block.position.x},${block.position.y},${block.position.z}`);
}
}
}
});
// Player physics and movement
function movePlayer(delta) {
if (controls.isLocked) {
// Gravity
velocity.y -= 20 * delta; // Minecraft-like gravity
// Forward/backward movement
const direction = new THREE.Vector3();
direction.z = Number(moveForward) - Number(moveBackward);
direction.x = Number(moveRight) - Number(moveLeft);
direction.normalize();
// Apply movement based on camera direction
if (moveForward || moveBackward) {
velocity.z -= direction.z * 20 * delta;
}
if (moveLeft || moveRight) {
velocity.x -= direction.x * 20 * delta;
}
// Apply friction
velocity.x *= 0.9;
velocity.z *= 0.9;
// Collision detection
const futurePosition = camera.position.clone();
futurePosition.x += velocity.x * delta;
futurePosition.y += velocity.y * delta;
futurePosition.z += velocity.z * delta;
// Check for collisions with blocks
const playerRadius = 0.3;
const checkPositions = [
[0, 0, 0], // Center
[playerRadius, 0, playerRadius], // Corners
[-playerRadius, 0, playerRadius],
[playerRadius, 0, -playerRadius],
[-playerRadius, 0, -playerRadius]
];
let collision = false;
for (const [offsetX, offsetY, offsetZ] of checkPositions) {
const checkPos = futurePosition.clone().add(new THREE.Vector3(offsetX, offsetY, offsetZ));
const blockPos = checkPos.clone().floor();
if (blocks.has(`${blockPos.x},${blockPos.y},${blockPos.z}`)) {
collision = true;
break;
}
}
// Update position if no collision
if (!collision) {
controls.moveRight(-velocity.x * delta);
controls.moveForward(-velocity.z * delta);
camera.position.y += velocity.y * delta;
} else {
velocity.setX(0);
velocity.setZ(0);
if (velocity.y < 0) {
velocity.setY(0);
canJump = true;
}
}
// Prevent falling through ground
if (camera.position.y < playerHeight) {
camera.position.y = playerHeight;
velocity.y = 0;
canJump = true;
}
// Update HUD
document.getElementById('coordinates').textContent =
`Position: ${Math.round(camera.position.x)}, ${Math.round(camera.position.y)}, ${Math.round(camera.position.z)}`;
document.getElementById('selected-block').textContent =
`Selected: ${inventory.slots[inventory.selectedSlot].type}`;
}
}
// ... (previous code for controls, movement, and interaction remains unchanged)
// Update animation loop with fog
function animate() {
requestAnimationFrame(animate);
const delta = Math.min(0.1, clock.getDelta());
movePlayer(delta);
// Update fog based on time of day (simplified)
const time = Date.now() * 0.001;
const fogColor = new THREE.Color(0x8CB4DB);
scene.fog.color = fogColor;
scene.background = fogColor;
renderer.render(scene, camera);
}
// Initialize the game
generateTerrain();
animate();
// Handle window resize
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
</script>
<script src="script.js"></script>
</body>
</html>

View File

@ -0,0 +1,140 @@
class AGIInterface {
constructor() {
this.initializeElements();
this.bindEvents();
this.initializeNeuralNetwork();
this.updateMetrics();
}
initializeElements() {
this.chatMessages = document.getElementById('chat-messages');
this.userInput = document.getElementById('user-input');
this.sendButton = document.getElementById('send-btn');
this.canvas = document.getElementById('neural-canvas');
this.ctx = this.canvas.getContext('2d');
this.processingPower = document.getElementById('processing-power');
this.learningRate = document.getElementById('learning-rate');
}
bindEvents() {
this.sendButton.addEventListener('click', () => this.handleUserInput());
this.userInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') this.handleUserInput();
});
window.addEventListener('resize', () => this.resizeCanvas());
}
handleUserInput() {
const message = this.userInput.value.trim();
if (message) {
this.addMessage('user', message);
this.generateResponse(message);
this.userInput.value = '';
}
}
addMessage(type, content) {
const messageDiv = document.createElement('div');
messageDiv.className = `message ${type}-message`;
messageDiv.innerHTML = `
<div class="message-content">
<span class="message-text">${content}</span>
<span class="timestamp">${new Date().toLocaleTimeString()}</span>
</div>
`;
this.chatMessages.appendChild(messageDiv);
this.chatMessages.scrollTop = this.chatMessages.scrollHeight;
}
generateResponse(userMessage) {
// Simulate AI processing
setTimeout(() => {
const responses = [
"I understand your query about " + userMessage,
"Processing your request regarding " + userMessage,
"Analyzing the context of " + userMessage,
"Interesting perspective on " + userMessage
];
const response = responses[Math.floor(Math.random() * responses.length)];
this.addMessage('ai', response);
this.updateMetrics();
}, 1000);
}
initializeNeuralNetwork() {
this.resizeCanvas();
this.nodes = [];
this.connections = [];
// Create nodes
for (let layer = 0; layer < 3; layer++) {
const nodesInLayer = layer === 1 ? 4 : 3;
for (let i = 0; i < nodesInLayer; i++) {
this.nodes.push({
x: (layer + 1) * this.canvas.width / 4,
y: (i + 1) * this.canvas.height / (nodesInLayer + 1),
layer: layer
});
}
}
// Create connections
this.nodes.forEach(node => {
if (node.layer < 2) {
this.nodes.filter(n => n.layer === node.layer + 1).forEach(nextNode => {
this.connections.push({
start: node,
end: nextNode,
activity: Math.random()
});
});
}
});
this.animate();
}
resizeCanvas() {
this.canvas.width = this.canvas.offsetWidth;
this.canvas.height = this.canvas.offsetHeight;
}
animate() {
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
// Draw connections
this.connections.forEach(conn => {
this.ctx.beginPath();
this.ctx.moveTo(conn.start.x, conn.start.y);
this.ctx.lineTo(conn.end.x, conn.end.y);
this.ctx.strokeStyle = `rgba(52, 152, 219, ${conn.activity})`;
this.ctx.lineWidth = 2;
this.ctx.stroke();
conn.activity = Math.max(0.1, Math.min(1, conn.activity + (Math.random() - 0.5) * 0.1));
});
// Draw nodes
this.nodes.forEach(node => {
this.ctx.beginPath();
this.ctx.arc(node.x, node.y, 10, 0, Math.PI * 2);
this.ctx.fillStyle = '#3498db';
this.ctx.fill();
});
requestAnimationFrame(() => this.animate());
}
updateMetrics() {
const processingPowerValue = Math.random() * 100;
const learningRateValue = Math.random() * 100;
this.processingPower.style.width = `${processingPowerValue}%`;
this.learningRate.style.width = `${learningRateValue}%`;
}
}
// Initialize the application
document.addEventListener('DOMContentLoaded', () => {
const agi = new AGIInterface();
});

View File

@ -0,0 +1,150 @@
:root {
--primary-color: #2c3e50;
--secondary-color: #3498db;
--accent-color: #e74c3c;
--background-color: #f5f6fa;
--text-color: #2c3e50;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Arial', sans-serif;
background-color: var(--background-color);
color: var(--text-color);
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20px 0;
margin-bottom: 30px;
}
h1 {
color: var(--primary-color);
font-size: 2.5em;
}
.status-indicator {
display: flex;
align-items: center;
gap: 10px;
}
.pulse {
width: 10px;
height: 10px;
background-color: #2ecc71;
border-radius: 50%;
animation: pulse 2s infinite;
}
@keyframes pulse {
0% { transform: scale(1); opacity: 1; }
50% { transform: scale(1.5); opacity: 0.7; }
100% { transform: scale(1); opacity: 1; }
}
main {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 30px;
}
.interaction-panel, .visualization-panel {
background: white;
border-radius: 15px;
padding: 20px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.chat-interface {
height: 500px;
display: flex;
flex-direction: column;
}
.messages {
flex-grow: 1;
overflow-y: auto;
padding: 15px;
margin-bottom: 15px;
}
.input-area {
display: flex;
gap: 10px;
}
input[type="text"] {
flex-grow: 1;
padding: 12px;
border: 2px solid #e0e0e0;
border-radius: 8px;
font-size: 16px;
}
button {
padding: 12px 24px;
background-color: var(--secondary-color);
color: white;
border: none;
border-radius: 8px;
cursor: pointer;
transition: background-color 0.3s;
}
button:hover {
background-color: #2980b9;
}
.neural-network {
height: 300px;
margin-bottom: 20px;
}
canvas {
width: 100%;
height: 100%;
}
.metrics {
display: grid;
gap: 20px;
}
.metric h3 {
margin-bottom: 10px;
}
.progress-bar {
height: 20px;
background-color: #f0f0f0;
border-radius: 10px;
overflow: hidden;
}
.progress {
height: 100%;
background-color: var(--secondary-color);
width: 0%;
transition: width 0.3s ease;
}
@media (max-width: 768px) {
main {
grid-template-columns: 1fr;
}
}

View File

@ -697,16 +697,20 @@ class ResponseProcessor:
if not tag_match:
logger.error(f"No tag found in XML chunk: {xml_chunk}")
return None
tag_name = tag_match.group(1)
logger.info(f"Found XML tag: {tag_name}")
# Get tool info and schema
tool_info = self.tool_registry.get_xml_tool(tag_name)
# This is the XML tag as it appears in the text (e.g., "create-file")
xml_tag_name = tag_match.group(1)
logger.info(f"Found XML tag: {xml_tag_name}")
# Get tool info and schema from registry
tool_info = self.tool_registry.get_xml_tool(xml_tag_name)
if not tool_info or not tool_info['schema'].xml_schema:
logger.error(f"No tool or schema found for tag: {tag_name}")
logger.error(f"No tool or schema found for tag: {xml_tag_name}")
return None
# This is the actual function name to call (e.g., "create_file")
function_name = tool_info['method']
schema = tool_info['schema'].xml_schema
params = {}
remaining_chunk = xml_chunk
@ -721,26 +725,26 @@ class ResponseProcessor:
if value is not None:
params[mapping.param_name] = value
logger.info(f"Found attribute {mapping.path} -> {mapping.param_name}: {value}")
elif mapping.node_type == "element":
# Extract element content
content, remaining_chunk = self._extract_tag_content(remaining_chunk, mapping.path)
if content is not None:
params[mapping.param_name] = content.strip()
logger.info(f"Found element {mapping.path} -> {mapping.param_name}")
elif mapping.node_type == "text":
if mapping.path == ".":
# Extract root content
content, _ = self._extract_tag_content(remaining_chunk, tag_name)
content, _ = self._extract_tag_content(remaining_chunk, xml_tag_name)
if content is not None:
params[mapping.param_name] = content.strip()
logger.info(f"Found text content for {mapping.param_name}")
elif mapping.node_type == "content":
if mapping.path == ".":
# Extract root content
content, _ = self._extract_tag_content(remaining_chunk, tag_name)
content, _ = self._extract_tag_content(remaining_chunk, xml_tag_name)
if content is not None:
params[mapping.param_name] = content.strip()
logger.info(f"Found root content for {mapping.param_name}")
@ -757,10 +761,11 @@ class ResponseProcessor:
logger.error(f"XML chunk: {xml_chunk}")
return None
# Create tool call
# Create tool call with clear separation between function_name and xml_tag_name
tool_call = {
"name": tool_info['method'],
"arguments": params
"function_name": function_name, # The actual method to call (e.g., create_file)
"xml_tag_name": xml_tag_name, # The original XML tag (e.g., create-file)
"arguments": params # The extracted parameters
}
logger.info(f"Created tool call: {tool_call}")
@ -792,7 +797,7 @@ class ResponseProcessor:
async def _execute_tool(self, tool_call: Dict[str, Any]) -> ToolResult:
"""Execute a single tool call and return the result."""
try:
function_name = tool_call["name"]
function_name = tool_call["function_name"]
arguments = tool_call["arguments"]
logger.info(f"Executing tool: {function_name} with arguments: {arguments}")
@ -817,7 +822,7 @@ class ResponseProcessor:
logger.info(f"Tool execution complete: {function_name} -> {result}")
return result
except Exception as e:
logger.error(f"Error executing tool {tool_call['name']}: {str(e)}", exc_info=True)
logger.error(f"Error executing tool {tool_call['function_name']}: {str(e)}", exc_info=True)
return ToolResult(success=False, output=f"Error executing tool: {str(e)}")
async def _execute_tools(
@ -981,37 +986,43 @@ class ResponseProcessor:
def _format_xml_tool_result(self, tool_call: Dict[str, Any], result: ToolResult) -> str:
"""Format a tool result as a simple XML tag.
"""Format a tool result as an XML tag or plain text.
Args:
tool_call: The tool call that was executed
result: The result of the tool execution
Returns:
String containing the XML-formatted result or standard format if not XML
String containing the formatted result
"""
xml_tag_name = self._get_tool_display_name(tool_call["name"])
# Always use xml_tag_name if it exists
if "xml_tag_name" in tool_call:
xml_tag_name = tool_call["xml_tag_name"]
return f"<{xml_tag_name}> {str(result)} </{xml_tag_name}>"
# If display name is same as method name, it's not an XML tool
if xml_tag_name == tool_call["name"]:
return f"Result for {tool_call['name']}: {str(result)}"
# Format as simple XML tag without attributes
xml_output = f"<{xml_tag_name}> {str(result)} </{xml_tag_name}>"
return xml_output
# Non-XML tool, just return the function result
function_name = tool_call["function_name"]
return f"Result for {function_name}: {str(result)}"
def _get_tool_display_name(self, method_name: str) -> str:
"""Get the display name for a tool (XML tag name if applicable, or method name)."""
if not hasattr(self.tool_registry, 'xml_tools'):
return method_name
def _get_tool_display_name(self, function_name: str) -> str:
"""Get the XML tag name for a function name.
Args:
function_name: The function name to look up
# Check if this method corresponds to an XML tool
Returns:
The XML tag name if found, otherwise the original function name
"""
if not hasattr(self.tool_registry, 'xml_tools'):
return function_name
# Check if this function corresponds to an XML tool
for tag_name, xml_tool_info in self.tool_registry.xml_tools.items():
if xml_tool_info.get('method') == method_name:
if xml_tool_info.get('method') == function_name:
return tag_name
# Default to the method name if no XML tag found
return method_name
# Default to the function name if no XML tag found
return function_name
# At class level, define a method for yielding tool results
def _yield_tool_result(self, context: ToolExecutionContext) -> Dict[str, Any]:
@ -1038,7 +1049,14 @@ class ResponseProcessor:
tool_call=tool_call,
tool_index=tool_index
)
context.display_name = self._get_tool_display_name(tool_call["name"])
# Always use xml_tag_name if it exists
if "xml_tag_name" in tool_call:
context.display_name = tool_call["xml_tag_name"]
else:
# For non-XML tools, use function name directly
context.display_name = tool_call["function_name"]
return context
def _yield_tool_started(self, context: ToolExecutionContext) -> Dict[str, Any]: