@agent-native/core 0.84.18 → 0.84.21
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/corpus/README.md +1 -1
- package/corpus/core/CHANGELOG.md +21 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/a2a/caller-auth.ts +37 -8
- package/corpus/core/src/a2a/client.ts +178 -67
- package/corpus/core/src/agent/production-agent.ts +19 -3
- package/corpus/core/src/agent/run-store.ts +180 -13
- package/corpus/core/src/agent/types.ts +1 -1
- package/corpus/core/src/cli/pr-visual-recap-workflow.ts +1 -1
- package/corpus/core/src/cli/recap.ts +43 -34
- package/corpus/core/src/client/AssistantChat.tsx +49 -0
- package/corpus/core/src/client/PoweredByBadge.tsx +70 -17
- package/corpus/core/src/client/active-run-state.ts +30 -0
- package/corpus/core/src/client/agent-chat-adapter.ts +5 -1
- package/corpus/core/src/client/extensions/EmbeddedExtension.tsx +41 -3
- package/corpus/core/src/client/extensions/ExtensionViewer.tsx +133 -0
- package/corpus/core/src/client/extensions/ExtensionsSidebarSection.tsx +2 -2
- package/corpus/core/src/client/i18n.tsx +10 -5
- package/corpus/core/src/client/sse-event-processor.ts +147 -5
- package/corpus/core/src/extensions/html-shell.ts +17 -3
- package/corpus/core/src/extensions/theme.ts +39 -0
- package/corpus/core/src/file-upload/builder.ts +35 -14
- package/corpus/core/src/file-upload/types.ts +3 -0
- package/corpus/core/src/integrations/a2a-continuation-processor.ts +49 -24
- package/corpus/core/src/mcp/builtin-tools.ts +3 -0
- package/corpus/core/src/mcp/org-directory.ts +66 -20
- package/corpus/core/src/scripts/call-agent.ts +7 -2
- package/corpus/templates/analytics/actions/provider-api-request.ts +8 -1
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +2 -1
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +91 -33
- package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +161 -12
- package/corpus/templates/analytics/changelog/2026-07-01-session-replays-load-large-production-recordings-from-scoped.md +6 -0
- package/corpus/templates/calendar/app/pages/BookingPage.tsx +14 -8
- package/corpus/templates/calendar/changelog/2026-07-01-meeting-invite-pages-have-cleaner-branding-a-black-dark-mo.md +6 -0
- package/corpus/templates/clips/actions/create-recording.ts +7 -2
- package/corpus/templates/clips/actions/finalize-recording.ts +11 -0
- package/corpus/templates/clips/actions/get-recording-player-data.ts +4 -2
- package/corpus/templates/clips/actions/import-loom-recording.ts +1 -0
- package/corpus/templates/clips/actions/lib/loom-video.ts +16 -0
- package/corpus/templates/clips/app/components/player/scrubber.tsx +2 -2
- package/corpus/templates/clips/app/components/recorder/countdown-overlay.tsx +4 -3
- package/corpus/templates/clips/app/components/recorder/pre-record-panel.tsx +39 -12
- package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +65 -1
- package/corpus/templates/clips/app/components/recorder/recording-toolbar.tsx +1 -22
- package/corpus/templates/clips/app/routes/record.tsx +48 -8
- package/corpus/templates/clips/changelog/2026-07-01-chrome-recording-uploads-now-serialize-chunks-to-avoid-resum.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-01-clip-uploads-and-loom-imports-finish-sooner-by-skipping-the-.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-01-clip-uploads-and-playback-recover-more-reliably-from-storage.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-01-desktop-recording-avoids-unsupported-browser-tab-capture.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-01-embedded-player-progress-is-easier-to-see-on-dark-videos.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-01-loom-imports-show-clear-guidance-when-loom-does-not-provide-a-downloadable-video.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-01-preserve-in-flight-streaming-uploads-when-the-streaming-kill.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-01-recording-controls-are-cleaner-and-the-countdown-uses-shadow.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-01-recordings-now-recover-when-final-upload-status-gets-lost.md +6 -0
- package/corpus/templates/clips/chrome-extension/public/manifest.json +1 -1
- package/corpus/templates/clips/chrome-extension/src/finalize-recovery.ts +7 -224
- package/corpus/templates/clips/chrome-extension/src/offscreen.ts +94 -29
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +87 -5
- package/corpus/templates/clips/server/lib/streaming-upload-mode.ts +7 -0
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +14 -1
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/status.get.ts +4 -1
- package/corpus/templates/clips/server/routes/api/video/[recordingId].get.ts +96 -1
- package/corpus/templates/clips/shared/finalize-recovery.ts +242 -0
- package/corpus/templates/design/changelog/2026-07-01-design-recovers-sooner-when-an-agent-gets-stuck-preparing-a-.md +6 -0
- package/corpus/templates/plan/app/global.css +1 -1
- package/dist/a2a/caller-auth.d.ts +1 -0
- package/dist/a2a/caller-auth.d.ts.map +1 -1
- package/dist/a2a/caller-auth.js +34 -8
- package/dist/a2a/caller-auth.js.map +1 -1
- package/dist/a2a/client.d.ts +4 -0
- package/dist/a2a/client.d.ts.map +1 -1
- package/dist/a2a/client.js +148 -58
- package/dist/a2a/client.js.map +1 -1
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +19 -4
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-store.d.ts +19 -6
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +163 -13
- package/dist/agent/run-store.js.map +1 -1
- package/dist/agent/types.d.ts +1 -0
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/cli/pr-visual-recap-workflow.d.ts +1 -1
- package/dist/cli/pr-visual-recap-workflow.d.ts.map +1 -1
- package/dist/cli/pr-visual-recap-workflow.js +1 -1
- package/dist/cli/pr-visual-recap-workflow.js.map +1 -1
- package/dist/cli/recap.d.ts +3 -3
- package/dist/cli/recap.d.ts.map +1 -1
- package/dist/cli/recap.js +41 -34
- package/dist/cli/recap.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +2 -0
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +36 -2
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/PoweredByBadge.d.ts +9 -3
- package/dist/client/PoweredByBadge.d.ts.map +1 -1
- package/dist/client/PoweredByBadge.js +47 -15
- package/dist/client/PoweredByBadge.js.map +1 -1
- package/dist/client/active-run-state.d.ts +3 -0
- package/dist/client/active-run-state.d.ts.map +1 -1
- package/dist/client/active-run-state.js +24 -0
- package/dist/client/active-run-state.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +5 -1
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/extensions/EmbeddedExtension.d.ts.map +1 -1
- package/dist/client/extensions/EmbeddedExtension.js +32 -3
- package/dist/client/extensions/EmbeddedExtension.js.map +1 -1
- package/dist/client/extensions/ExtensionViewer.d.ts.map +1 -1
- package/dist/client/extensions/ExtensionViewer.js +59 -2
- package/dist/client/extensions/ExtensionViewer.js.map +1 -1
- package/dist/client/extensions/ExtensionsSidebarSection.js +2 -2
- package/dist/client/extensions/ExtensionsSidebarSection.js.map +1 -1
- package/dist/client/i18n.d.ts +1 -1
- package/dist/client/i18n.d.ts.map +1 -1
- package/dist/client/i18n.js +6 -2
- package/dist/client/i18n.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts +2 -0
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +121 -5
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/extensions/html-shell.d.ts.map +1 -1
- package/dist/extensions/html-shell.js +17 -3
- package/dist/extensions/html-shell.js.map +1 -1
- package/dist/extensions/theme.d.ts +9 -0
- package/dist/extensions/theme.d.ts.map +1 -1
- package/dist/extensions/theme.js +38 -0
- package/dist/extensions/theme.js.map +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +2 -2
- package/dist/file-upload/builder.d.ts.map +1 -1
- package/dist/file-upload/builder.js +22 -8
- package/dist/file-upload/builder.js.map +1 -1
- package/dist/file-upload/types.d.ts +5 -1
- package/dist/file-upload/types.d.ts.map +1 -1
- package/dist/file-upload/types.js.map +1 -1
- package/dist/integrations/a2a-continuation-processor.js +43 -18
- package/dist/integrations/a2a-continuation-processor.js.map +1 -1
- package/dist/mcp/builtin-tools.d.ts.map +1 -1
- package/dist/mcp/builtin-tools.js +3 -0
- package/dist/mcp/builtin-tools.js.map +1 -1
- package/dist/mcp/org-directory.d.ts.map +1 -1
- package/dist/mcp/org-directory.js +58 -20
- package/dist/mcp/org-directory.js.map +1 -1
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/observability/routes.d.ts +6 -6
- package/dist/progress/routes.d.ts +1 -1
- package/dist/resources/handlers.d.ts +3 -3
- package/dist/scripts/call-agent.d.ts.map +1 -1
- package/dist/scripts/call-agent.js +2 -2
- package/dist/scripts/call-agent.js.map +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
type FetchLike = (
|
|
2
|
+
input: RequestInfo | URL,
|
|
3
|
+
init?: RequestInit,
|
|
4
|
+
) => Promise<Response>;
|
|
5
|
+
|
|
6
|
+
export type RecoveredReadyRecording = {
|
|
7
|
+
ok: true;
|
|
8
|
+
finalized: true;
|
|
9
|
+
recoveredAfterFinalizeError: true;
|
|
10
|
+
id: string;
|
|
11
|
+
recordingId: string;
|
|
12
|
+
status: "ready";
|
|
13
|
+
videoUrl: string;
|
|
14
|
+
durationMs?: number;
|
|
15
|
+
width?: number;
|
|
16
|
+
height?: number;
|
|
17
|
+
hasAudio?: boolean;
|
|
18
|
+
hasCamera?: boolean;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
type ProbeResult =
|
|
22
|
+
| { ready: true; result: RecoveredReadyRecording }
|
|
23
|
+
| { ready: false; terminal: boolean; status?: string };
|
|
24
|
+
|
|
25
|
+
const DEFAULT_READY_RECOVERY_TIMEOUT_MS = 90_000;
|
|
26
|
+
const DEFAULT_READY_RECOVERY_INTERVAL_MS = 3_000;
|
|
27
|
+
const DEFAULT_READY_RECOVERY_FETCH_TIMEOUT_MS = 2_000;
|
|
28
|
+
|
|
29
|
+
function sleep(ms: number): Promise<void> {
|
|
30
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function absoluteUploadUrl(uploadUrl: string): URL {
|
|
34
|
+
if (/^[a-z][a-z0-9+.-]*:/i.test(uploadUrl)) return new URL(uploadUrl);
|
|
35
|
+
const origin =
|
|
36
|
+
typeof globalThis.location?.origin === "string"
|
|
37
|
+
? globalThis.location.origin
|
|
38
|
+
: "http://localhost";
|
|
39
|
+
return new URL(uploadUrl, origin);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function maybeRelativeUrl(url: URL, original: string): string {
|
|
43
|
+
if (/^[a-z][a-z0-9+.-]*:/i.test(original)) return url.toString();
|
|
44
|
+
return `${url.pathname}${url.search}${url.hash}`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function publicRecordingStatusUrl(
|
|
48
|
+
uploadUrl: string,
|
|
49
|
+
recordingId: string,
|
|
50
|
+
): string {
|
|
51
|
+
const url = absoluteUploadUrl(uploadUrl);
|
|
52
|
+
const match = url.pathname.match(/^(.*)\/api\/uploads\/[^/]+\/chunk$/);
|
|
53
|
+
const basePath = match?.[1] ?? "";
|
|
54
|
+
url.pathname = `${basePath}/api/public-recording`;
|
|
55
|
+
url.search = "";
|
|
56
|
+
url.searchParams.set("id", recordingId);
|
|
57
|
+
return maybeRelativeUrl(url, uploadUrl);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function authenticatedRecordingStatusUrl(
|
|
61
|
+
uploadUrl: string,
|
|
62
|
+
recordingId: string,
|
|
63
|
+
): string {
|
|
64
|
+
const url = absoluteUploadUrl(uploadUrl);
|
|
65
|
+
const match = url.pathname.match(/^(.*)\/api\/uploads\/[^/]+\/chunk$/);
|
|
66
|
+
const basePath = match?.[1] ?? "";
|
|
67
|
+
url.pathname = `${basePath}/api/uploads/${encodeURIComponent(
|
|
68
|
+
recordingId,
|
|
69
|
+
)}/status`;
|
|
70
|
+
url.search = "";
|
|
71
|
+
return maybeRelativeUrl(url, uploadUrl);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function optionalNumber(value: unknown): number | undefined {
|
|
75
|
+
return typeof value === "number" && Number.isFinite(value)
|
|
76
|
+
? value
|
|
77
|
+
: undefined;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function optionalBoolean(value: unknown): boolean | undefined {
|
|
81
|
+
return typeof value === "boolean" ? value : undefined;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function readyRecordingFromPublicPayload(
|
|
85
|
+
payload: unknown,
|
|
86
|
+
fallbackRecordingId: string,
|
|
87
|
+
): ProbeResult {
|
|
88
|
+
const root =
|
|
89
|
+
payload && typeof payload === "object"
|
|
90
|
+
? (payload as Record<string, unknown>)
|
|
91
|
+
: null;
|
|
92
|
+
const recording =
|
|
93
|
+
root?.recording && typeof root.recording === "object"
|
|
94
|
+
? (root.recording as Record<string, unknown>)
|
|
95
|
+
: null;
|
|
96
|
+
const status =
|
|
97
|
+
typeof recording?.status === "string" ? recording.status : undefined;
|
|
98
|
+
|
|
99
|
+
if (!recording) return { ready: false, terminal: false };
|
|
100
|
+
if (status === "failed") return { ready: false, terminal: true, status };
|
|
101
|
+
|
|
102
|
+
const videoUrl =
|
|
103
|
+
typeof recording.videoUrl === "string" ? recording.videoUrl : "";
|
|
104
|
+
if (status !== "ready" || !videoUrl) {
|
|
105
|
+
return { ready: false, terminal: false, status };
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const id =
|
|
109
|
+
typeof recording.id === "string" && recording.id
|
|
110
|
+
? recording.id
|
|
111
|
+
: fallbackRecordingId;
|
|
112
|
+
return {
|
|
113
|
+
ready: true,
|
|
114
|
+
result: {
|
|
115
|
+
ok: true,
|
|
116
|
+
finalized: true,
|
|
117
|
+
recoveredAfterFinalizeError: true,
|
|
118
|
+
id,
|
|
119
|
+
recordingId: id,
|
|
120
|
+
status: "ready",
|
|
121
|
+
videoUrl,
|
|
122
|
+
durationMs: optionalNumber(recording.durationMs),
|
|
123
|
+
width: optionalNumber(recording.width),
|
|
124
|
+
height: optionalNumber(recording.height),
|
|
125
|
+
hasAudio: optionalBoolean(recording.hasAudio),
|
|
126
|
+
hasCamera: optionalBoolean(recording.hasCamera),
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
async function fetchWithTimeout(
|
|
132
|
+
fetchImpl: FetchLike,
|
|
133
|
+
url: string,
|
|
134
|
+
init: RequestInit,
|
|
135
|
+
timeoutMs: number,
|
|
136
|
+
): Promise<Response> {
|
|
137
|
+
if (timeoutMs <= 0 || typeof AbortController === "undefined") {
|
|
138
|
+
return fetchImpl(url, init);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const controller = new AbortController();
|
|
142
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
143
|
+
try {
|
|
144
|
+
return await fetchImpl(url, { ...init, signal: controller.signal });
|
|
145
|
+
} finally {
|
|
146
|
+
clearTimeout(timer);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export async function waitForReadyRecordingAfterFinalizeError(args: {
|
|
151
|
+
uploadUrl: string;
|
|
152
|
+
recordingId: string;
|
|
153
|
+
authToken?: string | null;
|
|
154
|
+
preferAuthenticated?: boolean;
|
|
155
|
+
fetchImpl?: FetchLike;
|
|
156
|
+
sleepImpl?: (ms: number) => Promise<void>;
|
|
157
|
+
timeoutMs?: number;
|
|
158
|
+
intervalMs?: number;
|
|
159
|
+
fetchTimeoutMs?: number;
|
|
160
|
+
}): Promise<RecoveredReadyRecording | null> {
|
|
161
|
+
const fetchImpl = args.fetchImpl ?? fetch;
|
|
162
|
+
const sleepImpl = args.sleepImpl ?? sleep;
|
|
163
|
+
const timeoutMs = Math.max(
|
|
164
|
+
1,
|
|
165
|
+
args.timeoutMs ?? DEFAULT_READY_RECOVERY_TIMEOUT_MS,
|
|
166
|
+
);
|
|
167
|
+
const intervalMs = Math.max(
|
|
168
|
+
1,
|
|
169
|
+
args.intervalMs ?? DEFAULT_READY_RECOVERY_INTERVAL_MS,
|
|
170
|
+
);
|
|
171
|
+
const attempts = Math.max(1, Math.ceil(timeoutMs / intervalMs));
|
|
172
|
+
let url: string;
|
|
173
|
+
let authenticatedUrl: string | null = null;
|
|
174
|
+
try {
|
|
175
|
+
url = publicRecordingStatusUrl(args.uploadUrl, args.recordingId);
|
|
176
|
+
authenticatedUrl =
|
|
177
|
+
args.authToken || args.preferAuthenticated
|
|
178
|
+
? authenticatedRecordingStatusUrl(args.uploadUrl, args.recordingId)
|
|
179
|
+
: null;
|
|
180
|
+
} catch {
|
|
181
|
+
return null;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
for (let attempt = 0; attempt < attempts; attempt += 1) {
|
|
185
|
+
const urls = authenticatedUrl
|
|
186
|
+
? [
|
|
187
|
+
{ url: authenticatedUrl, authenticated: true },
|
|
188
|
+
{ url, authenticated: false },
|
|
189
|
+
]
|
|
190
|
+
: [{ url, authenticated: false }];
|
|
191
|
+
|
|
192
|
+
for (const endpoint of urls) {
|
|
193
|
+
const headers: Record<string, string> = {
|
|
194
|
+
Accept: "application/json",
|
|
195
|
+
"X-Agent-Native-Frontend": "1",
|
|
196
|
+
};
|
|
197
|
+
if (endpoint.authenticated && args.authToken) {
|
|
198
|
+
headers.Authorization = `Bearer ${args.authToken}`;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
try {
|
|
202
|
+
const response = await fetchWithTimeout(
|
|
203
|
+
fetchImpl,
|
|
204
|
+
endpoint.url,
|
|
205
|
+
{
|
|
206
|
+
method: "GET",
|
|
207
|
+
headers,
|
|
208
|
+
credentials: "include",
|
|
209
|
+
cache: "no-store",
|
|
210
|
+
},
|
|
211
|
+
args.fetchTimeoutMs ?? DEFAULT_READY_RECOVERY_FETCH_TIMEOUT_MS,
|
|
212
|
+
);
|
|
213
|
+
|
|
214
|
+
if (response.ok) {
|
|
215
|
+
const payload = await response.json().catch(() => null);
|
|
216
|
+
const probe = readyRecordingFromPublicPayload(
|
|
217
|
+
payload,
|
|
218
|
+
args.recordingId,
|
|
219
|
+
);
|
|
220
|
+
if (probe.ready) return probe.result;
|
|
221
|
+
if (probe.terminal) return null;
|
|
222
|
+
break;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (
|
|
226
|
+
response.status >= 400 &&
|
|
227
|
+
response.status < 500 &&
|
|
228
|
+
!endpoint.authenticated &&
|
|
229
|
+
!authenticatedUrl
|
|
230
|
+
) {
|
|
231
|
+
return null;
|
|
232
|
+
}
|
|
233
|
+
} catch {
|
|
234
|
+
// Try the public endpoint fallback below, then keep polling.
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
if (attempt < attempts - 1) await sleepImpl(intervalMs);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return null;
|
|
242
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"caller-auth.d.ts","sourceRoot":"","sources":["../../src/a2a/caller-auth.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,wBAAsB,oBAAoB,CAAC,OAAO,CAAC,EAAE;IACnD,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B,GAAG,OAAO,CAAC,aAAa,CAAC,
|
|
1
|
+
{"version":3,"file":"caller-auth.d.ts","sourceRoot":"","sources":["../../src/a2a/caller-auth.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,wBAAsB,oBAAoB,CAAC,OAAO,CAAC,EAAE;IACnD,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B,GAAG,OAAO,CAAC,aAAa,CAAC,CA+DzB"}
|
package/dist/a2a/caller-auth.js
CHANGED
|
@@ -23,20 +23,46 @@ export async function resolveA2ACallerAuth(options) {
|
|
|
23
23
|
}
|
|
24
24
|
catch { }
|
|
25
25
|
}
|
|
26
|
-
|
|
26
|
+
const apiKeyAttempts = [];
|
|
27
|
+
const addApiKeyAttempt = (token) => {
|
|
28
|
+
if (!token || apiKeyAttempts.includes(token))
|
|
29
|
+
return;
|
|
30
|
+
apiKeyAttempts.push(token);
|
|
31
|
+
};
|
|
27
32
|
if (userEmail && (orgSecret || process.env.A2A_SECRET)) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
+
if (process.env.A2A_SECRET?.trim()) {
|
|
34
|
+
try {
|
|
35
|
+
addApiKeyAttempt(await signA2AToken(userEmail, orgDomain, orgSecret, {
|
|
36
|
+
expiresIn: options?.expiresIn ?? DEFAULT_A2A_CALLER_TOKEN_TTL,
|
|
37
|
+
preferGlobalSecret: true,
|
|
38
|
+
}));
|
|
39
|
+
}
|
|
40
|
+
catch { }
|
|
41
|
+
}
|
|
42
|
+
if (orgSecret) {
|
|
43
|
+
try {
|
|
44
|
+
addApiKeyAttempt(await signA2AToken(userEmail, orgDomain, orgSecret, {
|
|
45
|
+
expiresIn: options?.expiresIn ?? DEFAULT_A2A_CALLER_TOKEN_TTL,
|
|
46
|
+
preferGlobalSecret: false,
|
|
47
|
+
}));
|
|
48
|
+
}
|
|
49
|
+
catch { }
|
|
33
50
|
}
|
|
34
|
-
catch { }
|
|
35
51
|
}
|
|
36
52
|
if (options?.includeGoogleToken) {
|
|
37
53
|
await attachGoogleTokenMetadata(metadata, userEmail);
|
|
38
54
|
}
|
|
39
|
-
return {
|
|
55
|
+
return {
|
|
56
|
+
apiKey: apiKeyAttempts[0],
|
|
57
|
+
...(apiKeyAttempts.length > 1
|
|
58
|
+
? { apiKeyFallbacks: apiKeyAttempts.slice(1) }
|
|
59
|
+
: {}),
|
|
60
|
+
userEmail,
|
|
61
|
+
orgId,
|
|
62
|
+
orgDomain,
|
|
63
|
+
orgSecret,
|
|
64
|
+
metadata,
|
|
65
|
+
};
|
|
40
66
|
}
|
|
41
67
|
async function attachGoogleTokenMetadata(metadata, userEmail) {
|
|
42
68
|
if (process.env.NODE_ENV !== "production" || !userEmail)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"caller-auth.js","sourceRoot":"","sources":["../../src/a2a/caller-auth.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,mBAAmB,GACpB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,4BAA4B,GAAG,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"caller-auth.js","sourceRoot":"","sources":["../../src/a2a/caller-auth.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n getRequestOrgId,\n getRequestUserEmail,\n} from \"../server/request-context.js\";\nimport { signA2AToken } from \"./client.js\";\n\nconst DEFAULT_A2A_CALLER_TOKEN_TTL = \"30m\";\n\nexport interface A2ACallerAuth {\n apiKey?: string;\n apiKeyFallbacks?: string[];\n userEmail?: string;\n orgId?: string;\n orgDomain?: string;\n orgSecret?: string;\n metadata: Record<string, unknown>;\n}\n\nexport async function resolveA2ACallerAuth(options?: {\n expiresIn?: string | number;\n includeGoogleToken?: boolean;\n}): Promise<A2ACallerAuth> {\n const userEmail = getRequestUserEmail();\n const metadata: Record<string, unknown> = {};\n if (userEmail) metadata.userEmail = userEmail;\n\n let orgDomain: string | undefined;\n let orgSecret: string | undefined;\n const orgId = getRequestOrgId();\n if (orgId) {\n try {\n const { getOrgDomain } = await import(\"../org/context.js\");\n orgDomain = (await getOrgDomain(orgId)) ?? undefined;\n if (orgDomain) metadata.orgDomain = orgDomain;\n } catch {}\n try {\n const { getOrgA2ASecret } = await import(\"../org/context.js\");\n orgSecret = (await getOrgA2ASecret(orgId)) ?? undefined;\n } catch {}\n }\n\n const apiKeyAttempts: string[] = [];\n const addApiKeyAttempt = (token: string | undefined) => {\n if (!token || apiKeyAttempts.includes(token)) return;\n apiKeyAttempts.push(token);\n };\n if (userEmail && (orgSecret || process.env.A2A_SECRET)) {\n if (process.env.A2A_SECRET?.trim()) {\n try {\n addApiKeyAttempt(\n await signA2AToken(userEmail, orgDomain, orgSecret, {\n expiresIn: options?.expiresIn ?? DEFAULT_A2A_CALLER_TOKEN_TTL,\n preferGlobalSecret: true,\n }),\n );\n } catch {}\n }\n if (orgSecret) {\n try {\n addApiKeyAttempt(\n await signA2AToken(userEmail, orgDomain, orgSecret, {\n expiresIn: options?.expiresIn ?? DEFAULT_A2A_CALLER_TOKEN_TTL,\n preferGlobalSecret: false,\n }),\n );\n } catch {}\n }\n }\n\n if (options?.includeGoogleToken) {\n await attachGoogleTokenMetadata(metadata, userEmail);\n }\n\n return {\n apiKey: apiKeyAttempts[0],\n ...(apiKeyAttempts.length > 1\n ? { apiKeyFallbacks: apiKeyAttempts.slice(1) }\n : {}),\n userEmail,\n orgId,\n orgDomain,\n orgSecret,\n metadata,\n };\n}\n\nasync function attachGoogleTokenMetadata(\n metadata: Record<string, unknown>,\n userEmail: string | undefined,\n): Promise<void> {\n if (process.env.NODE_ENV !== \"production\" || !userEmail) return;\n\n try {\n const { listOAuthAccountsByOwner } =\n await import(\"../oauth-tokens/store.js\");\n const accounts = await listOAuthAccountsByOwner(\"google\", userEmail);\n const tokens = accounts[0]?.tokens;\n if (tokens?.access_token) {\n metadata.googleToken = tokens.access_token;\n }\n } catch {}\n}\n"]}
|
package/dist/a2a/client.d.ts
CHANGED
|
@@ -27,14 +27,17 @@ export declare function signA2AToken(email: string, orgDomain?: string, orgSecre
|
|
|
27
27
|
*/
|
|
28
28
|
extraClaims?: Record<string, unknown>;
|
|
29
29
|
}): Promise<string>;
|
|
30
|
+
export declare function shouldPreferGlobalA2ASecret(orgSecret?: string): boolean;
|
|
30
31
|
export declare class A2AClient {
|
|
31
32
|
private baseUrl;
|
|
32
33
|
private apiKey?;
|
|
34
|
+
private apiKeyAttempts;
|
|
33
35
|
private endpointCandidates;
|
|
34
36
|
private endpointResolved;
|
|
35
37
|
private requestTimeoutMs?;
|
|
36
38
|
constructor(baseUrl: string, apiKey?: string, options?: {
|
|
37
39
|
requestTimeoutMs?: number;
|
|
40
|
+
fallbackApiKeys?: string[];
|
|
38
41
|
});
|
|
39
42
|
/**
|
|
40
43
|
* Detect which A2A path the target agent uses.
|
|
@@ -42,6 +45,7 @@ export declare class A2AClient {
|
|
|
42
45
|
*/
|
|
43
46
|
resolveEndpoint(): Promise<void>;
|
|
44
47
|
private headers;
|
|
48
|
+
private markApiKeySucceeded;
|
|
45
49
|
private rpc;
|
|
46
50
|
getAgentCard(): Promise<AgentCard>;
|
|
47
51
|
send(message: Message, opts?: {
|
package/dist/a2a/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/a2a/client.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,SAAS,EAGT,OAAO,EACP,IAAI,EACL,MAAM,YAAY,CAAC;AAEpB,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B,YAAY,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAU5D;CACF;AAED;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAChC,KAAK,EAAE,MAAM,EACb,SAAS,CAAC,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE;IACR,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC7B;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACvC,GACA,OAAO,CAAC,MAAM,CAAC,CA+BjB;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,kBAAkB,CAAgB;IAC1C,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,gBAAgB,CAAC,CAAS;IAElC,YACE,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QAAE,gBAAgB,CAAC,EAAE,MAAM,CAAA;KAAE,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/a2a/client.ts"],"names":[],"mappings":"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"}
|