@agent-native/core 0.227.0-nightly-20261110032437 → 0.227.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/dist/agent/default-agent-engine.d.ts +1 -0
- package/dist/agent/default-agent-engine.js +6 -3
- package/dist/agent/engine/builder-engine.js +10 -6
- package/dist/agent/engine/chat-model-availability.d.ts +9 -0
- package/dist/agent/engine/chat-model-availability.js +39 -0
- package/dist/agent/optional-placeholders.d.ts +1 -0
- package/dist/agent/optional-placeholders.js +3 -0
- package/dist/cli/create.js +0 -49
- package/dist/cli/index.js +1 -1
- package/dist/cli/react-router-command.js +13 -7
- package/dist/client/chat/agentkit-protocol.js +259 -200
- package/dist/client/chat/run-outcome.d.ts +48 -0
- package/dist/client/chat/run-outcome.js +50 -0
- package/dist/collab/routes.d.ts +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/deploy/build.d.ts +1 -0
- package/dist/deploy/build.js +30 -1
- package/dist/framework-package-versions.json +11 -11
- package/dist/jobs/run-now.js +9 -1
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/org/index.d.ts +1 -1
- package/dist/org/migrations.d.ts +1 -1
- package/dist/provider-api/actions/provider-api.d.ts +1 -1
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/scripts/agent-engines/list-agent-engines.js +9 -5
- package/dist/server/auth.d.ts +3 -1
- package/dist/server/auth.js +29 -9
- package/dist/server/builder-signup-experiment.d.ts +89 -42
- package/dist/server/builder-signup-experiment.js +36 -14
- package/dist/server/core-routes-plugin.js +5 -3
- package/dist/server/index.d.ts +2 -1
- package/dist/server/index.js +2 -1
- package/dist/server/onboarding-html.d.ts +2 -0
- package/dist/server/onboarding-html.js +9 -5
- package/dist/server/release-migrations.d.ts +3 -1
- package/dist/server/release-migrations.js +8 -6
- package/dist/shared/mcp-embed-headers.js +8 -2
- package/dist/templates/builder-code-starter/AGENTS.md.patch +1 -1
- package/dist/templates/builder-code-starter/server/plugins/auth.ts.patch +2 -1
- package/dist/templates/chat/AGENTS.md +1 -1
- package/dist/templates/chat/app/components/layout/Sidebar.tsx +1 -1
- package/dist/templates/chat/scripts/migrate-production.ts +1 -1
- package/dist/templates/chat/server/plugins/auth.ts +1 -0
- package/dist/templates/default/pnpm-workspace.yaml +0 -41
- package/dist/templates/default/scripts/migrate-production.ts +1 -1
- package/dist/templates/workspace-root/pnpm-workspace.yaml +0 -41
- package/dist/tracking/providers.js +20 -8
- package/dist/triggers/actions/list-automations.js +7 -1
- package/docs/content/agent-web-surfaces.mdx +54 -42
- package/docs/content/authentication.mdx +14 -0
- package/docs/content/client-agent-chat.mdx +2 -0
- package/docs/content/client-routing.mdx +2 -0
- package/docs/content/create-with-an-agent.mdx +1 -1
- package/docs/content/environment-variables.mdx +2 -0
- package/docs/content/extensions.mdx +8 -9
- package/docs/content/external-agents.mdx +8 -0
- package/docs/content/upgrading-core-ui.mdx +2 -0
- package/docs/content/vercel.mdx +2 -0
- package/package.json +4 -4
- package/src/templates/builder-code-starter/AGENTS.md.patch +1 -1
- package/src/templates/builder-code-starter/server/plugins/auth.ts.patch +2 -1
- package/src/templates/chat/AGENTS.md +1 -1
- package/src/templates/chat/app/components/layout/Sidebar.tsx +1 -1
- package/src/templates/chat/scripts/migrate-production.ts +1 -1
- package/src/templates/chat/server/plugins/auth.ts +1 -0
- package/src/templates/default/pnpm-workspace.yaml +0 -41
- package/src/templates/default/scripts/migrate-production.ts +1 -1
- package/src/templates/workspace-root/pnpm-workspace.yaml +0 -41
|
@@ -15,6 +15,54 @@ import { type AutoContinueRefusalCode } from "../../agent/auto-continue.js";
|
|
|
15
15
|
*/
|
|
16
16
|
export declare const RUN_OUTCOMES: readonly ["running", "succeeded", "stopped", "interrupted", "failed", "unverified"];
|
|
17
17
|
export type RunOutcome = (typeof RUN_OUTCOMES)[number];
|
|
18
|
+
export type ActiveRunPhase = {
|
|
19
|
+
readonly type: "streaming";
|
|
20
|
+
} | {
|
|
21
|
+
readonly type: "holdingInterruption";
|
|
22
|
+
readonly error: AgentError;
|
|
23
|
+
} | {
|
|
24
|
+
readonly type: "followingSuccessor";
|
|
25
|
+
} | {
|
|
26
|
+
readonly type: "awaitingContinuation";
|
|
27
|
+
readonly streamClosed: boolean;
|
|
28
|
+
};
|
|
29
|
+
export type RunPhase = ActiveRunPhase | {
|
|
30
|
+
readonly type: "cancelling";
|
|
31
|
+
readonly previous: ActiveRunPhase;
|
|
32
|
+
} | {
|
|
33
|
+
readonly type: "terminal";
|
|
34
|
+
} | {
|
|
35
|
+
readonly type: "disposed";
|
|
36
|
+
};
|
|
37
|
+
export type RunPhaseEvent = {
|
|
38
|
+
readonly type: "streamEnded";
|
|
39
|
+
} | {
|
|
40
|
+
readonly type: "streamFailed";
|
|
41
|
+
} | {
|
|
42
|
+
readonly type: "interrupted";
|
|
43
|
+
readonly error: AgentError;
|
|
44
|
+
} | {
|
|
45
|
+
readonly type: "followSuccessor";
|
|
46
|
+
} | {
|
|
47
|
+
readonly type: "streamOpened";
|
|
48
|
+
} | {
|
|
49
|
+
readonly type: "continuationResumed";
|
|
50
|
+
} | {
|
|
51
|
+
readonly type: "awaitContinuation";
|
|
52
|
+
readonly streamClosed: boolean;
|
|
53
|
+
} | {
|
|
54
|
+
readonly type: "terminal";
|
|
55
|
+
} | {
|
|
56
|
+
readonly type: "cancelStarted";
|
|
57
|
+
} | {
|
|
58
|
+
readonly type: "cancelSucceeded";
|
|
59
|
+
} | {
|
|
60
|
+
readonly type: "cancelFailed";
|
|
61
|
+
} | {
|
|
62
|
+
readonly type: "dispose";
|
|
63
|
+
};
|
|
64
|
+
/** Late stream and authority results cannot revive a terminal or disposed run. */
|
|
65
|
+
export declare function transition(phase: RunPhase, event: RunPhaseEvent): RunPhase;
|
|
18
66
|
/**
|
|
19
67
|
* Codes that described "the agent stopped / is stuck" one incident at a time.
|
|
20
68
|
* They survive only as telemetry detail; the user sees their outcome. A new
|
|
@@ -24,6 +24,56 @@ export const RUN_OUTCOMES = [
|
|
|
24
24
|
"failed",
|
|
25
25
|
"unverified",
|
|
26
26
|
];
|
|
27
|
+
/** Late stream and authority results cannot revive a terminal or disposed run. */
|
|
28
|
+
export function transition(phase, event) {
|
|
29
|
+
if (event.type === "dispose")
|
|
30
|
+
return { type: "disposed" };
|
|
31
|
+
if (phase.type === "disposed")
|
|
32
|
+
return phase;
|
|
33
|
+
if (phase.type === "terminal")
|
|
34
|
+
return phase;
|
|
35
|
+
if (phase.type === "cancelling") {
|
|
36
|
+
if (event.type === "cancelFailed")
|
|
37
|
+
return phase.previous;
|
|
38
|
+
if (event.type === "cancelSucceeded")
|
|
39
|
+
return { type: "terminal" };
|
|
40
|
+
return phase;
|
|
41
|
+
}
|
|
42
|
+
switch (event.type) {
|
|
43
|
+
case "streamEnded":
|
|
44
|
+
case "streamFailed":
|
|
45
|
+
return phase.type === "streaming"
|
|
46
|
+
? { type: "followingSuccessor" }
|
|
47
|
+
: phase;
|
|
48
|
+
case "interrupted":
|
|
49
|
+
return phase.type === "streaming"
|
|
50
|
+
? { type: "holdingInterruption", error: event.error }
|
|
51
|
+
: phase;
|
|
52
|
+
case "followSuccessor":
|
|
53
|
+
return phase.type === "holdingInterruption"
|
|
54
|
+
? { type: "followingSuccessor" }
|
|
55
|
+
: phase;
|
|
56
|
+
case "streamOpened":
|
|
57
|
+
return phase.type === "followingSuccessor"
|
|
58
|
+
? { type: "streaming" }
|
|
59
|
+
: phase;
|
|
60
|
+
case "continuationResumed":
|
|
61
|
+
return phase.type === "awaitingContinuation"
|
|
62
|
+
? { type: "streaming" }
|
|
63
|
+
: phase;
|
|
64
|
+
case "awaitContinuation":
|
|
65
|
+
return phase.type === "streaming"
|
|
66
|
+
? { type: "awaitingContinuation", streamClosed: event.streamClosed }
|
|
67
|
+
: phase;
|
|
68
|
+
case "terminal":
|
|
69
|
+
return { type: "terminal" };
|
|
70
|
+
case "cancelStarted":
|
|
71
|
+
return { type: "cancelling", previous: phase };
|
|
72
|
+
case "cancelSucceeded":
|
|
73
|
+
case "cancelFailed":
|
|
74
|
+
return phase;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
27
77
|
/**
|
|
28
78
|
* Codes that described "the agent stopped / is stuck" one incident at a time.
|
|
29
79
|
* They survive only as telemetry detail; the user sees their outcome. A new
|
package/dist/collab/routes.d.ts
CHANGED
|
@@ -26,8 +26,8 @@ export declare const postCollabUpdate: import("h3").EventHandlerWithFetch<import
|
|
|
26
26
|
ok: boolean;
|
|
27
27
|
}>>;
|
|
28
28
|
export declare const postCollabText: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
29
|
-
ok?: undefined;
|
|
30
29
|
text?: undefined;
|
|
30
|
+
ok?: undefined;
|
|
31
31
|
error: string;
|
|
32
32
|
} | {
|
|
33
33
|
error?: undefined;
|
|
@@ -13,9 +13,9 @@ export declare const postCollabPatch: import("h3").EventHandlerWithFetch<import(
|
|
|
13
13
|
ok: boolean;
|
|
14
14
|
}>>;
|
|
15
15
|
export declare const getCollabJson: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
16
|
-
data?: undefined;
|
|
17
16
|
error: string;
|
|
18
17
|
docId?: undefined;
|
|
18
|
+
data?: undefined;
|
|
19
19
|
} | {
|
|
20
20
|
error?: undefined;
|
|
21
21
|
docId: string;
|
package/dist/deploy/build.d.ts
CHANGED
|
@@ -186,6 +186,7 @@ export declare function cloudflareExternalBundleEntry(resolvedMod: string, neede
|
|
|
186
186
|
*/
|
|
187
187
|
export declare function patchCloudflareModuleServerOutput(serverDir: string): void;
|
|
188
188
|
export declare function bundleYjsRuntimeForServerlessOutput(serverDir: string, projectCwd: string): string[];
|
|
189
|
+
export declare function prepareVercelFunctionOutputs(outputDir: string, projectCwd: string): void;
|
|
189
190
|
export declare function shouldBundleYjsRuntimeForPreset(targetPreset: string): boolean;
|
|
190
191
|
export declare function nitroServerCodeSplittingGroupsForPreset(targetPreset: string): {
|
|
191
192
|
test: RegExp;
|
package/dist/deploy/build.js
CHANGED
|
@@ -3864,6 +3864,32 @@ export function bundleYjsRuntimeForServerlessOutput(serverDir, projectCwd) {
|
|
|
3864
3864
|
});
|
|
3865
3865
|
return bareImports;
|
|
3866
3866
|
}
|
|
3867
|
+
export function prepareVercelFunctionOutputs(outputDir, projectCwd) {
|
|
3868
|
+
const functionsDir = path.join(outputDir, "functions");
|
|
3869
|
+
if (!fs.existsSync(functionsDir))
|
|
3870
|
+
return;
|
|
3871
|
+
const visit = (dir) => {
|
|
3872
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
3873
|
+
const entryPath = path.join(dir, entry.name);
|
|
3874
|
+
if (entry.name.endsWith(".func")) {
|
|
3875
|
+
if (entry.isSymbolicLink()) {
|
|
3876
|
+
const target = fs.realpathSync(entryPath);
|
|
3877
|
+
const relative = path.relative(fs.realpathSync(functionsDir), target);
|
|
3878
|
+
if (relative.startsWith("..") || path.isAbsolute(relative)) {
|
|
3879
|
+
throw new Error(`[deploy] Vercel function link leaves output: ${entryPath}`);
|
|
3880
|
+
}
|
|
3881
|
+
fs.unlinkSync(entryPath);
|
|
3882
|
+
fs.cpSync(target, entryPath, { recursive: true });
|
|
3883
|
+
}
|
|
3884
|
+
bundleYjsRuntimeForServerlessOutput(entryPath, projectCwd);
|
|
3885
|
+
}
|
|
3886
|
+
else if (entry.isDirectory()) {
|
|
3887
|
+
visit(entryPath);
|
|
3888
|
+
}
|
|
3889
|
+
}
|
|
3890
|
+
};
|
|
3891
|
+
visit(functionsDir);
|
|
3892
|
+
}
|
|
3867
3893
|
export function shouldBundleYjsRuntimeForPreset(targetPreset) {
|
|
3868
3894
|
return (targetPreset === "netlify" ||
|
|
3869
3895
|
targetPreset === "vercel" ||
|
|
@@ -5050,7 +5076,10 @@ export default bundle;
|
|
|
5050
5076
|
sanitizeServerlessFunctionPackageManifest(nitro.options.output.serverDir);
|
|
5051
5077
|
pruneServerlessFunctionDeadWeight(nitro.options.output.serverDir);
|
|
5052
5078
|
}
|
|
5053
|
-
if (
|
|
5079
|
+
if (preset === "vercel") {
|
|
5080
|
+
prepareVercelFunctionOutputs(nitro.options.output.dir, cwd);
|
|
5081
|
+
}
|
|
5082
|
+
else if (shouldBundleYjsRuntimeForPreset(preset)) {
|
|
5054
5083
|
bundleYjsRuntimeForServerlessOutput(nitro.options.output.serverDir, cwd);
|
|
5055
5084
|
}
|
|
5056
5085
|
if (isCloudflareModulePreset(preset)) {
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
|
-
"@agent-native/agentkit": "0.227.0
|
|
2
|
+
"@agent-native/agentkit": "0.227.0",
|
|
3
3
|
"@agent-native/code-agents-ui": "0.1.75",
|
|
4
|
-
"@agent-native/core": "0.227.0
|
|
5
|
-
"@agent-native/core-corpus": "0.227.0
|
|
6
|
-
"@agent-native/creative-context": "0.8.
|
|
7
|
-
"@agent-native/dispatch": "0.42.4
|
|
4
|
+
"@agent-native/core": "0.227.0",
|
|
5
|
+
"@agent-native/core-corpus": "0.227.0",
|
|
6
|
+
"@agent-native/creative-context": "0.8.69",
|
|
7
|
+
"@agent-native/dispatch": "0.42.4",
|
|
8
8
|
"@agent-native/embedding": "0.2.0",
|
|
9
9
|
"@agent-native/migrate": "0.0.7",
|
|
10
|
-
"@agent-native/otel": "0.1.
|
|
11
|
-
"@agent-native/pinpoint": "0.1.
|
|
12
|
-
"@agent-native/recap-cli": "0.5.
|
|
13
|
-
"@agent-native/scheduling": "0.2.56
|
|
10
|
+
"@agent-native/otel": "0.1.36",
|
|
11
|
+
"@agent-native/pinpoint": "0.1.112",
|
|
12
|
+
"@agent-native/recap-cli": "0.5.100",
|
|
13
|
+
"@agent-native/scheduling": "0.2.56",
|
|
14
14
|
"@agent-native/shared-app-config": "0.1.2",
|
|
15
|
-
"@agent-native/skills": "0.4.4
|
|
16
|
-
"@agent-native/toolkit": "0.227.0
|
|
15
|
+
"@agent-native/skills": "0.4.4",
|
|
16
|
+
"@agent-native/toolkit": "0.227.0"
|
|
17
17
|
}
|
package/dist/jobs/run-now.js
CHANGED
|
@@ -4,7 +4,7 @@ import { canQueueAutomationRunNow, } from "../automations/service.js";
|
|
|
4
4
|
import { isLocalDatabase } from "../db/client.js";
|
|
5
5
|
import { organizationResourceOwner, resourceGetByPath, } from "../resources/store.js";
|
|
6
6
|
import { fireInternalDispatch } from "../server/self-dispatch.js";
|
|
7
|
-
import { parseJobResource } from "./frontmatter.js";
|
|
7
|
+
import { isRecoveredFactoryJob, jobBelongsToApp, parseJobResource, } from "./frontmatter.js";
|
|
8
8
|
import { automationRunOwnership } from "./run-history-ownership.js";
|
|
9
9
|
import { listUnclaimedAutomationRuns, startAutomationRun, } from "./run-history.js";
|
|
10
10
|
async function dispatchAutomationRun(historyId, requestHeaders) {
|
|
@@ -113,6 +113,14 @@ export async function authorizeAutomationRunNow(input) {
|
|
|
113
113
|
});
|
|
114
114
|
}
|
|
115
115
|
if (!(await canQueueAutomationRunNow(input, access.resource, access.scope, input.additionalJobAppIds))) {
|
|
116
|
+
const { meta } = parseJobResource(access.resource.content);
|
|
117
|
+
if (!jobBelongsToApp(meta, input.appId, input.additionalJobAppIds) &&
|
|
118
|
+
!isRecoveredFactoryJob(meta, access.resource.path, input.appId, access.resource.owner)) {
|
|
119
|
+
const ownerAppId = meta.appId?.trim();
|
|
120
|
+
throw Object.assign(new Error(ownerAppId
|
|
121
|
+
? `This automation belongs to the "${ownerAppId}" app. Run it from that app.`
|
|
122
|
+
: "This automation has no app owner and cannot be run."), { statusCode: 403 });
|
|
123
|
+
}
|
|
116
124
|
throw Object.assign(new Error("Collaborate access is required to run this automation."), { statusCode: 403 });
|
|
117
125
|
}
|
|
118
126
|
return access;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
export declare function createNotificationsHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<"" | import("./types.js").Notification[] | {
|
|
2
|
-
error?: undefined;
|
|
3
2
|
count: number;
|
|
4
3
|
updated?: undefined;
|
|
4
|
+
error?: undefined;
|
|
5
5
|
ok?: undefined;
|
|
6
6
|
} | {
|
|
7
|
-
error?: undefined;
|
|
8
7
|
count?: undefined;
|
|
9
8
|
updated: number;
|
|
9
|
+
error?: undefined;
|
|
10
10
|
ok?: undefined;
|
|
11
11
|
} | {
|
|
12
12
|
count?: undefined;
|
|
@@ -14,8 +14,8 @@ export declare function createNotificationsHandler(): import("h3").EventHandlerW
|
|
|
14
14
|
error: string;
|
|
15
15
|
ok?: undefined;
|
|
16
16
|
} | {
|
|
17
|
-
error?: undefined;
|
|
18
17
|
count?: undefined;
|
|
19
18
|
updated?: undefined;
|
|
19
|
+
error?: undefined;
|
|
20
20
|
ok: boolean;
|
|
21
21
|
}>>;
|
package/dist/org/index.d.ts
CHANGED
|
@@ -180,9 +180,9 @@ export declare const getMyOrgHandler: import("h3").EventHandlerWithFetch<import(
|
|
|
180
180
|
soloDeploymentAdmin: boolean | undefined;
|
|
181
181
|
}>>;
|
|
182
182
|
export declare const createOrgHandler: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
183
|
-
id?: undefined;
|
|
184
183
|
name?: undefined;
|
|
185
184
|
success: boolean;
|
|
185
|
+
id?: undefined;
|
|
186
186
|
role?: undefined;
|
|
187
187
|
} | {
|
|
188
188
|
success?: undefined;
|
package/dist/org/migrations.d.ts
CHANGED
|
@@ -316,8 +316,8 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
|
|
|
316
316
|
notes?: string | undefined;
|
|
317
317
|
scope?: "org" | "user" | undefined;
|
|
318
318
|
}, {
|
|
319
|
-
provider?: undefined;
|
|
320
319
|
id?: undefined;
|
|
320
|
+
provider?: undefined;
|
|
321
321
|
message?: undefined;
|
|
322
322
|
providers: {
|
|
323
323
|
id: string;
|
|
@@ -49,7 +49,6 @@ export declare function handleUploadResource(event: any): Promise<import("./stor
|
|
|
49
49
|
error: string;
|
|
50
50
|
storageSetupRequired?: undefined;
|
|
51
51
|
} | {
|
|
52
|
-
error?: undefined;
|
|
53
52
|
id: string;
|
|
54
53
|
path: string;
|
|
55
54
|
owner: string;
|
|
@@ -64,6 +63,7 @@ export declare function handleUploadResource(event: any): Promise<import("./stor
|
|
|
64
63
|
runId: string | null;
|
|
65
64
|
expiresAt: number | null;
|
|
66
65
|
metadata: string | null;
|
|
66
|
+
error?: undefined;
|
|
67
67
|
url: string;
|
|
68
68
|
provider: string;
|
|
69
69
|
storageSetupRequired?: undefined;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getAgentAppModelDefaultForCurrentRequest } from "../../agent/app-model-defaults.js";
|
|
2
2
|
import { CHATGPT_SUBSCRIPTION_ENGINE_NAME } from "../../agent/chatgpt-subscription-contract.js";
|
|
3
|
-
import { readDefaultAgentEngineSettingDetailed, resolveDefaultAgentEngineAuthority, } from "../../agent/default-agent-engine.js";
|
|
3
|
+
import { isDefaultAgentEngineScopeResolved, readDefaultAgentEngineSettingDetailed, resolveDefaultAgentEngineAuthority, } from "../../agent/default-agent-engine.js";
|
|
4
4
|
import { listChatGPTSubscriptionModels } from "../../agent/engine/chatgpt-subscription-engine.js";
|
|
5
5
|
import { listAgentEngines, registerBuiltinEngines, detectEngineFromEnv, detectEngineFromUserSecrets, getAgentEngineEntry, isAgentEnginePackageInstalled, isStoredEngineUsableForRequest, normalizeModelForEngine, resolveEngineAcceptsCustomModels, resolveEnginePreservesCustomModels, } from "../../agent/engine/index.js";
|
|
6
6
|
import { applyProviderModelSelection, providerForEngineName, resolveEffectiveProviderModelSelection, } from "../../agent/provider-model-selection.js";
|
|
@@ -101,10 +101,14 @@ export async function run(args = {}) {
|
|
|
101
101
|
}
|
|
102
102
|
return pending;
|
|
103
103
|
};
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
104
|
+
// An unresolved scope cannot say which default applies. Listing engines
|
|
105
|
+
// must still work, so the read is skipped and reported as "unresolved"
|
|
106
|
+
// instead of "none", which would claim no default is saved.
|
|
107
|
+
const defaultAuthority = await resolveDefaultAgentEngineAuthority();
|
|
108
|
+
const scopeUnresolved = !isDefaultAgentEngineScopeResolved();
|
|
109
|
+
const defaultSetting = scopeUnresolved
|
|
110
|
+
? { value: null, source: "unresolved" }
|
|
111
|
+
: await readDefaultAgentEngineSettingDetailed();
|
|
108
112
|
const current = defaultSetting.value
|
|
109
113
|
? defaultSetting.value
|
|
110
114
|
: null;
|
package/dist/server/auth.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ import type { GoogleAuthMode } from "./google-auth-mode.js";
|
|
|
9
9
|
import { type OnboardingHtmlOptions } from "./onboarding-html.js";
|
|
10
10
|
import { isSessionResolutionUnavailable } from "./session-resolution-unavailable.js";
|
|
11
11
|
export declare function getSessionMaxAge(): number;
|
|
12
|
-
export declare function recordBuilderSignupBinding(event: H3Event, attemptId: unknown, method: "password" | "magic-link" | "google", email: string): Promise<void>;
|
|
12
|
+
export declare function recordBuilderSignupBinding(event: H3Event, attemptId: unknown, method: "password" | "magic-link" | "google", email: string, verifiedSession?: AuthSession): Promise<void>;
|
|
13
13
|
export interface AuthSession {
|
|
14
14
|
email: string;
|
|
15
15
|
userId?: string;
|
|
@@ -94,6 +94,8 @@ export interface AuthOptions {
|
|
|
94
94
|
* fallback markup, which the auth client script replaces in the browser.
|
|
95
95
|
*/
|
|
96
96
|
renderSignInPage?: (props: AuthPageProps) => string | undefined;
|
|
97
|
+
/** Trusted HTML appended to the sign-in document head. */
|
|
98
|
+
authHeadHtml?: string;
|
|
97
99
|
renderResetPasswordPage?: (props: ResetPasswordPageProps) => string | undefined;
|
|
98
100
|
rootAuth?: boolean;
|
|
99
101
|
googleOnly?: boolean;
|
package/dist/server/auth.js
CHANGED
|
@@ -12,7 +12,7 @@ import { FIRST_RUN_ONBOARDING_COOKIE, FIRST_RUN_ONBOARDING_MAX_AGE, } from "../s
|
|
|
12
12
|
import { FIRST_TOUCH_SERVER_PATH } from "../shared/first-touch-persistence.js";
|
|
13
13
|
import { isGoogleProfileImageUrl } from "../shared/google-profile-image.js";
|
|
14
14
|
import { corsAllowHeadersFor, EMBED_TRANSPLANT_HEADER, isExplicitCorsAllowedOrigin, isMcpEmbedCorsOrigin, MCP_EMBED_CORS_ALLOW_HEADERS, shouldAllowMcpEmbedCredentials, } from "../shared/mcp-embed-headers.js";
|
|
15
|
-
import { bindBuilderSignupAttempt, builderSignupAssignmentCookieName, } from "./builder-signup-experiment.js";
|
|
15
|
+
import { bindBuilderSignupAttempt, startBuilderSignupForVerifiedSession, builderSignupAssignmentCookieName, } from "./builder-signup-experiment.js";
|
|
16
16
|
import { createConsentHandler, createConsentRegionHandler, requestAllowsConsentCategory, } from "./consent-route.js";
|
|
17
17
|
import { readDevActionDiscoveryFile } from "./dev-action-discovery.js";
|
|
18
18
|
import { devLoopbackAuthHint } from "./dev-origin-hint.js";
|
|
@@ -155,12 +155,24 @@ function requestWithSignupAttribution(request, signupAttribution) {
|
|
|
155
155
|
function headersWithSignupAttribution(headers, cookieHeader) {
|
|
156
156
|
return addSignupAttributionHeader(headers, signupAttributionContextFromCookieHeader(cookieHeader));
|
|
157
157
|
}
|
|
158
|
-
export async function recordBuilderSignupBinding(event, attemptId, method, email) {
|
|
158
|
+
export async function recordBuilderSignupBinding(event, attemptId, method, email, verifiedSession) {
|
|
159
159
|
if (typeof attemptId !== "string" &&
|
|
160
160
|
!getCookie(event, builderSignupAssignmentCookieName()))
|
|
161
161
|
return;
|
|
162
162
|
try {
|
|
163
|
-
await bindBuilderSignupAttempt(event, attemptId, method, email);
|
|
163
|
+
const bound = await bindBuilderSignupAttempt(event, attemptId, method, email);
|
|
164
|
+
if (bound &&
|
|
165
|
+
verifiedSession?.emailVerified === true &&
|
|
166
|
+
verifiedSession.token &&
|
|
167
|
+
verifiedSession.email.trim().toLowerCase() === email.trim().toLowerCase()) {
|
|
168
|
+
// The callback just issued this session; its cookie is in the response,
|
|
169
|
+
// not the incoming request. Org/credential checks must see that identity.
|
|
170
|
+
const signupSession = { ...verifiedSession, userId: bound.userId };
|
|
171
|
+
event.context.__anSessionCache = Promise.resolve(signupSession);
|
|
172
|
+
delete event.context.__anOrgContextCache;
|
|
173
|
+
markRequestIdentityAuthenticatedAtMs(event, verifiedSession.email, Date.now(), verifiedSession.token);
|
|
174
|
+
await startBuilderSignupForVerifiedSession(event, signupSession);
|
|
175
|
+
}
|
|
164
176
|
}
|
|
165
177
|
catch (error) {
|
|
166
178
|
captureAuthError(error, { route: "signup", email });
|
|
@@ -1862,6 +1874,7 @@ function getOnboardingHtmlOptions(options, event, rawPath, authMode) {
|
|
|
1862
1874
|
signupLegalNotice: options.signupLegalNotice,
|
|
1863
1875
|
googleAuthMode: options.googleAuthMode,
|
|
1864
1876
|
renderSignInPage: options.renderSignInPage,
|
|
1877
|
+
authHeadHtml: options.authHeadHtml,
|
|
1865
1878
|
requestHost: event ? getRequestHost(event) : undefined,
|
|
1866
1879
|
requestPath: rawPath,
|
|
1867
1880
|
requestOrigin: event ? getOrigin(event) : undefined,
|
|
@@ -4420,15 +4433,16 @@ async function mountBetterAuthRoutes(app, options) {
|
|
|
4420
4433
|
console.warn("[auth] failed to store Google profile image:", error);
|
|
4421
4434
|
});
|
|
4422
4435
|
}
|
|
4436
|
+
const signupUserId = isNewGoogleUser
|
|
4437
|
+
? await getBetterAuthUserIdForEmail(email)
|
|
4438
|
+
: undefined;
|
|
4423
4439
|
const { sessionToken } = await createOAuthSession(event, email, {
|
|
4424
4440
|
hasProductionSession: false,
|
|
4425
4441
|
desktop,
|
|
4426
4442
|
mobile,
|
|
4427
4443
|
trackSignup: {
|
|
4428
4444
|
authProvider: "google",
|
|
4429
|
-
canonicalAuthUserId:
|
|
4430
|
-
? await getBetterAuthUserIdForEmail(email)
|
|
4431
|
-
: undefined,
|
|
4445
|
+
...(signupUserId ? { canonicalAuthUserId: signupUserId } : {}),
|
|
4432
4446
|
name: typeof user.name === "string" ? user.name : undefined,
|
|
4433
4447
|
attribution: signupAttribution,
|
|
4434
4448
|
signupAnonymousId,
|
|
@@ -4437,8 +4451,14 @@ async function mountBetterAuthRoutes(app, options) {
|
|
|
4437
4451
|
isNewUser: isNewGoogleUser,
|
|
4438
4452
|
},
|
|
4439
4453
|
});
|
|
4440
|
-
if (isNewGoogleUser)
|
|
4441
|
-
await recordBuilderSignupBinding(event, builderSignupAttemptId, "google", email
|
|
4454
|
+
if (isNewGoogleUser) {
|
|
4455
|
+
await recordBuilderSignupBinding(event, builderSignupAttemptId, "google", email, {
|
|
4456
|
+
email,
|
|
4457
|
+
...(sessionToken ? { token: sessionToken } : {}),
|
|
4458
|
+
...(typeof user.name === "string" ? { name: user.name } : {}),
|
|
4459
|
+
emailVerified: true,
|
|
4460
|
+
});
|
|
4461
|
+
}
|
|
4442
4462
|
logGoogleOAuthDebug(event, "callback-session-created", {
|
|
4443
4463
|
flowId,
|
|
4444
4464
|
desktop,
|
|
@@ -5418,7 +5438,7 @@ async function mountBetterAuthRoutes(app, options) {
|
|
|
5418
5438
|
: query.return;
|
|
5419
5439
|
const signupSession = await getSession(event);
|
|
5420
5440
|
if (signupSession?.emailVerified)
|
|
5421
|
-
await recordBuilderSignupBinding(event, query.builder_signup_attempt, "magic-link", signupSession.email);
|
|
5441
|
+
await recordBuilderSignupBinding(event, query.builder_signup_attempt, "magic-link", signupSession.email, signupSession);
|
|
5422
5442
|
setFirstRunOnboardingCookie(event);
|
|
5423
5443
|
return queryEchoSafeRedirect(event, redirectWithStagedCookies(event, safeReturnPath(rawReturn), 302));
|
|
5424
5444
|
}));
|
|
@@ -31,13 +31,18 @@ export declare function builderSignupAssignmentCookieName(): string;
|
|
|
31
31
|
export declare function encodeBuilderSignupAssignment(assignment: Assignment): string;
|
|
32
32
|
export declare function decodeBuilderSignupAssignment(value: string | undefined): Assignment | null;
|
|
33
33
|
export declare function isBuilderSignupExperimentEnabled(): boolean;
|
|
34
|
-
export declare function bindBuilderSignupAttempt(event: H3Event, attemptId: unknown, method: "password" | "magic-link" | "google", email: string): Promise<
|
|
34
|
+
export declare function bindBuilderSignupAttempt(event: H3Event, attemptId: unknown, method: "password" | "magic-link" | "google", email: string): Promise<{
|
|
35
|
+
userId: string;
|
|
36
|
+
} | false>;
|
|
35
37
|
export declare function getBuilderSignupConnectError(userId: string | undefined): Promise<{
|
|
36
38
|
code: "account_exists";
|
|
37
39
|
message: string;
|
|
38
40
|
at: number;
|
|
39
41
|
} | undefined>;
|
|
40
|
-
export declare function
|
|
42
|
+
export declare function setBuilderSignupVerifiedStarter(starter: (event: H3Event, session: AuthSession) => Promise<unknown>): void;
|
|
43
|
+
/** Called only after the auth provider issued this verified signup's session. */
|
|
44
|
+
export declare function startBuilderSignupForVerifiedSession(event: H3Event, session: AuthSession): Promise<void>;
|
|
45
|
+
export declare function createBuilderSignupExperiment(dependencies: {
|
|
41
46
|
getSession: (event: H3Event) => Promise<AuthSession | null>;
|
|
42
47
|
sameOrigin: (event: H3Event) => boolean;
|
|
43
48
|
activate: (event: H3Event, session: AuthSession, owner: {
|
|
@@ -53,44 +58,86 @@ export declare function createBuilderSignupExperimentHandler(dependencies: {
|
|
|
53
58
|
attempt: string;
|
|
54
59
|
startedAt: number;
|
|
55
60
|
}) => Promise<boolean>;
|
|
56
|
-
}):
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
61
|
+
}): {
|
|
62
|
+
handler: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
63
|
+
status: "connected" | "fallback";
|
|
64
|
+
code?: string | undefined;
|
|
65
|
+
} | {
|
|
66
|
+
status: "unavailable";
|
|
67
|
+
code: string;
|
|
68
|
+
} | {
|
|
69
|
+
status: "disabled";
|
|
70
|
+
code?: undefined;
|
|
71
|
+
} | {
|
|
72
|
+
id: string;
|
|
73
|
+
variant: "automatic" | "control";
|
|
74
|
+
issuedAt: number;
|
|
75
|
+
acceptedAt?: number | undefined;
|
|
76
|
+
attemptId?: string | undefined;
|
|
77
|
+
method?: "google" | "magic-link" | "password" | undefined;
|
|
78
|
+
email?: string | undefined;
|
|
79
|
+
policy: "builder-signup-2026-11-06";
|
|
80
|
+
status: "assigned";
|
|
81
|
+
experimentId: string;
|
|
82
|
+
code?: undefined;
|
|
83
|
+
} | {
|
|
84
|
+
status: "disabled";
|
|
85
|
+
code: string;
|
|
86
|
+
} | {
|
|
87
|
+
code?: undefined;
|
|
88
|
+
status: "pending";
|
|
89
|
+
} | {
|
|
90
|
+
code?: undefined;
|
|
91
|
+
status: "eligible";
|
|
92
|
+
} | {
|
|
93
|
+
code?: undefined;
|
|
94
|
+
status: "not_required";
|
|
95
|
+
} | {
|
|
96
|
+
code?: undefined;
|
|
97
|
+
status: "accepted";
|
|
98
|
+
} | {
|
|
99
|
+
status: "pending";
|
|
100
|
+
code: string;
|
|
101
|
+
}>>;
|
|
102
|
+
startVerifiedSignup: (event: H3Event, session: AuthSession) => Promise<{
|
|
103
|
+
status: "connected" | "fallback";
|
|
104
|
+
code?: string | undefined;
|
|
105
|
+
} | {
|
|
106
|
+
status: "unavailable";
|
|
107
|
+
code: string;
|
|
108
|
+
} | {
|
|
109
|
+
status: "disabled";
|
|
110
|
+
code?: undefined;
|
|
111
|
+
} | {
|
|
112
|
+
id: string;
|
|
113
|
+
variant: "automatic" | "control";
|
|
114
|
+
issuedAt: number;
|
|
115
|
+
acceptedAt?: number | undefined;
|
|
116
|
+
attemptId?: string | undefined;
|
|
117
|
+
method?: "google" | "magic-link" | "password" | undefined;
|
|
118
|
+
email?: string | undefined;
|
|
119
|
+
policy: "builder-signup-2026-11-06";
|
|
120
|
+
status: "assigned";
|
|
121
|
+
experimentId: string;
|
|
122
|
+
code?: undefined;
|
|
123
|
+
} | {
|
|
124
|
+
status: "disabled";
|
|
125
|
+
code: string;
|
|
126
|
+
} | {
|
|
127
|
+
code?: undefined;
|
|
128
|
+
status: "pending";
|
|
129
|
+
} | {
|
|
130
|
+
code?: undefined;
|
|
131
|
+
status: "eligible";
|
|
132
|
+
} | {
|
|
133
|
+
code?: undefined;
|
|
134
|
+
status: "not_required";
|
|
135
|
+
} | {
|
|
136
|
+
code?: undefined;
|
|
137
|
+
status: "accepted";
|
|
138
|
+
} | {
|
|
139
|
+
status: "pending";
|
|
140
|
+
code: string;
|
|
141
|
+
}>;
|
|
142
|
+
};
|
|
96
143
|
export {};
|