Repository navigation
Commit fc19bd5
authored
Split the Core/Web boundary: official /v1, one Core-key /core/v1 tree, Core-key executor credentials (#128)
* Serve exactly the pinned official routes under /v1
/v1 now has the 58 method and path pairs of the pinned OpenAI Python SDK
3.13.0. The eight Core extension routes are removed from /v1: startup
configuration, Runtime observations (list and per Session), Runtime
history (capabilities and per Session), Session execution configuration,
Session sandbox placement and the sandbox node directory. Their
administrator equivalents under /core/v1/admin keep the same handlers.
Placement is automatic only: x_agents_core.sandbox_node_id is removed and
is now rejected as an unknown member (400). The store no longer selects an
explicit node, and the unused per-Session placement read is gone.
The shared client drops SandboxProjectClient and the public /v1 readers
for the removed routes; AdminClient keeps its /core equivalents.
scripts/extract-agents-api-upstream.py writes upstream-routes.json and
upstream-fields.json from the pinned SDK. Contract tests require the
public OpenAPI to have exactly those routes and to keep every
non-official field inside x_agents_core, with three shared-schema
mismatches listed for a decision.
* Test the administrator Runtime observation list
Port the ordering, concurrency-limit and whole-page failure tests of the
removed /v1 list to GET /core/v1/admin/runtime-observations, including its
Project labels and tenant binding.
* Hold /v1 fields and routes to the pinned SDK
The field audit now accepts x_agents_core only on the Agent, saved-Agent
and Session definitions, with harness and model_provider as its only
members, and compares query parameters with the SDK's query params types,
which the extractor now records. A test proves the audit catches
sandbox_node_id in the Session or Agent extension and x_agents_core on a
Vault, and the extracted operations must equal the pinned route set.
The router walk compares the served non-HEAD /v1 routes with the pinned
set. Administrator Runtime tests cover the unconfigured 503 and HEAD 405,
and the client tests cover the observation page invariants.
Docs no longer mention explicit node selection or Project node reads, say
when a Session carries agent.x_agents_core, list executor credential
issuance in the API index and drop the removed /v1 Runtime reads from the
HEAD exceptions.
* Remove the startup configuration and history capability reads left without a route
P1 removed their /core/v1/admin routes and P4 removed their /v1 routes, so
after the merge the handlers, Core types, server composition, client
projections and tests had no caller.
* Serve /core/v1 as one Core-key tree and issue executor credentials there
/core/v1/admin/** moves to /core/v1/**: projects, summary, audit-log,
metrics (was core-metrics) and sandbox/runtime-observations. One
Core-key router serves the whole tree, so every /core/v1 request,
including an unknown path, is authenticated before routing, and old
/core/v1/admin paths return 404.
Executor credentials move from the Project-key route
/core/v1/environments/{id}/executor-credentials to
/core/v1/projects/{project_id}/environments/{environment_id}/executor-credentials
with the Core key: GET lists metadata, POST issues or rotates, DELETE
revokes. The target must be a self_hosted Environment of the Project whose
Session exists. The Project's principal remains the execution principal,
the scope stays daemon enrollment and connection for that Environment, and
each write records an administrator audit entry in its transaction.
* Forward every signed-in /core/v1 request from the console with the Core key
The per-route allowlists in admin_routes.go and sandbox_admin.go and the
/core/v1/environments special case are replaced by one rule: after console
sign-in and the existing origin and CSRF checks, a /core/v1/* request is
forwarded with the Core key and Core decides whether the route exists.
/v1 and /api/v1 still return 404, and the path checks that keep dot
segments and encoded separators from leaving /core/v1 are unchanged.
* Give the Core clients their own /core/v1 request layer
AdminClient, SandboxAdminClient and CoreMetricsClient keep their names and
methods but no longer extend the /v1 OpenAIAgentsClient. They share an
internal Core request layer that reuses AdminClient's error projection and
AgentCoreError, never sends OpenAI-Beta and sends a bearer only when a Core
key is given. Defaults are /core/v1, /core/v1/sandbox and /core/v1/metrics;
listRuntimeObservations reads /core/v1/sandbox/runtime-observations.
Export CoreProjectReader as agreed with Web, tighten listSkills,
listSkillVersions and listSourceFiles to SkillList, SkillVersionList and
SourceFileList so a project-bound AdminClient satisfies it without a cast,
and add listExecutorCredentials, issueExecutorCredential and
revokeExecutorCredential with ExecutorCredential,
IssueExecutorCredentialInput and IssuedExecutorCredential.
SandboxNode.diagnostic is optional because Core omits it when ready.
* Generate the /core/v1 contract as core.openapi.yaml
sandbox-manager.openapi.yaml held every /core/v1 route, not only sandbox
administration. make openapi now splits the generated document by
namespace into openapi.yaml (/v1), core.openapi.yaml (/core/v1) and
runtime.openapi.yaml (/api/v1); the public openapi.yaml is unchanged.
* Test that each credential works only in its own namespace
A table over the served composition shows a Project API key reaches only
/v1, the Core key only /core/v1, and node and executor credentials only
their own /api/v1 machine connection routes; every other cell is 401.
* Document the three namespaces and the Core-key executor credentials
AGENTS.md is replaced with the agreed draft adjusted to the final facts.
docs/api/README.md becomes the /v1, /core/v1 and /api/v1 table with a
/core/v1 route-group index; CONTRIBUTING.md, design principles, the Web
and public API guides and getting-started describe Web as a /core/v1-only
client behind a prefix proxy. Contracts move from /core/v1/admin to
/core/v1, the executor credential contract and self-hosted installation
steps describe Core-key issuance by the operator, and the removed startup
configuration and history capability reads are noted.
* Name the Core key in the machine connection contract
* Test executor credential key_id form and unknown-key rotation over HTTP
A key_id that is not a canonical lowercase, non-nil UUID is 400 before any
store call, and rotate:true for a key_id that was never issued is 404.
* Refuse executor credential issuance and rotation in an archived Project
Issue and rotate return the existing 409 project_archived. The check
share-locks the Project inside the issuing transaction, before the write and
its audit entry, so a concurrent archive either follows the issuance or is
seen by it. Listing and revocation stay available, because revoking must
always work.
* Say "Core key only" in the /core/v1 operation descriptions
The generated Core contract described its operations as deployment
administrator only; it now names the Core key, as the docs do, and says the
Project ID, not a key, selects the target space. openapi.yaml is unchanged.
* Check executor credential writes in the agreed order
Issue and rotate now validate the request body (400), then the target
Environment (404), then an archived Project (409 project_archived), and only
then the key: 409 executor_credential_exists without rotate, or 404 for
rotating a key_id that was never issued. Previously the Project was
resolved before the body, and rotation checked the key before the archive.
The in-transaction archive check stays for concurrent archives.
* Issue the release guide's executor credential with the Core key
The Core-key POST under /core/v1/projects/{p}/environments/{e} is now the
instruction; keys.json no longer exists. agents-api-environment-key remains
only as a marked break-glass database path that skips the archived-Project
check and writes no administrator audit entry.
* Treat CoreMetricsClient baseUrl as a prefix like the other Core clients
The default is now /core/v1 and the client requests /metrics?range=..., so
new CoreMetricsClient() still reads /core/v1/metrics. Option names are
unchanged; each option has a one-line doc comment.
* Add the node enrollment token to the credential matrix
An unconsumed enrollment token reads node configuration and gets 401 on
/v1, /core/v1, node identity and both agent-daemon routes. The matrix now
also covers daemon enrollment, which only the executor credential passes.
* Tag the Core execution configuration read like the other /core/v1 reads
It was the last Core operation tagged "Core extensions"; it is now
"Execution configuration", beside "Runtime observations" and "Runtime
history". Project resource summaries say "in a Project" instead of the
stale "in a managed key space". openapi.yaml is unchanged.
* Read the console's data through Core's new routes
* Check the project reader against Core's client type
* Issue, rotate and revoke executor credentials from a self-hosted Session
* Rotate restores a revoked executor credential, as in Core
* Match Core's executor credential rules in the fixture
Rotating a key_id never issued for the environment returns 404, key IDs must be lowercase non-nil canonical UUIDs, and not-found responses use Core's not_found_error code.
* Hide executor credential writes on an archived project
Core refuses issue and rotate on an archived project with 409 project_archived while list and revoke still work. The fixture returns that 409, and the Session page hides Issue and Rotate with a note; a write that meets project_archived shows the same note as its error and rereads the projects instead of entering rotate recovery.
* Derive the fixture's error type as Core does
* Describe the console's /core/v1 prefix forwarding in the Web docs
* Never recover an executor credential the administrator already managed
A kept key ID from an issuance with an unknown outcome is no longer sent
again once it is listed, and a successful rotation or revocation of it
forgets it, so the next Issue starts a new credential instead of offering
to rotate one that was just rotated or revoked. An existing key ID (409)
opens rotation only after a fresh read shows it active in an active
project; otherwise the issuance is reported as rejected.
Dismissing the one-time credential dialog now keeps the credential on the
page until Done, as the API-key flow does. The list's date column is
"Created", and the empty state no longer repeats the Issue button.
* Reject a non-JSON executor credential body with 400, as Core does
* Correct the executor credential rules in the Web docs
Core accepts the self_hosted environment of any existing Session in the project and returns 404 otherwise; its only conflicts are project_archived and executor_credential_exists, and rotation restores a revoked key, which the console hides by choice. Record the archived-project view, the recovery rules and the Session page's credential management.1 parent 44d0caa commit fc19bd5
192 files changed
Lines changed: 6594 additions & 4434 deletions
File tree
- apps/web
- .impeccable/surfaces
- e2e
- data
- src
- features
- dashboard
- files
- metrics
- sessions
- skills
- vaults
- i18n/locales
- en
- zh-CN
- lib
- contracts/agents-api
- v1
- deploy/install
- docs
- api
- getting-started
- web
- packages/agents-client
- src
- scripts
- openapi-split
- services
- agents-api
- cmd/server
- internal
- api
- db
- queries
- sqlc
- store
- tests
- core-console
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
4 | | - | |
5 | | - | |
6 | | - | |
7 | | - | |
8 | | - | |
9 | | - | |
10 | | - | |
11 | | - | |
12 | | - | |
13 | | - | |
14 | | - | |
15 | | - | |
16 | | - | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
17 | 54 | | |
18 | 55 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
31 | | - | |
32 | | - | |
33 | | - | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
34 | 36 | | |
35 | 37 | | |
36 | | - | |
37 | | - | |
38 | | - | |
| 38 | + | |
| 39 | + | |
39 | 40 | | |
40 | 41 | | |
41 | 42 | | |
42 | 43 | | |
43 | 44 | | |
44 | | - | |
45 | | - | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
46 | 48 | | |
47 | 49 | | |
48 | 50 | | |
| |||
156 | 158 | | |
157 | 159 | | |
158 | 160 | | |
159 | | - | |
160 | | - | |
161 | | - | |
| 161 | + | |
| 162 | + | |
162 | 163 | | |
163 | 164 | | |
164 | 165 | | |
| |||
190 | 191 | | |
191 | 192 | | |
192 | 193 | | |
193 | | - | |
194 | | - | |
195 | | - | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
196 | 197 | | |
197 | 198 | | |
198 | 199 | | |
| |||
207 | 208 | | |
208 | 209 | | |
209 | 210 | | |
210 | | - | |
| 211 | + | |
211 | 212 | | |
212 | 213 | | |
213 | 214 | | |
| |||
733 | 734 | | |
734 | 735 | | |
735 | 736 | | |
736 | | - | |
737 | | - | |
| 737 | + | |
| 738 | + | |
738 | 739 | | |
739 | 740 | | |
740 | 741 | | |
| |||
827 | 828 | | |
828 | 829 | | |
829 | 830 | | |
830 | | - | |
831 | | - | |
| 831 | + | |
| 832 | + | |
832 | 833 | | |
833 | 834 | | |
834 | 835 | | |
| |||
905 | 906 | | |
906 | 907 | | |
907 | 908 | | |
908 | | - | |
909 | | - | |
910 | | - | |
911 | | - | |
| 909 | + | |
| 910 | + | |
912 | 911 | | |
913 | 912 | | |
914 | 913 | | |
| |||
1770 | 1769 | | |
1771 | 1770 | | |
1772 | 1771 | | |
1773 | | - | |
1774 | | - | |
1775 | | - | |
1776 | | - | |
1777 | | - | |
| 1772 | + | |
| 1773 | + | |
| 1774 | + | |
| 1775 | + | |
| 1776 | + | |
| 1777 | + | |
| 1778 | + | |
| 1779 | + | |
| 1780 | + | |
1778 | 1781 | | |
1779 | 1782 | | |
1780 | 1783 | | |
| |||
1842 | 1845 | | |
1843 | 1846 | | |
1844 | 1847 | | |
1845 | | - | |
1846 | | - | |
1847 | | - | |
1848 | | - | |
1849 | | - | |
1850 | | - | |
1851 | | - | |
1852 | | - | |
1853 | | - | |
1854 | | - | |
1855 | | - | |
1856 | | - | |
| 1848 | + | |
| 1849 | + | |
| 1850 | + | |
| 1851 | + | |
| 1852 | + | |
| 1853 | + | |
| 1854 | + | |
| 1855 | + | |
| 1856 | + | |
| 1857 | + | |
| 1858 | + | |
| 1859 | + | |
1857 | 1860 | | |
1858 | 1861 | | |
1859 | 1862 | | |
| |||
1881 | 1884 | | |
1882 | 1885 | | |
1883 | 1886 | | |
1884 | | - | |
1885 | | - | |
| 1887 | + | |
| 1888 | + | |
| 1889 | + | |
1886 | 1890 | | |
1887 | 1891 | | |
1888 | 1892 | | |
| |||
2236 | 2240 | | |
2237 | 2241 | | |
2238 | 2242 | | |
2239 | | - | |
2240 | | - | |
2241 | | - | |
| 2243 | + | |
| 2244 | + | |
| 2245 | + | |
2242 | 2246 | | |
2243 | 2247 | | |
2244 | 2248 | | |
2245 | 2249 | | |
2246 | 2250 | | |
2247 | 2251 | | |
2248 | | - | |
| 2252 | + | |
2249 | 2253 | | |
2250 | 2254 | | |
2251 | 2255 | | |
| |||
3448 | 3452 | | |
3449 | 3453 | | |
3450 | 3454 | | |
3451 | | - | |
3452 | | - | |
| 3455 | + | |
3453 | 3456 | | |
3454 | 3457 | | |
3455 | 3458 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
31 | | - | |
| 31 | + | |
32 | 32 | | |
33 | 33 | | |
34 | 34 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
19 | 19 | | |
20 | 20 | | |
21 | 21 | | |
22 | | - | |
23 | | - | |
24 | | - | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
25 | 25 | | |
26 | 26 | | |
27 | 27 | | |
| |||
0 commit comments