mirror of
https://github.com/getpaseo/paseo.git
synced 2026-07-29 12:01:31 +00:00
feat(codex): archive native Codex thread when archiving agent (#827)
When a Codex-backed agent is archived from Paseo, call Codex's thread/archive API so the session is also marked archived in the Codex app. This keeps both UIs in sync. - Add optional archiveNativeSession() to AgentClient interface - Implement for Codex provider via thread/archive JSON-RPC call - Call best-effort in both archiveAgent() and archiveSnapshot() paths - Failures are logged as warnings and do not block the archive flow Closes #822
This commit is contained in:
@@ -975,6 +975,9 @@ export class AgentManager {
|
||||
attentionReason: null,
|
||||
attentionTimestamp: null,
|
||||
});
|
||||
|
||||
await this.archiveNativeSessionBestEffort(agent.provider, stored.persistence);
|
||||
|
||||
this.notifyAgentState(agentId);
|
||||
await this.closeAgent(agentId);
|
||||
|
||||
@@ -1118,6 +1121,9 @@ export class AgentManager {
|
||||
attentionTimestamp: null,
|
||||
};
|
||||
await registry.upsert(nextRecord);
|
||||
|
||||
await this.archiveNativeSessionBestEffort(record.provider, record.persistence);
|
||||
|
||||
return nextRecord;
|
||||
}
|
||||
|
||||
@@ -3136,6 +3142,23 @@ export class AgentManager {
|
||||
return client;
|
||||
}
|
||||
|
||||
async archiveNativeSessionBestEffort(
|
||||
provider: AgentProvider,
|
||||
persistence: AgentPersistenceHandle | null | undefined,
|
||||
): Promise<void> {
|
||||
if (!persistence) return;
|
||||
const client = this.clients.get(provider);
|
||||
if (!client?.archiveNativeSession) return;
|
||||
try {
|
||||
await client.archiveNativeSession(persistence);
|
||||
} catch (error) {
|
||||
this.logger.warn(
|
||||
{ error, provider, sessionId: persistence.sessionId },
|
||||
"Failed to archive native session (best-effort)",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private requireAgent(id: string): LiveManagedAgent {
|
||||
const normalizedId = validateAgentId(id, "requireAgent");
|
||||
const agent = this.agents.get(normalizedId);
|
||||
|
||||
@@ -558,4 +558,9 @@ export interface AgentClient {
|
||||
*/
|
||||
isAvailable(): Promise<boolean>;
|
||||
getDiagnostic?(): Promise<{ diagnostic: string }>;
|
||||
/**
|
||||
* Archive a persisted session in the native provider (best-effort).
|
||||
* Called when Paseo archives an agent so the provider's own UI reflects the same state.
|
||||
*/
|
||||
archiveNativeSession?(handle: AgentPersistenceHandle): Promise<void>;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import type {
|
||||
AgentMode,
|
||||
AgentModelDefinition,
|
||||
McpServerConfig,
|
||||
AgentPersistenceHandle,
|
||||
AgentPermissionRequest,
|
||||
AgentPermissionResponse,
|
||||
AgentPermissionResult,
|
||||
@@ -4904,6 +4905,22 @@ export class CodexAppServerAgentClient implements AgentClient {
|
||||
}
|
||||
}
|
||||
|
||||
async archiveNativeSession(handle: AgentPersistenceHandle): Promise<void> {
|
||||
const threadId = handle.nativeHandle ?? handle.sessionId;
|
||||
if (!threadId) return;
|
||||
|
||||
const child = await this.spawnAppServer();
|
||||
const client = new CodexAppServerClient(child, this.logger);
|
||||
|
||||
try {
|
||||
await client.request("initialize", buildCodexAppServerInitializeParams());
|
||||
client.notify("initialized", {});
|
||||
await client.request("thread/archive", { threadId });
|
||||
} finally {
|
||||
await client.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
async isAvailable(): Promise<boolean> {
|
||||
const command = this.runtimeSettings?.command;
|
||||
if (command?.mode === "replace") {
|
||||
|
||||
Reference in New Issue
Block a user