@promptbook/cli 0.113.0-10 → 0.113.0-11
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/apps/agents-server/src/app/admin/{code-runners/CodeRunnersClient.tsx → harness-auth/HarnessAuthClient.tsx} +98 -65
- package/apps/agents-server/src/app/admin/{code-runners → harness-auth}/page.tsx +4 -4
- package/apps/agents-server/src/app/api/admin/{code-runners → harness-auth}/authentication/route.ts +17 -17
- package/apps/agents-server/src/app/api/admin/{code-runners → harness-auth}/route.ts +13 -13
- package/apps/agents-server/src/app/layout.tsx +16 -0
- package/apps/agents-server/src/components/AdminTerminal/AdminTerminalCard.tsx +32 -24
- package/apps/agents-server/src/components/Footer/Footer.tsx +38 -15
- package/apps/agents-server/src/components/Header/buildHeaderSystemMenuItems.ts +5 -4
- package/apps/agents-server/src/components/LayoutWrapper/LayoutWrapper.tsx +4 -1
- package/apps/agents-server/src/constants/harnessAuthRoutes.ts +20 -0
- package/apps/agents-server/src/languages/ServerTranslationKeys.ts +1 -1
- package/apps/agents-server/src/languages/translations/czech.yaml +2 -2
- package/apps/agents-server/src/languages/translations/english.yaml +1 -1
- package/apps/agents-server/src/utils/{codeRunnerAuthentication.ts → harnessAuthentication.ts} +72 -56
- package/apps/agents-server/src/utils/{codeRunnerConfiguration.ts → harnessConfiguration.ts} +18 -12
- package/apps/agents-server/src/utils/taskTerminal/resolveAdminTaskTerminalSession.ts +28 -5
- package/apps/agents-server/src/utils/vpsConfiguration.ts +3 -3
- package/apps/agents-server/src/utils/vpsSelfUpdate/readAgentsServerFooterVersion.ts +335 -0
- package/apps/agents-server/src/utils/vpsSelfUpdate/vpsSelfUpdateJobHistory.ts +107 -4
- package/esm/index.es.js +697 -591
- package/esm/index.es.js.map +1 -1
- package/esm/scripts/run-codex-prompts/common/sleepWithCountdown.d.ts +1 -0
- package/esm/scripts/run-codex-prompts/common/waitUntilWorldTimeDeadline.d.ts +17 -0
- package/esm/scripts/run-codex-prompts/ui/buildCoderRunAgentVisual.d.ts +3 -16
- package/esm/src/utils/agents/terminalAgentAvatarVisual.d.ts +94 -0
- package/esm/src/utils/agents/terminalAgentAvatarVisual.test.d.ts +1 -0
- package/esm/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/other/templates/getTemplatesPipelineCollection.ts +790 -807
- package/src/utils/agents/terminalAgentAvatarVisual.ts +261 -0
- package/src/version.ts +2 -2
- package/src/versions.txt +1 -0
- package/umd/index.umd.js +697 -591
- package/umd/index.umd.js.map +1 -1
- package/umd/scripts/run-codex-prompts/common/sleepWithCountdown.d.ts +1 -0
- package/umd/scripts/run-codex-prompts/common/waitUntilWorldTimeDeadline.d.ts +17 -0
- package/umd/scripts/run-codex-prompts/ui/buildCoderRunAgentVisual.d.ts +3 -16
- package/umd/src/utils/agents/terminalAgentAvatarVisual.d.ts +94 -0
- package/umd/src/utils/agents/terminalAgentAvatarVisual.test.d.ts +1 -0
- package/umd/src/version.d.ts +1 -1
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import { CLAIM, NAME, PROMPTBOOK_ENGINE_VERSION } from '@promptbook-local/core';
|
|
3
|
+
import { CLAIM, NAME } from '@promptbook-local/core';
|
|
5
4
|
import { useServerLanguage } from '../ServerLanguage/ServerLanguageProvider';
|
|
6
5
|
import { HeadlessLink } from '../_utils/headlessParam';
|
|
7
6
|
import { getCommitFooterEmoji } from './getCommitFooterEmoji';
|
|
@@ -16,6 +15,18 @@ export type FooterLink = {
|
|
|
16
15
|
url: string;
|
|
17
16
|
};
|
|
18
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Lightweight precomputed version metadata rendered in the footer.
|
|
20
|
+
*
|
|
21
|
+
* @private Internal to `apps/agents-server`
|
|
22
|
+
*/
|
|
23
|
+
export type FooterVersionInfo = {
|
|
24
|
+
label: string;
|
|
25
|
+
url: string;
|
|
26
|
+
commitSha: string | null;
|
|
27
|
+
releasedAtLabel: string | null;
|
|
28
|
+
};
|
|
29
|
+
|
|
19
30
|
/**
|
|
20
31
|
* Configuration passed to `Footer` from the layout container.
|
|
21
32
|
*
|
|
@@ -23,6 +34,7 @@ export type FooterLink = {
|
|
|
23
34
|
*/
|
|
24
35
|
type FooterProps = {
|
|
25
36
|
extraLinks?: FooterLink[];
|
|
37
|
+
version: FooterVersionInfo;
|
|
26
38
|
};
|
|
27
39
|
|
|
28
40
|
/**
|
|
@@ -31,8 +43,9 @@ type FooterProps = {
|
|
|
31
43
|
* @private Internal to `apps/agents-server`
|
|
32
44
|
*/
|
|
33
45
|
export function Footer(props: FooterProps) {
|
|
34
|
-
const { extraLinks = [] } = props;
|
|
46
|
+
const { extraLinks = [], version } = props;
|
|
35
47
|
const { t } = useServerLanguage();
|
|
48
|
+
const versionText = version.releasedAtLabel ? `${version.label}, ${version.releasedAtLabel}` : version.label;
|
|
36
49
|
|
|
37
50
|
return (
|
|
38
51
|
<footer className="border-t border-gray-200 bg-white dark:border-slate-700 dark:bg-slate-950">
|
|
@@ -46,7 +59,9 @@ export function Footer(props: FooterProps) {
|
|
|
46
59
|
|
|
47
60
|
{/* Products */}
|
|
48
61
|
<div className="space-y-4">
|
|
49
|
-
<h3 className="font-bold text-gray-900 dark:text-slate-100">
|
|
62
|
+
<h3 className="font-bold text-gray-900 dark:text-slate-100">
|
|
63
|
+
{t('footer.productSectionTitle')}
|
|
64
|
+
</h3>
|
|
50
65
|
<ul className="space-y-2 text-sm">
|
|
51
66
|
<li>
|
|
52
67
|
<HeadlessLink href="/get-started" className="text-gray-500 hover:text-gray-900">
|
|
@@ -81,7 +96,9 @@ export function Footer(props: FooterProps) {
|
|
|
81
96
|
|
|
82
97
|
{/* Company */}
|
|
83
98
|
<div className="space-y-4">
|
|
84
|
-
<h3 className="font-bold text-gray-900 dark:text-slate-100">
|
|
99
|
+
<h3 className="font-bold text-gray-900 dark:text-slate-100">
|
|
100
|
+
{t('footer.companySectionTitle')}
|
|
101
|
+
</h3>
|
|
85
102
|
<ul className="space-y-2 text-sm">
|
|
86
103
|
<li>
|
|
87
104
|
<a
|
|
@@ -111,7 +128,9 @@ export function Footer(props: FooterProps) {
|
|
|
111
128
|
|
|
112
129
|
{/* Social */}
|
|
113
130
|
<div className="space-y-4">
|
|
114
|
-
<h3 className="font-bold text-gray-900 dark:text-slate-100">
|
|
131
|
+
<h3 className="font-bold text-gray-900 dark:text-slate-100">
|
|
132
|
+
{t('footer.connectSectionTitle')}
|
|
133
|
+
</h3>
|
|
115
134
|
<ul className="space-y-2 text-sm">
|
|
116
135
|
<li>
|
|
117
136
|
<a
|
|
@@ -145,7 +164,9 @@ export function Footer(props: FooterProps) {
|
|
|
145
164
|
{/* Extra Links from Metadata */}
|
|
146
165
|
{extraLinks.length > 0 && (
|
|
147
166
|
<div className="space-y-4">
|
|
148
|
-
<h3 className="font-bold text-gray-900 dark:text-slate-100">
|
|
167
|
+
<h3 className="font-bold text-gray-900 dark:text-slate-100">
|
|
168
|
+
{t('footer.linksSectionTitle')}
|
|
169
|
+
</h3>
|
|
149
170
|
<ul className="space-y-2 text-sm">
|
|
150
171
|
{extraLinks.map((link, index) => (
|
|
151
172
|
<li key={index}>
|
|
@@ -168,16 +189,18 @@ export function Footer(props: FooterProps) {
|
|
|
168
189
|
<p>
|
|
169
190
|
© {new Date().getFullYear()} Promptbook
|
|
170
191
|
<br />
|
|
171
|
-
{t('footer.
|
|
172
|
-
<br />
|
|
173
|
-
{t('footer.madeInCzechRepublic', { emoji: getCommitFooterEmoji(NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA) })}
|
|
192
|
+
{t('footer.madeInCzechRepublic', { emoji: getCommitFooterEmoji(version.commitSha) })}
|
|
174
193
|
{/* <- TODO: !!!!!!!! Put here Prague outline */}
|
|
175
194
|
</p>
|
|
176
|
-
<p className="mt-2 text-xs text-gray-400">
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
195
|
+
<p className="mt-2 text-xs text-gray-400 dark:text-slate-500">
|
|
196
|
+
<a
|
|
197
|
+
href={version.url}
|
|
198
|
+
className="hover:text-gray-600 dark:hover:text-slate-300"
|
|
199
|
+
target="_blank"
|
|
200
|
+
rel="noopener noreferrer"
|
|
201
|
+
>
|
|
202
|
+
{versionText}
|
|
203
|
+
</a>
|
|
181
204
|
</p>
|
|
182
205
|
</div>
|
|
183
206
|
{/*
|
|
@@ -52,6 +52,7 @@ import {
|
|
|
52
52
|
type LucideIcon,
|
|
53
53
|
} from 'lucide-react';
|
|
54
54
|
import { createElement } from 'react';
|
|
55
|
+
import { HARNESS_AUTH_ADMIN_PATH } from '../../constants/harnessAuthRoutes';
|
|
55
56
|
import type { ServerTranslationKey } from '../../languages/ServerTranslationKeys';
|
|
56
57
|
import type { ShibbolethAuthenticationMenuStatus } from '../../constants/shibbolethAuth';
|
|
57
58
|
import type { ChatFeedbackMode } from '../../utils/chatFeedbackMode';
|
|
@@ -102,7 +103,7 @@ type SystemMenuItemHref =
|
|
|
102
103
|
| '/admin/update'
|
|
103
104
|
| '/admin/database'
|
|
104
105
|
| '/admin/logs'
|
|
105
|
-
|
|
|
106
|
+
| typeof HARNESS_AUTH_ADMIN_PATH
|
|
106
107
|
| '/admin/cli-access'
|
|
107
108
|
| '/admin/models'
|
|
108
109
|
| '/admin/metadata'
|
|
@@ -178,7 +179,7 @@ const SYSTEM_MENU_ICON_BY_HREF: Record<SystemMenuItemHref, LucideIcon> = {
|
|
|
178
179
|
'/admin/update': RefreshCw,
|
|
179
180
|
'/admin/database': Database,
|
|
180
181
|
'/admin/logs': ScrollText,
|
|
181
|
-
|
|
182
|
+
[HARNESS_AUTH_ADMIN_PATH]: TerminalSquare,
|
|
182
183
|
'/admin/cli-access': Terminal,
|
|
183
184
|
'/admin/models': Bot,
|
|
184
185
|
'/admin/metadata': FileJson,
|
|
@@ -411,8 +412,8 @@ export function buildHeaderSystemMenuItems({
|
|
|
411
412
|
href: '/admin/logs',
|
|
412
413
|
} as SubMenuItem,
|
|
413
414
|
{
|
|
414
|
-
label: translate('header.
|
|
415
|
-
href:
|
|
415
|
+
label: translate('header.harnessAuth'),
|
|
416
|
+
href: HARNESS_AUTH_ADMIN_PATH,
|
|
416
417
|
} as SubMenuItem,
|
|
417
418
|
{
|
|
418
419
|
label: translate('header.cliAccess'),
|
|
@@ -18,7 +18,7 @@ import { ClientVersionMismatchListener } from '../ClientVersion/ClientVersionMis
|
|
|
18
18
|
import { ChatEnterBehaviorPreferencesProvider } from '../ChatEnterBehavior/ChatEnterBehaviorPreferencesProvider';
|
|
19
19
|
import { HomepageOptimisticNavigation } from '../Homepage/HomepageOptimisticNavigation';
|
|
20
20
|
import { FileUploadAvailabilityProvider } from '../FileUploadAvailability/FileUploadAvailabilityContext';
|
|
21
|
-
import { Footer, type FooterLink } from '../Footer/Footer';
|
|
21
|
+
import { Footer, type FooterLink, type FooterVersionInfo } from '../Footer/Footer';
|
|
22
22
|
import { ActiveAgentBreadcrumbProvider } from '../Header/ActiveAgentBreadcrumbContext';
|
|
23
23
|
import { Header } from '../Header/Header';
|
|
24
24
|
import { MobileMenuHoistingProvider } from '../Header/MobileMenuHoistingContext';
|
|
@@ -50,6 +50,7 @@ type LayoutWrapperProps = {
|
|
|
50
50
|
agentNaming: AgentNaming;
|
|
51
51
|
isFooterShown: boolean;
|
|
52
52
|
footerLinks: Array<FooterLink>;
|
|
53
|
+
footerVersion: FooterVersionInfo;
|
|
53
54
|
federatedServers: Array<{ url: string; title: string }>;
|
|
54
55
|
isExperimental: boolean;
|
|
55
56
|
feedbackMode: ChatFeedbackMode;
|
|
@@ -102,6 +103,7 @@ export function LayoutWrapper({
|
|
|
102
103
|
agentNaming,
|
|
103
104
|
isFooterShown,
|
|
104
105
|
footerLinks,
|
|
106
|
+
footerVersion,
|
|
105
107
|
federatedServers,
|
|
106
108
|
isExperimental,
|
|
107
109
|
feedbackMode,
|
|
@@ -212,6 +214,7 @@ export function LayoutWrapper({
|
|
|
212
214
|
!isFooterHiddenOnPage && (
|
|
213
215
|
<Footer
|
|
214
216
|
extraLinks={footerLinks}
|
|
217
|
+
version={footerVersion}
|
|
215
218
|
/>
|
|
216
219
|
)}
|
|
217
220
|
</div>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Admin page path for configuring standalone harness authentication.
|
|
3
|
+
*
|
|
4
|
+
* @private internal route constant for Agents Server Harness Auth UI
|
|
5
|
+
*/
|
|
6
|
+
export const HARNESS_AUTH_ADMIN_PATH = '/admin/harness-auth';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Admin API path for configuring standalone harness authentication.
|
|
10
|
+
*
|
|
11
|
+
* @private internal route constant for Agents Server Harness Auth UI
|
|
12
|
+
*/
|
|
13
|
+
export const HARNESS_AUTH_API_PATH = '/api/admin/harness-auth';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Admin API path for the interactive harness authentication terminal.
|
|
17
|
+
*
|
|
18
|
+
* @private internal route constant for Agents Server Harness Auth UI
|
|
19
|
+
*/
|
|
20
|
+
export const HARNESS_AUTHENTICATION_API_PATH = `${HARNESS_AUTH_API_PATH}/authentication`;
|
|
@@ -141,7 +141,7 @@ header.resourceMonitor: Monitoring zdrojů
|
|
|
141
141
|
header.update: Aktualizace
|
|
142
142
|
header.database: Databáze
|
|
143
143
|
header.logs: Logy
|
|
144
|
-
header.
|
|
144
|
+
header.harnessAuth: Přihlášení harnessu
|
|
145
145
|
header.cliAccess: CLI přístup
|
|
146
146
|
header.models: Modely
|
|
147
147
|
header.openApiDocumentation: Dokumentace OpenAPI
|
|
@@ -381,7 +381,7 @@ footer.logosAndBranding: Loga a vizuální identita
|
|
|
381
381
|
footer.connectSectionTitle: Spojte se s námi
|
|
382
382
|
footer.linksSectionTitle: Odkazy
|
|
383
383
|
footer.allRightsReserved: Všechna práva vyhrazena.
|
|
384
|
-
footer.madeInCzechRepublic: Vytvořeno s {emoji} v
|
|
384
|
+
footer.madeInCzechRepublic: Vytvořeno s {emoji} v Evropě.
|
|
385
385
|
footer.engineVersion: Verze jádra Promptbooku
|
|
386
386
|
forbidden.title: 403 Zakázáno
|
|
387
387
|
forbidden.message: Nemáte oprávnění k přístupu na tuto stránku.
|
|
@@ -143,7 +143,7 @@ header.resourceMonitor: Resource monitor
|
|
|
143
143
|
header.update: Update
|
|
144
144
|
header.database: Database
|
|
145
145
|
header.logs: Logs
|
|
146
|
-
header.
|
|
146
|
+
header.harnessAuth: Harness Auth
|
|
147
147
|
header.cliAccess: CLI Access
|
|
148
148
|
header.models: Models
|
|
149
149
|
header.openApiDocumentation: OpenAPI Documentation
|
package/apps/agents-server/src/utils/{codeRunnerAuthentication.ts → harnessAuthentication.ts}
RENAMED
|
@@ -11,21 +11,23 @@ import {
|
|
|
11
11
|
} from './interactiveTerminalSession';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
* Serializable snapshot of one interactive
|
|
14
|
+
* Serializable snapshot of one interactive harness authentication session.
|
|
15
|
+
*
|
|
16
|
+
* @private internal utility of Agents Server Harness Auth
|
|
15
17
|
*/
|
|
16
|
-
export type
|
|
18
|
+
export type HarnessAuthenticationSessionSnapshot = {
|
|
17
19
|
/**
|
|
18
20
|
* Session identifier used by the browser UI.
|
|
19
21
|
*/
|
|
20
22
|
readonly id: string;
|
|
21
23
|
|
|
22
24
|
/**
|
|
23
|
-
*
|
|
25
|
+
* Harness being authenticated.
|
|
24
26
|
*/
|
|
25
|
-
readonly
|
|
27
|
+
readonly harness: string;
|
|
26
28
|
|
|
27
29
|
/**
|
|
28
|
-
* Whether the interactive
|
|
30
|
+
* Whether the interactive harness process is still active.
|
|
29
31
|
*/
|
|
30
32
|
readonly isRunning: boolean;
|
|
31
33
|
|
|
@@ -57,8 +59,10 @@ export type CodeRunnerAuthenticationSessionSnapshot = {
|
|
|
57
59
|
|
|
58
60
|
/**
|
|
59
61
|
* Browser stream callbacks used by one subscribed UI client.
|
|
62
|
+
*
|
|
63
|
+
* @private internal utility of Agents Server Harness Auth
|
|
60
64
|
*/
|
|
61
|
-
export type
|
|
65
|
+
export type HarnessAuthenticationSessionSubscriber = {
|
|
62
66
|
/**
|
|
63
67
|
* Called whenever new terminal output arrives.
|
|
64
68
|
*/
|
|
@@ -67,27 +71,29 @@ export type CodeRunnerAuthenticationSessionSubscriber = {
|
|
|
67
71
|
/**
|
|
68
72
|
* Called once the session exits.
|
|
69
73
|
*/
|
|
70
|
-
readonly onExit: (event: { readonly type: 'exit'; readonly snapshot:
|
|
74
|
+
readonly onExit: (event: { readonly type: 'exit'; readonly snapshot: HarnessAuthenticationSessionSnapshot }) => void;
|
|
71
75
|
};
|
|
72
76
|
|
|
73
77
|
/**
|
|
74
|
-
* Starts a streamed authentication session for the currently configured standalone
|
|
78
|
+
* Starts a streamed authentication session for the currently configured standalone harness.
|
|
75
79
|
*
|
|
76
|
-
* @param
|
|
77
|
-
* @returns Existing running session for the same
|
|
80
|
+
* @param harness - Harness identifier stored in `.env`.
|
|
81
|
+
* @returns Existing running session for the same harness or a new one.
|
|
82
|
+
*
|
|
83
|
+
* @private internal utility of Agents Server Harness Auth
|
|
78
84
|
*/
|
|
79
|
-
export async function
|
|
80
|
-
|
|
81
|
-
): Promise<
|
|
85
|
+
export async function startHarnessAuthenticationSession(
|
|
86
|
+
harness: string,
|
|
87
|
+
): Promise<HarnessAuthenticationSessionSnapshot> {
|
|
82
88
|
const scriptPath = await resolveVpsInstallerScriptPath();
|
|
83
89
|
if (!scriptPath) {
|
|
84
90
|
throw new Error('The VPS installer script could not be found on this server.');
|
|
85
91
|
}
|
|
86
92
|
|
|
87
|
-
return
|
|
93
|
+
return toRequiredHarnessAuthenticationSessionSnapshot(
|
|
88
94
|
startInteractiveTerminalSession({
|
|
89
|
-
sessionKey:
|
|
90
|
-
title: `${
|
|
95
|
+
sessionKey: buildHarnessAuthenticationSessionKey(harness),
|
|
96
|
+
title: `${harness} authentication`,
|
|
91
97
|
command: 'bash',
|
|
92
98
|
arguments: [scriptPath, 'authenticate-runner'],
|
|
93
99
|
env: createVpsInstallerCommandEnvironment({
|
|
@@ -95,26 +101,28 @@ export async function startCodeRunnerAuthenticationSession(
|
|
|
95
101
|
isProcessRestartEnabled: false,
|
|
96
102
|
}),
|
|
97
103
|
metadata: {
|
|
98
|
-
|
|
104
|
+
harness,
|
|
99
105
|
},
|
|
100
|
-
unavailableErrorMessage: 'Interactive
|
|
106
|
+
unavailableErrorMessage: 'Interactive harness authentication is available only on the Linux VPS runtime.',
|
|
101
107
|
}),
|
|
102
|
-
|
|
108
|
+
harness,
|
|
103
109
|
);
|
|
104
110
|
}
|
|
105
111
|
|
|
106
112
|
/**
|
|
107
|
-
* Returns the latest known authentication session for a
|
|
113
|
+
* Returns the latest known authentication session for a harness.
|
|
108
114
|
*
|
|
109
|
-
* @param
|
|
115
|
+
* @param harness - Harness identifier.
|
|
110
116
|
* @returns Serializable session snapshot or `null`.
|
|
117
|
+
*
|
|
118
|
+
* @private internal utility of Agents Server Harness Auth
|
|
111
119
|
*/
|
|
112
|
-
export function
|
|
113
|
-
|
|
114
|
-
):
|
|
115
|
-
return
|
|
116
|
-
getLatestInteractiveTerminalSession(
|
|
117
|
-
|
|
120
|
+
export function getLatestHarnessAuthenticationSession(
|
|
121
|
+
harness: string,
|
|
122
|
+
): HarnessAuthenticationSessionSnapshot | null {
|
|
123
|
+
return toHarnessAuthenticationSessionSnapshot(
|
|
124
|
+
getLatestInteractiveTerminalSession(buildHarnessAuthenticationSessionKey(harness)),
|
|
125
|
+
harness,
|
|
118
126
|
);
|
|
119
127
|
}
|
|
120
128
|
|
|
@@ -123,11 +131,13 @@ export function getLatestCodeRunnerAuthenticationSession(
|
|
|
123
131
|
*
|
|
124
132
|
* @param sessionId - Session identifier.
|
|
125
133
|
* @returns Serializable session snapshot or `null`.
|
|
134
|
+
*
|
|
135
|
+
* @private internal utility of Agents Server Harness Auth
|
|
126
136
|
*/
|
|
127
|
-
export function
|
|
137
|
+
export function getHarnessAuthenticationSession(
|
|
128
138
|
sessionId: string,
|
|
129
|
-
):
|
|
130
|
-
return
|
|
139
|
+
): HarnessAuthenticationSessionSnapshot | null {
|
|
140
|
+
return toHarnessAuthenticationSessionSnapshot(getInteractiveTerminalSession(sessionId));
|
|
131
141
|
}
|
|
132
142
|
|
|
133
143
|
/**
|
|
@@ -136,17 +146,19 @@ export function getCodeRunnerAuthenticationSession(
|
|
|
136
146
|
* @param sessionId - Session identifier.
|
|
137
147
|
* @param subscriber - Stream callbacks.
|
|
138
148
|
* @returns Cleanup callback.
|
|
149
|
+
*
|
|
150
|
+
* @private internal utility of Agents Server Harness Auth
|
|
139
151
|
*/
|
|
140
|
-
export function
|
|
152
|
+
export function subscribeToHarnessAuthenticationSession(
|
|
141
153
|
sessionId: string,
|
|
142
|
-
subscriber:
|
|
154
|
+
subscriber: HarnessAuthenticationSessionSubscriber,
|
|
143
155
|
): (() => void) | null {
|
|
144
156
|
return subscribeToInteractiveTerminalSession(sessionId, {
|
|
145
157
|
onOutput: subscriber.onOutput,
|
|
146
158
|
onExit: ({ snapshot }) =>
|
|
147
159
|
subscriber.onExit({
|
|
148
160
|
type: 'exit',
|
|
149
|
-
snapshot:
|
|
161
|
+
snapshot: toRequiredHarnessAuthenticationSessionSnapshot(snapshot),
|
|
150
162
|
}),
|
|
151
163
|
});
|
|
152
164
|
}
|
|
@@ -157,12 +169,14 @@ export function subscribeToCodeRunnerAuthenticationSession(
|
|
|
157
169
|
* @param sessionId - Session identifier.
|
|
158
170
|
* @param input - Raw text to write to stdin.
|
|
159
171
|
* @returns Updated session snapshot.
|
|
172
|
+
*
|
|
173
|
+
* @private internal utility of Agents Server Harness Auth
|
|
160
174
|
*/
|
|
161
|
-
export function
|
|
175
|
+
export function writeHarnessAuthenticationSessionInput(
|
|
162
176
|
sessionId: string,
|
|
163
177
|
input: string,
|
|
164
|
-
):
|
|
165
|
-
return
|
|
178
|
+
): HarnessAuthenticationSessionSnapshot {
|
|
179
|
+
return toRequiredHarnessAuthenticationSessionSnapshot(writeInteractiveTerminalSessionInput(sessionId, input));
|
|
166
180
|
}
|
|
167
181
|
|
|
168
182
|
/**
|
|
@@ -170,41 +184,43 @@ export function writeCodeRunnerAuthenticationSessionInput(
|
|
|
170
184
|
*
|
|
171
185
|
* @param sessionId - Session identifier.
|
|
172
186
|
* @returns Updated session snapshot.
|
|
187
|
+
*
|
|
188
|
+
* @private internal utility of Agents Server Harness Auth
|
|
173
189
|
*/
|
|
174
|
-
export function
|
|
190
|
+
export function stopHarnessAuthenticationSession(
|
|
175
191
|
sessionId: string,
|
|
176
|
-
):
|
|
177
|
-
return
|
|
192
|
+
): HarnessAuthenticationSessionSnapshot {
|
|
193
|
+
return toRequiredHarnessAuthenticationSessionSnapshot(stopInteractiveTerminalSession(sessionId));
|
|
178
194
|
}
|
|
179
195
|
|
|
180
196
|
/**
|
|
181
|
-
* Builds the stable logical session key for one
|
|
197
|
+
* Builds the stable logical session key for one harness authentication terminal.
|
|
182
198
|
*
|
|
183
|
-
* @param
|
|
199
|
+
* @param harness - Harness identifier.
|
|
184
200
|
* @returns Stable session key.
|
|
185
201
|
*/
|
|
186
|
-
function
|
|
187
|
-
return `
|
|
202
|
+
function buildHarnessAuthenticationSessionKey(harness: string): string {
|
|
203
|
+
return `harness-authentication:${harness}`;
|
|
188
204
|
}
|
|
189
205
|
|
|
190
206
|
/**
|
|
191
|
-
* Converts one generic terminal snapshot into the
|
|
207
|
+
* Converts one generic terminal snapshot into the harness-specific browser shape.
|
|
192
208
|
*
|
|
193
209
|
* @param session - Generic terminal snapshot.
|
|
194
|
-
* @param
|
|
195
|
-
* @returns
|
|
210
|
+
* @param fallbackHarness - Harness name used when older sessions miss metadata.
|
|
211
|
+
* @returns Harness-specific snapshot or `null`.
|
|
196
212
|
*/
|
|
197
|
-
function
|
|
213
|
+
function toHarnessAuthenticationSessionSnapshot(
|
|
198
214
|
session: InteractiveTerminalSessionSnapshot | null,
|
|
199
|
-
|
|
200
|
-
):
|
|
215
|
+
fallbackHarness = '',
|
|
216
|
+
): HarnessAuthenticationSessionSnapshot | null {
|
|
201
217
|
if (!session) {
|
|
202
218
|
return null;
|
|
203
219
|
}
|
|
204
220
|
|
|
205
221
|
return {
|
|
206
222
|
id: session.id,
|
|
207
|
-
|
|
223
|
+
harness: session.metadata.harness || session.metadata.agent || fallbackHarness,
|
|
208
224
|
isRunning: session.isRunning,
|
|
209
225
|
output: session.output,
|
|
210
226
|
startedAt: session.startedAt,
|
|
@@ -215,16 +231,16 @@ function toCodeRunnerAuthenticationSessionSnapshot(
|
|
|
215
231
|
}
|
|
216
232
|
|
|
217
233
|
/**
|
|
218
|
-
* Converts one generic terminal snapshot into a required
|
|
234
|
+
* Converts one generic terminal snapshot into a required harness-specific snapshot.
|
|
219
235
|
*
|
|
220
236
|
* @param session - Generic terminal snapshot.
|
|
221
|
-
* @returns
|
|
237
|
+
* @returns Harness-specific snapshot.
|
|
222
238
|
*/
|
|
223
|
-
function
|
|
239
|
+
function toRequiredHarnessAuthenticationSessionSnapshot(
|
|
224
240
|
session: InteractiveTerminalSessionSnapshot | null,
|
|
225
|
-
|
|
226
|
-
):
|
|
227
|
-
const mappedSession =
|
|
241
|
+
fallbackHarness = '',
|
|
242
|
+
): HarnessAuthenticationSessionSnapshot {
|
|
243
|
+
const mappedSession = toHarnessAuthenticationSessionSnapshot(session, fallbackHarness);
|
|
228
244
|
|
|
229
245
|
if (!mappedSession) {
|
|
230
246
|
throw new Error('Authentication session was not found.');
|
|
@@ -5,13 +5,15 @@ import { listVpsEnvironmentVariables } from './vpsConfiguration';
|
|
|
5
5
|
const execFileAsync = promisify(execFile);
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* Saved standalone VPS
|
|
8
|
+
* Saved standalone VPS harness configuration exposed to the admin UI.
|
|
9
|
+
*
|
|
10
|
+
* @private internal utility of Agents Server Harness Auth
|
|
9
11
|
*/
|
|
10
|
-
export type
|
|
12
|
+
export type ConfiguredHarness = {
|
|
11
13
|
/**
|
|
12
|
-
*
|
|
14
|
+
* Harness identifier persisted in `.env`.
|
|
13
15
|
*/
|
|
14
|
-
readonly
|
|
16
|
+
readonly harness: string;
|
|
15
17
|
|
|
16
18
|
/**
|
|
17
19
|
* Model identifier persisted in `.env`.
|
|
@@ -25,11 +27,13 @@ export type ConfiguredCodeRunner = {
|
|
|
25
27
|
};
|
|
26
28
|
|
|
27
29
|
/**
|
|
28
|
-
* Reads the currently configured standalone VPS
|
|
30
|
+
* Reads the currently configured standalone VPS harness from managed environment variables.
|
|
31
|
+
*
|
|
32
|
+
* @returns Saved harness settings with fallback defaults.
|
|
29
33
|
*
|
|
30
|
-
* @
|
|
34
|
+
* @private internal utility of Agents Server Harness Auth
|
|
31
35
|
*/
|
|
32
|
-
export async function
|
|
36
|
+
export async function readConfiguredHarness(): Promise<ConfiguredHarness> {
|
|
33
37
|
const snapshot = await listVpsEnvironmentVariables();
|
|
34
38
|
const environmentByKey = Object.fromEntries(snapshot.variables.map((variable) => [variable.key, variable.value])) as Record<
|
|
35
39
|
string,
|
|
@@ -37,20 +41,22 @@ export async function readConfiguredCodeRunner(): Promise<ConfiguredCodeRunner>
|
|
|
37
41
|
>;
|
|
38
42
|
|
|
39
43
|
return {
|
|
40
|
-
|
|
44
|
+
harness: environmentByKey.PTBK_HARNESS || process.env.PTBK_HARNESS || process.env.PTBK_AGENT || 'github-copilot',
|
|
41
45
|
model: environmentByKey.PTBK_MODEL || process.env.PTBK_MODEL || 'gpt-5.4',
|
|
42
46
|
thinkingLevel: environmentByKey.PTBK_THINKING_LEVEL || process.env.PTBK_THINKING_LEVEL || 'xhigh',
|
|
43
47
|
};
|
|
44
48
|
}
|
|
45
49
|
|
|
46
50
|
/**
|
|
47
|
-
* Resolves a short
|
|
51
|
+
* Resolves a short authentication status for the configured harness.
|
|
48
52
|
*
|
|
49
|
-
* @param
|
|
53
|
+
* @param harness - Harness id.
|
|
50
54
|
* @returns Human-readable status.
|
|
55
|
+
*
|
|
56
|
+
* @private internal utility of Agents Server Harness Auth
|
|
51
57
|
*/
|
|
52
|
-
export async function
|
|
53
|
-
if (
|
|
58
|
+
export async function resolveHarnessStatus(harness: string): Promise<string> {
|
|
59
|
+
if (harness !== 'github-copilot') {
|
|
54
60
|
return 'Status check is currently available for GitHub Copilot CLI only.';
|
|
55
61
|
}
|
|
56
62
|
|
|
@@ -9,7 +9,6 @@ import { getLocalUserChatJobMetadata } from '../localChatRunner/LocalUserChatJob
|
|
|
9
9
|
import { resolveLocalAgentRootPath } from '../localChatRunner/ensureLocalAgentFolder';
|
|
10
10
|
import { listPagePreviewBrowserAdminTasks } from '../pagePreviewBrowserSessions';
|
|
11
11
|
import {
|
|
12
|
-
readVpsSelfUpdateJobSnapshot,
|
|
13
12
|
readVpsSelfUpdateJobTaskSnapshots,
|
|
14
13
|
readVpsSelfUpdateLogFileContent,
|
|
15
14
|
} from '../vpsSelfUpdate';
|
|
@@ -308,8 +307,8 @@ async function resolveVpsSelfUpdateTaskTerminalSession(taskId: string): Promise<
|
|
|
308
307
|
return null;
|
|
309
308
|
}
|
|
310
309
|
|
|
311
|
-
const latestJob =
|
|
312
|
-
const isLatestJob = resolveVpsSelfUpdateJobIdentity(latestJob) === jobIdentity;
|
|
310
|
+
const latestJob = jobSnapshots[0] ?? null;
|
|
311
|
+
const isLatestJob = latestJob !== null && resolveVpsSelfUpdateJobIdentity(latestJob) === jobIdentity;
|
|
313
312
|
const output = isLatestJob
|
|
314
313
|
? (await readVpsSelfUpdateLogFileContent()) || ''
|
|
315
314
|
: createArchivedVpsSelfUpdateLogPlaceholder(job);
|
|
@@ -330,13 +329,27 @@ async function resolveVpsSelfUpdateTaskTerminalSession(taskId: string): Promise<
|
|
|
330
329
|
subscribe: createPolledTaskTerminalLogFileSubscribe({
|
|
331
330
|
session,
|
|
332
331
|
readOutput: async () => {
|
|
333
|
-
const latestJobSnapshot = await
|
|
332
|
+
const latestJobSnapshot = await readLatestVpsSelfUpdateTaskSnapshot();
|
|
333
|
+
if (!latestJobSnapshot) {
|
|
334
|
+
return null;
|
|
335
|
+
}
|
|
336
|
+
|
|
334
337
|
const isStillLatestJob = resolveVpsSelfUpdateJobIdentity(latestJobSnapshot) === jobIdentity;
|
|
335
338
|
|
|
336
339
|
return isStillLatestJob ? (await readVpsSelfUpdateLogFileContent()) || '' : null;
|
|
337
340
|
},
|
|
338
341
|
resolveExitSnapshot: async (knownOutput) => {
|
|
339
|
-
const latestJobSnapshot = await
|
|
342
|
+
const latestJobSnapshot = await readLatestVpsSelfUpdateTaskSnapshot();
|
|
343
|
+
if (!latestJobSnapshot) {
|
|
344
|
+
return {
|
|
345
|
+
...session,
|
|
346
|
+
isRunning: false,
|
|
347
|
+
output: knownOutput,
|
|
348
|
+
finishedAt: new Date().toISOString(),
|
|
349
|
+
exitCode: 1,
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
|
|
340
353
|
const isStillLatestJob = resolveVpsSelfUpdateJobIdentity(latestJobSnapshot) === jobIdentity;
|
|
341
354
|
|
|
342
355
|
if (isStillLatestJob && latestJobSnapshot.status === 'running') {
|
|
@@ -355,6 +368,16 @@ async function resolveVpsSelfUpdateTaskTerminalSession(taskId: string): Promise<
|
|
|
355
368
|
};
|
|
356
369
|
}
|
|
357
370
|
|
|
371
|
+
/**
|
|
372
|
+
* Reads the latest restart-aware standalone VPS self-update task snapshot.
|
|
373
|
+
*
|
|
374
|
+
* @returns Latest self-update task snapshot or `null` when no task snapshot is persisted.
|
|
375
|
+
*/
|
|
376
|
+
async function readLatestVpsSelfUpdateTaskSnapshot(): Promise<VpsSelfUpdateJobSnapshot | null> {
|
|
377
|
+
const jobSnapshots = await readVpsSelfUpdateJobTaskSnapshots();
|
|
378
|
+
return jobSnapshots[0] ?? null;
|
|
379
|
+
}
|
|
380
|
+
|
|
358
381
|
/**
|
|
359
382
|
* Explains why an archived self-update run has no full installer log anymore.
|
|
360
383
|
*
|
|
@@ -284,12 +284,12 @@ export async function applyVpsRuntimeConfiguration(
|
|
|
284
284
|
}
|
|
285
285
|
|
|
286
286
|
/**
|
|
287
|
-
* Installs/configures the selected local
|
|
287
|
+
* Installs/configures the selected local harness through the shared VPS installer script.
|
|
288
288
|
*
|
|
289
289
|
* @returns Command output or a skipped reason when not running on a Linux VPS.
|
|
290
290
|
*/
|
|
291
|
-
export async function
|
|
292
|
-
return runVpsInstallerCommand('apply-runner', 'VPS
|
|
291
|
+
export async function applyVpsHarnessConfiguration(): Promise<VpsCommandResult> {
|
|
292
|
+
return runVpsInstallerCommand('apply-runner', 'VPS harness configuration can only be applied on Linux.');
|
|
293
293
|
}
|
|
294
294
|
|
|
295
295
|
/**
|