@@ -614,10 +614,147 @@
614 614 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
import traceback
615 615 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
616 616 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
traceback.print_exc()
617 617 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
sys.exit(1)
618 618 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
619 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
620 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ @cli.command()
621 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ @click.argument("request", required=False, default=None)
622 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ @click.option("--kb", multiple=True, type=click.Path(exists=True), help="Knowledge base paths")
623 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ @click.option("--interactive", "-I", is_flag=True, help="Interactive chat mode")
624 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ @click.option("--export", type=click.Path(), default=None, help="Export artifacts to directory")
625 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ @click.option(
626 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "--provider",
627 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "-p",
628 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ type=click.Choice(
629 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ [
630 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "auto",
631 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "openai",
632 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "anthropic",
633 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "gemini",
634 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "ollama",
635 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "azure",
636 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "together",
637 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "fireworks",
638 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "cerebras",
639 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "xai",
640 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ]
641 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ),
642 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ default="auto",
643 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ help="API provider",
644 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ )
645 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ @click.option("--chat-model", type=str, default=None, help="Override model for LLM/chat tasks")
646 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ @click.pass_context
647 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def agent(ctx, request, kb, interactive, export, provider, chat_model):
648 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ """AI planning agent. Synthesizes knowledge into project plans and artifacts.
649 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
650 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ Examples:
651 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
652 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ planopticon agent "Create a project plan" --kb ./results
653 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
654 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ planopticon agent -I --kb ./videos --kb ./docs
655 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
656 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ planopticon agent "Generate a PRD" --export ./output
657 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ """
658 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ from video_processor.agent.agent_loop import PlanningAgent
659 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ from video_processor.agent.kb_context import KBContext
660 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ from video_processor.agent.skills.base import AgentContext
661 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
662 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # Build provider manager
663 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ pm = None
664 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ try:
665 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ from video_processor.providers.manager import ProviderManager
666 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
667 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ prov = None if provider == "auto" else provider
668 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ pm = ProviderManager(chat_model=chat_model, provider=prov)
669 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ except Exception:
670 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if not interactive:
671 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ click.echo("Warning: could not initialize LLM provider.", err=True)
672 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
673 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # Load knowledge base
674 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ kb_ctx = KBContext()
675 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if kb:
676 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ for path in kb:
677 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ kb_ctx.add_source(Path(path))
678 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ kb_ctx.load(provider_manager=pm)
679 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ click.echo(kb_ctx.summary())
680 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ else:
681 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # Auto-discover
682 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ kb_ctx = KBContext.auto_discover(provider_manager=pm)
683 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if kb_ctx.sources:
684 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ click.echo(kb_ctx.summary())
685 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ else:
686 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ click.echo("No knowledge base found. Use --kb to specify paths.")
687 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
688 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ agent_inst = PlanningAgent(
689 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ context=AgentContext(
690 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ knowledge_graph=kb_ctx.knowledge_graph if kb_ctx.sources else None,
691 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ query_engine=kb_ctx.query_engine if kb_ctx.sources else None,
692 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ provider_manager=pm,
693 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ )
694 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ )
695 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
696 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if interactive:
697 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ click.echo("\nPlanOpticon Agent (interactive mode)")
698 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ click.echo("Type your request, or 'quit' to exit.\n")
699 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ while True:
700 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ try:
701 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ line = click.prompt("agent", prompt_suffix="> ")
702 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ except (KeyboardInterrupt, EOFError):
703 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ click.echo("\nBye.")
704 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ break
705 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if line.strip().lower() in ("quit", "exit", "q"):
706 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ click.echo("Bye.")
707 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ break
708 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
709 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # Check for slash commands
710 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if line.strip().startswith("/"):
711 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ cmd = line.strip()[1:].split()[0]
712 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if cmd == "plan":
713 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ artifacts = agent_inst.execute("Generate a project plan")
714 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ elif cmd == "skills":
715 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ from video_processor.agent.skills.base import list_skills
716 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
717 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ for s in list_skills():
718 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ click.echo(f" {s.name}: {s.description}")
719 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ continue
720 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ elif cmd == "summary":
721 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if kb_ctx.sources:
722 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ click.echo(kb_ctx.summary())
723 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ continue
724 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ else:
725 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ artifacts = agent_inst.execute(line.strip()[1:])
726 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
727 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ for a in artifacts:
728 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ click.echo(f"\n--- {a.name} ({a.artifact_type}) ---\n")
729 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ click.echo(a.content)
730 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ else:
731 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ response = agent_inst.chat(line)
732 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ click.echo(f"\n{response}\n")
733 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ elif request:
734 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ artifacts = agent_inst.execute(request)
735 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if not artifacts:
736 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ click.echo("No artifacts generated. Try a more specific request.")
737 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ for artifact in artifacts:
738 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ click.echo(f"\n--- {artifact.name} ({artifact.artifact_type}) ---\n")
739 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ click.echo(artifact.content)
740 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
741 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if export:
742 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ export_dir = Path(export)
743 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ export_dir.mkdir(parents=True, exist_ok=True)
744 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ for artifact in artifacts:
745 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ext = ".md" if artifact.format == "markdown" else f".{artifact.format}"
746 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ safe_name = "".join(
747 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ c if c.isalnum() or c in "-_" else "_" for c in artifact.name
748 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ )
749 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ fpath = export_dir / f"{safe_name}{ext}"
750 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ fpath.write_text(artifact.content)
751 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ click.echo(f"Exported: {fpath}")
752 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ else:
753 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ click.echo("Provide a request or use -I for interactive mode.")
754 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ click.echo("Example: planopticon agent 'Create a project plan' --kb ./results")
755 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
619 756 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
620 757 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
@cli.command()
621 758 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
@click.argument("question", required=False, default=None)
622 759 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
@click.option(
623 760 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
"--db-path",
624 761 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!