synkro 0.4.30__tar.gz → 0.4.53__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.
- {synkro-0.4.30 → synkro-0.4.53}/PKG-INFO +298 -9
- synkro-0.4.53/README.md +551 -0
- {synkro-0.4.30 → synkro-0.4.53}/examples/advanced_usage.py +5 -0
- {synkro-0.4.30 → synkro-0.4.53}/examples/anthropic_basic.py +6 -1
- synkro-0.4.53/examples/coverage_tracking.py +58 -0
- synkro-0.4.53/examples/eval_scenarios.py +138 -0
- synkro-0.4.53/examples/evaluation_test.py +37 -0
- {synkro-0.4.30 → synkro-0.4.53}/examples/finetune_llama.py +9 -4
- {synkro-0.4.30 → synkro-0.4.53}/examples/multi_file_policy.py +6 -1
- {synkro-0.4.30 → synkro-0.4.53}/examples/openai_basic.py +5 -0
- synkro-0.4.53/examples/pdf_examples/dmv_handbook.py +87 -0
- {synkro-0.4.30 → synkro-0.4.53}/examples/quickstart.py +12 -10
- {synkro-0.4.30 → synkro-0.4.53}/examples/tool_calling.py +5 -0
- {synkro-0.4.30 → synkro-0.4.53}/pyproject.toml +4 -5
- {synkro-0.4.30 → synkro-0.4.53}/synkro/__init__.py +157 -4
- {synkro-0.4.30 → synkro-0.4.53}/synkro/advanced.py +2 -2
- {synkro-0.4.30 → synkro-0.4.53}/synkro/cli.py +2 -2
- {synkro-0.4.30 → synkro-0.4.53}/synkro/core/checkpoint.py +1 -1
- {synkro-0.4.30 → synkro-0.4.53}/synkro/core/dataset.py +61 -28
- {synkro-0.4.30 → synkro-0.4.53}/synkro/core/policy.py +10 -10
- synkro-0.4.53/synkro/coverage/__init__.py +23 -0
- synkro-0.4.53/synkro/coverage/calculator.py +363 -0
- synkro-0.4.53/synkro/coverage/improver.py +321 -0
- synkro-0.4.53/synkro/coverage/scenario_tagger.py +186 -0
- synkro-0.4.53/synkro/coverage/taxonomy_extractor.py +161 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/factory.py +50 -2
- synkro-0.4.53/synkro/formatters/__init__.py +17 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/formatters/chatml.py +10 -3
- synkro-0.4.53/synkro/formatters/langfuse.py +109 -0
- synkro-0.4.53/synkro/formatters/langsmith.py +109 -0
- synkro-0.4.30/synkro/formatters/sft.py → synkro-0.4.53/synkro/formatters/messages.py +16 -11
- synkro-0.4.53/synkro/formatters/qa.py +123 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/formatters/tool_call.py +14 -7
- {synkro-0.4.30 → synkro-0.4.53}/synkro/generation/generator.py +86 -4
- {synkro-0.4.30 → synkro-0.4.53}/synkro/generation/golden_responses.py +25 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/generation/golden_scenarios.py +168 -49
- {synkro-0.4.30 → synkro-0.4.53}/synkro/generation/golden_tool_responses.py +29 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/interactive/intent_classifier.py +3 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/interactive/rich_ui.py +109 -13
- {synkro-0.4.30 → synkro-0.4.53}/synkro/llm/client.py +37 -1
- {synkro-0.4.30 → synkro-0.4.53}/synkro/modes/config.py +2 -1
- {synkro-0.4.30 → synkro-0.4.53}/synkro/modes/conversation.py +9 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/pipeline/runner.py +417 -9
- {synkro-0.4.30 → synkro-0.4.53}/synkro/pipelines.py +11 -1
- synkro-0.4.53/synkro/prompts/coverage_templates.py +294 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/prompts/golden_templates.py +77 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/prompts/interactive_templates.py +20 -2
- synkro-0.4.53/synkro/reporting.py +803 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/schemas.py +83 -2
- {synkro-0.4.30 → synkro-0.4.53}/synkro/types/__init__.py +2 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/types/core.py +33 -0
- synkro-0.4.53/synkro/types/coverage.py +399 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/types/dataset_type.py +5 -1
- {synkro-0.4.30 → synkro-0.4.53}/synkro/types/logic_map.py +9 -1
- {synkro-0.4.30 → synkro-0.4.53}/tests/test_imports.py +3 -3
- synkro-0.4.30/README.md +0 -261
- synkro-0.4.30/synkro/formatters/__init__.py +0 -12
- synkro-0.4.30/synkro/reporting.py +0 -403
- {synkro-0.4.30 → synkro-0.4.53}/.gitignore +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/LICENSE +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/examples/policies/hr_policy.md +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/examples/policies/security_policy.txt +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/examples/test_fixes.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/core/__init__.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/errors.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/examples/__init__.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/generation/__init__.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/generation/follow_ups.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/generation/logic_extractor.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/generation/multiturn_responses.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/generation/planner.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/generation/responses.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/generation/scenarios.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/generation/tool_responses.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/generation/tool_simulator.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/interactive/__init__.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/interactive/hitl_session.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/interactive/logic_map_editor.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/interactive/scenario_editor.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/llm/__init__.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/llm/rate_limits.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/models/__init__.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/models/anthropic.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/models/google.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/models/local.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/models/openai.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/modes/__init__.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/modes/tool_call.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/parsers.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/pipeline/__init__.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/pipeline/phases.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/prompts/__init__.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/prompts/base.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/prompts/multiturn_templates.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/prompts/templates.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/prompts/tool_templates.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/quality/__init__.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/quality/golden_refiner.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/quality/grader.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/quality/multiturn_grader.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/quality/refiner.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/quality/tool_grader.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/quality/tool_refiner.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/quality/verifier.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/synkro/types/tool.py +0 -0
- {synkro-0.4.30 → synkro-0.4.53}/tests/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: synkro
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.53
|
|
4
4
|
Summary: Generate training datasets from any document
|
|
5
5
|
Author: Murtaza Meerza
|
|
6
6
|
License-Expression: MIT
|
|
@@ -20,9 +20,8 @@ Requires-Dist: html2text>=2020.1
|
|
|
20
20
|
Requires-Dist: httpx>=0.25
|
|
21
21
|
Requires-Dist: litellm>=1.40
|
|
22
22
|
Requires-Dist: mammoth>=1.6
|
|
23
|
-
Requires-Dist: marker-pdf>=0.2
|
|
24
23
|
Requires-Dist: pydantic>=2.0
|
|
25
|
-
Requires-Dist:
|
|
24
|
+
Requires-Dist: pymupdf>=1.24
|
|
26
25
|
Requires-Dist: rich>=13.0
|
|
27
26
|
Requires-Dist: typer>=0.9
|
|
28
27
|
Provides-Extra: dev
|
|
@@ -33,16 +32,19 @@ Description-Content-Type: text/markdown
|
|
|
33
32
|
|
|
34
33
|
# Synkro
|
|
35
34
|
|
|
36
|
-
|
|
35
|
+
Library for turning unstructured policies, handbooks, and documentation into high-quality conversation, tool calling or evaluation data for LLMs.
|
|
37
36
|
|
|
38
37
|
## Features
|
|
39
38
|
|
|
40
39
|
- **Quality Evaluation** - Each response is graded and automatically refined if it fails
|
|
41
|
-
- **Multiple Formats** - Conversation (multi-turn), Instruction (single-turn), and Tool Calling
|
|
40
|
+
- **Multiple Formats** - Conversation (multi-turn), Instruction (single-turn), Evaluation (Q&A), and Tool Calling
|
|
41
|
+
- **Eval Platform Support** - Export to LangSmith, Langfuse, or generic Q&A format
|
|
42
42
|
- **Tool Call Training** - Generate OpenAI function calling format for teaching models to use custom tools
|
|
43
|
-
- **
|
|
43
|
+
- **Coverage Tracking** - Track scenario diversity like code coverage, identify gaps, and improve coverage with natural language commands
|
|
44
|
+
- **Top LLM Providers** - OpenAI, Anthropic, Google, and local models (Ollama, vLLM)
|
|
44
45
|
- **File Support** - PDF, DOCX, TXT, Markdown, URLs
|
|
45
46
|
- **CLI Included** - Generate datasets from the command line
|
|
47
|
+
- **Cost Tracking** - See total cost and LLM call breakdown after each generation
|
|
46
48
|
|
|
47
49
|
## Installation
|
|
48
50
|
|
|
@@ -95,9 +97,10 @@ dataset = pipeline.generate(policy)
|
|
|
95
97
|
|
|
96
98
|
| Type | Turns | Output Formats | Best For |
|
|
97
99
|
|------|-------|----------------|----------|
|
|
98
|
-
| **CONVERSATION** | Multi | messages | Fine-tuning chat models |
|
|
99
|
-
| **INSTRUCTION** | 1 | messages | Instruction-following models |
|
|
100
|
-
| **
|
|
100
|
+
| **CONVERSATION** | Multi | messages, chatml | Fine-tuning chat models |
|
|
101
|
+
| **INSTRUCTION** | 1 | messages, chatml | Instruction-following models |
|
|
102
|
+
| **EVALUATION** | 1 | qa, langsmith, langfuse | LLM evaluation & benchmarks |
|
|
103
|
+
| **TOOL_CALL** | Multi | tool_call, chatml | Teaching tool use |
|
|
101
104
|
|
|
102
105
|
### Conversation (Default)
|
|
103
106
|
|
|
@@ -133,6 +136,50 @@ Output (single-turn):
|
|
|
133
136
|
]}
|
|
134
137
|
```
|
|
135
138
|
|
|
139
|
+
### Evaluation
|
|
140
|
+
|
|
141
|
+
Generate Q&A datasets for LLM evaluation with ground truth:
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
pipeline = create_pipeline(dataset_type=DatasetType.EVALUATION)
|
|
145
|
+
dataset = pipeline.generate(policy, traces=50)
|
|
146
|
+
|
|
147
|
+
# Save in different formats
|
|
148
|
+
dataset.save("eval.jsonl", format="qa") # Generic Q&A
|
|
149
|
+
dataset.save("eval.jsonl", format="langsmith") # LangSmith format
|
|
150
|
+
dataset.save("eval.jsonl", format="langfuse") # Langfuse format
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Output (`format="qa"`):
|
|
154
|
+
```json
|
|
155
|
+
{
|
|
156
|
+
"question": "Can I submit a $200 expense without a receipt?",
|
|
157
|
+
"answer": "All expenses require receipts per policy...",
|
|
158
|
+
"expected_outcome": "Deny - missing receipt violates R003",
|
|
159
|
+
"ground_truth_rules": ["R003", "R005"],
|
|
160
|
+
"difficulty": "negative",
|
|
161
|
+
"category": "Receipt Requirements"
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Output (`format="langsmith"`):
|
|
166
|
+
```json
|
|
167
|
+
{
|
|
168
|
+
"inputs": {"question": "...", "context": "..."},
|
|
169
|
+
"outputs": {"answer": "..."},
|
|
170
|
+
"metadata": {"expected_outcome": "...", "ground_truth_rules": [...]}
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Output (`format="langfuse"`):
|
|
175
|
+
```json
|
|
176
|
+
{
|
|
177
|
+
"input": {"question": "...", "context": "..."},
|
|
178
|
+
"expectedOutput": {"answer": "...", "expected_outcome": "..."},
|
|
179
|
+
"metadata": {"ground_truth_rules": [...], "difficulty": "..."}
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
136
183
|
### Tool Calling
|
|
137
184
|
|
|
138
185
|
Generate training data for teaching models when and how to use your custom tools:
|
|
@@ -218,6 +265,188 @@ high_quality = dataset.filter(passed=True)
|
|
|
218
265
|
high_quality.save("training.jsonl")
|
|
219
266
|
```
|
|
220
267
|
|
|
268
|
+
## Eval API
|
|
269
|
+
|
|
270
|
+
Generate test scenarios and grade your own model's responses against policy compliance.
|
|
271
|
+
|
|
272
|
+
```python
|
|
273
|
+
import synkro
|
|
274
|
+
|
|
275
|
+
# Generate scenarios with ground truth (no synthetic responses)
|
|
276
|
+
result = synkro.generate_scenarios(
|
|
277
|
+
policy="Expenses over $50 require manager approval...",
|
|
278
|
+
count=100,
|
|
279
|
+
)
|
|
280
|
+
|
|
281
|
+
# Each scenario has ground truth labels
|
|
282
|
+
for scenario in result.scenarios:
|
|
283
|
+
print(scenario.user_message) # "Can I expense a $200 dinner?"
|
|
284
|
+
print(scenario.expected_outcome) # "Requires manager approval per R001"
|
|
285
|
+
print(scenario.target_rule_ids) # ["R001", "R003"]
|
|
286
|
+
print(scenario.scenario_type) # "positive" | "negative" | "edge_case"
|
|
287
|
+
|
|
288
|
+
# Grade YOUR model's responses
|
|
289
|
+
for scenario in result.scenarios:
|
|
290
|
+
response = my_model(scenario.user_message) # Your model
|
|
291
|
+
grade = synkro.grade(response, scenario, policy)
|
|
292
|
+
|
|
293
|
+
if not grade.passed:
|
|
294
|
+
print(f"Failed: {grade.feedback}")
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
### When to Use
|
|
298
|
+
|
|
299
|
+
| Use Case | API |
|
|
300
|
+
|----------|-----|
|
|
301
|
+
| Generate training data | `synkro.generate()` |
|
|
302
|
+
| Generate eval scenarios | `synkro.generate_scenarios()` |
|
|
303
|
+
| Grade external model | `synkro.grade()` |
|
|
304
|
+
|
|
305
|
+
### Scenario Types
|
|
306
|
+
|
|
307
|
+
Scenarios are generated with balanced coverage:
|
|
308
|
+
|
|
309
|
+
| Type | % | Description |
|
|
310
|
+
|------|---|-------------|
|
|
311
|
+
| `positive` | 35% | Happy path - user meets all criteria |
|
|
312
|
+
| `negative` | 30% | Violations - user fails one criterion |
|
|
313
|
+
| `edge_case` | 25% | Boundary conditions at exact limits |
|
|
314
|
+
| `irrelevant` | 10% | Outside policy scope |
|
|
315
|
+
|
|
316
|
+
### EvalScenario Fields
|
|
317
|
+
|
|
318
|
+
```python
|
|
319
|
+
scenario.user_message # The test input
|
|
320
|
+
scenario.expected_outcome # Ground truth behavior
|
|
321
|
+
scenario.target_rule_ids # Rules being tested
|
|
322
|
+
scenario.scenario_type # positive/negative/edge_case/irrelevant
|
|
323
|
+
scenario.category # Policy category
|
|
324
|
+
scenario.context # Additional context
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
### Temperature
|
|
328
|
+
|
|
329
|
+
Use `temperature` to control output diversity:
|
|
330
|
+
|
|
331
|
+
```python
|
|
332
|
+
# High temp for diverse scenario coverage
|
|
333
|
+
result = synkro.generate_scenarios(policy, temperature=0.8)
|
|
334
|
+
|
|
335
|
+
# Low temp for deterministic training data
|
|
336
|
+
dataset = synkro.generate(policy, temperature=0.2)
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
## Coverage Tracking
|
|
340
|
+
|
|
341
|
+
Track how well your generated scenarios cover different aspects of your policy, similar to code coverage for tests.
|
|
342
|
+
|
|
343
|
+
```python
|
|
344
|
+
import synkro
|
|
345
|
+
|
|
346
|
+
# Generate with logic map access
|
|
347
|
+
result = synkro.generate(policy, traces=50, return_logic_map=True)
|
|
348
|
+
|
|
349
|
+
# View coverage report
|
|
350
|
+
synkro.coverage_report(result)
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
Output:
|
|
354
|
+
```
|
|
355
|
+
Coverage Report
|
|
356
|
+
========================================
|
|
357
|
+
Overall: 68.8%
|
|
358
|
+
Sub-categories: 2 covered, 1 partial, 1 uncovered
|
|
359
|
+
Total scenarios: 20
|
|
360
|
+
|
|
361
|
+
Gaps (2):
|
|
362
|
+
- Receipt requirements [HIGH] (0% coverage, 0 scenarios)
|
|
363
|
+
- Travel booking rules [MEDIUM] (partial: 40% coverage)
|
|
364
|
+
|
|
365
|
+
Suggestions:
|
|
366
|
+
1. Add 3+ scenarios for 'Receipt requirements' testing R008, R009
|
|
367
|
+
2. Add edge_case scenarios for 'Travel booking rules'
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
### Coverage Report Formats
|
|
371
|
+
|
|
372
|
+
```python
|
|
373
|
+
# Print to console (default)
|
|
374
|
+
synkro.coverage_report(result)
|
|
375
|
+
|
|
376
|
+
# Get as dictionary for programmatic use
|
|
377
|
+
report = synkro.coverage_report(result, format="dict")
|
|
378
|
+
print(f"Coverage: {report['overall_coverage_percent']}%")
|
|
379
|
+
print(f"Gaps: {len(report['gaps'])}")
|
|
380
|
+
|
|
381
|
+
# Get as JSON string
|
|
382
|
+
json_str = synkro.coverage_report(result, format="json")
|
|
383
|
+
|
|
384
|
+
# Get raw CoverageReport object
|
|
385
|
+
report = synkro.coverage_report(result, format="report")
|
|
386
|
+
for gap in report.gaps:
|
|
387
|
+
print(f"Gap: {gap}")
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
### Interactive Coverage Commands
|
|
391
|
+
|
|
392
|
+
In interactive mode, use natural language to view and improve coverage:
|
|
393
|
+
|
|
394
|
+
| Command | Action |
|
|
395
|
+
|---------|--------|
|
|
396
|
+
| `"show coverage"` | Display coverage summary |
|
|
397
|
+
| `"show coverage gaps"` | Show uncovered sub-categories |
|
|
398
|
+
| `"show heatmap"` | Visual coverage by category |
|
|
399
|
+
| `"increase coverage for refunds by 20%"` | Add scenarios for a sub-category |
|
|
400
|
+
| `"get amount thresholds to 80%"` | Target specific coverage percentage |
|
|
401
|
+
| `"add more negative scenarios for time eligibility"` | Add specific scenario types |
|
|
402
|
+
|
|
403
|
+
### Coverage Metrics
|
|
404
|
+
|
|
405
|
+
Each sub-category is tracked with:
|
|
406
|
+
|
|
407
|
+
| Metric | Description |
|
|
408
|
+
|--------|-------------|
|
|
409
|
+
| `coverage_percent` | % of expected coverage achieved |
|
|
410
|
+
| `coverage_status` | `covered` (80%+), `partial` (30-80%), `uncovered` (<30%) |
|
|
411
|
+
| `scenario_count` | Number of scenarios testing this sub-category |
|
|
412
|
+
| `type_distribution` | Breakdown by positive/negative/edge_case |
|
|
413
|
+
|
|
414
|
+
## Cost & Performance
|
|
415
|
+
|
|
416
|
+
Approximate costs using Gemini 2.5 Flash (multi-turn conversations):
|
|
417
|
+
|
|
418
|
+
| Traces | LLM Calls | Time | Cost |
|
|
419
|
+
|--------|-----------|------|------|
|
|
420
|
+
| 100 | ~335 | ~13 min | ~$3 |
|
|
421
|
+
| 500 | ~1,675 | ~1 hour | ~$14 |
|
|
422
|
+
| 1000 | ~3,350 | ~2 hours | ~$28 |
|
|
423
|
+
|
|
424
|
+
*Based on ~3.3 LLM calls per trace (generation + grading) with max_iterations=3. Actual costs vary by policy complexity and turn count.*
|
|
425
|
+
|
|
426
|
+
## Local LLMs
|
|
427
|
+
|
|
428
|
+
Run with Ollama, vLLM, or any OpenAI-compatible endpoint:
|
|
429
|
+
|
|
430
|
+
```python
|
|
431
|
+
from synkro import create_pipeline
|
|
432
|
+
from synkro.models import Local
|
|
433
|
+
|
|
434
|
+
# Ollama
|
|
435
|
+
pipeline = create_pipeline(model=Local.OLLAMA("llama3.2"))
|
|
436
|
+
|
|
437
|
+
# vLLM
|
|
438
|
+
pipeline = create_pipeline(model=Local.VLLM("mistral-7b"))
|
|
439
|
+
|
|
440
|
+
# Custom endpoint
|
|
441
|
+
pipeline = create_pipeline(model=Local.CUSTOM("my-model", endpoint="http://localhost:8080"))
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
**CLI:**
|
|
445
|
+
```bash
|
|
446
|
+
synkro generate policy.pdf --provider ollama --model llama3.2
|
|
447
|
+
synkro generate policy.pdf --provider vllm --endpoint http://localhost:8000
|
|
448
|
+
```
|
|
449
|
+
|
|
221
450
|
## CLI
|
|
222
451
|
|
|
223
452
|
```bash
|
|
@@ -232,12 +461,18 @@ synkro generate https://example.com/policy -o training.jsonl
|
|
|
232
461
|
|
|
233
462
|
# Skip interactive mode
|
|
234
463
|
synkro generate policy.pdf --no-interactive
|
|
464
|
+
|
|
465
|
+
# Quick demo with built-in policy
|
|
466
|
+
synkro demo
|
|
235
467
|
```
|
|
236
468
|
|
|
237
469
|
**Options:**
|
|
238
470
|
- `--traces, -n` - Number of traces (default: 20)
|
|
239
471
|
- `--output, -o` - Output file path
|
|
240
472
|
- `--model, -m` - Model for generation
|
|
473
|
+
- `--format, -f` - Output format: `messages`, `qa`, `langsmith`, `langfuse`, `tool_call`, `chatml`
|
|
474
|
+
- `--provider, -p` - LLM provider for local models (`ollama`, `vllm`)
|
|
475
|
+
- `--endpoint, -e` - Custom API endpoint URL
|
|
241
476
|
- `--interactive/-i, --no-interactive/-I` - Review/edit extracted rules before generation (default: on)
|
|
242
477
|
|
|
243
478
|
## Interactive Mode
|
|
@@ -278,6 +513,60 @@ You can adjust both **conversation turns** and **rules** using natural language:
|
|
|
278
513
|
|
|
279
514
|
Commands: `done`, `undo`, `reset`, `show R001`, `help`
|
|
280
515
|
|
|
516
|
+
## Advanced Features
|
|
517
|
+
|
|
518
|
+
### Checkpointing
|
|
519
|
+
|
|
520
|
+
Resume interrupted generations:
|
|
521
|
+
|
|
522
|
+
```python
|
|
523
|
+
pipeline = create_pipeline(checkpoint_dir="./checkpoints")
|
|
524
|
+
dataset = pipeline.generate(policy, traces=100) # Resumes from checkpoint
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
### Dataset Operations
|
|
528
|
+
|
|
529
|
+
```python
|
|
530
|
+
# Filter by quality
|
|
531
|
+
high_quality = dataset.filter(passed=True)
|
|
532
|
+
|
|
533
|
+
# Remove duplicates
|
|
534
|
+
unique = dataset.dedupe(threshold=0.85)
|
|
535
|
+
|
|
536
|
+
# Check pass rate
|
|
537
|
+
print(f"Pass rate: {dataset.passing_rate:.1%}")
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
### Folder Loading
|
|
541
|
+
|
|
542
|
+
Generate from multiple documents at once:
|
|
543
|
+
|
|
544
|
+
```python
|
|
545
|
+
from synkro.core.policy import Policy
|
|
546
|
+
|
|
547
|
+
policy = Policy.from_file("policies/") # Loads all PDF, DOCX, TXT, MD files
|
|
548
|
+
dataset = pipeline.generate(policy, traces=100)
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
### Thinking Mode
|
|
552
|
+
|
|
553
|
+
Generate training data with explicit reasoning in `<think>` tags, compatible with Qwen3 and DeepSeek-R1:
|
|
554
|
+
|
|
555
|
+
```python
|
|
556
|
+
pipeline = create_pipeline(thinking=True)
|
|
557
|
+
dataset = pipeline.generate(policy, traces=50)
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
Output:
|
|
561
|
+
```json
|
|
562
|
+
{"messages": [
|
|
563
|
+
{"role": "user", "content": "Can I expense a $350 team dinner?"},
|
|
564
|
+
{"role": "assistant", "content": "<think>\nLet me check the expense policy...\n- Rule: Expenses over $50 require manager approval\n- $350 exceeds the $50 threshold\n- Manager approval is required\n</think>\n\nFor a $350 team dinner, you'll need manager approval since it exceeds the $50 threshold. Please submit your expense report with the receipt and request approval from your manager."}
|
|
565
|
+
]}
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
Works with all dataset types (`CONVERSATION`, `INSTRUCTION`, `TOOL_CALL`).
|
|
569
|
+
|
|
281
570
|
## Logic Map Inspection
|
|
282
571
|
|
|
283
572
|
Access the extracted rules programmatically:
|