@parall/sdk 1.36.1 → 1.37.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/client.d.ts +67 -4
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +118 -3
- package/dist/constants.d.ts +65 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +99 -8
- package/dist/types.d.ts +286 -5
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +211 -2
- package/src/constants.ts +116 -8
- package/src/types.ts +333 -5
package/src/client.ts
CHANGED
|
@@ -41,6 +41,7 @@ import type {
|
|
|
41
41
|
MachineRuntimeAuthState,
|
|
42
42
|
AgentWorkspaceState,
|
|
43
43
|
AgentWorkspaceReportStatus,
|
|
44
|
+
DetectedRuntime,
|
|
44
45
|
BrowseMachineFilesystemResponse,
|
|
45
46
|
FilesystemEntry,
|
|
46
47
|
DaemonAgentConfig,
|
|
@@ -74,6 +75,14 @@ import type {
|
|
|
74
75
|
CreateExternalConnectionInput,
|
|
75
76
|
UpdateExternalConnectionInput,
|
|
76
77
|
ExternalConnectionFilters,
|
|
78
|
+
ChannelConnection,
|
|
79
|
+
ChannelConversation,
|
|
80
|
+
ChannelMessage,
|
|
81
|
+
ChannelCredentialsInput,
|
|
82
|
+
ChannelProvisioningSession,
|
|
83
|
+
CreateChannelConnectionInput,
|
|
84
|
+
InitiateChannelProvisioningInput,
|
|
85
|
+
UpdateChannelConnectionInput,
|
|
77
86
|
ExternalIngressEvent,
|
|
78
87
|
ExternalIngressEventFilters,
|
|
79
88
|
ExternalTrigger,
|
|
@@ -97,6 +106,8 @@ import type {
|
|
|
97
106
|
PlatformConfigResponse,
|
|
98
107
|
Wiki,
|
|
99
108
|
WikiBlob,
|
|
109
|
+
CopyWikiFileRequest,
|
|
110
|
+
CopyWikiFileResponse,
|
|
100
111
|
WikiChangeset,
|
|
101
112
|
WikiFileUploadResponse,
|
|
102
113
|
WikiFilePreviewUrlResponse,
|
|
@@ -163,6 +174,8 @@ import type {
|
|
|
163
174
|
UpdateAutoReloadRequest,
|
|
164
175
|
ComputePricing,
|
|
165
176
|
ComputePricingResponse,
|
|
177
|
+
RuntimeCapability,
|
|
178
|
+
PlatformModelsResponse,
|
|
166
179
|
Clip,
|
|
167
180
|
AgentClip,
|
|
168
181
|
CreateClipRequest,
|
|
@@ -178,6 +191,7 @@ import type {
|
|
|
178
191
|
MachineBrowserProfile,
|
|
179
192
|
BrowserProfileListItem,
|
|
180
193
|
BrowserProfileStatus,
|
|
194
|
+
BrowserRuntimeStatus,
|
|
181
195
|
BrowserProfileConsent,
|
|
182
196
|
CreateBrowserProfileRequest,
|
|
183
197
|
UpdateBrowserProfileRequest,
|
|
@@ -631,6 +645,17 @@ export class ParallClient {
|
|
|
631
645
|
return res.data;
|
|
632
646
|
}
|
|
633
647
|
|
|
648
|
+
/** User IDs of soft-removed (former) org members — for marking their avatar /
|
|
649
|
+
* name as "left" where dormant relations still surface them (DMs, task
|
|
650
|
+
* assignees, message history). */
|
|
651
|
+
async getFormerMemberIds(orgId: string): Promise<string[]> {
|
|
652
|
+
const res = await this.request<{ user_ids: string[] }>(
|
|
653
|
+
'GET',
|
|
654
|
+
ENDPOINTS.ORG_MEMBERS_FORMER(orgId),
|
|
655
|
+
);
|
|
656
|
+
return res.user_ids ?? [];
|
|
657
|
+
}
|
|
658
|
+
|
|
634
659
|
async getTeams(orgId: string): Promise<Team[]> {
|
|
635
660
|
const res = await this.request<{ data: Team[] }>('GET', ENDPOINTS.TEAMS(orgId));
|
|
636
661
|
return res.data;
|
|
@@ -1515,29 +1540,40 @@ export class ParallClient {
|
|
|
1515
1540
|
profileId: string,
|
|
1516
1541
|
status: BrowserProfileStatus,
|
|
1517
1542
|
errorMsg?: string,
|
|
1543
|
+
// The lifecycle generation this report was issued under (captured at op start,
|
|
1544
|
+
// PR #1650). Omitted by pre-generation callers; the server then falls back to
|
|
1545
|
+
// safe-state compatibility. The server no-ops a report older than the row's.
|
|
1546
|
+
generation?: number,
|
|
1518
1547
|
): Promise<void> {
|
|
1519
1548
|
await this.request('POST', ENDPOINTS.MACHINES_ME_BROWSER_PROFILE_STATUS(profileId), {
|
|
1520
1549
|
status,
|
|
1521
1550
|
...(errorMsg ? { error_msg: errorMsg } : {}),
|
|
1551
|
+
...(generation !== undefined ? { generation } : {}),
|
|
1522
1552
|
});
|
|
1523
1553
|
}
|
|
1524
1554
|
|
|
1525
1555
|
/**
|
|
1526
1556
|
* `POST /machines/me/health` — bump the Machine's `updated_at` to now and
|
|
1527
|
-
* report daemon state. The daemon
|
|
1528
|
-
*
|
|
1557
|
+
* report daemon state. The daemon calls this on startup and again whenever
|
|
1558
|
+
* periodic runtime re-detection produces a CHANGED result (there is no
|
|
1559
|
+
* fixed-cadence keepalive loop today — steady state posts nothing). All
|
|
1529
1560
|
* fields are optional and only persisted when changed:
|
|
1530
1561
|
* - `daemonVersion` — the running bundle/launcher version.
|
|
1531
1562
|
* - `selfUpdateCapable` — whether the daemon can act on a machine.update
|
|
1532
1563
|
* signal (true under a service manager, false for bare `npx` foreground).
|
|
1564
|
+
* - `detectedRuntimes` — runtime CLIs found on the host. Omitted = no
|
|
1565
|
+
* report this beat (server keeps the stored value); [] = detection ran
|
|
1566
|
+
* and found nothing (server clears to empty).
|
|
1533
1567
|
*/
|
|
1534
1568
|
async postMachineHeartbeat(opts?: {
|
|
1535
1569
|
daemonVersion?: string;
|
|
1536
1570
|
selfUpdateCapable?: boolean;
|
|
1571
|
+
detectedRuntimes?: DetectedRuntime[];
|
|
1537
1572
|
}): Promise<void> {
|
|
1538
1573
|
const body: Record<string, unknown> = {};
|
|
1539
1574
|
if (opts?.daemonVersion) body.daemon_version = opts.daemonVersion;
|
|
1540
1575
|
if (opts?.selfUpdateCapable !== undefined) body.self_update_capable = opts.selfUpdateCapable;
|
|
1576
|
+
if (opts?.detectedRuntimes !== undefined) body.detected_runtimes = opts.detectedRuntimes;
|
|
1541
1577
|
return this.request(
|
|
1542
1578
|
'POST',
|
|
1543
1579
|
ENDPOINTS.MACHINES_ME_HEALTH,
|
|
@@ -2165,6 +2201,124 @@ export class ParallClient {
|
|
|
2165
2201
|
return this.request('DELETE', ENDPOINTS.EXTERNAL_CONNECTION(orgId, connectionId));
|
|
2166
2202
|
}
|
|
2167
2203
|
|
|
2204
|
+
// ---- External IM channel (org-scoped) ----
|
|
2205
|
+
|
|
2206
|
+
async createChannelConnection(
|
|
2207
|
+
orgId: string,
|
|
2208
|
+
input: CreateChannelConnectionInput,
|
|
2209
|
+
): Promise<ChannelConnection> {
|
|
2210
|
+
return this.request('POST', ENDPOINTS.CHANNEL_CONNECTIONS(orgId), input);
|
|
2211
|
+
}
|
|
2212
|
+
|
|
2213
|
+
async listChannelConnections(orgId: string): Promise<{ connections: ChannelConnection[] }> {
|
|
2214
|
+
return this.request('GET', ENDPOINTS.CHANNEL_CONNECTIONS(orgId));
|
|
2215
|
+
}
|
|
2216
|
+
|
|
2217
|
+
async getChannelConnection(orgId: string, connectionId: string): Promise<ChannelConnection> {
|
|
2218
|
+
return this.request('GET', ENDPOINTS.CHANNEL_CONNECTION(orgId, connectionId));
|
|
2219
|
+
}
|
|
2220
|
+
|
|
2221
|
+
async updateChannelConnection(
|
|
2222
|
+
orgId: string,
|
|
2223
|
+
connectionId: string,
|
|
2224
|
+
patch: UpdateChannelConnectionInput,
|
|
2225
|
+
): Promise<ChannelConnection> {
|
|
2226
|
+
return this.request('PATCH', ENDPOINTS.CHANNEL_CONNECTION(orgId, connectionId), patch);
|
|
2227
|
+
}
|
|
2228
|
+
|
|
2229
|
+
async archiveChannelConnection(orgId: string, connectionId: string): Promise<ChannelConnection> {
|
|
2230
|
+
return this.request('DELETE', ENDPOINTS.CHANNEL_CONNECTION(orgId, connectionId));
|
|
2231
|
+
}
|
|
2232
|
+
|
|
2233
|
+
async deliverChannelCredentials(
|
|
2234
|
+
orgId: string,
|
|
2235
|
+
connectionId: string,
|
|
2236
|
+
credentials: ChannelCredentialsInput,
|
|
2237
|
+
): Promise<ChannelConnection> {
|
|
2238
|
+
return this.request(
|
|
2239
|
+
'POST',
|
|
2240
|
+
ENDPOINTS.CHANNEL_CONNECTION_CREDENTIALS(orgId, connectionId),
|
|
2241
|
+
credentials,
|
|
2242
|
+
);
|
|
2243
|
+
}
|
|
2244
|
+
|
|
2245
|
+
async regenerateChannelIngressToken(
|
|
2246
|
+
orgId: string,
|
|
2247
|
+
connectionId: string,
|
|
2248
|
+
): Promise<ChannelConnection> {
|
|
2249
|
+
return this.request(
|
|
2250
|
+
'POST',
|
|
2251
|
+
ENDPOINTS.CHANNEL_CONNECTION_INGRESS_TOKEN_REGENERATE(orgId, connectionId),
|
|
2252
|
+
);
|
|
2253
|
+
}
|
|
2254
|
+
|
|
2255
|
+
/** Start a Feishu one-click provisioning session (device flow QR). */
|
|
2256
|
+
async initiateChannelProvisioning(
|
|
2257
|
+
orgId: string,
|
|
2258
|
+
input: InitiateChannelProvisioningInput,
|
|
2259
|
+
): Promise<ChannelProvisioningSession> {
|
|
2260
|
+
return this.request('POST', ENDPOINTS.CHANNEL_PROVISIONING(orgId), input);
|
|
2261
|
+
}
|
|
2262
|
+
|
|
2263
|
+
/**
|
|
2264
|
+
* Lazy status poll — server-side this may forward one provider poll, so
|
|
2265
|
+
* call it at the session's `poll_interval_seconds` cadence, not faster.
|
|
2266
|
+
*/
|
|
2267
|
+
async getChannelProvisioningSession(
|
|
2268
|
+
orgId: string,
|
|
2269
|
+
sessionId: string,
|
|
2270
|
+
): Promise<ChannelProvisioningSession> {
|
|
2271
|
+
return this.request('GET', ENDPOINTS.CHANNEL_PROVISIONING_SESSION(orgId, sessionId));
|
|
2272
|
+
}
|
|
2273
|
+
|
|
2274
|
+
async cancelChannelProvisioning(
|
|
2275
|
+
orgId: string,
|
|
2276
|
+
sessionId: string,
|
|
2277
|
+
): Promise<ChannelProvisioningSession> {
|
|
2278
|
+
return this.request('POST', ENDPOINTS.CHANNEL_PROVISIONING_CANCEL(orgId, sessionId));
|
|
2279
|
+
}
|
|
2280
|
+
|
|
2281
|
+
async listChannelConversations(
|
|
2282
|
+
orgId: string,
|
|
2283
|
+
connectionId: string,
|
|
2284
|
+
): Promise<{ conversations: ChannelConversation[] }> {
|
|
2285
|
+
return this.request('GET', ENDPOINTS.CHANNEL_CONNECTION_CONVERSATIONS(orgId, connectionId));
|
|
2286
|
+
}
|
|
2287
|
+
|
|
2288
|
+
async getChannelConversation(
|
|
2289
|
+
orgId: string,
|
|
2290
|
+
conversationId: string,
|
|
2291
|
+
): Promise<ChannelConversation> {
|
|
2292
|
+
return this.request('GET', ENDPOINTS.CHANNEL_CONVERSATION(orgId, conversationId));
|
|
2293
|
+
}
|
|
2294
|
+
|
|
2295
|
+
async listChannelConversationMessages(
|
|
2296
|
+
orgId: string,
|
|
2297
|
+
conversationId: string,
|
|
2298
|
+
limit?: number,
|
|
2299
|
+
): Promise<{ messages: ChannelMessage[] }> {
|
|
2300
|
+
return this.request(
|
|
2301
|
+
'GET',
|
|
2302
|
+
ENDPOINTS.CHANNEL_CONVERSATION_MESSAGES(orgId, conversationId),
|
|
2303
|
+
undefined,
|
|
2304
|
+
{ limit },
|
|
2305
|
+
);
|
|
2306
|
+
}
|
|
2307
|
+
|
|
2308
|
+
async setChannelConversationSession(
|
|
2309
|
+
orgId: string,
|
|
2310
|
+
conversationId: string,
|
|
2311
|
+
agentSessionId: string,
|
|
2312
|
+
): Promise<ChannelConversation> {
|
|
2313
|
+
return this.request('PATCH', ENDPOINTS.CHANNEL_CONVERSATION_SESSION(orgId, conversationId), {
|
|
2314
|
+
agent_session_id: agentSessionId,
|
|
2315
|
+
});
|
|
2316
|
+
}
|
|
2317
|
+
|
|
2318
|
+
async getChannelMessage(orgId: string, messageId: string): Promise<ChannelMessage> {
|
|
2319
|
+
return this.request('GET', ENDPOINTS.CHANNEL_MESSAGE(orgId, messageId));
|
|
2320
|
+
}
|
|
2321
|
+
|
|
2168
2322
|
async getExternalTriggerSchema(
|
|
2169
2323
|
orgId: string,
|
|
2170
2324
|
connectionId: string,
|
|
@@ -2254,6 +2408,26 @@ export class ParallClient {
|
|
|
2254
2408
|
return this.request('GET', ENDPOINTS.WIKI(orgId, wikiId));
|
|
2255
2409
|
}
|
|
2256
2410
|
|
|
2411
|
+
/** Soft-delete an entire wiki (org owner only; the default wiki is
|
|
2412
|
+
* protected → 403 WIKI_PROTECTED). Returns the deleted wiki. Recoverable
|
|
2413
|
+
* via restoreWiki within the retention window. */
|
|
2414
|
+
async deleteWiki(orgId: string, wikiId: string): Promise<Wiki> {
|
|
2415
|
+
return this.request('DELETE', ENDPOINTS.WIKI(orgId, wikiId));
|
|
2416
|
+
}
|
|
2417
|
+
|
|
2418
|
+
/** Restore a soft-deleted wiki (org owner only). 409 WIKI_PURGE_STARTED once
|
|
2419
|
+
* purge has been claimed (no longer restorable), or 404 once the row is gone.
|
|
2420
|
+
* Returns the restored wiki. */
|
|
2421
|
+
async restoreWiki(orgId: string, wikiId: string): Promise<Wiki> {
|
|
2422
|
+
return this.request('POST', ENDPOINTS.WIKI_RESTORE(orgId, wikiId));
|
|
2423
|
+
}
|
|
2424
|
+
|
|
2425
|
+
/** Recycle bin — list soft-deleted wikis for the org (owner only). */
|
|
2426
|
+
async getDeletedWikis(orgId: string): Promise<Wiki[]> {
|
|
2427
|
+
const res = await this.request<{ data: Wiki[] }>('GET', ENDPOINTS.WIKIS_DELETED(orgId));
|
|
2428
|
+
return res.data;
|
|
2429
|
+
}
|
|
2430
|
+
|
|
2257
2431
|
async getWikiTree(
|
|
2258
2432
|
orgId: string,
|
|
2259
2433
|
wikiId: string,
|
|
@@ -2301,6 +2475,20 @@ export class ParallClient {
|
|
|
2301
2475
|
return blob;
|
|
2302
2476
|
}
|
|
2303
2477
|
|
|
2478
|
+
/**
|
|
2479
|
+
* Copy one wiki file to another path as an independent snapshot (no sync).
|
|
2480
|
+
* Used to "share a private file out": copy a file from the caller's personal
|
|
2481
|
+
* namespace (`users/{userId}/…`) into the public wiki, leaving the original
|
|
2482
|
+
* untouched. 409 `FILE_EXISTS` if `dest_path` already exists.
|
|
2483
|
+
*/
|
|
2484
|
+
async copyWikiFile(
|
|
2485
|
+
orgId: string,
|
|
2486
|
+
wikiId: string,
|
|
2487
|
+
req: CopyWikiFileRequest,
|
|
2488
|
+
): Promise<CopyWikiFileResponse> {
|
|
2489
|
+
return this.request('POST', ENDPOINTS.WIKI_COPY(orgId, wikiId), req);
|
|
2490
|
+
}
|
|
2491
|
+
|
|
2304
2492
|
async getWikiNodeSections(
|
|
2305
2493
|
orgId: string,
|
|
2306
2494
|
wikiId: string,
|
|
@@ -2828,6 +3016,21 @@ export class ParallClient {
|
|
|
2828
3016
|
return resp.data;
|
|
2829
3017
|
}
|
|
2830
3018
|
|
|
3019
|
+
/** Runtime capability table (public) — SSOT for the create/settings interlock. */
|
|
3020
|
+
async getRuntimes(): Promise<RuntimeCapability[]> {
|
|
3021
|
+
const resp = await this.request<{ data: RuntimeCapability[] }>('GET', ENDPOINTS.RUNTIMES());
|
|
3022
|
+
return resp.data;
|
|
3023
|
+
}
|
|
3024
|
+
|
|
3025
|
+
/**
|
|
3026
|
+
* Platform model catalog (public) — DB-backed, replaces the compile-time
|
|
3027
|
+
* PLATFORM_MODELS constant. Pass includeModel to keep an agent's pinned
|
|
3028
|
+
* hidden legacy model representable (settings picker).
|
|
3029
|
+
*/
|
|
3030
|
+
async getModels(includeModel?: string): Promise<PlatformModelsResponse> {
|
|
3031
|
+
return this.request<PlatformModelsResponse>('GET', ENDPOINTS.MODELS(includeModel));
|
|
3032
|
+
}
|
|
3033
|
+
|
|
2831
3034
|
// ---- Clips ----
|
|
2832
3035
|
|
|
2833
3036
|
async listClips(orgId: string): Promise<Clip[]> {
|
|
@@ -2895,6 +3098,12 @@ export class ParallClient {
|
|
|
2895
3098
|
return resp.data;
|
|
2896
3099
|
}
|
|
2897
3100
|
|
|
3101
|
+
/** Deployment-wide hosted browser runtime availability — drives whether the
|
|
3102
|
+
* create UI offers the platform-hosted placement. Fail-closed server-side. */
|
|
3103
|
+
async getBrowserRuntimeStatus(orgId: string): Promise<BrowserRuntimeStatus> {
|
|
3104
|
+
return this.request('GET', ENDPOINTS.BROWSER_RUNTIME_STATUS(orgId));
|
|
3105
|
+
}
|
|
3106
|
+
|
|
2898
3107
|
/** Org-wide browser-profile discovery list. Returns the sanitized
|
|
2899
3108
|
* {@link BrowserProfileListItem} shape (not the full domain model), each row
|
|
2900
3109
|
* carrying a per-viewer `can_open` control hint. */
|
package/src/constants.ts
CHANGED
|
@@ -7,11 +7,17 @@ export const WIKI_BASE = '/wiki/v1';
|
|
|
7
7
|
// Clip-service base path (served by clip-service, routed via LB path rules)
|
|
8
8
|
export const CLIP_BASE = '/clip/v1';
|
|
9
9
|
|
|
10
|
-
// LLM model catalog —
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
|
|
10
|
+
// LLM model catalog — frozen compile-time mirror of the catalog at the time
|
|
11
|
+
// the DB-backed source shipped (docs/engineering-design/model-catalog-design.md).
|
|
12
|
+
// Kept ONLY as the offline/degraded fallback for pickers; it is NOT updated
|
|
13
|
+
// when models are added through the admin catalog.
|
|
14
|
+
/**
|
|
15
|
+
* @deprecated The catalog is DB-backed — fetch it via `client.getModels()`
|
|
16
|
+
* (GET /api/v1/models). This constant is a frozen degraded-mode fallback and
|
|
17
|
+
* will be removed after one release cycle. Still structurally consumed by
|
|
18
|
+
* FALLBACK_CATALOG (`@parall/app` agent-interlock) — do not delete before
|
|
19
|
+
* that fallback strategy changes (PR-3).
|
|
20
|
+
*/
|
|
15
21
|
export const PLATFORM_MODELS = [
|
|
16
22
|
// Fable 5 rejects an explicit thinking "disabled" param (400) — bridges must
|
|
17
23
|
// omit the thinking config entirely instead of disabling it.
|
|
@@ -211,6 +217,12 @@ export const PLATFORM_MODELS = [
|
|
|
211
217
|
|
|
212
218
|
// Hidden from new-agent pickers, but available to editors so persisted Beta
|
|
213
219
|
// agent defaults remain representable.
|
|
220
|
+
/**
|
|
221
|
+
* @deprecated Fetch via `client.getModels(currentModelId)` — the include_model
|
|
222
|
+
* parameter serves the legacy-pin case. Frozen degraded-mode fallback only.
|
|
223
|
+
* Still structurally consumed by FALLBACK_CATALOG (`@parall/app`
|
|
224
|
+
* agent-interlock) — do not delete before that fallback changes (PR-3).
|
|
225
|
+
*/
|
|
214
226
|
export const PLATFORM_LEGACY_MODELS = [
|
|
215
227
|
{
|
|
216
228
|
id: 'openai/gpt-5.4-mini',
|
|
@@ -284,9 +296,13 @@ export const PLATFORM_LEGACY_MODELS = [
|
|
|
284
296
|
},
|
|
285
297
|
] as const;
|
|
286
298
|
|
|
287
|
-
//
|
|
288
|
-
//
|
|
289
|
-
//
|
|
299
|
+
// Frozen mirror of the per-runtime defaults at ship time of the DB-backed
|
|
300
|
+
// catalog (llm_runtime_defaults). Live values arrive as recommended_model on
|
|
301
|
+
// GET /runtimes.
|
|
302
|
+
/**
|
|
303
|
+
* @deprecated Read `recommended_model` from `client.getRuntimes()` instead.
|
|
304
|
+
* Frozen degraded-mode fallback only.
|
|
305
|
+
*/
|
|
290
306
|
export const PLATFORM_DEFAULT_MODEL_BY_RUNTIME = {
|
|
291
307
|
openclaw: 'anthropic/claude-sonnet-4.6',
|
|
292
308
|
'claude-code': 'anthropic/claude-sonnet-4.6',
|
|
@@ -312,6 +328,11 @@ export function platformDefaultModelForRuntime(runtime: string | null | undefine
|
|
|
312
328
|
case '':
|
|
313
329
|
case 'openclaw':
|
|
314
330
|
case 'claude-code':
|
|
331
|
+
// hermes / parel route through the Parall proxy and accept any model; the
|
|
332
|
+
// server (DefaultModelIDForRuntime) recommends the platform default, so
|
|
333
|
+
// mirror it.
|
|
334
|
+
case 'hermes':
|
|
335
|
+
case 'parel':
|
|
315
336
|
return PLATFORM_DEFAULT_MODEL_BY_RUNTIME.openclaw;
|
|
316
337
|
case 'codex':
|
|
317
338
|
return PLATFORM_DEFAULT_MODEL_BY_RUNTIME.codex;
|
|
@@ -347,6 +368,7 @@ export const ENDPOINTS = {
|
|
|
347
368
|
// Org-scoped
|
|
348
369
|
ORG: (orgId: string) => `${API_BASE}/orgs/${orgId}`,
|
|
349
370
|
ORG_MEMBERS: (orgId: string) => `${API_BASE}/orgs/${orgId}/members`,
|
|
371
|
+
ORG_MEMBERS_FORMER: (orgId: string) => `${API_BASE}/orgs/${orgId}/members/former`,
|
|
350
372
|
TEAMS: (orgId: string) => `${API_BASE}/orgs/${orgId}/teams`,
|
|
351
373
|
ORG_MEMBERS_ONLINE: (orgId: string) => `${API_BASE}/orgs/${orgId}/members/online`,
|
|
352
374
|
ORG_MEMBER: (orgId: string, userId: string) => `${API_BASE}/orgs/${orgId}/members/${userId}`,
|
|
@@ -584,6 +606,30 @@ export const ENDPOINTS = {
|
|
|
584
606
|
EXTERNAL_TRIGGER_RUN: (orgId: string, runId: string) =>
|
|
585
607
|
`${API_BASE}/orgs/${orgId}/external-trigger-runs/${runId}`,
|
|
586
608
|
|
|
609
|
+
// External IM channel (org-scoped, platform-mediated Feishu/Slack)
|
|
610
|
+
CHANNEL_CONNECTIONS: (orgId: string) => `${API_BASE}/orgs/${orgId}/channel-connections`,
|
|
611
|
+
CHANNEL_CONNECTION: (orgId: string, connectionId: string) =>
|
|
612
|
+
`${API_BASE}/orgs/${orgId}/channel-connections/${connectionId}`,
|
|
613
|
+
CHANNEL_CONNECTION_CREDENTIALS: (orgId: string, connectionId: string) =>
|
|
614
|
+
`${API_BASE}/orgs/${orgId}/channel-connections/${connectionId}/credentials`,
|
|
615
|
+
CHANNEL_CONNECTION_INGRESS_TOKEN_REGENERATE: (orgId: string, connectionId: string) =>
|
|
616
|
+
`${API_BASE}/orgs/${orgId}/channel-connections/${connectionId}/ingress-token/regenerate`,
|
|
617
|
+
CHANNEL_CONNECTION_CONVERSATIONS: (orgId: string, connectionId: string) =>
|
|
618
|
+
`${API_BASE}/orgs/${orgId}/channel-connections/${connectionId}/conversations`,
|
|
619
|
+
CHANNEL_CONVERSATION: (orgId: string, conversationId: string) =>
|
|
620
|
+
`${API_BASE}/orgs/${orgId}/channel-conversations/${conversationId}`,
|
|
621
|
+
CHANNEL_CONVERSATION_MESSAGES: (orgId: string, conversationId: string) =>
|
|
622
|
+
`${API_BASE}/orgs/${orgId}/channel-conversations/${conversationId}/messages`,
|
|
623
|
+
CHANNEL_CONVERSATION_SESSION: (orgId: string, conversationId: string) =>
|
|
624
|
+
`${API_BASE}/orgs/${orgId}/channel-conversations/${conversationId}/session`,
|
|
625
|
+
CHANNEL_MESSAGE: (orgId: string, messageId: string) =>
|
|
626
|
+
`${API_BASE}/orgs/${orgId}/channel-messages/${messageId}`,
|
|
627
|
+
CHANNEL_PROVISIONING: (orgId: string) => `${API_BASE}/orgs/${orgId}/channel-provisioning`,
|
|
628
|
+
CHANNEL_PROVISIONING_SESSION: (orgId: string, sessionId: string) =>
|
|
629
|
+
`${API_BASE}/orgs/${orgId}/channel-provisioning/${sessionId}`,
|
|
630
|
+
CHANNEL_PROVISIONING_CANCEL: (orgId: string, sessionId: string) =>
|
|
631
|
+
`${API_BASE}/orgs/${orgId}/channel-provisioning/${sessionId}/cancel`,
|
|
632
|
+
|
|
587
633
|
// Invitations (org-scoped, admin)
|
|
588
634
|
ORG_INVITATIONS: (orgId: string) => `${API_BASE}/orgs/${orgId}/invitations`,
|
|
589
635
|
ORG_INVITATION: (orgId: string, invId: string) =>
|
|
@@ -608,9 +654,17 @@ export const ENDPOINTS = {
|
|
|
608
654
|
|
|
609
655
|
// Wikis (org-scoped, served by wiki-service)
|
|
610
656
|
WIKIS: (orgId: string) => `${WIKI_BASE}/orgs/${orgId}/wikis`,
|
|
657
|
+
// Recycle bin — soft-deleted wikis (owner only). Must precede WIKI in the
|
|
658
|
+
// backend router so `deleted` isn't captured as a {wikiId}; the SDK builder
|
|
659
|
+
// is just a string.
|
|
660
|
+
WIKIS_DELETED: (orgId: string) => `${WIKI_BASE}/orgs/${orgId}/wikis/deleted`,
|
|
661
|
+
// Detail URL — also reused for DELETE (soft-delete) and `${WIKI}/restore`.
|
|
611
662
|
WIKI: (orgId: string, wikiId: string) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}`,
|
|
663
|
+
WIKI_RESTORE: (orgId: string, wikiId: string) =>
|
|
664
|
+
`${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/restore`,
|
|
612
665
|
WIKI_TREE: (orgId: string, wikiId: string) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/tree`,
|
|
613
666
|
WIKI_BLOB: (orgId: string, wikiId: string) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/blob`,
|
|
667
|
+
WIKI_COPY: (orgId: string, wikiId: string) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/copy`,
|
|
614
668
|
WIKI_NODE_SECTIONS: (orgId: string, wikiId: string) =>
|
|
615
669
|
`${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/node-sections`,
|
|
616
670
|
WIKI_SEARCH: (orgId: string, wikiId: string) =>
|
|
@@ -734,6 +788,19 @@ export const ENDPOINTS = {
|
|
|
734
788
|
BILLING_SETUP_INTENT: (orgId: string) => `${API_BASE}/orgs/${orgId}/billing/setup-intent`,
|
|
735
789
|
COMPUTE_PRICING: () => `${API_BASE}/billing/compute-pricing`,
|
|
736
790
|
|
|
791
|
+
// Runtime capability table (public, no auth) — SSOT for the create/settings
|
|
792
|
+
// interlock: per-runtime compute modes, native model family, cross-family
|
|
793
|
+
// availability, and recommended model.
|
|
794
|
+
RUNTIMES: () => `${API_BASE}/runtimes`,
|
|
795
|
+
|
|
796
|
+
// Model catalog (public, no auth) — served from the server's DB-backed
|
|
797
|
+
// snapshot. Optional include_model keeps an agent's pinned hidden legacy
|
|
798
|
+
// model representable in settings pickers.
|
|
799
|
+
MODELS: (includeModel?: string) =>
|
|
800
|
+
includeModel
|
|
801
|
+
? `${API_BASE}/models?include_model=${encodeURIComponent(includeModel)}`
|
|
802
|
+
: `${API_BASE}/models`,
|
|
803
|
+
|
|
737
804
|
// ADMIN_GRANTS intentionally NOT exported here — it sits under the
|
|
738
805
|
// unauthenticated `/internal/admin/*` surface and must not bleed into the
|
|
739
806
|
// public SDK. Admin dashboard hits the URL directly from its own client.
|
|
@@ -750,6 +817,7 @@ export const ENDPOINTS = {
|
|
|
750
817
|
`${CLIP_BASE}/orgs/${orgId}/agents/${agentId}/clips/${clipId}`,
|
|
751
818
|
CLIP_INVOKE: (orgId: string) => `${CLIP_BASE}/orgs/${orgId}/invoke`,
|
|
752
819
|
CLIP_ONLINE: (orgId: string) => `${CLIP_BASE}/orgs/${orgId}/online`,
|
|
820
|
+
BROWSER_RUNTIME_STATUS: (orgId: string) => `${CLIP_BASE}/orgs/${orgId}/browser-runtime/status`,
|
|
753
821
|
BROWSER_PROFILES: (orgId: string) => `${CLIP_BASE}/orgs/${orgId}/browser-profiles`,
|
|
754
822
|
BROWSER_PROFILE: (orgId: string, profileId: string) =>
|
|
755
823
|
`${CLIP_BASE}/orgs/${orgId}/browser-profiles/${profileId}`,
|
|
@@ -772,6 +840,42 @@ export const ENDPOINTS = {
|
|
|
772
840
|
CLIP_REGISTRY: () => `${CLIP_BASE}/registry/clips`,
|
|
773
841
|
} as const;
|
|
774
842
|
|
|
843
|
+
/**
|
|
844
|
+
* Wiki personal-namespace prefix — the path subtree a member owns for
|
|
845
|
+
* self-service private spaces: `users/{userId}/`. SSOT mirror of the
|
|
846
|
+
* wiki-service `personalNamespacePrefix` (server/internal/wiki/handler/acl.go):
|
|
847
|
+
* a member may create/manage path restrictions anywhere under this prefix
|
|
848
|
+
* without org/path admin. The trailing slash is load-bearing — it keeps a user
|
|
849
|
+
* ID that is a string prefix of another from matching across namespaces.
|
|
850
|
+
*/
|
|
851
|
+
export function wikiPersonalNamespacePrefix(userId: string): string {
|
|
852
|
+
return `users/${userId}/`;
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
/**
|
|
856
|
+
* Whether `path` falls inside `userId`'s personal namespace (the namespace root
|
|
857
|
+
* itself or any descendant). Mirrors the server's `ownsPersonalNamespacePath`;
|
|
858
|
+
* use it for UI affordance gating only — the wiki-service stays the security
|
|
859
|
+
* SSOT and re-checks on every mutation.
|
|
860
|
+
*/
|
|
861
|
+
export function isInWikiPersonalNamespace(userId: string, path: string): boolean {
|
|
862
|
+
if (!userId) return false;
|
|
863
|
+
const prefix = wikiPersonalNamespacePrefix(userId);
|
|
864
|
+
return path === prefix || path.startsWith(prefix);
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
/**
|
|
868
|
+
* Whether `path` falls inside ANY user's personal namespace (`users/{id}/…`),
|
|
869
|
+
* regardless of whose. UI affordance helper — e.g. badging member personal-space
|
|
870
|
+
* restriction rows in the admin Access tab, or keeping "copy to shared wiki"
|
|
871
|
+
* destinations out of personal namespaces. Matches by shape (`users/<segment>/`
|
|
872
|
+
* or the bare `users/<segment>`), deliberately broader than
|
|
873
|
+
* `isInWikiPersonalNamespace`.
|
|
874
|
+
*/
|
|
875
|
+
export function isWikiPersonalNamespacePath(path: string): boolean {
|
|
876
|
+
return /^users\/[^/]+(\/|$)/.test(path);
|
|
877
|
+
}
|
|
878
|
+
|
|
775
879
|
// WebSocket event types
|
|
776
880
|
export const WS_EVENTS = {
|
|
777
881
|
// Client -> Server
|
|
@@ -813,10 +917,13 @@ export const WS_EVENTS = {
|
|
|
813
917
|
INVITATION_REVOKED: 'invitation.revoked',
|
|
814
918
|
ORG_JOIN_REQUEST_NEW: 'org.join_request.new',
|
|
815
919
|
ORG_INVITE_LINK_JOINED: 'org.invite_link.joined',
|
|
920
|
+
ORG_MEMBER_REMOVED: 'org.member.removed',
|
|
816
921
|
AGENT_CONFIG_UPDATE: 'agent_config.update',
|
|
817
922
|
PRESENCE_UPDATE: 'presence.update',
|
|
818
923
|
WIKI_CHANGESET_CREATED: 'wiki.changeset.created',
|
|
819
924
|
WIKI_CHANGESET_UPDATED: 'wiki.changeset.updated',
|
|
925
|
+
WIKI_DELETED: 'wiki.deleted',
|
|
926
|
+
WIKI_RESTORED: 'wiki.restored',
|
|
820
927
|
COMMENT_CREATED: 'comment.created',
|
|
821
928
|
COMMENT_UPDATED: 'comment.updated',
|
|
822
929
|
COMMENT_DELETED: 'comment.deleted',
|
|
@@ -844,6 +951,7 @@ export const WS_EVENTS = {
|
|
|
844
951
|
MACHINE_FILESYSTEM_BROWSE: 'machine.filesystem.browse',
|
|
845
952
|
MACHINE_UPDATE: 'machine.update',
|
|
846
953
|
MACHINE_CONFIG_UPDATED: 'machine.config.updated',
|
|
954
|
+
MACHINE_AGENT_CONFIG_UPDATED: 'machine.agent_config.updated',
|
|
847
955
|
MACHINE_CLIP_SYNC: 'machine.clip.sync',
|
|
848
956
|
MACHINE_BROWSER_PROFILE_LIFECYCLE: 'machine.browser_profile.lifecycle',
|
|
849
957
|
MACHINE_BROWSER_PROFILE_VIEWER: 'machine.browser_profile.viewer',
|