Skip to content

Commit d3f532b

Browse files
authored
Merge branch 'main' into test-e2e-grpc-not-set
2 parents 9911bd3 + 66c5de7 commit d3f532b

759 files changed

Lines changed: 68484 additions & 71853 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yaml

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -358,33 +358,45 @@ jobs:
358358
uses: actions/setup-node@v7
359359
with:
360360
node-version-file: ui/.nvmrc
361-
cache: "npm"
362-
cache-dependency-path: ui/package-lock.json
363361

364-
# Honor the pinned npm from ui/package.json "packageManager" so npm ci
365-
# resolves the lock file with the same npm version it was generated with.
362+
# Before any cache step that shells out to yarn: the pinned version in
363+
# ui/package.json "packageManager" is Yarn 4, and without corepack the shim
364+
# on the runner is a different one that cannot read this lock file.
366365
- name: Enable Corepack
367366
run: corepack enable
368367

368+
- name: Cache Yarn downloads
369+
uses: actions/cache@v4
370+
with:
371+
path: ui/.yarn/cache
372+
key: yarn-${{ runner.os }}-${{ hashFiles('ui/yarn.lock') }}
373+
restore-keys: yarn-${{ runner.os }}-
374+
369375
- name: Install dependencies
370376
working-directory: ./ui
371-
run: npm ci
377+
run: yarn install --immutable
378+
379+
- name: Typecheck
380+
working-directory: ./ui
381+
run: yarn typecheck
372382

373383
- name: Run lint
374384
working-directory: ./ui
375-
run: npm run lint
385+
run: yarn lint
376386

377-
- name: Run unit tests (Jest)
387+
- name: Run unit tests
378388
working-directory: ./ui
379-
run: npm run test
389+
run: yarn test
380390

381-
- name: Install Playwright browser (Chromium)
391+
# Both engines the suite declares. Installing only one leaves that project
392+
# failing to launch, which reads as a broken app rather than a missing browser.
393+
- name: Install Playwright browsers
382394
working-directory: ./ui
383-
run: npx playwright install --with-deps chromium
395+
run: yarn playwright install --with-deps chromium firefox
384396

385-
- name: Run Storybook tests (Vitest + Playwright)
397+
- name: Run browser tests
386398
working-directory: ./ui
387-
run: npm run test:vitest
399+
run: yarn test:pw
388400

389401
# This job builds the Docker images for the controller, UI, ADKs, and CLI on arm64.
390402
build:

.github/workflows/ui-chromatic.yaml

Lines changed: 0 additions & 55 deletions
This file was deleted.

.github/workflows/ui-playwright.yaml

Lines changed: 0 additions & 119 deletions
This file was deleted.

CLAUDE.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,85 @@ Common commands:
108108
- Do not commit or push unless asked.
109109
- Keep PRs focused. Explain non-obvious invariants and operational tradeoffs, not line-by-line implementation details.
110110

