feat(tess): add generic interaction CLI (#731)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/publish Pipeline was successful

This commit was merged in pull request #731.
This commit is contained in:
2026-07-13 05:52:41 +00:00
parent 99a2d0fc9d
commit 8246ee0137
8 changed files with 646 additions and 2 deletions

View File

@@ -361,6 +361,138 @@ export async function deleteMission(
}
}
// ── Authenticated interaction runtime endpoints ──
export interface InteractionRequest {
agentName: string;
correlationId?: string;
}
function interactionHeaders(sessionCookie: string, gatewayUrl: string, correlationId?: string) {
return {
...jsonHeaders(sessionCookie, gatewayUrl),
...(correlationId ? { 'X-Correlation-Id': correlationId } : {}),
};
}
function interactionPath(agentName: string, suffix: string): string {
return `/api/interaction/${encodeURIComponent(agentName)}${suffix}`;
}
export async function fetchInteractionSessions(
gatewayUrl: string,
sessionCookie: string,
request: InteractionRequest & { providerId: string },
): Promise<unknown[]> {
const params = new URLSearchParams({ provider: request.providerId });
const res = await fetch(
`${gatewayUrl}${interactionPath(request.agentName, `/sessions?${params}`)}`,
{
headers: interactionHeaders(sessionCookie, gatewayUrl, request.correlationId),
},
);
return handleResponse<unknown[]>(res, 'Failed to list interaction sessions');
}
export async function fetchInteractionTree(
gatewayUrl: string,
sessionCookie: string,
request: InteractionRequest & { providerId: string },
): Promise<unknown[]> {
const params = new URLSearchParams({ provider: request.providerId });
const res = await fetch(`${gatewayUrl}${interactionPath(request.agentName, `/tree?${params}`)}`, {
headers: interactionHeaders(sessionCookie, gatewayUrl, request.correlationId),
});
return handleResponse<unknown[]>(res, 'Failed to get interaction session tree');
}
export async function attachInteractionSession(
gatewayUrl: string,
sessionCookie: string,
request: InteractionRequest & { sessionId: string; mode?: 'read' | 'control' },
): Promise<unknown> {
const res = await fetch(
`${gatewayUrl}${interactionPath(request.agentName, `/sessions/${encodeURIComponent(request.sessionId)}/attach`)}`,
{
method: 'POST',
headers: interactionHeaders(sessionCookie, gatewayUrl, request.correlationId),
body: JSON.stringify({ mode: request.mode ?? 'read' }),
},
);
return handleResponse<unknown>(res, 'Failed to attach interaction session');
}
export async function sendInteractionMessage(
gatewayUrl: string,
sessionCookie: string,
request: InteractionRequest & { sessionId: string; content: string; idempotencyKey: string },
): Promise<{ status: string; sessionId: string }> {
const res = await fetch(
`${gatewayUrl}${interactionPath(request.agentName, `/sessions/${encodeURIComponent(request.sessionId)}/send`)}`,
{
method: 'POST',
headers: interactionHeaders(sessionCookie, gatewayUrl, request.correlationId),
body: JSON.stringify({ content: request.content, idempotencyKey: request.idempotencyKey }),
},
);
return handleResponse<{ status: string; sessionId: string }>(
res,
'Failed to send interaction message',
);
}
export async function stopInteractionSession(
gatewayUrl: string,
sessionCookie: string,
request: InteractionRequest & { sessionId: string; approvalRef: string },
): Promise<{ status: string; sessionId: string }> {
const res = await fetch(
`${gatewayUrl}${interactionPath(request.agentName, `/sessions/${encodeURIComponent(request.sessionId)}/stop`)}`,
{
method: 'POST',
headers: interactionHeaders(sessionCookie, gatewayUrl, request.correlationId),
body: JSON.stringify({ approvalRef: request.approvalRef }),
},
);
return handleResponse<{ status: string; sessionId: string }>(
res,
'Failed to stop interaction session',
);
}
export async function recoverInteractionSession(
gatewayUrl: string,
sessionCookie: string,
request: InteractionRequest & { sessionId: string },
): Promise<{ status: string; sessionId: string }> {
const res = await fetch(
`${gatewayUrl}${interactionPath(request.agentName, `/sessions/${encodeURIComponent(request.sessionId)}/recover`)}`,
{
method: 'POST',
headers: interactionHeaders(sessionCookie, gatewayUrl, request.correlationId),
},
);
return handleResponse<{ status: string; sessionId: string }>(
res,
'Failed to recover interaction session',
);
}
export async function fetchInteractionStatus(
gatewayUrl: string,
sessionCookie: string,
): Promise<unknown> {
const res = await fetch(`${gatewayUrl}/api/providers/status`, {
headers: headers(sessionCookie, gatewayUrl),
});
return handleResponse<unknown>(res, 'Failed to get effective interaction policy');
}
export async function fetchInteractionHealth(gatewayUrl: string): Promise<unknown> {
const res = await fetch(`${gatewayUrl}/health/ready`);
return handleResponse<unknown>(res, 'Failed to get interaction readiness');
}
// ── Conversation Message types ──
export interface ConversationMessage {