frontier-council 0.1.0__py3-none-any.whl → 0.1.2__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.
- frontier_council/__init__.py +1 -1
- frontier_council/cli.py +70 -2
- {frontier_council-0.1.0.dist-info → frontier_council-0.1.2.dist-info}/METADATA +12 -2
- frontier_council-0.1.2.dist-info/RECORD +8 -0
- frontier_council-0.1.2.dist-info/licenses/LICENSE +21 -0
- frontier_council-0.1.0.dist-info/RECORD +0 -7
- {frontier_council-0.1.0.dist-info → frontier_council-0.1.2.dist-info}/WHEEL +0 -0
- {frontier_council-0.1.0.dist-info → frontier_council-0.1.2.dist-info}/entry_points.txt +0 -0
frontier_council/__init__.py
CHANGED
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,
|
|
@@ -78,8 +94,33 @@ 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
|
+
|
|
83
124
|
# Auto-detect social context if not explicitly set
|
|
84
125
|
social_mode = args.social or detect_social_context(args.question)
|
|
85
126
|
if social_mode and not args.social and not args.quiet:
|
|
@@ -153,12 +194,38 @@ Examples:
|
|
|
153
194
|
print("=" * 60)
|
|
154
195
|
print()
|
|
155
196
|
|
|
156
|
-
# Save transcript
|
|
197
|
+
# Save transcript to user-specified location
|
|
157
198
|
if args.output:
|
|
158
199
|
Path(args.output).write_text(transcript)
|
|
159
200
|
if not args.quiet:
|
|
160
201
|
print(f"Transcript saved to: {args.output}")
|
|
161
202
|
|
|
203
|
+
# Auto-save to sessions directory
|
|
204
|
+
session_path = None
|
|
205
|
+
if not args.no_save:
|
|
206
|
+
timestamp = datetime.now().strftime("%Y%m%d-%H%M%S")
|
|
207
|
+
slug = slugify(args.question)
|
|
208
|
+
filename = f"{timestamp}-{slug}.md"
|
|
209
|
+
session_path = get_sessions_dir() / filename
|
|
210
|
+
|
|
211
|
+
# Build full session content with metadata header
|
|
212
|
+
session_content = f"""# Council Session
|
|
213
|
+
|
|
214
|
+
**Question:** {args.question}
|
|
215
|
+
**Date:** {datetime.now().strftime("%Y-%m-%d %H:%M")}
|
|
216
|
+
**Rounds:** {args.rounds}
|
|
217
|
+
**Mode:** {"named" if args.named else "anonymous"}, {"blind" if use_blind else "no blind"}{", social" if social_mode else ""}
|
|
218
|
+
{f"**Context:** {args.context}" if args.context else ""}
|
|
219
|
+
{f"**Persona:** {args.persona}" if args.persona else ""}
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
{transcript}
|
|
224
|
+
"""
|
|
225
|
+
session_path.write_text(session_content)
|
|
226
|
+
if not args.quiet:
|
|
227
|
+
print(f"Session saved to: {session_path}")
|
|
228
|
+
|
|
162
229
|
# Share via gist
|
|
163
230
|
gist_url = None
|
|
164
231
|
if args.share:
|
|
@@ -190,10 +257,11 @@ Examples:
|
|
|
190
257
|
print("Error: 'gh' CLI not found. Install with: brew install gh", file=sys.stderr)
|
|
191
258
|
|
|
192
259
|
# Log to history
|
|
193
|
-
history_file =
|
|
260
|
+
history_file = get_sessions_dir().parent / "history.jsonl"
|
|
194
261
|
log_entry = {
|
|
195
262
|
"timestamp": datetime.now().isoformat(),
|
|
196
263
|
"question": args.question[:200],
|
|
264
|
+
"session": str(session_path) if session_path else None,
|
|
197
265
|
"gist": gist_url,
|
|
198
266
|
"context": args.context,
|
|
199
267
|
"rounds": args.rounds,
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: frontier-council
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: Multi-model deliberation for important decisions. 5 frontier LLMs debate, then a judge synthesizes consensus.
|
|
5
|
-
Project-URL: Homepage, https://github.com/terry-li-hm/
|
|
5
|
+
Project-URL: Homepage, https://github.com/terry-li-hm/frontier-council
|
|
6
|
+
Project-URL: Repository, https://github.com/terry-li-hm/frontier-council
|
|
7
|
+
Project-URL: Issues, https://github.com/terry-li-hm/frontier-council/issues
|
|
6
8
|
Author-email: Terry Li <terry.li.hm@gmail.com>
|
|
7
9
|
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
8
11
|
Keywords: ai,council,debate,deliberation,frontier,llm,multi-model,openrouter
|
|
9
12
|
Classifier: Development Status :: 4 - Beta
|
|
10
13
|
Classifier: Environment :: Console
|
|
@@ -77,8 +80,13 @@ frontier-council "Career question" --output transcript.md
|
|
|
77
80
|
|
|
78
81
|
# Share via GitHub Gist
|
|
79
82
|
frontier-council "Important decision" --share
|
|
83
|
+
|
|
84
|
+
# List past sessions
|
|
85
|
+
frontier-council --sessions
|
|
80
86
|
```
|
|
81
87
|
|
|
88
|
+
All sessions are auto-saved to `~/.frontier-council/sessions/` for later review.
|
|
89
|
+
|
|
82
90
|
## Options
|
|
83
91
|
|
|
84
92
|
| Flag | Description |
|
|
@@ -93,6 +101,8 @@ frontier-council "Important decision" --share
|
|
|
93
101
|
| `--persona TEXT` | Context about the person asking |
|
|
94
102
|
| `--advocate N` | Which speaker (1-5) should be devil's advocate (default: random) |
|
|
95
103
|
| `--quiet` | Suppress progress output |
|
|
104
|
+
| `--sessions` | List recent saved sessions |
|
|
105
|
+
| `--no-save` | Don't auto-save transcript to ~/.frontier-council/sessions/ |
|
|
96
106
|
|
|
97
107
|
## How It Works
|
|
98
108
|
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
frontier_council/__init__.py,sha256=VAITtl8rVW6wSN4iN86TVOmB2D2nrGu8ZI9ezDnOL3I,357
|
|
2
|
+
frontier_council/cli.py,sha256=9ZJgdFXHSgFDACf30veWb3uHruxlueVQY-N8hHSJL9M,9772
|
|
3
|
+
frontier_council/council.py,sha256=u2ir34dNostBOhXUi1R0wFEfBIEgiRX8thiS5lRFnnU,30226
|
|
4
|
+
frontier_council-0.1.2.dist-info/METADATA,sha256=E9iEMkdVEBtmA2NyprKIWipDAnR0gHWVGbIonlmVYrc,5229
|
|
5
|
+
frontier_council-0.1.2.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
6
|
+
frontier_council-0.1.2.dist-info/entry_points.txt,sha256=I3xjPK-nupfQz5PANVXUnXjuxlP-4-mykkA3wXhFOGY,63
|
|
7
|
+
frontier_council-0.1.2.dist-info/licenses/LICENSE,sha256=8qmwox7khp-AakNVvL-Ga25eYbsCtLx8RyXM4zKkX0w,1065
|
|
8
|
+
frontier_council-0.1.2.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Terry Li
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
frontier_council/__init__.py,sha256=VfpeWHijQ1z8zd_ecKPIjI6S9VT3E6yAQ1PVt8-eExU,357
|
|
2
|
-
frontier_council/cli.py,sha256=BbM1cHWjAA0DBn4uyGKajaNAMxhKYQt-ZGNQ6hTnlkc,7337
|
|
3
|
-
frontier_council/council.py,sha256=u2ir34dNostBOhXUi1R0wFEfBIEgiRX8thiS5lRFnnU,30226
|
|
4
|
-
frontier_council-0.1.0.dist-info/METADATA,sha256=hZGQzWU0DUtuexLkKR4sXVHFjDbw75bYg02uQ8dFAB4,4792
|
|
5
|
-
frontier_council-0.1.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
6
|
-
frontier_council-0.1.0.dist-info/entry_points.txt,sha256=I3xjPK-nupfQz5PANVXUnXjuxlP-4-mykkA3wXhFOGY,63
|
|
7
|
-
frontier_council-0.1.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|