a spawned session says who started it
The other half of making a spawned agent visible. The commander's pane now lists its children; opening one gave no way back — no link to the conversation that owns it, and nothing to tell it apart from a chat somebody had started themselves and forgotten. `parentCommanderOf` is the row `ingestSpawnedChildren` already writes, read from the other end. So this needed no table and no write path: a commander's children were recorded because deleting one has to take them with it, and that record answers "who is my parent" for free. Nothing had asked. `GET /chat/sessions/:id` carries `spawnedBy`, and the chat panel renders one line above the transcript linking back to the commander. Null for almost every session, which is the normal case rather than a miss — a chat somebody opened has no parent — so the bar renders nothing at all rather than saying so. Never fatal: a session must open when this lookup will not. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -15,6 +15,7 @@ export {
|
||||
disarmCommandHqWatcher,
|
||||
recordCommandHqTurn,
|
||||
ingestSpawnedChildren,
|
||||
parentCommanderOf,
|
||||
recordSpawnedOutcome,
|
||||
getCommandHqCostSummary,
|
||||
listCommandHqTurns,
|
||||
|
||||
@@ -475,3 +475,44 @@ export async function recordSpawnedOutcome(
|
||||
and(eq(commandHqSpawned.sessionRowId, sessionRowId), eq(commandHqSpawned.spawnedSessionId, spawnedSessionId)),
|
||||
);
|
||||
}
|
||||
|
||||
export type SpawnParent = {
|
||||
/** The commander's transcript id — what `/command-hq/<id>` opens. */
|
||||
sessionId: string;
|
||||
/** What the owner called it, or null for a commander filed before the column existed. */
|
||||
name: string | null;
|
||||
firstSeenAt: string;
|
||||
finishedAt: string | null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Which commander spawned this session, if any.
|
||||
*
|
||||
* The same row `ingestSpawnedChildren` writes, read from the other end — so this needed no new table and no
|
||||
* new write path. A commander's children were already recorded because deleting one has to take them with
|
||||
* it; that record answers "who is my parent" for free, and nothing was asking.
|
||||
*
|
||||
* Null for almost every session, and that is the normal case rather than a miss: a chat somebody opened
|
||||
* themselves has no parent, and a session spawned by anything other than a commander has no row here. The
|
||||
* caller must treat absence as "not spawned", never as "lookup failed".
|
||||
*/
|
||||
export async function parentCommanderOf(spawnedSessionId: string): Promise<SpawnParent | null> {
|
||||
const [row] = await db
|
||||
.select({
|
||||
sessionId: commandHqSessions.sessionId,
|
||||
name: commandHqSessions.name,
|
||||
firstSeenAt: commandHqSpawned.firstSeenAt,
|
||||
finishedAt: commandHqSpawned.finishedAt,
|
||||
})
|
||||
.from(commandHqSpawned)
|
||||
.innerJoin(commandHqSessions, eq(commandHqSessions.id, commandHqSpawned.sessionRowId))
|
||||
.where(eq(commandHqSpawned.spawnedSessionId, spawnedSessionId))
|
||||
.limit(1);
|
||||
if (!row) return null;
|
||||
return {
|
||||
sessionId: row.sessionId,
|
||||
name: row.name,
|
||||
firstSeenAt: row.firstSeenAt.toISOString(),
|
||||
finishedAt: row.finishedAt ? row.finishedAt.toISOString() : null,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user