emdash-core 0.1.7__py3-none-any.whl → 0.1.33__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.
- emdash_core/__init__.py +6 -1
- emdash_core/agent/__init__.py +4 -0
- emdash_core/agent/events.py +52 -1
- emdash_core/agent/inprocess_subagent.py +123 -10
- emdash_core/agent/prompts/__init__.py +6 -0
- emdash_core/agent/prompts/main_agent.py +53 -3
- emdash_core/agent/prompts/plan_mode.py +255 -0
- emdash_core/agent/prompts/subagents.py +84 -16
- emdash_core/agent/prompts/workflow.py +270 -56
- emdash_core/agent/providers/base.py +4 -0
- emdash_core/agent/providers/factory.py +2 -2
- emdash_core/agent/providers/models.py +7 -0
- emdash_core/agent/providers/openai_provider.py +137 -13
- emdash_core/agent/runner/__init__.py +49 -0
- emdash_core/agent/runner/agent_runner.py +753 -0
- emdash_core/agent/runner/context.py +451 -0
- emdash_core/agent/runner/factory.py +108 -0
- emdash_core/agent/runner/plan.py +217 -0
- emdash_core/agent/runner/sdk_runner.py +324 -0
- emdash_core/agent/runner/utils.py +67 -0
- emdash_core/agent/skills.py +358 -0
- emdash_core/agent/toolkit.py +85 -5
- emdash_core/agent/toolkits/plan.py +9 -11
- emdash_core/agent/tools/__init__.py +3 -2
- emdash_core/agent/tools/coding.py +48 -4
- emdash_core/agent/tools/modes.py +207 -55
- emdash_core/agent/tools/search.py +4 -0
- emdash_core/agent/tools/skill.py +193 -0
- emdash_core/agent/tools/spec.py +61 -94
- emdash_core/agent/tools/task.py +41 -2
- emdash_core/agent/tools/tasks.py +15 -78
- emdash_core/api/agent.py +562 -8
- emdash_core/api/index.py +1 -1
- emdash_core/api/projectmd.py +4 -2
- emdash_core/api/router.py +2 -0
- emdash_core/api/skills.py +241 -0
- emdash_core/checkpoint/__init__.py +40 -0
- emdash_core/checkpoint/cli.py +175 -0
- emdash_core/checkpoint/git_operations.py +250 -0
- emdash_core/checkpoint/manager.py +231 -0
- emdash_core/checkpoint/models.py +107 -0
- emdash_core/checkpoint/storage.py +201 -0
- emdash_core/config.py +1 -1
- emdash_core/core/config.py +18 -2
- emdash_core/graph/schema.py +5 -5
- emdash_core/ingestion/orchestrator.py +19 -10
- emdash_core/models/agent.py +1 -1
- emdash_core/server.py +42 -0
- emdash_core/skills/frontend-design/SKILL.md +56 -0
- emdash_core/sse/stream.py +5 -0
- {emdash_core-0.1.7.dist-info → emdash_core-0.1.33.dist-info}/METADATA +2 -2
- {emdash_core-0.1.7.dist-info → emdash_core-0.1.33.dist-info}/RECORD +54 -37
- {emdash_core-0.1.7.dist-info → emdash_core-0.1.33.dist-info}/entry_points.txt +1 -0
- emdash_core/agent/runner.py +0 -601
- {emdash_core-0.1.7.dist-info → emdash_core-0.1.33.dist-info}/WHEEL +0 -0
|
@@ -8,57 +8,183 @@ consistent behavior across agent types.
|
|
|
8
8
|
WORKFLOW_PATTERNS = """
|
|
9
9
|
## Workflow for Complex Tasks
|
|
10
10
|
|
|
11
|
+
### User Plan Mode Commands
|
|
12
|
+
|
|
13
|
+
When the user explicitly asks to "enter plan mode" or says "plan mode":
|
|
14
|
+
- Call `enter_plan_mode(reason="User requested to enter plan mode for task planning")`
|
|
15
|
+
- This REQUIRES user approval before plan mode activates
|
|
16
|
+
- Do NOT ask clarification questions instead - use the tool
|
|
17
|
+
|
|
18
|
+
### CRITICAL: Spawn Plan Agent for Non-Trivial Tasks
|
|
19
|
+
|
|
20
|
+
For ANY task that involves:
|
|
21
|
+
- Creating new features or applications
|
|
22
|
+
- Multi-file changes
|
|
23
|
+
- Architectural decisions
|
|
24
|
+
- Unclear or ambiguous requirements
|
|
25
|
+
|
|
26
|
+
You MUST spawn a **Plan agent** via the `task` tool FIRST before implementing. The Plan agent will:
|
|
27
|
+
1. Explore the codebase to understand patterns and architecture
|
|
28
|
+
2. Design a concrete implementation plan
|
|
29
|
+
3. Return the plan to you
|
|
30
|
+
|
|
31
|
+
After receiving the plan:
|
|
32
|
+
1. Write it to the plan file specified in plan mode (usually `.emdash/plan.md`) using `write_to_file`
|
|
33
|
+
2. Call `exit_plan` to present for user approval
|
|
34
|
+
3. After approval, implement the plan
|
|
35
|
+
|
|
36
|
+
**Plan agent is for IMPLEMENTATION tasks** (building/changing code):
|
|
37
|
+
- "Create a family expense app" → spawn Plan agent
|
|
38
|
+
- "Add authentication routes" → spawn Plan agent
|
|
39
|
+
- "Refactor the database layer" → spawn Plan agent
|
|
40
|
+
|
|
41
|
+
**Plan agent is NOT for RESEARCH tasks** (reading/understanding code):
|
|
42
|
+
- "Read the router and report" → use direct tools, no planning needed
|
|
43
|
+
- "What files handle routing?" → use direct tools or Explore agent
|
|
44
|
+
- "How does authentication work?" → use Explore agent
|
|
45
|
+
- "What does this function do?" → just read and answer
|
|
46
|
+
|
|
47
|
+
**Trivial implementation tasks** (no planning needed):
|
|
48
|
+
- "Fix this typo" → just fix it
|
|
49
|
+
- "Add a log statement here" → just add it
|
|
50
|
+
|
|
11
51
|
### 1. Understand Before Acting
|
|
12
52
|
- Read code before modifying it
|
|
13
|
-
- Ask clarifying questions when requirements are ambiguous
|
|
14
53
|
- Search for similar patterns already in the codebase
|
|
54
|
+
- When requirements are ambiguous, use `ask_followup_question` tool (not text output)
|
|
55
|
+
- ONLY after exploring the codebase first - questions should be informed by research
|
|
56
|
+
- ONLY one question at a time - never ask multiple questions in parallel
|
|
57
|
+
- Ask the most critical question first, then continue based on the answer
|
|
58
|
+
- NEVER ask generic questions like "What platform?" without first understanding the codebase
|
|
15
59
|
|
|
16
60
|
### 2. Break Down Hard Problems
|
|
17
61
|
When facing a task you don't immediately know how to solve:
|
|
18
62
|
|
|
19
|
-
a) **
|
|
20
|
-
b) **
|
|
21
|
-
c) **
|
|
22
|
-
d) **Execute**:
|
|
63
|
+
a) **Spawn Plan Agent**: Call `task(subagent_type="Plan", prompt="...")` to design the approach
|
|
64
|
+
b) **Save Plan**: Write the returned plan to the plan file (specified in plan mode approval)
|
|
65
|
+
c) **Present for Approval**: Call `exit_plan` to show the plan to the user
|
|
66
|
+
d) **Execute**: After approval, implement the plan step by step
|
|
23
67
|
e) **Validate**: Check your work against requirements
|
|
24
68
|
|
|
25
|
-
### 3.
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
-
|
|
69
|
+
### 3. Targeted vs Open-Ended Queries
|
|
70
|
+
|
|
71
|
+
**Targeted queries** (you know what to look for) → Use direct tools:
|
|
72
|
+
- "Read the router" → `glob("**/router*")` then `read_file`
|
|
73
|
+
- "What's in config.ts?" → `read_file("config.ts")`
|
|
74
|
+
- "Find the UserService class" → `grep("class UserService")`
|
|
75
|
+
|
|
76
|
+
**Open-ended queries** (need to explore possibilities) → Spawn Explore agent:
|
|
77
|
+
- "Where are errors handled?" → could be many places
|
|
78
|
+
- "How does authentication work?" → requires understanding multiple files
|
|
79
|
+
- "What is the codebase structure?" → broad exploration
|
|
80
|
+
|
|
81
|
+
### 4. Parallel Tool Execution
|
|
82
|
+
|
|
83
|
+
Run independent searches in parallel (single response with multiple tool calls):
|
|
84
|
+
```
|
|
85
|
+
# Good: parallel independent searches
|
|
86
|
+
glob("**/router*")
|
|
87
|
+
glob("**/pages/**/*.astro")
|
|
88
|
+
→ Both run concurrently, results return together
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### 5. Sub-Agent Decision Matrix
|
|
92
|
+
|
|
93
|
+
| Task Type | Example | Sub-Agent |
|
|
94
|
+
|-----------|---------|-----------|
|
|
95
|
+
| **Research (open-ended)** | "How does auth work?" | Explore |
|
|
96
|
+
| **Research (targeted)** | "Read the router" | None (direct tools) |
|
|
97
|
+
| **Implementation (complex)** | "Add user profiles" | Plan |
|
|
98
|
+
| **Implementation (trivial)** | "Fix this typo" | None (just do it) |
|
|
29
99
|
|
|
30
|
-
|
|
31
|
-
-
|
|
32
|
-
-
|
|
33
|
-
- Prefer sub-agents over doing 5+ search operations yourself
|
|
100
|
+
**Explore agent**: Open-ended research across multiple files
|
|
101
|
+
- "Where are errors handled?"
|
|
102
|
+
- "What is the codebase structure?"
|
|
34
103
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
104
|
+
**Plan agent**: Implementation tasks that modify code
|
|
105
|
+
- New features, refactoring, architectural changes
|
|
106
|
+
- NOT for research/reading tasks
|
|
38
107
|
"""
|
|
39
108
|
|
|
40
109
|
# Exploration strategy for code navigation
|
|
41
110
|
EXPLORATION_STRATEGY = """
|
|
42
111
|
## Exploration Strategy
|
|
43
112
|
|
|
44
|
-
###
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
113
|
+
### Phase 1: Orient (Where to Start)
|
|
114
|
+
Before searching randomly, understand the codebase structure:
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
list_files("src") → Understand directory structure
|
|
118
|
+
glob("**/*.py") → Find all Python files
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Phase 2: Search (Find Relevant Code)
|
|
122
|
+
Use the right tool for the job:
|
|
49
123
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
124
|
+
| Tool | Searches | Use When | Example |
|
|
125
|
+
|------|----------|----------|---------|
|
|
126
|
+
| `glob` | File paths/names | Know filename pattern | `glob("**/auth*.py")` |
|
|
127
|
+
| `grep` | File contents | Know exact text | `grep("def authenticate")` |
|
|
128
|
+
| `semantic_search` | Conceptual meaning | Fuzzy/conceptual | `semantic_search("user login flow")` |
|
|
129
|
+
|
|
130
|
+
**Parallel searches based on multiple hypotheses**:
|
|
131
|
+
When you have context clues, run parallel searches for each possibility:
|
|
132
|
+
```
|
|
133
|
+
# Example: "read the router" in an Astro project
|
|
134
|
+
glob("**/router*") # Files with "router" in name
|
|
135
|
+
glob("**/pages/**/*.astro") # Astro's file-based routing
|
|
136
|
+
→ Both run in parallel, then read the relevant results
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
**Following imports after reading**:
|
|
140
|
+
When you read a file and see an import, read that imported file to complete the picture:
|
|
141
|
+
```
|
|
142
|
+
# After reading src/pages/[...slug].astro which imports AppRouter
|
|
143
|
+
read_file("src/components/Router.tsx") # Follow the import
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Phase 3: Understand (Deep Dive)
|
|
147
|
+
Once you find relevant code:
|
|
148
|
+
|
|
149
|
+
```
|
|
150
|
+
read_file("src/auth/manager.py")
|
|
151
|
+
→ Read the full file to understand implementation
|
|
152
|
+
|
|
153
|
+
read_file("src/auth/manager.py", offset=45, limit=30)
|
|
154
|
+
→ Read specific section (lines 45-75)
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Follow imports and function calls manually by reading related files.
|
|
158
|
+
|
|
159
|
+
### Tool Selection Quick Reference
|
|
160
|
+
|
|
161
|
+
| Goal | Best Tool |
|
|
162
|
+
|------|-----------|
|
|
163
|
+
| Find by filename | `glob` |
|
|
164
|
+
| Find by content | `grep` |
|
|
165
|
+
| Find by concept | `semantic_search` |
|
|
166
|
+
| Read code | `read_file` |
|
|
167
|
+
| List directory | `list_files` |
|
|
168
|
+
| Web research | `web` |
|
|
56
169
|
|
|
57
170
|
### When Stuck
|
|
58
|
-
1.
|
|
59
|
-
2.
|
|
60
|
-
3.
|
|
61
|
-
4. Ask
|
|
171
|
+
1. **Wrong results?** → Try `semantic_search` with different phrasing
|
|
172
|
+
2. **Too many results?** → Add more specific terms to grep
|
|
173
|
+
3. **Need context?** → Read imports at top of file, follow them
|
|
174
|
+
4. **Still lost?** → Ask user ONE focused question with `ask_followup_question` (after exhausting search options)
|
|
175
|
+
|
|
176
|
+
### Stopping Criteria
|
|
177
|
+
You have enough context when you can answer:
|
|
178
|
+
- What files/functions are involved?
|
|
179
|
+
- What patterns does the codebase use?
|
|
180
|
+
- What would need to change?
|
|
181
|
+
|
|
182
|
+
Stop exploring when you can confidently describe the implementation approach.
|
|
183
|
+
|
|
184
|
+
### CRITICAL: After Clarification → Act
|
|
185
|
+
**When you receive an answer to a clarification question, your NEXT action must be implementation/planning - NOT more exploration.**
|
|
186
|
+
|
|
187
|
+
The user answered your question. You now have what you need. Act on it.
|
|
62
188
|
"""
|
|
63
189
|
|
|
64
190
|
# Output formatting guidelines
|
|
@@ -68,7 +194,41 @@ OUTPUT_GUIDELINES = """
|
|
|
68
194
|
- Show relevant code snippets
|
|
69
195
|
- Be concise but thorough
|
|
70
196
|
- Explain your reasoning for complex decisions
|
|
71
|
-
- NEVER provide time estimates (hours, days, weeks)
|
|
197
|
+
- NEVER provide time estimates (hours, days, weeks)
|
|
198
|
+
"""
|
|
199
|
+
|
|
200
|
+
# Parallel tool execution patterns
|
|
201
|
+
PARALLEL_EXECUTION = """
|
|
202
|
+
## Parallel Tool Execution
|
|
203
|
+
|
|
204
|
+
You can execute multiple tools concurrently by invoking them in a single response.
|
|
205
|
+
|
|
206
|
+
### How It Works
|
|
207
|
+
- Multiple tool invocations in one message execute concurrently, not sequentially
|
|
208
|
+
- Results return together before continuing
|
|
209
|
+
|
|
210
|
+
### Use Parallel Execution For:
|
|
211
|
+
- Reading multiple files simultaneously
|
|
212
|
+
- Running independent grep/glob searches
|
|
213
|
+
- Launching multiple sub-agents for independent exploration
|
|
214
|
+
- Any independent operations that don't depend on each other
|
|
215
|
+
|
|
216
|
+
### Use Sequential Execution When:
|
|
217
|
+
- One tool's output is needed for the next (dependencies)
|
|
218
|
+
- Example: read a file before editing it
|
|
219
|
+
- Example: mkdir before cp, git add before git commit
|
|
220
|
+
|
|
221
|
+
### Example
|
|
222
|
+
Instead of:
|
|
223
|
+
1. grep for "authenticate" → wait for results
|
|
224
|
+
2. grep for "login" → wait for results
|
|
225
|
+
3. grep for "session" → wait for results
|
|
226
|
+
|
|
227
|
+
Do this in ONE message:
|
|
228
|
+
- grep for "authenticate"
|
|
229
|
+
- grep for "login"
|
|
230
|
+
- grep for "session"
|
|
231
|
+
→ All three run concurrently, results return together
|
|
72
232
|
"""
|
|
73
233
|
|
|
74
234
|
# Efficiency rules for sub-agents with limited turns
|
|
@@ -78,6 +238,7 @@ EFFICIENCY_RULES = """
|
|
|
78
238
|
- If 3 searches return nothing, try different terms or report "not found"
|
|
79
239
|
- Read only the parts of files you need (use offset/limit for large files)
|
|
80
240
|
- Don't read entire files when you only need a specific function
|
|
241
|
+
- Parallelize independent searches - invoke multiple tools in one response
|
|
81
242
|
"""
|
|
82
243
|
|
|
83
244
|
# Structured output format for exploration results
|
|
@@ -96,41 +257,94 @@ Structure your final response as:
|
|
|
96
257
|
**Confidence**: high/medium/low
|
|
97
258
|
"""
|
|
98
259
|
|
|
99
|
-
# Plan template for Plan agents
|
|
260
|
+
# Plan template for Plan sub-agents (returns to main agent)
|
|
100
261
|
PLAN_TEMPLATE = """
|
|
101
|
-
## Plan
|
|
102
|
-
Use `write_plan` to save your plan. Structure it as:
|
|
262
|
+
## Adaptive Plan Structure
|
|
103
263
|
|
|
104
|
-
|
|
105
|
-
# [Feature Name] Implementation Plan
|
|
264
|
+
Adapt your plan structure based on these factors:
|
|
106
265
|
|
|
107
|
-
|
|
108
|
-
|
|
266
|
+
| Factor | Simple Task | Complex Task |
|
|
267
|
+
|--------|-------------|--------------|
|
|
268
|
+
| **Complexity** | Checklist format | Phases with rollback points |
|
|
269
|
+
| **Risk** | Minimal detail | Detailed with edge cases |
|
|
270
|
+
| **Uncertainty** | Prescriptive steps | Exploratory phases first |
|
|
271
|
+
| **Scope** | Implicit boundaries | Explicit scope & non-goals |
|
|
109
272
|
|
|
110
|
-
|
|
111
|
-
- `path/to/file.py` - What changes
|
|
273
|
+
### Required Sections (always include)
|
|
112
274
|
|
|
113
|
-
|
|
114
|
-
- `path/to/new.py` - Purpose
|
|
275
|
+
**Summary**: What and why (1-2 sentences)
|
|
115
276
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
- Specific changes to make
|
|
119
|
-
- Code patterns to follow (reference existing code)
|
|
277
|
+
**Critical Files**: Files to modify with line numbers - this bridges to execution
|
|
278
|
+
- `path/to/file.py:45-60` - What changes
|
|
120
279
|
|
|
121
|
-
|
|
280
|
+
### Conditional Sections (include only if needed)
|
|
122
281
|
|
|
123
|
-
|
|
124
|
-
-
|
|
282
|
+
**Files to Create**: Only if creating new files
|
|
283
|
+
**Phases**: Only for multi-phase work (each phase independently testable)
|
|
284
|
+
**Risks**: Only if non-trivial risks exist
|
|
285
|
+
**Open Questions**: Only if genuine unknowns - mark explicitly, don't hide uncertainty
|
|
286
|
+
**Testing**: Only if tests needed beyond obvious
|
|
125
287
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
288
|
+
### Principles
|
|
289
|
+
- Each section must "earn its place" - no empty boilerplate
|
|
290
|
+
- Detail scales with risk (logout button ≠ database migration)
|
|
291
|
+
- Follow existing codebase patterns, not novel approaches
|
|
292
|
+
- Mark unknowns explicitly rather than pretending certainty
|
|
293
|
+
- **NEVER include time estimates** (no "Day 1-2", "Week 1", hours, days, sprints, timelines)
|
|
294
|
+
|
|
295
|
+
### Anti-patterns to Avoid
|
|
296
|
+
- Over-planning simple tasks
|
|
297
|
+
- Under-planning complex/risky ones
|
|
298
|
+
- Hiding uncertainty behind confident language
|
|
299
|
+
- Ignoring existing patterns in the codebase
|
|
300
|
+
- Including time estimates (Days, Weeks, Sprints, etc.) - focus on WHAT, not WHEN
|
|
301
|
+
|
|
302
|
+
Your output will be reviewed by the main agent, who will consolidate findings and submit the final plan for user approval.
|
|
129
303
|
"""
|
|
130
304
|
|
|
131
|
-
#
|
|
305
|
+
# Guidelines (no time estimates)
|
|
132
306
|
SIZING_GUIDELINES = """
|
|
133
|
-
##
|
|
307
|
+
## Guidelines
|
|
134
308
|
- NEVER include time estimates (no hours, days, weeks, sprints, timelines)
|
|
135
|
-
-
|
|
309
|
+
- Focus on what needs to be done, not how long it takes
|
|
310
|
+
"""
|
|
311
|
+
|
|
312
|
+
# Todo list usage guidance
|
|
313
|
+
TODO_LIST_GUIDANCE = """
|
|
314
|
+
## Todo List Usage
|
|
315
|
+
|
|
316
|
+
You have access to `write_todo` and `update_todo_list` tools. Use them strategically - not for every task.
|
|
317
|
+
|
|
318
|
+
### When to USE the todo list:
|
|
319
|
+
- **3+ distinct steps** needed to complete the task
|
|
320
|
+
- **Multiple files** need to be changed
|
|
321
|
+
- **User gives a list** of tasks (numbered or comma-separated)
|
|
322
|
+
- **Complex feature** implementation with multiple pieces
|
|
323
|
+
- **Need to track progress** across iterations or when task spans multiple tool calls
|
|
324
|
+
|
|
325
|
+
### When to SKIP the todo list:
|
|
326
|
+
- **Single focused change** (one edit, one file)
|
|
327
|
+
- **Trivial fixes** (typo, add a log statement)
|
|
328
|
+
- **Research/informational questions** (just answer them)
|
|
329
|
+
- **Task completes in 1-2 steps** (just do it)
|
|
330
|
+
|
|
331
|
+
### Examples:
|
|
332
|
+
|
|
333
|
+
**Use todo list:**
|
|
334
|
+
- "Implement user authentication with login, logout, and session management" → 3+ steps, multiple files
|
|
335
|
+
- "Fix these 5 type errors" → list of tasks
|
|
336
|
+
- "Add dark mode support across the app" → complex, multiple files
|
|
337
|
+
|
|
338
|
+
**Skip todo list:**
|
|
339
|
+
- "Fix the typo in README" → single focused change
|
|
340
|
+
- "Add tool_choice parameter to this function" → one edit
|
|
341
|
+
- "What files handle routing?" → informational question
|
|
342
|
+
- "Update the error message here" → trivial fix
|
|
343
|
+
|
|
344
|
+
### Usage pattern:
|
|
345
|
+
1. Use `write_todo(title="...", reset=true)` to start fresh with first task
|
|
346
|
+
2. Use `write_todo(title="...")` to add more tasks
|
|
347
|
+
3. Use `update_todo_list(task_id="1", status="in_progress")` when starting a task
|
|
348
|
+
4. Use `update_todo_list(task_id="1", status="completed")` when done
|
|
349
|
+
5. Mark tasks complete IMMEDIATELY after finishing - don't batch completions
|
|
136
350
|
"""
|
|
@@ -34,11 +34,13 @@ class LLMResponse:
|
|
|
34
34
|
"""Unified response from any LLM provider."""
|
|
35
35
|
|
|
36
36
|
content: Optional[str] = None
|
|
37
|
+
thinking: Optional[str] = None # Model's chain-of-thought reasoning
|
|
37
38
|
tool_calls: list[ToolCall] = field(default_factory=list)
|
|
38
39
|
raw: Any = None # Original provider response
|
|
39
40
|
stop_reason: Optional[str] = None
|
|
40
41
|
input_tokens: int = 0 # Tokens in the request
|
|
41
42
|
output_tokens: int = 0 # Tokens in the response
|
|
43
|
+
thinking_tokens: int = 0 # Tokens used for thinking (if available)
|
|
42
44
|
|
|
43
45
|
|
|
44
46
|
class LLMProvider(ABC):
|
|
@@ -54,6 +56,7 @@ class LLMProvider(ABC):
|
|
|
54
56
|
tools: Optional[list[dict]] = None,
|
|
55
57
|
system: Optional[str] = None,
|
|
56
58
|
reasoning: bool = False,
|
|
59
|
+
thinking: bool = False,
|
|
57
60
|
images: Optional[list[ImageContent]] = None,
|
|
58
61
|
) -> LLMResponse:
|
|
59
62
|
"""Send a chat completion request.
|
|
@@ -63,6 +66,7 @@ class LLMProvider(ABC):
|
|
|
63
66
|
tools: Optional list of tool schemas
|
|
64
67
|
system: Optional system prompt (will be prepended or handled per provider)
|
|
65
68
|
reasoning: Enable reasoning mode (for models that support it)
|
|
69
|
+
thinking: Enable extended thinking (for models that support it)
|
|
66
70
|
images: Optional list of images for vision-capable models
|
|
67
71
|
|
|
68
72
|
Returns:
|
|
@@ -13,8 +13,8 @@ from .transformers_provider import TransformersProvider
|
|
|
13
13
|
# Configuration - Single source of truth
|
|
14
14
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
15
15
|
|
|
16
|
-
# Default model alias
|
|
17
|
-
DEFAULT_MODEL = "fireworks:accounts/fireworks/models/minimax-m2p1"
|
|
16
|
+
# Default model alias - uses OPENAI_BASE_URL if set
|
|
17
|
+
DEFAULT_MODEL = os.environ.get("EMDASH_DEFAULT_MODEL", "fireworks:accounts/fireworks/models/minimax-m2p1")
|
|
18
18
|
|
|
19
19
|
# Default API key environment variable (used by default model)
|
|
20
20
|
DEFAULT_API_KEY_ENV = "FIREWORKS_API_KEY"
|
|
@@ -16,6 +16,7 @@ class ChatModelSpec:
|
|
|
16
16
|
max_output_tokens: int # Max output tokens
|
|
17
17
|
supports_tools: bool # Whether model supports function calling
|
|
18
18
|
supports_vision: bool # Whether model supports image input
|
|
19
|
+
supports_thinking: bool # Whether model supports extended thinking
|
|
19
20
|
description: str # Human-readable description
|
|
20
21
|
|
|
21
22
|
|
|
@@ -43,6 +44,7 @@ class ChatModel(Enum):
|
|
|
43
44
|
max_output_tokens=32000,
|
|
44
45
|
supports_tools=True,
|
|
45
46
|
supports_vision=True,
|
|
47
|
+
supports_thinking=True,
|
|
46
48
|
description="Claude Opus 4 - Most capable, complex reasoning",
|
|
47
49
|
)
|
|
48
50
|
|
|
@@ -54,6 +56,7 @@ class ChatModel(Enum):
|
|
|
54
56
|
max_output_tokens=16000,
|
|
55
57
|
supports_tools=True,
|
|
56
58
|
supports_vision=True,
|
|
59
|
+
supports_thinking=True,
|
|
57
60
|
description="Claude Sonnet 4 - Balanced performance and cost",
|
|
58
61
|
)
|
|
59
62
|
|
|
@@ -65,6 +68,7 @@ class ChatModel(Enum):
|
|
|
65
68
|
max_output_tokens=8192,
|
|
66
69
|
supports_tools=True,
|
|
67
70
|
supports_vision=True,
|
|
71
|
+
supports_thinking=False,
|
|
68
72
|
description="Claude Haiku 4.5 - Fast and efficient",
|
|
69
73
|
)
|
|
70
74
|
|
|
@@ -80,6 +84,7 @@ class ChatModel(Enum):
|
|
|
80
84
|
max_output_tokens=16384,
|
|
81
85
|
supports_tools=True,
|
|
82
86
|
supports_vision=True,
|
|
87
|
+
supports_thinking=False,
|
|
83
88
|
description="GPT-4o Mini - Fast and cost-effective",
|
|
84
89
|
)
|
|
85
90
|
|
|
@@ -95,6 +100,7 @@ class ChatModel(Enum):
|
|
|
95
100
|
max_output_tokens=16384,
|
|
96
101
|
supports_tools=True,
|
|
97
102
|
supports_vision=False,
|
|
103
|
+
supports_thinking=False,
|
|
98
104
|
description="GLM-4P7 - Fireworks GLM model",
|
|
99
105
|
)
|
|
100
106
|
|
|
@@ -106,6 +112,7 @@ class ChatModel(Enum):
|
|
|
106
112
|
max_output_tokens=16384,
|
|
107
113
|
supports_tools=True,
|
|
108
114
|
supports_vision=False,
|
|
115
|
+
supports_thinking=False,
|
|
109
116
|
description="MiniMax M2P1 - Long context model",
|
|
110
117
|
)
|
|
111
118
|
|