Spaces:
Running
Running
sync: 192 file da Baida98/AI@3608369b (2026-08-26 20:24 UTC) [deploy-all]
#123
by Baida07 - opened
- api/agent.py +17 -1
api/agent.py
CHANGED
|
@@ -1155,13 +1155,19 @@ async def stream_agent_task(task_id: str, request: Request, resume: int = 0, rol
|
|
| 1155 |
# soltanto quelli con contenuto così il commit atomico può avvenire
|
| 1156 |
# una sola volta dopo un task riuscito.
|
| 1157 |
_vfs_written_paths: set[str] = set()
|
|
|
|
|
|
|
|
|
|
| 1158 |
|
| 1159 |
async def step_cb(step_data: dict) -> None:
|
| 1160 |
step_idx[0] += 1
|
| 1161 |
_action = step_data.get('action', f'Step {step_idx[0]}')
|
| 1162 |
# S420: streaming token — emetti direttamente senza passare dal buffer step
|
| 1163 |
if _action == 'text_chunk':
|
| 1164 |
-
|
|
|
|
|
|
|
|
|
|
| 1165 |
return
|
| 1166 |
# RECOV-P1: engineering_state event — forward projection to frontend
|
| 1167 |
if _action == 'engineering_state':
|
|
@@ -1481,6 +1487,16 @@ async def stream_agent_task(task_id: str, request: Request, resume: int = 0, rol
|
|
| 1481 |
'status': 'QUALITY_CHECK_PENDING',
|
| 1482 |
'primaryStatus': 'COMPLETED',
|
| 1483 |
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1484 |
_sse('task_done', {
|
| 1485 |
'taskId': task_id,
|
| 1486 |
'result': _result_text[:8000],
|
|
|
|
| 1155 |
# soltanto quelli con contenuto così il commit atomico può avvenire
|
| 1156 |
# una sola volta dopo un task riuscito.
|
| 1157 |
_vfs_written_paths: set[str] = set()
|
| 1158 |
+
# Accumula soltanto i token realmente emessi per poter riconciliare
|
| 1159 |
+
# il testo in streaming con l'output autorevole del finalizer.
|
| 1160 |
+
_streamed_chunks: list[str] = []
|
| 1161 |
|
| 1162 |
async def step_cb(step_data: dict) -> None:
|
| 1163 |
step_idx[0] += 1
|
| 1164 |
_action = step_data.get('action', f'Step {step_idx[0]}')
|
| 1165 |
# S420: streaming token — emetti direttamente senza passare dal buffer step
|
| 1166 |
if _action == 'text_chunk':
|
| 1167 |
+
_token = _ss(step_data.get('token', ''))
|
| 1168 |
+
if _token:
|
| 1169 |
+
_streamed_chunks.append(_token)
|
| 1170 |
+
_sse('text_chunk', {'taskId': task_id, 'token': _token})
|
| 1171 |
return
|
| 1172 |
# RECOV-P1: engineering_state event — forward projection to frontend
|
| 1173 |
if _action == 'engineering_state':
|
|
|
|
| 1487 |
'status': 'QUALITY_CHECK_PENDING',
|
| 1488 |
'primaryStatus': 'COMPLETED',
|
| 1489 |
})
|
| 1490 |
+
_streamed_text = ''.join(_streamed_chunks)
|
| 1491 |
+
if _streamed_text and _result_text != _streamed_text:
|
| 1492 |
+
# Il finalizer può riparare/normalizzare la risposta dopo gli
|
| 1493 |
+
# ultimi chunk. Notifica esplicitamente la sostituzione così il
|
| 1494 |
+
# client non mostra un testo parziale o divergente.
|
| 1495 |
+
_sse('text_replace', {
|
| 1496 |
+
'taskId': task_id,
|
| 1497 |
+
'text': _result_text[:8000],
|
| 1498 |
+
'reason': 'authoritative_finalizer_output',
|
| 1499 |
+
})
|
| 1500 |
_sse('task_done', {
|
| 1501 |
'taskId': task_id,
|
| 1502 |
'result': _result_text[:8000],
|