agent-comfy-ui-api-workflow 0.0.1__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.
Files changed (55) hide show
  1. agent_comfy_ui_api_workflow-0.0.1/.gitignore +10 -0
  2. agent_comfy_ui_api_workflow-0.0.1/LICENSE +0 -0
  3. agent_comfy_ui_api_workflow-0.0.1/PKG-INFO +191 -0
  4. agent_comfy_ui_api_workflow-0.0.1/README.md +168 -0
  5. agent_comfy_ui_api_workflow-0.0.1/pyproject.toml +53 -0
  6. agent_comfy_ui_api_workflow-0.0.1/src/agent_comfy_ui_api_workflow/__about__.py +1 -0
  7. agent_comfy_ui_api_workflow-0.0.1/src/agent_comfy_ui_api_workflow/__init__.py +39 -0
  8. agent_comfy_ui_api_workflow-0.0.1/src/agent_comfy_ui_api_workflow/_impl/__init__.py +0 -0
  9. agent_comfy_ui_api_workflow-0.0.1/src/agent_comfy_ui_api_workflow/_impl/agent.py +276 -0
  10. agent_comfy_ui_api_workflow-0.0.1/src/agent_comfy_ui_api_workflow/_impl/catalog/__init__.py +348 -0
  11. agent_comfy_ui_api_workflow-0.0.1/src/agent_comfy_ui_api_workflow/_impl/catalog/essential.py +98 -0
  12. agent_comfy_ui_api_workflow-0.0.1/src/agent_comfy_ui_api_workflow/_impl/catalog/new_object_info.json +58779 -0
  13. agent_comfy_ui_api_workflow-0.0.1/src/agent_comfy_ui_api_workflow/_impl/env.py +44 -0
  14. agent_comfy_ui_api_workflow-0.0.1/src/agent_comfy_ui_api_workflow/_impl/errors.py +54 -0
  15. agent_comfy_ui_api_workflow-0.0.1/src/agent_comfy_ui_api_workflow/_impl/families.py +314 -0
  16. agent_comfy_ui_api_workflow-0.0.1/src/agent_comfy_ui_api_workflow/_impl/files.py +152 -0
  17. agent_comfy_ui_api_workflow-0.0.1/src/agent_comfy_ui_api_workflow/_impl/inventory.py +168 -0
  18. agent_comfy_ui_api_workflow-0.0.1/src/agent_comfy_ui_api_workflow/_impl/middleware.py +39 -0
  19. agent_comfy_ui_api_workflow-0.0.1/src/agent_comfy_ui_api_workflow/_impl/model.py +32 -0
  20. agent_comfy_ui_api_workflow-0.0.1/src/agent_comfy_ui_api_workflow/_impl/pipelines/__init__.py +70 -0
  21. agent_comfy_ui_api_workflow-0.0.1/src/agent_comfy_ui_api_workflow/_impl/pipelines/base.py +87 -0
  22. agent_comfy_ui_api_workflow-0.0.1/src/agent_comfy_ui_api_workflow/_impl/pipelines/generation.py +1249 -0
  23. agent_comfy_ui_api_workflow-0.0.1/src/agent_comfy_ui_api_workflow/_impl/pipelines/media.py +370 -0
  24. agent_comfy_ui_api_workflow-0.0.1/src/agent_comfy_ui_api_workflow/_impl/prompts.py +101 -0
  25. agent_comfy_ui_api_workflow-0.0.1/src/agent_comfy_ui_api_workflow/_impl/runpod.py +209 -0
  26. agent_comfy_ui_api_workflow-0.0.1/src/agent_comfy_ui_api_workflow/_impl/session.py +357 -0
  27. agent_comfy_ui_api_workflow-0.0.1/src/agent_comfy_ui_api_workflow/_impl/tools/__init__.py +25 -0
  28. agent_comfy_ui_api_workflow-0.0.1/src/agent_comfy_ui_api_workflow/_impl/tools/common.py +56 -0
  29. agent_comfy_ui_api_workflow-0.0.1/src/agent_comfy_ui_api_workflow/_impl/tools/editing.py +249 -0
  30. agent_comfy_ui_api_workflow-0.0.1/src/agent_comfy_ui_api_workflow/_impl/tools/nodes.py +98 -0
  31. agent_comfy_ui_api_workflow-0.0.1/src/agent_comfy_ui_api_workflow/_impl/tools/pipelines.py +92 -0
  32. agent_comfy_ui_api_workflow-0.0.1/src/agent_comfy_ui_api_workflow/_impl/tools/questions.py +42 -0
  33. agent_comfy_ui_api_workflow-0.0.1/src/agent_comfy_ui_api_workflow/_impl/validation.py +142 -0
  34. agent_comfy_ui_api_workflow-0.0.1/tests/builders.py +34 -0
  35. agent_comfy_ui_api_workflow-0.0.1/tests/conftest.py +102 -0
  36. agent_comfy_ui_api_workflow-0.0.1/tests/main.py +23 -0
  37. agent_comfy_ui_api_workflow-0.0.1/tests/media.py +51 -0
  38. agent_comfy_ui_api_workflow-0.0.1/tests/scripted.py +46 -0
  39. agent_comfy_ui_api_workflow-0.0.1/tests/test_agent.py +249 -0
  40. agent_comfy_ui_api_workflow-0.0.1/tests/test_agent_claude.py +172 -0
  41. agent_comfy_ui_api_workflow-0.0.1/tests/test_agent_runpod.py +167 -0
  42. agent_comfy_ui_api_workflow-0.0.1/tests/test_catalog.py +123 -0
  43. agent_comfy_ui_api_workflow-0.0.1/tests/test_env.py +34 -0
  44. agent_comfy_ui_api_workflow-0.0.1/tests/test_families.py +116 -0
  45. agent_comfy_ui_api_workflow-0.0.1/tests/test_files.py +101 -0
  46. agent_comfy_ui_api_workflow-0.0.1/tests/test_inventory.py +160 -0
  47. agent_comfy_ui_api_workflow-0.0.1/tests/test_pipelines_generation.py +414 -0
  48. agent_comfy_ui_api_workflow-0.0.1/tests/test_pipelines_media.py +216 -0
  49. agent_comfy_ui_api_workflow-0.0.1/tests/test_runpod_client.py +266 -0
  50. agent_comfy_ui_api_workflow-0.0.1/tests/test_runpod_jobs.py +98 -0
  51. agent_comfy_ui_api_workflow-0.0.1/tests/test_runpod_pipelines.py +1269 -0
  52. agent_comfy_ui_api_workflow-0.0.1/tests/test_runpod_server.py +167 -0
  53. agent_comfy_ui_api_workflow-0.0.1/tests/test_session.py +137 -0
  54. agent_comfy_ui_api_workflow-0.0.1/tests/test_tools.py +375 -0
  55. agent_comfy_ui_api_workflow-0.0.1/tests/test_validation.py +103 -0
