Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
da237de
docs(spec): client-tools — frontend-declared, frontend-executed tools
blove Jun 9, 2026
94e8ace
docs(plan): client-tools index + plan 01 (render foundation)
blove Jun 9, 2026
cd71760
docs(plan): vendor StandardSchemaV1 in plan 01 (avoid lockfile regen)
blove Jun 9, 2026
50b0370
feat(render): RenderViewEntry carries optional schema + description
blove Jun 9, 2026
af3b59f
feat(render): add RenderResultEvent to the RenderEvent union
blove Jun 9, 2026
306c56a
feat(render): add RenderHost contract + injectRenderHost()
blove Jun 9, 2026
d358e0b
feat(render): provide element-scoped RenderHost (set/emit/result)
blove Jun 9, 2026
9495bd7
fix(render): flatten vendored StandardSchema types to satisfy no-name…
blove Jun 9, 2026
759a24a
refactor(chat): a2ui catalog writes via RenderHost.set (drop datamode…
blove Jun 9, 2026
f2af133
refactor(render): remove dead a2ui:datamodel string path
blove Jun 9, 2026
7e3e67c
docs(chat): update stale a2ui:datamodel comments in surface-to-spec
blove Jun 9, 2026
240a9d6
feat(chat): client-tools declaration API (tools/action/view/ask + JSO…
blove Jun 9, 2026
f6af9ea
feat(chat): Agent.clientTools capability + function-tool executor
blove Jun 9, 2026
92773ed
feat(chat): client-tools coordinator + tool-views event forwarding
blove Jun 9, 2026
b3ab39d
feat(chat): wire client-tools coordinator into ChatComponent
blove Jun 9, 2026
144f3d3
feat(ag-ui): implement Agent.clientTools (native tools catalog + addM…
blove Jun 9, 2026
7d0eb7c
feat(langgraph): implement Agent.clientTools (catalog via run input +…
blove Jun 9, 2026
b15b61c
feat(python): client-tools LangGraph middleware package (helpers + st…
blove Jun 9, 2026
b022364
feat(cockpit): ag-ui/client-tools example (function/view/ask) + wiring
blove Jun 9, 2026
65313b9
fix(chat): client-tool executor must run 'complete' tool calls
blove Jun 9, 2026
70de660
docs(cockpit): ag-ui/client-tools guide (function/view/ask, middleware)
blove Jun 9, 2026
8089f12
test(cockpit): e2e for ag-ui/client-tools (function/view/ask)
blove Jun 9, 2026
5afb3c3
feat(cockpit): langgraph/client-tools example (function/view/ask) + e…
blove Jun 9, 2026
c2406c9
refactor(python): threadplane.client_tools namespace package + OIDC p…
blove Jun 10, 2026
2570a7e
chore(docs): regenerate api docs
github-actions[bot] Jun 10, 2026
a1fd68b
chore(python): reserve cacheplane name with a namespace placeholder
blove Jun 10, 2026
d960b8b
chore(cockpit): client-tools examples depend on published threadplane…
blove Jun 10, 2026
8850c56
fix(client-tools): compile under strictNullChecks:false + declare @ag…
blove Jun 10, 2026
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
79 changes: 79 additions & 0 deletions .github/workflows/publish-client-tools-python.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Staged PyPI publish workflow for threadplane-client-tools (Python package).
#
# This workflow uses PyPI TRUSTED PUBLISHING (OIDC) — no API token secret is
# required. GitHub exchanges its OIDC token for a short-lived PyPI upload
# credential automatically when the job has `id-token: write`.
#
# To enable trusted publishing on PyPI:
# 1. Log into PyPI under the **cacheplane** organization.
# 2. Navigate to threadplane-client-tools → Settings → "Trusted Publishers".
# 3. Add a **Pending Publisher** with:
# Repository: cacheplane/angular-agent-framework
# Workflow: publish-client-tools-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
# using a PyPI API token (`uv publish --token <tok> dist/*`). After that
# initial upload creates the project on PyPI, all subsequent releases use
# OIDC from this workflow — no secret needed.
#
# This workflow is MANUALLY TRIGGERED ONLY — it will never run automatically
# on push or pull_request. A maintainer must dispatch it from the Actions tab
# (or via `gh workflow run`) after verifying the release is ready.
#
# Inputs:
# dry_run (default: true) — when true, `uv publish --dry-run` is used and
# nothing is uploaded to PyPI. Set to false only for a real release.

name: Publish threadplane-client-tools (Python)

on:
# STAGED: dispatch manually only. Never add push: or pull_request: triggers.
workflow_dispatch:
inputs:
dry_run:
description: "Dry run — skip actual upload to PyPI (default: true)"
type: boolean
default: true

concurrency:
group: publish-client-tools-python
cancel-in-progress: false

jobs:
build-and-publish:
name: Build and publish threadplane-client-tools
runs-on: ubuntu-latest

permissions:
id-token: write # Required for OIDC trusted publishing to PyPI
contents: read

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v5
with:
version: "latest"

- name: Run tests before publishing
working-directory: packages/threadplane-client-tools
run: |
uv venv
uv pip install -e '.[test]'
uv run pytest -q

- name: Build distribution
working-directory: packages/threadplane-client-tools
run: uv build

- name: Publish to PyPI (dry run)
if: ${{ inputs.dry_run == true }}
working-directory: packages/threadplane-client-tools
run: uv publish --dry-run dist/*

- name: Publish to PyPI (real release — OIDC trusted publishing)
if: ${{ inputs.dry_run == false }}
working-directory: packages/threadplane-client-tools
run: uv publish dist/*
2 changes: 2 additions & 0 deletions apps/cockpit/scripts/capability-registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export const capabilities: readonly Capability[] = [
{ id: 'subgraphs', product: 'langgraph', topic: 'subgraphs', angularProject: 'cockpit-langgraph-subgraphs-angular', port: 4305, pythonPort: 5305, pythonDir: 'cockpit/langgraph/subgraphs/python', graphName: 'subgraphs' },
{ id: 'time-travel', product: 'langgraph', topic: 'time-travel', angularProject: 'cockpit-langgraph-time-travel-angular', port: 4306, pythonPort: 5306, pythonDir: 'cockpit/langgraph/time-travel/python', graphName: 'time-travel' },
{ id: 'deployment-runtime', product: 'langgraph', topic: 'deployment-runtime', angularProject: 'cockpit-langgraph-deployment-runtime-angular', port: 4307, pythonPort: 5307, pythonDir: 'cockpit/langgraph/deployment-runtime/python', graphName: 'deployment-runtime' },
{ id: 'langgraph-client-tools', product: 'langgraph', topic: 'client-tools', angularProject: 'cockpit-langgraph-client-tools-angular', port: 4308, pythonPort: 5308, pythonDir: 'cockpit/langgraph/client-tools/python', graphName: 'client-tools' },
{ id: 'da-planning', product: 'deep-agents', topic: 'planning', angularProject: 'cockpit-deep-agents-planning-angular', port: 4310, pythonPort: 5310, pythonDir: 'cockpit/deep-agents/planning/python', graphName: 'da-planning' },
{ id: 'da-filesystem', product: 'deep-agents', topic: 'filesystem', angularProject: 'cockpit-deep-agents-filesystem-angular', port: 4311, pythonPort: 5311, pythonDir: 'cockpit/deep-agents/filesystem/python', graphName: 'da-filesystem' },
{ id: 'da-subagents', product: 'deep-agents', topic: 'subagents', angularProject: 'cockpit-deep-agents-subagents-angular', port: 4312, pythonPort: 5312, pythonDir: 'cockpit/deep-agents/subagents/python', graphName: 'subagents' },
Expand Down Expand Up @@ -54,6 +55,7 @@ export const capabilities: readonly Capability[] = [
{ id: 'ag-ui-streaming', product: 'ag-ui', topic: 'streaming', angularProject: 'cockpit-ag-ui-streaming-angular', port: 4321, pythonPort: 5321, pythonDir: 'cockpit/ag-ui/streaming/python' },
{ id: 'ag-ui-tool-views', product: 'ag-ui', topic: 'tool-views', angularProject: 'cockpit-ag-ui-tool-views-angular', port: 4322, pythonPort: 5322, pythonDir: 'cockpit/ag-ui/tool-views/python' },
{ id: 'ag-ui-json-render', product: 'ag-ui', topic: 'json-render', angularProject: 'cockpit-ag-ui-json-render-angular', port: 4323, pythonPort: 5323, pythonDir: 'cockpit/ag-ui/json-render/python' },
{ id: 'ag-ui-client-tools', product: 'ag-ui', topic: 'client-tools', angularProject: 'cockpit-ag-ui-client-tools-angular', port: 4325, pythonPort: 5325, pythonDir: 'cockpit/ag-ui/client-tools/python' },
{ id: 'ag-ui-a2ui', product: 'ag-ui', topic: 'a2ui', angularProject: 'cockpit-ag-ui-a2ui-angular', port: 4324, pythonPort: 5324, pythonDir: 'cockpit/ag-ui/a2ui/python' },
] as const;

Expand Down
4 changes: 4 additions & 0 deletions apps/cockpit/src/lib/route-resolution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ import { langgraphDurableExecutionPythonModule } from '../../../../cockpit/langg
import { langgraphSubgraphsPythonModule } from '../../../../cockpit/langgraph/subgraphs/python/src/index';
import { langgraphTimeTravelPythonModule } from '../../../../cockpit/langgraph/time-travel/python/src/index';
import { langgraphDeploymentRuntimePythonModule } from '../../../../cockpit/langgraph/deployment-runtime/python/src/index';
import { langgraphClientToolsPythonModule } from '../../../../cockpit/langgraph/client-tools/python/src/index';
import { agUiInterruptsPythonModule } from '../../../../cockpit/ag-ui/interrupts/python/src/index';
import { agUiStreamingPythonModule } from '../../../../cockpit/ag-ui/streaming/python/src/index';
import { agUiToolViewsPythonModule } from '../../../../cockpit/ag-ui/tool-views/python/src/index';
import { agUiJsonRenderPythonModule } from '../../../../cockpit/ag-ui/json-render/python/src/index';
import { agUiClientToolsPythonModule } from '../../../../cockpit/ag-ui/client-tools/python/src/index';
import { agUiA2uiPythonModule } from '../../../../cockpit/ag-ui/a2ui/python/src/index';
import { deepAgentsMemoryPythonModule } from '../../../../cockpit/deep-agents/memory/python/src/index';
import { deepAgentsPlanningPythonModule } from '../../../../cockpit/deep-agents/planning/python/src/index';
Expand Down Expand Up @@ -86,10 +88,12 @@ const capabilityModules = [
langgraphSubgraphsPythonModule,
langgraphTimeTravelPythonModule,
langgraphDeploymentRuntimePythonModule,
langgraphClientToolsPythonModule,
agUiInterruptsPythonModule,
agUiStreamingPythonModule,
agUiToolViewsPythonModule,
agUiJsonRenderPythonModule,
agUiClientToolsPythonModule,
agUiA2uiPythonModule,
deepAgentsMemoryPythonModule,
deepAgentsPlanningPythonModule,
Expand Down
8 changes: 7 additions & 1 deletion apps/website/content/docs/ag-ui/api/api-docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -405,8 +405,14 @@
{
"name": "AgUiAgent",
"kind": "interface",
"description": "The neutral Agent contract, widened with the AG-UI adapter's optional\n`customEvents` signal (the chat composition feature-detects it to enable\nlive a2ui streaming). Mirrors langgraph's LangGraphAgent extension.",
"description": "The neutral Agent contract, widened with the AG-UI adapter's optional\n`customEvents` signal (the chat composition feature-detects it to enable\nlive a2ui streaming) and the optional `clientTools` capability.\nMirrors langgraph's LangGraphAgent extension.",
"properties": [
{
"name": "clientTools",
"type": "ClientToolsCapability",
"description": "Optional: client-declared, client-executed tools (see ClientToolsCapability).",
"optional": false
},
{
"name": "customEvents",
"type": "Signal<CustomStreamEvent[]>",
Expand Down
Loading
Loading