@hyperdrive.bot/fleet-server 0.3.126 → 0.3.128
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/server/server/session.js +97 -2
- package/dist/server/web-ui/_expo/static/js/web/{index-98fb0396dda5c1146d743e92ada27017.js → index-eff6fb3c2913cae6f04c753f1f953e8e.js} +12 -12
- package/dist/server/web-ui/_expo/static/js/web/index-eff6fb3c2913cae6f04c753f1f953e8e.js.br +0 -0
- package/dist/server/web-ui/_expo/static/js/web/{index-98fb0396dda5c1146d743e92ada27017.js.gz → index-eff6fb3c2913cae6f04c753f1f953e8e.js.gz} +0 -0
- package/dist/server/web-ui/_expo/static/js/web/{index-98fb0396dda5c1146d743e92ada27017.js.map.br → index-eff6fb3c2913cae6f04c753f1f953e8e.js.map.br} +0 -0
- package/dist/server/web-ui/_expo/static/js/web/{index-98fb0396dda5c1146d743e92ada27017.js.map.gz → index-eff6fb3c2913cae6f04c753f1f953e8e.js.map.gz} +0 -0
- package/dist/server/web-ui/index.html +1 -1
- package/dist/server/web-ui/index.html.br +0 -0
- package/dist/server/web-ui/index.html.gz +0 -0
- package/package.json +6 -6
- package/dist/server/web-ui/_expo/static/js/web/index-98fb0396dda5c1146d743e92ada27017.js.br +0 -0
|
@@ -1146,7 +1146,33 @@ export class Session {
|
|
|
1146
1146
|
const record = await this.agentStorage.get(agentId);
|
|
1147
1147
|
if (!record)
|
|
1148
1148
|
return;
|
|
1149
|
-
|
|
1149
|
+
/*
|
|
1150
|
+
* The LIVE payload when the agent is live.
|
|
1151
|
+
*
|
|
1152
|
+
* This always built the stored one, and `buildStoredAgentPayload`
|
|
1153
|
+
* hardcodes `pendingPermissions: []`, `availableModes: []` and the
|
|
1154
|
+
* default capabilities, because a stored record genuinely has none of
|
|
1155
|
+
* those. Broadcasting that for a LIVE agent is a lie the app believes:
|
|
1156
|
+
* `writeStoredMetadata` stamps a strictly newer `updatedAt`, so the
|
|
1157
|
+
* client's staleness guard waves it through, and
|
|
1158
|
+
* `applyAuthoritativeAgentSnapshot` then deletes the agent's permission
|
|
1159
|
+
* keys because the incoming list is empty.
|
|
1160
|
+
*
|
|
1161
|
+
* The user-visible cost was specific and bad: a permission-blocked
|
|
1162
|
+
* session ranks FIRST in the triage ring, and snoozing it - an ordinary
|
|
1163
|
+
* move - erased the approval prompt app-wide, dropped the agent out of
|
|
1164
|
+
* `needs_input`, and downgraded its mode list. The daemon stays blocked
|
|
1165
|
+
* waiting on that approval and a blocked agent emits nothing further, so
|
|
1166
|
+
* only a reconnect brought it back.
|
|
1167
|
+
*
|
|
1168
|
+
* Introduced by the round-35 broadcast fix, which is the shape this log
|
|
1169
|
+
* keeps naming: a fix verified against the case that motivated it (an
|
|
1170
|
+
* idle session) and not the space around it (a live one).
|
|
1171
|
+
*/
|
|
1172
|
+
const liveAgent = this.agentManager.getAgent(agentId);
|
|
1173
|
+
const agent = liveAgent
|
|
1174
|
+
? await this.buildAgentPayload(liveAgent)
|
|
1175
|
+
: this.buildStoredAgentPayload(record);
|
|
1150
1176
|
// `workspaceId` is optional on the record: an agent outside a workspace has
|
|
1151
1177
|
// no project placement, and the payload's `project` is optional too.
|
|
1152
1178
|
const project = record.workspaceId
|
|
@@ -2866,10 +2892,60 @@ export class Session {
|
|
|
2866
2892
|
await this.agentManager.updateAgentMetadata(winnerId, {
|
|
2867
2893
|
digest: { ...winnerDigest, links: [...(winnerDigest.links ?? []), ...newLinks] },
|
|
2868
2894
|
});
|
|
2895
|
+
/*
|
|
2896
|
+
* `archiveAgentCommand`, like every other archive caller in the repo.
|
|
2897
|
+
*
|
|
2898
|
+
* This called `agentManager.archiveAgent` directly, whose first statement
|
|
2899
|
+
* is `requireAgent`, which THROWS `Unknown agent '<id>'` when the agent is
|
|
2900
|
+
* not in memory. Most of a triage backlog is exactly that, and consolidate
|
|
2901
|
+
* is the verb the refused-snooze copy points the user at: the hold
|
|
2902
|
+
* completed, the sheet showed a raw uuid in an error, and nothing was
|
|
2903
|
+
* archived.
|
|
2904
|
+
*
|
|
2905
|
+
* Worse on a mixed set: the links above were already written, on the
|
|
2906
|
+
* winner AND on every source, so the live sources got archived, the
|
|
2907
|
+
* stored-only ones did not, and the response said `accepted: false`. That
|
|
2908
|
+
* is the half-consolidated fleet the single-call design exists to
|
|
2909
|
+
* prevent, and a retry appends the links again because they are not
|
|
2910
|
+
* deduped.
|
|
2911
|
+
*
|
|
2912
|
+
* The command branches on `getAgent()` and falls back to
|
|
2913
|
+
* `archiveStoredAgent`, which is the same fallback `archiveAgentForClose`
|
|
2914
|
+
* uses a few hundred lines up.
|
|
2915
|
+
*/
|
|
2916
|
+
const archivedAtById = new Map();
|
|
2869
2917
|
for (const sourceId of sources) {
|
|
2870
|
-
await
|
|
2918
|
+
const { archivedAt } = await archiveAgentCommand({
|
|
2919
|
+
agentManager: this.agentManager,
|
|
2920
|
+
agentStorage: this.agentStorage,
|
|
2921
|
+
logger: this.sessionLogger,
|
|
2922
|
+
}, sourceId);
|
|
2923
|
+
archivedAtById.set(sourceId, archivedAt);
|
|
2871
2924
|
archivedIds.push(sourceId);
|
|
2872
2925
|
}
|
|
2926
|
+
/*
|
|
2927
|
+
* Tell every client the sources are archived.
|
|
2928
|
+
*
|
|
2929
|
+
* This emitted only `agent.consolidate.response`, which is point to
|
|
2930
|
+
* point: nothing set `archivedAt` in the app's store, so
|
|
2931
|
+
* `selectFeedCandidates`' archived clause could not drop them and the N
|
|
2932
|
+
* sources came back in the ring - the exact outcome
|
|
2933
|
+
* `reels-feed-source.ts` says it closed. `handleArchiveAgentRequest`
|
|
2934
|
+
* emits `agent_archived` for the single-session case; consolidate is the
|
|
2935
|
+
* batch of the same operation and owes the same event.
|
|
2936
|
+
*/
|
|
2937
|
+
for (const sourceId of archivedIds) {
|
|
2938
|
+
const archivedAt = archivedAtById.get(sourceId);
|
|
2939
|
+
if (!archivedAt)
|
|
2940
|
+
continue;
|
|
2941
|
+
// `requestId` is the consolidate request's: the archive is part of it,
|
|
2942
|
+
// and the schema requires the correlation id.
|
|
2943
|
+
this.emit({
|
|
2944
|
+
type: "agent_archived",
|
|
2945
|
+
payload: { agentId: sourceId, archivedAt, requestId },
|
|
2946
|
+
});
|
|
2947
|
+
}
|
|
2948
|
+
await this.emitAgentUpsertFromStorage(winnerId);
|
|
2873
2949
|
this.emit({
|
|
2874
2950
|
type: "agent.consolidate.response",
|
|
2875
2951
|
payload: { requestId, winnerId, accepted: true, archivedIds, error: null },
|
|
@@ -3057,6 +3133,25 @@ export class Session {
|
|
|
3057
3133
|
});
|
|
3058
3134
|
return;
|
|
3059
3135
|
}
|
|
3136
|
+
/*
|
|
3137
|
+
* Broadcast it, exactly like the snooze and decision handlers.
|
|
3138
|
+
*
|
|
3139
|
+
* `emitAgentUpsertFromStorage`'s own docblock names a kanban move on an
|
|
3140
|
+
* idle session as one of the two symptoms it exists to fix, and then only
|
|
3141
|
+
* the decision half was wired. This handler is the SOLE path for
|
|
3142
|
+
* `setKanban` and `setTags`, and it emitted a point-to-point response and
|
|
3143
|
+
* nothing else. For an agent the daemon has not loaded,
|
|
3144
|
+
* `updateAgentMetadata` falls through to `writeStoredMetadata`, which
|
|
3145
|
+
* emits nothing at all.
|
|
3146
|
+
*
|
|
3147
|
+
* What that cost, beyond the stale chip: reels reads the WIP occupancy
|
|
3148
|
+
* from the same store labels, so a column at its limit kept counting the
|
|
3149
|
+
* cards it had before the moves, and the gate that was added to refuse a
|
|
3150
|
+
* fourth card went blind for the rest of the sitting. Nothing recovers
|
|
3151
|
+
* within a session: the authoritative revalidation fires on connection
|
|
3152
|
+
* events, not on a timer.
|
|
3153
|
+
*/
|
|
3154
|
+
await this.emitAgentUpsertFromStorage(agentId);
|
|
3060
3155
|
this.emit({
|
|
3061
3156
|
type: "update_agent_response",
|
|
3062
3157
|
payload: { requestId, agentId, accepted: true, error: null },
|