feat(web): expose the agent-preset roster over the API
`agentPreset.list` gives a browser the deployment's roster so it can offer a choice when starting a session. Each row carries the id, its `trust`, and whether it is the current default. `trust` is on the wire deliberately: a `user` preset is exactly as privileged as the plugins it names, so a surface that offers one alongside a shipped preset can say which is which rather than presenting both as vetted. The domain is read-only. A preset is a composition on disk, so authoring one is a filesystem act rather than an RPC; and a deployment composing no presets answers with an empty roster rather than an error, because sharing the host composition is a valid deployment. The RPC map made every registration site a type error, so the route, the response-schema table, the service delegate, and the browser fixture are all wired rather than only the ones I remembered.
This commit is contained in:
16 files changed
+159
-2
No files matched your search
@@ -2484,6 +2484,24 @@ export function createApiProxy(ctx: Context, defaults: ApiProxyDefaults): ApiPro
|
||||
},
|
||||
},
|
||||
|
||||
agentPresets: {
|
||||
// A deployment with no roster answers with an empty list rather than an
|
||||
// error: composing no presets is a valid deployment, and the browser
|
||||
// simply offers no choice.
|
||||
async list(request) {
|
||||
const presets = ctx.get('agentPresets')
|
||||
if (presets === undefined) return ok(request, { presets: [] })
|
||||
const defaultId = presets.defaultId
|
||||
return ok(request, {
|
||||
presets: (await presets.list()).map(preset => ({
|
||||
id: preset.id,
|
||||
trust: preset.trust,
|
||||
isDefault: preset.id === defaultId,
|
||||
})),
|
||||
})
|
||||
},
|
||||
},
|
||||
|
||||
skills: {
|
||||
// Skill lookup never touches the Agent registry: the session address
|
||||
// resolves to a canonical cwd from the host-resident session header, so
|
||||
|
||||
Reference in New Issue
Block a user