ziya 0.3.0__py3-none-any.whl → 0.3.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ziya might be problematic. Click here for more details.
- app/agents/agent.py +71 -73
- app/agents/direct_streaming.py +1 -1
- app/agents/prompts.py +1 -1
- app/agents/prompts_manager.py +14 -10
- app/agents/wrappers/google_direct.py +31 -1
- app/agents/wrappers/nova_tool_execution.py +2 -2
- app/agents/wrappers/nova_wrapper.py +1 -1
- app/agents/wrappers/ziya_bedrock.py +53 -31
- app/config/models_config.py +61 -20
- app/config/shell_config.py +5 -1
- app/extensions/prompt_extensions/claude_extensions.py +27 -5
- app/extensions/prompt_extensions/mcp_prompt_extensions.py +82 -56
- app/main.py +5 -3
- app/mcp/client.py +19 -10
- app/mcp/manager.py +68 -10
- app/mcp/tools.py +8 -9
- app/mcp_servers/shell_server.py +3 -3
- app/middleware/streaming.py +29 -41
- app/routes/file_validation.py +35 -0
- app/routes/mcp_routes.py +54 -8
- app/server.py +525 -614
- app/streaming_tool_executor.py +748 -137
- app/templates/asset-manifest.json +20 -20
- app/templates/index.html +1 -1
- app/templates/static/css/{main.0297bfee.css → main.e7109b49.css} +2 -2
- app/templates/static/css/main.e7109b49.css.map +1 -0
- app/templates/static/js/14386.65fcfe53.chunk.js +2 -0
- app/templates/static/js/14386.65fcfe53.chunk.js.map +1 -0
- app/templates/static/js/35589.0368973a.chunk.js +2 -0
- app/templates/static/js/35589.0368973a.chunk.js.map +1 -0
- app/templates/static/js/{50295.ab92f61b.chunk.js → 50295.90aca393.chunk.js} +3 -3
- app/templates/static/js/50295.90aca393.chunk.js.map +1 -0
- app/templates/static/js/55734.5f0fd567.chunk.js +2 -0
- app/templates/static/js/55734.5f0fd567.chunk.js.map +1 -0
- app/templates/static/js/58542.57fed736.chunk.js +2 -0
- app/templates/static/js/58542.57fed736.chunk.js.map +1 -0
- app/templates/static/js/{68418.2554bb1e.chunk.js → 68418.f7b4d2d9.chunk.js} +3 -3
- app/templates/static/js/68418.f7b4d2d9.chunk.js.map +1 -0
- app/templates/static/js/99948.b280eda0.chunk.js +2 -0
- app/templates/static/js/99948.b280eda0.chunk.js.map +1 -0
- app/templates/static/js/main.e075582c.js +3 -0
- app/templates/static/js/main.e075582c.js.map +1 -0
- app/utils/code_util.py +5 -2
- app/utils/context_cache.py +11 -0
- app/utils/conversation_filter.py +90 -0
- app/utils/custom_bedrock.py +43 -1
- app/utils/diff_utils/validation/validators.py +32 -22
- app/utils/file_cache.py +5 -3
- app/utils/precision_prompt_system.py +116 -0
- app/utils/streaming_optimizer.py +100 -0
- {ziya-0.3.0.dist-info → ziya-0.3.2.dist-info}/METADATA +3 -2
- {ziya-0.3.0.dist-info → ziya-0.3.2.dist-info}/RECORD +59 -55
- app/templates/static/css/main.0297bfee.css.map +0 -1
- app/templates/static/js/14386.567bf803.chunk.js +0 -2
- app/templates/static/js/14386.567bf803.chunk.js.map +0 -1
- app/templates/static/js/35589.278ecda2.chunk.js +0 -2
- app/templates/static/js/35589.278ecda2.chunk.js.map +0 -1
- app/templates/static/js/50295.ab92f61b.chunk.js.map +0 -1
- app/templates/static/js/55734.90d8bd52.chunk.js +0 -2
- app/templates/static/js/55734.90d8bd52.chunk.js.map +0 -1
- app/templates/static/js/58542.08fb5cf4.chunk.js +0 -2
- app/templates/static/js/58542.08fb5cf4.chunk.js.map +0 -1
- app/templates/static/js/68418.2554bb1e.chunk.js.map +0 -1
- app/templates/static/js/99948.71670e91.chunk.js +0 -2
- app/templates/static/js/99948.71670e91.chunk.js.map +0 -1
- app/templates/static/js/main.1d79eac2.js +0 -3
- app/templates/static/js/main.1d79eac2.js.map +0 -1
- /app/templates/static/js/{50295.ab92f61b.chunk.js.LICENSE.txt → 50295.90aca393.chunk.js.LICENSE.txt} +0 -0
- /app/templates/static/js/{68418.2554bb1e.chunk.js.LICENSE.txt → 68418.f7b4d2d9.chunk.js.LICENSE.txt} +0 -0
- /app/templates/static/js/{main.1d79eac2.js.LICENSE.txt → main.e075582c.js.LICENSE.txt} +0 -0
- {ziya-0.3.0.dist-info → ziya-0.3.2.dist-info}/WHEEL +0 -0
- {ziya-0.3.0.dist-info → ziya-0.3.2.dist-info}/entry_points.txt +0 -0
- {ziya-0.3.0.dist-info → ziya-0.3.2.dist-info}/licenses/LICENSE +0 -0
app/middleware/streaming.py
CHANGED
|
@@ -80,13 +80,19 @@ class StreamingMiddleware(BaseHTTPMiddleware):
|
|
|
80
80
|
self._recent_lines = []
|
|
81
81
|
accumulated_content = ""
|
|
82
82
|
accumulated_chunks = [] # Track all chunks for better preservation
|
|
83
|
+
|
|
84
|
+
# Code block state tracking for frontend
|
|
85
|
+
frontend_code_block_state = {
|
|
86
|
+
'in_block': False,
|
|
87
|
+
'block_type': None
|
|
88
|
+
}
|
|
83
89
|
|
|
84
90
|
# Limits for preserved content to prevent context bloat
|
|
85
91
|
MAX_PRESERVED_TOOLS = 10
|
|
86
92
|
MAX_TOOL_OUTPUT_LENGTH = 5000
|
|
87
93
|
successful_tool_outputs = [] # Track successful tool executions
|
|
88
94
|
tool_sequence_count = 0
|
|
89
|
-
content_buffer = "" #
|
|
95
|
+
# content_buffer = "" # Disabled buffering for real-time streaming
|
|
90
96
|
partial_response_preserved = False
|
|
91
97
|
try:
|
|
92
98
|
async for chunk in original_iterator:
|
|
@@ -138,7 +144,7 @@ class StreamingMiddleware(BaseHTTPMiddleware):
|
|
|
138
144
|
chunk_content = json.dumps(json_obj)
|
|
139
145
|
|
|
140
146
|
# DEBUGGING: Check if JSON serialization changed size
|
|
141
|
-
if len(chunk_content) != chunk_size and json_obj.get('type')
|
|
147
|
+
if len(chunk_content) != chunk_size and json_obj.get('type') in ['tool_execution', 'tool_display']:
|
|
142
148
|
logger.warning(f"🔍 JSON_SIZE_CHANGE: Original {chunk_size} -> Serialized {len(chunk_content)} chars")
|
|
143
149
|
|
|
144
150
|
yield f"data: {json.dumps(json_obj)}\n\n"
|
|
@@ -146,46 +152,18 @@ class StreamingMiddleware(BaseHTTPMiddleware):
|
|
|
146
152
|
# If it's not valid JSON, just pass it as a string
|
|
147
153
|
content = str(chunk)
|
|
148
154
|
|
|
149
|
-
#
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
if self._should_flush_buffer(content_buffer):
|
|
154
|
-
# If this contains a complete tool call, execute it and send the result
|
|
155
|
-
if self._contains_complete_tool_call(content_buffer):
|
|
156
|
-
# First, send the complete tool call to the frontend as JSON
|
|
157
|
-
yield f"data: {json.dumps({'tool_call': content_buffer})}\n\n"
|
|
158
|
-
|
|
159
|
-
try:
|
|
160
|
-
# Execute the tool call
|
|
161
|
-
logger.info(f"Executing tool call in streaming middleware: {content_buffer[:100]}...")
|
|
162
|
-
from app.mcp.consolidated import execute_mcp_tools_with_status
|
|
163
|
-
tool_result = await execute_mcp_tools_with_status(content_buffer)
|
|
164
|
-
logger.info(f"Tool execution result: {tool_result[:100]}...")
|
|
165
|
-
|
|
166
|
-
# Send the tool result to the frontend
|
|
167
|
-
yield f"data: {json.dumps({'tool_result': tool_result})}\n\n"
|
|
168
|
-
except Exception as tool_error:
|
|
169
|
-
logger.error(f"Error executing tool call: {tool_error}")
|
|
170
|
-
# Send error message
|
|
171
|
-
error_msg = f"\n\n```tool:error\n❌ **Tool Error:** {str(tool_error)}\n```\n\n"
|
|
172
|
-
yield f"data: {json.dumps({'tool_error': error_msg})}\n\n"
|
|
173
|
-
|
|
174
|
-
# Clear buffer
|
|
175
|
-
content_buffer = ""
|
|
176
|
-
else:
|
|
177
|
-
# Send buffered content as JSON, not raw content
|
|
155
|
+
# Immediately pass through tool_start messages without buffering
|
|
156
|
+
if '"type": "tool_start"' in content:
|
|
157
|
+
# First flush any buffered content
|
|
158
|
+
if content_buffer:
|
|
178
159
|
yield f"data: {json.dumps({'content': content_buffer})}\n\n"
|
|
179
160
|
content_buffer = ""
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
accumulated_content += content
|
|
183
|
-
# Hold the content in buffer, don't send yet
|
|
161
|
+
# Then send the tool_start message
|
|
162
|
+
yield content
|
|
184
163
|
continue
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
content_buffer = ""
|
|
164
|
+
|
|
165
|
+
# Send content immediately for real-time streaming
|
|
166
|
+
yield f"data: {json.dumps({'content': content})}\\n\\n"
|
|
189
167
|
|
|
190
168
|
# Log chunk content preview
|
|
191
169
|
if len(chunk) > 200:
|
|
@@ -247,6 +225,16 @@ class StreamingMiddleware(BaseHTTPMiddleware):
|
|
|
247
225
|
# For simple string content
|
|
248
226
|
content = str(raw_content)
|
|
249
227
|
|
|
228
|
+
# Immediately pass through tool_start messages without buffering
|
|
229
|
+
if '"type": "tool_start"' in content:
|
|
230
|
+
# First flush any buffered content
|
|
231
|
+
if content_buffer:
|
|
232
|
+
yield f"data: {json.dumps({'content': content_buffer})}\n\n"
|
|
233
|
+
content_buffer = ""
|
|
234
|
+
# Then send the tool_start message
|
|
235
|
+
yield content
|
|
236
|
+
continue
|
|
237
|
+
|
|
250
238
|
# Buffer content to check for tool calls
|
|
251
239
|
content_buffer += content
|
|
252
240
|
|
|
@@ -354,7 +342,7 @@ class StreamingMiddleware(BaseHTTPMiddleware):
|
|
|
354
342
|
logger.warning(f"🔍 LARGE_CHUNK_DETECTED: {chunk_size} chars - monitoring for truncation")
|
|
355
343
|
|
|
356
344
|
# Check if this is a tool result chunk
|
|
357
|
-
if "tool_execution" in chunk or "tool_result" in chunk:
|
|
345
|
+
if "tool_execution" in chunk or "tool_display" in chunk or "tool_result" in chunk:
|
|
358
346
|
logger.info(f"🔍 TOOL_RESULT_CHUNK: size={chunk_size}, content preview: {chunk[:100]}...")
|
|
359
347
|
|
|
360
348
|
# Check if it might be JSON
|
|
@@ -368,7 +356,7 @@ class StreamingMiddleware(BaseHTTPMiddleware):
|
|
|
368
356
|
# DEBUGGING: Track large JSON objects
|
|
369
357
|
if len(chunk_content) > 5000:
|
|
370
358
|
logger.warning(f"🔍 MIDDLEWARE_LARGE_JSON: {len(chunk_content)} chars, type={json_obj.get('type')}")
|
|
371
|
-
|
|
359
|
+
if json_obj.get('type') in ['tool_execution', 'tool_display']:
|
|
372
360
|
result_size = len(json_obj.get('result', ''))
|
|
373
361
|
logger.warning(f"🔍 MIDDLEWARE_TOOL_RESULT: tool={json_obj.get('tool_name')}, result_size={result_size}")
|
|
374
362
|
if result_size == 0:
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""
|
|
2
|
+
File validation API endpoint.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
from typing import List
|
|
7
|
+
from fastapi import APIRouter, HTTPException
|
|
8
|
+
from pydantic import BaseModel
|
|
9
|
+
|
|
10
|
+
router = APIRouter()
|
|
11
|
+
|
|
12
|
+
class FileValidationRequest(BaseModel):
|
|
13
|
+
files: List[str]
|
|
14
|
+
|
|
15
|
+
class FileValidationResponse(BaseModel):
|
|
16
|
+
existingFiles: List[str]
|
|
17
|
+
missingFiles: List[str]
|
|
18
|
+
|
|
19
|
+
@router.post("/api/files/validate", response_model=FileValidationResponse)
|
|
20
|
+
async def validate_files(request: FileValidationRequest):
|
|
21
|
+
"""Validate which files exist and return lists of existing/missing files."""
|
|
22
|
+
|
|
23
|
+
existing_files = []
|
|
24
|
+
missing_files = []
|
|
25
|
+
|
|
26
|
+
for file_path in request.files:
|
|
27
|
+
if os.path.exists(file_path):
|
|
28
|
+
existing_files.append(file_path)
|
|
29
|
+
else:
|
|
30
|
+
missing_files.append(file_path)
|
|
31
|
+
|
|
32
|
+
return FileValidationResponse(
|
|
33
|
+
existingFiles=existing_files,
|
|
34
|
+
missingFiles=missing_files
|
|
35
|
+
)
|
app/routes/mcp_routes.py
CHANGED
|
@@ -283,11 +283,15 @@ async def get_shell_config():
|
|
|
283
283
|
server_env = server_config.get("env", {})
|
|
284
284
|
|
|
285
285
|
# Extract allowed commands from environment configuration
|
|
286
|
+
# Always start with the full default command list
|
|
286
287
|
allowed_commands = DEFAULT_SHELL_CONFIG["allowedCommands"].copy()
|
|
287
|
-
|
|
288
|
+
|
|
289
|
+
# Only override if environment explicitly provides a DIFFERENT set
|
|
290
|
+
if "ALLOW_COMMANDS" in server_env and server_env["ALLOW_COMMANDS"].strip():
|
|
288
291
|
# If environment override exists, use it instead
|
|
289
292
|
env_commands = [cmd.strip() for cmd in server_env["ALLOW_COMMANDS"].split(",") if cmd.strip()]
|
|
290
|
-
if
|
|
293
|
+
# Only replace if the environment list is substantially different (not just a subset)
|
|
294
|
+
if env_commands and len(env_commands) >= len(DEFAULT_SHELL_CONFIG["allowedCommands"]) * 0.8:
|
|
291
295
|
allowed_commands = env_commands
|
|
292
296
|
logger.info(f"Using environment override commands: {allowed_commands}")
|
|
293
297
|
|
|
@@ -302,14 +306,20 @@ async def get_shell_config():
|
|
|
302
306
|
|
|
303
307
|
return {
|
|
304
308
|
"enabled": True,
|
|
309
|
+
"allowedCommands": allowed_commands,
|
|
305
310
|
"gitOperationsEnabled": git_operations_enabled,
|
|
306
|
-
"safeGitOperations": git_operations
|
|
311
|
+
"safeGitOperations": git_operations,
|
|
312
|
+
"timeout": timeout
|
|
307
313
|
}
|
|
308
314
|
else:
|
|
309
315
|
# Shell server not connected, return default config with enabled=False
|
|
316
|
+
# But still check for environment timeout override
|
|
317
|
+
default_config = get_default_shell_config()
|
|
318
|
+
timeout = int(os.environ.get("COMMAND_TIMEOUT", default_config["timeout"]))
|
|
310
319
|
return {
|
|
311
|
-
**
|
|
312
|
-
"enabled": False
|
|
320
|
+
**default_config,
|
|
321
|
+
"enabled": False,
|
|
322
|
+
"timeout": timeout
|
|
313
323
|
}
|
|
314
324
|
|
|
315
325
|
except Exception as e:
|
|
@@ -341,7 +351,7 @@ async def update_shell_config(config: ShellConfig):
|
|
|
341
351
|
|
|
342
352
|
# Create new shell server configuration
|
|
343
353
|
new_shell_config = {
|
|
344
|
-
"command": ["python", "-u", "mcp_servers/shell_server.py"],
|
|
354
|
+
"command": ["python", "-u", "app/mcp_servers/shell_server.py"],
|
|
345
355
|
"enabled": config.enabled,
|
|
346
356
|
"env": {
|
|
347
357
|
"ALLOW_COMMANDS": ",".join(config.allowedCommands),
|
|
@@ -352,17 +362,38 @@ async def update_shell_config(config: ShellConfig):
|
|
|
352
362
|
}
|
|
353
363
|
|
|
354
364
|
if config.enabled:
|
|
365
|
+
# Update the server configuration in MCP manager before restarting
|
|
366
|
+
mcp_manager.server_configs["shell"] = new_shell_config
|
|
367
|
+
|
|
355
368
|
# Restart the shell server with new configuration
|
|
369
|
+
logger.info(f"Attempting to restart shell server with config: {new_shell_config}")
|
|
356
370
|
success = await mcp_manager.restart_server("shell", new_shell_config)
|
|
357
371
|
|
|
372
|
+
if not success:
|
|
373
|
+
# Get detailed error information
|
|
374
|
+
shell_client = mcp_manager.clients.get("shell")
|
|
375
|
+
error_details = "Unknown error"
|
|
376
|
+
if shell_client and shell_client.process:
|
|
377
|
+
try:
|
|
378
|
+
stderr_output = shell_client.process.stderr.read() if shell_client.process.stderr else ""
|
|
379
|
+
if stderr_output:
|
|
380
|
+
error_details = f"Shell server stderr: {stderr_output}"
|
|
381
|
+
except Exception as e:
|
|
382
|
+
error_details = f"Could not read shell server error: {str(e)}"
|
|
383
|
+
|
|
384
|
+
logger.error(f"Shell server restart failed. Details: {error_details}")
|
|
385
|
+
return {"success": False, "message": f"Failed to restart shell server: {error_details}"}
|
|
386
|
+
|
|
358
387
|
if success:
|
|
359
388
|
logger.info(f"Shell server restarted with new config: {config.allowedCommands}")
|
|
389
|
+
|
|
390
|
+
# Invalidate tools cache to ensure fresh tool list with updated shell tools
|
|
391
|
+
mcp_manager.invalidate_tools_cache()
|
|
392
|
+
|
|
360
393
|
return {
|
|
361
394
|
"success": True,
|
|
362
395
|
"message": f"Shell server updated instantly. Basic commands: {', '.join(config.allowedCommands)}, Git operations: {'enabled' if config.gitOperationsEnabled else 'disabled'}"
|
|
363
396
|
}
|
|
364
|
-
else:
|
|
365
|
-
return {"success": False, "message": "Failed to restart shell server"}
|
|
366
397
|
else:
|
|
367
398
|
# Disable shell server by disconnecting it
|
|
368
399
|
if "shell" in mcp_manager.clients:
|
|
@@ -375,6 +406,9 @@ async def update_shell_config(config: ShellConfig):
|
|
|
375
406
|
mcp_manager.server_configs["shell"]["enabled"] = False
|
|
376
407
|
logger.info("Shell server marked as disabled in server configs")
|
|
377
408
|
|
|
409
|
+
# Invalidate tools cache to ensure fresh tool list without shell tools
|
|
410
|
+
mcp_manager.invalidate_tools_cache()
|
|
411
|
+
|
|
378
412
|
return {"success": True, "message": "Shell server disabled instantly"}
|
|
379
413
|
|
|
380
414
|
except Exception as e:
|
|
@@ -421,6 +455,10 @@ async def toggle_server(request: ServerToggleRequest):
|
|
|
421
455
|
if server_config:
|
|
422
456
|
success = await mcp_manager.restart_server(request.server_name, server_config)
|
|
423
457
|
message = f"{request.server_name} server enabled and restarted" if success else f"Failed to restart {request.server_name} server"
|
|
458
|
+
|
|
459
|
+
# Invalidate tools cache to ensure fresh tool list with newly enabled server tools
|
|
460
|
+
if success:
|
|
461
|
+
mcp_manager.invalidate_tools_cache()
|
|
424
462
|
else:
|
|
425
463
|
message = f"No configuration found for {request.server_name} server"
|
|
426
464
|
else:
|
|
@@ -429,6 +467,14 @@ async def toggle_server(request: ServerToggleRequest):
|
|
|
429
467
|
await mcp_manager.clients[request.server_name].disconnect()
|
|
430
468
|
del mcp_manager.clients[request.server_name]
|
|
431
469
|
logger.info(f"{request.server_name} server disabled")
|
|
470
|
+
|
|
471
|
+
# Update server config to mark as disabled
|
|
472
|
+
if request.server_name in mcp_manager.server_configs:
|
|
473
|
+
mcp_manager.server_configs[request.server_name]["enabled"] = False
|
|
474
|
+
|
|
475
|
+
# Invalidate tools cache to ensure fresh tool list without disabled server tools
|
|
476
|
+
mcp_manager.invalidate_tools_cache()
|
|
477
|
+
|
|
432
478
|
message = f"{request.server_name} server disabled"
|
|
433
479
|
|
|
434
480
|
return {"success": True, "message": message}
|