Skip to content

Commit 52e40a2

Browse files
Merge pull request #30 from Helixar-AI/feat/hdp-agent-framework
feat: add hdp-agent-framework package for Microsoft agent-framework
2 parents 4da27f1 + 990e183 commit 52e40a2

14 files changed

Lines changed: 1638 additions & 0 deletions

File tree

.github/workflows/release.yml

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ on:
88
- 'python/hdp-grok/v*'
99
- 'python/hdp-langchain/v*'
1010
- 'python/hdp-autogen/v*'
11+
- 'python/hdp-agent-framework/v*'
1112
- 'python/hdp-physical/v*'
1213
- 'python/llama-index-callbacks-hdp/v*'
1314
- 'python/hdp-llamaindex/v*'
@@ -872,6 +873,89 @@ jobs:
872873
with:
873874
packages-dir: dist/
874875

876+
# ── hdp-agent-framework (Python / Microsoft agent-framework) ─────────────
877+
878+
test-hdp-agent-framework:
879+
name: Test hdp-agent-framework
880+
if: startsWith(github.ref, 'refs/tags/python/hdp-agent-framework/v')
881+
runs-on: ubuntu-latest
882+
strategy:
883+
matrix:
884+
python-version: ['3.10', '3.11', '3.12']
885+
steps:
886+
- uses: actions/checkout@v5
887+
888+
- name: Set up Python ${{ matrix.python-version }}
889+
uses: actions/setup-python@v5
890+
with:
891+
python-version: ${{ matrix.python-version }}
892+
893+
- name: Install dependencies
894+
working-directory: packages/hdp-agent-framework
895+
run: pip install -e ".[dev]"
896+
897+
- name: Run tests
898+
working-directory: packages/hdp-agent-framework
899+
run: pytest tests/ -v
900+
901+
vet-hdp-agent-framework:
902+
name: Build & Vet hdp-agent-framework (ReleaseGuard)
903+
needs: test-hdp-agent-framework
904+
runs-on: ubuntu-latest
905+
steps:
906+
- uses: actions/checkout@v5
907+
908+
- name: Set up Python
909+
uses: actions/setup-python@v5
910+
with:
911+
python-version: '3.12'
912+
913+
- name: Install build tools
914+
run: pip install build
915+
916+
- name: Build distribution
917+
working-directory: packages/hdp-agent-framework
918+
run: python -m build
919+
920+
- name: Vet artifacts with ReleaseGuard
921+
uses: Helixar-AI/ReleaseGuard@94c067008f3ad516d4b61a6e7163d9d5518a4548
922+
with:
923+
path: packages/hdp-agent-framework/dist
924+
config: packages/hdp-agent-framework/.releaseguard.yml
925+
sbom: 'true'
926+
fix: 'true'
927+
format: sarif
928+
artifact-name: releaseguard-evidence-hdp-agent-framework
929+
930+
- name: Upload vetted distribution
931+
uses: actions/upload-artifact@v4
932+
with:
933+
name: hdp-agent-framework-dist
934+
path: packages/hdp-agent-framework/dist/
935+
retention-days: 1
936+
937+
publish-hdp-agent-framework:
938+
name: Publish hdp-agent-framework to PyPI
939+
needs: vet-hdp-agent-framework
940+
runs-on: ubuntu-latest
941+
permissions:
942+
contents: read
943+
id-token: write
944+
environment:
945+
name: pypi-hdp-agent-framework
946+
url: https://pypi.org/project/hdp-agent-framework/
947+
steps:
948+
- name: Download vetted distribution
949+
uses: actions/download-artifact@v4
950+
with:
951+
name: hdp-agent-framework-dist
952+
path: dist/
953+
954+
- name: Publish to PyPI
955+
uses: pypa/gh-action-pypi-publish@release/v1
956+
with:
957+
packages-dir: dist/
958+
875959
# ── hdp-physical (TypeScript) ─────────────────────────────────────────────
876960

877961
test-hdp-physical:

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
node_modules/
22
dist/
3+
.venv/
34
*.js.map
45
__pycache__/
56
*.pyc
@@ -10,6 +11,8 @@ __pycache__/
1011