111+
## The web interface (`ui/`)
112+
113+
A Vite single-page app. It is a static bundle served by nginx: there is no server
114+
process, so there are no server components, no server-side data fetching and no
115+
file-system routing.
116+
117+
**Stack:** Vite + React 19, TypeScript, antd 6 for components, Emotion for styling
118+
(the `css` prop, via `jsxImportSource`), SWR for reads, Yarn 4. React Router owns
119+
routing; there is no file-system routing and no server rendering.
120+
121+
### Commands
122+
123+
Run these from `ui/`:
124+
125+
| Task | Command |
126+
|------|---------|
127+
| Dev server | `yarn dev` |
128+
| Unit tests | `yarn test` |
129+
| End-to-end, no cluster needed | `yarn test:pw` (Chromium and Firefox) |
130+
| End-to-end against a real cluster | `yarn test:pw:live` |
131+
| Type check | `yarn typecheck` |
132+
| Lint | `yarn lint` |
133+
134+
Only lint **errors** gate a change; a handful of warnings are pre-existing.
135+
136+
`scripts/setup-cluster/setup-cluster.sh` builds a Kind cluster with kagent on it in one
137+
command, for work that needs a real backend.
138+
139+
### Settings reach the app at runtime, not at build time
140+
141+
Configuration is read from `window.environmentVariables`, which the container
142+
rewrites from its own environment on every start. So one image serves every
143+
deployment, and a setting is an operator's decision rather than something frozen
144+
into a build. Locally the same values come from `ui/.env` (git-ignored;
145+
`ui/.env.example` documents each one).
146+
147+
Two consequences worth knowing before touching that code:
148+
149+
- The script that supplies them is **synchronous** in `index.html`. Several modules
150+
read settings at import time, so anything awaited would be read before it arrived.
151+
- `import.meta.env` is for build-time flags only. A value that an operator should be
152+
able to change belongs in `window.environmentVariables`.
153+
154+
### Fixtures are opt-in
155+
156+
`ENABLE_MOCK_UI=true` serves the whole API from an in-browser mock (MSW) with no
157+
cluster at all, and `?mock=ok|empty|error|slow` picks which scenario the fixtures
158+
play. **It is off unless asked for**, in a dev server exactly as in a built image: a
159+
page that quietly serves fixtures when the backend is down looks healthy while
160+
showing data that was never real.
161+
162+
When mock mode is on it overrides every backend setting, and anything reporting who
163+
is signed in correctly reports nobody — there is no backend to have signed in to.
164+
165+
### Extension points
166+
167+
One `VendorExtensionConfig` contributes navigation entries and overrides, routes and
168+
route handles, slots, form fields, table columns, API overrides, providers, theme
169+
tokens, shell regions, branding, provider icons and agent links. Components read
170+
every colour, radius and font from those tokens, so overriding them restyles
171+
components an extension never touches. When adding a feature, check whether it
172+
belongs behind an extension point rather than as a branch inside a shared component.
173+
174+
The full guide is [ui/docs/vendor-extensions.md](ui/docs/vendor-extensions.md).
175+
176+
### Conventions specific to this codebase
177+
178+
- **Say when data is not real.** A page showing fixtures says so on the page. Never
179+
suppress an error because a mock flag is set — a broken backend must not render as
180+
healthy mock data.
181+
- **Normalise at the client boundary.** Go marshals a nil slice as JSON `null`, so
182+
any collection the controller has nothing for arrives as null. Fix it once where the
183+
response is parsed, not at each use.
184+
- **Fixtures must match the controller, not each other.** A fixture, a type and a
185+
test can agree perfectly and all three be wrong; that has happened here more than
186+
once and each time only a real cluster objected. Check the CRD.
187+
- **Prefer a smaller honest test suite** over a green one that proves nothing.
188+
Coverage debt belongs in `playwright/DEFERRED.md`, not in skipped specs.
189+
111190
## 9. References
112191

113192
- [STYLE.md](STYLE.md)

docs/plans/api-v2-execution-plan.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,10 @@ MCP:
326326

327327
- Discover ready AgentInstances.
328328
- Invoke them only through the public gateway A2A path.
329+
- Expose durable A2A turns through the MCP Tasks extension, including polling,
330+
cancellation, and input-required continuation.
331+
- Keep synchronous `tools/call` fallback for clients without Tasks support.
332+
- Store no MCP-owned task or session state.
329333
- Never expose Actor or private MCP endpoints.
330334

331335
Content:

go/Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ ARG TARGETARCH
66
ARG TARGETPLATFORM
77
ARG BUILDPLATFORM
88

9-
# Which package to build (e.g. core/cmd/controller/main.go, adk/cmd/main.go)
10-
ARG BUILD_PACKAGE=core/cmd/controller/main.go
9+
# Which package to build (e.g. core/cmd/controller-v2/main.go, adk/cmd/main.go)
10+
ARG BUILD_PACKAGE=core/cmd/controller-v2/main.go
1111

