@ai-accounts/ts-core 0.2.1 → 0.3.0-alpha.1
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/index.cjs +134 -1
- package/dist/index.d.cts +164 -1
- package/dist/index.d.ts +164 -1
- package/dist/index.js +134 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -31,6 +31,36 @@ module.exports = __toCommonJS(index_exports);
|
|
|
31
31
|
// src/protocol/wire.ts
|
|
32
32
|
var WIRE_PROTOCOL_VERSION = 1;
|
|
33
33
|
|
|
34
|
+
// src/client/login-stream.ts
|
|
35
|
+
async function* parseSseLoginEvents(response) {
|
|
36
|
+
if (!response.body) return;
|
|
37
|
+
const reader = response.body.getReader();
|
|
38
|
+
const decoder = new TextDecoder();
|
|
39
|
+
let buffer = "";
|
|
40
|
+
try {
|
|
41
|
+
while (true) {
|
|
42
|
+
const { value, done } = await reader.read();
|
|
43
|
+
if (done) break;
|
|
44
|
+
buffer += decoder.decode(value, { stream: true });
|
|
45
|
+
while (true) {
|
|
46
|
+
const sep = buffer.indexOf("\n\n");
|
|
47
|
+
if (sep === -1) break;
|
|
48
|
+
const frame = buffer.slice(0, sep);
|
|
49
|
+
buffer = buffer.slice(sep + 2);
|
|
50
|
+
const dataLine = frame.split("\n").find((l) => l.startsWith("data: "));
|
|
51
|
+
if (!dataLine) continue;
|
|
52
|
+
const payload = dataLine.slice(6);
|
|
53
|
+
try {
|
|
54
|
+
yield JSON.parse(payload);
|
|
55
|
+
} catch {
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
} finally {
|
|
60
|
+
reader.releaseLock();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
34
64
|
// src/client/index.ts
|
|
35
65
|
async function toError(r) {
|
|
36
66
|
let code = "http_error";
|
|
@@ -55,7 +85,11 @@ var AiAccountsClient = class {
|
|
|
55
85
|
constructor(opts) {
|
|
56
86
|
this.baseUrl = opts.baseUrl.replace(/\/$/, "");
|
|
57
87
|
this.token = opts.token;
|
|
58
|
-
|
|
88
|
+
if (opts.fetch) {
|
|
89
|
+
this._fetch = opts.fetch;
|
|
90
|
+
} else {
|
|
91
|
+
this._fetch = (input, init) => fetch(input, init);
|
|
92
|
+
}
|
|
59
93
|
}
|
|
60
94
|
headers() {
|
|
61
95
|
const h = { "content-type": "application/json" };
|
|
@@ -126,6 +160,55 @@ var AiAccountsClient = class {
|
|
|
126
160
|
async validateBackend(id) {
|
|
127
161
|
return this.postAction(id, "validate");
|
|
128
162
|
}
|
|
163
|
+
async beginLogin(accountId, flowKind, inputs) {
|
|
164
|
+
const r = await this._fetch(
|
|
165
|
+
`${this.baseUrl}/api/v1/backends/${encodeURIComponent(accountId)}/login/begin`,
|
|
166
|
+
{
|
|
167
|
+
method: "POST",
|
|
168
|
+
headers: this.headers(),
|
|
169
|
+
body: JSON.stringify({ flow_kind: flowKind, inputs })
|
|
170
|
+
}
|
|
171
|
+
);
|
|
172
|
+
if (!r.ok) throw await toError(r);
|
|
173
|
+
return await r.json();
|
|
174
|
+
}
|
|
175
|
+
async respondLogin(accountId, sessionId, promptId, answer) {
|
|
176
|
+
const r = await this._fetch(
|
|
177
|
+
`${this.baseUrl}/api/v1/backends/${encodeURIComponent(accountId)}/login/respond`,
|
|
178
|
+
{
|
|
179
|
+
method: "POST",
|
|
180
|
+
headers: this.headers(),
|
|
181
|
+
body: JSON.stringify({ session_id: sessionId, prompt_id: promptId, answer })
|
|
182
|
+
}
|
|
183
|
+
);
|
|
184
|
+
if (!r.ok) throw await toError(r);
|
|
185
|
+
}
|
|
186
|
+
async cancelLogin(accountId, sessionId) {
|
|
187
|
+
const r = await this._fetch(
|
|
188
|
+
`${this.baseUrl}/api/v1/backends/${encodeURIComponent(accountId)}/login/cancel`,
|
|
189
|
+
{
|
|
190
|
+
method: "POST",
|
|
191
|
+
headers: this.headers(),
|
|
192
|
+
body: JSON.stringify({ session_id: sessionId })
|
|
193
|
+
}
|
|
194
|
+
);
|
|
195
|
+
if (!r.ok) throw await toError(r);
|
|
196
|
+
}
|
|
197
|
+
async *streamLogin(accountId, sessionId) {
|
|
198
|
+
const url = `${this.baseUrl}/api/v1/backends/${encodeURIComponent(accountId)}/login/stream?session_id=${encodeURIComponent(sessionId)}`;
|
|
199
|
+
const headers = { Accept: "text/event-stream" };
|
|
200
|
+
if (this.token) headers["authorization"] = `Bearer ${this.token}`;
|
|
201
|
+
const r = await this._fetch(url, { method: "GET", headers });
|
|
202
|
+
if (!r.ok) throw await toError(r);
|
|
203
|
+
yield* parseSseLoginEvents(r);
|
|
204
|
+
}
|
|
205
|
+
async getBackendMetadata() {
|
|
206
|
+
const r = await this._fetch(`${this.baseUrl}/api/v1/backends/_meta`, {
|
|
207
|
+
headers: this.headers()
|
|
208
|
+
});
|
|
209
|
+
if (!r.ok) throw await toError(r);
|
|
210
|
+
return await r.json();
|
|
211
|
+
}
|
|
129
212
|
async startOnboarding() {
|
|
130
213
|
const r = await this._fetch(`${this.baseUrl}/api/v1/onboarding`, {
|
|
131
214
|
method: "POST",
|
|
@@ -163,6 +246,56 @@ var AiAccountsClient = class {
|
|
|
163
246
|
async finalizeOnboarding(id) {
|
|
164
247
|
return this.onboardingAction(id, "finalize");
|
|
165
248
|
}
|
|
249
|
+
// --- Backend CLI install ---
|
|
250
|
+
async installBackendCli(kind) {
|
|
251
|
+
const r = await this._fetch(
|
|
252
|
+
`${this.baseUrl}/api/v1/backends/${encodeURIComponent(kind)}/install`,
|
|
253
|
+
{
|
|
254
|
+
method: "POST",
|
|
255
|
+
headers: this.headers()
|
|
256
|
+
}
|
|
257
|
+
);
|
|
258
|
+
if (!r.ok) throw await toError(r);
|
|
259
|
+
return await r.json();
|
|
260
|
+
}
|
|
261
|
+
// --- CLIProxyAPI ---
|
|
262
|
+
async cliproxyStatus() {
|
|
263
|
+
const r = await this._fetch(`${this.baseUrl}/api/v1/cliproxy/status`, {
|
|
264
|
+
method: "GET",
|
|
265
|
+
headers: this.headers()
|
|
266
|
+
});
|
|
267
|
+
if (!r.ok) throw await toError(r);
|
|
268
|
+
return await r.json();
|
|
269
|
+
}
|
|
270
|
+
async cliproxyInstall() {
|
|
271
|
+
const r = await this._fetch(`${this.baseUrl}/api/v1/cliproxy/install`, {
|
|
272
|
+
method: "POST",
|
|
273
|
+
headers: this.headers()
|
|
274
|
+
});
|
|
275
|
+
if (!r.ok) throw await toError(r);
|
|
276
|
+
return await r.json();
|
|
277
|
+
}
|
|
278
|
+
async cliproxyLoginBegin(backendKind, configDir) {
|
|
279
|
+
const r = await this._fetch(`${this.baseUrl}/api/v1/cliproxy/login/begin`, {
|
|
280
|
+
method: "POST",
|
|
281
|
+
headers: this.headers(),
|
|
282
|
+
body: JSON.stringify({ backend_kind: backendKind, config_dir: configDir ?? null })
|
|
283
|
+
});
|
|
284
|
+
if (!r.ok) throw await toError(r);
|
|
285
|
+
return await r.json();
|
|
286
|
+
}
|
|
287
|
+
async cliproxyCallbackForward(callbackUrl) {
|
|
288
|
+
const r = await this._fetch(
|
|
289
|
+
`${this.baseUrl}/api/v1/cliproxy/login/callback-forward`,
|
|
290
|
+
{
|
|
291
|
+
method: "POST",
|
|
292
|
+
headers: this.headers(),
|
|
293
|
+
body: JSON.stringify({ callback_url: callbackUrl })
|
|
294
|
+
}
|
|
295
|
+
);
|
|
296
|
+
if (!r.ok) throw await toError(r);
|
|
297
|
+
return await r.json();
|
|
298
|
+
}
|
|
166
299
|
async postAction(id, action, body) {
|
|
167
300
|
const r = await this._fetch(
|
|
168
301
|
`${this.baseUrl}/api/v1/backends/${encodeURIComponent(id)}/${action}`,
|
package/dist/index.d.cts
CHANGED
|
@@ -61,6 +61,115 @@ interface ErrorEvent {
|
|
|
61
61
|
}
|
|
62
62
|
type WireEvent = SessionStartEvent | SessionEndEvent | ChatTokenEvent | ChatToolCallEvent | ChatDoneEvent | PtyOutputEvent | PtyResizeEvent | PtyExitEvent | ErrorEvent;
|
|
63
63
|
|
|
64
|
+
type UrlPrompt = {
|
|
65
|
+
type: 'url_prompt';
|
|
66
|
+
prompt_id: string;
|
|
67
|
+
url: string;
|
|
68
|
+
user_code?: string | null;
|
|
69
|
+
};
|
|
70
|
+
type TextPrompt = {
|
|
71
|
+
type: 'text_prompt';
|
|
72
|
+
prompt_id: string;
|
|
73
|
+
prompt: string;
|
|
74
|
+
hidden: boolean;
|
|
75
|
+
};
|
|
76
|
+
type StdoutChunk = {
|
|
77
|
+
type: 'stdout';
|
|
78
|
+
text: string;
|
|
79
|
+
};
|
|
80
|
+
type ProgressUpdate = {
|
|
81
|
+
type: 'progress';
|
|
82
|
+
label: string;
|
|
83
|
+
percent?: number | null;
|
|
84
|
+
};
|
|
85
|
+
type LoginComplete = {
|
|
86
|
+
type: 'complete';
|
|
87
|
+
account_id: string;
|
|
88
|
+
backend_status: string;
|
|
89
|
+
};
|
|
90
|
+
type LoginFailed = {
|
|
91
|
+
type: 'failed';
|
|
92
|
+
code: string;
|
|
93
|
+
message: string;
|
|
94
|
+
};
|
|
95
|
+
type LoginEvent = UrlPrompt | TextPrompt | StdoutChunk | ProgressUpdate | LoginComplete | LoginFailed;
|
|
96
|
+
type PromptAnswer = {
|
|
97
|
+
prompt_id: string;
|
|
98
|
+
answer: string;
|
|
99
|
+
};
|
|
100
|
+
type LoginFlowKind = 'api_key' | 'oauth_device' | 'cli_browser';
|
|
101
|
+
|
|
102
|
+
type InstallCheck = {
|
|
103
|
+
command: string[];
|
|
104
|
+
version_regex: string;
|
|
105
|
+
};
|
|
106
|
+
type InputSpec = {
|
|
107
|
+
name: string;
|
|
108
|
+
label: string;
|
|
109
|
+
kind: 'text' | 'secret' | 'email' | 'path';
|
|
110
|
+
placeholder?: string | null;
|
|
111
|
+
};
|
|
112
|
+
type LoginFlowSpec = {
|
|
113
|
+
kind: string;
|
|
114
|
+
display_name: string;
|
|
115
|
+
description: string;
|
|
116
|
+
requires_inputs: InputSpec[];
|
|
117
|
+
};
|
|
118
|
+
type PlanOption = {
|
|
119
|
+
id: string;
|
|
120
|
+
label: string;
|
|
121
|
+
description: string;
|
|
122
|
+
};
|
|
123
|
+
type BackendMetadata = {
|
|
124
|
+
kind: string;
|
|
125
|
+
display_name: string;
|
|
126
|
+
icon_url: string | null;
|
|
127
|
+
install_check: InstallCheck;
|
|
128
|
+
login_flows: LoginFlowSpec[];
|
|
129
|
+
plan_options: PlanOption[] | null;
|
|
130
|
+
config_schema: Record<string, unknown>;
|
|
131
|
+
supports_multi_account: boolean;
|
|
132
|
+
isolation_env_var: string | null;
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Types for backend CLI install + CLIProxyAPI install/login flows.
|
|
137
|
+
*
|
|
138
|
+
* Mirror of Python models in `ai_accounts.core.cli_install` /
|
|
139
|
+
* `ai_accounts.core.cliproxy_manager` and the Litestar route responses.
|
|
140
|
+
*/
|
|
141
|
+
type InstallResult = {
|
|
142
|
+
kind: string;
|
|
143
|
+
success: boolean;
|
|
144
|
+
display: string;
|
|
145
|
+
stdout: string;
|
|
146
|
+
stderr: string;
|
|
147
|
+
exit_code: number;
|
|
148
|
+
binary_path: string | null;
|
|
149
|
+
};
|
|
150
|
+
type CliproxyStatus = {
|
|
151
|
+
installed: boolean;
|
|
152
|
+
version: string | null;
|
|
153
|
+
binary_path: string | null;
|
|
154
|
+
};
|
|
155
|
+
type CliproxyInstallResult = {
|
|
156
|
+
success: boolean;
|
|
157
|
+
display: string;
|
|
158
|
+
stdout: string;
|
|
159
|
+
stderr: string;
|
|
160
|
+
binary_path: string | null;
|
|
161
|
+
};
|
|
162
|
+
type CliproxyLoginBeginResponse = {
|
|
163
|
+
status: 'started' | 'imported' | 'skipped' | 'error';
|
|
164
|
+
message: string;
|
|
165
|
+
oauth_url?: string | null;
|
|
166
|
+
device_code?: string | null;
|
|
167
|
+
};
|
|
168
|
+
type CliproxyCallbackForwardResponse = {
|
|
169
|
+
status: 'completed' | 'error';
|
|
170
|
+
message: string;
|
|
171
|
+
};
|
|
172
|
+
|
|
64
173
|
/**
|
|
65
174
|
* This file was auto-generated by openapi-typescript.
|
|
66
175
|
* Do not make direct changes to the file.
|
|
@@ -1074,6 +1183,15 @@ declare class AiAccountsClient {
|
|
|
1074
1183
|
loginBackend(id: string, flowKind: string, inputs: Record<string, string>): Promise<LoginResponseDTO>;
|
|
1075
1184
|
pollBackendLogin(id: string, handle: string): Promise<LoginResponseDTO>;
|
|
1076
1185
|
validateBackend(id: string): Promise<BackendDTO>;
|
|
1186
|
+
beginLogin(accountId: string, flowKind: LoginFlowKind, inputs: Record<string, string>): Promise<{
|
|
1187
|
+
session_id: string;
|
|
1188
|
+
}>;
|
|
1189
|
+
respondLogin(accountId: string, sessionId: string, promptId: string, answer: string): Promise<void>;
|
|
1190
|
+
cancelLogin(accountId: string, sessionId: string): Promise<void>;
|
|
1191
|
+
streamLogin(accountId: string, sessionId: string): AsyncIterable<LoginEvent>;
|
|
1192
|
+
getBackendMetadata(): Promise<{
|
|
1193
|
+
items: BackendMetadata[];
|
|
1194
|
+
}>;
|
|
1077
1195
|
startOnboarding(): Promise<OnboardingStateDTO>;
|
|
1078
1196
|
getOnboarding(id: string): Promise<OnboardingStateDTO>;
|
|
1079
1197
|
detectForOnboarding(id: string): Promise<DetectResultsDTO>;
|
|
@@ -1081,10 +1199,55 @@ declare class AiAccountsClient {
|
|
|
1081
1199
|
beginOnboardingLogin(id: string, flowKind: string, inputs: Record<string, string>): Promise<LoginResponseDTO>;
|
|
1082
1200
|
pollOnboardingLogin(id: string, handle: string): Promise<LoginResponseDTO>;
|
|
1083
1201
|
finalizeOnboarding(id: string): Promise<OnboardingStateDTO>;
|
|
1202
|
+
installBackendCli(kind: string): Promise<InstallResult>;
|
|
1203
|
+
cliproxyStatus(): Promise<CliproxyStatus>;
|
|
1204
|
+
cliproxyInstall(): Promise<CliproxyInstallResult>;
|
|
1205
|
+
cliproxyLoginBegin(backendKind: string, configDir?: string): Promise<CliproxyLoginBeginResponse>;
|
|
1206
|
+
cliproxyCallbackForward(callbackUrl: string): Promise<CliproxyCallbackForwardResponse>;
|
|
1084
1207
|
private postAction;
|
|
1085
1208
|
private onboardingAction;
|
|
1086
1209
|
}
|
|
1087
1210
|
|
|
1211
|
+
type AiAccountsEvent = {
|
|
1212
|
+
type: 'wizard.opened';
|
|
1213
|
+
backendKind: string;
|
|
1214
|
+
} | {
|
|
1215
|
+
type: 'wizard.step';
|
|
1216
|
+
backendKind: string;
|
|
1217
|
+
step: string;
|
|
1218
|
+
} | {
|
|
1219
|
+
type: 'wizard.account.created';
|
|
1220
|
+
backendKind: string;
|
|
1221
|
+
accountId: string;
|
|
1222
|
+
} | {
|
|
1223
|
+
type: 'wizard.closed';
|
|
1224
|
+
backendKind: string;
|
|
1225
|
+
reason: 'done' | 'skip' | 'cancel';
|
|
1226
|
+
} | {
|
|
1227
|
+
type: 'login.started';
|
|
1228
|
+
sessionId: string;
|
|
1229
|
+
backendKind: string;
|
|
1230
|
+
flow: string;
|
|
1231
|
+
} | {
|
|
1232
|
+
type: 'login.prompt';
|
|
1233
|
+
sessionId: string;
|
|
1234
|
+
promptKind: 'url' | 'text';
|
|
1235
|
+
} | {
|
|
1236
|
+
type: 'login.completed';
|
|
1237
|
+
sessionId: string;
|
|
1238
|
+
accountId: string;
|
|
1239
|
+
} | {
|
|
1240
|
+
type: 'login.failed';
|
|
1241
|
+
sessionId: string;
|
|
1242
|
+
code: string;
|
|
1243
|
+
message: string;
|
|
1244
|
+
} | {
|
|
1245
|
+
type: 'internal.handler_error';
|
|
1246
|
+
error: string;
|
|
1247
|
+
original: AiAccountsEvent;
|
|
1248
|
+
};
|
|
1249
|
+
type AiAccountsEventHandler = (event: AiAccountsEvent) => void;
|
|
1250
|
+
|
|
1088
1251
|
type WizardState = 'idle' | 'picking_kind' | 'detecting' | 'entering_credential' | 'validating' | 'done' | 'error';
|
|
1089
1252
|
interface AccountWizard {
|
|
1090
1253
|
readonly state: WizardState;
|
|
@@ -1134,4 +1297,4 @@ declare function createOnboardingFlow(opts: CreateOnboardingFlowOptions): Onboar
|
|
|
1134
1297
|
|
|
1135
1298
|
declare const version = "0.0.0";
|
|
1136
1299
|
|
|
1137
|
-
export { type AccountWizard, type paths as AiAccountsApiPaths, AiAccountsClient, type ApiError, type BackendDTO, type ChatDoneEvent, type ChatTokenEvent, type ChatToolCallEvent, type ClientOptions, type CreateAccountWizardOptions, type CreateOnboardingFlowOptions, type DetectResultDTO, type DetectResultsDTO, type ErrorEvent, type LoginResponseDTO, type OAuthDeviceLoginDTO, type OnboardingFlowMachine, type OnboardingMachineState, type OnboardingStateDTO, type PtyExitEvent, type PtyOutputEvent, type PtyResizeEvent, type SessionEndEvent, type SessionStartEvent, WIRE_PROTOCOL_VERSION, type WireEvent, type WizardState, createAccountWizard, createOnboardingFlow, version };
|
|
1300
|
+
export { type AccountWizard, type paths as AiAccountsApiPaths, AiAccountsClient, type AiAccountsEvent, type AiAccountsEventHandler, type ApiError, type BackendDTO, type BackendMetadata, type ChatDoneEvent, type ChatTokenEvent, type ChatToolCallEvent, type ClientOptions, type CliproxyCallbackForwardResponse, type CliproxyInstallResult, type CliproxyLoginBeginResponse, type CliproxyStatus, type CreateAccountWizardOptions, type CreateOnboardingFlowOptions, type DetectResultDTO, type DetectResultsDTO, type ErrorEvent, type InputSpec, type InstallCheck, type InstallResult, type LoginComplete, type LoginEvent, type LoginFailed, type LoginFlowKind, type LoginFlowSpec, type LoginResponseDTO, type OAuthDeviceLoginDTO, type OnboardingFlowMachine, type OnboardingMachineState, type OnboardingStateDTO, type PlanOption, type ProgressUpdate, type PromptAnswer, type PtyExitEvent, type PtyOutputEvent, type PtyResizeEvent, type SessionEndEvent, type SessionStartEvent, type StdoutChunk, type TextPrompt, type UrlPrompt, WIRE_PROTOCOL_VERSION, type WireEvent, type WizardState, createAccountWizard, createOnboardingFlow, version };
|
package/dist/index.d.ts
CHANGED
|
@@ -61,6 +61,115 @@ interface ErrorEvent {
|
|
|
61
61
|
}
|
|
62
62
|
type WireEvent = SessionStartEvent | SessionEndEvent | ChatTokenEvent | ChatToolCallEvent | ChatDoneEvent | PtyOutputEvent | PtyResizeEvent | PtyExitEvent | ErrorEvent;
|
|
63
63
|
|
|
64
|
+
type UrlPrompt = {
|
|
65
|
+
type: 'url_prompt';
|
|
66
|
+
prompt_id: string;
|
|
67
|
+
url: string;
|
|
68
|
+
user_code?: string | null;
|
|
69
|
+
};
|
|
70
|
+
type TextPrompt = {
|
|
71
|
+
type: 'text_prompt';
|
|
72
|
+
prompt_id: string;
|
|
73
|
+
prompt: string;
|
|
74
|
+
hidden: boolean;
|
|
75
|
+
};
|
|
76
|
+
type StdoutChunk = {
|
|
77
|
+
type: 'stdout';
|
|
78
|
+
text: string;
|
|
79
|
+
};
|
|
80
|
+
type ProgressUpdate = {
|
|
81
|
+
type: 'progress';
|
|
82
|
+
label: string;
|
|
83
|
+
percent?: number | null;
|
|
84
|
+
};
|
|
85
|
+
type LoginComplete = {
|
|
86
|
+
type: 'complete';
|
|
87
|
+
account_id: string;
|
|
88
|
+
backend_status: string;
|
|
89
|
+
};
|
|
90
|
+
type LoginFailed = {
|
|
91
|
+
type: 'failed';
|
|
92
|
+
code: string;
|
|
93
|
+
message: string;
|
|
94
|
+
};
|
|
95
|
+
type LoginEvent = UrlPrompt | TextPrompt | StdoutChunk | ProgressUpdate | LoginComplete | LoginFailed;
|
|
96
|
+
type PromptAnswer = {
|
|
97
|
+
prompt_id: string;
|
|
98
|
+
answer: string;
|
|
99
|
+
};
|
|
100
|
+
type LoginFlowKind = 'api_key' | 'oauth_device' | 'cli_browser';
|
|
101
|
+
|
|
102
|
+
type InstallCheck = {
|
|
103
|
+
command: string[];
|
|
104
|
+
version_regex: string;
|
|
105
|
+
};
|
|
106
|
+
type InputSpec = {
|
|
107
|
+
name: string;
|
|
108
|
+
label: string;
|
|
109
|
+
kind: 'text' | 'secret' | 'email' | 'path';
|
|
110
|
+
placeholder?: string | null;
|
|
111
|
+
};
|
|
112
|
+
type LoginFlowSpec = {
|
|
113
|
+
kind: string;
|
|
114
|
+
display_name: string;
|
|
115
|
+
description: string;
|
|
116
|
+
requires_inputs: InputSpec[];
|
|
117
|
+
};
|
|
118
|
+
type PlanOption = {
|
|
119
|
+
id: string;
|
|
120
|
+
label: string;
|
|
121
|
+
description: string;
|
|
122
|
+
};
|
|
123
|
+
type BackendMetadata = {
|
|
124
|
+
kind: string;
|
|
125
|
+
display_name: string;
|
|
126
|
+
icon_url: string | null;
|
|
127
|
+
install_check: InstallCheck;
|
|
128
|
+
login_flows: LoginFlowSpec[];
|
|
129
|
+
plan_options: PlanOption[] | null;
|
|
130
|
+
config_schema: Record<string, unknown>;
|
|
131
|
+
supports_multi_account: boolean;
|
|
132
|
+
isolation_env_var: string | null;
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Types for backend CLI install + CLIProxyAPI install/login flows.
|
|
137
|
+
*
|
|
138
|
+
* Mirror of Python models in `ai_accounts.core.cli_install` /
|
|
139
|
+
* `ai_accounts.core.cliproxy_manager` and the Litestar route responses.
|
|
140
|
+
*/
|
|
141
|
+
type InstallResult = {
|
|
142
|
+
kind: string;
|
|
143
|
+
success: boolean;
|
|
144
|
+
display: string;
|
|
145
|
+
stdout: string;
|
|
146
|
+
stderr: string;
|
|
147
|
+
exit_code: number;
|
|
148
|
+
binary_path: string | null;
|
|
149
|
+
};
|
|
150
|
+
type CliproxyStatus = {
|
|
151
|
+
installed: boolean;
|
|
152
|
+
version: string | null;
|
|
153
|
+
binary_path: string | null;
|
|
154
|
+
};
|
|
155
|
+
type CliproxyInstallResult = {
|
|
156
|
+
success: boolean;
|
|
157
|
+
display: string;
|
|
158
|
+
stdout: string;
|
|
159
|
+
stderr: string;
|
|
160
|
+
binary_path: string | null;
|
|
161
|
+
};
|
|
162
|
+
type CliproxyLoginBeginResponse = {
|
|
163
|
+
status: 'started' | 'imported' | 'skipped' | 'error';
|
|
164
|
+
message: string;
|
|
165
|
+
oauth_url?: string | null;
|
|
166
|
+
device_code?: string | null;
|
|
167
|
+
};
|
|
168
|
+
type CliproxyCallbackForwardResponse = {
|
|
169
|
+
status: 'completed' | 'error';
|
|
170
|
+
message: string;
|
|
171
|
+
};
|
|
172
|
+
|
|
64
173
|
/**
|
|
65
174
|
* This file was auto-generated by openapi-typescript.
|
|
66
175
|
* Do not make direct changes to the file.
|
|
@@ -1074,6 +1183,15 @@ declare class AiAccountsClient {
|
|
|
1074
1183
|
loginBackend(id: string, flowKind: string, inputs: Record<string, string>): Promise<LoginResponseDTO>;
|
|
1075
1184
|
pollBackendLogin(id: string, handle: string): Promise<LoginResponseDTO>;
|
|
1076
1185
|
validateBackend(id: string): Promise<BackendDTO>;
|
|
1186
|
+
beginLogin(accountId: string, flowKind: LoginFlowKind, inputs: Record<string, string>): Promise<{
|
|
1187
|
+
session_id: string;
|
|
1188
|
+
}>;
|
|
1189
|
+
respondLogin(accountId: string, sessionId: string, promptId: string, answer: string): Promise<void>;
|
|
1190
|
+
cancelLogin(accountId: string, sessionId: string): Promise<void>;
|
|
1191
|
+
streamLogin(accountId: string, sessionId: string): AsyncIterable<LoginEvent>;
|
|
1192
|
+
getBackendMetadata(): Promise<{
|
|
1193
|
+
items: BackendMetadata[];
|
|
1194
|
+
}>;
|
|
1077
1195
|
startOnboarding(): Promise<OnboardingStateDTO>;
|
|
1078
1196
|
getOnboarding(id: string): Promise<OnboardingStateDTO>;
|
|
1079
1197
|
detectForOnboarding(id: string): Promise<DetectResultsDTO>;
|
|
@@ -1081,10 +1199,55 @@ declare class AiAccountsClient {
|
|
|
1081
1199
|
beginOnboardingLogin(id: string, flowKind: string, inputs: Record<string, string>): Promise<LoginResponseDTO>;
|
|
1082
1200
|
pollOnboardingLogin(id: string, handle: string): Promise<LoginResponseDTO>;
|
|
1083
1201
|
finalizeOnboarding(id: string): Promise<OnboardingStateDTO>;
|
|
1202
|
+
installBackendCli(kind: string): Promise<InstallResult>;
|
|
1203
|
+
cliproxyStatus(): Promise<CliproxyStatus>;
|
|
1204
|
+
cliproxyInstall(): Promise<CliproxyInstallResult>;
|
|
1205
|
+
cliproxyLoginBegin(backendKind: string, configDir?: string): Promise<CliproxyLoginBeginResponse>;
|
|
1206
|
+
cliproxyCallbackForward(callbackUrl: string): Promise<CliproxyCallbackForwardResponse>;
|
|
1084
1207
|
private postAction;
|
|
1085
1208
|
private onboardingAction;
|
|
1086
1209
|
}
|
|
1087
1210
|
|
|
1211
|
+
type AiAccountsEvent = {
|
|
1212
|
+
type: 'wizard.opened';
|
|
1213
|
+
backendKind: string;
|
|
1214
|
+
} | {
|
|
1215
|
+
type: 'wizard.step';
|
|
1216
|
+
backendKind: string;
|
|
1217
|
+
step: string;
|
|
1218
|
+
} | {
|
|
1219
|
+
type: 'wizard.account.created';
|
|
1220
|
+
backendKind: string;
|
|
1221
|
+
accountId: string;
|
|
1222
|
+
} | {
|
|
1223
|
+
type: 'wizard.closed';
|
|
1224
|
+
backendKind: string;
|
|
1225
|
+
reason: 'done' | 'skip' | 'cancel';
|
|
1226
|
+
} | {
|
|
1227
|
+
type: 'login.started';
|
|
1228
|
+
sessionId: string;
|
|
1229
|
+
backendKind: string;
|
|
1230
|
+
flow: string;
|
|
1231
|
+
} | {
|
|
1232
|
+
type: 'login.prompt';
|
|
1233
|
+
sessionId: string;
|
|
1234
|
+
promptKind: 'url' | 'text';
|
|
1235
|
+
} | {
|
|
1236
|
+
type: 'login.completed';
|
|
1237
|
+
sessionId: string;
|
|
1238
|
+
accountId: string;
|
|
1239
|
+
} | {
|
|
1240
|
+
type: 'login.failed';
|
|
1241
|
+
sessionId: string;
|
|
1242
|
+
code: string;
|
|
1243
|
+
message: string;
|
|
1244
|
+
} | {
|
|
1245
|
+
type: 'internal.handler_error';
|
|
1246
|
+
error: string;
|
|
1247
|
+
original: AiAccountsEvent;
|
|
1248
|
+
};
|
|
1249
|
+
type AiAccountsEventHandler = (event: AiAccountsEvent) => void;
|
|
1250
|
+
|
|
1088
1251
|
type WizardState = 'idle' | 'picking_kind' | 'detecting' | 'entering_credential' | 'validating' | 'done' | 'error';
|
|
1089
1252
|
interface AccountWizard {
|
|
1090
1253
|
readonly state: WizardState;
|
|
@@ -1134,4 +1297,4 @@ declare function createOnboardingFlow(opts: CreateOnboardingFlowOptions): Onboar
|
|
|
1134
1297
|
|
|
1135
1298
|
declare const version = "0.0.0";
|
|
1136
1299
|
|
|
1137
|
-
export { type AccountWizard, type paths as AiAccountsApiPaths, AiAccountsClient, type ApiError, type BackendDTO, type ChatDoneEvent, type ChatTokenEvent, type ChatToolCallEvent, type ClientOptions, type CreateAccountWizardOptions, type CreateOnboardingFlowOptions, type DetectResultDTO, type DetectResultsDTO, type ErrorEvent, type LoginResponseDTO, type OAuthDeviceLoginDTO, type OnboardingFlowMachine, type OnboardingMachineState, type OnboardingStateDTO, type PtyExitEvent, type PtyOutputEvent, type PtyResizeEvent, type SessionEndEvent, type SessionStartEvent, WIRE_PROTOCOL_VERSION, type WireEvent, type WizardState, createAccountWizard, createOnboardingFlow, version };
|
|
1300
|
+
export { type AccountWizard, type paths as AiAccountsApiPaths, AiAccountsClient, type AiAccountsEvent, type AiAccountsEventHandler, type ApiError, type BackendDTO, type BackendMetadata, type ChatDoneEvent, type ChatTokenEvent, type ChatToolCallEvent, type ClientOptions, type CliproxyCallbackForwardResponse, type CliproxyInstallResult, type CliproxyLoginBeginResponse, type CliproxyStatus, type CreateAccountWizardOptions, type CreateOnboardingFlowOptions, type DetectResultDTO, type DetectResultsDTO, type ErrorEvent, type InputSpec, type InstallCheck, type InstallResult, type LoginComplete, type LoginEvent, type LoginFailed, type LoginFlowKind, type LoginFlowSpec, type LoginResponseDTO, type OAuthDeviceLoginDTO, type OnboardingFlowMachine, type OnboardingMachineState, type OnboardingStateDTO, type PlanOption, type ProgressUpdate, type PromptAnswer, type PtyExitEvent, type PtyOutputEvent, type PtyResizeEvent, type SessionEndEvent, type SessionStartEvent, type StdoutChunk, type TextPrompt, type UrlPrompt, WIRE_PROTOCOL_VERSION, type WireEvent, type WizardState, createAccountWizard, createOnboardingFlow, version };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,36 @@
|
|
|
1
1
|
// src/protocol/wire.ts
|
|
2
2
|
var WIRE_PROTOCOL_VERSION = 1;
|
|
3
3
|
|
|
4
|
+
// src/client/login-stream.ts
|
|
5
|
+
async function* parseSseLoginEvents(response) {
|
|
6
|
+
if (!response.body) return;
|
|
7
|
+
const reader = response.body.getReader();
|
|
8
|
+
const decoder = new TextDecoder();
|
|
9
|
+
let buffer = "";
|
|
10
|
+
try {
|
|
11
|
+
while (true) {
|
|
12
|
+
const { value, done } = await reader.read();
|
|
13
|
+
if (done) break;
|
|
14
|
+
buffer += decoder.decode(value, { stream: true });
|
|
15
|
+
while (true) {
|
|
16
|
+
const sep = buffer.indexOf("\n\n");
|
|
17
|
+
if (sep === -1) break;
|
|
18
|
+
const frame = buffer.slice(0, sep);
|
|
19
|
+
buffer = buffer.slice(sep + 2);
|
|
20
|
+
const dataLine = frame.split("\n").find((l) => l.startsWith("data: "));
|
|
21
|
+
if (!dataLine) continue;
|
|
22
|
+
const payload = dataLine.slice(6);
|
|
23
|
+
try {
|
|
24
|
+
yield JSON.parse(payload);
|
|
25
|
+
} catch {
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
} finally {
|
|
30
|
+
reader.releaseLock();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
4
34
|
// src/client/index.ts
|
|
5
35
|
async function toError(r) {
|
|
6
36
|
let code = "http_error";
|
|
@@ -25,7 +55,11 @@ var AiAccountsClient = class {
|
|
|
25
55
|
constructor(opts) {
|
|
26
56
|
this.baseUrl = opts.baseUrl.replace(/\/$/, "");
|
|
27
57
|
this.token = opts.token;
|
|
28
|
-
|
|
58
|
+
if (opts.fetch) {
|
|
59
|
+
this._fetch = opts.fetch;
|
|
60
|
+
} else {
|
|
61
|
+
this._fetch = (input, init) => fetch(input, init);
|
|
62
|
+
}
|
|
29
63
|
}
|
|
30
64
|
headers() {
|
|
31
65
|
const h = { "content-type": "application/json" };
|
|
@@ -96,6 +130,55 @@ var AiAccountsClient = class {
|
|
|
96
130
|
async validateBackend(id) {
|
|
97
131
|
return this.postAction(id, "validate");
|
|
98
132
|
}
|
|
133
|
+
async beginLogin(accountId, flowKind, inputs) {
|
|
134
|
+
const r = await this._fetch(
|
|
135
|
+
`${this.baseUrl}/api/v1/backends/${encodeURIComponent(accountId)}/login/begin`,
|
|
136
|
+
{
|
|
137
|
+
method: "POST",
|
|
138
|
+
headers: this.headers(),
|
|
139
|
+
body: JSON.stringify({ flow_kind: flowKind, inputs })
|
|
140
|
+
}
|
|
141
|
+
);
|
|
142
|
+
if (!r.ok) throw await toError(r);
|
|
143
|
+
return await r.json();
|
|
144
|
+
}
|
|
145
|
+
async respondLogin(accountId, sessionId, promptId, answer) {
|
|
146
|
+
const r = await this._fetch(
|
|
147
|
+
`${this.baseUrl}/api/v1/backends/${encodeURIComponent(accountId)}/login/respond`,
|
|
148
|
+
{
|
|
149
|
+
method: "POST",
|
|
150
|
+
headers: this.headers(),
|
|
151
|
+
body: JSON.stringify({ session_id: sessionId, prompt_id: promptId, answer })
|
|
152
|
+
}
|
|
153
|
+
);
|
|
154
|
+
if (!r.ok) throw await toError(r);
|
|
155
|
+
}
|
|
156
|
+
async cancelLogin(accountId, sessionId) {
|
|
157
|
+
const r = await this._fetch(
|
|
158
|
+
`${this.baseUrl}/api/v1/backends/${encodeURIComponent(accountId)}/login/cancel`,
|
|
159
|
+
{
|
|
160
|
+
method: "POST",
|
|
161
|
+
headers: this.headers(),
|
|
162
|
+
body: JSON.stringify({ session_id: sessionId })
|
|
163
|
+
}
|
|
164
|
+
);
|
|
165
|
+
if (!r.ok) throw await toError(r);
|
|
166
|
+
}
|
|
167
|
+
async *streamLogin(accountId, sessionId) {
|
|
168
|
+
const url = `${this.baseUrl}/api/v1/backends/${encodeURIComponent(accountId)}/login/stream?session_id=${encodeURIComponent(sessionId)}`;
|
|
169
|
+
const headers = { Accept: "text/event-stream" };
|
|
170
|
+
if (this.token) headers["authorization"] = `Bearer ${this.token}`;
|
|
171
|
+
const r = await this._fetch(url, { method: "GET", headers });
|
|
172
|
+
if (!r.ok) throw await toError(r);
|
|
173
|
+
yield* parseSseLoginEvents(r);
|
|
174
|
+
}
|
|
175
|
+
async getBackendMetadata() {
|
|
176
|
+
const r = await this._fetch(`${this.baseUrl}/api/v1/backends/_meta`, {
|
|
177
|
+
headers: this.headers()
|
|
178
|
+
});
|
|
179
|
+
if (!r.ok) throw await toError(r);
|
|
180
|
+
return await r.json();
|
|
181
|
+
}
|
|
99
182
|
async startOnboarding() {
|
|
100
183
|
const r = await this._fetch(`${this.baseUrl}/api/v1/onboarding`, {
|
|
101
184
|
method: "POST",
|
|
@@ -133,6 +216,56 @@ var AiAccountsClient = class {
|
|
|
133
216
|
async finalizeOnboarding(id) {
|
|
134
217
|
return this.onboardingAction(id, "finalize");
|
|
135
218
|
}
|
|
219
|
+
// --- Backend CLI install ---
|
|
220
|
+
async installBackendCli(kind) {
|
|
221
|
+
const r = await this._fetch(
|
|
222
|
+
`${this.baseUrl}/api/v1/backends/${encodeURIComponent(kind)}/install`,
|
|
223
|
+
{
|
|
224
|
+
method: "POST",
|
|
225
|
+
headers: this.headers()
|
|
226
|
+
}
|
|
227
|
+
);
|
|
228
|
+
if (!r.ok) throw await toError(r);
|
|
229
|
+
return await r.json();
|
|
230
|
+
}
|
|
231
|
+
// --- CLIProxyAPI ---
|
|
232
|
+
async cliproxyStatus() {
|
|
233
|
+
const r = await this._fetch(`${this.baseUrl}/api/v1/cliproxy/status`, {
|
|
234
|
+
method: "GET",
|
|
235
|
+
headers: this.headers()
|
|
236
|
+
});
|
|
237
|
+
if (!r.ok) throw await toError(r);
|
|
238
|
+
return await r.json();
|
|
239
|
+
}
|
|
240
|
+
async cliproxyInstall() {
|
|
241
|
+
const r = await this._fetch(`${this.baseUrl}/api/v1/cliproxy/install`, {
|
|
242
|
+
method: "POST",
|
|
243
|
+
headers: this.headers()
|
|
244
|
+
});
|
|
245
|
+
if (!r.ok) throw await toError(r);
|
|
246
|
+
return await r.json();
|
|
247
|
+
}
|
|
248
|
+
async cliproxyLoginBegin(backendKind, configDir) {
|
|
249
|
+
const r = await this._fetch(`${this.baseUrl}/api/v1/cliproxy/login/begin`, {
|
|
250
|
+
method: "POST",
|
|
251
|
+
headers: this.headers(),
|
|
252
|
+
body: JSON.stringify({ backend_kind: backendKind, config_dir: configDir ?? null })
|
|
253
|
+
});
|
|
254
|
+
if (!r.ok) throw await toError(r);
|
|
255
|
+
return await r.json();
|
|
256
|
+
}
|
|
257
|
+
async cliproxyCallbackForward(callbackUrl) {
|
|
258
|
+
const r = await this._fetch(
|
|
259
|
+
`${this.baseUrl}/api/v1/cliproxy/login/callback-forward`,
|
|
260
|
+
{
|
|
261
|
+
method: "POST",
|
|
262
|
+
headers: this.headers(),
|
|
263
|
+
body: JSON.stringify({ callback_url: callbackUrl })
|
|
264
|
+
}
|
|
265
|
+
);
|
|
266
|
+
if (!r.ok) throw await toError(r);
|
|
267
|
+
return await r.json();
|
|
268
|
+
}
|
|
136
269
|
async postAction(id, action, body) {
|
|
137
270
|
const r = await this._fetch(
|
|
138
271
|
`${this.baseUrl}/api/v1/backends/${encodeURIComponent(id)}/${action}`,
|