Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -377,11 +377,14 @@ jobs:
with:
python-version: '3.12'
- run: npm ci
# The venv bakes in the absolute workspace path (/home/runner/work/<repo>/<repo>),
# so the key carries github.repository: a repository rename must not restore a
# venv whose launcher shebangs point at the old path.
- name: Cache examples-chat python venv
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: examples/chat/python/.venv
key: uv-venv-${{ runner.os }}-py3.12-${{ hashFiles('examples/chat/python/uv.lock') }}
key: uv-venv-${{ github.repository }}-${{ runner.os }}-py3.12-${{ hashFiles('examples/chat/python/uv.lock') }}
- working-directory: examples/chat/python
run: uv sync
- run: npx nx run examples-chat-python:smoke --skip-nx-cache
Expand Down Expand Up @@ -411,7 +414,7 @@ jobs:
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: examples/chat/python/.venv
key: uv-venv-${{ runner.os }}-py3.12-${{ hashFiles('examples/chat/python/uv.lock') }}
key: uv-venv-${{ github.repository }}-${{ runner.os }}-py3.12-${{ hashFiles('examples/chat/python/uv.lock') }}
- working-directory: examples/chat/python
run: uv sync
- name: Cache Playwright browsers
Expand Down Expand Up @@ -468,7 +471,7 @@ jobs:
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: examples/ag-ui/python/.venv
key: uv-venv-${{ runner.os }}-py3.12-${{ hashFiles('examples/ag-ui/python/uv.lock') }}
key: uv-venv-${{ github.repository }}-${{ runner.os }}-py3.12-${{ hashFiles('examples/ag-ui/python/uv.lock') }}
- working-directory: examples/ag-ui/python
run: uv sync
- name: Check requirements.txt matches uv.lock
Expand Down Expand Up @@ -578,7 +581,7 @@ jobs:
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: ${{ matrix.cap.python }}/.venv
key: uv-venv-${{ runner.os }}-py3.12-${{ matrix.cap.python }}-${{ hashFiles(format('{0}/uv.lock', matrix.cap.python)) }}
key: uv-venv-${{ github.repository }}-${{ runner.os }}-py3.12-${{ matrix.cap.python }}-${{ hashFiles(format('{0}/uv.lock', matrix.cap.python)) }}
- name: uv sync per-cap python
if: matrix.cap.python != ''
working-directory: ${{ matrix.cap.python }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish-middleware-npm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
# That initial upload creates the @threadplane/middleware package on npm.
# 2. On npmjs.com → @threadplane/middleware → Settings → "Trusted Publisher",
# add this repo + workflow:
# Repository: cacheplane/angular-agent-framework
# Repository: cacheplane/threadplane
# Workflow: publish-middleware-npm.yml
# 3. After that, all releases use OIDC from this workflow — no secret needed.
#
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish-middleware-python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
# 1. Log into PyPI under the **cacheplane** organization.
# 2. Navigate to threadplane-middleware → Settings → "Trusted Publishers".
# 3. Add a **Pending Publisher** with:
# Repository: cacheplane/angular-agent-framework
# Repository: cacheplane/threadplane
# Workflow: publish-middleware-python.yml
# Environment: (leave blank, or set to "pypi" if you create one)
# 4. The FIRST-EVER publish must be bootstrapped locally by a maintainer
Expand Down
8 changes: 4 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Threadplane is MIT-licensed and developed in the open. Contributions are welcome
## How to contribute

1. **Found a bug or have a feature idea?** Open an issue at
<https://github.com/cacheplane/angular-agent-framework/issues> describing the
<https://github.com/cacheplane/threadplane/issues> describing the
problem or proposal. Please search existing issues first.
2. **Code changes:** fork the repository (or create a topic branch if you have
access), make your change on a branch, and open a pull request against `main`.
Expand Down Expand Up @@ -148,11 +148,11 @@ Compare what was actually posted on the head SHA against what protection
requires:

```bash
gh api repos/cacheplane/angular-agent-framework/commits/<head-sha>/status --jq '[.statuses[].context]'
gh api repos/cacheplane/threadplane/commits/<head-sha>/status --jq '[.statuses[].context]'
```

```bash
gh api repos/cacheplane/angular-agent-framework/branches/main/protection --jq '.required_status_checks.checks'
gh api repos/cacheplane/threadplane/branches/main/protection --jq '.required_status_checks.checks'
```

Any required context missing from the posted list is the cause. Fix branch
Expand All @@ -162,7 +162,7 @@ the next one.
Note that check *runs* (GitHub Actions) and commit *statuses* (external apps
like Vercel) are different APIs. `CI — required` is a check run, so it appears
in `gh pr checks` but not in the `/status` output above; use
`gh api repos/cacheplane/angular-agent-framework/commits/<head-sha>/check-runs`
`gh api repos/cacheplane/threadplane/commits/<head-sha>/check-runs`
for those.

### Rollback reference
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
<a href="https://langchain-ai.github.io/langgraph/">
<img alt="LangGraph" src="https://img.shields.io/badge/LangGraph-SDK-6C8EFF?labelColor=080B14&style=flat-square" />
</a>
<a href="https://scorecard.dev/viewer/?uri=github.com/cacheplane/angular-agent-framework">
<img alt="OpenSSF Scorecard" src="https://api.scorecard.dev/projects/github.com/cacheplane/angular-agent-framework/badge" />
<a href="https://scorecard.dev/viewer/?uri=github.com/cacheplane/threadplane">
<img alt="OpenSSF Scorecard" src="https://api.scorecard.dev/projects/github.com/cacheplane/threadplane/badge" />
</a>
<a href="https://www.bestpractices.dev/projects/13316">
<img alt="OpenSSF Best Practices" src="https://www.bestpractices.dev/projects/13316/badge" />
Expand Down
2 changes: 1 addition & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ fixes.
## Reporting a Vulnerability

Please report security issues privately via GitHub's
[private vulnerability reporting](https://github.com/cacheplane/angular-agent-framework/security/advisories/new).
[private vulnerability reporting](https://github.com/cacheplane/threadplane/security/advisories/new).

We aim to acknowledge reports within 5 business days and to provide a
remediation timeline after triage. Please do not open public issues for
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Clone the repo, run `nx serve cockpit-langgraph-interrupts-angular`, and follow
<Card title="Run the live demo" href="/docs/langgraph/guides/interrupts?mode=run">
The refund agent running in the docs workspace. Walk the approve / edit / cancel flow yourself.
</Card>
<Card title="View the source" external href="https://github.com/cacheplane/angular-agent-framework/tree/main/cockpit/langgraph/interrupts">
<Card title="View the source" external href="https://github.com/cacheplane/threadplane/tree/main/cockpit/langgraph/interrupts">
The exact graph.py and Angular component from this post.
</Card>
</CardGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Clone the repo, run `nx serve cockpit-ag-ui-interrupts-angular`, and follow alon
<Card title="Run the live demo" href="/docs/ag-ui/guides/interrupts?mode=run">
The refund agent running in the docs workspace. Walk the approve / edit / cancel flow yourself.
</Card>
<Card title="View the source" external href="https://github.com/cacheplane/angular-agent-framework/tree/main/cockpit/ag-ui/interrupts">
<Card title="View the source" external href="https://github.com/cacheplane/threadplane/tree/main/cockpit/ag-ui/interrupts">
The exact graph.py, server.py, and Angular component from this post.
</Card>
</CardGroup>
Expand Down Expand Up @@ -439,7 +439,7 @@ Your chat surface does not pick.

Pointers:

- The working example: [`cockpit/ag-ui/interrupts`](https://github.com/cacheplane/angular-agent-framework/tree/main/cockpit/ag-ui/interrupts) — Angular + Python, e2e-tested.
- The working example: [`cockpit/ag-ui/interrupts`](https://github.com/cacheplane/threadplane/tree/main/cockpit/ag-ui/interrupts) — Angular + Python, e2e-tested.
- The cross-adapter parity rendered in docs: [Choosing an adapter](https://threadplane.ai/docs/choosing-an-adapter).
- The AG-UI interrupts guide for protocol-level detail: [/docs/ag-ui/guides/interrupts](https://threadplane.ai/docs/ag-ui/guides/interrupts).
- The langgraph counterpart, if you want both sides side-by-side: [Human-in-the-Loop LangGraph Agents in Angular](/blog/2026-05-28-human-in-the-loop-langgraph-agents-in-angular).
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ The full breakdown — every dimension, the Scorecard checks, and the raw JSON

A trust grade is a starting point, not a finish line. The real way to evaluate a framework is to build something with it.

So if you are curious: read the [listing](https://hvtracker.net/agents/threadplane/) and the [Agent Frameworks leaderboard](https://hvtracker.net/categories/agent-frameworks/), browse the [source on GitHub](https://github.com/cacheplane/angular-agent-framework) (all of it — it is almost all open), and ship your first streaming agent UI with the [quickstart](/docs/chat/getting-started/quickstart).
So if you are curious: read the [listing](https://hvtracker.net/agents/threadplane/) and the [Agent Frameworks leaderboard](https://hvtracker.net/categories/agent-frameworks/), browse the [source on GitHub](https://github.com/cacheplane/threadplane) (all of it — it is almost all open), and ship your first streaming agent UI with the [quickstart](/docs/chat/getting-started/quickstart).

We will keep the signals fresh, keep the framework open, and keep working on the one number I am not proud of yet.
The rest, you can verify.
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ It finalized as a success, with a tool call sitting there waiting for an approva
The adapter's `interrupt` signal stayed undefined.
It failed silently, which only means it took longer to notice.

The fix was small once the cause was clear, and it landed in [#888](https://github.com/cacheplane/angular-agent-framework/pull/888).
The fix was small once the cause was clear, and it landed in [#888](https://github.com/cacheplane/threadplane/pull/888).
Both conventions are now recognized.
Updated September 9, 2026: the adapter retains both forms in one session. Native batches take precedence in `auto` mode regardless of arrival order; the Mastra integration explicitly selects `mastra-command` so the resume includes its decision and suspended-tool correlation.

Expand Down Expand Up @@ -112,8 +112,8 @@ Send it nothing addressable and it raises an error.
Four runtimes, three answers to the question of how a resume identifies itself.

The adapter now derives the outgoing shape from how the interrupt arrived, which is the only signal available that is not a hardcoded runtime name.
That work is in [#889](https://github.com/cacheplane/angular-agent-framework/pull/889).
The protocol-package upgrade in [#891](https://github.com/cacheplane/angular-agent-framework/pull/891) is what made the standard top-level array sendable at all.
That work is in [#889](https://github.com/cacheplane/threadplane/pull/889).
The protocol-package upgrade in [#891](https://github.com/cacheplane/threadplane/pull/891) is what made the standard top-level array sendable at all.
The application-facing call did not change.
You still write `submit({ resume })` and the adapter decides what goes on the wire.

Expand Down Expand Up @@ -158,7 +158,7 @@ The platform kept serving the last image that booted.
Nothing was red anywhere.
The route had been returning a not-found for months.

The fix in [#899](https://github.com/cacheplane/angular-agent-framework/pull/899) was two import statements.
The fix in [#899](https://github.com/cacheplane/threadplane/pull/899) was two import statements.
The deploy workflow now installs the exact dependency set, imports the server, and fails the job if it cannot boot.

Verify the route, not the exit code.
Expand Down
8 changes: 4 additions & 4 deletions apps/website/content/docs/choosing-an-adapter/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -145,16 +145,16 @@ Each demo backend ships its emitter in tree, roughly 200 to 430 lines per runtim
Each runtime got a real server, started against the upstream AG-UI integration and driven with live model calls.
The raw Server-Sent Events were captured off the wire, then replayed event-for-event through the pinned `@ag-ui/client` — schema parse plus `verifyEvents` — and through the adapter reducer itself.

The captures for messages, tool calls, state, and interrupts are committed at [`libs/ag-ui/fixtures/runtime-transcripts/`](https://github.com/cacheplane/angular-agent-framework/tree/main/libs/ag-ui/fixtures/runtime-transcripts), verbatim from the wire, and the adapter test suite replays them on every run.
The captures for messages, tool calls, state, and interrupts are committed at [`libs/ag-ui/fixtures/runtime-transcripts/`](https://github.com/cacheplane/threadplane/tree/main/libs/ag-ui/fixtures/runtime-transcripts), verbatim from the wire, and the adapter test suite replays them on every run.
The subagent captures are committed as a `wire-capture-subagents.md` document alongside each backend under `cockpit/runtimes/<runtime>/`; the subagent transcript the suite replays is synthetic, built to the event shape those captures record.

### Runnable examples

Each runtime has a standalone Angular example bound through `@threadplane/ag-ui`, with its own backend:

- [`cockpit/runtimes/aws-strands`](https://github.com/cacheplane/angular-agent-framework/tree/main/cockpit/runtimes/aws-strands) — Python, hosted in the shared FastAPI deployment.
- [`cockpit/runtimes/microsoft-agent-framework`](https://github.com/cacheplane/angular-agent-framework/tree/main/cockpit/runtimes/microsoft-agent-framework) — Python, hosted in that same FastAPI deployment, running beside the Strands and LangGraph topics in one process.
- [`cockpit/runtimes/mastra`](https://github.com/cacheplane/angular-agent-framework/tree/main/cockpit/runtimes/mastra) — TypeScript, hosted by a Node AG-UI service, because the upstream Mastra integration ships an in-process bridge rather than an HTTP endpoint.
- [`cockpit/runtimes/aws-strands`](https://github.com/cacheplane/threadplane/tree/main/cockpit/runtimes/aws-strands) — Python, hosted in the shared FastAPI deployment.
- [`cockpit/runtimes/microsoft-agent-framework`](https://github.com/cacheplane/threadplane/tree/main/cockpit/runtimes/microsoft-agent-framework) — Python, hosted in that same FastAPI deployment, running beside the Strands and LangGraph topics in one process.
- [`cockpit/runtimes/mastra`](https://github.com/cacheplane/threadplane/tree/main/cockpit/runtimes/mastra) — TypeScript, hosted by a Node AG-UI service, because the upstream Mastra integration ships an in-process bridge rather than an HTTP endpoint.

In all three, the component binds the agent through `injectAgent()` and renders `<chat [agent]="agent" />`; the shared-state panels and approval cards around it are demo-specific, and each example wraps `provideAgent()` in a factory only because it resolves its endpoint at runtime.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ That last row is a real constraint of the framework as it stands, not an oversig

## The demos

Each capability page describes a standalone example that runs the real framework against a real model. The examples live in the [repository's deep-agents examples](https://github.com/cacheplane/angular-agent-framework/tree/main/cockpit/deep-agents) and run in the [Threadplane docs workspace](/docs/deep-agents/capabilities/planning?mode=run), which shows the Angular source, the Python graph, and the system prompt beside the running demo.
Each capability page describes a standalone example that runs the real framework against a real model. The examples live in the [repository's deep-agents examples](https://github.com/cacheplane/threadplane/tree/main/cockpit/deep-agents) and run in the [Threadplane docs workspace](/docs/deep-agents/capabilities/planning?mode=run), which shows the Angular source, the Python graph, and the system prompt beside the running demo.

All five share one scenario — an aviation dispatch desk with a handful of airport lookup tools — so the difference between two pages is the capability under test and nothing else.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: The AG-UI wire conventions measured for AWS Strands: outcome interr

# How AWS Strands Connects

This page records the AG-UI wire behavior measured for the Strands bridge on 2026-08-31. It describes what the runtime emitted, not what the protocol permits in general. The captured Server-Sent Events are committed at [`libs/ag-ui/fixtures/runtime-transcripts/`](https://github.com/cacheplane/angular-agent-framework/tree/main/libs/ag-ui/fixtures/runtime-transcripts) and replayed by the adapter test suite on every run.
This page records the AG-UI wire behavior measured for the Strands bridge on 2026-08-31. It describes what the runtime emitted, not what the protocol permits in general. The captured Server-Sent Events are committed at [`libs/ag-ui/fixtures/runtime-transcripts/`](https://github.com/cacheplane/threadplane/tree/main/libs/ag-ui/fixtures/runtime-transcripts) and replayed by the adapter test suite on every run.

## Transport

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ Strands wraps every value an async-generator tool yields as a `tool_stream_event

The handler registered on `research_availability` closes that gap. `subagent_emitter.py` translates the specialist's stream into `SUBAGENT_STARTED`, attributed `TEXT_MESSAGE_*` deltas carrying `subagentRunId`, and `SUBAGENT_FINISHED`, deriving every identifier from the tool call identifier the bridge already put on the wire. The adapter routes those attributed events into a subagent entry instead of the parent transcript, which is why the card streams the specialist's tokens live.

The wire capture behind that matrix cell is committed beside the backend at [`docs/wire-capture-subagents.md`](https://github.com/cacheplane/angular-agent-framework/blob/main/cockpit/runtimes/aws-strands/python/docs/wire-capture-subagents.md), before and after the emitter. Multi-agent routes crash the stale published wheel, which is one reason the example pins the bridge to a git reference instead.
The wire capture behind that matrix cell is committed beside the backend at [`docs/wire-capture-subagents.md`](https://github.com/cacheplane/threadplane/blob/main/cockpit/runtimes/aws-strands/python/docs/wire-capture-subagents.md), before and after the emitter. Multi-agent routes crash the stale published wheel, which is one reason the example pins the bridge to a git reference instead.

## Model access

Expand Down
6 changes: 3 additions & 3 deletions apps/website/content/docs/runtimes/aws-strands/quickstart.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: Run the AWS Strands runtime example locally, backend and Angular ap

# AWS Strands Quickstart

This runs the example from a clone of the [monorepo](https://github.com/cacheplane/angular-agent-framework). The backend is a uvicorn process on port 5331; the Angular dev server is on port 4331 and proxies `/agent` to it.
This runs the example from a clone of the [monorepo](https://github.com/cacheplane/threadplane). The backend is a uvicorn process on port 5331; the Angular dev server is on port 4331 and proxies `/agent` to it.

<Callout type="info" title="Prerequisites">
Node.js 20 or newer, Python 3.12 or newer, [`uv`](https://docs.astral.sh/uv/), and an OpenAI API key. No AWS account and no AWS credentials are required.
Expand All @@ -15,8 +15,8 @@ Node.js 20 or newer, Python 3.12 or newer, [`uv`](https://docs.astral.sh/uv/), a
<Step title="Install workspace dependencies">

```bash
git clone https://github.com/cacheplane/angular-agent-framework.git
cd angular-agent-framework
git clone https://github.com/cacheplane/threadplane.git
cd threadplane
npm ci
```

Expand Down
Loading
Loading