1112
# Claude / AI planning artifacts — excluded from repo
1213
docs/superpowers/
14+
docs/*-design.md
15+
docs/*-draft.md
1316
.superpowers/
1417
.DS_Store
1518
.worktrees/

README.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ _Every action an AI agent takes, traceable back to the human who authorized it._
2323
[![CrewAI](https://img.shields.io/badge/CrewAI-integration-f43f5e?style=flat-square)](./packages/hdp-crewai)
2424
[![Grok / xAI](https://img.shields.io/badge/Grok%20%2F%20xAI-integration-000000?style=flat-square)](./packages/hdp-grok)
2525
[![AutoGen](https://img.shields.io/badge/AutoGen-integration-10b981?style=flat-square)](./packages/hdp-autogen)
26+
[![agent-framework](https://img.shields.io/badge/agent--framework-integration-0078d4?style=flat-square)](./packages/hdp-agent-framework)
2627
[![LangChain](https://img.shields.io/badge/LangChain-integration-1c7c4c?style=flat-square)](./packages/hdp-langchain)
2728
[![LlamaIndex](https://img.shields.io/badge/LlamaIndex-integration-7c3aed?style=flat-square)](./packages/llama-index-callbacks-hdp)
2829
[![PyPI llama-index-callbacks-hdp](https://img.shields.io/pypi/v/llama-index-callbacks-hdp?style=flat-square&logo=pypi&logoColor=white&color=7c3aed&label=llama-index-callbacks-hdp)](https://pypi.org/project/llama-index-callbacks-hdp/)
@@ -59,6 +60,7 @@ When a person authorizes an AI agent to act — and that agent delegates to anot
5960
| [`hdp-crewai`](./packages/hdp-crewai) | [PyPI](https://pypi.org/project/hdp-crewai/) | Python | CrewAI | CrewAI middleware — attaches HDP to any crew |
6061
| [`hdp-grok`](./packages/hdp-grok) | [PyPI](https://pypi.org/project/hdp-grok/) | Python | Grok / xAI | Grok middleware — attaches HDP to any xAI conversation |
6162
| [`hdp-autogen`](./packages/hdp-autogen) | [PyPI](https://pypi.org/project/hdp-autogen/) | Python | AutoGen | AutoGen middleware — attaches HDP to any AutoGen agent or GroupChat |
63+
| [`hdp-agent-framework`](./packages/hdp-agent-framework) | [PyPI](https://pypi.org/project/hdp-agent-framework/) | Python | Microsoft agent-framework | agent-framework middleware — attaches HDP to any Agent or workflow |
6264
| [`@helixar_ai/hdp-autogen`](./packages/hdp-autogen-ts) | [npm](https://www.npmjs.com/package/@helixar_ai/hdp-autogen) | TypeScript | AutoGen | AutoGen middleware — HdpAgentWrapper + hdpMiddleware for AutoGen flows |
6365
| [`hdp-langchain`](./packages/hdp-langchain) | [PyPI](https://pypi.org/project/hdp-langchain/) | Python | LangChain / LangGraph | LangChain middleware — attaches HDP to any chain, agent, or LangGraph node |
6466
| [`llama-index-callbacks-hdp`](./packages/llama-index-callbacks-hdp) | [PyPI](https://pypi.org/project/llama-index-callbacks-hdp/) | Python | LlamaIndex | LlamaIndex integration — callback handler, instrumentation dispatcher, node postprocessor |
@@ -102,6 +104,12 @@ pip install hdp-grok
102104
pip install hdp-autogen
103105
```
104106

107+
**Python / Microsoft agent-framework**
108+
109+
```bash
110+
pip install hdp-agent-framework
111+
```
112+
105113
**Python / LangChain**
106114

107115
```bash
@@ -418,6 +426,50 @@ print(result.valid, result.hop_count, result.violations)
418426

419427
---
420428

429+
## Microsoft agent-framework Integration
430+
431+
`hdp-agent-framework` attaches HDP to any Microsoft agent-framework `Agent` via the native `ChatMiddleware` and function middleware protocols. A single `middleware.configure(agent)` call appends both middlewares to `agent.middleware` — no other changes required.
432+
433+
```python
434+
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
435+
from agent_framework import Agent
436+
from agent_framework.foundry import FoundryChatClient
437+
from azure.identity.aio import AzureCliCredential
438+
from hdp_agent_framework import HdpMiddleware, HdpPrincipal, ScopePolicy, verify_chain
439+
440+
private_key = Ed25519PrivateKey.generate()
441+
442+
middleware = HdpMiddleware(
443+
signing_key=private_key.private_bytes_raw(),
444+
session_id="analysis-2026",
445+
principal=HdpPrincipal(id="analyst@corp.com", id_type="email"),
446+
scope=ScopePolicy(
447+
intent="Analyse Q1 sales data and generate a summary",
448+
authorized_tools=["fetch_data", "write_report"],
449+
max_hops=5,
450+
),
451+
)
452+
453+
agent = Agent(client=FoundryChatClient(credential=AzureCliCredential()), name="sales_analyst", tools=[...])
454+
middleware.configure(agent) # attaches chat + function middleware — one line
455+
await agent.run("Analyse Q1 EMEA sales and write a summary.")
456+
457+
result = verify_chain(middleware.export_token(), private_key.public_key())
458+
print(result.valid, result.hop_count)
459+
```
460+
461+
| # | Consideration | Behaviour |
462+
|---|---|---|
463+
| 1 | **Scope enforcement** | Tool calls are inspected against `authorized_tools`. `strict=True` raises `HDPScopeViolationError`; default logs and records in the audit trail. |
464+
| 2 | **Delegation depth** | `max_hops` is enforced; hops beyond the limit are skipped and logged. |
465+
| 3 | **Token size / perf** | Ed25519 = 64 bytes/hop. All operations are non-blocking — failures log, never halt agents. |
466+
| 4 | **Verification** | `verify_chain(token, public_key)` validates root + every hop offline. |
467+
| 5 | **Agent integration** | `configure()` appends `HdpMiddleware` and `_function_middleware` to `agent.middleware` — idempotent, duck-typed, no hard dependency on agent-framework internals. |
468+
469+
[Full agent-framework integration docs](./packages/hdp-agent-framework/README.md)
470+
471+
---
472+
421473
## LlamaIndex Integration
422474

423475
`llama-index-callbacks-hdp` covers all three LlamaIndex hook points. Use whichever layer fits your pipeline — they share the same ContextVar-backed session so all three can be active simultaneously.
@@ -707,6 +759,14 @@ git tag python/hdp-autogen/v0.1.2 && git push origin python/hdp-autogen/v0.1.2
707759

708760
Pipeline: `test-hdp-autogen``vet-hdp-autogen` (ReleaseGuard) → `publish-hdp-autogen`
709761

762+
### hdp-agent-framework → PyPI
763+
764+
```bash
765+
git tag python/hdp-agent-framework/v0.1.0 && git push origin python/hdp-agent-framework/v0.1.0
766+
```
767+
768+
Pipeline: `test-hdp-agent-framework``vet-hdp-agent-framework` (ReleaseGuard) → `publish-hdp-agent-framework`
769+
710770
### hdp-langchain → PyPI
711771

712772
```bash
@@ -740,6 +800,7 @@ Every artifact is scanned by [ReleaseGuard](https://github.com/Helixar-AI/Releas
740800
cd packages/hdp-grok && python -m build && releaseguard check ./dist
741801
cd packages/hdp-crewai && python -m build && releaseguard check ./dist
742802
cd packages/hdp-autogen && python -m build && releaseguard check ./dist
803+
cd packages/hdp-agent-framework && python -m build && releaseguard check ./dist
743804
cd packages/hdp-langchain && python -m build && releaseguard check ./dist
744805
cd packages/llama-index-callbacks-hdp && python -m build && releaseguard check ./dist
745806
cd packages/hdp-autogen-ts && npm run build && releaseguard check ./dist
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# ReleaseGuard policy for hdp-agent-framework Python artifacts
2+
# https://github.com/Helixar-AI/ReleaseGuard
3+
#
4+
# Scans the built wheel and sdist before they are published to PyPI.
5+
# Run locally: releaseguard check ./dist
6+
version: 2
7+
8+
project:
9+
name: hdp-agent-framework
10+
mode: release
11+
12+
inputs:
13+
- path: ./dist
14+
type: directory
15+
16+
sbom:
17+
enabled: true
18+
ecosystems: [python]
19+
formats: [cyclonedx]
20+
enrich_cve: false
21+
22+
scanning:
23+
secrets:
24+
enabled: true
25+
metadata:
26+
enabled: true
27+
fail_on_source_maps: false
28+
fail_on_internal_urls: false
29+
fail_on_build_paths: false
30+
unexpected_files:
31+
enabled: true
32+
deny:
33+
- ".env"
34+
- "*.bak"
35+
- "*.tmp"
36+
- "*.key"
37+
- "*.pem"
38+
licenses:
39+
enabled: true
40+
require:
41+
- LICENSE
42+
43+
transforms:
44+
add_checksums: false # PyPI rejects non-dist files — checksums are handled by PyPI itself
45+
add_manifest: false
46+
47+
policy:
48+
fail_on:
49+
- severity: critical
50+
- category: secret
51+
warn_on:
52+
- severity: high
53+
54+
output:
55+
reports:
56+
- cli
57+
- sarif
58+
directory: ./.releaseguard

0 commit comments

Comments
 (0)