difficult-dialogs 0.2__tar.gz → 0.5.1a1__tar.gz
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.
- difficult_dialogs-0.5.1a1/PKG-INFO +564 -0
- difficult_dialogs-0.5.1a1/difficult_dialogs/__init__.py +62 -0
- difficult_dialogs-0.5.1a1/difficult_dialogs/arguments.py +344 -0
- difficult_dialogs-0.5.1a1/difficult_dialogs/cli.py +476 -0
- difficult_dialogs-0.5.1a1/difficult_dialogs/exceptions.py +35 -0
- difficult_dialogs-0.5.1a1/difficult_dialogs/export/__init__.py +25 -0
- difficult_dialogs-0.5.1a1/difficult_dialogs/export/json.py +168 -0
- difficult_dialogs-0.5.1a1/difficult_dialogs/export/markdown.py +81 -0
- difficult_dialogs-0.5.1a1/difficult_dialogs/export/sqlite.py +388 -0
- difficult_dialogs-0.5.1a1/difficult_dialogs/llm/__init__.py +6 -0
- difficult_dialogs-0.5.1a1/difficult_dialogs/llm/client.py +185 -0
- difficult_dialogs-0.5.1a1/difficult_dialogs/llm/enhancer.py +185 -0
- difficult_dialogs-0.5.1a1/difficult_dialogs/llm/generator.py +318 -0
- difficult_dialogs-0.5.1a1/difficult_dialogs/policy.py +975 -0
- difficult_dialogs-0.5.1a1/difficult_dialogs/premises.py +247 -0
- difficult_dialogs-0.5.1a1/difficult_dialogs/statements.py +45 -0
- difficult_dialogs-0.5.1a1/difficult_dialogs/validators.py +404 -0
- difficult_dialogs-0.5.1a1/difficult_dialogs/version.py +8 -0
- difficult_dialogs-0.5.1a1/difficult_dialogs.egg-info/PKG-INFO +564 -0
- difficult_dialogs-0.5.1a1/difficult_dialogs.egg-info/SOURCES.txt +35 -0
- difficult_dialogs-0.5.1a1/difficult_dialogs.egg-info/entry_points.txt +3 -0
- difficult_dialogs-0.5.1a1/difficult_dialogs.egg-info/requires.txt +21 -0
- difficult_dialogs-0.5.1a1/pyproject.toml +109 -0
- difficult_dialogs-0.5.1a1/readme.md +527 -0
- difficult_dialogs-0.5.1a1/test/test_arguments.py +367 -0
- difficult_dialogs-0.5.1a1/test/test_cli.py +630 -0
- difficult_dialogs-0.5.1a1/test/test_export.py +535 -0
- difficult_dialogs-0.5.1a1/test/test_llm.py +452 -0
- difficult_dialogs-0.5.1a1/test/test_policies.py +452 -0
- difficult_dialogs-0.5.1a1/test/test_policy.py +732 -0
- difficult_dialogs-0.5.1a1/test/test_premises.py +222 -0
- difficult_dialogs-0.5.1a1/test/test_sample_arguments.py +279 -0
- difficult_dialogs-0.5.1a1/test/test_statements.py +65 -0
- difficult_dialogs-0.5.1a1/test/test_validators.py +644 -0
- difficult_dialogs-0.2/PKG-INFO +0 -10
- difficult_dialogs-0.2/difficult_dialogs/__init__.py +0 -146
- difficult_dialogs-0.2/difficult_dialogs/arguments.py +0 -299
- difficult_dialogs-0.2/difficult_dialogs/exceptions.py +0 -42
- difficult_dialogs-0.2/difficult_dialogs/policy.py +0 -256
- difficult_dialogs-0.2/difficult_dialogs/premises.py +0 -123
- difficult_dialogs-0.2/difficult_dialogs/statements.py +0 -26
- difficult_dialogs-0.2/difficult_dialogs.egg-info/PKG-INFO +0 -10
- difficult_dialogs-0.2/difficult_dialogs.egg-info/SOURCES.txt +0 -11
- difficult_dialogs-0.2/setup.py +0 -12
- {difficult_dialogs-0.2 → difficult_dialogs-0.5.1a1}/difficult_dialogs.egg-info/dependency_links.txt +0 -0
- {difficult_dialogs-0.2 → difficult_dialogs-0.5.1a1}/difficult_dialogs.egg-info/top_level.txt +0 -0
- {difficult_dialogs-0.2 → difficult_dialogs-0.5.1a1}/setup.cfg +0 -0
|
@@ -0,0 +1,564 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: difficult_dialogs
|
|
3
|
+
Version: 0.5.1a1
|
|
4
|
+
Summary: Structured argument framework for meaningful debates
|
|
5
|
+
Author-email: JarbasAl <jarbasai@protonmail.com>
|
|
6
|
+
License: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/JarbasAl/difficult_dialogs
|
|
8
|
+
Project-URL: Documentation, https://github.com/JarbasAl/difficult_dialogs#readme
|
|
9
|
+
Project-URL: Repository, https://github.com/JarbasAl/difficult_dialogs
|
|
10
|
+
Project-URL: Issues, https://github.com/JarbasAl/difficult_dialogs/issues
|
|
11
|
+
Keywords: argument,debate,dialog,llm,reasoning,logic
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
Requires-Dist: requests>=2.28.0
|
|
22
|
+
Provides-Extra: dev
|
|
23
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
24
|
+
Requires-Dist: pytest-cov>=4.0; extra == "dev"
|
|
25
|
+
Requires-Dist: pytest-asyncio>=0.21; extra == "dev"
|
|
26
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
27
|
+
Requires-Dist: mypy>=1.0; extra == "dev"
|
|
28
|
+
Provides-Extra: cli
|
|
29
|
+
Requires-Dist: tqdm>=4.65.0; extra == "cli"
|
|
30
|
+
Provides-Extra: export
|
|
31
|
+
Requires-Dist: sqlite3; extra == "export"
|
|
32
|
+
Provides-Extra: web
|
|
33
|
+
Requires-Dist: streamlit>=1.28.0; extra == "web"
|
|
34
|
+
Provides-Extra: all
|
|
35
|
+
Requires-Dist: tqdm>=4.65.0; extra == "all"
|
|
36
|
+
Requires-Dist: streamlit>=1.28.0; extra == "all"
|
|
37
|
+
|
|
38
|
+
# Difficult Dialogs
|
|
39
|
+
|
|
40
|
+
**Compile LLM knowledge into portable, deterministic debate modules.**
|
|
41
|
+
|
|
42
|
+
[]()
|
|
43
|
+
[]()
|
|
44
|
+
[]()
|
|
45
|
+
[]()
|
|
46
|
+
[]()
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## The Problem
|
|
51
|
+
|
|
52
|
+
LLMs are great for debates, but they're:
|
|
53
|
+
- ❌ **Expensive** at scale ($0.15 per 10-turn debate)
|
|
54
|
+
- ❌ **Unreliable** (hallucinate mid-conversation)
|
|
55
|
+
- ❌ **Slow** (2-5s latency per response)
|
|
56
|
+
- ❌ **Online-only** (need API access)
|
|
57
|
+
|
|
58
|
+
## The Solution
|
|
59
|
+
|
|
60
|
+
**Generate once with an LLM, run forever without one.**
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
┌─────────────────────┐ ┌──────────────────┐ ┌─────────────────┐
|
|
64
|
+
│ LLM (one-time) │ │ File Format │ │ Interpreter │
|
|
65
|
+
│ │ │ (.premise, │ │ (dumb, fast, │
|
|
66
|
+
│ Generate argument │─────▶│ .support, │─────▶│ deterministic)│
|
|
67
|
+
│ structure │ │ .source) │ │ │
|
|
68
|
+
└─────────────────────┘ └──────────────────┘ └─────────────────┘
|
|
69
|
+
~60 seconds Portable Microseconds
|
|
70
|
+
Smart Auditable Offline
|
|
71
|
+
One-time Versionable Infinite runs
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Quick Start (5 Minutes)
|
|
77
|
+
|
|
78
|
+
### 1. Install
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
pip install difficult-dialogs
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Requires Python 3.10+
|
|
85
|
+
|
|
86
|
+
### 2. Try the CLI
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
# List available arguments
|
|
90
|
+
difficult-dialogs list examples/sample_arguments
|
|
91
|
+
|
|
92
|
+
# Validate quality
|
|
93
|
+
difficult-dialogs validate examples/sample_arguments
|
|
94
|
+
|
|
95
|
+
# Run a debate
|
|
96
|
+
difficult-dialogs debate examples/sample_arguments/philosophy/free_will_exists
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### 3. Web Interface (Optional)
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
# Install Streamlit
|
|
103
|
+
pip install streamlit
|
|
104
|
+
|
|
105
|
+
# Launch web demo
|
|
106
|
+
streamlit run examples/streamlit_demo.py
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Opens at `http://localhost:8501` with beautiful UI for browsing and debating.
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Features
|
|
114
|
+
|
|
115
|
+
### ✅ Complete Tool Suite
|
|
116
|
+
|
|
117
|
+
- **CLI Tool** - Generate, validate, export, debate from command line
|
|
118
|
+
- **Web Demo** - Streamlit-based interactive interface
|
|
119
|
+
- **Python API** - Full programmatic control
|
|
120
|
+
- **Export Formats** - JSON bundles, SQLite databases, Markdown documents
|
|
121
|
+
- **Validation** - Quality scoring and issue detection
|
|
122
|
+
|
|
123
|
+
### ✅ Rich Sample Library
|
|
124
|
+
|
|
125
|
+
**32 pre-generated arguments** across 6 categories:
|
|
126
|
+
- 💻 Technology (5 args) - AI, open source, privacy, remote work, social media
|
|
127
|
+
- 🔬 Science (5 args) - Climate change, space exploration, vaccines, genetics, renewable energy
|
|
128
|
+
- 🏥 Health (6 args) - Exercise, diet, sleep, meditation, preventive care
|
|
129
|
+
- 🌍 Society (6 args) - UBI, education, transportation, recycling, volunteering
|
|
130
|
+
- 🤔 Philosophy (5 args) - Cogito, free will, happiness, knowledge, ethics
|
|
131
|
+
- 📚 Education (5 args) - Critical thinking, testing, lifelong learning, teacher pay, online learning
|
|
132
|
+
|
|
133
|
+
### ✅ Quality Assurance
|
|
134
|
+
|
|
135
|
+
- **704 automated tests** (100% pass rate)
|
|
136
|
+
- **Validation framework** with scoring (0.0-1.0)
|
|
137
|
+
- **Quality labels**: Excellent ⭐, Good 👍, Fair 😐, Poor ❌
|
|
138
|
+
- **All 32 sample arguments**: Excellent quality (1.00 avg score)
|
|
139
|
+
|
|
140
|
+
### ✅ Developer Friendly
|
|
141
|
+
|
|
142
|
+
- **Zero runtime dependencies** (only requests for LLM generation)
|
|
143
|
+
- **Type hints** throughout (mypy strict mode)
|
|
144
|
+
- **Well tested** (pytest suite)
|
|
145
|
+
- **Clean API** with dataclasses
|
|
146
|
+
- **Comprehensive docs** (inline + markdown)
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## CLI Commands
|
|
151
|
+
|
|
152
|
+
### Generate Arguments
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
# Generate single topic
|
|
156
|
+
difficult-dialogs generate "AI benefits humanity" \
|
|
157
|
+
--server http://localhost:8000 \
|
|
158
|
+
--model qwen-72b \
|
|
159
|
+
--output my_arguments
|
|
160
|
+
|
|
161
|
+
# Generate multiple topics
|
|
162
|
+
difficult-dialogs generate "Topic 1" "Topic 2" "Topic 3" \
|
|
163
|
+
--stance pro \
|
|
164
|
+
--depth 2 \
|
|
165
|
+
--validate
|
|
166
|
+
|
|
167
|
+
# With progress bar (install tqdm first)
|
|
168
|
+
pip install tqdm
|
|
169
|
+
difficult-dialogs generate "Topic 1" "Topic 2" -v
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Validate Quality
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
# Validate entire library
|
|
176
|
+
difficult-dialogs validate examples/sample_arguments
|
|
177
|
+
|
|
178
|
+
# Verbose mode (show issues)
|
|
179
|
+
difficult-dialogs validate examples/sample_arguments --verbose
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Export
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
# Export to JSON bundle
|
|
186
|
+
difficult-dialogs export examples/sample_arguments library.json
|
|
187
|
+
|
|
188
|
+
# Export to SQLite database
|
|
189
|
+
difficult-dialogs export examples/sample_arguments library.db --stats
|
|
190
|
+
|
|
191
|
+
# Without validation data
|
|
192
|
+
difficult-dialogs export examples/sample_arguments library.json --no-validation
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Debate
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
# Interactive debate
|
|
199
|
+
difficult-dialogs debate examples/sample_arguments/science/space_exploration
|
|
200
|
+
|
|
201
|
+
# Or use short alias
|
|
202
|
+
dd debate examples/sample_arguments/health/exercise_improves_mental_health
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### List Available
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
# List all arguments
|
|
209
|
+
difficult-dialogs list examples/sample_arguments
|
|
210
|
+
|
|
211
|
+
# Output:
|
|
212
|
+
# TECHNOLOGY (5):
|
|
213
|
+
# • Artificial Intelligence Will Benefit Humanity
|
|
214
|
+
# • Open Source Software Is Superior To Proprietary
|
|
215
|
+
# ...
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## Python API
|
|
221
|
+
|
|
222
|
+
### Generate with LLM
|
|
223
|
+
|
|
224
|
+
```python
|
|
225
|
+
from difficult_dialogs.llm import ArgumentGenerator
|
|
226
|
+
|
|
227
|
+
gen = ArgumentGenerator("http://localhost:8000")
|
|
228
|
+
|
|
229
|
+
arg = gen.generate(
|
|
230
|
+
topic="Solar energy is cost-effective",
|
|
231
|
+
stance="pro",
|
|
232
|
+
depth=2,
|
|
233
|
+
include_sources=True
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
print(f"Generated {len(arg.premises)} premises")
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### Validate
|
|
240
|
+
|
|
241
|
+
```python
|
|
242
|
+
from difficult_dialogs.validators import validate_argument, get_quality_label
|
|
243
|
+
|
|
244
|
+
result = validate_argument(arg)
|
|
245
|
+
|
|
246
|
+
print(f"Score: {result.score:.2f}")
|
|
247
|
+
print(f"Passed: {result.passed}")
|
|
248
|
+
print(f"Quality: {get_quality_label(result.score)}")
|
|
249
|
+
|
|
250
|
+
for issue in result.issues:
|
|
251
|
+
print(f" {issue}")
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### Export
|
|
255
|
+
|
|
256
|
+
```python
|
|
257
|
+
from difficult_dialogs.export import (
|
|
258
|
+
export_to_json,
|
|
259
|
+
export_library_to_json,
|
|
260
|
+
export_to_markdown,
|
|
261
|
+
LibraryDatabase,
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
# Single argument to JSON
|
|
265
|
+
export_to_json(arg, "my_argument.json")
|
|
266
|
+
|
|
267
|
+
# Entire library to JSON bundle
|
|
268
|
+
export_library_to_json("examples/sample_arguments", "library.json")
|
|
269
|
+
|
|
270
|
+
# Human-readable Markdown (returns string; writes file when path given)
|
|
271
|
+
md = export_to_markdown(arg)
|
|
272
|
+
export_to_markdown(arg, "my_argument.md")
|
|
273
|
+
|
|
274
|
+
# Export to SQLite
|
|
275
|
+
db = LibraryDatabase("library.db")
|
|
276
|
+
db.add_argument(arg, category="energy")
|
|
277
|
+
|
|
278
|
+
stats = db.get_statistics()
|
|
279
|
+
print(f"Total: {stats['total_arguments']}")
|
|
280
|
+
print(f"By category: {stats['by_category']}")
|
|
281
|
+
|
|
282
|
+
db.close()
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### Compare Argument Versions
|
|
286
|
+
|
|
287
|
+
```python
|
|
288
|
+
# Review LLM-generated changes before committing
|
|
289
|
+
diff = original.diff(updated)
|
|
290
|
+
print(diff["meta"]) # changed name/intro/conclusion
|
|
291
|
+
print(diff["added_premises"]) # new premise names
|
|
292
|
+
print(diff["removed_premises"]) # deleted premise names
|
|
293
|
+
print(diff["modified_premises"]) # {name: {added_statements, removed_statements}}
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### Run Debate Programmatically
|
|
297
|
+
|
|
298
|
+
```python
|
|
299
|
+
from difficult_dialogs.arguments import Argument
|
|
300
|
+
from difficult_dialogs.policy import KnowItAllPolicy
|
|
301
|
+
|
|
302
|
+
# Load argument
|
|
303
|
+
arg = Argument.from_directory("examples/sample_arguments/philosophy/free_will_exists")
|
|
304
|
+
|
|
305
|
+
# Create policy
|
|
306
|
+
policy = KnowItAllPolicy(arg)
|
|
307
|
+
|
|
308
|
+
# Start dialog
|
|
309
|
+
print(policy.start())
|
|
310
|
+
|
|
311
|
+
# Process user input (generator/coroutine protocol)
|
|
312
|
+
gen = policy.run_sync()
|
|
313
|
+
response = next(gen)
|
|
314
|
+
while response:
|
|
315
|
+
print(f"BOT: {response}")
|
|
316
|
+
user_input = input("USER: ")
|
|
317
|
+
try:
|
|
318
|
+
response = gen.send(user_input)
|
|
319
|
+
except StopIteration:
|
|
320
|
+
break
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
325
|
+
## File Structure
|
|
326
|
+
|
|
327
|
+
Arguments are plain text files in structured directories:
|
|
328
|
+
|
|
329
|
+
```
|
|
330
|
+
argument_name/
|
|
331
|
+
├── intro.dialog # Opening statement
|
|
332
|
+
├── conclusion.conclusion # Final statement
|
|
333
|
+
└── premise_name/ # One subdirectory per premise
|
|
334
|
+
├── premise_name.premise # Core claims (one per line)
|
|
335
|
+
├── premise_name.support # Fallback arguments (optional)
|
|
336
|
+
├── premise_name.source # Evidence URLs (optional)
|
|
337
|
+
├── premise_name.what # Five-Ws explanations (optional)
|
|
338
|
+
├── premise_name.why
|
|
339
|
+
├── premise_name.how
|
|
340
|
+
├── premise_name.when
|
|
341
|
+
└── premise_name.where
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
Example:
|
|
345
|
+
```
|
|
346
|
+
free_will_exists/
|
|
347
|
+
├── intro.dialog
|
|
348
|
+
├── conclusion.conclusion
|
|
349
|
+
├── moral_responsibility/
|
|
350
|
+
│ ├── moral_responsibility.premise
|
|
351
|
+
│ └── moral_responsibility.support
|
|
352
|
+
└── quantum_indeterminacy/
|
|
353
|
+
├── quantum_indeterminacy.premise
|
|
354
|
+
└── quantum_indeterminacy.source
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
---
|
|
358
|
+
|
|
359
|
+
## Comparison
|
|
360
|
+
|
|
361
|
+
| Feature | Difficult Dialogs | Raw LLM API | Other Debate Tools |
|
|
362
|
+
|---------|------------------|-------------|-------------------|
|
|
363
|
+
| **Cost per debate** | $0 (after generation) | $0.10-0.50 | Varies |
|
|
364
|
+
| **Latency** | <1ms | 2-5s | 1-3s |
|
|
365
|
+
| **Offline** | ✅ Yes | ❌ No | ❌ No |
|
|
366
|
+
| **Hallucinations** | ❌ None | ✅ Possible | ⚠️ Sometimes |
|
|
367
|
+
| **Auditable** | ✅ Full file format | ❌ Black box | ⚠️ Limited |
|
|
368
|
+
| **Versionable** | ✅ Git-friendly | ❌ API-dependent | ⚠️ Database |
|
|
369
|
+
| **Customizable** | ✅ Edit files | ⚠️ Prompt only | ❌ Fixed |
|
|
370
|
+
| **Language** | Any (LLM choice) | Any | Usually English |
|
|
371
|
+
|
|
372
|
+
---
|
|
373
|
+
|
|
374
|
+
## Installation
|
|
375
|
+
|
|
376
|
+
### Basic Install
|
|
377
|
+
|
|
378
|
+
```bash
|
|
379
|
+
pip install difficult-dialogs
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
### With Extras
|
|
383
|
+
|
|
384
|
+
```bash
|
|
385
|
+
# Development tools
|
|
386
|
+
pip install difficult-dialogs[dev]
|
|
387
|
+
|
|
388
|
+
# Web interface
|
|
389
|
+
pip install difficult-dialogs[web]
|
|
390
|
+
|
|
391
|
+
# All extras
|
|
392
|
+
pip install difficult-dialogs[all]
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
### From Source
|
|
396
|
+
|
|
397
|
+
```bash
|
|
398
|
+
git clone https://github.com/JarbasAl/difficult_dialogs
|
|
399
|
+
cd difficult_dialogs
|
|
400
|
+
pip install -e ".[dev]"
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
---
|
|
404
|
+
|
|
405
|
+
## Testing
|
|
406
|
+
|
|
407
|
+
```bash
|
|
408
|
+
# Run all tests
|
|
409
|
+
pytest test/ -v
|
|
410
|
+
|
|
411
|
+
# With coverage
|
|
412
|
+
pytest test/ --cov=difficult_dialogs --cov-report=html
|
|
413
|
+
|
|
414
|
+
# Specific test categories
|
|
415
|
+
pytest test/test_cli.py -v
|
|
416
|
+
pytest test/test_validators.py -v
|
|
417
|
+
pytest test/test_export.py -v
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
**Current Status:** 704 tests passing ✅
|
|
421
|
+
|
|
422
|
+
---
|
|
423
|
+
|
|
424
|
+
## Configuration
|
|
425
|
+
|
|
426
|
+
### LLM Server Setup
|
|
427
|
+
|
|
428
|
+
Works with any OpenAI-compatible server:
|
|
429
|
+
|
|
430
|
+
**Llama.cpp:**
|
|
431
|
+
```bash
|
|
432
|
+
./server -m models/qwen-72b.gguf --host 0.0.0.0 --port 8000
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
**Ollama:**
|
|
436
|
+
```bash
|
|
437
|
+
ollama serve
|
|
438
|
+
# Default: http://localhost:11434
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
**OpenAI:**
|
|
442
|
+
```bash
|
|
443
|
+
export OPENAI_API_KEY="your-key"
|
|
444
|
+
# Use in generator: --server https://api.openai.com/v1
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
### Environment Variables
|
|
448
|
+
|
|
449
|
+
```bash
|
|
450
|
+
export DD_LLM_SERVER="http://localhost:8000"
|
|
451
|
+
export DD_LLM_MODEL="qwen-72b"
|
|
452
|
+
export DD_TIMEOUT="120"
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
---
|
|
456
|
+
|
|
457
|
+
## Project Structure
|
|
458
|
+
|
|
459
|
+
```
|
|
460
|
+
difficult_dialogs/
|
|
461
|
+
├── difficult_dialogs/
|
|
462
|
+
│ ├── __init__.py # Package exports
|
|
463
|
+
│ ├── statements.py # Statement dataclass
|
|
464
|
+
│ ├── premises.py # Premise dataclass
|
|
465
|
+
│ ├── arguments.py # Argument class + loader + diff
|
|
466
|
+
│ ├── policy.py # All 10 dialog policies + POLICY_REGISTRY
|
|
467
|
+
│ ├── validators.py # Quality validation
|
|
468
|
+
│ ├── export/
|
|
469
|
+
│ │ ├── __init__.py # Re-exports full public API
|
|
470
|
+
│ │ ├── json.py # JSON serialization
|
|
471
|
+
│ │ ├── sqlite.py # SQLite database
|
|
472
|
+
│ │ └── markdown.py # Markdown export
|
|
473
|
+
│ ├── cli.py # Command-line interface
|
|
474
|
+
│ └── llm/
|
|
475
|
+
│ ├── client.py # HTTP client
|
|
476
|
+
│ ├── generator.py # Argument generator
|
|
477
|
+
│ └── enhancer.py # Runtime enhancement
|
|
478
|
+
├── examples/
|
|
479
|
+
│ ├── sample_arguments/ # 32 pre-made arguments
|
|
480
|
+
│ ├── streamlit_demo.py # Web interface
|
|
481
|
+
│ └── run_argument.py # Simple runner
|
|
482
|
+
├── test/
|
|
483
|
+
│ └── test_*.py # 704 tests
|
|
484
|
+
├── docs/
|
|
485
|
+
│ ├── index.md # Overview and navigation
|
|
486
|
+
│ ├── argument-format.md # File format reference
|
|
487
|
+
│ ├── USER_GUIDE.md # User manual
|
|
488
|
+
│ ├── DEVELOPER_GUIDE.md # API reference
|
|
489
|
+
│ └── POLICIES.md # Policy reference
|
|
490
|
+
├── pyproject.toml # Build config
|
|
491
|
+
└── readme.md # This file
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
---
|
|
495
|
+
|
|
496
|
+
## Contributing
|
|
497
|
+
|
|
498
|
+
### Report Issues
|
|
499
|
+
https://github.com/JarbasAl/difficult_dialogs/issues
|
|
500
|
+
|
|
501
|
+
### Submit PRs
|
|
502
|
+
1. Fork the repo
|
|
503
|
+
2. Create feature branch
|
|
504
|
+
3. Add tests
|
|
505
|
+
4. Ensure all tests pass
|
|
506
|
+
5. Submit pull request
|
|
507
|
+
|
|
508
|
+
### Create Arguments
|
|
509
|
+
See `examples/sample_arguments/README.md` for argument creation guide.
|
|
510
|
+
|
|
511
|
+
---
|
|
512
|
+
|
|
513
|
+
## Roadmap
|
|
514
|
+
|
|
515
|
+
### Q2 2026
|
|
516
|
+
- ✅ CLI tool
|
|
517
|
+
- ✅ Export formats (JSON, SQLite)
|
|
518
|
+
- ✅ Validation framework
|
|
519
|
+
- ✅ Web demo
|
|
520
|
+
- ✅ 32 sample arguments
|
|
521
|
+
|
|
522
|
+
### Q3 2026
|
|
523
|
+
- [ ] JavaScript implementation
|
|
524
|
+
- [ ] Mobile app (React Native)
|
|
525
|
+
- [ ] Multi-language support
|
|
526
|
+
- [ ] Counter-argument generator
|
|
527
|
+
|
|
528
|
+
### Q4 2026
|
|
529
|
+
- [ ] Visual argument editor
|
|
530
|
+
- [ ] Collaborative debates
|
|
531
|
+
- [ ] Argument marketplace
|
|
532
|
+
- [ ] Enterprise features
|
|
533
|
+
|
|
534
|
+
---
|
|
535
|
+
|
|
536
|
+
## License
|
|
537
|
+
|
|
538
|
+
Apache 2.0 - See [LICENSE](LICENSE) for details.
|
|
539
|
+
|
|
540
|
+
Free for personal and commercial use. Attribution appreciated but not required.
|
|
541
|
+
|
|
542
|
+
---
|
|
543
|
+
|
|
544
|
+
## Citation
|
|
545
|
+
|
|
546
|
+
```bibtex
|
|
547
|
+
@software{difficult_dialogs2026,
|
|
548
|
+
title = {Difficult Dialogs: Structured Argument Framework},
|
|
549
|
+
author = {JarbasAl},
|
|
550
|
+
year = {2026},
|
|
551
|
+
url = {https://github.com/JarbasAl/difficult_dialogs},
|
|
552
|
+
version = {0.5.0}
|
|
553
|
+
}
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
---
|
|
557
|
+
|
|
558
|
+
## Support
|
|
559
|
+
|
|
560
|
+
- **Documentation:** `docs/USER_GUIDE.md`, `docs/DEVELOPER_GUIDE.md`
|
|
561
|
+
- **Issues:** https://github.com/JarbasAl/difficult_dialogs/issues
|
|
562
|
+
- **Discussions:** https://github.com/JarbasAl/difficult_dialogs/discussions
|
|
563
|
+
|
|
564
|
+
Happy debating! 💬
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"""Difficult Dialogs - Structured argumentation framework.
|
|
2
|
+
|
|
3
|
+
Tools to guide conversations towards a certain objective using file-based
|
|
4
|
+
argument definitions and pluggable policy engines.
|
|
5
|
+
"""
|
|
6
|
+
from difficult_dialogs.exceptions import (
|
|
7
|
+
DifficultDialogsError,
|
|
8
|
+
ArgumentLoadError,
|
|
9
|
+
ArgumentSaveError,
|
|
10
|
+
InvalidPolicyError,
|
|
11
|
+
MissingStatementError,
|
|
12
|
+
)
|
|
13
|
+
from difficult_dialogs.statements import Statement
|
|
14
|
+
from difficult_dialogs.premises import Premise
|
|
15
|
+
from difficult_dialogs.arguments import Argument
|
|
16
|
+
from difficult_dialogs.policy import (
|
|
17
|
+
BasePolicy,
|
|
18
|
+
KnowItAllPolicy,
|
|
19
|
+
SilentPolicy,
|
|
20
|
+
SocraticPolicy,
|
|
21
|
+
DebatePolicy,
|
|
22
|
+
ExploratoryPolicy,
|
|
23
|
+
MaieuticPolicy,
|
|
24
|
+
SkepticPolicy,
|
|
25
|
+
TeacherPolicy,
|
|
26
|
+
DebaterPolicy,
|
|
27
|
+
MinimalistPolicy,
|
|
28
|
+
PolicyState,
|
|
29
|
+
POLICY_REGISTRY,
|
|
30
|
+
get_policy,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
from difficult_dialogs.version import __version__
|
|
34
|
+
__all__ = [
|
|
35
|
+
# Exceptions
|
|
36
|
+
"DifficultDialogsError",
|
|
37
|
+
"ArgumentLoadError",
|
|
38
|
+
"ArgumentSaveError",
|
|
39
|
+
"InvalidPolicyError",
|
|
40
|
+
"MissingStatementError",
|
|
41
|
+
# Core data model
|
|
42
|
+
"Statement",
|
|
43
|
+
"Premise",
|
|
44
|
+
"Argument",
|
|
45
|
+
# Policy base + state
|
|
46
|
+
"BasePolicy",
|
|
47
|
+
"PolicyState",
|
|
48
|
+
# Built-in policies
|
|
49
|
+
"KnowItAllPolicy",
|
|
50
|
+
"SilentPolicy",
|
|
51
|
+
"SocraticPolicy",
|
|
52
|
+
"DebatePolicy",
|
|
53
|
+
"ExploratoryPolicy",
|
|
54
|
+
"MaieuticPolicy",
|
|
55
|
+
"SkepticPolicy",
|
|
56
|
+
"TeacherPolicy",
|
|
57
|
+
"DebaterPolicy",
|
|
58
|
+
"MinimalistPolicy",
|
|
59
|
+
# Policy registry
|
|
60
|
+
"POLICY_REGISTRY",
|
|
61
|
+
"get_policy",
|
|
62
|
+
]
|