@@ -0,0 +1,10 @@
1
+ .venv
2
+ .env
3
+ __pycache__
4
+ .pytest_cache
5
+ .coverage
6
+ htmlcov
7
+ dist
8
+ runpod_outputs
9
+ examples/output
10
+ docs
File without changes
@@ -0,0 +1,191 @@
1
+ Metadata-Version: 2.5
2
+ Name: agent-comfy-ui-api-workflow
3
+ Version: 0.0.1
4
+ Summary: Async LangChain agent on Claude that builds, edits and validates ComfyUI API workflows.
5
+ Author-email: Fabio Antonio Astore <astore.a.fabio@gmail.com>
6
+ License-Expression: MIT
7
+ License-File: LICENSE
8
+ Classifier: Operating System :: OS Independent
9
+ Classifier: Programming Language :: Python :: 3
10
+ Requires-Python: >=3.10
11
+ Requires-Dist: comfy-ui-api-workflow==0.0.9
12
+ Requires-Dist: httpx==0.28.1
13
+ Requires-Dist: langchain-anthropic==1.7.6
14
+ Requires-Dist: langchain==1.4.7
15
+ Requires-Dist: langgraph==1.2.16
16
+ Requires-Dist: pillow==13.0.0
17
+ Provides-Extra: dev
18
+ Requires-Dist: build>=1.2; extra == 'dev'
19
+ Requires-Dist: pytest-asyncio>=1.4.0; extra == 'dev'
20
+ Requires-Dist: pytest-cov>=7.1; extra == 'dev'
21
+ Requires-Dist: pytest>=8.0; extra == 'dev'
22
+ Description-Content-Type: text/markdown
23
+
24
+ # agent-comfy-ui-api-workflow
25
+
26
+ An async agent on Claude (through LangChain) that builds, edits and validates
27
+ [ComfyUI](https://github.com/comfyanonymous/ComfyUI) workflows in the API format, with
28
+ [comfy-ui-api-workflow](https://github.com/fabioantonioastore/comfy-ui-api-workflow).
29
+
30
+ - **Pipelines first.** The agent adds tested chains of nodes in one call:
31
+ `text_to_image`, `image_to_image`, `inpaint`, `outpaint`, `text_to_video`,
32
+ `image_to_video` (also between a start and an end image), `sound_to_video` (a photo
33
+ that talks or sings an audio), `text_to_audio` (music), `upscale_image_with_model`,
34
+ and video, audio and image editing. Single nodes come from a short list of essential
35
+ ones, only for steps no pipeline covers.
36
+ - **Your server's models only.** Generation pipelines are offered for the model
37
+ families found on the server, and every model name is checked against the server's
38
+ files. The families it knows:
39
+
40
+ | Family | Pipelines |
41
+ |---|---|
42
+ | SDXL | images: text to image, image to image, inpaint, outpaint |
43
+ | Wan 2.2 TI2V 5B | video from text or an image, 24 fps |
44
+ | Wan 2.2 A14B T2V / I2V, with the LightX2V 4-step LoRAs | video from text, an image, or a start and an end image, 16 fps |
45
+ | MiniMax H3 (with its turbo LoRA) | video with its own sound: speech, effects, music; 5 to 15 s |
46
+ | Wan 2.2 S2V | a photo animated in sync with an audio |
47
+ | ACE-Step 1.5 XL turbo | music, sung or instrumental |
48
+ | Upscale models (Real-ESRGAN...) | image upscaling |
49
+
50
+ MiniMax H3 has its own community license, which restricts where it may be used:
51
+ read it before serving that model.
52
+ - **It asks when it must.** A request that needs a file the user did not attach (an
53
+ image, a video, an audio, a mask), something the server cannot do, or a choice that
54
+ changes the result, comes back as a question instead of a guess.
55
+ - **Checked before it is delivered.** When the agent finishes, the workflow is
56
+ validated: an output node, every node connected, model files the server has, files
57
+ the user attached, and a JSON that loads back. Problems go back to the agent to fix.
58
+ - **It never runs the workflow.** You get the JSON for `POST /prompt` and the list of
59
+ files to upload with it.
60
+
61
+ ## Installation
62
+
63
+ ```bash
64
+ pip install git+https://github.com/fabioantonioastore/agent-comfy-ui-api-workflow
65
+ ```
66
+
67
+ The agent reads `ANTHROPIC_API_KEY`, and `RunPodClient` reads `RUNPOD_API_KEY` and
68
+ `RUNPOD_ENDPOINT_ID`, from the environment or from a `.env` file (`NAME=value` or
69
+ `NAME: value` lines).
70
+
71
+ ## Quick start
72
+
73
+ ```python
74
+ import asyncio
75
+ from pathlib import Path
76
+
77
+ from agent_comfy_ui_api_workflow import RunPodClient, ServerInventory, WorkflowAgent
78
+
79
+
80
+ async def main():
81
+ # Once: ask the server which model files it has, and keep the answer. Workers that
82
+ # answer {"object_info": true} jobs give every loader's files; the official worker
83
+ # gets a probe instead, which misses the loaders its handler does not check.
84
+ async with RunPodClient.from_env() as runpod:
85
+ inventory = await runpod.discover_inventory()
86
+ inventory.save("inventory.json") # later: ServerInventory.load("inventory.json")
87
+
88
+ agent = WorkflowAgent(inventory)
89
+ reply = await agent.send("make an elephant with my face")
90
+ if reply.status == "needs_input":
91
+ print(reply.question.text, reply.question.needs) # ... ('image',)
92
+ photo = Path("me.jpg").read_bytes()
93
+ reply = await agent.send("here it is", files={"me.jpg": photo})
94
+
95
+ print(reply.status, reply.message)
96
+ print(reply.workflow) # the API format, ready for POST /prompt
97
+ print(reply.input_files) # ('me.jpg',): upload it with the workflow
98
+
99
+
100
+ asyncio.run(main())
101
+ ```
102
+
103
+ Each `send` is one turn of the same conversation, so the next request can change what
104
+ the agent built: "now make it 16:9 with 35 steps".
105
+
106
+ More in [examples/](examples/): questions, editing, conversations, running on RunPod,
107
+ a chat in the terminal and a server described by hand.
108
+
109
+ ## Editing an exported workflow
110
+
111
+ ```python
112
+ import json
113
+
114
+ workflow = json.loads(Path("workflow_api.json").read_text()) # ComfyUI's Export (API)
115
+ agent = WorkflowAgent.from_workflow(workflow, inventory)
116
+ reply = await agent.send("change the prompt to a lighthouse at dusk and use 30 steps")
117
+ print(reply.changes.text()) # Changed: 6 (text), 3 (steps).
118
+ ```
119
+
120
+ The agent reads the workflow before changing it, changes only what was asked and keeps
121
+ the node ids.
122
+
123
+ ## Replies
124
+
125
+ `send` returns an `AgentReply`:
126
+
127
+ | Field | What it holds |
128
+ |---|---|
129
+ | `status` | `completed`, `needs_input` (a question), `invalid` (problems the agent could not fix), `refused` or `error` |
130
+ | `message` | The agent's answer, in the user's language |
131
+ | `workflow` | The workflow in the API format, as plain JSON |
132
+ | `question` | For `needs_input`: `text` and `needs` (`image`, `video`, `audio`, `mask`, `answer`) |
133
+ | `changes` | Nodes added, removed and changed in this turn |
134
+ | `validation` | The checks above: `ok`, `problems`, `text()` |
135
+ | `input_files` | The user files the workflow loads |
136
+ | `usage` | Tokens of the turn: input, output, cache reads and writes, model calls |
137
+
138
+ `agent.workflow`, `agent.files` (the attached files the workflow loads),
139
+ `agent.previous_workflows`, `agent.view()` and `agent.validate()` give the same
140
+ information between turns.
141
+
142
+ ## Running a workflow
143
+
144
+ The agent only builds workflows. To run one on a RunPod `worker-comfyui` endpoint:
145
+
146
+ ```python
147
+ async with RunPodClient.from_env() as runpod:
148
+ job = await runpod.run(reply.workflow, files=agent.files)
149
+ if not job.ok:
150
+ raise RuntimeError(job.error)
151
+ for file in job.files:
152
+ if file.filename not in agent.files: # the worker also returns some of the inputs
153
+ Path(file.filename).write_bytes(file.data)
154
+ ```
155
+
156
+ `job.ok` is false when a node failed, even when RunPod reports the job `COMPLETED`;
157
+ `job.error` then names the node and the reason. RunPod takes requests of up to 10 MiB,
158
+ and the files go in them base64-encoded: about 7.5 MB of files per job.
159
+
160
+ `run` waits up to `timeout` seconds (600 by default) and then cancels the job. When
161
+ RunPod's API fails for a moment while the job runs, it asks for the status again.
162
+
163
+ ## Configuration
164
+
165
+ ```python
166
+ WorkflowAgent(
167
+ inventory,
168
+ model="claude-opus-5-5", # any Claude model id
169
+ effort="high", # low, medium, high, xhigh or max
170
+ api_key=None, # default: ANTHROPIC_API_KEY from the environment or env_file
171
+ env_file=".env",
172
+ vision=True, # show attached images to the model
173
+ refusal_fallback=True, # let the API retry a declined request on another model
174
+ max_model_calls=40, # per turn
175
+ )
176
+ ```
177
+
178
+ ## Development
179
+
180
+ ```bash
181
+ pip install -e ".[dev]"
182
+ pytest # offline tests
183
+ pytest --anthropic # the agent on the Claude API (paid tokens)
184
+ pytest --runpod # every pipeline on the RunPod endpoint (paid GPU time)
185
+ pytest --runpod --anthropic # everything, plus the agent's workflows run on the endpoint
186
+ pytest --cov=agent_comfy_ui_api_workflow --cov-report=term-missing # coverage
187
+ ```
188
+
189
+ ## License
190
+
191
+ MIT
@@ -0,0 +1,168 @@
1
+ # agent-comfy-ui-api-workflow
2
+
3
+ An async agent on Claude (through LangChain) that builds, edits and validates
4
+ [ComfyUI](https://github.com/comfyanonymous/ComfyUI) workflows in the API format, with
5
+ [comfy-ui-api-workflow](https://github.com/fabioantonioastore/comfy-ui-api-workflow).
6
+
7
+ - **Pipelines first.** The agent adds tested chains of nodes in one call:
8
+ `text_to_image`, `image_to_image`, `inpaint`, `outpaint`, `text_to_video`,
9
+ `image_to_video` (also between a start and an end image), `sound_to_video` (a photo
10
+ that talks or sings an audio), `text_to_audio` (music), `upscale_image_with_model`,
11
+ and video, audio and image editing. Single nodes come from a short list of essential
12
+ ones, only for steps no pipeline covers.
13
+ - **Your server's models only.** Generation pipelines are offered for the model
14
+ families found on the server, and every model name is checked against the server's
15
+ files. The families it knows:
16
+
17
+ | Family | Pipelines |
18
+ |---|---|
19
+ | SDXL | images: text to image, image to image, inpaint, outpaint |
20
+ | Wan 2.2 TI2V 5B | video from text or an image, 24 fps |
21
+ | Wan 2.2 A14B T2V / I2V, with the LightX2V 4-step LoRAs | video from text, an image, or a start and an end image, 16 fps |
22
+ | MiniMax H3 (with its turbo LoRA) | video with its own sound: speech, effects, music; 5 to 15 s |
23
+ | Wan 2.2 S2V | a photo animated in sync with an audio |
24
+ | ACE-Step 1.5 XL turbo | music, sung or instrumental |
25
+ | Upscale models (Real-ESRGAN...) | image upscaling |
26
+
27
+ MiniMax H3 has its own community license, which restricts where it may be used:
28
+ read it before serving that model.
29
+ - **It asks when it must.** A request that needs a file the user did not attach (an
30
+ image, a video, an audio, a mask), something the server cannot do, or a choice that
31
+ changes the result, comes back as a question instead of a guess.
32
+ - **Checked before it is delivered.** When the agent finishes, the workflow is
33
+ validated: an output node, every node connected, model files the server has, files
34
+ the user attached, and a JSON that loads back. Problems go back to the agent to fix.
35
+ - **It never runs the workflow.** You get the JSON for `POST /prompt` and the list of
36
+ files to upload with it.
37
+
38
+ ## Installation
39
+
40
+ ```bash
41
+ pip install git+https://github.com/fabioantonioastore/agent-comfy-ui-api-workflow
42
+ ```
43
+
44
+ The agent reads `ANTHROPIC_API_KEY`, and `RunPodClient` reads `RUNPOD_API_KEY` and
45
+ `RUNPOD_ENDPOINT_ID`, from the environment or from a `.env` file (`NAME=value` or
46
+ `NAME: value` lines).
47
+
48
+ ## Quick start
49
+
50
+ ```python
51
+ import asyncio
52
+ from pathlib import Path
53
+
54
+ from agent_comfy_ui_api_workflow import RunPodClient, ServerInventory, WorkflowAgent
55
+
56
+
57
+ async def main():
58
+ # Once: ask the server which model files it has, and keep the answer. Workers that
59
+ # answer {"object_info": true} jobs give every loader's files; the official worker
60
+ # gets a probe instead, which misses the loaders its handler does not check.
61
+ async with RunPodClient.from_env() as runpod:
62
+ inventory = await runpod.discover_inventory()
63
+ inventory.save("inventory.json") # later: ServerInventory.load("inventory.json")
64
+
65
+ agent = WorkflowAgent(inventory)
66
+ reply = await agent.send("make an elephant with my face")
67
+ if reply.status == "needs_input":
68
+ print(reply.question.text, reply.question.needs) # ... ('image',)
69
+ photo = Path("me.jpg").read_bytes()
70
+ reply = await agent.send("here it is", files={"me.jpg": photo})
71
+
72
+ print(reply.status, reply.message)
73
+ print(reply.workflow) # the API format, ready for POST /prompt
74
+ print(reply.input_files) # ('me.jpg',): upload it with the workflow
75
+
76
+
77
+ asyncio.run(main())
78
+ ```
79
+
80
+ Each `send` is one turn of the same conversation, so the next request can change what
81
+ the agent built: "now make it 16:9 with 35 steps".
82
+
83
+ More in [examples/](examples/): questions, editing, conversations, running on RunPod,
84
+ a chat in the terminal and a server described by hand.
85
+
86
+ ## Editing an exported workflow
87
+
88
+ ```python
89
+ import json
90
+
91
+ workflow = json.loads(Path("workflow_api.json").read_text()) # ComfyUI's Export (API)
92
+ agent = WorkflowAgent.from_workflow(workflow, inventory)
93
+ reply = await agent.send("change the prompt to a lighthouse at dusk and use 30 steps")
94
+ print(reply.changes.text()) # Changed: 6 (text), 3 (steps).
95
+ ```
96
+
97
+ The agent reads the workflow before changing it, changes only what was asked and keeps
98
+ the node ids.
99
+
100
+ ## Replies
101
+
102
+ `send` returns an `AgentReply`:
103
+
104
+ | Field | What it holds |
105
+ |---|---|
106
+ | `status` | `completed`, `needs_input` (a question), `invalid` (problems the agent could not fix), `refused` or `error` |
107
+ | `message` | The agent's answer, in the user's language |
108
+ | `workflow` | The workflow in the API format, as plain JSON |
109
+ | `question` | For `needs_input`: `text` and `needs` (`image`, `video`, `audio`, `mask`, `answer`) |
110
+ | `changes` | Nodes added, removed and changed in this turn |
111
+ | `validation` | The checks above: `ok`, `problems`, `text()` |
112
+ | `input_files` | The user files the workflow loads |
113
+ | `usage` | Tokens of the turn: input, output, cache reads and writes, model calls |
114
+
115
+ `agent.workflow`, `agent.files` (the attached files the workflow loads),
116
+ `agent.previous_workflows`, `agent.view()` and `agent.validate()` give the same
117
+ information between turns.
118
+
119
+ ## Running a workflow
120
+
121
+ The agent only builds workflows. To run one on a RunPod `worker-comfyui` endpoint:
122
+
123
+ ```python
124
+ async with RunPodClient.from_env() as runpod:
125
+ job = await runpod.run(reply.workflow, files=agent.files)
126
+ if not job.ok:
127
+ raise RuntimeError(job.error)
128
+ for file in job.files:
129
+ if file.filename not in agent.files: # the worker also returns some of the inputs
130
+ Path(file.filename).write_bytes(file.data)
131
+ ```
132
+
133
+ `job.ok` is false when a node failed, even when RunPod reports the job `COMPLETED`;
134
+ `job.error` then names the node and the reason. RunPod takes requests of up to 10 MiB,
135
+ and the files go in them base64-encoded: about 7.5 MB of files per job.
136
+
137
+ `run` waits up to `timeout` seconds (600 by default) and then cancels the job. When
138
+ RunPod's API fails for a moment while the job runs, it asks for the status again.
139
+
140
+ ## Configuration
141
+
142
+ ```python
143
+ WorkflowAgent(
144
+ inventory,
145
+ model="claude-opus-5-5", # any Claude model id
146
+ effort="high", # low, medium, high, xhigh or max
147
+ api_key=None, # default: ANTHROPIC_API_KEY from the environment or env_file
148
+ env_file=".env",
149
+ vision=True, # show attached images to the model
150
+ refusal_fallback=True, # let the API retry a declined request on another model
151
+ max_model_calls=40, # per turn
152
+ )
153
+ ```
154
+
155
+ ## Development
156
+
157
+ ```bash
158
+ pip install -e ".[dev]"
159
+ pytest # offline tests
160
+ pytest --anthropic # the agent on the Claude API (paid tokens)
161
+ pytest --runpod # every pipeline on the RunPod endpoint (paid GPU time)
162
+ pytest --runpod --anthropic # everything, plus the agent's workflows run on the endpoint
163
+ pytest --cov=agent_comfy_ui_api_workflow --cov-report=term-missing # coverage
164
+ ```
165
+
166
+ ## License
167
+
168
+ MIT
@@ -0,0 +1,53 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "agent-comfy-ui-api-workflow"
7
+ dynamic = ["version"]
8
+ description = "Async LangChain agent on Claude that builds, edits and validates ComfyUI API workflows."
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = "MIT"
12
+ authors = [
13
+ { name = "Fabio Antonio Astore", email = "astore.a.fabio@gmail.com" },
14
+ ]
15
+ classifiers = [
16
+ "Programming Language :: Python :: 3",
17
+ "Operating System :: OS Independent",
18
+ ]
19
+ dependencies = [
20
+ "comfy-ui-api-workflow==0.0.9",
21
+ "langchain==1.4.7",
22
+ "langchain-anthropic==1.7.6",
23
+ "langgraph==1.2.16",
24
+ "httpx==0.28.1",
25
+ "pillow==13.0.0",
26
+ ]
27
+
28
+ [project.optional-dependencies]
29
+ dev = [
30
+ "pytest>=8.0",
31
+ "pytest-asyncio>=1.4.0",
32
+ "pytest-cov>=7.1",
33
+ "build>=1.2",
34
+ ]
35
+
36
+ [tool.hatch.version]
37
+ path = "src/agent_comfy_ui_api_workflow/__about__.py"
38
+
39
+ [tool.hatch.build.targets.wheel]
40
+ packages = ["src/agent_comfy_ui_api_workflow"]
41
+
42
+ # only-include keeps the src/ path, so the wheel built from the sdist finds the package.
43
+ [tool.hatch.build.targets.sdist]
44
+ only-include = ["src/agent_comfy_ui_api_workflow", "tests"]
45
+
46
+ [tool.pytest.ini_options]
47
+ testpaths = ["tests"]
48
+ asyncio_mode = "auto"
49
+ asyncio_default_fixture_loop_scope = "function"
50
+ markers = [
51
+ "runpod: sends real jobs to the RunPod ComfyUI endpoint in .env; needs --runpod",
52
+ "anthropic: calls the Claude API with ANTHROPIC_API_KEY; needs --anthropic",
53
+ ]
@@ -0,0 +1,39 @@
1
+ from .__about__ import version as __version__
2
+ from ._impl.agent import AgentReply, WorkflowAgent
3
+ from ._impl.errors import (
4
+ AgentComfyUIError,
5
+ InputFileError,
6
+ InventoryError,
7
+ JobTimeoutError,
8
+ RunPodError,
9
+ SettingsError,
10
+ )
11
+ from ._impl.files import InputFile
12
+ from ._impl.inventory import ServerInventory
13
+ from ._impl.pipelines import MEDIA_PIPELINES, AgentPipeline
14
+ from ._impl.runpod import JobResult, OutputFile, RunPodClient
15
+ from ._impl.session import Question, WorkflowDiff
16
+ from ._impl.validation import Problem, ValidationReport
17
+
18
+ __all__ = [
19
+ "MEDIA_PIPELINES",
20
+ "AgentComfyUIError",
21
+ "AgentPipeline",
22
+ "AgentReply",
23
+ "InputFile",
24
+ "InputFileError",
25
+ "InventoryError",
26
+ "JobResult",
27
+ "JobTimeoutError",
28
+ "OutputFile",
29
+ "Problem",
30
+ "Question",
31
+ "RunPodClient",
32
+ "RunPodError",
33
+ "ServerInventory",
34
+ "SettingsError",
35
+ "ValidationReport",
36
+ "WorkflowAgent",
37
+ "WorkflowDiff",
38
+ "__version__",
39
+ ]