@agent-native/core 0.159.3 → 0.160.0
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/templates/assets/server/lib/generation.ts +10 -6
- package/corpus/templates/calendar/.agents/skills/event-management/SKILL.md +18 -4
- package/corpus/templates/calendar/actions/create-event.ts +4 -2
- package/corpus/templates/calendar/actions/event-action-helpers.ts +56 -9
- package/corpus/templates/calendar/actions/update-event.ts +1 -0
- package/corpus/templates/calendar/agent-native.config.ts +1 -0
- package/corpus/templates/calendar/app/components/calendar/CreateEventDialog.tsx +8 -2
- package/corpus/templates/calendar/app/components/calendar/DayView.tsx +102 -68
- package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +150 -49
- package/corpus/templates/calendar/app/components/calendar/MonthView.tsx +57 -23
- package/corpus/templates/calendar/app/components/calendar/OutOfOfficeEvent.tsx +4 -1
- package/corpus/templates/calendar/app/components/calendar/TimezoneSwitchDialog.tsx +70 -0
- package/corpus/templates/calendar/app/components/calendar/WeekView.tsx +127 -88
- package/corpus/templates/calendar/app/components/calendar/WorkingLocationEditor.tsx +59 -25
- package/corpus/templates/calendar/app/hooks/use-event-drag.ts +55 -18
- package/corpus/templates/calendar/app/i18n-data.ts +60 -0
- package/corpus/templates/calendar/app/lib/all-day-layout.ts +16 -8
- package/corpus/templates/calendar/app/lib/calendar-drafts.ts +56 -0
- package/corpus/templates/calendar/app/lib/calendar-timezone.ts +351 -0
- package/corpus/templates/calendar/app/lib/event-layout.ts +14 -8
- package/corpus/templates/calendar/app/lib/out-of-office.ts +29 -61
- package/corpus/templates/calendar/app/lib/working-location.ts +34 -2
- package/corpus/templates/calendar/app/pages/CalendarView.tsx +317 -139
- package/corpus/templates/calendar/changelog/2026-08-13-calendar-stays-pinned-to-the-saved-timezone-and-asks-before-.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-13-working-locations-can-be-added-from-calendar-days-with-a-ful.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-14-choosing-office-or-other-when-adding-a-working-location-creates.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-14-creating-an-other-working-location-now-keeps-the-custom-name.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-14-timed-working-locations-keep-home-office-or-custom-titles.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-14-timed-working-locations-now-keep-a-home-office-or-custom-title.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-14-turning-a-midnight-ending-working-location-back-to-all-day.md +6 -0
- package/corpus/templates/calendar/server/lib/google-calendar.ts +22 -1
- package/dist/agent/engine/builder-engine.d.ts +16 -2
- package/dist/agent/engine/builder-engine.js +178 -115
- package/dist/agent/engine/builtin.js +13 -4
- package/dist/agent/engine/credential-errors.d.ts +23 -0
- package/dist/agent/engine/credential-errors.js +19 -0
- package/dist/agent/engine/error-detail.d.ts +15 -0
- package/dist/agent/engine/error-detail.js +29 -0
- package/dist/agent/engine/registry.d.ts +14 -3
- package/dist/agent/engine/registry.js +106 -61
- package/dist/agent/engine/types.d.ts +16 -0
- package/dist/agent/engine/types.js +9 -0
- package/dist/agent/production-agent.d.ts +7 -0
- package/dist/agent/production-agent.js +58 -20
- package/dist/agent/run-manager.js +30 -0
- package/dist/agent/thread-data-builder.js +4 -0
- package/dist/agent/types.d.ts +9 -0
- package/dist/client/agent-chat-adapter.js +46 -15
- package/dist/client/chat-first/app-pane.js +1 -1
- package/dist/client/chat-first/copy.js +1 -0
- package/dist/client/error-format.js +25 -2
- package/dist/client/sse-event-processor.d.ts +2 -0
- package/dist/client/sse-event-processor.js +12 -1
- package/dist/feature-flags/index.d.ts +0 -2
- package/dist/feature-flags/index.js +3 -2
- package/dist/feature-flags/server.d.ts +2 -0
- package/dist/feature-flags/server.js +2 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/jobs/background-automation-runner.js +9 -15
- package/dist/mcp/screen-memory-stdio.d.ts +7 -7
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/observability/routes.d.ts +2 -2
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +2 -2
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/secrets/register-framework-secrets.js +25 -0
- package/dist/secrets/routes.d.ts +6 -6
- package/dist/server/agent-chat-plugin.js +9 -2
- package/dist/server/auth.js +10 -0
- package/dist/server/credential-provider.d.ts +80 -0
- package/dist/server/credential-provider.js +168 -1
- package/dist/server/google-realtime-session.d.ts +1 -1
- package/dist/server/google-realtime-session.js +6 -6
- package/dist/server/index.d.ts +2 -2
- package/dist/server/index.js +7 -2
- package/dist/server/onboarding-html.js +16 -257
- package/dist/server/realtime-token.d.ts +1 -1
- package/dist/server/realtime-voice.js +12 -6
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/server/transcribe-voice.js +18 -16
- package/dist/shared/auth-copy.d.ts +34 -0
- package/dist/shared/auth-copy.js +293 -0
- package/dist/shared/index.d.ts +1 -0
- package/dist/shared/index.js +1 -0
- package/dist/transcription/builder-transcription.js +8 -4
- package/docs/content/actions-advanced.mdx +1 -1
- package/docs/content/portal.mdx +21 -8
- package/package.json +3 -1
|
@@ -26,8 +26,8 @@ export declare function createRealtimeTokenHandler(): import("h3").EventHandlerW
|
|
|
26
26
|
expiresAt?: undefined;
|
|
27
27
|
ttlSeconds?: undefined;
|
|
28
28
|
} | {
|
|
29
|
-
error?: undefined;
|
|
30
29
|
token: string;
|
|
31
30
|
expiresAt: string;
|
|
32
31
|
ttlSeconds: number;
|
|
32
|
+
error?: undefined;
|
|
33
33
|
}>>;
|
|
@@ -5,7 +5,7 @@ import { redactSensitiveFields, sanitizeToolErrorText, sanitizeToolErrorValue, }
|
|
|
5
5
|
import { TOOL_SEARCH_ACTION_NAME } from "../agent/tool-search.js";
|
|
6
6
|
import { parseAcceptLanguage } from "../localization/server.js";
|
|
7
7
|
import { getSession } from "./auth.js";
|
|
8
|
-
import { getBuilderGatewayBaseUrl,
|
|
8
|
+
import { gatewayLaneUnavailableMessage, getBuilderGatewayBaseUrl, resolveBuilderGatewayCredentials, resolveSecret, } from "./credential-provider.js";
|
|
9
9
|
import { getH3App } from "./framework-request-handler.js";
|
|
10
10
|
import { runWithRequestContext } from "./request-context.js";
|
|
11
11
|
import { isSameOriginRequest } from "./request-origin.js";
|
|
@@ -379,7 +379,7 @@ function createSessionHandler(tools, options) {
|
|
|
379
379
|
? { browserTabId: auth.browserTabId }
|
|
380
380
|
: undefined,
|
|
381
381
|
}, async () => {
|
|
382
|
-
const builderCredentials = await
|
|
382
|
+
const builderCredentials = await resolveBuilderGatewayCredentials();
|
|
383
383
|
const builderConfigured = Boolean(builderCredentials.privateKey?.trim() &&
|
|
384
384
|
builderCredentials.publicKey?.trim());
|
|
385
385
|
const apiKey = builderConfigured
|
|
@@ -388,7 +388,7 @@ function createSessionHandler(tools, options) {
|
|
|
388
388
|
if (!builderConfigured && !apiKey) {
|
|
389
389
|
setResponseStatus(event, 409);
|
|
390
390
|
return {
|
|
391
|
-
error: "Connect Builder (free tier available) or configure an OpenAI API key to use realtime voice.",
|
|
391
|
+
error: gatewayLaneUnavailableMessage("Connect Builder (free tier available) or configure an OpenAI API key to use realtime voice."),
|
|
392
392
|
code: "realtime_voice_setup_required",
|
|
393
393
|
};
|
|
394
394
|
}
|
|
@@ -466,22 +466,28 @@ function createSessionHandler(tools, options) {
|
|
|
466
466
|
setResponseStatus(event, 502);
|
|
467
467
|
return {
|
|
468
468
|
error: builderConfigured
|
|
469
|
-
? "Could not reach the Builder realtime voice gateway"
|
|
469
|
+
? gatewayLaneUnavailableMessage("Could not reach the Builder realtime voice gateway")
|
|
470
470
|
: "Could not reach the OpenAI Realtime API",
|
|
471
471
|
};
|
|
472
472
|
}
|
|
473
473
|
if (!upstream.ok) {
|
|
474
474
|
const detail = await safeOpenAiErrorDetail(upstream, builderConfigured ? builderCredentials.privateKey : apiKey);
|
|
475
475
|
setResponseStatus(event, builderConfigured ? upstream.status : 502);
|
|
476
|
+
const rejection = `${builderConfigured ? "Builder" : "OpenAI"} rejected the realtime session (${upstream.status})${detail ? `: ${detail}` : ""}`;
|
|
476
477
|
return {
|
|
477
|
-
error:
|
|
478
|
+
error: builderConfigured
|
|
479
|
+
? gatewayLaneUnavailableMessage(rejection)
|
|
480
|
+
: rejection,
|
|
478
481
|
};
|
|
479
482
|
}
|
|
480
483
|
const answerSdp = await upstream.text().catch(() => "");
|
|
481
484
|
if (!answerSdp.trim()) {
|
|
482
485
|
setResponseStatus(event, 502);
|
|
486
|
+
const emptyAnswer = `${builderConfigured ? "Builder" : "OpenAI"} returned an empty realtime session answer`;
|
|
483
487
|
return {
|
|
484
|
-
error:
|
|
488
|
+
error: builderConfigured
|
|
489
|
+
? gatewayLaneUnavailableMessage(emptyAnswer)
|
|
490
|
+
: emptyAnswer,
|
|
485
491
|
};
|
|
486
492
|
}
|
|
487
493
|
setResponseStatus(event, upstream.status);
|
|
@@ -23,7 +23,7 @@ import { getOrgContext } from "../org/context.js";
|
|
|
23
23
|
import { transcribeWithBuilder } from "../transcription/builder-transcription.js";
|
|
24
24
|
import { applyVoiceContextReplacements, buildVoiceGuidanceBlock, parseVoiceContextPack, voiceContextTermsOnly, } from "../voice/index.js";
|
|
25
25
|
import { getSession } from "./auth.js";
|
|
26
|
-
import {
|
|
26
|
+
import { gatewayLaneUnavailableMessage, resolveHasBuilderGatewayCredential, resolveSecret, } from "./credential-provider.js";
|
|
27
27
|
import { runWithRequestContext } from "./request-context.js";
|
|
28
28
|
import { isSameOriginRequest } from "./request-origin.js";
|
|
29
29
|
const WHISPER_URL = "https://api.openai.com/v1/audio/transcriptions";
|
|
@@ -149,7 +149,7 @@ export function createTranscribeVoiceHandler() {
|
|
|
149
149
|
const withRequestContext = async (fn) => requestContext.userEmail
|
|
150
150
|
? runWithRequestContext(requestContext, fn)
|
|
151
151
|
: fn();
|
|
152
|
-
const
|
|
152
|
+
const hasBuilderCredential = async () => withRequestContext(() => resolveHasBuilderGatewayCredential());
|
|
153
153
|
const transcribeWithBuilderForRequest = (opts) => withRequestContext(() => transcribeWithBuilder(opts));
|
|
154
154
|
const sessionId = session?.email ?? "local";
|
|
155
155
|
let providerPref;
|
|
@@ -212,7 +212,7 @@ export function createTranscribeVoiceHandler() {
|
|
|
212
212
|
instructions: voiceGuidance,
|
|
213
213
|
contextPack: voiceContext,
|
|
214
214
|
providerPref,
|
|
215
|
-
|
|
215
|
+
hasBuilderCredential,
|
|
216
216
|
withRequestContext,
|
|
217
217
|
resolveApiKey,
|
|
218
218
|
clientAbortSignal: clientAbort,
|
|
@@ -266,10 +266,10 @@ export function createTranscribeVoiceHandler() {
|
|
|
266
266
|
const label = providerPref === "builder-gemini"
|
|
267
267
|
? "Builder Gemini Flash-Lite"
|
|
268
268
|
: "Builder";
|
|
269
|
-
if (!(await
|
|
269
|
+
if (!(await hasBuilderCredential())) {
|
|
270
270
|
setResponseStatus(event, 400);
|
|
271
271
|
return {
|
|
272
|
-
error: `${label} is selected but Builder.io is not connected. Connect Builder.io (free tier available) in Settings, or change the provider preference
|
|
272
|
+
error: gatewayLaneUnavailableMessage(`${label} is selected but Builder.io is not connected. Connect Builder.io (free tier available) in Settings, or change the provider preference.`),
|
|
273
273
|
};
|
|
274
274
|
}
|
|
275
275
|
try {
|
|
@@ -288,10 +288,12 @@ export function createTranscribeVoiceHandler() {
|
|
|
288
288
|
const message = err?.message ?? String(err);
|
|
289
289
|
if (message.includes("credits exhausted")) {
|
|
290
290
|
setResponseStatus(event, 402);
|
|
291
|
-
return { error: message };
|
|
291
|
+
return { error: gatewayLaneUnavailableMessage(message) };
|
|
292
292
|
}
|
|
293
293
|
setResponseStatus(event, 502);
|
|
294
|
-
return {
|
|
294
|
+
return {
|
|
295
|
+
error: gatewayLaneUnavailableMessage(`${label} transcription failed: ${message}`),
|
|
296
|
+
};
|
|
295
297
|
}
|
|
296
298
|
}
|
|
297
299
|
if (providerPref === "groq") {
|
|
@@ -322,7 +324,7 @@ export function createTranscribeVoiceHandler() {
|
|
|
322
324
|
// ── Builder Gemini Flash-Lite path ─────────────────────────────────
|
|
323
325
|
// First-priority in auto mode when Builder is connected. This lets users
|
|
324
326
|
// try Gemini 3.1 Flash-Lite without bringing their own Google key.
|
|
325
|
-
if (providerPref !== "openai" && (await
|
|
327
|
+
if (providerPref !== "openai" && (await hasBuilderCredential())) {
|
|
326
328
|
try {
|
|
327
329
|
const result = await transcribeWithBuilderForRequest({
|
|
328
330
|
audioBytes,
|
|
@@ -339,7 +341,7 @@ export function createTranscribeVoiceHandler() {
|
|
|
339
341
|
// a specific upgrade prompt.
|
|
340
342
|
if (message.includes("credits exhausted")) {
|
|
341
343
|
setResponseStatus(event, 402);
|
|
342
|
-
return { error: message };
|
|
344
|
+
return { error: gatewayLaneUnavailableMessage(message) };
|
|
343
345
|
}
|
|
344
346
|
builderError = message;
|
|
345
347
|
}
|
|
@@ -401,9 +403,9 @@ export function createTranscribeVoiceHandler() {
|
|
|
401
403
|
if (!provider) {
|
|
402
404
|
setResponseStatus(event, builderError ? 502 : 400);
|
|
403
405
|
return {
|
|
404
|
-
error: builderError
|
|
406
|
+
error: gatewayLaneUnavailableMessage(builderError
|
|
405
407
|
? `Builder transcription failed: ${builderError}. Add GEMINI_API_KEY, GROQ_API_KEY, or OPENAI_API_KEY in Settings → API Keys to enable a fallback provider.`
|
|
406
|
-
: "No voice transcription provider configured. Connect Builder.io (free tier available) or add GEMINI_API_KEY / GROQ_API_KEY / OPENAI_API_KEY in Settings → API Keys.",
|
|
408
|
+
: "No voice transcription provider configured. Connect Builder.io (free tier available) or add GEMINI_API_KEY / GROQ_API_KEY / OPENAI_API_KEY in Settings → API Keys."),
|
|
407
409
|
};
|
|
408
410
|
}
|
|
409
411
|
return await callWhisperCompat({
|
|
@@ -477,7 +479,7 @@ async function callWhisperCompat({ event, provider, audioBytes, mime, language,
|
|
|
477
479
|
clearTimeout(timeout);
|
|
478
480
|
}
|
|
479
481
|
}
|
|
480
|
-
async function cleanupTranscriptText({ event, text, instructions, contextPack, providerPref,
|
|
482
|
+
async function cleanupTranscriptText({ event, text, instructions, contextPack, providerPref, hasBuilderCredential, withRequestContext, resolveApiKey, clientAbortSignal, }) {
|
|
481
483
|
const original = text.trim();
|
|
482
484
|
if (!original)
|
|
483
485
|
return { text: "" };
|
|
@@ -486,10 +488,10 @@ async function cleanupTranscriptText({ event, text, instructions, contextPack, p
|
|
|
486
488
|
return { text: finalizeText(original) };
|
|
487
489
|
}
|
|
488
490
|
if (providerPref === "builder" || providerPref === "builder-gemini") {
|
|
489
|
-
if (!(await
|
|
491
|
+
if (!(await hasBuilderCredential())) {
|
|
490
492
|
setResponseStatus(event, 400);
|
|
491
493
|
return {
|
|
492
|
-
error: "Builder.io cleanup is selected but Builder.io is not connected. Connect Builder.io (free tier available) in Settings, or change the provider preference.",
|
|
494
|
+
error: gatewayLaneUnavailableMessage("Builder.io cleanup is selected but Builder.io is not connected. Connect Builder.io (free tier available) in Settings, or change the provider preference."),
|
|
493
495
|
};
|
|
494
496
|
}
|
|
495
497
|
try {
|
|
@@ -506,7 +508,7 @@ async function cleanupTranscriptText({ event, text, instructions, contextPack, p
|
|
|
506
508
|
catch (err) {
|
|
507
509
|
setResponseStatus(event, 502);
|
|
508
510
|
return {
|
|
509
|
-
error: `Builder.io cleanup failed: ${err?.message ?? String(err)}
|
|
511
|
+
error: gatewayLaneUnavailableMessage(`Builder.io cleanup failed: ${err?.message ?? String(err)}`),
|
|
510
512
|
};
|
|
511
513
|
}
|
|
512
514
|
}
|
|
@@ -560,7 +562,7 @@ async function cleanupTranscriptText({ event, text, instructions, contextPack, p
|
|
|
560
562
|
};
|
|
561
563
|
}
|
|
562
564
|
}
|
|
563
|
-
if (await
|
|
565
|
+
if (await hasBuilderCredential()) {
|
|
564
566
|
try {
|
|
565
567
|
const cleaned = await withRequestContext(() => cleanupWithBuilder({ text: original, instructions, clientAbortSignal }));
|
|
566
568
|
if (cleaned)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type LocaleCode } from "../localization/shared.js";
|
|
2
|
+
/**
|
|
3
|
+
* The native sign-in surfaces use the same copy keys as the hosted onboarding
|
|
4
|
+
* form. Keep this browser-safe subset here so Electron and mobile do not load
|
|
5
|
+
* the server HTML renderer or grow a second auth vocabulary.
|
|
6
|
+
*/
|
|
7
|
+
export interface NativeAuthCopy {
|
|
8
|
+
googleButton: string;
|
|
9
|
+
dividerOr: string;
|
|
10
|
+
email: string;
|
|
11
|
+
emailPlaceholder: string;
|
|
12
|
+
password: string;
|
|
13
|
+
confirmPassword: string;
|
|
14
|
+
enterPasswordPlaceholder: string;
|
|
15
|
+
forgotPassword: string;
|
|
16
|
+
sendMagicLink: string;
|
|
17
|
+
magicLinkSent: string;
|
|
18
|
+
magicLinkSentCopy: string;
|
|
19
|
+
magicLinkFailed: string;
|
|
20
|
+
usePasswordInstead: string;
|
|
21
|
+
backToMagicLink: string;
|
|
22
|
+
signIn: string;
|
|
23
|
+
back: string;
|
|
24
|
+
close: string;
|
|
25
|
+
sending: string;
|
|
26
|
+
signingIn: string;
|
|
27
|
+
invalidEmail: string;
|
|
28
|
+
invalidLogin: string;
|
|
29
|
+
failedToConnect: string;
|
|
30
|
+
googleNeverFinished: string;
|
|
31
|
+
checking: string;
|
|
32
|
+
}
|
|
33
|
+
export declare const NATIVE_AUTH_COPY: Record<LocaleCode, NativeAuthCopy>;
|
|
34
|
+
export declare function resolveNativeAuthCopy(locale: unknown): NativeAuthCopy;
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
import { DEFAULT_LOCALE, resolveLocaleFromCandidates, } from "../localization/shared.js";
|
|
2
|
+
export const NATIVE_AUTH_COPY = {
|
|
3
|
+
"en-US": {
|
|
4
|
+
googleButton: "Sign in with Google",
|
|
5
|
+
dividerOr: "or",
|
|
6
|
+
email: "Email",
|
|
7
|
+
emailPlaceholder: "you@example.com",
|
|
8
|
+
password: "Password",
|
|
9
|
+
confirmPassword: "Confirm password",
|
|
10
|
+
enterPasswordPlaceholder: "Enter password",
|
|
11
|
+
forgotPassword: "Forgot password?",
|
|
12
|
+
sendMagicLink: "Continue",
|
|
13
|
+
magicLinkSent: "Check your email",
|
|
14
|
+
magicLinkSentCopy: "We sent a secure sign-in link to",
|
|
15
|
+
magicLinkFailed: "We couldn't send a sign-in link. Check your email and try again.",
|
|
16
|
+
usePasswordInstead: "Use a password instead",
|
|
17
|
+
backToMagicLink: "Use a sign-in link instead",
|
|
18
|
+
signIn: "Sign in",
|
|
19
|
+
back: "Back",
|
|
20
|
+
close: "Close",
|
|
21
|
+
sending: "Sending...",
|
|
22
|
+
signingIn: "Signing in…",
|
|
23
|
+
invalidEmail: "Enter a valid email address, like you@example.com.",
|
|
24
|
+
invalidLogin: "The email or password is incorrect.",
|
|
25
|
+
failedToConnect: "We couldn't connect. Please try again.",
|
|
26
|
+
googleNeverFinished: "Google sign-in did not finish. Check the Google OAuth redirect URI and server logs for [agent-native][google-oauth].",
|
|
27
|
+
checking: "Checking...",
|
|
28
|
+
},
|
|
29
|
+
"zh-CN": {
|
|
30
|
+
googleButton: "使用 Google 登录",
|
|
31
|
+
dividerOr: "或",
|
|
32
|
+
email: "电子邮箱",
|
|
33
|
+
emailPlaceholder: "you@example.com",
|
|
34
|
+
password: "密码",
|
|
35
|
+
confirmPassword: "确认密码",
|
|
36
|
+
enterPasswordPlaceholder: "输入密码",
|
|
37
|
+
forgotPassword: "忘记密码?",
|
|
38
|
+
sendMagicLink: "继续",
|
|
39
|
+
magicLinkSent: "检查你的邮箱",
|
|
40
|
+
magicLinkSentCopy: "我们已向以下邮箱发送安全登录链接:",
|
|
41
|
+
magicLinkFailed: "无法发送登录链接。",
|
|
42
|
+
usePasswordInstead: "改用密码",
|
|
43
|
+
backToMagicLink: "改用登录链接",
|
|
44
|
+
signIn: "登录",
|
|
45
|
+
back: "返回",
|
|
46
|
+
close: "关闭",
|
|
47
|
+
sending: "正在发送...",
|
|
48
|
+
signingIn: "正在登录…",
|
|
49
|
+
invalidEmail: "请输入有效邮箱地址,例如 you@example.com。",
|
|
50
|
+
invalidLogin: "邮箱或密码无效",
|
|
51
|
+
failedToConnect: "连接失败。请重试。",
|
|
52
|
+
googleNeverFinished: "Google 登录未完成。请检查 Google OAuth 重定向 URI 和服务器日志中的 [agent-native][google-oauth]。",
|
|
53
|
+
checking: "正在检查...",
|
|
54
|
+
},
|
|
55
|
+
"zh-TW": {
|
|
56
|
+
googleButton: "使用 Google 登入",
|
|
57
|
+
dividerOr: "或",
|
|
58
|
+
email: "電子郵件",
|
|
59
|
+
emailPlaceholder: "you@example.com",
|
|
60
|
+
password: "密碼",
|
|
61
|
+
confirmPassword: "確認密碼",
|
|
62
|
+
enterPasswordPlaceholder: "輸入密碼",
|
|
63
|
+
forgotPassword: "忘記密碼?",
|
|
64
|
+
sendMagicLink: "繼續",
|
|
65
|
+
magicLinkSent: "檢查你的電子郵件",
|
|
66
|
+
magicLinkSentCopy: "我們已向以下電子郵件寄送安全登入連結:",
|
|
67
|
+
magicLinkFailed: "無法寄送登入連結。",
|
|
68
|
+
usePasswordInstead: "改用密碼",
|
|
69
|
+
backToMagicLink: "改用登入連結",
|
|
70
|
+
signIn: "登入",
|
|
71
|
+
back: "返回",
|
|
72
|
+
close: "關閉",
|
|
73
|
+
sending: "正在寄送...",
|
|
74
|
+
signingIn: "正在登入...",
|
|
75
|
+
invalidEmail: "請輸入有效的電子郵件地址,例如 you@example.com。",
|
|
76
|
+
invalidLogin: "電子郵件或密碼無效",
|
|
77
|
+
failedToConnect: "連線失敗。請重試。",
|
|
78
|
+
googleNeverFinished: "Google 登入未完成。請檢查 Google OAuth 重新導向 URI,以及伺服器記錄中的 [agent-native][google-oauth]。",
|
|
79
|
+
checking: "正在檢查...",
|
|
80
|
+
},
|
|
81
|
+
"es-ES": {
|
|
82
|
+
googleButton: "Iniciar sesión con Google",
|
|
83
|
+
dividerOr: "o",
|
|
84
|
+
email: "Email",
|
|
85
|
+
emailPlaceholder: "you@example.com",
|
|
86
|
+
password: "Contraseña",
|
|
87
|
+
confirmPassword: "Confirmar contraseña",
|
|
88
|
+
enterPasswordPlaceholder: "Introduce la contraseña",
|
|
89
|
+
forgotPassword: "¿Olvidaste tu contraseña?",
|
|
90
|
+
sendMagicLink: "Continuar",
|
|
91
|
+
magicLinkSent: "Revisa tu email",
|
|
92
|
+
magicLinkSentCopy: "Enviamos un enlace seguro a",
|
|
93
|
+
magicLinkFailed: "No se pudo enviar el enlace de inicio de sesión.",
|
|
94
|
+
usePasswordInstead: "Usar una contraseña",
|
|
95
|
+
backToMagicLink: "Usar un enlace de inicio de sesión",
|
|
96
|
+
signIn: "Iniciar sesión",
|
|
97
|
+
back: "Volver",
|
|
98
|
+
close: "Cerrar",
|
|
99
|
+
sending: "Enviando...",
|
|
100
|
+
signingIn: "Iniciando sesión…",
|
|
101
|
+
invalidEmail: "Introduce un email válido, como you@example.com.",
|
|
102
|
+
invalidLogin: "Email o contraseña no válidos",
|
|
103
|
+
failedToConnect: "No se pudo conectar. Inténtalo de nuevo.",
|
|
104
|
+
googleNeverFinished: "El inicio de sesión con Google no terminó. Comprueba el URI de redirección de Google OAuth y los logs del servidor para [agent-native][google-oauth].",
|
|
105
|
+
checking: "Comprobando...",
|
|
106
|
+
},
|
|
107
|
+
"fr-FR": {
|
|
108
|
+
googleButton: "Se connecter avec Google",
|
|
109
|
+
dividerOr: "ou",
|
|
110
|
+
email: "E-mail",
|
|
111
|
+
emailPlaceholder: "you@example.com",
|
|
112
|
+
password: "Mot de passe",
|
|
113
|
+
confirmPassword: "Confirmer le mot de passe",
|
|
114
|
+
enterPasswordPlaceholder: "Saisir le mot de passe",
|
|
115
|
+
forgotPassword: "Mot de passe oublié ?",
|
|
116
|
+
sendMagicLink: "Continuer",
|
|
117
|
+
magicLinkSent: "Vérifiez votre e-mail",
|
|
118
|
+
magicLinkSentCopy: "Nous avons envoyé un lien sécurisé à",
|
|
119
|
+
magicLinkFailed: "Impossible d'envoyer le lien de connexion.",
|
|
120
|
+
usePasswordInstead: "Utiliser un mot de passe",
|
|
121
|
+
backToMagicLink: "Utiliser un lien de connexion",
|
|
122
|
+
signIn: "Connexion",
|
|
123
|
+
back: "Retour",
|
|
124
|
+
close: "Fermer",
|
|
125
|
+
sending: "Envoi...",
|
|
126
|
+
signingIn: "Connexion…",
|
|
127
|
+
invalidEmail: "Saisissez une adresse e-mail valide, comme you@example.com.",
|
|
128
|
+
invalidLogin: "E-mail ou mot de passe invalide",
|
|
129
|
+
failedToConnect: "Connexion impossible. Veuillez réessayer.",
|
|
130
|
+
googleNeverFinished: "La connexion Google n'a pas abouti. Vérifiez l'URI de redirection Google OAuth et les logs serveur pour [agent-native][google-oauth].",
|
|
131
|
+
checking: "Vérification...",
|
|
132
|
+
},
|
|
133
|
+
"de-DE": {
|
|
134
|
+
googleButton: "Mit Google anmelden",
|
|
135
|
+
dividerOr: "oder",
|
|
136
|
+
email: "E-Mail",
|
|
137
|
+
emailPlaceholder: "you@example.com",
|
|
138
|
+
password: "Passwort",
|
|
139
|
+
confirmPassword: "Passwort bestätigen",
|
|
140
|
+
enterPasswordPlaceholder: "Passwort eingeben",
|
|
141
|
+
forgotPassword: "Passwort vergessen?",
|
|
142
|
+
sendMagicLink: "Weiter",
|
|
143
|
+
magicLinkSent: "Prüfe deine E-Mail",
|
|
144
|
+
magicLinkSentCopy: "Wir haben einen sicheren Anmeldelink gesendet an",
|
|
145
|
+
magicLinkFailed: "Anmeldelink konnte nicht gesendet werden.",
|
|
146
|
+
usePasswordInstead: "Stattdessen Passwort verwenden",
|
|
147
|
+
backToMagicLink: "Stattdessen Anmeldelink verwenden",
|
|
148
|
+
signIn: "Anmelden",
|
|
149
|
+
back: "Zurück",
|
|
150
|
+
close: "Schließen",
|
|
151
|
+
sending: "Senden...",
|
|
152
|
+
signingIn: "Anmeldung…",
|
|
153
|
+
invalidEmail: "Gib eine gültige E-Mail-Adresse ein, z. B. you@example.com.",
|
|
154
|
+
invalidLogin: "E-Mail oder Passwort ungültig",
|
|
155
|
+
failedToConnect: "Verbindung fehlgeschlagen. Bitte erneut versuchen.",
|
|
156
|
+
googleNeverFinished: "Die Google-Anmeldung wurde nicht abgeschlossen. Prüfe die Google-OAuth-Redirect-URI und Serverlogs für [agent-native][google-oauth].",
|
|
157
|
+
checking: "Prüfen...",
|
|
158
|
+
},
|
|
159
|
+
"ja-JP": {
|
|
160
|
+
googleButton: "Google でサインイン",
|
|
161
|
+
dividerOr: "または",
|
|
162
|
+
email: "メール",
|
|
163
|
+
emailPlaceholder: "you@example.com",
|
|
164
|
+
password: "パスワード",
|
|
165
|
+
confirmPassword: "パスワードを確認",
|
|
166
|
+
enterPasswordPlaceholder: "パスワードを入力",
|
|
167
|
+
forgotPassword: "パスワードをお忘れですか?",
|
|
168
|
+
sendMagicLink: "続行",
|
|
169
|
+
magicLinkSent: "メールを確認してください",
|
|
170
|
+
magicLinkSentCopy: "安全なサインインリンクを送信しました:",
|
|
171
|
+
magicLinkFailed: "サインインリンクを送信できませんでした。",
|
|
172
|
+
usePasswordInstead: "パスワードを使用する",
|
|
173
|
+
backToMagicLink: "サインインリンクを使用する",
|
|
174
|
+
signIn: "サインイン",
|
|
175
|
+
back: "戻る",
|
|
176
|
+
close: "閉じる",
|
|
177
|
+
sending: "送信中...",
|
|
178
|
+
signingIn: "サインイン中…",
|
|
179
|
+
invalidEmail: "you@example.com のような有効なメールアドレスを入力してください。",
|
|
180
|
+
invalidLogin: "メールまたはパスワードが正しくありません",
|
|
181
|
+
failedToConnect: "接続できませんでした。もう一度お試しください。",
|
|
182
|
+
googleNeverFinished: "Google サインインが完了しませんでした。Google OAuth リダイレクト URI と [agent-native][google-oauth] のサーバーログを確認してください。",
|
|
183
|
+
checking: "確認中...",
|
|
184
|
+
},
|
|
185
|
+
"ko-KR": {
|
|
186
|
+
googleButton: "Google로 로그인",
|
|
187
|
+
dividerOr: "또는",
|
|
188
|
+
email: "이메일",
|
|
189
|
+
emailPlaceholder: "you@example.com",
|
|
190
|
+
password: "비밀번호",
|
|
191
|
+
confirmPassword: "비밀번호 확인",
|
|
192
|
+
enterPasswordPlaceholder: "비밀번호 입력",
|
|
193
|
+
forgotPassword: "비밀번호를 잊으셨나요?",
|
|
194
|
+
sendMagicLink: "계속",
|
|
195
|
+
magicLinkSent: "이메일을 확인하세요",
|
|
196
|
+
magicLinkSentCopy: "안전한 로그인 링크를 보냈습니다:",
|
|
197
|
+
magicLinkFailed: "로그인 링크를 보낼 수 없습니다.",
|
|
198
|
+
usePasswordInstead: "비밀번호 사용",
|
|
199
|
+
backToMagicLink: "로그인 링크 사용",
|
|
200
|
+
signIn: "로그인",
|
|
201
|
+
back: "뒤로",
|
|
202
|
+
close: "닫기",
|
|
203
|
+
sending: "보내는 중...",
|
|
204
|
+
signingIn: "로그인 중…",
|
|
205
|
+
invalidEmail: "you@example.com 같은 올바른 이메일 주소를 입력하세요.",
|
|
206
|
+
invalidLogin: "이메일 또는 비밀번호가 올바르지 않습니다",
|
|
207
|
+
failedToConnect: "연결하지 못했습니다. 다시 시도하세요.",
|
|
208
|
+
googleNeverFinished: "Google 로그인이 완료되지 않았습니다. Google OAuth 리디렉션 URI와 [agent-native][google-oauth] 서버 로그를 확인하세요.",
|
|
209
|
+
checking: "확인 중...",
|
|
210
|
+
},
|
|
211
|
+
"pt-BR": {
|
|
212
|
+
googleButton: "Entrar com Google",
|
|
213
|
+
dividerOr: "ou",
|
|
214
|
+
email: "Email",
|
|
215
|
+
emailPlaceholder: "you@example.com",
|
|
216
|
+
password: "Senha",
|
|
217
|
+
confirmPassword: "Confirmar senha",
|
|
218
|
+
enterPasswordPlaceholder: "Digite a senha",
|
|
219
|
+
forgotPassword: "Esqueceu a senha?",
|
|
220
|
+
sendMagicLink: "Continuar",
|
|
221
|
+
magicLinkSent: "Confira seu email",
|
|
222
|
+
magicLinkSentCopy: "Enviamos um link seguro para",
|
|
223
|
+
magicLinkFailed: "Não foi possível enviar o link de acesso.",
|
|
224
|
+
usePasswordInstead: "Usar uma senha",
|
|
225
|
+
backToMagicLink: "Usar um link de acesso",
|
|
226
|
+
signIn: "Entrar",
|
|
227
|
+
back: "Voltar",
|
|
228
|
+
close: "Fechar",
|
|
229
|
+
sending: "Enviando...",
|
|
230
|
+
signingIn: "Entrando…",
|
|
231
|
+
invalidEmail: "Digite um email válido, como you@example.com.",
|
|
232
|
+
invalidLogin: "Email ou senha inválidos",
|
|
233
|
+
failedToConnect: "Não foi possível conectar. Tente novamente.",
|
|
234
|
+
googleNeverFinished: "O login com Google não terminou. Confira o URI de redirecionamento do Google OAuth e os logs do servidor para [agent-native][google-oauth].",
|
|
235
|
+
checking: "Verificando...",
|
|
236
|
+
},
|
|
237
|
+
"hi-IN": {
|
|
238
|
+
googleButton: "Google से साइन इन करें",
|
|
239
|
+
dividerOr: "या",
|
|
240
|
+
email: "ईमेल",
|
|
241
|
+
emailPlaceholder: "you@example.com",
|
|
242
|
+
password: "पासवर्ड",
|
|
243
|
+
confirmPassword: "पासवर्ड की पुष्टि करें",
|
|
244
|
+
enterPasswordPlaceholder: "पासवर्ड दर्ज करें",
|
|
245
|
+
forgotPassword: "पासवर्ड भूल गए?",
|
|
246
|
+
sendMagicLink: "जारी रखें",
|
|
247
|
+
magicLinkSent: "अपना ईमेल देखें",
|
|
248
|
+
magicLinkSentCopy: "हमने सुरक्षित साइन-इन लिंक यहां भेजा है:",
|
|
249
|
+
magicLinkFailed: "साइन-इन लिंक नहीं भेजा जा सका।",
|
|
250
|
+
usePasswordInstead: "पासवर्ड का उपयोग करें",
|
|
251
|
+
backToMagicLink: "साइन-इन लिंक का उपयोग करें",
|
|
252
|
+
signIn: "साइन इन",
|
|
253
|
+
back: "वापस",
|
|
254
|
+
close: "बंद करें",
|
|
255
|
+
sending: "भेजा जा रहा है...",
|
|
256
|
+
signingIn: "साइन इन हो रहा है…",
|
|
257
|
+
invalidEmail: "एक मान्य ईमेल पता दर्ज करें, जैसे you@example.com.",
|
|
258
|
+
invalidLogin: "ईमेल या पासवर्ड अमान्य है",
|
|
259
|
+
failedToConnect: "कनेक्ट नहीं हो सका। कृपया फिर कोशिश करें।",
|
|
260
|
+
googleNeverFinished: "Google साइन इन पूरा नहीं हुआ। Google OAuth redirect URI और [agent-native][google-oauth] के server logs देखें।",
|
|
261
|
+
checking: "जांच हो रही है...",
|
|
262
|
+
},
|
|
263
|
+
"ar-SA": {
|
|
264
|
+
googleButton: "تسجيل الدخول باستخدام Google",
|
|
265
|
+
dividerOr: "أو",
|
|
266
|
+
email: "البريد الإلكتروني",
|
|
267
|
+
emailPlaceholder: "you@example.com",
|
|
268
|
+
password: "كلمة المرور",
|
|
269
|
+
confirmPassword: "تأكيد كلمة المرور",
|
|
270
|
+
enterPasswordPlaceholder: "أدخل كلمة المرور",
|
|
271
|
+
forgotPassword: "هل نسيت كلمة المرور؟",
|
|
272
|
+
sendMagicLink: "متابعة",
|
|
273
|
+
magicLinkSent: "تحقق من بريدك الإلكتروني",
|
|
274
|
+
magicLinkSentCopy: "أرسلنا رابط تسجيل دخول آمنًا إلى",
|
|
275
|
+
magicLinkFailed: "تعذر إرسال رابط تسجيل الدخول.",
|
|
276
|
+
usePasswordInstead: "استخدام كلمة مرور بدلًا من ذلك",
|
|
277
|
+
backToMagicLink: "استخدام رابط تسجيل الدخول بدلًا من ذلك",
|
|
278
|
+
signIn: "تسجيل الدخول",
|
|
279
|
+
back: "رجوع",
|
|
280
|
+
close: "إغلاق",
|
|
281
|
+
sending: "جارٍ الإرسال...",
|
|
282
|
+
signingIn: "جارٍ تسجيل الدخول…",
|
|
283
|
+
invalidEmail: "أدخل بريدًا إلكترونيًا صالحًا، مثل you@example.com.",
|
|
284
|
+
invalidLogin: "البريد الإلكتروني أو كلمة المرور غير صحيحة",
|
|
285
|
+
failedToConnect: "تعذر الاتصال. حاول مرة أخرى.",
|
|
286
|
+
googleNeverFinished: "لم يكتمل تسجيل الدخول عبر Google. تحقق من URI إعادة التوجيه في Google OAuth وسجلات الخادم لـ [agent-native][google-oauth].",
|
|
287
|
+
checking: "جارٍ التحقق...",
|
|
288
|
+
},
|
|
289
|
+
};
|
|
290
|
+
export function resolveNativeAuthCopy(locale) {
|
|
291
|
+
const resolvedLocale = resolveLocaleFromCandidates([locale]);
|
|
292
|
+
return NATIVE_AUTH_COPY[resolvedLocale] ?? NATIVE_AUTH_COPY[DEFAULT_LOCALE];
|
|
293
|
+
}
|
package/dist/shared/index.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export { DISPATCH_WORKSPACE_ROOT_REDIRECTS, RESERVED_WORKSPACE_APP_IDS, assertVa
|
|
|
13
13
|
export { DEFAULT_WORKSPACE_APP_AUDIENCE, WORKSPACE_APP_AUDIENCES, normalizeWorkspaceAppAudience, normalizeWorkspaceAppPathList, workspaceAppAudienceFromEnv, workspaceAppAudienceFromPackageJson, workspaceAppRouteAccessFromEnv, workspaceAppRouteAccessFromPackageJson, type WorkspaceAppRouteAccess, type WorkspaceAppRouteAccessFromConfig, type WorkspaceAppAudience, } from "./workspace-app-audience.js";
|
|
14
14
|
export { AGENT_NATIVE_OPEN_PATH, AGENT_SIDEBAR_QUERY_PARAM, AGENT_SIDEBAR_QUERY_VALUE_CLOSED, isAgentNativeOpenDeepLink, withCollapsedAgentSidebarParam, } from "./agent-sidebar-url.js";
|
|
15
15
|
export { buildChatFirstAppCreationPrompt, titleFromChatFirstAppPrompt, type ChatFirstAppCreationPromptInput, type ChatFirstAppCreationResource, type ChatFirstAppCreationVaultAccessMode, } from "./chat-first-app-creation.js";
|
|
16
|
+
export { NATIVE_AUTH_COPY, resolveNativeAuthCopy, type NativeAuthCopy, } from "./auth-copy.js";
|
|
16
17
|
export { createPollEngine, type PollEngineOptions, type PollEngineHandle, } from "./poll-engine.js";
|
|
17
18
|
export { AGENT_NATIVE_DEFAULT_SOCIAL_IMAGE, AGENT_NATIVE_SOCIAL_IMAGE_CACHE_BUSTER, AGENT_NATIVE_SOCIAL_IMAGE_ALT, AGENT_NATIVE_SOCIAL_IMAGE_HEIGHT, AGENT_NATIVE_SOCIAL_IMAGE_PATH, AGENT_NATIVE_SOCIAL_IMAGE_TYPE, AGENT_NATIVE_SOCIAL_IMAGE_WIDTH, defaultSocialImageMeta, withAgentNativeSocialImageCacheBuster, withDefaultSocialImage, type SocialMetaDescriptor, } from "./social-meta.js";
|
|
18
19
|
export { EMBED_MODE_QUERY_PARAM, EMBED_SESSION_COOKIE, EMBED_START_PATH, EMBED_TOKEN_QUERY_PARAM, } from "./embed-auth.js";
|
package/dist/shared/index.js
CHANGED
|
@@ -13,6 +13,7 @@ export { DISPATCH_WORKSPACE_ROOT_REDIRECTS, RESERVED_WORKSPACE_APP_IDS, assertVa
|
|
|
13
13
|
export { DEFAULT_WORKSPACE_APP_AUDIENCE, WORKSPACE_APP_AUDIENCES, normalizeWorkspaceAppAudience, normalizeWorkspaceAppPathList, workspaceAppAudienceFromEnv, workspaceAppAudienceFromPackageJson, workspaceAppRouteAccessFromEnv, workspaceAppRouteAccessFromPackageJson, } from "./workspace-app-audience.js";
|
|
14
14
|
export { AGENT_NATIVE_OPEN_PATH, AGENT_SIDEBAR_QUERY_PARAM, AGENT_SIDEBAR_QUERY_VALUE_CLOSED, isAgentNativeOpenDeepLink, withCollapsedAgentSidebarParam, } from "./agent-sidebar-url.js";
|
|
15
15
|
export { buildChatFirstAppCreationPrompt, titleFromChatFirstAppPrompt, } from "./chat-first-app-creation.js";
|
|
16
|
+
export { NATIVE_AUTH_COPY, resolveNativeAuthCopy, } from "./auth-copy.js";
|
|
16
17
|
export { createPollEngine, } from "./poll-engine.js";
|
|
17
18
|
export { AGENT_NATIVE_DEFAULT_SOCIAL_IMAGE, AGENT_NATIVE_SOCIAL_IMAGE_CACHE_BUSTER, AGENT_NATIVE_SOCIAL_IMAGE_ALT, AGENT_NATIVE_SOCIAL_IMAGE_HEIGHT, AGENT_NATIVE_SOCIAL_IMAGE_PATH, AGENT_NATIVE_SOCIAL_IMAGE_TYPE, AGENT_NATIVE_SOCIAL_IMAGE_WIDTH, defaultSocialImageMeta, withAgentNativeSocialImageCacheBuster, withDefaultSocialImage, } from "./social-meta.js";
|
|
18
19
|
export { EMBED_MODE_QUERY_PARAM, EMBED_SESSION_COOKIE, EMBED_START_PATH, EMBED_TOKEN_QUERY_PARAM, } from "./embed-auth.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { resolveBuilderGatewayAuth, getBuilderProxyOrigin, } from "../server/credential-provider.js";
|
|
2
2
|
function describeError(err) {
|
|
3
3
|
if (!(err instanceof Error))
|
|
4
4
|
return String(err);
|
|
@@ -7,8 +7,8 @@ function describeError(err) {
|
|
|
7
7
|
return `${err.name}: ${err.message}${causeText}`;
|
|
8
8
|
}
|
|
9
9
|
export async function transcribeWithBuilder(opts) {
|
|
10
|
-
const
|
|
11
|
-
if (!
|
|
10
|
+
const auth = await resolveBuilderGatewayAuth();
|
|
11
|
+
if (!auth) {
|
|
12
12
|
throw new Error("Builder private key not configured. Connect your Builder.io account (free tier available) in Settings.");
|
|
13
13
|
}
|
|
14
14
|
const params = new URLSearchParams();
|
|
@@ -39,8 +39,12 @@ export async function transcribeWithBuilder(opts) {
|
|
|
39
39
|
res = await fetch(url, {
|
|
40
40
|
method: "POST",
|
|
41
41
|
headers: {
|
|
42
|
-
Authorization:
|
|
42
|
+
Authorization: auth.authorization,
|
|
43
43
|
"Content-Type": "application/octet-stream",
|
|
44
|
+
// A gateway token without a space id is rejected before any route
|
|
45
|
+
// policy is consulted, so the space id travels with every call.
|
|
46
|
+
...(auth.spaceId ? { "x-builder-api-key": auth.spaceId } : {}),
|
|
47
|
+
...(auth.userId ? { "x-builder-user-id": auth.userId } : {}),
|
|
44
48
|
},
|
|
45
49
|
body,
|
|
46
50
|
signal: controller.signal,
|
|
@@ -17,7 +17,7 @@ Declare the flag in a module both the server and the client can import, since th
|
|
|
17
17
|
|
|
18
18
|
```ts
|
|
19
19
|
// shared/feature-flags.ts
|
|
20
|
-
import { defineFeatureFlag } from "@agent-native/core/feature-flags";
|
|
20
|
+
import { defineFeatureFlag } from "@agent-native/core/feature-flags/registry";
|
|
21
21
|
|
|
22
22
|
export const FULL_APP_BUILDING = defineFeatureFlag({
|
|
23
23
|
key: "full-app-building",
|
package/docs/content/portal.mdx
CHANGED
|
@@ -47,15 +47,28 @@ the device token was rotated or the workspace moved. If Cloud is unavailable,
|
|
|
47
47
|
the run has not started - use Local or Computer instead of retrying a queued
|
|
48
48
|
cloud request.
|
|
49
49
|
|
|
50
|
+
If the connector runs and polls but every request returns `401`, and the queued
|
|
51
|
+
run is never claimed, repairing the pairing will not help. A deployment only
|
|
52
|
+
accepts device tokens minted against its own database, so a device paired
|
|
53
|
+
against one origin polls a second origin forever without ever being recognized.
|
|
54
|
+
Read `deviceId` and `relayUrl` from `~/.agent-native/remote-device.json`, then
|
|
55
|
+
request the authenticated host list from the origin `relayUrl` names. An
|
|
56
|
+
authenticated `200` whose `hosts` array does not contain that `deviceId` is the
|
|
57
|
+
mismatch - pair again from the origin the connector actually polls. Restart the
|
|
58
|
+
connector afterwards: it reads the token and relay URL once at startup and
|
|
59
|
+
caches them for the life of the process, so a running connector keeps using the
|
|
60
|
+
previous pairing.
|
|
61
|
+
|
|
50
62
|
## Environment variables
|
|
51
63
|
|
|
52
64
|
Self-hosted deployments can customize the Portal connection with:
|
|
53
65
|
|
|
54
|
-
| Variable | Purpose
|
|
55
|
-
| ------------------------------------ |
|
|
56
|
-
| `WORKSPACE_GATEWAY_URL` | Public workspace gateway used for device handoff.
|
|
57
|
-
| `AGENT_NATIVE_REMOTE_DEVICE_PATH` | Override the local device registration file path.
|
|
58
|
-
| `AGENT_NATIVE_COMPUTER_BRIDGE_URL` | Computer bridge URL used by remote execution.
|
|
59
|
-
| `AGENT_NATIVE_COMPUTER_BRIDGE_TOKEN` | Token used to authenticate with that bridge.
|
|
60
|
-
| `
|
|
61
|
-
| `
|
|
66
|
+
| Variable | Purpose |
|
|
67
|
+
| ------------------------------------ | -------------------------------------------------------------------------------------------------------------- |
|
|
68
|
+
| `WORKSPACE_GATEWAY_URL` | Public workspace gateway used for device handoff. |
|
|
69
|
+
| `AGENT_NATIVE_REMOTE_DEVICE_PATH` | Override the local device registration file path. |
|
|
70
|
+
| `AGENT_NATIVE_COMPUTER_BRIDGE_URL` | Computer bridge URL used by remote execution. |
|
|
71
|
+
| `AGENT_NATIVE_COMPUTER_BRIDGE_TOKEN` | Token used to authenticate with that bridge. |
|
|
72
|
+
| `AGENT_NATIVE_COMPUTER_CAPABILITIES` | Capabilities that bridge exposes. Required with the two above - the bridge stays off unless all three are set. |
|
|
73
|
+
| `AGENT_NATIVE_REMOTE_ENGINES` | Comma-separated remote execution engines available to the workspace. |
|
|
74
|
+
| `AGENT_NATIVE_IDENTITY_HUB_URL` | Optional Dispatch identity hub for self-hosted cross-app sign-in. |
|