frontier-council 0.1.1__py3-none-any.whl → 0.1.3__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.
@@ -1,6 +1,6 @@
1
1
  """Frontier Council - Multi-model deliberation for important decisions."""
2
2
 
3
- __version__ = "0.1.1"
3
+ __version__ = "0.1.3"
4
4
 
5
5
  from .council import (
6
6
  run_council,
frontier_council/cli.py CHANGED
@@ -4,11 +4,27 @@ import argparse
4
4
  import json
5
5
  import os
6
6
  import random
7
+ import re
7
8
  import subprocess
8
9
  import sys
9
10
  from datetime import datetime
10
11
  from pathlib import Path
11
12
 
13
+
14
+ def get_sessions_dir() -> Path:
15
+ """Get the sessions directory, creating if needed."""
16
+ sessions_dir = Path.home() / ".frontier-council" / "sessions"
17
+ sessions_dir.mkdir(parents=True, exist_ok=True)
18
+ return sessions_dir
19
+
20
+
21
+ def slugify(text: str, max_len: int = 40) -> str:
22
+ """Convert text to a filename-safe slug."""
23
+ text = text.lower()
24
+ text = re.sub(r'[^\w\s-]', '', text)
25
+ text = re.sub(r'[\s_-]+', '-', text)
26
+ return text[:max_len].strip('-')
27
+
12
28
  from .council import (
13
29
  COUNCIL,
14
30
  detect_social_context,
@@ -28,7 +44,7 @@ Examples:
28
44
  frontier-council "Architecture choice" --rounds 3 --output transcript.md
29
45
  """,
30
46
  )
31
- parser.add_argument("question", help="The question for the council to deliberate")
47
+ parser.add_argument("question", nargs="?", help="The question for the council to deliberate")
32
48
  parser.add_argument(
33
49
  "--rounds",
34
50
  type=int,
@@ -78,8 +94,37 @@ Examples:
78
94
  choices=[1, 2, 3, 4, 5],
79
95
  help="Which speaker (1-5) should be devil's advocate (default: random)",
80
96
  )
97
+ parser.add_argument(
98
+ "--no-save",
99
+ action="store_true",
100
+ help="Don't auto-save transcript to ~/.frontier-council/sessions/",
101
+ )
102
+ parser.add_argument(
103
+ "--sessions",
104
+ action="store_true",
105
+ help="List recent sessions and exit",
106
+ )
81
107
  args = parser.parse_args()
82
108
 
109
+ # Handle --sessions flag
110
+ if args.sessions:
111
+ sessions_dir = get_sessions_dir()
112
+ sessions = sorted(sessions_dir.glob("*.md"), key=lambda p: p.stat().st_mtime, reverse=True)
113
+ if not sessions:
114
+ print("No sessions found.")
115
+ else:
116
+ print(f"Sessions in {sessions_dir}:\n")
117
+ for s in sessions[:20]: # Show last 20
118
+ mtime = datetime.fromtimestamp(s.stat().st_mtime).strftime("%Y-%m-%d %H:%M")
119
+ print(f" {mtime} {s.name}")
120
+ if len(sessions) > 20:
121
+ print(f"\n ... and {len(sessions) - 20} more")
122
+ sys.exit(0)
123
+
124
+ # Require question for normal operation
125
+ if not args.question:
126
+ parser.error("the following arguments are required: question")
127
+
83
128
  # Auto-detect social context if not explicitly set
84
129
  social_mode = args.social or detect_social_context(args.question)
85
130
  if social_mode and not args.social and not args.quiet:
@@ -153,12 +198,38 @@ Examples:
153
198
  print("=" * 60)
154
199
  print()
155
200
 
156
- # Save transcript
201
+ # Save transcript to user-specified location
157
202
  if args.output:
158
203
  Path(args.output).write_text(transcript)
159
204
  if not args.quiet:
160
205
  print(f"Transcript saved to: {args.output}")
161
206
 
207
+ # Auto-save to sessions directory
208
+ session_path = None
209
+ if not args.no_save:
210
+ timestamp = datetime.now().strftime("%Y%m%d-%H%M%S")
211
+ slug = slugify(args.question)
212
+ filename = f"{timestamp}-{slug}.md"
213
+ session_path = get_sessions_dir() / filename
214
+
215
+ # Build full session content with metadata header
216
+ session_content = f"""# Council Session
217
+
218
+ **Question:** {args.question}
219
+ **Date:** {datetime.now().strftime("%Y-%m-%d %H:%M")}
220
+ **Rounds:** {args.rounds}
221
+ **Mode:** {"named" if args.named else "anonymous"}, {"blind" if use_blind else "no blind"}{", social" if social_mode else ""}
222
+ {f"**Context:** {args.context}" if args.context else ""}
223
+ {f"**Persona:** {args.persona}" if args.persona else ""}
224
+
225
+ ---
226
+
227
+ {transcript}
228
+ """
229
+ session_path.write_text(session_content)
230
+ if not args.quiet:
231
+ print(f"Session saved to: {session_path}")
232
+
162
233
  # Share via gist
163
234
  gist_url = None
164
235
  if args.share:
@@ -190,10 +261,11 @@ Examples:
190
261
  print("Error: 'gh' CLI not found. Install with: brew install gh", file=sys.stderr)
191
262
 
192
263
  # Log to history
193
- history_file = Path(__file__).parent.parent / "council_history.jsonl"
264
+ history_file = get_sessions_dir().parent / "history.jsonl"
194
265
  log_entry = {
195
266
  "timestamp": datetime.now().isoformat(),
196
267
  "question": args.question[:200],
268
+ "session": str(session_path) if session_path else None,
197
269
  "gist": gist_url,
198
270
  "context": args.context,
199
271
  "rounds": args.rounds,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: frontier-council
3
- Version: 0.1.1
3
+ Version: 0.1.3
4
4
  Summary: Multi-model deliberation for important decisions. 5 frontier LLMs debate, then a judge synthesizes consensus.
5
5
  Project-URL: Homepage, https://github.com/terry-li-hm/frontier-council
6
6
  Project-URL: Repository, https://github.com/terry-li-hm/frontier-council
@@ -80,8 +80,13 @@ frontier-council "Career question" --output transcript.md
80
80
 
81
81
  # Share via GitHub Gist
82
82
  frontier-council "Important decision" --share
83
+
84
+ # List past sessions
85
+ frontier-council --sessions
83
86
  ```
84
87
 
88
+ All sessions are auto-saved to `~/.frontier-council/sessions/` for later review.
89
+
85
90
  ## Options
86
91
 
87
92
  | Flag | Description |
@@ -96,6 +101,8 @@ frontier-council "Important decision" --share
96
101
  | `--persona TEXT` | Context about the person asking |
97
102
  | `--advocate N` | Which speaker (1-5) should be devil's advocate (default: random) |
98
103
  | `--quiet` | Suppress progress output |
104
+ | `--sessions` | List recent saved sessions |
105
+ | `--no-save` | Don't auto-save transcript to ~/.frontier-council/sessions/ |
99
106
 
100
107
  ## How It Works
101
108
 
@@ -0,0 +1,8 @@
1
+ frontier_council/__init__.py,sha256=lJJIdVKStG2zLYlKMtvIpxK3S2D0NsWK_ZIKc86y2VM,357
2
+ frontier_council/cli.py,sha256=JQ_4Hd5vqALEbLBA4madX9u5PN7oLy59MjmSfveiNV4,9925
3
+ frontier_council/council.py,sha256=u2ir34dNostBOhXUi1R0wFEfBIEgiRX8thiS5lRFnnU,30226
4
+ frontier_council-0.1.3.dist-info/METADATA,sha256=x3rZJOZpRNikTs8DOVwiHA4w7G4V_p4dvEYSNfnowvA,5229
5
+ frontier_council-0.1.3.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
6
+ frontier_council-0.1.3.dist-info/entry_points.txt,sha256=I3xjPK-nupfQz5PANVXUnXjuxlP-4-mykkA3wXhFOGY,63
7
+ frontier_council-0.1.3.dist-info/licenses/LICENSE,sha256=8qmwox7khp-AakNVvL-Ga25eYbsCtLx8RyXM4zKkX0w,1065
8
+ frontier_council-0.1.3.dist-info/RECORD,,
@@ -1,8 +0,0 @@
1
- frontier_council/__init__.py,sha256=E9pFFmwBgrMqWytSCigjEnJ6sI_NpufL3FvXaYCnW1A,357
2
- frontier_council/cli.py,sha256=BbM1cHWjAA0DBn4uyGKajaNAMxhKYQt-ZGNQ6hTnlkc,7337
3
- frontier_council/council.py,sha256=u2ir34dNostBOhXUi1R0wFEfBIEgiRX8thiS5lRFnnU,30226
4
- frontier_council-0.1.1.dist-info/METADATA,sha256=43yN-RjPztdcYqeuyljSt96KboV36tjOqCn3J70RPik,4973
5
- frontier_council-0.1.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
6
- frontier_council-0.1.1.dist-info/entry_points.txt,sha256=I3xjPK-nupfQz5PANVXUnXjuxlP-4-mykkA3wXhFOGY,63
7
- frontier_council-0.1.1.dist-info/licenses/LICENSE,sha256=8qmwox7khp-AakNVvL-Ga25eYbsCtLx8RyXM4zKkX0w,1065
8
- frontier_council-0.1.1.dist-info/RECORD,,