yaicli 0.3.3__py3-none-any.whl → 0.5.0__py3-none-any.whl

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.
yaicli/roles.py DELETED
@@ -1,248 +0,0 @@
1
- import json
2
- from pathlib import Path
3
- from typing import Any, Dict, Optional, Union
4
-
5
- import typer
6
- from rich.console import Console
7
- from rich.prompt import Prompt
8
- from rich.table import Table
9
-
10
- from yaicli.config import cfg
11
- from yaicli.console import get_console
12
- from yaicli.const import DEFAULT_ROLES, ROLES_DIR, DefaultRoleNames
13
- from yaicli.exceptions import RoleAlreadyExistsError, RoleCreationError
14
- from yaicli.utils import detect_os, detect_shell, option_callback
15
-
16
-
17
- class Role:
18
- def __init__(
19
- self, name: str, prompt: str, variables: Optional[Dict[str, Any]] = None, filepath: Optional[str] = None
20
- ):
21
- self.name = name
22
- self.prompt = prompt
23
- if not variables:
24
- variables = {"_os": detect_os(cfg), "_shell": detect_shell(cfg)}
25
- self.variables = variables
26
- self.filepath = filepath
27
-
28
- self.prompt = self.prompt.format(**self.variables)
29
-
30
- def to_dict(self) -> Dict[str, Any]:
31
- """Convert Role to dictionary for serialization"""
32
- return {
33
- "name": self.name,
34
- "prompt": self.prompt,
35
- }
36
-
37
- @classmethod
38
- def from_dict(cls, role_id: str, data: Dict[str, Any], filepath: Optional[str] = None) -> "Role":
39
- """Create Role object from dictionary"""
40
- return cls(
41
- name=data.get("name", role_id),
42
- prompt=data.get("prompt", ""),
43
- variables=data.get("variables", {}),
44
- filepath=filepath,
45
- )
46
-
47
- def __str__(self):
48
- return f"Role(name={self.name}, prompt={self.prompt[:30]}...)"
49
-
50
-
51
- class RoleManager:
52
- roles_dir: Path = ROLES_DIR
53
- console: Console = get_console()
54
-
55
- def __init__(self):
56
- self.roles: Dict[str, Role] = self._load_roles()
57
-
58
- def _load_roles(self) -> Dict[str, Role]:
59
- """Load all role configurations"""
60
- roles = {}
61
- self.roles_dir.mkdir(parents=True, exist_ok=True)
62
-
63
- # Check if any role files exist
64
- role_files: list[Path] = list(self.roles_dir.glob("*.json"))
65
-
66
- if not role_files:
67
- # Fast path: no existing roles, just create defaults
68
- for role_id, role_config in DEFAULT_ROLES.items():
69
- role_file = self.roles_dir / f"{role_id}.json"
70
- filepath = str(role_file)
71
- roles[role_id] = Role.from_dict(role_id, role_config, filepath)
72
- with role_file.open("w", encoding="utf-8") as f:
73
- json.dump(role_config, f, indent=2)
74
- return roles
75
-
76
- # Load existing role files
77
- for role_file in role_files:
78
- role_id = role_file.stem
79
- filepath = str(role_file)
80
- try:
81
- with role_file.open("r", encoding="utf-8") as f:
82
- role_data = json.load(f)
83
- roles[role_id] = Role.from_dict(role_id, role_data, filepath)
84
- except Exception as e:
85
- self.console.print(f"Error loading role {role_id}: {e}", style="red")
86
-
87
- # Ensure default roles exist
88
- for role_id, role_config in DEFAULT_ROLES.items():
89
- if role_id not in roles:
90
- role_file = self.roles_dir / f"{role_id}.json"
91
- filepath = str(role_file)
92
- roles[role_id] = Role.from_dict(role_id, role_config, filepath)
93
- with role_file.open("w", encoding="utf-8") as f:
94
- json.dump(role_config, f, indent=2)
95
-
96
- return roles
97
-
98
- @classmethod
99
- @option_callback
100
- def print_list_option(cls, _: Any):
101
- """Print the list of roles.
102
- This method is a cli option callback.
103
- """
104
- table = Table(show_header=True, show_footer=False)
105
- table.add_column("Name", style="dim")
106
- table.add_column("Filepath", style="dim")
107
- for file in sorted(cls.roles_dir.glob("*.json"), key=lambda f: f.stat().st_mtime):
108
- table.add_row(file.stem, str(file))
109
- cls.console.print(table)
110
- cls.console.print("Use `ai --show-role <name>` to view a role.", style="dim")
111
-
112
- def list_roles(self) -> list:
113
- """List all available roles info"""
114
- roles_list = []
115
- for role_id, role in sorted(self.roles.items()):
116
- roles_list.append(
117
- {
118
- "id": role_id,
119
- "name": role.name,
120
- "prompt": role.prompt,
121
- "is_default": role_id in DEFAULT_ROLES,
122
- "filepath": role.filepath,
123
- }
124
- )
125
- return roles_list
126
-
127
- @classmethod
128
- @option_callback
129
- def show_role_option(cls, name: str):
130
- """Show a role's prompt.
131
- This method is a cli option callback.
132
- """
133
- self = cls()
134
- role = self.get_role(name)
135
- if not role:
136
- self.console.print(f"Role '{name}' does not exist", style="red")
137
- return
138
- self.console.print(role.prompt)
139
-
140
- def get_role(self, role_id: str) -> Optional[Role]:
141
- """Get role by ID"""
142
- return self.roles.get(role_id)
143
-
144
- @classmethod
145
- def check_id_ok(cls, role_id: str):
146
- """Check if role exists by ID.
147
- This method is a cli option callback.
148
- If role does not exist, exit with error.
149
- """
150
- if not role_id:
151
- return role_id
152
- self = cls()
153
- if not self.role_exists(role_id):
154
- self.console.print(f"Role '{role_id}' does not exist", style="red")
155
- raise typer.Abort()
156
- return role_id
157
-
158
- def role_exists(self, role_id: str) -> bool:
159
- """Check if role exists"""
160
- return role_id in self.roles
161
-
162
- def save_role(self, role_id: str, role: Role) -> None:
163
- """Save role configuration"""
164
- try:
165
- self.roles[role_id] = role
166
- role_file = self.roles_dir / f"{role_id}.json"
167
- role.filepath = str(role_file)
168
- with role_file.open("w", encoding="utf-8") as f:
169
- json.dump(role.to_dict(), f, indent=2)
170
- except Exception as e:
171
- raise RoleCreationError(f"RoleCreationError {e}") from e
172
-
173
- @classmethod
174
- @option_callback
175
- def create_role_option(cls, name: str):
176
- """Create a new role and save it to file.
177
- This method is a cli option callback.
178
- """
179
- self = cls()
180
- if name in self.roles:
181
- self.console.print(f"Role '{name}' already exists", style="yellow")
182
- return
183
- description = Prompt.ask("Enter role description")
184
-
185
- # Format the prompt as "You are {role_id}, {description}"
186
- prompt = f"You are {name}, {description}"
187
-
188
- role = Role(name=name, prompt=prompt)
189
- self.create_role(name, role)
190
- self.console.print(f"Role '{name}' created successfully", style="green")
191
-
192
- def create_role(self, role_id: str, role: Union[Role, Dict[str, Any]]) -> None:
193
- """Create a new role and save it to file"""
194
- if role_id in self.roles:
195
- raise RoleAlreadyExistsError(f"Role '{role_id}' already exists")
196
- if isinstance(role, dict):
197
- if "name" not in role or "prompt" not in role:
198
- raise RoleCreationError("Role must have 'name' and 'prompt' keys")
199
- # Convert dict to Role object
200
- role = Role.from_dict(role_id, role)
201
- self.save_role(role_id, role)
202
-
203
- @classmethod
204
- @option_callback
205
- def delete_role_option(cls, name: str):
206
- """Delete a role and its file.
207
- This method is a cli option callback.
208
- """
209
- self = cls()
210
- if self.delete_role(name):
211
- self.console.print(f"Role '{name}' deleted successfully", style="green")
212
-
213
- def delete_role(self, role_id: str) -> bool:
214
- """Delete a role and its file"""
215
- if role_id not in self.roles:
216
- self.console.print(f"Role '{role_id}' does not exist", style="red")
217
- return False
218
-
219
- # Don't allow deleting default roles
220
- if role_id in DEFAULT_ROLES:
221
- self.console.print(f"Cannot delete default role: '{role_id}'", style="red")
222
- return False
223
-
224
- try:
225
- role = self.roles[role_id]
226
- if role.filepath:
227
- Path(role.filepath).unlink(missing_ok=True)
228
- del self.roles[role_id]
229
- return True
230
- except Exception as e:
231
- self.console.print(f"Error deleting role: {e}", style="red")
232
- return False
233
-
234
- def get_system_prompt(self, role_id: str) -> str:
235
- """Get prompt from file by role ID"""
236
- role = self.get_role(role_id)
237
- if not role:
238
- # Fall back to default role if specified role doesn't exist
239
- self.console.print(f"Role {role_id} not found, using default role", style="yellow")
240
- role = self.get_role(DefaultRoleNames.DEFAULT)
241
- if not role:
242
- # Last resort fallback
243
- default_config = DEFAULT_ROLES[DefaultRoleNames.DEFAULT]
244
- role = Role.from_dict(DefaultRoleNames.DEFAULT, default_config)
245
-
246
- # Create a copy of the role with system variables
247
- system_role = Role(name=role.name, prompt=role.prompt)
248
- return system_role.prompt
@@ -1,20 +0,0 @@
1
- pyproject.toml,sha256=gRdPPzuSEyfEEyHQ4TuoHqxrrkFhWGC9BXWY4XuOb7E,1519
2
- yaicli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- yaicli/api.py,sha256=9kRozzxBKduQsda3acnxzvOD9wRLL0cH182L4ddHY8E,13666
4
- yaicli/chat_manager.py,sha256=I7BAMz91FLYT6x69wbomtAGLx0WsoTwS4Wo0MgP6P9I,10644
5
- yaicli/cli.py,sha256=mw4aeDAEcD0KvbbOxPuripqCY17vEmIeuT2ZcWjK92o,22795
6
- yaicli/config.py,sha256=xtzgXApM93zCqSUxmVSBdph0co_NKfEUU3hWtPe8qvM,6236
7
- yaicli/console.py,sha256=291F4hGksJtxYpg_mehepCIJ-eB2MaDNIyv1JAMgJ1Y,1985
8
- yaicli/const.py,sha256=iOQNG6M4EBmKgbwZdNqRsHrcQ7Od1nKOyLAqUhfMEBM,7020
9
- yaicli/entry.py,sha256=Yp0Z--x-7dowrz-h8hJJ4_BoCzuDjS11NcM8YgFzUoY,7460
10
- yaicli/exceptions.py,sha256=ndedSdE0uaxxHrWN944BkbhMfRMSMxGDfmqmCKCGJco,924
11
- yaicli/history.py,sha256=s-57X9FMsaQHF7XySq1gGH_jpd_cHHTYafYu2ECuG6M,2472
12
- yaicli/printer.py,sha256=nXpralD5qZJQga3OTdEPhj22g7UoF-4mJbZeOtWXojo,12430
13
- yaicli/render.py,sha256=mB1OT9859_PTwI9f-KY802lPaeQXKRw6ls_5jN21jWc,511
14
- yaicli/roles.py,sha256=bhXpLnGTPRZp3-K1Tt6ppTsuG2v9S0RAXikfMFhDs_U,9144
15
- yaicli/utils.py,sha256=MLvb-C5n19AD9Z1nW4Z3Z43ZKNH8STxQmNDnL7mq26E,4490
16
- yaicli-0.3.3.dist-info/METADATA,sha256=CdEkOsFz76sEp75xvEf6lVFNAx7U7ff_yylLP-0ETRc,45320
17
- yaicli-0.3.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
18
- yaicli-0.3.3.dist-info/entry_points.txt,sha256=iMhGm3btBaqrknQoF6WCg5sdx69ZyNSC73tRpCcbcLw,63
19
- yaicli-0.3.3.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
20
- yaicli-0.3.3.dist-info/RECORD,,
File without changes