Skip to content

Commit e4a4160

Browse files
committed
fix(skill): persist result_urls to local for offline recovery
- Extend _save_session to store result_urls and completed_at - Save results locally on completion in wait-and-deliver, query-session, tasks, recover - Recover reads completed sessions from local (no API call), only checks pending via API - Reduces hallucination: agent can always find video URLs from local file
1 parent e58b193 commit e4a4160

1 file changed

Lines changed: 76 additions & 8 deletions

File tree

β€Žapps/desktop/static/bundled-skills/libtv-video/scripts/libtv_video.pyβ€Ž

Lines changed: 76 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -67,22 +67,32 @@ def _load_sessions():
6767
with open(path, "r") as f:
6868
return json.load(f)
6969

70-
def _save_session(session_id, project_uuid="", status="active", text=""):
70+
def _save_session(session_id, project_uuid="", status="active", text="",
71+
result_urls=None, completed_at=""):
7172
sessions = _load_sessions()
7273
for s in sessions:
7374
if s["session_id"] == session_id:
7475
s["status"] = status
7576
if project_uuid:
7677
s["project_uuid"] = project_uuid
78+
if result_urls:
79+
s["result_urls"] = result_urls
80+
if completed_at:
81+
s["completed_at"] = completed_at
7782
break
7883
else:
79-
sessions.append({
84+
entry = {
8085
"session_id": session_id,
8186
"project_uuid": project_uuid,
8287
"status": status,
8388
"text": text[:80],
8489
"created_at": datetime.now().isoformat(),
85-
})
90+
}
91+
if result_urls:
92+
entry["result_urls"] = result_urls
93+
if completed_at:
94+
entry["completed_at"] = completed_at
95+
sessions.append(entry)
8696
sessions = sessions[-50:]
8797
path = _sessions_file_path()
8898
os.makedirs(os.path.dirname(path), exist_ok=True)
@@ -396,6 +406,11 @@ def cmd_query_session(args):
396406
# Extract result URLs
397407
urls = extract_result_urls(messages)
398408

409+
# Persist results to local so recover can read without API
410+
if urls:
411+
_save_session(session_id, project_uuid=args.project_id or "", status="completed",
412+
result_urls=urls, completed_at=datetime.now().isoformat())
413+
399414
out = {"messages": messages}
400415
if args.project_id:
401416
out["projectUrl"] = f"{PROJECT_CANVAS_BASE}{args.project_id}"
@@ -463,7 +478,8 @@ def cmd_wait_and_deliver(args):
463478
urls = extract_result_urls(messages)
464479

465480
if urls:
466-
_save_session(session_id, project_uuid=project_uuid, status="completed")
481+
_save_session(session_id, project_uuid=project_uuid, status="completed",
482+
result_urls=urls, completed_at=datetime.now().isoformat())
467483
deliver_results(urls, project_uuid=project_uuid)
468484

469485
# Auto-download
@@ -496,12 +512,58 @@ def cmd_wait_and_deliver(args):
496512

497513

498514
def cmd_recover(args):
499-
pending = _get_pending_sessions()
515+
sessions = _load_sessions()
516+
if not sessions:
517+
print("No sessions found.")
518+
return
519+
520+
# Show completed sessions from local (no API call needed)
521+
completed = [s for s in sessions if s["status"] in ("completed", "failed", "timeout")]
522+
pending = [s for s in sessions if s["status"] not in ("completed", "failed", "timeout")]
523+
524+
if completed:
525+
print(f"πŸ“‹ {len(completed)} completed session(s) (from local):")
526+
for s in completed[-10:]:
527+
sid = s["session_id"]
528+
project_uuid = s.get("project_uuid", "")
529+
local_urls = s.get("result_urls", [])
530+
status = s["status"]
531+
text = s.get("text", "")
532+
533+
if status == "completed" and local_urls:
534+
print(f" βœ… {sid[:16]}... Completed ({text})")
535+
for url in local_urls:
536+
print(f" 🎬 {url}")
537+
if project_uuid:
538+
print(f" 🎨 Canvas: {PROJECT_CANVAS_BASE}{project_uuid}")
539+
elif status == "failed":
540+
print(f" ❌ {sid[:16]}... Failed ({text})")
541+
elif status == "timeout":
542+
print(f" ⏰ {sid[:16]}... Timeout ({text})")
543+
else:
544+
# Completed but no local URLs β€” re-fetch once
545+
try:
546+
result = call_gateway("GET", f"/libtv/v1/session/{sid}")
547+
messages = result.get("messages") or []
548+
urls = extract_result_urls(messages)
549+
if urls:
550+
_save_session(sid, project_uuid=project_uuid, status="completed",
551+
result_urls=urls, completed_at=datetime.now().isoformat())
552+
print(f" βœ… {sid[:16]}... Completed ({text})")
553+
for url in urls:
554+
print(f" 🎬 {url}")
555+
else:
556+
print(f" βœ… {sid[:16]}... Completed, no result URLs ({text})")
557+
except Exception as e:
558+
print(f" βœ… {sid[:16]}... Completed, fetch error: {e}")
559+
500560
if not pending:
501-
print("No pending sessions found.")
561+
if not completed:
562+
print("No sessions found.")
502563
return
503564

504-
print(f"Found {len(pending)} pending session(s):")
565+
# Check pending sessions via API
566+
print(f"\nπŸ” {len(pending)} pending session(s) (checking API...):")
505567
for s in pending:
506568
sid = s["session_id"]
507569
project_uuid = s.get("project_uuid", "")
@@ -513,7 +575,8 @@ def cmd_recover(args):
513575
urls = extract_result_urls(messages)
514576

515577
if urls:
516-
_save_session(sid, project_uuid=project_uuid, status="completed")
578+
_save_session(sid, project_uuid=project_uuid, status="completed",
579+
result_urls=urls, completed_at=datetime.now().isoformat())
517580
print(f" βœ… {sid[:16]}... Completed!")
518581
for url in urls:
519582
print(f" 🎬 {url}")
@@ -544,6 +607,11 @@ def cmd_tasks(args):
544607
video_url = t.get("video_url")
545608
error = t.get("error_message")
546609

610+
# Persist completed task results to local for offline recovery
611+
if status == "completed" and video_url:
612+
_save_session(tid, status="completed",
613+
result_urls=[video_url], completed_at=completed or "")
614+
547615
status_icon = {
548616
"completed": "βœ…", "failed": "❌", "composing": "⏳",
549617
"rendering": "⏳", "pending": "πŸ”„",

0 commit comments

Comments
Β (0)