openshell-agent-runner 0.0.2__tar.gz → 0.0.3__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.
- openshell_agent_runner-0.0.3/PKG-INFO +138 -0
- openshell_agent_runner-0.0.3/README.md +115 -0
- {openshell_agent_runner-0.0.2 → openshell_agent_runner-0.0.3}/src/openshell_agent_runner/cli.py +46 -8
- {openshell_agent_runner-0.0.2 → openshell_agent_runner-0.0.3}/src/openshell_agent_runner/config.py +37 -2
- {openshell_agent_runner-0.0.2 → openshell_agent_runner-0.0.3}/src/openshell_agent_runner/harnesses/pi/resources.py +10 -2
- {openshell_agent_runner-0.0.2 → openshell_agent_runner-0.0.3}/src/openshell_agent_runner/harnesses/pi/runtime/extensions/validate-tools.ts +3 -3
- {openshell_agent_runner-0.0.2 → openshell_agent_runner-0.0.3}/src/openshell_agent_runner/harnesses/pi/runtime/image/exec.sh +1 -0
- {openshell_agent_runner-0.0.2 → openshell_agent_runner-0.0.3}/src/openshell_agent_runner/openshell.py +2 -0
- {openshell_agent_runner-0.0.2 → openshell_agent_runner-0.0.3}/src/openshell_agent_runner/profile_init.py +1 -1
- openshell_agent_runner-0.0.3/src/openshell_agent_runner/profiles/code-reviewer/profile.yaml +21 -0
- openshell_agent_runner-0.0.3/src/openshell_agent_runner/profiles/code-reviewer/prompt-repository.md +15 -0
- openshell_agent_runner-0.0.3/src/openshell_agent_runner/profiles/code-reviewer/schemas/review.json +159 -0
- openshell_agent_runner-0.0.3/src/openshell_agent_runner/profiles/code-reviewer/skills/review-code/SKILL.md +111 -0
- openshell_agent_runner-0.0.3/src/openshell_agent_runner/profiles/code-reviewer/skills/review-code/agents/openai.yaml +4 -0
- openshell_agent_runner-0.0.3/src/openshell_agent_runner/profiles/technical-writing-reviewer/models.json +19 -0
- openshell_agent_runner-0.0.3/src/openshell_agent_runner/profiles/technical-writing-reviewer/policy.yaml +15 -0
- openshell_agent_runner-0.0.3/src/openshell_agent_runner/profiles/technical-writing-reviewer/profile.yaml +21 -0
- openshell_agent_runner-0.0.3/src/openshell_agent_runner/profiles/technical-writing-reviewer/prompt-document.md +15 -0
- openshell_agent_runner-0.0.3/src/openshell_agent_runner/profiles/technical-writing-reviewer/schemas/review.json +160 -0
- openshell_agent_runner-0.0.3/src/openshell_agent_runner/profiles/technical-writing-reviewer/settings.json +5 -0
- openshell_agent_runner-0.0.3/src/openshell_agent_runner/profiles/technical-writing-reviewer/skills/review-technical-writing/SKILL.md +120 -0
- openshell_agent_runner-0.0.3/src/openshell_agent_runner/profiles/technical-writing-reviewer/skills/review-technical-writing/agents/openai.yaml +4 -0
- openshell_agent_runner-0.0.3/src/openshell_agent_runner/prompt_templates.py +48 -0
- {openshell_agent_runner-0.0.2 → openshell_agent_runner-0.0.3}/src/openshell_agent_runner/runner.py +123 -18
- openshell_agent_runner-0.0.2/PKG-INFO +0 -164
- openshell_agent_runner-0.0.2/README.md +0 -141
- openshell_agent_runner-0.0.2/src/openshell_agent_runner/profiles/reviewer/profile.yaml +0 -12
- openshell_agent_runner-0.0.2/src/openshell_agent_runner/profiles/reviewer/prompt.md +0 -5
- {openshell_agent_runner-0.0.2 → openshell_agent_runner-0.0.3}/.gitignore +0 -0
- {openshell_agent_runner-0.0.2 → openshell_agent_runner-0.0.3}/LICENSE +0 -0
- {openshell_agent_runner-0.0.2 → openshell_agent_runner-0.0.3}/pyproject.toml +0 -0
- {openshell_agent_runner-0.0.2 → openshell_agent_runner-0.0.3}/src/openshell_agent_runner/__init__.py +0 -0
- {openshell_agent_runner-0.0.2 → openshell_agent_runner-0.0.3}/src/openshell_agent_runner/artifacts.py +0 -0
- {openshell_agent_runner-0.0.2 → openshell_agent_runner-0.0.3}/src/openshell_agent_runner/errors.py +0 -0
- {openshell_agent_runner-0.0.2 → openshell_agent_runner-0.0.3}/src/openshell_agent_runner/harnesses/__init__.py +0 -0
- {openshell_agent_runner-0.0.2 → openshell_agent_runner-0.0.3}/src/openshell_agent_runner/harnesses/pi/__init__.py +0 -0
- {openshell_agent_runner-0.0.2 → openshell_agent_runner-0.0.3}/src/openshell_agent_runner/harnesses/pi/runtime/extensions/submit-result.ts +0 -0
- {openshell_agent_runner-0.0.2 → openshell_agent_runner-0.0.3}/src/openshell_agent_runner/harnesses/pi/runtime/image/Dockerfile +0 -0
- {openshell_agent_runner-0.0.2 → openshell_agent_runner-0.0.3}/src/openshell_agent_runner/harnesses/resources.py +0 -0
- {openshell_agent_runner-0.0.2 → openshell_agent_runner-0.0.3}/src/openshell_agent_runner/profiles/__init__.py +0 -0
- {openshell_agent_runner-0.0.2/src/openshell_agent_runner/profiles/reviewer → openshell_agent_runner-0.0.3/src/openshell_agent_runner/profiles/code-reviewer}/models.json +0 -0
- {openshell_agent_runner-0.0.2/src/openshell_agent_runner/profiles/reviewer → openshell_agent_runner-0.0.3/src/openshell_agent_runner/profiles/code-reviewer}/policy.yaml +0 -0
- {openshell_agent_runner-0.0.2/src/openshell_agent_runner/profiles/reviewer → openshell_agent_runner-0.0.3/src/openshell_agent_runner/profiles/code-reviewer}/settings.json +0 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: openshell-agent-runner
|
|
3
|
+
Version: 0.0.3
|
|
4
|
+
Summary: Launch ephemeral agents for single tasks in OpenShell sandboxes.
|
|
5
|
+
Project-URL: Repository, https://github.com/NVIDIA/OpenShell-Research
|
|
6
|
+
Project-URL: Documentation, https://nvidia.github.io/OpenShell-Research/documentation/openshell-agent-runner/
|
|
7
|
+
Author: NVIDIA CORPORATION & AFFILIATES
|
|
8
|
+
License-Expression: Apache-2.0
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
16
|
+
Classifier: Topic :: Software Development
|
|
17
|
+
Requires-Python: >=3.12
|
|
18
|
+
Requires-Dist: jsonschema<5,>=4.25
|
|
19
|
+
Requires-Dist: pydantic<3,>=2.11
|
|
20
|
+
Requires-Dist: pyyaml<7,>=6
|
|
21
|
+
Requires-Dist: typer<1,>=0.16
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
# OpenShell Agent Runner
|
|
25
|
+
|
|
26
|
+
OpenShell Agent Runner (OAR) runs an agent task in an isolated OpenShell sandbox
|
|
27
|
+
and saves the result to a file. Use it to review code, review technical writing,
|
|
28
|
+
or run your own tasks from a terminal or CI job.
|
|
29
|
+
|
|
30
|
+
```text
|
|
31
|
+
Profile + input → OAR → Agent in a temporary sandbox → Result file
|
|
32
|
+
sandbox removed when the run ends
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
A **profile** packages prompts, reusable skills, and settings. A **task** is one
|
|
36
|
+
job in that profile; it selects the prompt and skills to use. OAR includes two
|
|
37
|
+
ready-to-use reviewers:
|
|
38
|
+
|
|
39
|
+
| Profile | Task | Input |
|
|
40
|
+
| --- | --- | --- |
|
|
41
|
+
| `code-reviewer` | `review-repository` | A local project directory |
|
|
42
|
+
| `technical-writing-reviewer` | `review-document` | A text file, such as Markdown or `.txt` |
|
|
43
|
+
|
|
44
|
+
## Get started
|
|
45
|
+
|
|
46
|
+
You need [uv](https://docs.astral.sh/uv/getting-started/installation/) and
|
|
47
|
+
OpenShell 0.0.111 or newer, with a running gateway and configured inference.
|
|
48
|
+
If OpenShell is not ready, follow its
|
|
49
|
+
[quickstart](https://docs.nvidia.com/openshell/latest/get-started/quickstart).
|
|
50
|
+
OAR uses that setup to create sandboxes and reach your model.
|
|
51
|
+
|
|
52
|
+
**1. Install OAR and check your connection.**
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
uv tool install openshell-agent-runner
|
|
56
|
+
oar doctor
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Alternatively, use `uvx --from openshell-agent-runner oar` in place of `oar`.
|
|
60
|
+
|
|
61
|
+
These commands use your selected OpenShell gateway and its `default` workspace.
|
|
62
|
+
For another target, add `--gateway NAME --workspace NAME` to `doctor` and `run`.
|
|
63
|
+
|
|
64
|
+
**2. Create your profiles.** Replace `YOUR_MODEL_ID` with the model ID shown in
|
|
65
|
+
the inference output from `oar doctor`.
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
oar init ./profiles --model YOUR_MODEL_ID
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
This creates editable copies of both reviewers. For a model without reasoning
|
|
72
|
+
support, add `--thinking off`.
|
|
73
|
+
|
|
74
|
+
**3. Review a document.** Replace `./README.md` with an existing text file.
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
oar run ./profiles/technical-writing-reviewer \
|
|
78
|
+
--task review-document \
|
|
79
|
+
--input ./README.md \
|
|
80
|
+
--output ./review.json
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Open `review.json` for the verdict, a score from 0 to 100, and specific findings.
|
|
84
|
+
OAR saves the validated result and removes the sandbox. Add `--dry-run` to
|
|
85
|
+
preview the operation without launching an agent.
|
|
86
|
+
|
|
87
|
+
## Review code
|
|
88
|
+
|
|
89
|
+
Pass a local project directory. Optional `focus` and `context` values help the
|
|
90
|
+
reviewer understand what matters for this run:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
oar run ./profiles/code-reviewer \
|
|
94
|
+
--task review-repository \
|
|
95
|
+
--input ./my-project \
|
|
96
|
+
--prompt-var focus="src/auth and tests/auth" \
|
|
97
|
+
--prompt-var context="A small internal tool; keep recommendations proportionate." \
|
|
98
|
+
--output ./code-review.json
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
The agent works on an uploaded copy. Changes in the sandbox stay there; only the
|
|
102
|
+
result is downloaded. A `focus` value guides attention but does not limit which
|
|
103
|
+
files are uploaded.
|
|
104
|
+
|
|
105
|
+
## Learn more
|
|
106
|
+
|
|
107
|
+
- [Get started](https://nvidia.github.io/OpenShell-Research/documentation/openshell-agent-runner/): setup and your first review.
|
|
108
|
+
- [Run reviews](https://nvidia.github.io/OpenShell-Research/documentation/openshell-agent-runner/reviews/): inputs, focus, context, and scores.
|
|
109
|
+
- [Customize profiles](https://nvidia.github.io/OpenShell-Research/documentation/openshell-agent-runner/profiles/): prompts, variables, skills, and output formats.
|
|
110
|
+
- [Command reference](https://nvidia.github.io/OpenShell-Research/documentation/openshell-agent-runner/reference/): options, CI behavior, and troubleshooting.
|
|
111
|
+
|
|
112
|
+
For help with a specific task:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
oar run ./profiles/code-reviewer --task review-repository --help
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Develop OAR
|
|
119
|
+
|
|
120
|
+
From `projects/openshell-agent-runner`, run:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
make check
|
|
124
|
+
make build
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
`make check` includes CLI workflows against a simulated OpenShell. With Docker,
|
|
128
|
+
run `make test-runtime` to exercise the real Pi harness without external inference.
|
|
129
|
+
For runtime changes, one live CI task checks input transfer, prompt variables,
|
|
130
|
+
structured output, and sandbox cleanup. It does not grade reviewer opinions.
|
|
131
|
+
|
|
132
|
+
Use `uv run --frozen oar` in this directory to run the checked-out code instead
|
|
133
|
+
of the installed release. Run a focused test with
|
|
134
|
+
`make test PYTEST_ARGS="tests/test_config.py"`. See
|
|
135
|
+
[RELEASING.md](https://github.com/NVIDIA/OpenShell-Research/blob/main/projects/openshell-agent-runner/RELEASING.md)
|
|
136
|
+
for publishing, and the
|
|
137
|
+
[repository CI guide](https://github.com/NVIDIA/OpenShell-Research/blob/main/docs/development/ci.md)
|
|
138
|
+
for automated project reviews and the live OAR smoke test.
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# OpenShell Agent Runner
|
|
2
|
+
|
|
3
|
+
OpenShell Agent Runner (OAR) runs an agent task in an isolated OpenShell sandbox
|
|
4
|
+
and saves the result to a file. Use it to review code, review technical writing,
|
|
5
|
+
or run your own tasks from a terminal or CI job.
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
Profile + input → OAR → Agent in a temporary sandbox → Result file
|
|
9
|
+
sandbox removed when the run ends
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
A **profile** packages prompts, reusable skills, and settings. A **task** is one
|
|
13
|
+
job in that profile; it selects the prompt and skills to use. OAR includes two
|
|
14
|
+
ready-to-use reviewers:
|
|
15
|
+
|
|
16
|
+
| Profile | Task | Input |
|
|
17
|
+
| --- | --- | --- |
|
|
18
|
+
| `code-reviewer` | `review-repository` | A local project directory |
|
|
19
|
+
| `technical-writing-reviewer` | `review-document` | A text file, such as Markdown or `.txt` |
|
|
20
|
+
|
|
21
|
+
## Get started
|
|
22
|
+
|
|
23
|
+
You need [uv](https://docs.astral.sh/uv/getting-started/installation/) and
|
|
24
|
+
OpenShell 0.0.111 or newer, with a running gateway and configured inference.
|
|
25
|
+
If OpenShell is not ready, follow its
|
|
26
|
+
[quickstart](https://docs.nvidia.com/openshell/latest/get-started/quickstart).
|
|
27
|
+
OAR uses that setup to create sandboxes and reach your model.
|
|
28
|
+
|
|
29
|
+
**1. Install OAR and check your connection.**
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
uv tool install openshell-agent-runner
|
|
33
|
+
oar doctor
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Alternatively, use `uvx --from openshell-agent-runner oar` in place of `oar`.
|
|
37
|
+
|
|
38
|
+
These commands use your selected OpenShell gateway and its `default` workspace.
|
|
39
|
+
For another target, add `--gateway NAME --workspace NAME` to `doctor` and `run`.
|
|
40
|
+
|
|
41
|
+
**2. Create your profiles.** Replace `YOUR_MODEL_ID` with the model ID shown in
|
|
42
|
+
the inference output from `oar doctor`.
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
oar init ./profiles --model YOUR_MODEL_ID
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
This creates editable copies of both reviewers. For a model without reasoning
|
|
49
|
+
support, add `--thinking off`.
|
|
50
|
+
|
|
51
|
+
**3. Review a document.** Replace `./README.md` with an existing text file.
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
oar run ./profiles/technical-writing-reviewer \
|
|
55
|
+
--task review-document \
|
|
56
|
+
--input ./README.md \
|
|
57
|
+
--output ./review.json
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Open `review.json` for the verdict, a score from 0 to 100, and specific findings.
|
|
61
|
+
OAR saves the validated result and removes the sandbox. Add `--dry-run` to
|
|
62
|
+
preview the operation without launching an agent.
|
|
63
|
+
|
|
64
|
+
## Review code
|
|
65
|
+
|
|
66
|
+
Pass a local project directory. Optional `focus` and `context` values help the
|
|
67
|
+
reviewer understand what matters for this run:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
oar run ./profiles/code-reviewer \
|
|
71
|
+
--task review-repository \
|
|
72
|
+
--input ./my-project \
|
|
73
|
+
--prompt-var focus="src/auth and tests/auth" \
|
|
74
|
+
--prompt-var context="A small internal tool; keep recommendations proportionate." \
|
|
75
|
+
--output ./code-review.json
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
The agent works on an uploaded copy. Changes in the sandbox stay there; only the
|
|
79
|
+
result is downloaded. A `focus` value guides attention but does not limit which
|
|
80
|
+
files are uploaded.
|
|
81
|
+
|
|
82
|
+
## Learn more
|
|
83
|
+
|
|
84
|
+
- [Get started](https://nvidia.github.io/OpenShell-Research/documentation/openshell-agent-runner/): setup and your first review.
|
|
85
|
+
- [Run reviews](https://nvidia.github.io/OpenShell-Research/documentation/openshell-agent-runner/reviews/): inputs, focus, context, and scores.
|
|
86
|
+
- [Customize profiles](https://nvidia.github.io/OpenShell-Research/documentation/openshell-agent-runner/profiles/): prompts, variables, skills, and output formats.
|
|
87
|
+
- [Command reference](https://nvidia.github.io/OpenShell-Research/documentation/openshell-agent-runner/reference/): options, CI behavior, and troubleshooting.
|
|
88
|
+
|
|
89
|
+
For help with a specific task:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
oar run ./profiles/code-reviewer --task review-repository --help
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Develop OAR
|
|
96
|
+
|
|
97
|
+
From `projects/openshell-agent-runner`, run:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
make check
|
|
101
|
+
make build
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
`make check` includes CLI workflows against a simulated OpenShell. With Docker,
|
|
105
|
+
run `make test-runtime` to exercise the real Pi harness without external inference.
|
|
106
|
+
For runtime changes, one live CI task checks input transfer, prompt variables,
|
|
107
|
+
structured output, and sandbox cleanup. It does not grade reviewer opinions.
|
|
108
|
+
|
|
109
|
+
Use `uv run --frozen oar` in this directory to run the checked-out code instead
|
|
110
|
+
of the installed release. Run a focused test with
|
|
111
|
+
`make test PYTEST_ARGS="tests/test_config.py"`. See
|
|
112
|
+
[RELEASING.md](https://github.com/NVIDIA/OpenShell-Research/blob/main/projects/openshell-agent-runner/RELEASING.md)
|
|
113
|
+
for publishing, and the
|
|
114
|
+
[repository CI guide](https://github.com/NVIDIA/OpenShell-Research/blob/main/docs/development/ci.md)
|
|
115
|
+
for automated project reviews and the live OAR smoke test.
|
{openshell_agent_runner-0.0.2 → openshell_agent_runner-0.0.3}/src/openshell_agent_runner/cli.py
RENAMED
|
@@ -120,9 +120,16 @@ def run(
|
|
|
120
120
|
output: Annotated[
|
|
121
121
|
Path, typer.Option("--output", help="Host path for the agent result.")
|
|
122
122
|
],
|
|
123
|
-
|
|
123
|
+
input_path: Annotated[
|
|
124
124
|
Path | None,
|
|
125
|
-
typer.Option("--input", help="Host
|
|
125
|
+
typer.Option("--input", help="Host input required by the selected task."),
|
|
126
|
+
] = None,
|
|
127
|
+
prompt_variable: Annotated[
|
|
128
|
+
list[str] | None,
|
|
129
|
+
typer.Option(
|
|
130
|
+
"--prompt-var",
|
|
131
|
+
help="Non-secret NAME=VALUE prompt variable. Repeat for several.",
|
|
132
|
+
),
|
|
126
133
|
] = None,
|
|
127
134
|
upload: Annotated[
|
|
128
135
|
list[str] | None,
|
|
@@ -159,7 +166,8 @@ def run(
|
|
|
159
166
|
profile_directory=profile,
|
|
160
167
|
task_id=task,
|
|
161
168
|
output=output,
|
|
162
|
-
|
|
169
|
+
input_path=input_path,
|
|
170
|
+
prompt_variables=prompt_variable or (),
|
|
163
171
|
uploads=upload or (),
|
|
164
172
|
environments=environment or (),
|
|
165
173
|
gateway=gateway,
|
|
@@ -185,12 +193,17 @@ def doctor(
|
|
|
185
193
|
str, typer.Option("--workspace", help="OpenShell workspace name.")
|
|
186
194
|
] = "default",
|
|
187
195
|
) -> None:
|
|
188
|
-
"""
|
|
196
|
+
"""Inspect OpenShell connection and configuration without changing its state."""
|
|
189
197
|
try:
|
|
190
198
|
checks = run_doctor(NativeTarget(gateway=gateway, workspace=workspace))
|
|
191
199
|
except OarError as error:
|
|
192
200
|
_fail(error)
|
|
193
201
|
typer.echo("\n\n".join(result for _, result in checks))
|
|
202
|
+
typer.echo(
|
|
203
|
+
"\nThese are configuration checks, not an inference request. "
|
|
204
|
+
"Before running a task, confirm that an inference provider and model "
|
|
205
|
+
"are listed above."
|
|
206
|
+
)
|
|
194
207
|
|
|
195
208
|
|
|
196
209
|
def _fail(error: OarError) -> NoReturn:
|
|
@@ -227,8 +240,10 @@ def _render_task_help(
|
|
|
227
240
|
_help_command(f" oar run {shlex.quote(str(profile_directory))} \\"),
|
|
228
241
|
_help_command(f" --task {shlex.quote(task_id)} \\"),
|
|
229
242
|
]
|
|
230
|
-
if task.required_input
|
|
231
|
-
usage_lines.append(
|
|
243
|
+
if task.required_input is not None:
|
|
244
|
+
usage_lines.append(
|
|
245
|
+
_help_command(f" --input {task.required_input.upper()} \\")
|
|
246
|
+
)
|
|
232
247
|
usage_lines.append(_help_command(" --output OUTPUT"))
|
|
233
248
|
|
|
234
249
|
upload_lines = [_help_heading("Additional configured uploads:")]
|
|
@@ -244,6 +259,22 @@ def _render_task_help(
|
|
|
244
259
|
environment_lines.append(" None. Add values with --env KEY=VALUE.")
|
|
245
260
|
|
|
246
261
|
input_lines = _required_input_help(task.required_input)
|
|
262
|
+
prompt_variable_lines = [_help_heading("Prompt variables:")]
|
|
263
|
+
if task.prompt_variables:
|
|
264
|
+
for name, variable in task.prompt_variables.items():
|
|
265
|
+
requirement = (
|
|
266
|
+
f"Default: {variable.default}"
|
|
267
|
+
if variable.default is not None
|
|
268
|
+
else "Required."
|
|
269
|
+
)
|
|
270
|
+
prompt_variable_lines.extend(
|
|
271
|
+
[
|
|
272
|
+
_help_command(f" --prompt-var {name}=VALUE"),
|
|
273
|
+
f" {variable.description} {requirement}",
|
|
274
|
+
]
|
|
275
|
+
)
|
|
276
|
+
else:
|
|
277
|
+
prompt_variable_lines.append(" None.")
|
|
247
278
|
|
|
248
279
|
output_description = (
|
|
249
280
|
f"JSON validated against {task.output_schema}."
|
|
@@ -260,6 +291,8 @@ def _render_task_help(
|
|
|
260
291
|
"",
|
|
261
292
|
*input_lines,
|
|
262
293
|
"",
|
|
294
|
+
*prompt_variable_lines,
|
|
295
|
+
"",
|
|
263
296
|
*upload_lines,
|
|
264
297
|
"",
|
|
265
298
|
*environment_lines,
|
|
@@ -274,10 +307,15 @@ def _render_task_help(
|
|
|
274
307
|
def _required_input_help(required_input: str | None) -> list[str]:
|
|
275
308
|
if required_input is None:
|
|
276
309
|
return [_help_heading("Required input:"), " None."]
|
|
310
|
+
description = (
|
|
311
|
+
"Host document to review."
|
|
312
|
+
if required_input == "document"
|
|
313
|
+
else "Host code repository to review."
|
|
314
|
+
)
|
|
277
315
|
return [
|
|
278
316
|
_help_heading("Required argument:"),
|
|
279
|
-
_help_command(" --input
|
|
280
|
-
"
|
|
317
|
+
_help_command(f" --input {required_input.upper()}"),
|
|
318
|
+
f" {description}",
|
|
281
319
|
]
|
|
282
320
|
|
|
283
321
|
|
{openshell_agent_runner-0.0.2 → openshell_agent_runner-0.0.3}/src/openshell_agent_runner/config.py
RENAMED
|
@@ -23,6 +23,11 @@ from pydantic import (
|
|
|
23
23
|
)
|
|
24
24
|
|
|
25
25
|
from openshell_agent_runner.errors import ConfigurationError
|
|
26
|
+
from openshell_agent_runner.prompt_templates import (
|
|
27
|
+
BUILTIN_PROMPT_VARIABLES,
|
|
28
|
+
PROMPT_VARIABLE_NAME_PATTERN,
|
|
29
|
+
validate_prompt_template,
|
|
30
|
+
)
|
|
26
31
|
|
|
27
32
|
IDENTIFIER_PATTERN = r"^[a-z][a-z0-9-]{0,62}$"
|
|
28
33
|
RESOURCE_IDENTIFIER_PATTERN = r"^[a-z][a-z0-9_-]{0,62}$"
|
|
@@ -62,6 +67,7 @@ class SandboxConfig(StrictModel):
|
|
|
62
67
|
|
|
63
68
|
|
|
64
69
|
ToolName = Annotated[str, Field(pattern=RESOURCE_IDENTIFIER_PATTERN)]
|
|
70
|
+
PromptVariableName = Annotated[str, Field(pattern=PROMPT_VARIABLE_NAME_PATTERN)]
|
|
65
71
|
|
|
66
72
|
|
|
67
73
|
class ExtensionConfig(StrictModel):
|
|
@@ -76,10 +82,18 @@ class ExtensionConfig(StrictModel):
|
|
|
76
82
|
return values
|
|
77
83
|
|
|
78
84
|
|
|
85
|
+
class PromptVariableConfig(StrictModel):
|
|
86
|
+
description: str = Field(min_length=1, max_length=1000)
|
|
87
|
+
default: str | None = Field(default=None, min_length=1)
|
|
88
|
+
|
|
89
|
+
|
|
79
90
|
class TaskConfig(StrictModel):
|
|
80
91
|
description: str | None = Field(default=None, min_length=1, max_length=1000)
|
|
81
|
-
required_input: Literal["document"] | None = None
|
|
92
|
+
required_input: Literal["document", "repository"] | None = None
|
|
82
93
|
prompt: Path
|
|
94
|
+
prompt_variables: dict[PromptVariableName, PromptVariableConfig] = Field(
|
|
95
|
+
default_factory=dict
|
|
96
|
+
)
|
|
83
97
|
output_schema: Path | None = None
|
|
84
98
|
tools: list[ToolName] = Field(default_factory=list)
|
|
85
99
|
skills: list[Path] = Field(default_factory=list)
|
|
@@ -125,6 +139,11 @@ class TaskConfig(StrictModel):
|
|
|
125
139
|
f"{sorted(BUILTIN_PI_TOOLS)}; declare each custom tool under a "
|
|
126
140
|
"referenced extension"
|
|
127
141
|
)
|
|
142
|
+
if self.skills and "read" not in self.tools:
|
|
143
|
+
raise ValueError(
|
|
144
|
+
"tasks with skills must include 'read' in tools so Pi can "
|
|
145
|
+
"discover and load the skills"
|
|
146
|
+
)
|
|
128
147
|
return self
|
|
129
148
|
|
|
130
149
|
|
|
@@ -345,7 +364,23 @@ def _validate_profile_resources(resolved: ResolvedProfile) -> None:
|
|
|
345
364
|
directory = resolved.profile_dir
|
|
346
365
|
_inside(directory, directory / resolved.profile.sandbox.policy, "sandbox policy")
|
|
347
366
|
for task_id, task in resolved.profile.tasks.items():
|
|
348
|
-
|
|
367
|
+
prompt = _inside(
|
|
368
|
+
directory, directory / task.prompt, f"prompt for task {task_id}"
|
|
369
|
+
)
|
|
370
|
+
available_builtins = (
|
|
371
|
+
BUILTIN_PROMPT_VARIABLES if task.required_input is not None else frozenset()
|
|
372
|
+
)
|
|
373
|
+
try:
|
|
374
|
+
template = prompt.read_text(encoding="utf-8")
|
|
375
|
+
validate_prompt_template(
|
|
376
|
+
template,
|
|
377
|
+
task.prompt_variables.keys(),
|
|
378
|
+
available_builtins,
|
|
379
|
+
)
|
|
380
|
+
except (OSError, UnicodeError, ValueError) as error:
|
|
381
|
+
raise ConfigurationError(
|
|
382
|
+
f"invalid prompt template for task {task_id}: {error}"
|
|
383
|
+
) from error
|
|
349
384
|
if task.output_schema is not None:
|
|
350
385
|
schema = _inside(
|
|
351
386
|
directory,
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
import json
|
|
7
7
|
import shutil
|
|
8
8
|
import tempfile
|
|
9
|
+
from collections.abc import Mapping
|
|
9
10
|
from importlib.resources import files
|
|
10
11
|
from pathlib import Path
|
|
11
12
|
|
|
@@ -15,6 +16,7 @@ from openshell_agent_runner.config import (
|
|
|
15
16
|
ResolvedProfile,
|
|
16
17
|
)
|
|
17
18
|
from openshell_agent_runner.harnesses.resources import PreparedResources
|
|
19
|
+
from openshell_agent_runner.prompt_templates import render_prompt_template
|
|
18
20
|
|
|
19
21
|
SANDBOX_RUNTIME_ROOT = "/sandbox/oar-runtime"
|
|
20
22
|
|
|
@@ -23,13 +25,19 @@ def image_directory() -> Path:
|
|
|
23
25
|
return Path(str(files("openshell_agent_runner.harnesses.pi") / "runtime" / "image"))
|
|
24
26
|
|
|
25
27
|
|
|
26
|
-
def prepare_resources(
|
|
28
|
+
def prepare_resources(
|
|
29
|
+
resolved: ResolvedProfile,
|
|
30
|
+
task_id: str,
|
|
31
|
+
prompt_variables: Mapping[str, str] | None = None,
|
|
32
|
+
) -> PreparedResources:
|
|
27
33
|
temporary = tempfile.TemporaryDirectory(prefix="oar-pi-")
|
|
28
34
|
runtime = Path(temporary.name) / "runtime"
|
|
29
35
|
(runtime / "skills").mkdir(parents=True, exist_ok=True)
|
|
30
36
|
(runtime / "extensions").mkdir(parents=True, exist_ok=True)
|
|
31
37
|
task = resolved.profile.tasks[task_id]
|
|
32
|
-
|
|
38
|
+
template = (resolved.profile_dir / task.prompt).read_text(encoding="utf-8")
|
|
39
|
+
rendered_prompt = render_prompt_template(template, prompt_variables or {})
|
|
40
|
+
(runtime / "prompt.md").write_text(rendered_prompt, encoding="utf-8")
|
|
33
41
|
shutil.copy2(resolved.profile_dir / MODELS_FILENAME, runtime / MODELS_FILENAME)
|
|
34
42
|
shutil.copy2(resolved.profile_dir / SETTINGS_FILENAME, runtime / SETTINGS_FILENAME)
|
|
35
43
|
arguments = [
|
|
@@ -19,10 +19,10 @@ export function findMissingTools(
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
export default function (pi: ExtensionAPI) {
|
|
22
|
-
pi.on("before_agent_start", (
|
|
23
|
-
const availableTools =
|
|
22
|
+
pi.on("before_agent_start", () => {
|
|
23
|
+
const availableTools = pi.getAllTools();
|
|
24
24
|
const missingTools = findMissingTools(requestedTools, availableTools);
|
|
25
|
-
const activeTools =
|
|
25
|
+
const activeTools = pi.getActiveTools();
|
|
26
26
|
const activeNames = new Set(activeTools);
|
|
27
27
|
const inactiveTools = requestedTools.filter((name) => !activeNames.has(name));
|
|
28
28
|
const unavailableTools = [...new Set([...missingTools, ...inactiveTools])];
|
|
@@ -17,7 +17,7 @@ from pathlib import Path
|
|
|
17
17
|
from openshell_agent_runner.config import MODEL_IDENTIFIER_PATTERN, load_profile
|
|
18
18
|
from openshell_agent_runner.errors import ConfigurationError
|
|
19
19
|
|
|
20
|
-
PACKAGED_PROFILES = ("reviewer",)
|
|
20
|
+
PACKAGED_PROFILES = ("code-reviewer", "technical-writing-reviewer")
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
class ThinkingLevel(StrEnum):
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
id: code-reviewer
|
|
2
|
+
description: Review an input code repository for concrete engineering issues.
|
|
3
|
+
|
|
4
|
+
sandbox:
|
|
5
|
+
policy: policy.yaml
|
|
6
|
+
|
|
7
|
+
tasks:
|
|
8
|
+
review-repository:
|
|
9
|
+
description: Review an input code repository and return a structured result.
|
|
10
|
+
required_input: repository
|
|
11
|
+
prompt: prompt-repository.md
|
|
12
|
+
prompt_variables:
|
|
13
|
+
focus:
|
|
14
|
+
description: Files, directories, behavior, or risks that deserve special attention.
|
|
15
|
+
default: Review the complete repository.
|
|
16
|
+
context:
|
|
17
|
+
description: Intent, constraints, non-goals, or maturity that should calibrate the review.
|
|
18
|
+
default: No additional context was provided.
|
|
19
|
+
output_schema: schemas/review.json
|
|
20
|
+
tools: [read, grep, find, ls, bash]
|
|
21
|
+
skills: [skills/review-code]
|
openshell_agent_runner-0.0.3/src/openshell_agent_runner/profiles/code-reviewer/prompt-repository.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Review the input code repository
|
|
2
|
+
|
|
3
|
+
Work as a code review agent. Load and follow the `review-code` skill.
|
|
4
|
+
|
|
5
|
+
Review the repository at `{{ oar.input_path }}`, originally provided as
|
|
6
|
+
`{{ oar.input_name }}`.
|
|
7
|
+
|
|
8
|
+
Review focus: {{ focus }}
|
|
9
|
+
|
|
10
|
+
Additional context: {{ context }}
|
|
11
|
+
|
|
12
|
+
Treat the focus as a priority, not permission to ignore directly related code.
|
|
13
|
+
Review the repository as it exists; do not assume it represents a pull request
|
|
14
|
+
or has useful Git history. Do not edit source files. Finish only by submitting a
|
|
15
|
+
result that satisfies the configured output schema.
|