@agent-native/core 0.175.5 → 0.175.6-nightly-20260827114203
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/templates/analytics/server/lib/replay-storage.ts +5 -3
- package/corpus/templates/assets/server/lib/storage.ts +7 -4
- package/corpus/templates/clips/actions/request-transcript.ts +7 -6
- package/corpus/templates/clips/app/components/meetings/share-meeting-dialog.tsx +99 -96
- package/corpus/templates/clips/app/components/player/share-dialog.tsx +196 -211
- package/corpus/templates/clips/app/components/player/video-player.tsx +2 -2
- package/corpus/templates/clips/app/components/sharing/share-ui.tsx +481 -263
- package/corpus/templates/clips/app/global.css +3 -0
- package/corpus/templates/clips/app/i18n/en-US.ts +21 -9
- package/corpus/templates/clips/app/routes/_app.settings._index.tsx +1 -2
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +0 -1
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +0 -1
- package/corpus/templates/clips/server/lib/builder-media-compression.ts +6 -6
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +1 -2
- package/dist/collab/routes.d.ts +1 -1
- package/dist/mcp/screen-memory-stdio.d.ts +7 -7
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/server/builder-api-auth.js +19 -5
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +1 -1
- package/dist/server/realtime-token.d.ts +1 -1
- package/package.json +2 -2
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { listFileUploadProviders } from "@agent-native/core/file-upload";
|
|
2
2
|
import {
|
|
3
|
-
|
|
3
|
+
CredentialStoreUnavailableError,
|
|
4
|
+
hasBuilderApiCredentialCustody,
|
|
4
5
|
runWithRequestContext,
|
|
5
6
|
} from "@agent-native/core/server";
|
|
6
7
|
|
|
@@ -63,8 +64,9 @@ export async function hasRequestReplayStorage(
|
|
|
63
64
|
}
|
|
64
65
|
|
|
65
66
|
try {
|
|
66
|
-
return await
|
|
67
|
-
} catch {
|
|
67
|
+
return await hasBuilderApiCredentialCustody();
|
|
68
|
+
} catch (err) {
|
|
69
|
+
if (err instanceof CredentialStoreUnavailableError) throw err;
|
|
68
70
|
return false;
|
|
69
71
|
}
|
|
70
72
|
};
|
|
@@ -21,7 +21,10 @@ import {
|
|
|
21
21
|
uploadFile,
|
|
22
22
|
getActiveFileUploadProvider,
|
|
23
23
|
} from "@agent-native/core/file-upload";
|
|
24
|
-
import {
|
|
24
|
+
import {
|
|
25
|
+
CredentialStoreUnavailableError,
|
|
26
|
+
hasBuilderApiCredentialCustody,
|
|
27
|
+
} from "@agent-native/core/server";
|
|
25
28
|
|
|
26
29
|
import {
|
|
27
30
|
getPresignedS3ObjectUrl,
|
|
@@ -93,9 +96,9 @@ export async function isObjectStorageConfigured(): Promise<boolean> {
|
|
|
93
96
|
const active = getActiveFileUploadProvider();
|
|
94
97
|
if (active && active.id !== "sql") return true;
|
|
95
98
|
try {
|
|
96
|
-
if (await
|
|
97
|
-
} catch {
|
|
98
|
-
|
|
99
|
+
if (await hasBuilderApiCredentialCustody()) return true;
|
|
100
|
+
} catch (err) {
|
|
101
|
+
if (err instanceof CredentialStoreUnavailableError) throw err;
|
|
99
102
|
}
|
|
100
103
|
return false;
|
|
101
104
|
}
|
|
@@ -37,7 +37,7 @@ import {
|
|
|
37
37
|
writeAppState,
|
|
38
38
|
} from "@agent-native/core/application-state";
|
|
39
39
|
import { ssrfSafeFetch } from "@agent-native/core/extensions/url-safety";
|
|
40
|
-
import {
|
|
40
|
+
import { resolveHasBuilderGatewayCredential } from "@agent-native/core/server";
|
|
41
41
|
import { assertAccess } from "@agent-native/core/sharing";
|
|
42
42
|
import { transcribeWithBuilder } from "@agent-native/core/transcription/builder";
|
|
43
43
|
import { and, eq } from "drizzle-orm";
|
|
@@ -1263,11 +1263,12 @@ const requestTranscriptAction = defineAction({
|
|
|
1263
1263
|
}
|
|
1264
1264
|
|
|
1265
1265
|
// ── Builder transcription (cloud fallback) ────────────────────────
|
|
1266
|
-
//
|
|
1267
|
-
//
|
|
1268
|
-
//
|
|
1269
|
-
//
|
|
1270
|
-
|
|
1266
|
+
// Gate on the gateway credential, not on Builder connection custody:
|
|
1267
|
+
// `transcribeWithBuilder` authenticates through `resolveBuilderGatewayAuth`,
|
|
1268
|
+
// which reads gateway credentials and a legacy private key and never
|
|
1269
|
+
// consults an OAuth grant. Gating on custody would select this path for an
|
|
1270
|
+
// OAuth-only user, write pending state, prepare audio, and only then fail.
|
|
1271
|
+
if (await resolveHasBuilderGatewayCredential()) {
|
|
1271
1272
|
if (!regeneratingReadyTranscript) {
|
|
1272
1273
|
await upsertTranscriptRow(db, {
|
|
1273
1274
|
recordingId: args.recordingId,
|
|
@@ -4,7 +4,6 @@ import {
|
|
|
4
4
|
useActionMutation,
|
|
5
5
|
} from "@agent-native/core/client/hooks";
|
|
6
6
|
import { useT } from "@agent-native/core/client/i18n";
|
|
7
|
-
import { ShareAgentsSection } from "@agent-native/toolkit/sharing";
|
|
8
7
|
import {
|
|
9
8
|
useCallback,
|
|
10
9
|
useEffect,
|
|
@@ -16,11 +15,12 @@ import {
|
|
|
16
15
|
import { toast } from "sonner";
|
|
17
16
|
|
|
18
17
|
import {
|
|
19
|
-
|
|
18
|
+
CopyButton,
|
|
20
19
|
GeneralAccessSelect,
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
InvitePeopleField,
|
|
21
|
+
PeopleAccessSection,
|
|
22
|
+
ShareSectionLabel,
|
|
23
|
+
nestedLayerDismissGuards,
|
|
24
24
|
useResourceVisibilityMutation,
|
|
25
25
|
type SharesQuery,
|
|
26
26
|
type SharesResponse,
|
|
@@ -32,6 +32,7 @@ import {
|
|
|
32
32
|
PopoverContent,
|
|
33
33
|
PopoverTrigger,
|
|
34
34
|
} from "@/components/ui/popover";
|
|
35
|
+
import { Separator } from "@/components/ui/separator";
|
|
35
36
|
import { Switch } from "@/components/ui/switch";
|
|
36
37
|
|
|
37
38
|
export interface ShareMeetingPopoverProps {
|
|
@@ -52,6 +53,7 @@ export function ShareMeetingPopover({
|
|
|
52
53
|
<PopoverTrigger asChild>{children}</PopoverTrigger>
|
|
53
54
|
<PopoverContent
|
|
54
55
|
align="end"
|
|
56
|
+
{...nestedLayerDismissGuards()}
|
|
55
57
|
className="max-h-[calc(100vh-1rem)] w-[440px] max-w-[calc(100vw-1rem)] overflow-y-auto border-border p-0"
|
|
56
58
|
>
|
|
57
59
|
<ShareMeetingContent
|
|
@@ -85,6 +87,14 @@ function ShareMeetingContent({
|
|
|
85
87
|
|
|
86
88
|
const data = sharesQuery.data;
|
|
87
89
|
const canManage = data?.role === "owner" || data?.role === "admin";
|
|
90
|
+
const visibility: Visibility =
|
|
91
|
+
(data?.visibility as Visibility | null) ?? "private";
|
|
92
|
+
const { setResourceVisibility, isPending } = useResourceVisibilityMutation(
|
|
93
|
+
"meeting",
|
|
94
|
+
meetingId,
|
|
95
|
+
sharesQuery,
|
|
96
|
+
);
|
|
97
|
+
const visibilityPending = isPending || sharesQuery.isLoading;
|
|
88
98
|
|
|
89
99
|
return (
|
|
90
100
|
<div className="min-w-0 px-4 py-3">
|
|
@@ -93,6 +103,9 @@ function ShareMeetingContent({
|
|
|
93
103
|
shareUrl={shareUrl}
|
|
94
104
|
sharesQuery={sharesQuery}
|
|
95
105
|
canManage={canManage}
|
|
106
|
+
visibility={visibility}
|
|
107
|
+
visibilityPending={visibilityPending}
|
|
108
|
+
onVisibilityChange={setResourceVisibility}
|
|
96
109
|
shareTranscript={shareTranscript}
|
|
97
110
|
transcriptReady={transcriptReady}
|
|
98
111
|
/>
|
|
@@ -105,6 +118,9 @@ function LinkTab({
|
|
|
105
118
|
shareUrl,
|
|
106
119
|
sharesQuery,
|
|
107
120
|
canManage,
|
|
121
|
+
visibility,
|
|
122
|
+
visibilityPending,
|
|
123
|
+
onVisibilityChange,
|
|
108
124
|
shareTranscript,
|
|
109
125
|
transcriptReady,
|
|
110
126
|
}: {
|
|
@@ -112,6 +128,12 @@ function LinkTab({
|
|
|
112
128
|
shareUrl: string;
|
|
113
129
|
sharesQuery: SharesQuery;
|
|
114
130
|
canManage: boolean;
|
|
131
|
+
visibility: Visibility;
|
|
132
|
+
visibilityPending: boolean;
|
|
133
|
+
onVisibilityChange: (
|
|
134
|
+
next: Visibility,
|
|
135
|
+
options?: { onSuccess?: () => void },
|
|
136
|
+
) => void;
|
|
115
137
|
shareTranscript: boolean;
|
|
116
138
|
transcriptReady: boolean;
|
|
117
139
|
}) {
|
|
@@ -121,14 +143,7 @@ function LinkTab({
|
|
|
121
143
|
{ id: string; shareTranscript: boolean }
|
|
122
144
|
>("update-meeting");
|
|
123
145
|
const [includeTranscript, setIncludeTranscript] = useState(shareTranscript);
|
|
124
|
-
const { setResourceVisibility, isPending } = useResourceVisibilityMutation(
|
|
125
|
-
"meeting",
|
|
126
|
-
meetingId,
|
|
127
|
-
sharesQuery,
|
|
128
|
-
);
|
|
129
146
|
const data = sharesQuery.data;
|
|
130
|
-
const visibility: Visibility =
|
|
131
|
-
(data?.visibility as Visibility | null) ?? "private";
|
|
132
147
|
const isPublic = visibility === "public";
|
|
133
148
|
const sharesLoaded = data?.visibility != null;
|
|
134
149
|
const createAgentLink = useActionMutation("create-agent-resource-link");
|
|
@@ -136,7 +151,6 @@ function LinkTab({
|
|
|
136
151
|
const agentLinkRequestIdRef = useRef(0);
|
|
137
152
|
const [agentLink, setAgentLink] = useState("");
|
|
138
153
|
const [agentLinkError, setAgentLinkError] = useState(false);
|
|
139
|
-
const [agentDetailsOpen, setAgentDetailsOpen] = useState(false);
|
|
140
154
|
|
|
141
155
|
useEffect(() => {
|
|
142
156
|
createAgentLinkAsyncRef.current = createAgentLink.mutateAsync;
|
|
@@ -172,10 +186,6 @@ function LinkTab({
|
|
|
172
186
|
};
|
|
173
187
|
}, [isPublic, loadAgentLink, meetingId, sharesLoaded, visibility]);
|
|
174
188
|
|
|
175
|
-
useEffect(() => {
|
|
176
|
-
if (isPublic) setAgentDetailsOpen(false);
|
|
177
|
-
}, [isPublic]);
|
|
178
|
-
|
|
179
189
|
const agentShareDisabled =
|
|
180
190
|
sharesQuery.isLoading ||
|
|
181
191
|
!sharesLoaded ||
|
|
@@ -206,23 +216,47 @@ function LinkTab({
|
|
|
206
216
|
|
|
207
217
|
return (
|
|
208
218
|
<div className="space-y-3">
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
219
|
+
{canManage ? (
|
|
220
|
+
<InvitePeopleField
|
|
221
|
+
resourceType="meeting"
|
|
222
|
+
resourceId={meetingId}
|
|
223
|
+
sharesQuery={sharesQuery}
|
|
224
|
+
onError={(err) =>
|
|
225
|
+
toast.error(
|
|
226
|
+
err instanceof Error
|
|
227
|
+
? err.message
|
|
228
|
+
: t("clipsFinalRaw.inviteFailed"),
|
|
229
|
+
)
|
|
230
|
+
}
|
|
231
|
+
/>
|
|
232
|
+
) : null}
|
|
218
233
|
|
|
219
|
-
<
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
234
|
+
<div className="space-y-2">
|
|
235
|
+
<ShareSectionLabel>{t("shareUi.whoHasAccess")}</ShareSectionLabel>
|
|
236
|
+
<div className="flex flex-col gap-1">
|
|
237
|
+
<PeopleAccessSection
|
|
238
|
+
resourceType="meeting"
|
|
239
|
+
resourceId={meetingId}
|
|
240
|
+
sharesQuery={sharesQuery}
|
|
241
|
+
canManage={canManage}
|
|
242
|
+
onError={(err, action) =>
|
|
243
|
+
toast.error(
|
|
244
|
+
err instanceof Error
|
|
245
|
+
? err.message
|
|
246
|
+
: action === "permission"
|
|
247
|
+
? t("clipsFinalRaw.permissionUpdateFailed")
|
|
248
|
+
: t("clipsFinalRaw.removePersonFailed"),
|
|
249
|
+
)
|
|
250
|
+
}
|
|
251
|
+
/>
|
|
252
|
+
<GeneralAccessSelect
|
|
253
|
+
visibility={visibility}
|
|
254
|
+
canManage={canManage}
|
|
255
|
+
isPending={visibilityPending}
|
|
256
|
+
onChange={onVisibilityChange}
|
|
257
|
+
/>
|
|
258
|
+
</div>
|
|
259
|
+
</div>
|
|
226
260
|
|
|
227
261
|
<div className="flex items-center justify-between gap-4 rounded-md border border-border px-3 py-2.5">
|
|
228
262
|
<div className="min-w-0">
|
|
@@ -251,73 +285,42 @@ function LinkTab({
|
|
|
251
285
|
/>
|
|
252
286
|
</div>
|
|
253
287
|
|
|
254
|
-
<
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
sharesQuery={sharesQuery}
|
|
258
|
-
canManage={canManage}
|
|
259
|
-
onError={(err, action) =>
|
|
260
|
-
toast.error(
|
|
261
|
-
err instanceof Error
|
|
262
|
-
? err.message
|
|
263
|
-
: action === "invite"
|
|
264
|
-
? t("clipsFinalRaw.inviteFailed")
|
|
265
|
-
: action === "permission"
|
|
266
|
-
? t("clipsFinalRaw.permissionUpdateFailed")
|
|
267
|
-
: t("clipsFinalRaw.removePersonFailed"),
|
|
268
|
-
)
|
|
269
|
-
}
|
|
270
|
-
/>
|
|
288
|
+
<CopyButton value={shareUrl} disabled={!sharesLoaded}>
|
|
289
|
+
{t("shareUi.copyLink")}
|
|
290
|
+
</CopyButton>
|
|
271
291
|
|
|
272
|
-
|
|
273
|
-
<MakePublicCard
|
|
274
|
-
isPending={isPending}
|
|
275
|
-
onMakePublic={() =>
|
|
276
|
-
setResourceVisibility("public", {
|
|
277
|
-
onSuccess: () => copyToClipboard(shareUrl),
|
|
278
|
-
})
|
|
279
|
-
}
|
|
280
|
-
/>
|
|
281
|
-
) : null}
|
|
292
|
+
<Separator />
|
|
282
293
|
|
|
283
|
-
<
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
294
|
+
<div className="flex items-center justify-between gap-4">
|
|
295
|
+
<div className="min-w-0">
|
|
296
|
+
<div className="text-sm font-medium">
|
|
297
|
+
{t("shareDialog.shareWithAgents")}
|
|
298
|
+
</div>
|
|
299
|
+
<p className="text-xs text-muted-foreground">
|
|
300
|
+
{t("shareMeeting.agentLinkDescription")}
|
|
301
|
+
</p>
|
|
302
|
+
</div>
|
|
303
|
+
{agentLinkError ? (
|
|
304
|
+
<Button
|
|
305
|
+
type="button"
|
|
306
|
+
variant="outline"
|
|
307
|
+
size="sm"
|
|
308
|
+
className="shrink-0"
|
|
309
|
+
onClick={() => void loadAgentLink()}
|
|
310
|
+
disabled={createAgentLink.isPending}
|
|
311
|
+
>
|
|
312
|
+
{t("shareDialog.retryAgentLink")}
|
|
313
|
+
</Button>
|
|
314
|
+
) : (
|
|
315
|
+
<CopyButton
|
|
292
316
|
value={visibleAgentLink}
|
|
293
317
|
disabled={agentShareDisabled}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
{agentLinkError ? (
|
|
301
|
-
<div className="flex items-center justify-between gap-2 rounded-md border border-border bg-muted/30 px-3 py-2">
|
|
302
|
-
<p className="text-xs text-muted-foreground">
|
|
303
|
-
{t("shareDialog.agentLinkUnavailable")}
|
|
304
|
-
</p>
|
|
305
|
-
<Button
|
|
306
|
-
type="button"
|
|
307
|
-
variant="ghost"
|
|
308
|
-
size="sm"
|
|
309
|
-
className="h-7"
|
|
310
|
-
onClick={() => void loadAgentLink()}
|
|
311
|
-
disabled={createAgentLink.isPending}
|
|
312
|
-
>
|
|
313
|
-
{t("shareDialog.retryAgentLink")}
|
|
314
|
-
</Button>
|
|
315
|
-
</div>
|
|
316
|
-
) : null}
|
|
317
|
-
</>
|
|
318
|
-
) : null}
|
|
319
|
-
</div>
|
|
320
|
-
</ShareAgentsSection>
|
|
318
|
+
className="shrink-0"
|
|
319
|
+
>
|
|
320
|
+
{t("shareUi.copy")}
|
|
321
|
+
</CopyButton>
|
|
322
|
+
)}
|
|
323
|
+
</div>
|
|
321
324
|
</div>
|
|
322
325
|
);
|
|
323
326
|
}
|