Merge branch 'stack/agent-profiles-1-seam' into stack/agent-profiles-3-wire
Rewires this layer onto the standing-mount model: - serviceForAgent roots its search at the agent's standing mount (parent scope key → live mount fiber) — the composition no longer lives under the agent's own fiber, and two agents on one preset now address ONE instance, which the sharing test asserts instead of distinctness. - viewFor/historyPage take a registry view SCOPE. A live agent is that scope; a cold read uses the recorded preset's standing key via standingKeyFor — composing plugins but starting no agent, session, or turn. A header without a preset (a pre-roster log) renders through the DEFAULT preset's standing layer; an unusable preset degrades the read to generic cards, never fails it. This turns produced-files and chat-scroll green structurally, with the token counts untouched (no resume, so the projections fold stays detached). - The detached projections baseline now includes every standing unit's key at its empty fold (todos: null): the standing mount registers units deterministically, which is what makes the client's "omitted key = capability absence → clear" rule safe again. seeded-history's contract test asserts the new shape. - The standard preset's realm preamble no longer claims a shared label pools instances — provide() throws on the second registration under one realm symbol; labels join REALMS.
This commit is contained in:
@@ -94,12 +94,16 @@ export const SERVICE_API: readonly ServiceApiEntry[] = [
|
||||
},
|
||||
{
|
||||
signature: 'async mount(agentCtx: Context, id?: string): Promise<AgentPreset>',
|
||||
jsDoc: '/**\n * Compose one agent from a preset, installing it under that agent alone.\n *\n * Call from the agent factory\'s `setup(agentCtx)`; a rejection there rolls\n * the agent creation back, so a broken preset never yields a half-composed\n * session.\n * @param agentCtx - the agent\'s scope context.\n * @param id - the preset id, or `undefined` for {@link defaultId}.\n * @returns the preset that was mounted, for the caller to record.\n * @throws when the preset is unknown or its composition is unusable.\n */',
|
||||
jsDoc: '/**\n * Compose one agent from a preset: ensure the preset\'s standing mount, then\n * parent the agent\'s scope key to it so the mount\'s registrations and\n * listeners cover this agent.\n *\n * Call from the agent factory\'s `setup(agentCtx)`; a rejection there rolls\n * the agent creation back, so a broken preset never yields a half-composed\n * session.\n * @param agentCtx - the agent\'s scope context.\n * @param id - the preset id, or `undefined` for {@link defaultId}.\n * @returns the preset that was composed, for the caller to record.\n * @throws when the preset is unknown or its composition is unusable.\n */',
|
||||
},
|
||||
{
|
||||
signature: 'serviceFor<K extends string & keyof Context>(agent: { ctx: Context }, name: K): Context[K] | undefined',
|
||||
jsDoc: '/**\n * One agent\'s instance of a service its preset mounted.\n *\n * A preset publishes services behind `isolate` realms, which are invisible\n * outside the group that declares them — including to the host. This is how a\n * caller holding the agent reads one anyway: a request that is ABOUT a\n * session but arrives from outside it, which is every browser RPC.\n *\n * Read addressing only. A host row that `inject`s a service cannot use this,\n * because injection resolves before any session exists and has no agent to\n * key by; such a service belongs on the host plane instead.\n * @param agent - the agent whose composition to look inside.\n * @param name - the service name as the preset\'s rows resolve it.\n * @returns the agent\'s instance, or undefined when its preset mounts none.\n */',
|
||||
},
|
||||
{
|
||||
signature: 'async standingKeyFor(id?: string): Promise<ScopeKey>',
|
||||
jsDoc: '/**\n * The standing scope key of one preset, for a host reader with no agent.\n *\n * A cold transcript read resolves tool presenters against the composition\n * the session recorded, and the standing mount makes that possible without\n * resuming anything: ensuring the mount composes plugins but starts no\n * agent, no session, and no turn.\n * @param id - the preset id, or `undefined` for {@link defaultId}.\n * @returns the standing scope key readers pass as a registry view scope.\n * @throws when the preset is unknown or its composition is unusable.\n */',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user