@aitherium/shell-cli 1.1.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/auth.d.ts +68 -0
- package/dist/auth.js +288 -0
- package/dist/client.d.ts +116 -0
- package/dist/client.js +528 -0
- package/dist/command-registry.d.ts +71 -0
- package/dist/command-registry.js +223 -0
- package/dist/commands.d.ts +14 -0
- package/dist/commands.js +6785 -0
- package/dist/completions.d.ts +27 -0
- package/dist/completions.js +351 -0
- package/dist/config.d.ts +23 -0
- package/dist/config.js +48 -0
- package/dist/gargbot.d.ts +11 -0
- package/dist/gargbot.js +230 -0
- package/dist/jobs.d.ts +65 -0
- package/dist/jobs.js +386 -0
- package/dist/main.d.ts +2 -0
- package/dist/main.js +389 -0
- package/dist/notebooks.d.ts +19 -0
- package/dist/notebooks.js +685 -0
- package/dist/products.d.ts +12 -0
- package/dist/products.js +159 -0
- package/dist/renderer.d.ts +104 -0
- package/dist/renderer.js +1812 -0
- package/dist/repl.d.ts +16 -0
- package/dist/repl.js +1190 -0
- package/dist/session-store.d.ts +35 -0
- package/dist/session-store.js +153 -0
- package/dist/tunnel.d.ts +13 -0
- package/dist/tunnel.js +169 -0
- package/package.json +36 -0
package/dist/auth.d.ts
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AitherShell CLI Authentication
|
|
3
|
+
* ================================
|
|
4
|
+
*
|
|
5
|
+
* Manages ~/.aither/auth.json — shared with the Python CLI.
|
|
6
|
+
* Multi-profile support (local, cloud, enterprise).
|
|
7
|
+
*/
|
|
8
|
+
export interface AuthUser {
|
|
9
|
+
id: string;
|
|
10
|
+
username: string;
|
|
11
|
+
display_name: string;
|
|
12
|
+
email: string;
|
|
13
|
+
roles: string[];
|
|
14
|
+
tenant_id: string;
|
|
15
|
+
tenant_slug: string;
|
|
16
|
+
}
|
|
17
|
+
export interface AuthProfile {
|
|
18
|
+
endpoint: string;
|
|
19
|
+
genesis_url: string;
|
|
20
|
+
token_type: string;
|
|
21
|
+
access_token: string;
|
|
22
|
+
expires_at: string;
|
|
23
|
+
user: AuthUser;
|
|
24
|
+
}
|
|
25
|
+
export interface AuthStoreData {
|
|
26
|
+
version: number;
|
|
27
|
+
active_profile: string;
|
|
28
|
+
profiles: Record<string, AuthProfile>;
|
|
29
|
+
}
|
|
30
|
+
export declare function loadAuth(): AuthStoreData | null;
|
|
31
|
+
export declare function saveAuth(store: AuthStoreData): void;
|
|
32
|
+
export declare function getActiveProfile(): AuthProfile | null;
|
|
33
|
+
export declare function getActiveToken(): string | null;
|
|
34
|
+
export declare function getActiveUser(): AuthUser | null;
|
|
35
|
+
export declare function setProfile(name: string, profile: AuthProfile): void;
|
|
36
|
+
export declare function clearProfile(name: string): void;
|
|
37
|
+
/**
|
|
38
|
+
* Ensure a root profile exists for local sessions.
|
|
39
|
+
* If no auth.json exists or token is expired, provision root.
|
|
40
|
+
* Like Linux auto-login as root on the console.
|
|
41
|
+
*/
|
|
42
|
+
export declare function ensureRootProfile(): AuthProfile;
|
|
43
|
+
export declare function loginWithPassword(endpoint: string, username: string, password: string): Promise<any>;
|
|
44
|
+
export declare function verify2FA(endpoint: string, tempToken: string, code: string): Promise<any>;
|
|
45
|
+
export declare function register(endpoint: string, username: string, password: string, email: string, inviteCode?: string): Promise<any>;
|
|
46
|
+
export declare function validateToken(endpoint: string, token: string): Promise<any | null>;
|
|
47
|
+
export declare function logoutSession(endpoint: string, token: string): Promise<void>;
|
|
48
|
+
export declare function requestEmailOTP(endpoint: string, usernameOrEmail: string): Promise<{
|
|
49
|
+
otp_token: string;
|
|
50
|
+
message: string;
|
|
51
|
+
}>;
|
|
52
|
+
export declare function verifyEmailOTP(endpoint: string, otpToken: string, code: string): Promise<any>;
|
|
53
|
+
export interface DeviceCodeResponse {
|
|
54
|
+
device_code: string;
|
|
55
|
+
user_code: string;
|
|
56
|
+
verification_uri: string;
|
|
57
|
+
verification_uri_complete: string;
|
|
58
|
+
expires_in: number;
|
|
59
|
+
interval: number;
|
|
60
|
+
}
|
|
61
|
+
export declare function requestDeviceCode(endpoint: string, clientName?: string): Promise<DeviceCodeResponse>;
|
|
62
|
+
export declare function pollDeviceToken(endpoint: string, deviceCode: string): Promise<{
|
|
63
|
+
status: string;
|
|
64
|
+
access_token?: string;
|
|
65
|
+
user?: any;
|
|
66
|
+
expires_at?: string;
|
|
67
|
+
}>;
|
|
68
|
+
export declare function buildProfile(endpoint: string, genesisUrl: string, data: any): AuthProfile;
|
package/dist/auth.js
ADDED
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AitherShell CLI Authentication
|
|
3
|
+
* ================================
|
|
4
|
+
*
|
|
5
|
+
* Manages ~/.aither/auth.json — shared with the Python CLI.
|
|
6
|
+
* Multi-profile support (local, cloud, enterprise).
|
|
7
|
+
*/
|
|
8
|
+
import { readFileSync, writeFileSync, mkdirSync, chmodSync, existsSync } from 'node:fs';
|
|
9
|
+
import { join } from 'node:path';
|
|
10
|
+
import { homedir } from 'node:os';
|
|
11
|
+
const AUTH_FILE = join(homedir(), '.aither', 'auth.json');
|
|
12
|
+
const AUTH_VERSION = 1;
|
|
13
|
+
/* ── Store operations ────────────────────────────────────────── */
|
|
14
|
+
export function loadAuth() {
|
|
15
|
+
if (!existsSync(AUTH_FILE))
|
|
16
|
+
return null;
|
|
17
|
+
try {
|
|
18
|
+
const data = JSON.parse(readFileSync(AUTH_FILE, 'utf-8'));
|
|
19
|
+
if (!data || data.version !== AUTH_VERSION)
|
|
20
|
+
return null;
|
|
21
|
+
return data;
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export function saveAuth(store) {
|
|
28
|
+
const dir = join(homedir(), '.aither');
|
|
29
|
+
if (!existsSync(dir))
|
|
30
|
+
mkdirSync(dir, { recursive: true });
|
|
31
|
+
store.version = AUTH_VERSION;
|
|
32
|
+
writeFileSync(AUTH_FILE, JSON.stringify(store, null, 2), 'utf-8');
|
|
33
|
+
try {
|
|
34
|
+
chmodSync(AUTH_FILE, 0o600);
|
|
35
|
+
}
|
|
36
|
+
catch { /* Windows */ }
|
|
37
|
+
}
|
|
38
|
+
export function getActiveProfile() {
|
|
39
|
+
const store = loadAuth();
|
|
40
|
+
if (!store)
|
|
41
|
+
return null;
|
|
42
|
+
const name = store.active_profile || 'local';
|
|
43
|
+
return store.profiles?.[name] ?? null;
|
|
44
|
+
}
|
|
45
|
+
export function getActiveToken() {
|
|
46
|
+
const profile = getActiveProfile();
|
|
47
|
+
if (!profile?.access_token)
|
|
48
|
+
return null;
|
|
49
|
+
if (profile.expires_at) {
|
|
50
|
+
try {
|
|
51
|
+
const exp = new Date(profile.expires_at);
|
|
52
|
+
if (exp < new Date())
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
catch { /* ignore parse errors */ }
|
|
56
|
+
}
|
|
57
|
+
return profile.access_token;
|
|
58
|
+
}
|
|
59
|
+
export function getActiveUser() {
|
|
60
|
+
const profile = getActiveProfile();
|
|
61
|
+
return profile?.user ?? null;
|
|
62
|
+
}
|
|
63
|
+
export function setProfile(name, profile) {
|
|
64
|
+
const store = loadAuth() ?? {
|
|
65
|
+
version: AUTH_VERSION,
|
|
66
|
+
active_profile: name,
|
|
67
|
+
profiles: {},
|
|
68
|
+
};
|
|
69
|
+
store.profiles[name] = profile;
|
|
70
|
+
store.active_profile = name;
|
|
71
|
+
saveAuth(store);
|
|
72
|
+
}
|
|
73
|
+
export function clearProfile(name) {
|
|
74
|
+
const store = loadAuth();
|
|
75
|
+
if (!store)
|
|
76
|
+
return;
|
|
77
|
+
delete store.profiles[name];
|
|
78
|
+
if (store.active_profile === name) {
|
|
79
|
+
const remaining = Object.keys(store.profiles);
|
|
80
|
+
store.active_profile = remaining[0] ?? '';
|
|
81
|
+
}
|
|
82
|
+
saveAuth(store);
|
|
83
|
+
}
|
|
84
|
+
/* ── Built-in root account (like Linux UID 0) ────────────────── */
|
|
85
|
+
const ROOT_PROFILE = {
|
|
86
|
+
endpoint: 'local',
|
|
87
|
+
genesis_url: 'https://localhost:8001',
|
|
88
|
+
token_type: 'local',
|
|
89
|
+
access_token: 'aither_root_local',
|
|
90
|
+
expires_at: '',
|
|
91
|
+
user: {
|
|
92
|
+
id: 'root',
|
|
93
|
+
username: 'root',
|
|
94
|
+
display_name: 'root',
|
|
95
|
+
email: '',
|
|
96
|
+
roles: ['admin'],
|
|
97
|
+
tenant_id: '',
|
|
98
|
+
tenant_slug: '',
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* Ensure a root profile exists for local sessions.
|
|
103
|
+
* If no auth.json exists or token is expired, provision root.
|
|
104
|
+
* Like Linux auto-login as root on the console.
|
|
105
|
+
*/
|
|
106
|
+
export function ensureRootProfile() {
|
|
107
|
+
const token = getActiveToken();
|
|
108
|
+
if (token) {
|
|
109
|
+
return getActiveProfile();
|
|
110
|
+
}
|
|
111
|
+
// No valid session — provision root
|
|
112
|
+
setProfile('local', ROOT_PROFILE);
|
|
113
|
+
return ROOT_PROFILE;
|
|
114
|
+
}
|
|
115
|
+
/* ── Auth API calls ──────────────────────────────────────────── */
|
|
116
|
+
export async function loginWithPassword(endpoint, username, password) {
|
|
117
|
+
const resp = await fetch(`${endpoint}/auth/login`, {
|
|
118
|
+
method: 'POST',
|
|
119
|
+
headers: { 'Content-Type': 'application/json' },
|
|
120
|
+
body: JSON.stringify({ username, password }),
|
|
121
|
+
signal: AbortSignal.timeout(15000),
|
|
122
|
+
});
|
|
123
|
+
if (resp.status === 401) {
|
|
124
|
+
const data = await resp.json().catch(() => ({}));
|
|
125
|
+
if (data.requires_2fa)
|
|
126
|
+
return { requires_2fa: true, temp_token: data.temp_token || '' };
|
|
127
|
+
throw new Error('Invalid credentials');
|
|
128
|
+
}
|
|
129
|
+
if (!resp.ok) {
|
|
130
|
+
const text = await resp.text().catch(() => '');
|
|
131
|
+
throw new Error(`Login failed: HTTP ${resp.status} ${text}`);
|
|
132
|
+
}
|
|
133
|
+
return resp.json();
|
|
134
|
+
}
|
|
135
|
+
export async function verify2FA(endpoint, tempToken, code) {
|
|
136
|
+
const resp = await fetch(`${endpoint}/auth/2fa/verify`, {
|
|
137
|
+
method: 'POST',
|
|
138
|
+
headers: { 'Content-Type': 'application/json' },
|
|
139
|
+
body: JSON.stringify({ temp_token: tempToken, code }),
|
|
140
|
+
signal: AbortSignal.timeout(15000),
|
|
141
|
+
});
|
|
142
|
+
if (resp.status === 401)
|
|
143
|
+
throw new Error('Invalid 2FA code');
|
|
144
|
+
if (!resp.ok)
|
|
145
|
+
throw new Error(`2FA verification failed: HTTP ${resp.status}`);
|
|
146
|
+
return resp.json();
|
|
147
|
+
}
|
|
148
|
+
export async function register(endpoint, username, password, email, inviteCode = '') {
|
|
149
|
+
// Check capacity first
|
|
150
|
+
try {
|
|
151
|
+
const cap = await fetch(`${endpoint}/auth/alpha-capacity`, {
|
|
152
|
+
signal: AbortSignal.timeout(5000),
|
|
153
|
+
});
|
|
154
|
+
if (cap.ok) {
|
|
155
|
+
const data = await cap.json();
|
|
156
|
+
if (!data.available)
|
|
157
|
+
throw new Error('Registration is currently closed (alpha capacity reached)');
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
catch (err) {
|
|
161
|
+
if (err.message?.includes('closed'))
|
|
162
|
+
throw err;
|
|
163
|
+
// Endpoint may not exist; proceed
|
|
164
|
+
}
|
|
165
|
+
const body = { username, password, email };
|
|
166
|
+
if (inviteCode)
|
|
167
|
+
body.invite_code = inviteCode;
|
|
168
|
+
const resp = await fetch(`${endpoint}/auth/register`, {
|
|
169
|
+
method: 'POST',
|
|
170
|
+
headers: { 'Content-Type': 'application/json' },
|
|
171
|
+
body: JSON.stringify(body),
|
|
172
|
+
signal: AbortSignal.timeout(15000),
|
|
173
|
+
});
|
|
174
|
+
if (resp.status === 409)
|
|
175
|
+
throw new Error('Username or email already taken');
|
|
176
|
+
if (!resp.ok) {
|
|
177
|
+
const text = await resp.text().catch(() => '');
|
|
178
|
+
throw new Error(`Registration failed: HTTP ${resp.status} ${text}`);
|
|
179
|
+
}
|
|
180
|
+
return resp.json();
|
|
181
|
+
}
|
|
182
|
+
export async function validateToken(endpoint, token) {
|
|
183
|
+
try {
|
|
184
|
+
const resp = await fetch(`${endpoint}/auth/me`, {
|
|
185
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
186
|
+
signal: AbortSignal.timeout(10000),
|
|
187
|
+
});
|
|
188
|
+
if (resp.ok)
|
|
189
|
+
return resp.json();
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
catch {
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
export async function logoutSession(endpoint, token) {
|
|
197
|
+
try {
|
|
198
|
+
await fetch(`${endpoint}/auth/logout`, {
|
|
199
|
+
method: 'POST',
|
|
200
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
201
|
+
signal: AbortSignal.timeout(5000),
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
catch { /* best effort */ }
|
|
205
|
+
}
|
|
206
|
+
/* ── Email OTP ───────────────────────────────────────────────── */
|
|
207
|
+
export async function requestEmailOTP(endpoint, usernameOrEmail) {
|
|
208
|
+
const body = {};
|
|
209
|
+
if (usernameOrEmail.includes('@'))
|
|
210
|
+
body.email = usernameOrEmail;
|
|
211
|
+
else
|
|
212
|
+
body.username = usernameOrEmail;
|
|
213
|
+
const resp = await fetch(`${endpoint}/auth/email-otp/request`, {
|
|
214
|
+
method: 'POST',
|
|
215
|
+
headers: { 'Content-Type': 'application/json' },
|
|
216
|
+
body: JSON.stringify(body),
|
|
217
|
+
signal: AbortSignal.timeout(15000),
|
|
218
|
+
});
|
|
219
|
+
if (!resp.ok)
|
|
220
|
+
throw new Error(`OTP request failed: HTTP ${resp.status}`);
|
|
221
|
+
return resp.json();
|
|
222
|
+
}
|
|
223
|
+
export async function verifyEmailOTP(endpoint, otpToken, code) {
|
|
224
|
+
const resp = await fetch(`${endpoint}/auth/email-otp/verify`, {
|
|
225
|
+
method: 'POST',
|
|
226
|
+
headers: { 'Content-Type': 'application/json' },
|
|
227
|
+
body: JSON.stringify({ otp_token: otpToken, code }),
|
|
228
|
+
signal: AbortSignal.timeout(15000),
|
|
229
|
+
});
|
|
230
|
+
if (resp.status === 401)
|
|
231
|
+
throw new Error('Invalid code');
|
|
232
|
+
if (resp.status === 429)
|
|
233
|
+
throw new Error('Too many attempts');
|
|
234
|
+
if (!resp.ok)
|
|
235
|
+
throw new Error(`OTP verify failed: HTTP ${resp.status}`);
|
|
236
|
+
return resp.json();
|
|
237
|
+
}
|
|
238
|
+
export async function requestDeviceCode(endpoint, clientName = 'AitherShell') {
|
|
239
|
+
const resp = await fetch(`${endpoint}/auth/device/code`, {
|
|
240
|
+
method: 'POST',
|
|
241
|
+
headers: { 'Content-Type': 'application/json' },
|
|
242
|
+
body: JSON.stringify({ client_name: clientName }),
|
|
243
|
+
signal: AbortSignal.timeout(15000),
|
|
244
|
+
});
|
|
245
|
+
if (!resp.ok)
|
|
246
|
+
throw new Error(`Device code request failed: HTTP ${resp.status}`);
|
|
247
|
+
return resp.json();
|
|
248
|
+
}
|
|
249
|
+
export async function pollDeviceToken(endpoint, deviceCode) {
|
|
250
|
+
const resp = await fetch(`${endpoint}/auth/device/token`, {
|
|
251
|
+
method: 'POST',
|
|
252
|
+
headers: { 'Content-Type': 'application/json' },
|
|
253
|
+
body: JSON.stringify({ device_code: deviceCode }),
|
|
254
|
+
signal: AbortSignal.timeout(15000),
|
|
255
|
+
});
|
|
256
|
+
if (resp.status === 400) {
|
|
257
|
+
const data = await resp.json().catch(() => ({}));
|
|
258
|
+
if (data.detail === 'expired_token')
|
|
259
|
+
throw new Error('Device code expired');
|
|
260
|
+
if (data.detail === 'invalid_device_code')
|
|
261
|
+
throw new Error('Invalid device code');
|
|
262
|
+
throw new Error(data.detail || 'Device code error');
|
|
263
|
+
}
|
|
264
|
+
if (!resp.ok)
|
|
265
|
+
throw new Error(`Poll failed: HTTP ${resp.status}`);
|
|
266
|
+
return resp.json();
|
|
267
|
+
}
|
|
268
|
+
/* ── Profile builder ─────────────────────────────────────────── */
|
|
269
|
+
export function buildProfile(endpoint, genesisUrl, data) {
|
|
270
|
+
const token = data.access_token || data.token || '';
|
|
271
|
+
const user = data.user || {};
|
|
272
|
+
return {
|
|
273
|
+
endpoint,
|
|
274
|
+
genesis_url: genesisUrl,
|
|
275
|
+
token_type: data.token_type || 'session',
|
|
276
|
+
access_token: token,
|
|
277
|
+
expires_at: data.expires_at || '',
|
|
278
|
+
user: {
|
|
279
|
+
id: user.id || '',
|
|
280
|
+
username: user.username || '',
|
|
281
|
+
display_name: user.display_name || user.username || '',
|
|
282
|
+
email: user.email || '',
|
|
283
|
+
roles: user.roles || [],
|
|
284
|
+
tenant_id: user.tenant_id || '',
|
|
285
|
+
tenant_slug: user.tenant_slug || '',
|
|
286
|
+
},
|
|
287
|
+
};
|
|
288
|
+
}
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AitherShell HTTP + SSE client.
|
|
3
|
+
* Pure Node.js — no browser APIs, no React.
|
|
4
|
+
*
|
|
5
|
+
* Works against any AitherOS-compatible backend:
|
|
6
|
+
* - Genesis (full AitherOS stack)
|
|
7
|
+
* - ADK server (standalone agent via `adk serve`)
|
|
8
|
+
* - Any server implementing /chat/stream SSE protocol
|
|
9
|
+
*
|
|
10
|
+
* Chat routing is handled by the backend's /chat/stream endpoint.
|
|
11
|
+
* This client is a thin SSE consumer — no trivial intercept,
|
|
12
|
+
* no fallback chains, no Veil dependency.
|
|
13
|
+
*/
|
|
14
|
+
import type { BackendType } from './config.js';
|
|
15
|
+
export interface SSEEvent {
|
|
16
|
+
type: string;
|
|
17
|
+
data: Record<string, any>;
|
|
18
|
+
}
|
|
19
|
+
export interface ClarificationResponse {
|
|
20
|
+
plan_id: string;
|
|
21
|
+
gate_id: string;
|
|
22
|
+
answers: Record<string, string> | string;
|
|
23
|
+
}
|
|
24
|
+
export interface StreamChatOpts {
|
|
25
|
+
agent?: string;
|
|
26
|
+
/** All @mentioned agents (for group-chat fan-out). */
|
|
27
|
+
mentions?: string[];
|
|
28
|
+
sessionId?: string;
|
|
29
|
+
model?: string;
|
|
30
|
+
signal?: AbortSignal;
|
|
31
|
+
/** LLM scheduling priority: 'user' (foreground), 'background', 'batch'. */
|
|
32
|
+
priority?: 'user' | 'background' | 'batch';
|
|
33
|
+
/** Auto-populated when answering a pending clarification gate. */
|
|
34
|
+
clarificationResponse?: ClarificationResponse;
|
|
35
|
+
/** Previous session context for RLM continuity. */
|
|
36
|
+
sessionContext?: {
|
|
37
|
+
summary: string;
|
|
38
|
+
tools_used: string[];
|
|
39
|
+
model: string;
|
|
40
|
+
errors: string[];
|
|
41
|
+
};
|
|
42
|
+
/** Effort level 1-10 for routing (higher = deeper reasoning / quality). */
|
|
43
|
+
effort?: number;
|
|
44
|
+
/** Safety level override: 'unrestricted' | 'casual' | 'professional'. */
|
|
45
|
+
safetyLevel?: string;
|
|
46
|
+
/** Private mode — hides prompt from logging/training. */
|
|
47
|
+
privateMode?: boolean;
|
|
48
|
+
/** Base64 data URL image attachments for vision analysis. */
|
|
49
|
+
attachments?: string[];
|
|
50
|
+
/** Max effort cap (prevents agentic upgrade at 7+). undefined = uncapped. */
|
|
51
|
+
maxEffort?: number;
|
|
52
|
+
}
|
|
53
|
+
export interface BackendInfo {
|
|
54
|
+
type: BackendType;
|
|
55
|
+
name: string;
|
|
56
|
+
version?: string;
|
|
57
|
+
agent?: string;
|
|
58
|
+
llmBackend?: string;
|
|
59
|
+
generationReady?: boolean;
|
|
60
|
+
slotsAvailable?: number;
|
|
61
|
+
services?: number;
|
|
62
|
+
agents?: number;
|
|
63
|
+
}
|
|
64
|
+
export declare class GenesisClient {
|
|
65
|
+
readonly baseUrl: string;
|
|
66
|
+
private _authToken;
|
|
67
|
+
private _tenantId;
|
|
68
|
+
private _userId;
|
|
69
|
+
private _backend;
|
|
70
|
+
constructor(baseUrl: string);
|
|
71
|
+
/** Probe the backend and detect its type (Genesis vs ADK vs unknown). */
|
|
72
|
+
detectBackend(): Promise<BackendInfo>;
|
|
73
|
+
/** Get cached backend info (call detectBackend first). */
|
|
74
|
+
get backend(): BackendInfo | null;
|
|
75
|
+
/** Set auth token for all subsequent requests. */
|
|
76
|
+
setAuthToken(token: string | null, tenantId?: string | null, userId?: string | null): void;
|
|
77
|
+
/** Build auth headers for requests. */
|
|
78
|
+
private authHeaders;
|
|
79
|
+
streamChat(message: string, opts?: StreamChatOpts): AsyncGenerator<SSEEvent>;
|
|
80
|
+
steer(sessionId: string, message: string, action?: 'append' | 'cancel'): Promise<{
|
|
81
|
+
ok: boolean;
|
|
82
|
+
error?: string;
|
|
83
|
+
}>;
|
|
84
|
+
chat(message: string, opts?: {
|
|
85
|
+
agent?: string;
|
|
86
|
+
sessionId?: string;
|
|
87
|
+
}): Promise<any>;
|
|
88
|
+
getStatus(): Promise<any>;
|
|
89
|
+
getServices(): Promise<any>;
|
|
90
|
+
getAgents(): Promise<any>;
|
|
91
|
+
forgeDispatch(task: string, opts?: {
|
|
92
|
+
agent?: string;
|
|
93
|
+
effort?: number;
|
|
94
|
+
}): Promise<any>;
|
|
95
|
+
getLogs(limit?: number, level?: string, service?: string): Promise<any>;
|
|
96
|
+
getLLMStatus(): Promise<any>;
|
|
97
|
+
getGpuStatus(): Promise<{
|
|
98
|
+
zone: string;
|
|
99
|
+
active: boolean;
|
|
100
|
+
} | null>;
|
|
101
|
+
getLLMModels(): Promise<any>;
|
|
102
|
+
private parseErrorResponse;
|
|
103
|
+
getDetailed(path: string): Promise<any>;
|
|
104
|
+
postDetailed(path: string, body?: Record<string, any>): Promise<any>;
|
|
105
|
+
get(path: string): Promise<any>;
|
|
106
|
+
post(path: string, body?: Record<string, any>): Promise<any>;
|
|
107
|
+
put(path: string, body?: Record<string, any>): Promise<any>;
|
|
108
|
+
patch(path: string, body?: Record<string, any>): Promise<any>;
|
|
109
|
+
delete(path: string): Promise<any>;
|
|
110
|
+
/**
|
|
111
|
+
* Read SSE stream from a fetch Response.
|
|
112
|
+
* Mirrors shell-core's parseSSEChunk / createSSEReader.
|
|
113
|
+
*/
|
|
114
|
+
private readSSE;
|
|
115
|
+
private parseBlock;
|
|
116
|
+
}
|