1#![doc = include_str!("../README.md")]
2
3pub mod derive;
4pub mod error;
5pub mod io;
6pub mod paths;
7pub mod provider;
8pub mod reader;
9pub mod types;
10
11pub use derive::{derive_graph, derive_path, derive_project};
12pub use error::{PiError, Result};
13pub use paths::PathResolver;
14pub use provider::session_to_view;
15pub use reader::{PiSession, SessionMeta};
16pub use toolpath_convo::DeriveConfig;
17pub use types::{
18 AgentMessage, ContentBlock, CostBreakdown, Entry, EntryBase, SessionHeader, Usage,
19};
20
21use toolpath_convo::ConversationView;
22
23#[derive(Debug, Clone, Default)]
25pub struct PiConvo {
26 resolver: PathResolver,
27}
28
29impl PiConvo {
30 pub fn new() -> Self {
32 Self {
33 resolver: PathResolver::new(),
34 }
35 }
36
37 pub fn with_resolver(resolver: PathResolver) -> Self {
39 Self { resolver }
40 }
41
42 pub fn resolver(&self) -> &PathResolver {
44 &self.resolver
45 }
46
47 pub fn exists(&self) -> bool {
49 self.resolver.sessions_dir().exists()
50 }
51
52 pub fn list_projects(&self) -> Result<Vec<String>> {
54 io::list_projects(&self.resolver)
55 }
56
57 pub fn list_sessions(&self, project: &str) -> Result<Vec<SessionMeta>> {
59 io::list_sessions(&self.resolver, project)
60 }
61
62 pub fn read_session(&self, project: &str, session_id: &str) -> Result<PiSession> {
64 reader::read_session(&self.resolver, project, session_id)
65 }
66
67 pub fn most_recent_session(&self, project: &str) -> Result<Option<PiSession>> {
69 let mut metas = self.list_sessions(project)?;
70 if let Some(meta) = metas.drain(..).next() {
71 let session = self.read_session(project, &meta.id)?;
72 Ok(Some(session))
73 } else {
74 Ok(None)
75 }
76 }
77
78 pub fn to_view(&self, session: &PiSession) -> ConversationView {
80 provider::session_to_view(session)
81 }
82
83 pub fn read_all_sessions(&self, project: &str) -> Result<Vec<PiSession>> {
85 let metas = self.list_sessions(project)?;
86 let mut sessions = Vec::new();
87 for meta in metas {
88 match self.read_session(project, &meta.id) {
89 Ok(s) => sessions.push(s),
90 Err(e) => {
91 eprintln!("Warning: failed to read Pi session {}: {}", meta.id, e);
92 }
93 }
94 }
95 Ok(sessions)
96 }
97}