Files
paseo/packages/protocol/src/agent-labels.ts
T
Mohamed Boudra 8342a95367 Create, prompt, and monitor agents across connected hosts (#7507)
* feat(hosts): delegate agents across connected hosts

Resolve MCP host operations through in-process commands for self and the existing routed client transport for other destinations. Keep ordinary parent labels, app sessions and idle finish notifications.

* test(app): normalize subagent fixtures through snapshots

* docs(protocol): clarify same-host parent labels

* fix(hosts): resolve subagents through destination sessions

A child address identifies its destination regardless of the connection used. Reuse the existing host candidate selection for discovered routes and direct connections, and keep navigation and row actions independent of the parent transport.

* fix(hosts): keep routed destinations distinct during discovery

A routed candidate names only the origin daemon. Match it within the named destination profile so two destinations discovered through the same origin retain separate identities and connections, including existing saved routes.

* feat(hosts): prompt and query agents on selected hosts

Extend the existing MCP host operation boundary with prompt, status, activity and list operations. Local calls retain their handlers and notification owner; selected destinations use ordinary client RPCs and the existing idle finish wait.
2026-10-21 10:33:48 +02:00

54 lines
1.8 KiB
TypeScript

import type { AgentAddress } from "./addresses.js";
export const PARENT_SERVER_ID_LABEL = "paseo.parent-server-id";
export const PARENT_AGENT_ID_LABEL = "paseo.parent-agent-id";
const OPEN_AGENT_TAB_LABEL_PREFIX = "paseo.open-agent-tab.";
export function getOpenAgentTabLabel(clientId: string): string {
return `${OPEN_AGENT_TAB_LABEL_PREFIX}${clientId}`;
}
export function isOpenAgentTabLabel(label: string): boolean {
return label.startsWith(OPEN_AGENT_TAB_LABEL_PREFIX);
}
export interface AgentLabelSource {
labels?: Record<string, unknown> | null;
}
export function getParentAgentIdFromLabels(labels: Record<string, unknown> | null | undefined) {
const parentAgentId = labels?.[PARENT_AGENT_ID_LABEL];
return typeof parentAgentId === "string" && parentAgentId.trim().length > 0
? parentAgentId.trim()
: null;
}
export function isDelegatedAgent(agent: AgentLabelSource): boolean {
return getParentAgentIdFromLabels(agent.labels) !== null;
}
export function hasOpenAgentTab(labels: Record<string, unknown> | null | undefined): boolean {
return Object.entries(labels ?? {}).some(
([label, value]) => isOpenAgentTabLabel(label) && value === "true",
);
}
// Absent parent server label means the same host.
export function getParentAddressFromLabels(
labels: Record<string, unknown> | null | undefined,
serverId: string,
): AgentAddress | null {
const agentId = getParentAgentIdFromLabels(labels);
if (!agentId) return null;
const parentServerId = labels?.[PARENT_SERVER_ID_LABEL];
return {
serverId:
typeof parentServerId === "string" && parentServerId.trim()
? parentServerId.trim()
: serverId,
agentId,
};
}
export function parentAddressLabels(parent: AgentAddress): Record<string, string> {
return { [PARENT_AGENT_ID_LABEL]: parent.agentId, [PARENT_SERVER_ID_LABEL]: parent.serverId };
}