@personaai/react 0.11.0 → 0.14.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/index.js CHANGED
@@ -3121,28 +3121,475 @@ function useRcpSources(options = {}) {
3121
3121
  };
3122
3122
  }
3123
3123
 
3124
- // src/hooks/useWorkflows.ts
3124
+ // src/hooks/useKnowledgeBases.ts
3125
3125
  import { useCallback as useCallback13, useEffect as useEffect12, useState as useState12 } from "react";
3126
+ function useKnowledgeBases(options = {}) {
3127
+ const { autoFetch = true, page, limit, search, scope } = options;
3128
+ const { fetchWithAuth } = usePersonaContext();
3129
+ const [knowledgeBases, setKnowledgeBases] = useState12([]);
3130
+ const [pagination, setPagination] = useState12({
3131
+ total: 0,
3132
+ page: page ?? 1,
3133
+ limit: limit ?? 20,
3134
+ pages: 0
3135
+ });
3136
+ const [isLoading, setIsLoading] = useState12(false);
3137
+ const [isUploading, setIsUploading] = useState12(false);
3138
+ const [error, setError] = useState12(null);
3139
+ const fetchKnowledgeBases = useCallback13(async () => {
3140
+ setIsLoading(true);
3141
+ setError(null);
3142
+ try {
3143
+ const query = new URLSearchParams();
3144
+ if (page) query.set("page", String(page));
3145
+ if (limit) query.set("limit", String(limit));
3146
+ if (search) query.set("search", search);
3147
+ if (scope) query.set("scope", scope);
3148
+ const queryStr = query.toString() ? `?${query.toString()}` : "";
3149
+ const res = await fetchWithAuth(`/knowledge${queryStr}`);
3150
+ if (!res.ok) throw new Error(`Failed to list knowledge bases: ${res.statusText}`);
3151
+ const data = await res.json();
3152
+ const items = Array.isArray(data) ? data : data?.items ?? [];
3153
+ setKnowledgeBases(items);
3154
+ setPagination(
3155
+ data?.pagination ?? { total: items.length, page: 1, limit: items.length, pages: 1 }
3156
+ );
3157
+ return items;
3158
+ } catch (err) {
3159
+ const errorObj = err instanceof Error ? err : new Error(String(err));
3160
+ setError(errorObj);
3161
+ return [];
3162
+ } finally {
3163
+ setIsLoading(false);
3164
+ }
3165
+ }, [fetchWithAuth, page, limit, search, scope]);
3166
+ const getKnowledgeBase = useCallback13(
3167
+ async (kbId) => {
3168
+ const res = await fetchWithAuth(`/knowledge/${kbId}`);
3169
+ if (!res.ok) throw new Error(`Failed to fetch knowledge base: ${res.statusText}`);
3170
+ return res.json();
3171
+ },
3172
+ [fetchWithAuth]
3173
+ );
3174
+ const createKnowledgeBase = useCallback13(
3175
+ async (input) => {
3176
+ setError(null);
3177
+ try {
3178
+ const res = await fetchWithAuth("/knowledge", {
3179
+ method: "POST",
3180
+ headers: { "Content-Type": "application/json" },
3181
+ body: JSON.stringify(input)
3182
+ });
3183
+ if (!res.ok) {
3184
+ const errText = await res.text().catch(() => res.statusText);
3185
+ throw new Error(`Failed to create knowledge base (${res.status}): ${errText}`);
3186
+ }
3187
+ const created = await res.json();
3188
+ setKnowledgeBases((prev) => [created, ...prev]);
3189
+ return created;
3190
+ } catch (err) {
3191
+ const errorObj = err instanceof Error ? err : new Error(String(err));
3192
+ setError(errorObj);
3193
+ throw errorObj;
3194
+ }
3195
+ },
3196
+ [fetchWithAuth]
3197
+ );
3198
+ const updateKnowledgeBase = useCallback13(
3199
+ async (kbId, input) => {
3200
+ setError(null);
3201
+ try {
3202
+ const res = await fetchWithAuth(`/knowledge/${kbId}`, {
3203
+ method: "PATCH",
3204
+ headers: { "Content-Type": "application/json" },
3205
+ body: JSON.stringify(input)
3206
+ });
3207
+ if (!res.ok) {
3208
+ const errText = await res.text().catch(() => res.statusText);
3209
+ throw new Error(`Failed to update knowledge base (${res.status}): ${errText}`);
3210
+ }
3211
+ const updated = await res.json();
3212
+ setKnowledgeBases((prev) => prev.map((kb) => kb._id === kbId ? updated : kb));
3213
+ return updated;
3214
+ } catch (err) {
3215
+ const errorObj = err instanceof Error ? err : new Error(String(err));
3216
+ setError(errorObj);
3217
+ throw errorObj;
3218
+ }
3219
+ },
3220
+ [fetchWithAuth]
3221
+ );
3222
+ const deleteKnowledgeBase = useCallback13(
3223
+ async (kbId) => {
3224
+ setError(null);
3225
+ try {
3226
+ const res = await fetchWithAuth(`/knowledge/${kbId}`, { method: "DELETE" });
3227
+ if (!res.ok) {
3228
+ const errText = await res.text().catch(() => res.statusText);
3229
+ throw new Error(`Failed to delete knowledge base (${res.status}): ${errText}`);
3230
+ }
3231
+ setKnowledgeBases((prev) => prev.filter((kb) => kb._id !== kbId));
3232
+ } catch (err) {
3233
+ const errorObj = err instanceof Error ? err : new Error(String(err));
3234
+ setError(errorObj);
3235
+ throw errorObj;
3236
+ }
3237
+ },
3238
+ [fetchWithAuth]
3239
+ );
3240
+ const bulkDeleteKnowledgeBases = useCallback13(
3241
+ async (ids) => {
3242
+ setError(null);
3243
+ try {
3244
+ const res = await fetchWithAuth("/knowledge/bulk-delete", {
3245
+ method: "POST",
3246
+ headers: { "Content-Type": "application/json" },
3247
+ body: JSON.stringify({ ids })
3248
+ });
3249
+ if (!res.ok) {
3250
+ const errText = await res.text().catch(() => res.statusText);
3251
+ throw new Error(`Failed to bulk-delete knowledge bases (${res.status}): ${errText}`);
3252
+ }
3253
+ const result = await res.json();
3254
+ const deletedSet = new Set(result.deleted);
3255
+ setKnowledgeBases((prev) => prev.filter((kb) => !deletedSet.has(kb._id)));
3256
+ return result;
3257
+ } catch (err) {
3258
+ const errorObj = err instanceof Error ? err : new Error(String(err));
3259
+ setError(errorObj);
3260
+ throw errorObj;
3261
+ }
3262
+ },
3263
+ [fetchWithAuth]
3264
+ );
3265
+ const getKnowledgeBaseUsage = useCallback13(
3266
+ async (kbId) => {
3267
+ const res = await fetchWithAuth(`/knowledge/${kbId}/usage`);
3268
+ if (!res.ok) throw new Error(`Failed to fetch knowledge base usage: ${res.statusText}`);
3269
+ return res.json();
3270
+ },
3271
+ [fetchWithAuth]
3272
+ );
3273
+ const uploadDocuments = useCallback13(
3274
+ async (kbId, files) => {
3275
+ setIsUploading(true);
3276
+ setError(null);
3277
+ try {
3278
+ const body = new FormData();
3279
+ for (const file of files) {
3280
+ if (file.content instanceof Blob) {
3281
+ body.append("files", file.content, file.filename);
3282
+ } else {
3283
+ body.append("files", {
3284
+ uri: file.content.uri,
3285
+ name: file.content.name ?? file.filename,
3286
+ type: file.content.type ?? file.contentType
3287
+ });
3288
+ }
3289
+ }
3290
+ const res = await fetchWithAuth(`/knowledge/${kbId}/documents`, {
3291
+ method: "POST",
3292
+ body
3293
+ });
3294
+ if (!res.ok) {
3295
+ const errText = await res.text().catch(() => res.statusText);
3296
+ throw new Error(`Failed to upload documents (${res.status}): ${errText}`);
3297
+ }
3298
+ const result = await res.json();
3299
+ setKnowledgeBases(
3300
+ (prev) => prev.map(
3301
+ (kb) => kb._id === kbId ? { ...kb, documentCount: result.documentCount, chunkCount: result.chunkCount } : kb
3302
+ )
3303
+ );
3304
+ return result;
3305
+ } catch (err) {
3306
+ const errorObj = err instanceof Error ? err : new Error(String(err));
3307
+ setError(errorObj);
3308
+ throw errorObj;
3309
+ } finally {
3310
+ setIsUploading(false);
3311
+ }
3312
+ },
3313
+ [fetchWithAuth]
3314
+ );
3315
+ const listDocuments = useCallback13(
3316
+ async (kbId) => {
3317
+ const res = await fetchWithAuth(`/knowledge/${kbId}/documents`);
3318
+ if (!res.ok) throw new Error(`Failed to list documents: ${res.statusText}`);
3319
+ return res.json();
3320
+ },
3321
+ [fetchWithAuth]
3322
+ );
3323
+ const deleteDocument = useCallback13(
3324
+ async (kbId, sourceName) => {
3325
+ setError(null);
3326
+ try {
3327
+ const res = await fetchWithAuth(
3328
+ `/knowledge/${kbId}/documents/${encodeURIComponent(sourceName)}`,
3329
+ { method: "DELETE" }
3330
+ );
3331
+ if (!res.ok) {
3332
+ const errText = await res.text().catch(() => res.statusText);
3333
+ throw new Error(`Failed to delete document (${res.status}): ${errText}`);
3334
+ }
3335
+ const result = await res.json();
3336
+ setKnowledgeBases(
3337
+ (prev) => prev.map(
3338
+ (kb) => kb._id === kbId ? { ...kb, documentCount: result.remainingDocuments, chunkCount: result.remainingChunks } : kb
3339
+ )
3340
+ );
3341
+ return result;
3342
+ } catch (err) {
3343
+ const errorObj = err instanceof Error ? err : new Error(String(err));
3344
+ setError(errorObj);
3345
+ throw errorObj;
3346
+ }
3347
+ },
3348
+ [fetchWithAuth]
3349
+ );
3350
+ const searchKnowledgeBase = useCallback13(
3351
+ async (kbId, query, opts) => {
3352
+ const res = await fetchWithAuth(`/knowledge/${kbId}/search`, {
3353
+ method: "POST",
3354
+ headers: { "Content-Type": "application/json" },
3355
+ body: JSON.stringify({ query, topK: opts?.topK })
3356
+ });
3357
+ if (!res.ok) {
3358
+ const errText = await res.text().catch(() => res.statusText);
3359
+ throw new Error(`Failed to search knowledge base (${res.status}): ${errText}`);
3360
+ }
3361
+ return res.json();
3362
+ },
3363
+ [fetchWithAuth]
3364
+ );
3365
+ useEffect12(() => {
3366
+ if (autoFetch) void fetchKnowledgeBases();
3367
+ }, [autoFetch, fetchKnowledgeBases]);
3368
+ return {
3369
+ knowledgeBases,
3370
+ pagination,
3371
+ isLoading,
3372
+ isUploading,
3373
+ error,
3374
+ refetch: fetchKnowledgeBases,
3375
+ getKnowledgeBase,
3376
+ createKnowledgeBase,
3377
+ updateKnowledgeBase,
3378
+ deleteKnowledgeBase,
3379
+ bulkDeleteKnowledgeBases,
3380
+ getKnowledgeBaseUsage,
3381
+ uploadDocuments,
3382
+ listDocuments,
3383
+ deleteDocument,
3384
+ search: searchKnowledgeBase
3385
+ };
3386
+ }
3387
+
3388
+ // src/hooks/useMcpAdmin.ts
3389
+ import { useCallback as useCallback14, useEffect as useEffect13, useState as useState13 } from "react";
3390
+ function useMcpAdmin(options = {}) {
3391
+ const { autoFetch = true, page, limit, search } = options;
3392
+ const { fetchWithAuth } = usePersonaContext();
3393
+ const [mcps, setMcps] = useState13([]);
3394
+ const [pagination, setPagination] = useState13({
3395
+ total: 0,
3396
+ page: page ?? 1,
3397
+ limit: limit ?? 20,
3398
+ pages: 0
3399
+ });
3400
+ const [isLoading, setIsLoading] = useState13(false);
3401
+ const [error, setError] = useState13(null);
3402
+ const fetchMcps = useCallback14(async () => {
3403
+ setIsLoading(true);
3404
+ setError(null);
3405
+ try {
3406
+ const query = new URLSearchParams();
3407
+ if (page) query.set("page", String(page));
3408
+ if (limit) query.set("limit", String(limit));
3409
+ if (search) query.set("search", search);
3410
+ query.set("scope", "mine");
3411
+ const res = await fetchWithAuth(`/mcps?${query.toString()}`);
3412
+ if (!res.ok) throw new Error(`Failed to list MCPs: ${res.statusText}`);
3413
+ const data = await res.json();
3414
+ const items = Array.isArray(data) ? data : data?.items ?? [];
3415
+ setMcps(items);
3416
+ setPagination(
3417
+ data?.pagination ?? { total: items.length, page: 1, limit: items.length, pages: 1 }
3418
+ );
3419
+ return items;
3420
+ } catch (err) {
3421
+ const errorObj = err instanceof Error ? err : new Error(String(err));
3422
+ setError(errorObj);
3423
+ return [];
3424
+ } finally {
3425
+ setIsLoading(false);
3426
+ }
3427
+ }, [fetchWithAuth, page, limit, search]);
3428
+ const getMcp = useCallback14(
3429
+ async (mcpId) => {
3430
+ const res = await fetchWithAuth(`/mcps/${mcpId}`);
3431
+ if (!res.ok) throw new Error(`Failed to fetch MCP: ${res.statusText}`);
3432
+ return res.json();
3433
+ },
3434
+ [fetchWithAuth]
3435
+ );
3436
+ const createMcp = useCallback14(
3437
+ async (input) => {
3438
+ setError(null);
3439
+ try {
3440
+ const res = await fetchWithAuth("/mcps", {
3441
+ method: "POST",
3442
+ headers: { "Content-Type": "application/json" },
3443
+ body: JSON.stringify(input)
3444
+ });
3445
+ if (!res.ok) {
3446
+ const errText = await res.text().catch(() => res.statusText);
3447
+ throw new Error(`Failed to create MCP (${res.status}): ${errText}`);
3448
+ }
3449
+ const created = await res.json();
3450
+ setMcps((prev) => [created, ...prev]);
3451
+ return created;
3452
+ } catch (err) {
3453
+ const errorObj = err instanceof Error ? err : new Error(String(err));
3454
+ setError(errorObj);
3455
+ throw errorObj;
3456
+ }
3457
+ },
3458
+ [fetchWithAuth]
3459
+ );
3460
+ const updateMcp = useCallback14(
3461
+ async (mcpId, input) => {
3462
+ setError(null);
3463
+ try {
3464
+ const res = await fetchWithAuth(`/mcps/${mcpId}`, {
3465
+ method: "PATCH",
3466
+ headers: { "Content-Type": "application/json" },
3467
+ body: JSON.stringify(input)
3468
+ });
3469
+ if (!res.ok) {
3470
+ const errText = await res.text().catch(() => res.statusText);
3471
+ throw new Error(`Failed to update MCP (${res.status}): ${errText}`);
3472
+ }
3473
+ const updated = await res.json();
3474
+ setMcps((prev) => prev.map((m) => m._id === mcpId ? updated : m));
3475
+ return updated;
3476
+ } catch (err) {
3477
+ const errorObj = err instanceof Error ? err : new Error(String(err));
3478
+ setError(errorObj);
3479
+ throw errorObj;
3480
+ }
3481
+ },
3482
+ [fetchWithAuth]
3483
+ );
3484
+ const deleteMcp = useCallback14(
3485
+ async (mcpId) => {
3486
+ setError(null);
3487
+ try {
3488
+ const res = await fetchWithAuth(`/mcps/${mcpId}`, { method: "DELETE" });
3489
+ if (!res.ok) {
3490
+ const errText = await res.text().catch(() => res.statusText);
3491
+ throw new Error(`Failed to delete MCP (${res.status}): ${errText}`);
3492
+ }
3493
+ setMcps((prev) => prev.filter((m) => m._id !== mcpId));
3494
+ } catch (err) {
3495
+ const errorObj = err instanceof Error ? err : new Error(String(err));
3496
+ setError(errorObj);
3497
+ throw errorObj;
3498
+ }
3499
+ },
3500
+ [fetchWithAuth]
3501
+ );
3502
+ const bulkDeleteMcps = useCallback14(
3503
+ async (ids) => {
3504
+ setError(null);
3505
+ try {
3506
+ const res = await fetchWithAuth("/mcps/bulk-delete", {
3507
+ method: "POST",
3508
+ headers: { "Content-Type": "application/json" },
3509
+ body: JSON.stringify({ ids })
3510
+ });
3511
+ if (!res.ok) {
3512
+ const errText = await res.text().catch(() => res.statusText);
3513
+ throw new Error(`Failed to bulk-delete MCPs (${res.status}): ${errText}`);
3514
+ }
3515
+ const result = await res.json();
3516
+ const deletedSet = new Set(result.deleted);
3517
+ setMcps((prev) => prev.filter((m) => !deletedSet.has(m._id)));
3518
+ return result;
3519
+ } catch (err) {
3520
+ const errorObj = err instanceof Error ? err : new Error(String(err));
3521
+ setError(errorObj);
3522
+ throw errorObj;
3523
+ }
3524
+ },
3525
+ [fetchWithAuth]
3526
+ );
3527
+ const testConnection = useCallback14(
3528
+ async (mcpId) => {
3529
+ setError(null);
3530
+ try {
3531
+ const res = await fetchWithAuth(`/mcps/${mcpId}/test`, { method: "POST" });
3532
+ if (!res.ok) {
3533
+ const errText = await res.text().catch(() => res.statusText);
3534
+ throw new Error(`Failed to test MCP connection (${res.status}): ${errText}`);
3535
+ }
3536
+ const result = await res.json();
3537
+ setMcps(
3538
+ (prev) => prev.map(
3539
+ (m) => m._id === mcpId ? { ...m, tools: result.tools, resources: result.resources, resourceTemplates: result.resourceTemplates } : m
3540
+ )
3541
+ );
3542
+ return result;
3543
+ } catch (err) {
3544
+ const errorObj = err instanceof Error ? err : new Error(String(err));
3545
+ setError(errorObj);
3546
+ throw errorObj;
3547
+ }
3548
+ },
3549
+ [fetchWithAuth]
3550
+ );
3551
+ useEffect13(() => {
3552
+ if (autoFetch) void fetchMcps();
3553
+ }, [autoFetch, fetchMcps]);
3554
+ return {
3555
+ mcps,
3556
+ pagination,
3557
+ isLoading,
3558
+ error,
3559
+ refetch: fetchMcps,
3560
+ getMcp,
3561
+ createMcp,
3562
+ updateMcp,
3563
+ deleteMcp,
3564
+ bulkDeleteMcps,
3565
+ testConnection
3566
+ };
3567
+ }
3568
+
3569
+ // src/hooks/useWorkflows.ts
3570
+ import { useCallback as useCallback15, useEffect as useEffect14, useState as useState14 } from "react";
3126
3571
  function useWorkflows(options) {
3127
3572
  const opts = typeof options === "boolean" ? { autoFetch: options } : options ?? {};
3128
- const { autoFetch = true, search, status, page, limit } = opts;
3573
+ const { autoFetch = true, search, scope, visibility, isEnabled, page, limit } = opts;
3129
3574
  const { fetchWithAuth } = usePersonaContext();
3130
- const [workflows, setWorkflows] = useState12([]);
3131
- const [pagination, setPagination] = useState12({
3575
+ const [workflows, setWorkflows] = useState14([]);
3576
+ const [pagination, setPagination] = useState14({
3132
3577
  page: page ?? 1,
3133
3578
  limit: limit ?? 20,
3134
3579
  total: 0,
3135
3580
  totalPages: 0
3136
3581
  });
3137
- const [isLoading, setIsLoading] = useState12(false);
3138
- const [error, setError] = useState12(null);
3139
- const fetchWorkflows = useCallback13(async () => {
3582
+ const [isLoading, setIsLoading] = useState14(false);
3583
+ const [error, setError] = useState14(null);
3584
+ const fetchWorkflows = useCallback15(async () => {
3140
3585
  setIsLoading(true);
3141
3586
  setError(null);
3142
3587
  try {
3143
3588
  const params = new URLSearchParams();
3144
3589
  if (search) params.set("search", search);
3145
- if (status) params.set("status", status);
3590
+ if (scope) params.set("scope", scope);
3591
+ if (visibility) params.set("visibility", visibility);
3592
+ if (isEnabled !== void 0) params.set("isEnabled", String(isEnabled));
3146
3593
  if (page) params.set("page", String(page));
3147
3594
  if (limit) params.set("limit", String(limit));
3148
3595
  const queryStr = params.toString() ? `?${params.toString()}` : "";
@@ -3151,7 +3598,7 @@ function useWorkflows(options) {
3151
3598
  throw new Error(`Failed to list workflows: ${res.statusText}`);
3152
3599
  }
3153
3600
  const data = await res.json();
3154
- const items = Array.isArray(data) ? data : data?.items || data?.workflows || [];
3601
+ const items = Array.isArray(data) ? data : data?.items ?? [];
3155
3602
  setWorkflows(items);
3156
3603
  if (data?.pagination) {
3157
3604
  setPagination({
@@ -3179,8 +3626,8 @@ function useWorkflows(options) {
3179
3626
  } finally {
3180
3627
  setIsLoading(false);
3181
3628
  }
3182
- }, [fetchWithAuth, search, status, page, limit]);
3183
- const createWorkflow = useCallback13(
3629
+ }, [fetchWithAuth, search, scope, visibility, isEnabled, page, limit]);
3630
+ const createWorkflow = useCallback15(
3184
3631
  async (input) => {
3185
3632
  setError(null);
3186
3633
  try {
@@ -3204,7 +3651,7 @@ function useWorkflows(options) {
3204
3651
  },
3205
3652
  [fetchWithAuth]
3206
3653
  );
3207
- useEffect12(() => {
3654
+ useEffect14(() => {
3208
3655
  if (autoFetch) {
3209
3656
  void fetchWorkflows();
3210
3657
  }
@@ -3220,17 +3667,17 @@ function useWorkflows(options) {
3220
3667
  }
3221
3668
 
3222
3669
  // src/hooks/useWorkflow.ts
3223
- import { useCallback as useCallback14, useEffect as useEffect13, useState as useState13 } from "react";
3670
+ import { useCallback as useCallback16, useEffect as useEffect15, useState as useState15 } from "react";
3224
3671
  function useWorkflow(workflowId, options) {
3225
3672
  const opts = typeof options === "boolean" ? { autoFetch: options } : options ?? {};
3226
3673
  const { autoFetch = true } = opts;
3227
3674
  const { fetchWithAuth } = usePersonaContext();
3228
- const [workflow, setWorkflow] = useState13(null);
3229
- const [versions, setVersions] = useState13([]);
3230
- const [mermaid, setMermaid] = useState13(null);
3231
- const [isLoading, setIsLoading] = useState13(false);
3232
- const [error, setError] = useState13(null);
3233
- const fetchWorkflow = useCallback14(async () => {
3675
+ const [workflow, setWorkflow] = useState15(null);
3676
+ const [versions, setVersions] = useState15([]);
3677
+ const [mermaid, setMermaid] = useState15(null);
3678
+ const [isLoading, setIsLoading] = useState15(false);
3679
+ const [error, setError] = useState15(null);
3680
+ const fetchWorkflow = useCallback16(async () => {
3234
3681
  if (!workflowId) return null;
3235
3682
  setIsLoading(true);
3236
3683
  setError(null);
@@ -3250,20 +3697,31 @@ function useWorkflow(workflowId, options) {
3250
3697
  setIsLoading(false);
3251
3698
  }
3252
3699
  }, [fetchWithAuth, workflowId]);
3253
- const fetchVersions = useCallback14(async () => {
3700
+ const fetchVersions = useCallback16(async () => {
3254
3701
  if (!workflowId) return [];
3255
3702
  try {
3256
3703
  const res = await fetchWithAuth(`/workflows/${workflowId}/versions`);
3257
3704
  if (!res.ok) return [];
3258
3705
  const data = await res.json();
3259
- const items = Array.isArray(data) ? data : data?.items || [];
3706
+ const items = Array.isArray(data) ? data : data?.items ?? [];
3260
3707
  setVersions(items);
3261
3708
  return items;
3262
3709
  } catch {
3263
3710
  return [];
3264
3711
  }
3265
3712
  }, [fetchWithAuth, workflowId]);
3266
- const fetchMermaid = useCallback14(async () => {
3713
+ const getVersion = useCallback16(
3714
+ async (version) => {
3715
+ if (!workflowId) throw new Error("Workflow ID is required");
3716
+ const res = await fetchWithAuth(`/workflows/${workflowId}/versions/${version}`);
3717
+ if (!res.ok) {
3718
+ throw new Error(`Failed to fetch workflow version (${res.status}): ${res.statusText}`);
3719
+ }
3720
+ return await res.json();
3721
+ },
3722
+ [fetchWithAuth, workflowId]
3723
+ );
3724
+ const fetchMermaid = useCallback16(async () => {
3267
3725
  if (!workflowId) return "";
3268
3726
  try {
3269
3727
  const res = await fetchWithAuth(`/workflows/${workflowId}/mermaid`);
@@ -3276,18 +3734,18 @@ function useWorkflow(workflowId, options) {
3276
3734
  return "";
3277
3735
  }
3278
3736
  }, [fetchWithAuth, workflowId]);
3279
- const saveDraft = useCallback14(
3280
- async (draft) => {
3737
+ const updateWorkflow = useCallback16(
3738
+ async (input) => {
3281
3739
  if (!workflowId) throw new Error("Workflow ID is required");
3282
3740
  setError(null);
3283
- const res = await fetchWithAuth(`/workflows/${workflowId}/draft`, {
3284
- method: "POST",
3741
+ const res = await fetchWithAuth(`/workflows/${workflowId}`, {
3742
+ method: "PATCH",
3285
3743
  headers: { "Content-Type": "application/json" },
3286
- body: JSON.stringify({ draft })
3744
+ body: JSON.stringify(input)
3287
3745
  });
3288
3746
  if (!res.ok) {
3289
3747
  const errText = await res.text().catch(() => res.statusText);
3290
- throw new Error(`Failed to save draft (${res.status}): ${errText}`);
3748
+ throw new Error(`Failed to update workflow (${res.status}): ${errText}`);
3291
3749
  }
3292
3750
  const updated = await res.json();
3293
3751
  setWorkflow(updated);
@@ -3295,27 +3753,41 @@ function useWorkflow(workflowId, options) {
3295
3753
  },
3296
3754
  [fetchWithAuth, workflowId]
3297
3755
  );
3298
- const publish = useCallback14(
3299
- async (summary) => {
3756
+ const saveDraft = useCallback16(
3757
+ async (draft) => {
3300
3758
  if (!workflowId) throw new Error("Workflow ID is required");
3301
3759
  setError(null);
3302
- const res = await fetchWithAuth(`/workflows/${workflowId}/publish`, {
3303
- method: "POST",
3760
+ const res = await fetchWithAuth(`/workflows/${workflowId}/draft`, {
3761
+ method: "PUT",
3304
3762
  headers: { "Content-Type": "application/json" },
3305
- body: JSON.stringify(summary ? { summary } : {})
3763
+ body: JSON.stringify(draft)
3306
3764
  });
3307
3765
  if (!res.ok) {
3308
3766
  const errText = await res.text().catch(() => res.statusText);
3309
- throw new Error(`Failed to publish workflow (${res.status}): ${errText}`);
3767
+ throw new Error(`Failed to save draft (${res.status}): ${errText}`);
3310
3768
  }
3311
- const versionResult = await res.json();
3312
- void fetchWorkflow();
3313
- void fetchVersions();
3314
- return versionResult;
3769
+ const updated = await res.json();
3770
+ setWorkflow(updated);
3771
+ return updated;
3315
3772
  },
3316
- [fetchWithAuth, workflowId, fetchWorkflow, fetchVersions]
3773
+ [fetchWithAuth, workflowId]
3317
3774
  );
3318
- const deleteWorkflow = useCallback14(async () => {
3775
+ const publish = useCallback16(async () => {
3776
+ if (!workflowId) throw new Error("Workflow ID is required");
3777
+ setError(null);
3778
+ const res = await fetchWithAuth(`/workflows/${workflowId}/publish`, {
3779
+ method: "POST"
3780
+ });
3781
+ if (!res.ok) {
3782
+ const errText = await res.text().catch(() => res.statusText);
3783
+ throw new Error(`Failed to publish workflow (${res.status}): ${errText}`);
3784
+ }
3785
+ const versionResult = await res.json();
3786
+ void fetchWorkflow();
3787
+ void fetchVersions();
3788
+ return versionResult;
3789
+ }, [fetchWithAuth, workflowId, fetchWorkflow, fetchVersions]);
3790
+ const deleteWorkflow = useCallback16(async () => {
3319
3791
  if (!workflowId) throw new Error("Workflow ID is required");
3320
3792
  setError(null);
3321
3793
  const res = await fetchWithAuth(`/workflows/${workflowId}`, {
@@ -3326,7 +3798,7 @@ function useWorkflow(workflowId, options) {
3326
3798
  }
3327
3799
  setWorkflow(null);
3328
3800
  }, [fetchWithAuth, workflowId]);
3329
- useEffect13(() => {
3801
+ useEffect15(() => {
3330
3802
  if (autoFetch && workflowId) {
3331
3803
  void fetchWorkflow();
3332
3804
  }
@@ -3339,7 +3811,9 @@ function useWorkflow(workflowId, options) {
3339
3811
  error,
3340
3812
  refetch: fetchWorkflow,
3341
3813
  fetchVersions,
3814
+ getVersion,
3342
3815
  fetchMermaid,
3816
+ updateWorkflow,
3343
3817
  saveDraft,
3344
3818
  publish,
3345
3819
  deleteWorkflow
@@ -3347,25 +3821,25 @@ function useWorkflow(workflowId, options) {
3347
3821
  }
3348
3822
 
3349
3823
  // src/hooks/useWorkflowStream.ts
3350
- import { useCallback as useCallback15, useEffect as useEffect14, useRef as useRef4, useState as useState14 } from "react";
3824
+ import { useCallback as useCallback17, useEffect as useEffect16, useRef as useRef4, useState as useState16 } from "react";
3351
3825
  function useWorkflowStream(workflowId, options) {
3352
3826
  const { baseUrl, getAuthToken, fetchWithAuth, logger } = usePersonaContext();
3353
- const [status, setStatus] = useState14("idle");
3354
- const [runId, setRunId] = useState14(null);
3355
- const [activeNodeId, setActiveNodeId] = useState14(null);
3356
- const [nodeRuns, setNodeRuns] = useState14(
3827
+ const [status, setStatus] = useState16("idle");
3828
+ const [runId, setRunId] = useState16(null);
3829
+ const [activeNodeId, setActiveNodeId] = useState16(null);
3830
+ const [nodeRuns, setNodeRuns] = useState16(
3357
3831
  {}
3358
3832
  );
3359
- const [text, setText] = useState14("");
3360
- const [output, setOutput] = useState14(null);
3361
- const [error, setError] = useState14(null);
3362
- const [events, setEvents] = useState14([]);
3833
+ const [text, setText] = useState16("");
3834
+ const [output, setOutput] = useState16(null);
3835
+ const [error, setError] = useState16(null);
3836
+ const [events, setEvents] = useState16([]);
3363
3837
  const abortControllerRef = useRef4(null);
3364
3838
  const currentRunIdRef = useRef4(null);
3365
3839
  currentRunIdRef.current = runId;
3366
3840
  const optionsRef = useRef4(options);
3367
3841
  optionsRef.current = options;
3368
- const cancel = useCallback15(async () => {
3842
+ const cancel = useCallback17(async () => {
3369
3843
  if (abortControllerRef.current) {
3370
3844
  abortControllerRef.current.abort();
3371
3845
  abortControllerRef.current = null;
@@ -3386,7 +3860,7 @@ function useWorkflowStream(workflowId, options) {
3386
3860
  setStatus("cancelled");
3387
3861
  setActiveNodeId(null);
3388
3862
  }, [fetchWithAuth, logger]);
3389
- const reset = useCallback15(() => {
3863
+ const reset = useCallback17(() => {
3390
3864
  if (abortControllerRef.current) {
3391
3865
  abortControllerRef.current.abort();
3392
3866
  abortControllerRef.current = null;
@@ -3400,7 +3874,7 @@ function useWorkflowStream(workflowId, options) {
3400
3874
  setError(null);
3401
3875
  setEvents([]);
3402
3876
  }, []);
3403
- const processStream = useCallback15(
3877
+ const processStream = useCallback17(
3404
3878
  async (url, method, body, targetRunId) => {
3405
3879
  if (abortControllerRef.current) {
3406
3880
  abortControllerRef.current.abort();
@@ -3565,7 +4039,7 @@ function useWorkflowStream(workflowId, options) {
3565
4039
  },
3566
4040
  [getAuthToken]
3567
4041
  );
3568
- const start = useCallback15(
4042
+ const start = useCallback17(
3569
4043
  async (input, opts) => {
3570
4044
  const targetWfId = opts?.workflowId || workflowId;
3571
4045
  if (!targetWfId) {
@@ -3586,7 +4060,7 @@ function useWorkflowStream(workflowId, options) {
3586
4060
  },
3587
4061
  [workflowId, baseUrl, processStream]
3588
4062
  );
3589
- const resume = useCallback15(
4063
+ const resume = useCallback17(
3590
4064
  async (targetRunId, sinceSeq) => {
3591
4065
  if (!targetRunId) {
3592
4066
  throw new Error("Run ID is required to resume stream");
@@ -3599,7 +4073,7 @@ function useWorkflowStream(workflowId, options) {
3599
4073
  },
3600
4074
  [baseUrl, processStream]
3601
4075
  );
3602
- useEffect14(() => {
4076
+ useEffect16(() => {
3603
4077
  return () => {
3604
4078
  if (abortControllerRef.current) {
3605
4079
  abortControllerRef.current.abort();
@@ -3624,21 +4098,21 @@ function useWorkflowStream(workflowId, options) {
3624
4098
  }
3625
4099
 
3626
4100
  // src/hooks/useWorkflowRuns.ts
3627
- import { useCallback as useCallback16, useEffect as useEffect15, useState as useState15 } from "react";
4101
+ import { useCallback as useCallback18, useEffect as useEffect17, useState as useState17 } from "react";
3628
4102
  function useWorkflowRuns(workflowId, options) {
3629
4103
  const opts = typeof options === "boolean" ? { autoFetch: options } : options ?? {};
3630
4104
  const { autoFetch = true, page = 1, limit = 20 } = opts;
3631
4105
  const { fetchWithAuth } = usePersonaContext();
3632
- const [runs, setRuns] = useState15([]);
3633
- const [pagination, setPagination] = useState15({
4106
+ const [runs, setRuns] = useState17([]);
4107
+ const [pagination, setPagination] = useState17({
3634
4108
  page,
3635
4109
  limit,
3636
4110
  total: 0,
3637
4111
  totalPages: 0
3638
4112
  });
3639
- const [isLoading, setIsLoading] = useState15(false);
3640
- const [error, setError] = useState15(null);
3641
- const fetchRuns = useCallback16(async () => {
4113
+ const [isLoading, setIsLoading] = useState17(false);
4114
+ const [error, setError] = useState17(null);
4115
+ const fetchRuns = useCallback18(async () => {
3642
4116
  if (!workflowId) return [];
3643
4117
  setIsLoading(true);
3644
4118
  setError(null);
@@ -3649,14 +4123,16 @@ function useWorkflowRuns(workflowId, options) {
3649
4123
  throw new Error(`Failed to list workflow runs: ${res.statusText}`);
3650
4124
  }
3651
4125
  const data = await res.json();
3652
- const items = Array.isArray(data) ? data : data?.items || data?.runs || [];
4126
+ const items = Array.isArray(data) ? data : data?.items ?? [];
3653
4127
  setRuns(items);
3654
4128
  if (data?.pagination) {
3655
4129
  setPagination({
3656
4130
  page: data.pagination.page ?? page,
3657
4131
  limit: data.pagination.limit ?? limit,
3658
4132
  total: data.pagination.total ?? items.length,
3659
- totalPages: data.pagination.totalPages ?? 1
4133
+ // Backend's paginationEnvelope() names this field `pages`, not
4134
+ // `totalPages`.
4135
+ totalPages: data.pagination.pages ?? 1
3660
4136
  });
3661
4137
  }
3662
4138
  return items;
@@ -3668,7 +4144,7 @@ function useWorkflowRuns(workflowId, options) {
3668
4144
  setIsLoading(false);
3669
4145
  }
3670
4146
  }, [fetchWithAuth, workflowId, page, limit]);
3671
- const getRun = useCallback16(
4147
+ const getRun = useCallback18(
3672
4148
  async (runId) => {
3673
4149
  if (!runId) throw new Error("Run ID is required");
3674
4150
  const res = await fetchWithAuth(`/workflows/runs/${runId}`);
@@ -3679,7 +4155,7 @@ function useWorkflowRuns(workflowId, options) {
3679
4155
  },
3680
4156
  [fetchWithAuth]
3681
4157
  );
3682
- const cancelRun = useCallback16(
4158
+ const cancelRun = useCallback18(
3683
4159
  async (runId) => {
3684
4160
  if (!runId) throw new Error("Run ID is required");
3685
4161
  const res = await fetchWithAuth(`/workflows/runs/${runId}/cancel`, {
@@ -3694,7 +4170,7 @@ function useWorkflowRuns(workflowId, options) {
3694
4170
  },
3695
4171
  [fetchWithAuth]
3696
4172
  );
3697
- useEffect15(() => {
4173
+ useEffect17(() => {
3698
4174
  if (autoFetch && workflowId) {
3699
4175
  void fetchRuns();
3700
4176
  }
@@ -3735,7 +4211,9 @@ export {
3735
4211
  useChat,
3736
4212
  useConnection,
3737
4213
  useFiles,
4214
+ useKnowledgeBases,
3738
4215
  useMcp,
4216
+ useMcpAdmin,
3739
4217
  useMcpConnections,
3740
4218
  useMemory,
3741
4219
  usePersonaContext,