Skip to content

Commit 283fb88

Browse files
Merge branch 'main' into dependabot/pip/cryptography-46.0.7
2 parents ad55955 + 910b424 commit 283fb88

40 files changed

Lines changed: 2695 additions & 166 deletions

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ jobs:
1616
strategy:
1717
matrix:
1818
os: [ubuntu-latest, windows-latest, macos-latest]
19-
python-version: ['3.11', '3.13'] # the one we have in the Codespace + the latest supported one by PyO3.
19+
python-version: ['3.11', '3.14'] # the one we have in the Codespace + the latest one supported by Python 3.
2020
fail-fast: false # Continue testing other version(s) if one fails
2121

2222
steps:
2323
- name: Checkout repository
24-
uses: actions/checkout@v5
24+
uses: actions/checkout@v6
2525

2626
- name: Set up Python ${{ matrix.python-version }}
2727
uses: actions/setup-python@v6

.github/workflows/codeql.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ jobs:
2929
build-mode: none
3030
steps:
3131
- name: Checkout repository
32-
uses: actions/checkout@v4
32+
uses: actions/checkout@v6
3333

3434
- name: Initialize CodeQL
3535
uses: github/codeql-action/init@v4

.github/workflows/publish-to-testpypi.yaml

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,17 @@ name: Publish Pre-Release to TestPyPI
33
on: workflow_dispatch
44

55
jobs:
6-
publish:
7-
name: Build
6+
build:
7+
name: Build distribution
88
runs-on: ubuntu-latest
9-
10-
# This environment is required as an input to pypa/gh-action-pypi-publish
11-
environment:
12-
name: testpypi
13-
url: https://test.pypi.org/p/seclab-taskflow-agent
9+
outputs:
10+
release_name: ${{ steps.create_version_number.outputs.RELEASE_NAME }}
1411

1512
env:
1613
GITHUB_REPO: ${{ github.repository }}
1714

1815
permissions:
19-
contents: write
20-
id-token: write # For trusted publishing
21-
attestations: write # For artifact attestation
16+
contents: read
2217

2318
steps:
2419
- name: Checkout repository
@@ -29,7 +24,7 @@ jobs:
2924
- name: Set up Python
3025
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
3126
with:
32-
python-version: "3.13"
27+
python-version: "3.14"
3328

3429
- name: Install Hatch
3530
run: pip install --upgrade hatch
@@ -52,17 +47,42 @@ jobs:
5247
- name: Build the wheel
5348
run: python3 -m hatch build
5449

