(sessionId: string, afterId: string | null = null, opts?: {
skipMetadata?: boolean;
})
| 731 | * per-call GET /v1/sessions/{id} when branch/status aren't needed. |
| 732 | */ |
| 733 | export async function pollRemoteSessionEvents(sessionId: string, afterId: string | null = null, opts?: { |
| 734 | skipMetadata?: boolean; |
| 735 | }): Promise<PollRemoteSessionResponse> { |
| 736 | let accessToken: string |
| 737 | let orgUUID: string |
| 738 | try { |
| 739 | const capability = await resolveManagedRemoteCapability() |
| 740 | accessToken = capability.accessToken |
| 741 | orgUUID = capability.orgUUID |
| 742 | } catch (error) { |
| 743 | const err = toError(error) |
| 744 | if (err.message === MANAGED_REMOTE_AUTH_REQUIRED_MESSAGE) { |
| 745 | throw new Error('No access token for polling') |
| 746 | } |
| 747 | if (err.message === 'Unable to get organization UUID') { |
| 748 | throw new Error('No org UUID for polling') |
| 749 | } |
| 750 | throw err |
| 751 | } |
| 752 | const headers = { |
| 753 | ...getOAuthHeaders(accessToken), |
| 754 | 'anthropic-beta': 'ccr-byoc-2025-07-29', |
| 755 | 'x-organization-uuid': orgUUID |
| 756 | }; |
| 757 | const eventsUrl = buildNoumenaPlatformUrl(`/v1/sessions/${sessionId}/events`); |
| 758 | type EventsResponse = { |
| 759 | data: unknown[]; |
| 760 | has_more: boolean; |
| 761 | first_id: string | null; |
| 762 | last_id: string | null; |
| 763 | }; |
| 764 | |
| 765 | // Cap is a safety valve against stuck cursors; steady-state is 0–1 pages. |
| 766 | const MAX_EVENT_PAGES = 50; |
| 767 | const sdkMessages: SDKMessage[] = []; |
| 768 | let cursor = afterId; |
| 769 | for (let page = 0; page < MAX_EVENT_PAGES; page++) { |
| 770 | const eventsResponse = await axios.get(eventsUrl, { |
| 771 | headers, |
| 772 | params: cursor ? { |
| 773 | after_id: cursor |
| 774 | } : undefined, |
| 775 | timeout: 30000 |
| 776 | }); |
| 777 | if (eventsResponse.status !== 200) { |
| 778 | throw new Error(`Failed to fetch session events: ${eventsResponse.statusText}`); |
| 779 | } |
| 780 | const eventsData: EventsResponse = eventsResponse.data; |
| 781 | if (!eventsData?.data || !Array.isArray(eventsData.data)) { |
| 782 | throw new Error('Invalid events response'); |
| 783 | } |
| 784 | for (const event of eventsData.data) { |
| 785 | if (event && typeof event === 'object' && 'type' in event) { |
| 786 | if (event.type === 'env_manager_log' || event.type === 'control_response') { |
| 787 | continue; |
| 788 | } |
| 789 | if ('session_id' in event) { |
| 790 | sdkMessages.push(event as SDKMessage); |
no test coverage detected