dkitchen 0.2.0__tar.gz → 0.2.2__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.
- {dkitchen-0.2.0/src/dkitchen.egg-info → dkitchen-0.2.2}/PKG-INFO +24 -4
- {dkitchen-0.2.0 → dkitchen-0.2.2}/README.md +23 -3
- {dkitchen-0.2.0 → dkitchen-0.2.2}/pyproject.toml +1 -1
- {dkitchen-0.2.0 → dkitchen-0.2.2}/src/dkitchen/watch.py +13 -9
- {dkitchen-0.2.0 → dkitchen-0.2.2/src/dkitchen.egg-info}/PKG-INFO +24 -4
- {dkitchen-0.2.0 → dkitchen-0.2.2}/tests/test_kitchen.py +21 -0
- {dkitchen-0.2.0 → dkitchen-0.2.2}/LICENSE +0 -0
- {dkitchen-0.2.0 → dkitchen-0.2.2}/setup.cfg +0 -0
- {dkitchen-0.2.0 → dkitchen-0.2.2}/src/dkitchen/__init__.py +0 -0
- {dkitchen-0.2.0 → dkitchen-0.2.2}/src/dkitchen/config.py +0 -0
- {dkitchen-0.2.0 → dkitchen-0.2.2}/src/dkitchen/ding.py +0 -0
- {dkitchen-0.2.0 → dkitchen-0.2.2}/src/dkitchen/orchestrate.py +0 -0
- {dkitchen-0.2.0 → dkitchen-0.2.2}/src/dkitchen/refs.py +0 -0
- {dkitchen-0.2.0 → dkitchen-0.2.2}/src/dkitchen.egg-info/SOURCES.txt +0 -0
- {dkitchen-0.2.0 → dkitchen-0.2.2}/src/dkitchen.egg-info/dependency_links.txt +0 -0
- {dkitchen-0.2.0 → dkitchen-0.2.2}/src/dkitchen.egg-info/entry_points.txt +0 -0
- {dkitchen-0.2.0 → dkitchen-0.2.2}/src/dkitchen.egg-info/requires.txt +0 -0
- {dkitchen-0.2.0 → dkitchen-0.2.2}/src/dkitchen.egg-info/top_level.txt +0 -0
- {dkitchen-0.2.0 → dkitchen-0.2.2}/tests/test_codex_session.py +0 -0
- {dkitchen-0.2.0 → dkitchen-0.2.2}/tests/test_records.py +0 -0
- {dkitchen-0.2.0 → dkitchen-0.2.2}/tests/test_reference_scripts.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dkitchen
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: A multi-agent workflow for research repos, with the ding CLI for messaging and waking agent sessions
|
|
5
5
|
Author: 917Dhj
|
|
6
6
|
License-Expression: MIT
|
|
@@ -30,11 +30,27 @@ Provides-Extra: dev
|
|
|
30
30
|
Requires-Dist: pytest>=8; extra == "dev"
|
|
31
31
|
Dynamic: license-file
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
<p align="center">
|
|
34
|
+
<img src="https://raw.githubusercontent.com/917Dhj/dkitchen/main/docs/assets/dkitchen.png" width="240" alt="Two pixel-art robot chefs: the big one rings a service bell, the small one answers with a pan">
|
|
35
|
+
</p>
|
|
34
36
|
|
|
35
|
-
|
|
37
|
+
<h1 align="center">dkitchen</h1>
|
|
36
38
|
|
|
37
|
-
|
|
39
|
+
<p align="center">
|
|
40
|
+
<b>English</b> | <a href="https://github.com/917Dhj/dkitchen/blob/main/README.zh-CN.md">简体中文</a>
|
|
41
|
+
</p>
|
|
42
|
+
|
|
43
|
+
<p align="center">
|
|
44
|
+
<b>You decide what to cook. Your agents run the kitchen.</b> 🧑🍳
|
|
45
|
+
</p>
|
|
46
|
+
|
|
47
|
+
<p align="center">
|
|
48
|
+
<a href="https://pypi.org/project/dkitchen/"><img src="https://img.shields.io/pypi/v/dkitchen" alt="PyPI"></a>
|
|
49
|
+
<a href="https://pypi.org/project/dkitchen/"><img src="https://img.shields.io/pypi/pyversions/dkitchen" alt="Python"></a>
|
|
50
|
+
<a href="https://github.com/917Dhj/dkitchen/actions/workflows/tests.yml"><img src="https://github.com/917Dhj/dkitchen/actions/workflows/tests.yml/badge.svg" alt="Tests"></a>
|
|
51
|
+
<a href="https://github.com/917Dhj/dkitchen/blob/main/LICENSE"><img src="https://img.shields.io/github/license/917Dhj/dkitchen" alt="License"></a>
|
|
52
|
+
<a href="https://x.com/dahuoji09"><img src="https://img.shields.io/badge/follow-%40dahuoji09-000000?logo=x" alt="X: @dahuoji09"></a>
|
|
53
|
+
</p>
|
|
38
54
|
|
|
39
55
|
dkitchen is the multi-agent workflow I use every day to run my research repo. It gives a set of Claude Code and Codex sessions fixed stations, a shared way to hand off work through GitHub issues, clear rules for when to stop and ask you, and the tools that tie it together. You keep the decisions only you can make: what to research, what to try, what to spend.
|
|
40
56
|
|
|
@@ -50,6 +66,10 @@ dkitchen sets up your agents the same way. You are the head chef.
|
|
|
50
66
|
|
|
51
67
|
## 🧑🍳 The kitchen
|
|
52
68
|
|
|
69
|
+
<p align="center">
|
|
70
|
+
<img src="https://raw.githubusercontent.com/917Dhj/dkitchen/main/docs/assets/kitchen.gif" width="100%" alt="A pixel-art kitchen: you talk a design through with the designer, the verifier checks the ticket, the orchestrator rings the bell to start a Codex executor on free GPUs, reviews and merges a PR, and brings you one decision to approve">
|
|
71
|
+
</p>
|
|
72
|
+
|
|
53
73
|
| Station | In a kitchen | What it does | Runs on |
|
|
54
74
|
| --- | --- | --- | --- |
|
|
55
75
|
| 👑 **You** | Head chef | Choose the direction, approve designs and budgets, decide what the results mean for your paper. | You |
|
|
@@ -1,8 +1,24 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/917Dhj/dkitchen/main/docs/assets/dkitchen.png" width="240" alt="Two pixel-art robot chefs: the big one rings a service bell, the small one answers with a pan">
|
|
3
|
+
</p>
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
<h1 align="center">dkitchen</h1>
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
<p align="center">
|
|
8
|
+
<b>English</b> | <a href="https://github.com/917Dhj/dkitchen/blob/main/README.zh-CN.md">简体中文</a>
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
<b>You decide what to cook. Your agents run the kitchen.</b> 🧑🍳
|
|
13
|
+
</p>
|
|
14
|
+
|
|
15
|
+
<p align="center">
|
|
16
|
+
<a href="https://pypi.org/project/dkitchen/"><img src="https://img.shields.io/pypi/v/dkitchen" alt="PyPI"></a>
|
|
17
|
+
<a href="https://pypi.org/project/dkitchen/"><img src="https://img.shields.io/pypi/pyversions/dkitchen" alt="Python"></a>
|
|
18
|
+
<a href="https://github.com/917Dhj/dkitchen/actions/workflows/tests.yml"><img src="https://github.com/917Dhj/dkitchen/actions/workflows/tests.yml/badge.svg" alt="Tests"></a>
|
|
19
|
+
<a href="https://github.com/917Dhj/dkitchen/blob/main/LICENSE"><img src="https://img.shields.io/github/license/917Dhj/dkitchen" alt="License"></a>
|
|
20
|
+
<a href="https://x.com/dahuoji09"><img src="https://img.shields.io/badge/follow-%40dahuoji09-000000?logo=x" alt="X: @dahuoji09"></a>
|
|
21
|
+
</p>
|
|
6
22
|
|
|
7
23
|
dkitchen is the multi-agent workflow I use every day to run my research repo. It gives a set of Claude Code and Codex sessions fixed stations, a shared way to hand off work through GitHub issues, clear rules for when to stop and ask you, and the tools that tie it together. You keep the decisions only you can make: what to research, what to try, what to spend.
|
|
8
24
|
|
|
@@ -18,6 +34,10 @@ dkitchen sets up your agents the same way. You are the head chef.
|
|
|
18
34
|
|
|
19
35
|
## 🧑🍳 The kitchen
|
|
20
36
|
|
|
37
|
+
<p align="center">
|
|
38
|
+
<img src="https://raw.githubusercontent.com/917Dhj/dkitchen/main/docs/assets/kitchen.gif" width="100%" alt="A pixel-art kitchen: you talk a design through with the designer, the verifier checks the ticket, the orchestrator rings the bell to start a Codex executor on free GPUs, reviews and merges a PR, and brings you one decision to approve">
|
|
39
|
+
</p>
|
|
40
|
+
|
|
21
41
|
| Station | In a kitchen | What it does | Runs on |
|
|
22
42
|
| --- | --- | --- | --- |
|
|
23
43
|
| 👑 **You** | Head chef | Choose the direction, approve designs and budgets, decide what the results mean for your paper. | You |
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "dkitchen"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.2"
|
|
8
8
|
description = "A multi-agent workflow for research repos, with the ding CLI for messaging and waking agent sessions"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -6,7 +6,8 @@ Wakes on:
|
|
|
6
6
|
- status labels being added, and newly opened PRs;
|
|
7
7
|
- stale tickets: no status label, last comment an executor "in progress" older than --stale-hours,
|
|
8
8
|
no running `ding run` for the ticket, and no live tmux job whose session name holds issue<N>.
|
|
9
|
-
On tickets labelled awaiting-user, executor comments wake only for blocked, done, and waiting on design
|
|
9
|
+
On tickets labelled awaiting-user, executor comments wake only for blocked, done, and waiting on design,
|
|
10
|
+
or when their "waiting on" names the orchestrator, designer, or verifier.
|
|
10
11
|
Verifier comments never wake on their own, since the verifier also messages the orchestrator;
|
|
11
12
|
they are listed in the next batch for reference.
|
|
12
13
|
The state file keeps the time already reported, so rerunning the same command loses nothing.
|
|
@@ -61,14 +62,16 @@ def issue_number(url: str) -> int:
|
|
|
61
62
|
|
|
62
63
|
|
|
63
64
|
def role(body: str, config: Config) -> str:
|
|
64
|
-
"""The
|
|
65
|
+
"""The station named at the start of the first line; otherwise the executor by a line starting with its
|
|
66
|
+
session signature; else the user. A session signature quoted inside a line signs nothing."""
|
|
65
67
|
stations = config.stations
|
|
66
|
-
if "Codex session:" in body:
|
|
67
|
-
return stations.executor
|
|
68
68
|
first = next((line for line in body.splitlines() if line.strip()), "")
|
|
69
69
|
first = re.sub(r"^[\s#*>]+", "", first)
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
signed = next((name for name in (stations.designer, stations.verifier, stations.orchestrator)
|
|
71
|
+
if first.startswith(name)), None)
|
|
72
|
+
if signed:
|
|
73
|
+
return signed
|
|
74
|
+
return stations.executor if re.search(r"(?m)^[ \t]*Codex session:", body) else stations.user
|
|
72
75
|
|
|
73
76
|
|
|
74
77
|
def fields(body: str, config: Config) -> dict[str, str]:
|
|
@@ -85,10 +88,11 @@ def state_and_waiting(body: str, config: Config) -> tuple[str, str]:
|
|
|
85
88
|
def executor_wakes(body: str, waiting_user: bool, config: Config) -> bool:
|
|
86
89
|
state, waiting = state_and_waiting(body, config)
|
|
87
90
|
status, stations = config.status, config.stations
|
|
91
|
+
names = lambda *who: not waiting.startswith(status.none) and any(name in waiting for name in who)
|
|
92
|
+
kitchen = (stations.orchestrator, stations.designer, stations.verifier)
|
|
88
93
|
if waiting_user:
|
|
89
|
-
return state in {status.blocked, status.done, status.waiting_on_design}
|
|
90
|
-
|
|
91
|
-
return state != status.in_progress or (not waiting.startswith(status.none) and any(name in waiting for name in names))
|
|
94
|
+
return state in {status.blocked, status.done, status.waiting_on_design} or names(*kitchen)
|
|
95
|
+
return state != status.in_progress or names(*kitchen, stations.user)
|
|
92
96
|
|
|
93
97
|
|
|
94
98
|
def summary(body: str, config: Config) -> str:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dkitchen
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: A multi-agent workflow for research repos, with the ding CLI for messaging and waking agent sessions
|
|
5
5
|
Author: 917Dhj
|
|
6
6
|
License-Expression: MIT
|
|
@@ -30,11 +30,27 @@ Provides-Extra: dev
|
|
|
30
30
|
Requires-Dist: pytest>=8; extra == "dev"
|
|
31
31
|
Dynamic: license-file
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
<p align="center">
|
|
34
|
+
<img src="https://raw.githubusercontent.com/917Dhj/dkitchen/main/docs/assets/dkitchen.png" width="240" alt="Two pixel-art robot chefs: the big one rings a service bell, the small one answers with a pan">
|
|
35
|
+
</p>
|
|
34
36
|
|
|
35
|
-
|
|
37
|
+
<h1 align="center">dkitchen</h1>
|
|
36
38
|
|
|
37
|
-
|
|
39
|
+
<p align="center">
|
|
40
|
+
<b>English</b> | <a href="https://github.com/917Dhj/dkitchen/blob/main/README.zh-CN.md">简体中文</a>
|
|
41
|
+
</p>
|
|
42
|
+
|
|
43
|
+
<p align="center">
|
|
44
|
+
<b>You decide what to cook. Your agents run the kitchen.</b> 🧑🍳
|
|
45
|
+
</p>
|
|
46
|
+
|
|
47
|
+
<p align="center">
|
|
48
|
+
<a href="https://pypi.org/project/dkitchen/"><img src="https://img.shields.io/pypi/v/dkitchen" alt="PyPI"></a>
|
|
49
|
+
<a href="https://pypi.org/project/dkitchen/"><img src="https://img.shields.io/pypi/pyversions/dkitchen" alt="Python"></a>
|
|
50
|
+
<a href="https://github.com/917Dhj/dkitchen/actions/workflows/tests.yml"><img src="https://github.com/917Dhj/dkitchen/actions/workflows/tests.yml/badge.svg" alt="Tests"></a>
|
|
51
|
+
<a href="https://github.com/917Dhj/dkitchen/blob/main/LICENSE"><img src="https://img.shields.io/github/license/917Dhj/dkitchen" alt="License"></a>
|
|
52
|
+
<a href="https://x.com/dahuoji09"><img src="https://img.shields.io/badge/follow-%40dahuoji09-000000?logo=x" alt="X: @dahuoji09"></a>
|
|
53
|
+
</p>
|
|
38
54
|
|
|
39
55
|
dkitchen is the multi-agent workflow I use every day to run my research repo. It gives a set of Claude Code and Codex sessions fixed stations, a shared way to hand off work through GitHub issues, clear rules for when to stop and ask you, and the tools that tie it together. You keep the decisions only you can make: what to research, what to try, what to spend.
|
|
40
56
|
|
|
@@ -50,6 +66,10 @@ dkitchen sets up your agents the same way. You are the head chef.
|
|
|
50
66
|
|
|
51
67
|
## 🧑🍳 The kitchen
|
|
52
68
|
|
|
69
|
+
<p align="center">
|
|
70
|
+
<img src="https://raw.githubusercontent.com/917Dhj/dkitchen/main/docs/assets/kitchen.gif" width="100%" alt="A pixel-art kitchen: you talk a design through with the designer, the verifier checks the ticket, the orchestrator rings the bell to start a Codex executor on free GPUs, reviews and merges a PR, and brings you one decision to approve">
|
|
71
|
+
</p>
|
|
72
|
+
|
|
53
73
|
| Station | In a kitchen | What it does | Runs on |
|
|
54
74
|
| --- | --- | --- | --- |
|
|
55
75
|
| 👑 **You** | Head chef | Choose the direction, approve designs and budgets, decide what the results mean for your paper. | You |
|
|
@@ -206,6 +206,8 @@ def executor(block):
|
|
|
206
206
|
("Status: in progress\nWaiting on: Designer, for the prompt\nKey numbers: 1\nNext: wait", False, True),
|
|
207
207
|
("Status: done\nWaiting on: none\nKey numbers: 1\nNext: merge", False, True),
|
|
208
208
|
("Status: waiting on user\nWaiting on: User\nKey numbers: 1\nNext: wait", True, False),
|
|
209
|
+
("Status: waiting on user\nWaiting on: User to approve; Orchestrator to merge PR #3\nKey numbers: 1\nNext: merge",
|
|
210
|
+
True, True),
|
|
209
211
|
("Status: blocked\nWaiting on: none\nKey numbers: 1\nNext: fix", True, True),
|
|
210
212
|
])
|
|
211
213
|
def test_executor_comments_wake_by_status_and_waiting_on(tmp_path, block, waiting_user, wakes):
|
|
@@ -222,6 +224,14 @@ def test_chinese_status_words_and_full_width_colons(tmp_path):
|
|
|
222
224
|
assert not watch.executor_wakes(executor("状态: 进行中\n在等: 无\n关键数字: 1\n下一步: 跑"), False, loaded)
|
|
223
225
|
|
|
224
226
|
|
|
227
|
+
def test_an_awaiting_user_ticket_wakes_when_the_comment_also_waits_on_the_kitchen(tmp_path):
|
|
228
|
+
# #209 issuecomment-6179869282: still waiting on the user, but also asking the orchestrator to merge
|
|
229
|
+
loaded = settings(tmp_path, CHINESE)
|
|
230
|
+
body = executor("状态: 等用户\n在等: 用户批准说话人 1,329 次单次作答;总编排重审合入 PR #314\n关键数字: 0\n下一步: 合入")
|
|
231
|
+
assert watch.executor_wakes(body, True, loaded)
|
|
232
|
+
assert not watch.executor_wakes(executor("状态: 等用户\n在等: 用户批准\n关键数字: 0\n下一步: 等"), True, loaded)
|
|
233
|
+
|
|
234
|
+
|
|
225
235
|
@pytest.fixture
|
|
226
236
|
def tree(tmp_path):
|
|
227
237
|
(tmp_path / "pkg").mkdir()
|
|
@@ -279,3 +289,14 @@ def test_log_issue_must_be_positive(capsys):
|
|
|
279
289
|
with pytest.raises(SystemExit) as exc:
|
|
280
290
|
ding.main(["log", "--item", "a", "--issue", "0"])
|
|
281
291
|
assert exc.value.code == 2
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
@pytest.mark.parametrize("text", [None, CHINESE])
|
|
295
|
+
def test_a_quoted_session_signature_signs_nothing(tmp_path, text):
|
|
296
|
+
loaded = settings(tmp_path, text)
|
|
297
|
+
stations = loaded.stations
|
|
298
|
+
verifier = (f"## {stations.verifier}{stations.separator}#272 run request check\n\n"
|
|
299
|
+
"| request body | ok: it starts with the status block and contains `Codex session:` |\n")
|
|
300
|
+
assert watch.role(verifier, loaded) == stations.verifier
|
|
301
|
+
assert watch.role("I checked it; the body has `Codex session:` in it.", loaded) == stations.user
|
|
302
|
+
assert watch.role(executor("Status: done\nWaiting on: none\nKey numbers: 1\nNext: merge"), loaded) == stations.executor
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|