@chainingintention/pi-web-cn 1.202607.11 → 1.202608.2
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/README.md +9 -9
- package/dist/cli.js +27 -12
- package/dist/cli.js.map +1 -1
- package/dist/client/assets/{CodeViewer-WeDkBH1U.js → CodeViewer-j37b7YHz.js} +1 -1
- package/dist/client/assets/{TerminalPanel-DgiIksV-.js → TerminalPanel-DqDiXDrk.js} +5 -5
- package/dist/client/assets/{UnifiedDiffViewer-FKeWfK-h.js → UnifiedDiffViewer-AQTSNI1y.js} +1 -1
- package/dist/client/assets/index-DDuQX9_Y.js +4101 -0
- package/dist/client/index.html +1 -1
- package/dist/config.js +36 -0
- package/dist/config.js.map +1 -1
- package/dist/nativeServices/servicePlan.js +3 -2
- package/dist/nativeServices/servicePlan.js.map +1 -1
- package/dist/nativeServices/serviceProbe.js +7 -5
- package/dist/nativeServices/serviceProbe.js.map +1 -1
- package/dist/pi-web-plugins/info/infoInternals.js +223 -0
- package/dist/pi-web-plugins/info/pi-web-plugin.js +19 -22
- package/dist/pi-web-plugins/relays/markdownDocument.js +81 -0
- package/dist/pi-web-plugins/relays/package.json +9 -0
- package/dist/pi-web-plugins/relays/pi-web-plugin.js +44 -0
- package/dist/pi-web-plugins/relays/relayDiscovery.js +96 -0
- package/dist/pi-web-plugins/relays/relaysPanelElement.js +327 -0
- package/dist/pi-web-plugins/relays/vendor/README.md +24 -0
- package/dist/pi-web-plugins/relays/vendor/marked.esm.js +76 -0
- package/dist/pi-web-plugins/updates/pi-web-plugin.js +100 -100
- package/dist/pi-web-plugins/updates/updatesLogic.js +8 -5
- package/dist/plugin-api.d.ts +5 -1
- package/dist/server/configRoutes.js +11 -0
- package/dist/server/configRoutes.js.map +1 -1
- package/dist/server/diagnostics/nodePtyNativeModule.js +36 -0
- package/dist/server/diagnostics/nodePtyNativeModule.js.map +1 -0
- package/dist/server/git/gitService.js +176 -5
- package/dist/server/git/gitService.js.map +1 -1
- package/dist/server/piWebStatus.js +7 -4
- package/dist/server/piWebStatus.js.map +1 -1
- package/dist/server/realtime/sessionEventHub.js +16 -2
- package/dist/server/realtime/sessionEventHub.js.map +1 -1
- package/dist/server/sessiond/sessionDaemonStartup.js +0 -42
- package/dist/server/sessiond/sessionDaemonStartup.js.map +1 -1
- package/dist/server/sessiond/sessionServiceDependencies.js +31 -0
- package/dist/server/sessiond/sessionServiceDependencies.js.map +1 -0
- package/dist/server/sessions/askUserTool.js +105 -0
- package/dist/server/sessions/askUserTool.js.map +1 -0
- package/dist/server/sessions/authProviderOptions.js +26 -29
- package/dist/server/sessions/authProviderOptions.js.map +1 -1
- package/dist/server/sessions/authRoutes.js +9 -1
- package/dist/server/sessions/authRoutes.js.map +1 -1
- package/dist/server/sessions/authService.js +143 -33
- package/dist/server/sessions/authService.js.map +1 -1
- package/dist/server/sessions/globalProviderPolicy.js +167 -0
- package/dist/server/sessions/globalProviderPolicy.js.map +1 -0
- package/dist/server/sessions/modelCatalogRefresher.js +192 -0
- package/dist/server/sessions/modelCatalogRefresher.js.map +1 -0
- package/dist/server/sessions/oauthLoginFlowService.js +181 -56
- package/dist/server/sessions/oauthLoginFlowService.js.map +1 -1
- package/dist/server/sessions/parentSessionLocator.js +75 -0
- package/dist/server/sessions/parentSessionLocator.js.map +1 -0
- package/dist/server/sessions/pendingAskStore.js +278 -0
- package/dist/server/sessions/pendingAskStore.js.map +1 -0
- package/dist/server/sessions/piSessionService.js +1264 -199
- package/dist/server/sessions/piSessionService.js.map +1 -1
- package/dist/server/sessions/plainTextTheme.js +112 -0
- package/dist/server/sessions/plainTextTheme.js.map +1 -0
- package/dist/server/sessions/projectAuthService.js +3 -3
- package/dist/server/sessions/projectAuthService.js.map +1 -1
- package/dist/server/sessions/sessionCommandService.js +60 -5
- package/dist/server/sessions/sessionCommandService.js.map +1 -1
- package/dist/server/sessions/sessionFileHeader.js +45 -0
- package/dist/server/sessions/sessionFileHeader.js.map +1 -0
- package/dist/server/sessions/sessionNotificationStore.js +484 -0
- package/dist/server/sessions/sessionNotificationStore.js.map +1 -0
- package/dist/server/sessions/sessionRoutes.js +245 -1
- package/dist/server/sessions/sessionRoutes.js.map +1 -1
- package/dist/server/sessions/sessionTreeProjection.js +250 -0
- package/dist/server/sessions/sessionTreeProjection.js.map +1 -0
- package/dist/server/sessions/sessionUnreadStore.js +520 -0
- package/dist/server/sessions/sessionUnreadStore.js.map +1 -0
- package/dist/server/sessions/spawnSubsessionTool.js +10 -12
- package/dist/server/sessions/spawnSubsessionTool.js.map +1 -1
- package/dist/server/sessions/spawnTargetResolver.js +3 -16
- package/dist/server/sessions/spawnTargetResolver.js.map +1 -1
- package/dist/server/terminals/terminalService.js +8 -2
- package/dist/server/terminals/terminalService.js.map +1 -1
- package/dist/server/workspaces/gitWorktreeDiscovery.js +9 -0
- package/dist/server/workspaces/gitWorktreeDiscovery.js.map +1 -1
- package/dist/server/workspaces/projectWorkspaceCwds.js +22 -0
- package/dist/server/workspaces/projectWorkspaceCwds.js.map +1 -0
- package/dist/server/workspaces/workspaceService.js +15 -2
- package/dist/server/workspaces/workspaceService.js.map +1 -1
- package/dist/shared/activity.js +9 -1
- package/dist/shared/activity.js.map +1 -1
- package/dist/shared/apiTypes.d.ts +403 -8
- package/dist/shared/apiTypes.js +26 -0
- package/dist/shared/apiTypes.js.map +1 -1
- package/dist/shared/capabilities.js +9 -0
- package/dist/shared/capabilities.js.map +1 -1
- package/dist/shared/federatedRoutes.js +12 -0
- package/dist/shared/federatedRoutes.js.map +1 -1
- package/docs/config.md +76 -9
- package/docs/plugins.md +72 -16
- package/install.sh +1 -1
- package/package.json +4 -2
- package/dist/client/assets/index-kgpXTDyy.js +0 -3247
- package/dist/server/sessions/sessionArchiveMigration.js +0 -590
- package/dist/server/sessions/sessionArchiveMigration.js.map +0 -1
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { Type } from "typebox";
|
|
2
|
+
import { defineTool } from "@earendil-works/pi-coding-agent";
|
|
3
|
+
import { ASK_USER_ID_MAX_LENGTH, ASK_USER_OPTION_LIMIT, ASK_USER_QUESTION_LIMIT, ASK_USER_TEXT_MAX_LENGTH, } from "../../shared/apiTypes.js";
|
|
4
|
+
import { renderSupersededAskText } from "./pendingAskStore.js";
|
|
5
|
+
const AskUserOptionParams = Type.Object({
|
|
6
|
+
value: Type.String({
|
|
7
|
+
maxLength: ASK_USER_ID_MAX_LENGTH,
|
|
8
|
+
description: "Stable machine value reported back to you when the user picks this option.",
|
|
9
|
+
}),
|
|
10
|
+
label: Type.String({
|
|
11
|
+
maxLength: ASK_USER_TEXT_MAX_LENGTH,
|
|
12
|
+
description: "Short label the user reads, ideally a few words.",
|
|
13
|
+
}),
|
|
14
|
+
detail: Type.Optional(Type.String({
|
|
15
|
+
maxLength: ASK_USER_TEXT_MAX_LENGTH,
|
|
16
|
+
description: "Optional clarification shown under the label.",
|
|
17
|
+
})),
|
|
18
|
+
});
|
|
19
|
+
const AskUserQuestionParams = Type.Object({
|
|
20
|
+
id: Type.String({
|
|
21
|
+
maxLength: ASK_USER_ID_MAX_LENGTH,
|
|
22
|
+
description: "Unique within this call; used as the answer key reported back to you.",
|
|
23
|
+
}),
|
|
24
|
+
question: Type.String({
|
|
25
|
+
maxLength: ASK_USER_TEXT_MAX_LENGTH,
|
|
26
|
+
description: "The question itself, as one plain-text line.",
|
|
27
|
+
}),
|
|
28
|
+
detail: Type.Optional(Type.String({
|
|
29
|
+
maxLength: ASK_USER_TEXT_MAX_LENGTH,
|
|
30
|
+
description: "Optional supporting context shown under the question.",
|
|
31
|
+
})),
|
|
32
|
+
options: Type.Optional(Type.Array(AskUserOptionParams, {
|
|
33
|
+
maxItems: ASK_USER_OPTION_LIMIT,
|
|
34
|
+
description: "Options to choose from. Omit when free text is the whole answer; the browser always adds a Custom choice.",
|
|
35
|
+
})),
|
|
36
|
+
multiple: Type.Optional(Type.Boolean({
|
|
37
|
+
description: "Allow several options at once. Default: one answer per question.",
|
|
38
|
+
})),
|
|
39
|
+
});
|
|
40
|
+
const AskUserParams = Type.Object({
|
|
41
|
+
questions: Type.Array(AskUserQuestionParams, {
|
|
42
|
+
minItems: 1,
|
|
43
|
+
maxItems: ASK_USER_QUESTION_LIMIT,
|
|
44
|
+
description: "The questions to post, in the order the user should read them. Every question may be left unanswered.",
|
|
45
|
+
}),
|
|
46
|
+
});
|
|
47
|
+
/** Shapes one schema question into the domain question; the store owns validation. */
|
|
48
|
+
function toQuestion(param) {
|
|
49
|
+
const { detail, options, multiple } = param;
|
|
50
|
+
return {
|
|
51
|
+
id: param.id,
|
|
52
|
+
question: param.question,
|
|
53
|
+
...(detail === undefined ? {} : { detail }),
|
|
54
|
+
options: (options ?? []).map(toOption),
|
|
55
|
+
// Keep the compatibility marker on the daemon wire even though the model no
|
|
56
|
+
// longer chooses whether a question accepts a custom answer.
|
|
57
|
+
allowOther: true,
|
|
58
|
+
...(multiple === undefined ? {} : { multiple }),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
function toOption(param) {
|
|
62
|
+
const { detail } = param;
|
|
63
|
+
return { value: param.value, label: param.label, ...(detail === undefined ? {} : { detail }) };
|
|
64
|
+
}
|
|
65
|
+
function postedText(result) {
|
|
66
|
+
const count = result.ask.questions.length;
|
|
67
|
+
const posted = `Posted ${count.toString()} question${count === 1 ? "" : "s"} to the user as ask ${result.ask.askId}. Ending this run; the answers arrive as a follow-up message that wakes you, naming every question the user left unanswered. Do not repost these questions.`;
|
|
68
|
+
return result.superseded === undefined ? posted : `${posted}\n\n${renderSupersededAskText(result.superseded)}`;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Custom tool that posts a question set to the user's browser as interactive UI.
|
|
72
|
+
*
|
|
73
|
+
* It deliberately does **not** await the user. Awaiting would pin the agent run
|
|
74
|
+
* for an unbounded human-scale wait, keep the session streaming, and leave a
|
|
75
|
+
* dangling tool call if the runtime were replaced meanwhile. Instead the ask
|
|
76
|
+
* becomes daemon-owned state, the tool terminates the run, and the submitted
|
|
77
|
+
* answers return later as a follow-up message that wakes the session.
|
|
78
|
+
*
|
|
79
|
+
* Rejected question sets throw: the agent loop turns the thrown message into an
|
|
80
|
+
* error tool result, so the model can fix the ask and post it again.
|
|
81
|
+
*/
|
|
82
|
+
export function createAskUserToolDefinition(deps) {
|
|
83
|
+
return defineTool({
|
|
84
|
+
name: "ask_user",
|
|
85
|
+
label: "Ask user",
|
|
86
|
+
description: "Post a set of questions to the user as a browser form and end this run. Answers arrive later as a follow-up message; the user may leave any question unanswered.",
|
|
87
|
+
promptSnippet: "ask_user: post a question set to the user; ends the run, answers return as a follow-up",
|
|
88
|
+
promptGuidelines: [
|
|
89
|
+
"When you need decisions from the user, post them together with ask_user instead of asking in prose one at a time. It ends the run and the answers, including the questions the user left unanswered, come back as a follow-up message that wakes you. Call it alone and last, and do not repost the same questions or poll for answers.",
|
|
90
|
+
],
|
|
91
|
+
parameters: AskUserParams,
|
|
92
|
+
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
93
|
+
const result = await deps.open({
|
|
94
|
+
sessionId: ctx.sessionManager.getSessionId(),
|
|
95
|
+
questions: params.questions.map(toQuestion),
|
|
96
|
+
});
|
|
97
|
+
return {
|
|
98
|
+
content: [{ type: "text", text: postedText(result) }],
|
|
99
|
+
details: result,
|
|
100
|
+
terminate: true,
|
|
101
|
+
};
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=askUserTool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"askUserTool.js","sourceRoot":"","sources":["../../../src/server/sessions/askUserTool.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,50 +1,47 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const providers = modelRuntime.getProviders();
|
|
4
|
-
const oauthProviderIds = new Set(providers.filter((provider) => provider.auth.oauth !== undefined).map((provider) => provider.id));
|
|
1
|
+
export function getLoginProviderOptions(runtime, authType) {
|
|
2
|
+
const providers = runtime.getProviders();
|
|
5
3
|
const options = [];
|
|
6
4
|
for (const provider of providers) {
|
|
7
|
-
if (provider.auth.oauth
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
|
|
5
|
+
if (provider.auth.oauth === undefined)
|
|
6
|
+
continue;
|
|
7
|
+
options.push({
|
|
8
|
+
id: provider.id,
|
|
9
|
+
name: provider.name,
|
|
10
|
+
authType: "oauth",
|
|
11
|
+
status: truthfulProviderStatus(runtime, provider.id),
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
for (const provider of providers) {
|
|
15
|
+
if (provider.auth.apiKey?.login === undefined)
|
|
16
16
|
continue;
|
|
17
17
|
options.push({
|
|
18
18
|
id: provider.id,
|
|
19
19
|
name: provider.name,
|
|
20
20
|
authType: "api_key",
|
|
21
|
-
status:
|
|
21
|
+
status: truthfulProviderStatus(runtime, provider.id),
|
|
22
|
+
loginFlow: "interactive",
|
|
22
23
|
});
|
|
23
24
|
}
|
|
24
25
|
return filterAndSort(options, authType);
|
|
25
26
|
}
|
|
26
|
-
export async function getLogoutProviderOptions(
|
|
27
|
+
export async function getLogoutProviderOptions(runtime) {
|
|
28
|
+
const providerNames = new Map(runtime.getProviders().map((provider) => [provider.id, provider.name]));
|
|
27
29
|
const options = [];
|
|
28
|
-
const
|
|
29
|
-
for (const credential of await modelRuntime.listCredentials()) {
|
|
30
|
-
const providerId = credential.providerId;
|
|
30
|
+
for (const credential of await runtime.listCredentials()) {
|
|
31
31
|
options.push({
|
|
32
|
-
id: providerId,
|
|
33
|
-
name:
|
|
32
|
+
id: credential.providerId,
|
|
33
|
+
name: providerNames.get(credential.providerId) ?? credential.providerId,
|
|
34
34
|
authType: credential.type,
|
|
35
|
-
status:
|
|
35
|
+
status: truthfulProviderStatus(runtime, credential.providerId),
|
|
36
36
|
});
|
|
37
37
|
}
|
|
38
38
|
return filterAndSort(options);
|
|
39
39
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
if (oauthProviderIds.has(providerId))
|
|
46
|
-
return false;
|
|
47
|
-
return true;
|
|
40
|
+
function truthfulProviderStatus(runtime, providerId) {
|
|
41
|
+
const reported = runtime.getProviderAuthStatus(providerId);
|
|
42
|
+
// ModelRuntime reports any stored entry as configured before checking whether
|
|
43
|
+
// the provider can resolve all required credential and ambient fields.
|
|
44
|
+
return reported.configured && !runtime.hasConfiguredAuth(providerId) ? { configured: false } : reported;
|
|
48
45
|
}
|
|
49
46
|
function filterAndSort(options, authType) {
|
|
50
47
|
const filtered = authType === undefined ? options : options.filter((option) => option.authType === authType);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authProviderOptions.js","sourceRoot":"","sources":["../../../src/server/sessions/authProviderOptions.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"authProviderOptions.js","sourceRoot":"","sources":["../../../src/server/sessions/authProviderOptions.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,6 +16,14 @@ export function registerAuthRoutes(app, auth, prefix = "") {
|
|
|
16
16
|
return reply.code(400).send({ error: error instanceof Error ? error.message : String(error) });
|
|
17
17
|
}
|
|
18
18
|
});
|
|
19
|
+
app.post(`${prefix}/auth/api-key/interactive`, async (request, reply) => {
|
|
20
|
+
try {
|
|
21
|
+
return await (await authForRequest(auth, request.headers, request.query.projectId)).startApiKeyLogin(request.body.providerId);
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
return reply.code(400).send({ error: error instanceof Error ? error.message : String(error) });
|
|
25
|
+
}
|
|
26
|
+
});
|
|
19
27
|
app.post(`${prefix}/auth/logout`, async (request, reply) => {
|
|
20
28
|
try {
|
|
21
29
|
return await (await authForRequest(auth, request.headers, request.query.projectId)).logoutProvider(request.body.providerId);
|
|
@@ -26,7 +34,7 @@ export function registerAuthRoutes(app, auth, prefix = "") {
|
|
|
26
34
|
});
|
|
27
35
|
app.post(`${prefix}/auth/oauth`, async (request, reply) => {
|
|
28
36
|
try {
|
|
29
|
-
return (await authForRequest(auth, request.headers, request.query.projectId)).startOAuthLogin(request.body.providerId);
|
|
37
|
+
return await (await authForRequest(auth, request.headers, request.query.projectId)).startOAuthLogin(request.body.providerId);
|
|
30
38
|
}
|
|
31
39
|
catch (error) {
|
|
32
40
|
return reply.code(400).send({ error: error instanceof Error ? error.message : String(error) });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authRoutes.js","sourceRoot":"","sources":["../../../src/server/sessions/authRoutes.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,+BAA+B,EAAE,MAAM,uBAAuB,CAAC;AAYjG,MAAM,UAAU,kBAAkB,CAAC,GAAoB,EAAE,IAAwB,EAAE,MAAM,GAAG,EAAE;IAC5F,GAAG,CAAC,GAAG,CAA6B,GAAG,MAAM,iBAAiB,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QACvF,IAAI,CAAC;YACH,OAAO,MAAM,CAAC,MAAM,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,IAAI,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC3J,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACjG,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,IAAI,CAAwE,GAAG,MAAM,eAAe,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QACjI,IAAI,CAAC;YACH,OAAO,MAAM,CAAC,MAAM,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC5I,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACjG,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,IAAI,CAA2D,GAAG,MAAM,cAAc,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QACnH,IAAI,CAAC;YACH,OAAO,MAAM,CAAC,MAAM,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC9H,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACjG,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,IAAI,CAA2D,GAAG,MAAM,aAAa,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QAClH,IAAI,CAAC;YACH,OAAO,CAAC,MAAM,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"authRoutes.js","sourceRoot":"","sources":["../../../src/server/sessions/authRoutes.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,+BAA+B,EAAE,MAAM,uBAAuB,CAAC;AAYjG,MAAM,UAAU,kBAAkB,CAAC,GAAoB,EAAE,IAAwB,EAAE,MAAM,GAAG,EAAE;IAC5F,GAAG,CAAC,GAAG,CAA6B,GAAG,MAAM,iBAAiB,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QACvF,IAAI,CAAC;YACH,OAAO,MAAM,CAAC,MAAM,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,IAAI,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC3J,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACjG,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,IAAI,CAAwE,GAAG,MAAM,eAAe,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QACjI,IAAI,CAAC;YACH,OAAO,MAAM,CAAC,MAAM,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC5I,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACjG,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,IAAI,CAA2D,GAAG,MAAM,2BAA2B,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QAChI,IAAI,CAAC;YACH,OAAO,MAAM,CAAC,MAAM,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAChI,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACjG,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,IAAI,CAA2D,GAAG,MAAM,cAAc,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QACnH,IAAI,CAAC;YACH,OAAO,MAAM,CAAC,MAAM,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC9H,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACjG,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,IAAI,CAA2D,GAAG,MAAM,aAAa,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QAClH,IAAI,CAAC;YACH,OAAO,MAAM,CAAC,MAAM,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC/H,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACjG,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,GAAG,CAAyD,GAAG,MAAM,qBAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QACvH,IAAI,CAAC;YACH,OAAO,CAAC,MAAM,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACjH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACjG,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,IAAI,CAAqG,GAAG,MAAM,6BAA6B,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QAC5K,IAAI,CAAC;YACH,OAAO,CAAC,MAAM,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,kBAAkB,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtK,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACjG,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,IAAI,CAAyD,GAAG,MAAM,4BAA4B,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QAC/H,IAAI,CAAC;YACH,OAAO,CAAC,MAAM,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACvH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACjG,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAQD,KAAK,UAAU,cAAc,CAAC,IAAwB,EAAE,OAAsD,EAAE,SAA6B;IAC3I,MAAM,GAAG,GAAG,OAAO,CAAC,+BAA+B,CAAC,CAAC;IACrD,MAAM,OAAO,GAAG,uBAAuB,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC3E,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC,UAAU,CAAC;IAClD,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,KAAK,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC1G,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;AAC3C,CAAC"}
|
|
@@ -1,10 +1,82 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { ModelRuntime } from "@earendil-works/pi-coding-agent";
|
|
1
3
|
import { getLoginProviderOptions, getLogoutProviderOptions } from "./authProviderOptions.js";
|
|
2
4
|
import { OAuthLoginFlowService } from "./oauthLoginFlowService.js";
|
|
5
|
+
const noopLogger = { error() { } };
|
|
6
|
+
/**
|
|
7
|
+
* Serializes the `PI_OFFLINE` windows below, which is what keeps their
|
|
8
|
+
* save/restore pairs properly nested. Two overlapping calls would otherwise both
|
|
9
|
+
* capture the forced `"1"` and restore it, leaving the whole process offline
|
|
10
|
+
* permanently. Owned by this module only; nothing else may mutate it.
|
|
11
|
+
*/
|
|
12
|
+
let offlineRuntimeCreations = Promise.resolve();
|
|
13
|
+
/**
|
|
14
|
+
* Create the shared model runtime with runtime-owned network refreshes disabled.
|
|
15
|
+
*
|
|
16
|
+
* Upstream `ModelRuntime.refresh()`, `login()`, and `logout()` always refresh
|
|
17
|
+
* with `allowNetwork: modelNetworkEnabled` by default, and `login()`/`logout()`
|
|
18
|
+
* accept no abort signal. With the default (`PI_OFFLINE` unset) a single stalled
|
|
19
|
+
* provider-catalog fetch can block those call paths for minutes — and, because
|
|
20
|
+
* pi-web shares one runtime and pi coalesces per-provider refreshes, session
|
|
21
|
+
* creation joins the same stalled fetch. Forcing `PI_OFFLINE` during construction makes every runtime-driven
|
|
22
|
+
* refresh local-only; pi-web performs its own bounded catalog refreshes in the
|
|
23
|
+
* background instead (see modelCatalogRefresher.ts).
|
|
24
|
+
*
|
|
25
|
+
* `modelNetworkEnabled` is computed once from the environment inside
|
|
26
|
+
* `ModelRuntime.create()`, so the env var is the only lever upstream exposes.
|
|
27
|
+
* Calls are queued so their env windows never overlap.
|
|
28
|
+
*/
|
|
29
|
+
function createOfflineModelRuntime(options) {
|
|
30
|
+
const created = offlineRuntimeCreations.then(() => forceOfflineWhile(() => ModelRuntime.create(options)));
|
|
31
|
+
// A failed creation must not poison the queue; the caller still sees the rejection.
|
|
32
|
+
offlineRuntimeCreations = created.then(() => undefined, () => undefined);
|
|
33
|
+
return created;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Force `PI_OFFLINE` for the duration of `create`, then restore what was there.
|
|
37
|
+
*
|
|
38
|
+
* `process.env` is process-wide, so this window is a real global side effect:
|
|
39
|
+
* anything reading `PI_OFFLINE` while `create` awaits observes offline mode,
|
|
40
|
+
* including upstream's package manager, tools manager, and version check. That
|
|
41
|
+
* is acceptable because pi-web only builds runtimes during daemon startup and in
|
|
42
|
+
* tests, and the window is one `ModelRuntime.create()` call — but it is why
|
|
43
|
+
* callers must stay serialized rather than run concurrently.
|
|
44
|
+
*/
|
|
45
|
+
async function forceOfflineWhile(create) {
|
|
46
|
+
const previous = process.env["PI_OFFLINE"];
|
|
47
|
+
process.env["PI_OFFLINE"] = "1";
|
|
48
|
+
try {
|
|
49
|
+
return await create();
|
|
50
|
+
}
|
|
51
|
+
finally {
|
|
52
|
+
if (previous === undefined)
|
|
53
|
+
delete process.env["PI_OFFLINE"];
|
|
54
|
+
else
|
|
55
|
+
process.env["PI_OFFLINE"] = previous;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
export function createModelRuntimeForAgentDir(agentDir) {
|
|
59
|
+
return createOfflineModelRuntime({
|
|
60
|
+
authPath: join(agentDir, "auth.json"),
|
|
61
|
+
modelsPath: join(agentDir, "models.json"),
|
|
62
|
+
});
|
|
63
|
+
}
|
|
3
64
|
export class AuthService {
|
|
4
65
|
constructor(deps) {
|
|
5
66
|
this.listeners = new Set();
|
|
6
|
-
|
|
7
|
-
|
|
67
|
+
const runtime = deps.runtime ?? deps.modelRuntime;
|
|
68
|
+
if (runtime === undefined)
|
|
69
|
+
throw new Error("AuthService requires a model runtime");
|
|
70
|
+
this.runtime = runtime;
|
|
71
|
+
this.modelRuntime = this.runtime;
|
|
72
|
+
this.logger = deps.logger ?? noopLogger;
|
|
73
|
+
this.authFlows = deps.authFlows ?? new OAuthLoginFlowService({ logger: this.logger });
|
|
74
|
+
}
|
|
75
|
+
static async create(deps = {}) {
|
|
76
|
+
const runtime = deps.runtime ?? deps.modelRuntime ?? (deps.agentDir === undefined ? await createOfflineModelRuntime({}) : await createModelRuntimeForAgentDir(deps.agentDir));
|
|
77
|
+
const logger = deps.logger ?? noopLogger;
|
|
78
|
+
const authFlows = deps.authFlows ?? new OAuthLoginFlowService({ logger });
|
|
79
|
+
return new AuthService({ runtime, authFlows, logger });
|
|
8
80
|
}
|
|
9
81
|
subscribe(listener) {
|
|
10
82
|
this.listeners.add(listener);
|
|
@@ -17,33 +89,57 @@ export class AuthService {
|
|
|
17
89
|
this.listeners.clear();
|
|
18
90
|
}
|
|
19
91
|
async authProviders(mode, authType) {
|
|
20
|
-
await this.
|
|
21
|
-
const providers = mode === "logout"
|
|
22
|
-
? await getLogoutProviderOptions(this.modelRuntime)
|
|
23
|
-
: getLoginProviderOptions(this.modelRuntime, authType);
|
|
92
|
+
await this.runtime.refresh();
|
|
93
|
+
const providers = mode === "logout" ? await getLogoutProviderOptions(this.runtime) : getLoginProviderOptions(this.runtime, authType);
|
|
24
94
|
return { providers };
|
|
25
95
|
}
|
|
26
96
|
async saveApiKey(providerId, key) {
|
|
27
97
|
if (key.trim() === "")
|
|
28
98
|
throw new Error("API key is required");
|
|
29
|
-
await this.
|
|
30
|
-
|
|
99
|
+
const provider = await this.requireApiKeyLoginProvider(providerId);
|
|
100
|
+
let promptAttempted = false;
|
|
101
|
+
const interaction = {
|
|
102
|
+
prompt: (prompt) => {
|
|
103
|
+
if (promptAttempted) {
|
|
104
|
+
throw new Error(`${provider.name} requires interactive setup; use Pi's generic /login flow`);
|
|
105
|
+
}
|
|
106
|
+
promptAttempted = true;
|
|
107
|
+
if (prompt.signal?.aborted === true)
|
|
108
|
+
throw new Error("Login cancelled");
|
|
109
|
+
if (prompt.type !== "secret") {
|
|
110
|
+
throw new Error(`${provider.name} requires interactive setup; use Pi's generic /login flow`);
|
|
111
|
+
}
|
|
112
|
+
return Promise.resolve(key);
|
|
113
|
+
},
|
|
114
|
+
notify: () => undefined,
|
|
115
|
+
};
|
|
116
|
+
await this.runtime.login(providerId, "api_key", interaction);
|
|
117
|
+
await this.emit({}, { operation: "login", providerId, authType: "api_key" });
|
|
31
118
|
return { accepted: true };
|
|
32
119
|
}
|
|
33
120
|
async logoutProvider(providerId) {
|
|
34
|
-
await this.
|
|
35
|
-
this.emit({
|
|
121
|
+
await this.runtime.logout(providerId);
|
|
122
|
+
await this.emit({ removedProviderId: providerId }, { operation: "logout", providerId });
|
|
36
123
|
return { accepted: true };
|
|
37
124
|
}
|
|
38
|
-
|
|
39
|
-
const provider = this.
|
|
125
|
+
async startApiKeyLogin(providerId) {
|
|
126
|
+
const provider = await this.requireApiKeyLoginProvider(providerId);
|
|
40
127
|
return this.authFlows.start({
|
|
41
128
|
providerId,
|
|
42
129
|
providerName: provider.name,
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
130
|
+
runtime: this.runtime,
|
|
131
|
+
authType: "api_key",
|
|
132
|
+
onComplete: () => this.emit({}, { operation: "login", providerId, authType: "api_key" }),
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
async startOAuthLogin(providerId) {
|
|
136
|
+
const provider = await this.requireOAuthLoginProvider(providerId);
|
|
137
|
+
return this.authFlows.start({
|
|
138
|
+
providerId,
|
|
139
|
+
providerName: provider.name,
|
|
140
|
+
runtime: this.runtime,
|
|
141
|
+
authType: "oauth",
|
|
142
|
+
onComplete: () => this.emit({}, { operation: "login", providerId, authType: "oauth" }),
|
|
47
143
|
});
|
|
48
144
|
}
|
|
49
145
|
oauthFlow(flowId) {
|
|
@@ -55,27 +151,41 @@ export class AuthService {
|
|
|
55
151
|
cancelOAuthFlow(flowId) {
|
|
56
152
|
return this.authFlows.cancel(flowId);
|
|
57
153
|
}
|
|
58
|
-
emit(change) {
|
|
59
|
-
|
|
60
|
-
|
|
154
|
+
async emit(change, context) {
|
|
155
|
+
const scopedChange = { ...change, modelRuntime: this.runtime };
|
|
156
|
+
Object.defineProperty(scopedChange, "modelRuntime", { value: this.runtime, enumerable: false });
|
|
157
|
+
const results = await Promise.allSettled([...this.listeners].map(async (listener) => listener(scopedChange)));
|
|
158
|
+
for (const result of results) {
|
|
159
|
+
if (result.status === "rejected") {
|
|
160
|
+
this.logErrorNoThrow({ err: result.reason, ...context }, "auth-change listener failed");
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
logErrorNoThrow(details, message) {
|
|
165
|
+
try {
|
|
166
|
+
this.logger.error(details, message);
|
|
167
|
+
}
|
|
168
|
+
catch {
|
|
169
|
+
// A diagnostic failure cannot turn an already-committed auth mutation into an API failure.
|
|
170
|
+
}
|
|
61
171
|
}
|
|
62
|
-
|
|
63
|
-
|
|
172
|
+
async requireApiKeyLoginProvider(providerId) {
|
|
173
|
+
await this.runtime.refresh();
|
|
174
|
+
const provider = getLoginProviderOptions(this.runtime, "api_key").find((option) => option.id === providerId);
|
|
175
|
+
if (provider !== undefined)
|
|
176
|
+
return provider;
|
|
177
|
+
const knownProvider = this.runtime.getProviders().find((option) => option.id === providerId);
|
|
178
|
+
if (knownProvider !== undefined) {
|
|
179
|
+
throw new Error(`${knownProvider.name} does not support interactive API-key setup`);
|
|
180
|
+
}
|
|
181
|
+
throw new Error(`API key provider not found: ${providerId}`);
|
|
182
|
+
}
|
|
183
|
+
async requireOAuthLoginProvider(providerId) {
|
|
184
|
+
await this.runtime.refresh();
|
|
185
|
+
const provider = getLoginProviderOptions(this.runtime, "oauth").find((option) => option.id === providerId);
|
|
64
186
|
if (provider === undefined)
|
|
65
187
|
throw new Error(`OAuth provider not found: ${providerId}`);
|
|
66
188
|
return provider;
|
|
67
189
|
}
|
|
68
190
|
}
|
|
69
|
-
function apiKeyInteraction(key) {
|
|
70
|
-
return {
|
|
71
|
-
prompt(prompt) {
|
|
72
|
-
if (prompt.type === "select")
|
|
73
|
-
return Promise.reject(new Error("此 API key 登录流程需要交互式选项,当前接口不支持"));
|
|
74
|
-
return Promise.resolve(key);
|
|
75
|
-
},
|
|
76
|
-
notify() {
|
|
77
|
-
// API-key login events do not need to be forwarded to the browser.
|
|
78
|
-
},
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
191
|
//# sourceMappingURL=authService.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authService.js","sourceRoot":"","sources":["../../../src/server/sessions/authService.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"authService.js","sourceRoot":"","sources":["../../../src/server/sessions/authService.ts"],"names":[],"mappings":"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"}
|