1212
WORKDIR /workspace
1313
# Copy the Go module manifests

go/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ build: core/bin/kagent-linux-amd64.sha256 core/bin/kagent-linux-arm64.sha256 cor
136136

137137
.PHONY: run
138138
run: fmt vet ## Run a controller from your host.
139-
go run ./core/cmd/controller/main.go
139+
go run ./core/cmd/controller-v2/main.go
140140

141141
.PHONY: test
142142
test: ## Run all unit tests.

go/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ The workspace uses a single `Dockerfile` parameterized with `BUILD_PACKAGE`:
103103

104104
```bash
105105
# Build controller image (default)
106-
docker build --build-arg BUILD_PACKAGE=core/cmd/controller/main.go -t controller .
106+
docker build --build-arg BUILD_PACKAGE=core/cmd/controller-v2/main.go -t controller .
107107

108108
# Build Go ADK image
109109
docker build --build-arg BUILD_PACKAGE=adk/cmd/main.go -t golang-adk .

go/api/database/client.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ type Client interface {
9494
GetSessionShareByToken(ctx context.Context, token string) (*SessionShare, error)
9595
ListSessionSharesBySession(ctx context.Context, sessionID string) ([]SessionShare, error)
9696
DeleteSessionShare(ctx context.Context, token, sessionID, userID string) error
97-
RecordShareAccess(ctx context.Context, userID string, shareID int64) error
9897

9998
// Agent memory (vector search) methods
10099
StoreAgentMemory(ctx context.Context, memory *Memory) error
@@ -124,12 +123,19 @@ type Client interface {
124123
CreateAgentInstance(context.Context, *apiv1alpha1.AgentInstance, string) (*apiv1alpha1.AgentInstance, bool, error)
125124
ForkAgentInstance(context.Context, string, string, string, string, string) (*apiv1alpha1.AgentInstance, bool, error)
126125
GetAgentInstance(context.Context, string, string, string) (*apiv1alpha1.AgentInstance, error)
127-
ListAgentInstances(context.Context, string, string, bool, map[string]string, string, int) ([]*apiv1alpha1.AgentInstance, error)
126+
ListAgentInstances(context.Context, AgentInstanceQuery) ([]*apiv1alpha1.AgentInstance, error)
127+
// UpdateAgentInstanceName sets the instance's display name, scoped to its owner.
128+
// Takes namespace, id, owner and the new name.
129+
UpdateAgentInstanceName(context.Context, string, string, string, string) (*apiv1alpha1.AgentInstance, error)
128130
MarkAgentInstanceReady(context.Context, string, string) (*apiv1alpha1.AgentInstance, error)
129131
TransitionAgentInstance(context.Context, *apiv1alpha1.AgentInstance, apiv1alpha1.AgentInstanceState, apiv1alpha1.AgentInstanceOperation) (*apiv1alpha1.AgentInstance, error)
130132
DeleteAgentInstance(context.Context, string) error
131133
CreateAgentInstanceShare(context.Context, AgentInstanceShare) (*AgentInstanceShare, error)
132134
ListAgentInstanceShares(context.Context, string, string, string, string, int) ([]AgentInstanceShare, error)
135+
// GetAgentInstanceShareByTokenHash resolves a share token to its share and the
136+
// owner of the instance it grants access to. Takes the digest, because only the
137+
// digest is stored.
138+
GetAgentInstanceShareByTokenHash(context.Context, []byte) (*AgentInstanceShare, error)
133139
DeleteAgentInstanceShare(context.Context, string, string, string) error
134140
// CreateAgentInstanceTask reserves the instance's single active-task slot.
135141
CreateAgentInstanceTask(context.Context, string, []byte, *a2a.Task) (*a2a.Task, bool, error)

0 commit comments

Comments
 (0)