prizmkit 1.1.152 → 1.1.153
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.
package/bundled/VERSION.json
CHANGED
|
@@ -820,24 +820,22 @@ class ProgressTracker:
|
|
|
820
820
|
self.message_count += 1
|
|
821
821
|
elif event_type in {"message_update", "message_end"}:
|
|
822
822
|
assistant_event = event.get("assistantMessageEvent")
|
|
823
|
+
message = event.get("message")
|
|
823
824
|
text = ""
|
|
824
825
|
if isinstance(assistant_event, dict):
|
|
825
826
|
text = str(assistant_event.get("delta") or assistant_event.get("text") or "")
|
|
826
|
-
if not text:
|
|
827
|
-
|
|
828
|
-
if isinstance(
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
for item in content if isinstance(item, dict)
|
|
836
|
-
)
|
|
827
|
+
if not text and isinstance(message, dict):
|
|
828
|
+
content = message.get("content")
|
|
829
|
+
if isinstance(content, str):
|
|
830
|
+
text = content
|
|
831
|
+
elif isinstance(content, list):
|
|
832
|
+
text = "\n".join(
|
|
833
|
+
str(item.get("text") or "")
|
|
834
|
+
for item in content if isinstance(item, dict)
|
|
835
|
+
)
|
|
837
836
|
if text.strip():
|
|
838
837
|
self.last_text_snippet = text.strip()[-120:]
|
|
839
838
|
self._detect_phase(text)
|
|
840
|
-
self._detect_terminal_error(text, require_error_context=True)
|
|
841
839
|
if (
|
|
842
840
|
event_type == "message_end"
|
|
843
841
|
and isinstance(message, dict)
|
|
@@ -1017,6 +1017,31 @@ def test_progress_parser_keeps_pi_length_as_nonfatal_diagnostic_metadata():
|
|
|
1017
1017
|
assert data["terminal_success_at"]
|
|
1018
1018
|
|
|
1019
1019
|
|
|
1020
|
+
@pytest.mark.parametrize("role", ("assistant", "toolResult"))
|
|
1021
|
+
def test_progress_parser_does_not_promote_pi_diagnostic_content_to_fatal_error(role):
|
|
1022
|
+
module = _load_progress_parser_module()
|
|
1023
|
+
tracker = module.ProgressTracker()
|
|
1024
|
+
tracker.process_event({"type": "session", "version": 3, "id": "pi-session", "cwd": "/tmp/project"})
|
|
1025
|
+
tracker.process_event({"type": "agent_start"})
|
|
1026
|
+
tracker.process_event({
|
|
1027
|
+
"type": "message_end",
|
|
1028
|
+
"message": {
|
|
1029
|
+
"role": role,
|
|
1030
|
+
"content": [{
|
|
1031
|
+
"type": "text",
|
|
1032
|
+
"text": 'continuation_reason = "context_overflow"\nerror = _error_text(result)',
|
|
1033
|
+
}],
|
|
1034
|
+
"stopReason": "toolUse",
|
|
1035
|
+
},
|
|
1036
|
+
})
|
|
1037
|
+
|
|
1038
|
+
data = tracker.to_dict()
|
|
1039
|
+
|
|
1040
|
+
assert data["api_error_code"] == ""
|
|
1041
|
+
assert data["fatal_error_code"] == ""
|
|
1042
|
+
assert data["last_result_is_error"] is False
|
|
1043
|
+
|
|
1044
|
+
|
|
1020
1045
|
def test_progress_parser_recovers_from_retrying_pi_attempt_before_final_success():
|
|
1021
1046
|
module = _load_progress_parser_module()
|
|
1022
1047
|
tracker = module.ProgressTracker()
|
|
@@ -1677,6 +1702,57 @@ def test_session_persists_normalized_stream_without_raw_history(tmp_path, monkey
|
|
|
1677
1702
|
assert not backup_log.exists()
|
|
1678
1703
|
|
|
1679
1704
|
|
|
1705
|
+
def test_pi_session_diagnostic_tool_output_does_not_trigger_fatal_termination(tmp_path):
|
|
1706
|
+
import prizmkit_runtime.sessions as sessions
|
|
1707
|
+
|
|
1708
|
+
fake_cli = tmp_path / "pi_diagnostic_cli.py"
|
|
1709
|
+
fake_cli.write_text(
|
|
1710
|
+
"#!/usr/bin/env python3\n"
|
|
1711
|
+
"import json, sys, time\n"
|
|
1712
|
+
"_prompt = sys.stdin.read()\n"
|
|
1713
|
+
"source = 'continuation_reason = \\\"context_overflow\\\"\\nerror = _error_text(result)'\n"
|
|
1714
|
+
"events = [\n"
|
|
1715
|
+
" {'type':'session','id':'s1'},\n"
|
|
1716
|
+
" {'type':'agent_start'},\n"
|
|
1717
|
+
" {'type':'turn_start'},\n"
|
|
1718
|
+
" {'type':'tool_execution_start','toolCallId':'c1','toolName':'read','args':{'path':'runtime.py'}},\n"
|
|
1719
|
+
" {'type':'tool_execution_end','toolCallId':'c1','toolName':'read','result':{'content':[{'type':'text','text':source}]},'isError':False},\n"
|
|
1720
|
+
" {'type':'message_end','message':{'role':'toolResult','toolCallId':'c1','content':[{'type':'text','text':source}],'stopReason':'toolUse'}},\n"
|
|
1721
|
+
"]\n"
|
|
1722
|
+
"for event in events: print(json.dumps(event), flush=True)\n"
|
|
1723
|
+
"time.sleep(1.5)\n"
|
|
1724
|
+
"message = {'role':'assistant','content':[{'type':'text','text':'Done'}],'stopReason':'stop'}\n"
|
|
1725
|
+
"print(json.dumps({'type':'message_end','message':message}), flush=True)\n"
|
|
1726
|
+
"print(json.dumps({'type':'agent_end','willRetry':False,'messages':[message]}), flush=True)\n",
|
|
1727
|
+
encoding="utf-8",
|
|
1728
|
+
)
|
|
1729
|
+
fake_cli.chmod(0o755)
|
|
1730
|
+
prompt = tmp_path / "prompt.md"
|
|
1731
|
+
prompt.write_text("hello", encoding="utf-8")
|
|
1732
|
+
session_log = tmp_path / "state" / "sessions" / "sess-diagnostic" / "logs" / "session.log"
|
|
1733
|
+
progress = session_log.with_name("progress.json")
|
|
1734
|
+
|
|
1735
|
+
result = sessions.AISessionLauncher(
|
|
1736
|
+
sessions.AISessionConfig(
|
|
1737
|
+
cli_command=str(fake_cli),
|
|
1738
|
+
platform="pi",
|
|
1739
|
+
model=None,
|
|
1740
|
+
prompt_path=prompt,
|
|
1741
|
+
cwd=tmp_path,
|
|
1742
|
+
log_path=session_log,
|
|
1743
|
+
progress_path=progress,
|
|
1744
|
+
)
|
|
1745
|
+
).run()
|
|
1746
|
+
|
|
1747
|
+
progress_data = json.loads(progress.read_text(encoding="utf-8"))
|
|
1748
|
+
assert result.exit_code == 0
|
|
1749
|
+
assert result.fatal_error_code == ""
|
|
1750
|
+
assert result.progress_summary.result_subtype == "success"
|
|
1751
|
+
assert progress_data["fatal_error_code"] == ""
|
|
1752
|
+
assert not session_log.with_name("fatal-error.json").exists()
|
|
1753
|
+
assert not session_log.with_name("stale-kill.json").exists()
|
|
1754
|
+
|
|
1755
|
+
|
|
1680
1756
|
def test_custom_session_launch_writes_existing_logs_and_progress(tmp_path):
|
|
1681
1757
|
from prizmkit_runtime.launch_profiles import HeadlessLaunchProfile
|
|
1682
1758
|
from prizmkit_runtime.sessions import AISessionConfig, AISessionLauncher
|