55-
- name: Attest build provenance
56-
uses: actions/attest-build-provenance@96278af6caaf10aea03fd8d33a09a777ca52d62f # v3.2.0
57-
with:
58-
subject-path: ./dist/*
59-
6050
- name: Upload artifacts
6151
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
6252
with:
6353
name: python-package-distributions
6454
path: ./dist/
6555

56+
publish:
57+
name: Publish to TestPyPI
58+
needs: build
59+
runs-on: ubuntu-latest
60+
61+
# This environment is required as an input to pypa/gh-action-pypi-publish
62+
environment:
63+
name: testpypi
64+
url: https://test.pypi.org/p/seclab-taskflow-agent
65+
66+
env:
67+
GITHUB_REPO: ${{ github.repository }}
68+
69+
permissions:
70+
contents: write
71+
id-token: write # For trusted publishing
72+
attestations: write # For artifact attestation
73+
74+
steps:
75+
- name: Download distribution artifacts
76+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
77+
with:
78+
name: python-package-distributions
79+
path: ./dist/
80+
81+
- name: Attest build provenance
82+
uses: actions/attest@v4.1.0 # immutable release
83+
with:
84+
subject-path: ./dist/*
85+
6686
- name: Publish to TestPyPI
6787
uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0
6888
with:
@@ -72,5 +92,5 @@ jobs:
7292
- name: Create GitHub Release
7393
env:
7494
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
75-
RELEASE_NAME: ${{ steps.create_version_number.outputs.RELEASE_NAME }}
95+
RELEASE_NAME: ${{ needs.build.outputs.release_name }}
7696
run: gh release create $RELEASE_NAME dist/* --repo $GITHUB_REPO --prerelease --generate-notes

.github/workflows/release.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ jobs:
2424
runs-on: ubuntu-latest
2525
steps:
2626
- name: Checkout code
27-
uses: actions/checkout@v4
27+
uses: actions/checkout@v6
2828

2929
- name: Set up Python
30-
uses: actions/setup-python@v5
30+
uses: actions/setup-python@v6
3131
with:
3232
python-version: '3.11'
3333

@@ -40,7 +40,7 @@ jobs:
4040
echo "digest=$DIGEST" >> $GITHUB_OUTPUT
4141
4242
- name: Generate artifact attestation
43-
uses: actions/attest-build-provenance@v3
43+
uses: actions/attest-build-provenance@v4
4444
with:
4545
subject-name: ${{ env.REGISTRY }}/${{ env.USER }}/${{ env.IMAGE_NAME }}
4646
subject-digest: '${{ steps.docker_build.outputs.digest }}'

.github/workflows/smoketest.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ jobs:
3131

3232
- name: Setup Python
3333
if: steps.branch-deploy.outputs.continue == 'true'
34-
uses: actions/setup-python@v5
34+
uses: actions/setup-python@v6
3535
with:
3636
python-version: '3.11'
3737

README.md

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,23 +24,23 @@ You can find a detailed overview of the taskflow grammar [here](doc/GRAMMAR.md)
2424
```
2525
┌─────────────────────────────────────────────────────┐
2626
│ CLI (cli.py) │
27-
│ Typer-based entry point: -p, -t, -l, -g, --resume │
27+
│ Typer-based entry point: -p, -t, -l, -g, --resume
2828
└─────────────────────┬───────────────────────────────┘
2929
3030
┌─────────────────────▼───────────────────────────────┐
31-
│ Runner (runner.py)
32-
│ Taskflow execution loop, model resolution,
33-
│ template rendering, session checkpointing
31+
│ Runner (runner.py) │
32+
│ Taskflow execution loop, model resolution, │
33+
│ template rendering, session checkpointing │
3434
└─────────────────────┬───────────────────────────────┘
3535
3636
┌─────────────────────▼───────────────────────────────┐
37-
│ MCP Lifecycle (mcp_lifecycle.py)
38-
│ Server connection, cleanup, process management
37+
│ MCP Lifecycle (mcp_lifecycle.py) │
38+
│ Server connection, cleanup, process management │
3939
└─────────────────────┬───────────────────────────────┘
4040
4141
┌─────────────────────▼───────────────────────────────┐
42-
│ Agent (agent.py)
43-
│ TaskAgent wrapper, hooks, OpenAI Agents SDK bridge
42+
│ Agent (agent.py) │
43+
│ TaskAgent wrapper, hooks, OpenAI Agents SDK bridge │
4444
└─────────────────────────────────────────────────────┘
4545
4646
Supporting modules:
@@ -81,6 +81,41 @@ Per-model `model_settings` can include:
8181
- **`endpoint`** — API base URL override for this model
8282
- **`token`** — name of an environment variable containing the API key
8383

84+
### Backends
85+
86+
The runner can drive two SDKs behind a common interface:
87+
88+
- **`openai_agents`** (default) — the OpenAI Agents Python SDK. Supports
89+
multi-personality handoffs, both `chat_completions` and `responses`
90+
`api_type`, `temperature`, `parallel_tool_calls`,
91+
`exclude_from_context`, and MCP over stdio, SSE, and streamable HTTP.
92+
- **`copilot_sdk`** (optional, `pip install seclab-taskflow-agent[copilot]`)
93+
— the GitHub Copilot Python SDK. Supports streaming, `reasoning_effort`,
94+
MCP over stdio/SSE/HTTP, and per-tool permission gating. The SDK
95+
selects its own wire protocol per model, so the YAML `api_type` field
96+
is not honoured; multi-personality handoffs, `temperature`, and
97+
`parallel_tool_calls` are likewise not available. Taskflows that use
98+
unsupported fields fail at load time with a `BackendCapabilityError`
99+
naming the offending field.
100+
101+
Selection precedence:
102+
103+
1. `backend:` field in the model config document.
104+
2. `SECLAB_TASKFLOW_BACKEND` environment variable.
105+
3. Endpoint auto-default (`api.githubcopilot.com` prefers `copilot_sdk`
106+
when the optional dependency is installed).
107+
4. `openai_agents`.
108+
109+
```yaml
110+
seclab-taskflow-agent:
111+
version: "1.0"
112+
filetype: model_config
113+
backend: copilot_sdk
114+
models:
115+
fast: gpt-5-mini
116+
slow: claude-opus-4.6
117+
```
118+
84119
### Session Recovery
85120

86121
Taskflow runs are automatically checkpointed at the task level. If a task

examples/model_configs/model_config.yaml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,7 @@ seclab-taskflow-agent:
55
version: "1.0"
66
filetype: model_config
77
models:
8-
gpt_default: gpt-4.1
9-
8+
gpt_default: gpt-5.4-mini
9+
model_settings:
10+
gpt_default:
11+
api_type: responses

examples/model_configs/responses_api.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ seclab-taskflow-agent:
99
version: "1.0"
1010
filetype: model_config
1111
models:
12-
gpt_responses: gpt-5.1
12+
gpt_responses: gpt-5.4
1313
model_settings:
1414
gpt_responses:
1515
api_type: responses

pyproject.toml

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ classifiers = [
2828
"Programming Language :: Python :: 3.11",
2929
"Programming Language :: Python :: 3.12",
3030
"Programming Language :: Python :: 3.13",
31+
"Programming Language :: Python :: 3.14",
3132
"Programming Language :: Python :: Implementation :: CPython",
3233
"Programming Language :: Python :: Implementation :: PyPy",
3334
"Intended Audience :: Developers",
@@ -86,9 +87,9 @@ dependencies = [
8687
"platformdirs==4.5.0",
8788
"pluggy==1.6.0",
8889
"pycparser==2.23",
89-
"pydantic==2.11.7",
90-
"pydantic-settings==2.10.1",
91-
"pydantic_core==2.33.2",
90+
"pydantic==2.13.3",
91+
"pydantic-settings==2.14.0",
92+
"pydantic_core==2.46.3",
9293
"Pygments==2.20.0",
9394
"pyperclip==1.9.0",
9495
"python-dotenv==1.1.1",
@@ -112,7 +113,7 @@ dependencies = [
112113
"tqdm==4.67.1",
113114
"typer==0.16.0",
114115
"types-requests==2.32.4.20250611",
115-
"typing-inspection==0.4.1",
116+
"typing-inspection==0.4.2",
116117
"typing_extensions==4.15.0",
117118
"ujson==5.12.0",
118119
"urllib3==2.6.3",
@@ -123,6 +124,15 @@ dependencies = [
123124
[project.scripts]
124125
seclab-taskflow-agent = "seclab_taskflow_agent.cli:app"
125126

127+
[project.optional-dependencies]
128+
# Pulls in the GitHub Copilot SDK (public preview) so the copilot_sdk
129+
# backend can be selected. Requires Python >= 3.11. Pinned to the
130+
# 0.2.x line because the SDK may ship breaking changes between minor
131+
# versions while still in preview.
132+
copilot = [
133+
"github-copilot-sdk>=0.2.2,<0.3",
134+
]
135+
126136
[project.urls]
127137
Source = "https://github.com/GitHubSecurityLab/seclab-taskflow-agent"
128138
Issues = "https://github.com/GitHubSecurityLab/seclab-taskflow-agent/issues"

src/seclab_taskflow_agent/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
__all__ = [
2727
"ApiType",
2828
"AvailableTools",
29+
"BackendSdk",
2930
"TaskAgent",
3031
"TaskRunHooks",
3132
"TaskAgentHooks",
@@ -41,6 +42,7 @@
4142
from .available_tools import AvailableTools
4243
from .models import (
4344
ApiType,
45+
BackendSdk,
4446
ModelConfigDocument,
4547
PersonalityDocument,
4648
PromptDocument,

0 commit comments

Comments
 (0)