spec4 0.1.0__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.
- spec4-0.1.0/PKG-INFO +179 -0
- spec4-0.1.0/README.md +163 -0
- spec4-0.1.0/pyproject.toml +37 -0
- spec4-0.1.0/src/spec4/__init__.py +1 -0
- spec4-0.1.0/src/spec4/a2a_bus.py +60 -0
- spec4-0.1.0/src/spec4/agents/__init__.py +0 -0
- spec4-0.1.0/src/spec4/agents/brainstormer.py +258 -0
- spec4-0.1.0/src/spec4/agents/phaser.py +247 -0
- spec4-0.1.0/src/spec4/agents/reviewer.py +246 -0
- spec4-0.1.0/src/spec4/agents/stack_advisor.py +281 -0
- spec4-0.1.0/src/spec4/app.py +267 -0
- spec4-0.1.0/src/spec4/app_constants.py +48 -0
- spec4-0.1.0/src/spec4/assets/favicon.svg +5 -0
- spec4-0.1.0/src/spec4/assets/v3.css +270 -0
- spec4-0.1.0/src/spec4/browser_prefs.py +5 -0
- spec4-0.1.0/src/spec4/callbacks.py +713 -0
- spec4-0.1.0/src/spec4/layouts.py +788 -0
- spec4-0.1.0/src/spec4/project_manager.py +137 -0
- spec4-0.1.0/src/spec4/providers.py +101 -0
- spec4-0.1.0/src/spec4/py.typed +0 -0
- spec4-0.1.0/src/spec4/session.py +137 -0
- spec4-0.1.0/src/spec4/tavily_mcp.py +195 -0
spec4-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: spec4
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: AI-assisted software project planning — from idea to executable coding phases
|
|
5
|
+
Author: Robert Crowe
|
|
6
|
+
Author-email: Robert Crowe <crowe3555@gmail.com>
|
|
7
|
+
License: Apache-2.0
|
|
8
|
+
Requires-Dist: a2a-sdk>=0.3.24
|
|
9
|
+
Requires-Dist: dash>=2.17.0
|
|
10
|
+
Requires-Dist: dash-iconify>=0.1.2
|
|
11
|
+
Requires-Dist: dash-mantine-components>=0.14.0
|
|
12
|
+
Requires-Dist: litellm>=1.82.0
|
|
13
|
+
Requires-Dist: mcp>=1.26.0
|
|
14
|
+
Requires-Python: >=3.12
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
|
|
17
|
+
# Spec4 AI
|
|
18
|
+
|
|
19
|
+
> AI-assisted software project planning — from idea to executable coding phases.
|
|
20
|
+
|
|
21
|
+
Spec4 is a Dash app (using Dash Mantine Components) that guides you through three stages of project planning using a pipeline of specialised LLM agents. Start with a rough idea and finish with a set of structured, ordered development phases ready to hand to an AI coding agent like Claude Code.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
|
|
27
|
+
**Option 1 — Install from PyPI (recommended for most users):**
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
uv tool install spec4
|
|
31
|
+
spec4
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**Option 2 — Run from source (for contributors and developers):**
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
git clone https://github.com/robertcrowe/spec4
|
|
38
|
+
cd spec4
|
|
39
|
+
make spec4
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
The app will be available at [http://localhost:8050](http://localhost:8050) in both cases.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Features
|
|
47
|
+
|
|
48
|
+
- **Four-stage planning pipeline** — Reviewer (optional) → Brainstormer → StackAdvisor → Phaser
|
|
49
|
+
- **Any LLM provider** — works with OpenAI, Anthropic, Google Gemini, Cohere, and Mistral via LiteLLM
|
|
50
|
+
- **Web search grounding** — all agents can search the web via Tavily to find canonical documentation
|
|
51
|
+
- **Saved credentials** — optionally remember your provider, model, and API keys in the browser (localStorage via `dcc.Store` — never sent to or stored on the server)
|
|
52
|
+
- **Incremental output** — each agent produces a downloadable JSON or ZIP file you can reuse in a later session
|
|
53
|
+
- **Jump-in anywhere** — start at StackAdvisor or Phaser by uploading previously saved output
|
|
54
|
+
- **Project persistence** — artifacts saved to a `.spec4/` folder inside your chosen project directory
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Agents
|
|
59
|
+
|
|
60
|
+
### 🔍 Reviewer *(optional)*
|
|
61
|
+
Analyzes an existing project directory to understand its architecture, technology stack, and coding style. Results inform Brainstormer and StackAdvisor when working on brownfield projects. Produces `code_review.json`.
|
|
62
|
+
|
|
63
|
+
### 🧠 Brainstormer
|
|
64
|
+
Develops a clear project vision through focused, one-at-a-time questions. Identifies technical standards via web search and embeds canonical documentation links in the output. Produces `vision.json`.
|
|
65
|
+
|
|
66
|
+
### ⚙️ StackAdvisor
|
|
67
|
+
Recommends languages, frameworks, hosting, and infrastructure based on the vision. Compares options, explains trade-offs, and uses web search to ground every recommendation. Produces `stack.json`.
|
|
68
|
+
|
|
69
|
+
### 📋 Phaser
|
|
70
|
+
Decomposes the vision and stack into an ordered sequence of development phases:
|
|
71
|
+
|
|
72
|
+
- **Phase 1 is always a steel thread** — a minimal end-to-end path that validates the core architecture
|
|
73
|
+
- **Each phase builds on the previous one**
|
|
74
|
+
- **Stack spec fidelity** — confirms before adding any dependency not in the stack spec
|
|
75
|
+
- **Verification criteria** — every phase includes the exact command needed to confirm it succeeded
|
|
76
|
+
|
|
77
|
+
Produces `phases.zip` with one JSON file per phase.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Requirements
|
|
82
|
+
|
|
83
|
+
- Python 3.12+
|
|
84
|
+
- **[uv](https://docs.astral.sh/uv/) package manager**
|
|
85
|
+
- An API key for at least one supported LLM provider
|
|
86
|
+
- _(Optional)_ A [Tavily](https://tavily.com/) API key for web search
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Installation & first run
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
git clone <repo-url>
|
|
94
|
+
cd spec4
|
|
95
|
+
make spec4
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
`make spec4` runs `uv sync` (which creates a `.venv` in the project directory and installs all
|
|
99
|
+
dependencies into it) and then launches the app. All packages stay inside `.venv` — nothing is
|
|
100
|
+
installed into your global Python.
|
|
101
|
+
|
|
102
|
+
Then open [http://localhost:8050](http://localhost:8050) in your browser.
|
|
103
|
+
|
|
104
|
+
> **Subsequent runs:** `make run` (or `uv run python src/spec4/app.py`) reuses the existing `.venv`.
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Usage
|
|
109
|
+
|
|
110
|
+
1. **Select a project directory** — new or existing; artifacts are saved to `.spec4/` inside it.
|
|
111
|
+
2. **Connect** — select a provider, enter your API key, and choose a model. Optionally add a Tavily key for web search.
|
|
112
|
+
3. **Choose a starting point** — pick an agent to begin with.
|
|
113
|
+
4. **Plan** — chat with each agent. When an agent completes, download the result and continue to the next agent.
|
|
114
|
+
|
|
115
|
+
### Picking up where you left off
|
|
116
|
+
|
|
117
|
+
Each session auto-saves to `.spec4/` inside your project directory. On a future visit, select the same directory and previously completed artifacts will be loaded automatically. You can also upload JSON files manually on the agent-select screen.
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Project structure
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
src/spec4/
|
|
125
|
+
├── app.py # Dash entry point — app wiring, root layout, page render
|
|
126
|
+
├── app_constants.py # Shared constants (theme, routes, fonts)
|
|
127
|
+
├── session.py # Session defaults, agent runner, artifact persistence
|
|
128
|
+
├── layouts.py # All page layout functions
|
|
129
|
+
├── callbacks.py # All Dash server-side callbacks
|
|
130
|
+
├── providers.py # Provider/model registry, live model fetching
|
|
131
|
+
├── tavily_mcp.py # Tavily web search integration
|
|
132
|
+
├── project_manager.py # .spec4/ artifact persistence
|
|
133
|
+
├── a2a_bus.py # In-memory A2A task bus
|
|
134
|
+
└── agents/
|
|
135
|
+
├── reviewer.py # Code review agent
|
|
136
|
+
├── brainstormer.py # Vision development agent
|
|
137
|
+
├── stack_advisor.py # Technology stack recommendation agent
|
|
138
|
+
└── phaser.py # Incremental phase planning agent
|
|
139
|
+
tests/ # pytest test suite
|
|
140
|
+
Makefile # Common commands
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Development
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
make spec4 # First-time setup: create .venv, install deps, and launch
|
|
149
|
+
make install # Create .venv and install all dependencies (uv sync)
|
|
150
|
+
make run # Start the app (http://localhost:8050)
|
|
151
|
+
make dev # Start with debug/hot-reload enabled
|
|
152
|
+
make test # Run tests
|
|
153
|
+
make lint # Lint check with ruff
|
|
154
|
+
make serve # Production server via gunicorn (requires: uv add gunicorn)
|
|
155
|
+
|
|
156
|
+
# Add a dependency (always use uv so it stays in .venv)
|
|
157
|
+
uv add <package>
|
|
158
|
+
uv add --dev <package>
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Supported providers
|
|
164
|
+
|
|
165
|
+
| Provider | Models fetched from |
|
|
166
|
+
|----------|-------------------|
|
|
167
|
+
| OpenAI | `api.openai.com/v1/models` |
|
|
168
|
+
| Anthropic | `api.anthropic.com/v1/models` |
|
|
169
|
+
| Google Gemini | `generativelanguage.googleapis.com` |
|
|
170
|
+
| Cohere | `api.cohere.com/v2/models` |
|
|
171
|
+
| Mistral | `api.mistral.ai/v1/models` |
|
|
172
|
+
|
|
173
|
+
Models are fetched live from each provider's API when you connect, with a hardcoded fallback list if the API is unavailable.
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## License
|
|
178
|
+
|
|
179
|
+
Apache 2.0 — see [LICENSE](LICENSE) for details.
|
spec4-0.1.0/README.md
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# Spec4 AI
|
|
2
|
+
|
|
3
|
+
> AI-assisted software project planning — from idea to executable coding phases.
|
|
4
|
+
|
|
5
|
+
Spec4 is a Dash app (using Dash Mantine Components) that guides you through three stages of project planning using a pipeline of specialised LLM agents. Start with a rough idea and finish with a set of structured, ordered development phases ready to hand to an AI coding agent like Claude Code.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
**Option 1 — Install from PyPI (recommended for most users):**
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
uv tool install spec4
|
|
15
|
+
spec4
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
**Option 2 — Run from source (for contributors and developers):**
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
git clone https://github.com/robertcrowe/spec4
|
|
22
|
+
cd spec4
|
|
23
|
+
make spec4
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
The app will be available at [http://localhost:8050](http://localhost:8050) in both cases.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Features
|
|
31
|
+
|
|
32
|
+
- **Four-stage planning pipeline** — Reviewer (optional) → Brainstormer → StackAdvisor → Phaser
|
|
33
|
+
- **Any LLM provider** — works with OpenAI, Anthropic, Google Gemini, Cohere, and Mistral via LiteLLM
|
|
34
|
+
- **Web search grounding** — all agents can search the web via Tavily to find canonical documentation
|
|
35
|
+
- **Saved credentials** — optionally remember your provider, model, and API keys in the browser (localStorage via `dcc.Store` — never sent to or stored on the server)
|
|
36
|
+
- **Incremental output** — each agent produces a downloadable JSON or ZIP file you can reuse in a later session
|
|
37
|
+
- **Jump-in anywhere** — start at StackAdvisor or Phaser by uploading previously saved output
|
|
38
|
+
- **Project persistence** — artifacts saved to a `.spec4/` folder inside your chosen project directory
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Agents
|
|
43
|
+
|
|
44
|
+
### 🔍 Reviewer *(optional)*
|
|
45
|
+
Analyzes an existing project directory to understand its architecture, technology stack, and coding style. Results inform Brainstormer and StackAdvisor when working on brownfield projects. Produces `code_review.json`.
|
|
46
|
+
|
|
47
|
+
### 🧠 Brainstormer
|
|
48
|
+
Develops a clear project vision through focused, one-at-a-time questions. Identifies technical standards via web search and embeds canonical documentation links in the output. Produces `vision.json`.
|
|
49
|
+
|
|
50
|
+
### ⚙️ StackAdvisor
|
|
51
|
+
Recommends languages, frameworks, hosting, and infrastructure based on the vision. Compares options, explains trade-offs, and uses web search to ground every recommendation. Produces `stack.json`.
|
|
52
|
+
|
|
53
|
+
### 📋 Phaser
|
|
54
|
+
Decomposes the vision and stack into an ordered sequence of development phases:
|
|
55
|
+
|
|
56
|
+
- **Phase 1 is always a steel thread** — a minimal end-to-end path that validates the core architecture
|
|
57
|
+
- **Each phase builds on the previous one**
|
|
58
|
+
- **Stack spec fidelity** — confirms before adding any dependency not in the stack spec
|
|
59
|
+
- **Verification criteria** — every phase includes the exact command needed to confirm it succeeded
|
|
60
|
+
|
|
61
|
+
Produces `phases.zip` with one JSON file per phase.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Requirements
|
|
66
|
+
|
|
67
|
+
- Python 3.12+
|
|
68
|
+
- **[uv](https://docs.astral.sh/uv/) package manager**
|
|
69
|
+
- An API key for at least one supported LLM provider
|
|
70
|
+
- _(Optional)_ A [Tavily](https://tavily.com/) API key for web search
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Installation & first run
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
git clone <repo-url>
|
|
78
|
+
cd spec4
|
|
79
|
+
make spec4
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
`make spec4` runs `uv sync` (which creates a `.venv` in the project directory and installs all
|
|
83
|
+
dependencies into it) and then launches the app. All packages stay inside `.venv` — nothing is
|
|
84
|
+
installed into your global Python.
|
|
85
|
+
|
|
86
|
+
Then open [http://localhost:8050](http://localhost:8050) in your browser.
|
|
87
|
+
|
|
88
|
+
> **Subsequent runs:** `make run` (or `uv run python src/spec4/app.py`) reuses the existing `.venv`.
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Usage
|
|
93
|
+
|
|
94
|
+
1. **Select a project directory** — new or existing; artifacts are saved to `.spec4/` inside it.
|
|
95
|
+
2. **Connect** — select a provider, enter your API key, and choose a model. Optionally add a Tavily key for web search.
|
|
96
|
+
3. **Choose a starting point** — pick an agent to begin with.
|
|
97
|
+
4. **Plan** — chat with each agent. When an agent completes, download the result and continue to the next agent.
|
|
98
|
+
|
|
99
|
+
### Picking up where you left off
|
|
100
|
+
|
|
101
|
+
Each session auto-saves to `.spec4/` inside your project directory. On a future visit, select the same directory and previously completed artifacts will be loaded automatically. You can also upload JSON files manually on the agent-select screen.
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## Project structure
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
src/spec4/
|
|
109
|
+
├── app.py # Dash entry point — app wiring, root layout, page render
|
|
110
|
+
├── app_constants.py # Shared constants (theme, routes, fonts)
|
|
111
|
+
├── session.py # Session defaults, agent runner, artifact persistence
|
|
112
|
+
├── layouts.py # All page layout functions
|
|
113
|
+
├── callbacks.py # All Dash server-side callbacks
|
|
114
|
+
├── providers.py # Provider/model registry, live model fetching
|
|
115
|
+
├── tavily_mcp.py # Tavily web search integration
|
|
116
|
+
├── project_manager.py # .spec4/ artifact persistence
|
|
117
|
+
├── a2a_bus.py # In-memory A2A task bus
|
|
118
|
+
└── agents/
|
|
119
|
+
├── reviewer.py # Code review agent
|
|
120
|
+
├── brainstormer.py # Vision development agent
|
|
121
|
+
├── stack_advisor.py # Technology stack recommendation agent
|
|
122
|
+
└── phaser.py # Incremental phase planning agent
|
|
123
|
+
tests/ # pytest test suite
|
|
124
|
+
Makefile # Common commands
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Development
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
make spec4 # First-time setup: create .venv, install deps, and launch
|
|
133
|
+
make install # Create .venv and install all dependencies (uv sync)
|
|
134
|
+
make run # Start the app (http://localhost:8050)
|
|
135
|
+
make dev # Start with debug/hot-reload enabled
|
|
136
|
+
make test # Run tests
|
|
137
|
+
make lint # Lint check with ruff
|
|
138
|
+
make serve # Production server via gunicorn (requires: uv add gunicorn)
|
|
139
|
+
|
|
140
|
+
# Add a dependency (always use uv so it stays in .venv)
|
|
141
|
+
uv add <package>
|
|
142
|
+
uv add --dev <package>
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Supported providers
|
|
148
|
+
|
|
149
|
+
| Provider | Models fetched from |
|
|
150
|
+
|----------|-------------------|
|
|
151
|
+
| OpenAI | `api.openai.com/v1/models` |
|
|
152
|
+
| Anthropic | `api.anthropic.com/v1/models` |
|
|
153
|
+
| Google Gemini | `generativelanguage.googleapis.com` |
|
|
154
|
+
| Cohere | `api.cohere.com/v2/models` |
|
|
155
|
+
| Mistral | `api.mistral.ai/v1/models` |
|
|
156
|
+
|
|
157
|
+
Models are fetched live from each provider's API when you connect, with a hardcoded fallback list if the API is unavailable.
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## License
|
|
162
|
+
|
|
163
|
+
Apache 2.0 — see [LICENSE](LICENSE) for details.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "spec4"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "AI-assisted software project planning — from idea to executable coding phases"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = { text = "Apache-2.0" }
|
|
7
|
+
authors = [
|
|
8
|
+
{ name = "Robert Crowe", email = "crowe3555@gmail.com" }
|
|
9
|
+
]
|
|
10
|
+
requires-python = ">=3.12"
|
|
11
|
+
dependencies = [
|
|
12
|
+
"a2a-sdk>=0.3.24",
|
|
13
|
+
"dash>=2.17.0",
|
|
14
|
+
"dash-iconify>=0.1.2",
|
|
15
|
+
"dash-mantine-components>=0.14.0",
|
|
16
|
+
"litellm>=1.82.0",
|
|
17
|
+
"mcp>=1.26.0",
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
[project.scripts]
|
|
21
|
+
spec4 = "spec4.app:main"
|
|
22
|
+
|
|
23
|
+
[build-system]
|
|
24
|
+
requires = ["uv_build>=0.10.0,<0.11.0"]
|
|
25
|
+
build-backend = "uv_build"
|
|
26
|
+
|
|
27
|
+
[dependency-groups]
|
|
28
|
+
dev = [
|
|
29
|
+
"pytest>=9.0.2",
|
|
30
|
+
"pytest-cov>=7.1.0",
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
[tool.hatch.build.targets.sdist]
|
|
34
|
+
exclude = [
|
|
35
|
+
"Makefile.publish",
|
|
36
|
+
"dist/",
|
|
37
|
+
]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.0"
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import uuid
|
|
4
|
+
|
|
5
|
+
from a2a.types import (
|
|
6
|
+
Message,
|
|
7
|
+
Part,
|
|
8
|
+
Role,
|
|
9
|
+
Task,
|
|
10
|
+
TaskState,
|
|
11
|
+
TaskStatus,
|
|
12
|
+
TextPart,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def make_message(role: Role, text: str, task_id: str | None = None, context_id: str | None = None) -> Message:
|
|
17
|
+
"""Create an A2A Message with a single TextPart."""
|
|
18
|
+
return Message(
|
|
19
|
+
role=role,
|
|
20
|
+
message_id=str(uuid.uuid4()),
|
|
21
|
+
parts=[Part(root=TextPart(text=text))],
|
|
22
|
+
task_id=task_id,
|
|
23
|
+
context_id=context_id,
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def create_task(context_id: str, initial_message: Message, session: dict) -> Task:
|
|
28
|
+
"""Create a new A2A Task in submitted state and store it in session."""
|
|
29
|
+
task_id = str(uuid.uuid4())
|
|
30
|
+
msg = Message(
|
|
31
|
+
role=initial_message.role,
|
|
32
|
+
message_id=initial_message.message_id,
|
|
33
|
+
parts=initial_message.parts,
|
|
34
|
+
task_id=task_id,
|
|
35
|
+
context_id=context_id,
|
|
36
|
+
)
|
|
37
|
+
task = Task(
|
|
38
|
+
id=task_id,
|
|
39
|
+
context_id=context_id,
|
|
40
|
+
status=TaskStatus(state=TaskState.submitted),
|
|
41
|
+
history=[msg],
|
|
42
|
+
)
|
|
43
|
+
session["a2a_tasks"][task_id] = task
|
|
44
|
+
return task
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def update_task(task_id: str, state: TaskState, message: Message | None = None, session: dict = None) -> Task:
|
|
48
|
+
"""Update a task's state and optionally append a message to its history."""
|
|
49
|
+
task: Task = session["a2a_tasks"][task_id]
|
|
50
|
+
new_history = list(task.history or [])
|
|
51
|
+
if message is not None:
|
|
52
|
+
new_history.append(message)
|
|
53
|
+
updated = task.model_copy(
|
|
54
|
+
update={
|
|
55
|
+
"status": TaskStatus(state=state, message=message),
|
|
56
|
+
"history": new_history,
|
|
57
|
+
}
|
|
58
|
+
)
|
|
59
|
+
session["a2a_tasks"][task_id] = updated
|
|
60
|
+
return updated
|
|
File without changes
|