@trustgraph/react-state 0.3.1 → 1.2.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.cjs +282 -427
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +281 -426
- package/dist/index.esm.js.map +1 -1
- package/dist/model/settings-types.d.ts +2 -2
- package/dist/model/settings-types.d.ts.map +1 -1
- package/dist/state/chat-session.d.ts.map +1 -1
- package/dist/state/conversation.d.ts +1 -0
- package/dist/state/conversation.d.ts.map +1 -1
- package/dist/state/entity-query.d.ts +4 -11
- package/dist/state/entity-query.d.ts.map +1 -1
- package/dist/state/flow-blueprints.d.ts +63 -0
- package/dist/state/flow-blueprints.d.ts.map +1 -0
- package/dist/state/flow-parameters.d.ts +3 -3
- package/dist/state/flow-parameters.d.ts.map +1 -1
- package/dist/state/flows.d.ts +5 -5
- package/dist/state/flows.d.ts.map +1 -1
- package/dist/state/graph-embeddings.d.ts +7 -7
- package/dist/state/graph-embeddings.d.ts.map +1 -1
- package/dist/state/inference.d.ts +13 -3
- package/dist/state/inference.d.ts.map +1 -1
- package/dist/state/library.d.ts +11 -11
- package/dist/state/library.d.ts.map +1 -1
- package/dist/state/nlp-query.d.ts +9 -9
- package/dist/state/nlp-query.d.ts.map +1 -1
- package/dist/state/processing.d.ts +3 -3
- package/dist/state/processing.d.ts.map +1 -1
- package/dist/state/token-costs.d.ts +3 -11
- package/dist/state/token-costs.d.ts.map +1 -1
- package/dist/state/triples.d.ts +9 -9
- package/dist/state/triples.d.ts.map +1 -1
- package/dist/utils/row.d.ts.map +1 -1
- package/package.json +5 -5
package/dist/index.cjs
CHANGED
|
@@ -6,6 +6,7 @@ var react = require('react');
|
|
|
6
6
|
var zustand = require('zustand');
|
|
7
7
|
var reactQuery = require('@tanstack/react-query');
|
|
8
8
|
var uuid = require('uuid');
|
|
9
|
+
var similarity = require('compute-cosine-similarity');
|
|
9
10
|
|
|
10
11
|
// Create context for notification handler
|
|
11
12
|
const NotificationContext = react.createContext(null);
|
|
@@ -170,6 +171,16 @@ const useConversation = zustand.create()((set) => ({
|
|
|
170
171
|
},
|
|
171
172
|
],
|
|
172
173
|
})),
|
|
174
|
+
updateLastMessage: (text) => set((state) => {
|
|
175
|
+
if (state.messages.length === 0)
|
|
176
|
+
return state;
|
|
177
|
+
const messages = [...state.messages];
|
|
178
|
+
messages[messages.length - 1] = {
|
|
179
|
+
...messages[messages.length - 1],
|
|
180
|
+
text: text,
|
|
181
|
+
};
|
|
182
|
+
return { messages };
|
|
183
|
+
}),
|
|
173
184
|
setInput: (v) => set(() => ({
|
|
174
185
|
input: v,
|
|
175
186
|
})),
|
|
@@ -302,8 +313,8 @@ const DEFAULT_SETTINGS = {
|
|
|
302
313
|
mcpTools: false, // Off by default
|
|
303
314
|
schemas: false, // Off by default
|
|
304
315
|
tokenCost: false, // Off by default
|
|
305
|
-
|
|
306
|
-
|
|
316
|
+
flowBlueprints: false, // Off by default
|
|
317
|
+
flowBlueprintEditor: false, // Off by default - experimental feature
|
|
307
318
|
structuredQuery: false, // Off by default
|
|
308
319
|
llmModels: false, // Off by default
|
|
309
320
|
},
|
|
@@ -536,19 +547,19 @@ const useFlows = () => {
|
|
|
536
547
|
},
|
|
537
548
|
});
|
|
538
549
|
/**
|
|
539
|
-
* Query for fetching all flow
|
|
550
|
+
* Query for fetching all flow blueprints
|
|
540
551
|
* Uses React Query for caching and background refetching
|
|
541
552
|
*/
|
|
542
|
-
const
|
|
543
|
-
queryKey: ["flow-
|
|
553
|
+
const flowBlueprintsQuery = reactQuery.useQuery({
|
|
554
|
+
queryKey: ["flow-blueprints"],
|
|
544
555
|
enabled: isSocketReady,
|
|
545
556
|
queryFn: () => {
|
|
546
557
|
return socket
|
|
547
558
|
.flows()
|
|
548
|
-
.
|
|
559
|
+
.getFlowBlueprints()
|
|
549
560
|
.then((cls) => Promise.all(cls.map((id) => socket
|
|
550
561
|
.flows()
|
|
551
|
-
.
|
|
562
|
+
.getFlowBlueprint(id)
|
|
552
563
|
.then((cls) => [id, cls]))));
|
|
553
564
|
},
|
|
554
565
|
});
|
|
@@ -556,10 +567,10 @@ const useFlows = () => {
|
|
|
556
567
|
* Mutation for starting a new flow for processing workflows
|
|
557
568
|
*/
|
|
558
569
|
const startFlowMutation = reactQuery.useMutation({
|
|
559
|
-
mutationFn: ({ id,
|
|
570
|
+
mutationFn: ({ id, blueprintName, description, parameters, onSuccess, }) => {
|
|
560
571
|
return socket
|
|
561
572
|
.flows()
|
|
562
|
-
.startFlow(id,
|
|
573
|
+
.startFlow(id, blueprintName, description, parameters)
|
|
563
574
|
.then(() => {
|
|
564
575
|
// Execute success callback if provided
|
|
565
576
|
if (onSuccess)
|
|
@@ -604,7 +615,7 @@ const useFlows = () => {
|
|
|
604
615
|
});
|
|
605
616
|
// Show loading indicators for long-running operations
|
|
606
617
|
useActivity(flowsQuery.isLoading, "Loading flows");
|
|
607
|
-
useActivity(
|
|
618
|
+
useActivity(flowBlueprintsQuery.isLoading, "Loading flow blueprints");
|
|
608
619
|
useActivity(startFlowMutation.isPending, "Starting flow");
|
|
609
620
|
useActivity(stopFlowMutation.isPending, "Stopping flows");
|
|
610
621
|
// Return flows state and operations for use in components
|
|
@@ -614,11 +625,11 @@ const useFlows = () => {
|
|
|
614
625
|
isLoading: flowsQuery.isLoading,
|
|
615
626
|
isError: flowsQuery.isError,
|
|
616
627
|
error: flowsQuery.error,
|
|
617
|
-
// Flow data and query state
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
628
|
+
// Flow blueprint data and query state
|
|
629
|
+
flowBlueprints: flowBlueprintsQuery.data,
|
|
630
|
+
isFlowBlueprintsLoading: flowBlueprintsQuery.isLoading,
|
|
631
|
+
isFlowBlueprintsError: flowBlueprintsQuery.isError,
|
|
632
|
+
flowBlueprintsError: flowBlueprintsQuery.error,
|
|
622
633
|
// Flow start operations
|
|
623
634
|
startFlow: startFlowMutation.mutate,
|
|
624
635
|
isStarting: startFlowMutation.isPending,
|
|
@@ -1409,273 +1420,6 @@ const useGraphEmbeddings = ({ flow, vecs, limit, collection }) => {
|
|
|
1409
1420
|
};
|
|
1410
1421
|
};
|
|
1411
1422
|
|
|
1412
|
-
function getDefaultExportFromCjs (x) {
|
|
1413
|
-
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
|
1414
|
-
}
|
|
1415
|
-
|
|
1416
|
-
/**
|
|
1417
|
-
* FUNCTION: isArray( value )
|
|
1418
|
-
* Validates if a value is an array.
|
|
1419
|
-
*
|
|
1420
|
-
* @param {*} value - value to be validated
|
|
1421
|
-
* @returns {Boolean} boolean indicating whether value is an array
|
|
1422
|
-
*/
|
|
1423
|
-
function isArray$3( value ) {
|
|
1424
|
-
return Object.prototype.toString.call( value ) === '[object Array]';
|
|
1425
|
-
} // end FUNCTION isArray()
|
|
1426
|
-
|
|
1427
|
-
// EXPORTS //
|
|
1428
|
-
|
|
1429
|
-
var lib$4 = Array.isArray || isArray$3;
|
|
1430
|
-
|
|
1431
|
-
/**
|
|
1432
|
-
*
|
|
1433
|
-
* VALIDATE: function
|
|
1434
|
-
*
|
|
1435
|
-
*
|
|
1436
|
-
* DESCRIPTION:
|
|
1437
|
-
* - Validates if a value is a function.
|
|
1438
|
-
*
|
|
1439
|
-
*
|
|
1440
|
-
* NOTES:
|
|
1441
|
-
* [1]
|
|
1442
|
-
*
|
|
1443
|
-
*
|
|
1444
|
-
* TODO:
|
|
1445
|
-
* [1]
|
|
1446
|
-
*
|
|
1447
|
-
*
|
|
1448
|
-
* LICENSE:
|
|
1449
|
-
* MIT
|
|
1450
|
-
*
|
|
1451
|
-
* Copyright (c) 2014. Athan Reines.
|
|
1452
|
-
*
|
|
1453
|
-
*
|
|
1454
|
-
* AUTHOR:
|
|
1455
|
-
* Athan Reines. kgryte@gmail.com. 2014.
|
|
1456
|
-
*
|
|
1457
|
-
*/
|
|
1458
|
-
|
|
1459
|
-
/**
|
|
1460
|
-
* FUNCTION: isFunction( value )
|
|
1461
|
-
* Validates if a value is a function.
|
|
1462
|
-
*
|
|
1463
|
-
* @param {*} value - value to be validated
|
|
1464
|
-
* @returns {Boolean} boolean indicating whether value is a function
|
|
1465
|
-
*/
|
|
1466
|
-
function isFunction$3( value ) {
|
|
1467
|
-
return ( typeof value === 'function' );
|
|
1468
|
-
} // end FUNCTION isFunction()
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
// EXPORTS //
|
|
1472
|
-
|
|
1473
|
-
var lib$3 = isFunction$3;
|
|
1474
|
-
|
|
1475
|
-
// MODULES //
|
|
1476
|
-
|
|
1477
|
-
var isArray$2 = lib$4,
|
|
1478
|
-
isFunction$2 = lib$3;
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
// DOT PRODUCT //
|
|
1482
|
-
|
|
1483
|
-
/**
|
|
1484
|
-
* FUNCTION: dot( x, y[, accessor] )
|
|
1485
|
-
* Computes the dot product between two arrays.
|
|
1486
|
-
*
|
|
1487
|
-
* @param {Array} x - input array
|
|
1488
|
-
* @param {Array} y - input array
|
|
1489
|
-
* @param {Function} [accessor] - accessor function for accessing array values
|
|
1490
|
-
* @returns {Number|Null} dot product
|
|
1491
|
-
*/
|
|
1492
|
-
function dot$1( x, y, clbk ) {
|
|
1493
|
-
if ( !isArray$2( x ) ) {
|
|
1494
|
-
throw new TypeError( 'dot()::invalid input argument. First argument must be an array. Value: `' + x + '`.' );
|
|
1495
|
-
}
|
|
1496
|
-
if ( !isArray$2( y ) ) {
|
|
1497
|
-
throw new TypeError( 'dot()::invalid input argument. Second argument must be an array. Value: `' + y + '`.' );
|
|
1498
|
-
}
|
|
1499
|
-
if ( arguments.length > 2 ) {
|
|
1500
|
-
if ( !isFunction$2( clbk ) ) {
|
|
1501
|
-
throw new TypeError( 'dot()::invalid input argument. Accessor must be a function. Value: `' + clbk + '`.' );
|
|
1502
|
-
}
|
|
1503
|
-
}
|
|
1504
|
-
var len = x.length,
|
|
1505
|
-
sum = 0,
|
|
1506
|
-
i;
|
|
1507
|
-
|
|
1508
|
-
if ( len !== y.length ) {
|
|
1509
|
-
throw new Error( 'dot()::invalid input argument. Arrays must be of equal length.' );
|
|
1510
|
-
}
|
|
1511
|
-
if ( !len ) {
|
|
1512
|
-
return null;
|
|
1513
|
-
}
|
|
1514
|
-
if ( clbk ) {
|
|
1515
|
-
for ( i = 0; i < len; i++ ) {
|
|
1516
|
-
sum += clbk( x[ i ], i, 0 ) * clbk( y[ i ], i, 1 );
|
|
1517
|
-
}
|
|
1518
|
-
} else {
|
|
1519
|
-
for ( i = 0; i < len; i++ ) {
|
|
1520
|
-
sum += x[ i ] * y[ i ];
|
|
1521
|
-
}
|
|
1522
|
-
}
|
|
1523
|
-
return sum;
|
|
1524
|
-
} // end FUNCTION dot()
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
// EXPORTS //
|
|
1528
|
-
|
|
1529
|
-
var lib$2 = dot$1;
|
|
1530
|
-
|
|
1531
|
-
// MODULES //
|
|
1532
|
-
|
|
1533
|
-
var isArray$1 = lib$4,
|
|
1534
|
-
isFunction$1 = lib$3;
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
// L2NORM //
|
|
1538
|
-
|
|
1539
|
-
/**
|
|
1540
|
-
* FUNCTION: l2norm( arr[, accessor] )
|
|
1541
|
-
* Calculates the L2 norm (Euclidean norm) of an array.
|
|
1542
|
-
*
|
|
1543
|
-
* @param {Array} arr - input array
|
|
1544
|
-
* @param {Function} [accessor] - accessor function for accessing array values
|
|
1545
|
-
* @returns {Number|Null} L2 norm or null
|
|
1546
|
-
*/
|
|
1547
|
-
function l2norm$1( arr, clbk ) {
|
|
1548
|
-
if ( !isArray$1( arr ) ) {
|
|
1549
|
-
throw new TypeError( 'l2norm()::invalid input argument. Must provide an array. Value: `' + arr + '`.' );
|
|
1550
|
-
}
|
|
1551
|
-
if ( arguments.length > 1 ) {
|
|
1552
|
-
if ( !isFunction$1( clbk ) ) {
|
|
1553
|
-
throw new TypeError( 'l2norm()::invalid input argument. Accessor must be a function. Value: `' + clbk + '`.' );
|
|
1554
|
-
}
|
|
1555
|
-
}
|
|
1556
|
-
var len = arr.length,
|
|
1557
|
-
t = 0,
|
|
1558
|
-
s = 1,
|
|
1559
|
-
r,
|
|
1560
|
-
val,
|
|
1561
|
-
abs,
|
|
1562
|
-
i;
|
|
1563
|
-
|
|
1564
|
-
if ( !len ) {
|
|
1565
|
-
return null;
|
|
1566
|
-
}
|
|
1567
|
-
if ( clbk ) {
|
|
1568
|
-
for ( i = 0; i < len; i++ ) {
|
|
1569
|
-
val = clbk( arr[ i ], i );
|
|
1570
|
-
abs = ( val < 0 ) ? -val : val;
|
|
1571
|
-
if ( abs > 0 ) {
|
|
1572
|
-
if ( abs > t ) {
|
|
1573
|
-
r = t / val;
|
|
1574
|
-
s = 1 + s*r*r;
|
|
1575
|
-
t = abs;
|
|
1576
|
-
} else {
|
|
1577
|
-
r = val / t;
|
|
1578
|
-
s = s + r*r;
|
|
1579
|
-
}
|
|
1580
|
-
}
|
|
1581
|
-
}
|
|
1582
|
-
} else {
|
|
1583
|
-
for ( i = 0; i < len; i++ ) {
|
|
1584
|
-
val = arr[ i ];
|
|
1585
|
-
abs = ( val < 0 ) ? -val : val;
|
|
1586
|
-
if ( abs > 0 ) {
|
|
1587
|
-
if ( abs > t ) {
|
|
1588
|
-
r = t / val;
|
|
1589
|
-
s = 1 + s*r*r;
|
|
1590
|
-
t = abs;
|
|
1591
|
-
} else {
|
|
1592
|
-
r = val / t;
|
|
1593
|
-
s = s + r*r;
|
|
1594
|
-
}
|
|
1595
|
-
}
|
|
1596
|
-
}
|
|
1597
|
-
}
|
|
1598
|
-
return t * Math.sqrt( s );
|
|
1599
|
-
} // end FUNCTION l2norm()
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
// EXPORTS //
|
|
1603
|
-
|
|
1604
|
-
var lib$1 = l2norm$1;
|
|
1605
|
-
|
|
1606
|
-
// MODULES //
|
|
1607
|
-
|
|
1608
|
-
var dot = lib$2,
|
|
1609
|
-
l2norm = lib$1,
|
|
1610
|
-
isArray = lib$4,
|
|
1611
|
-
isFunction = lib$3;
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
// FUNCTIONS //
|
|
1615
|
-
|
|
1616
|
-
/**
|
|
1617
|
-
* Partially applied function from the right.
|
|
1618
|
-
*
|
|
1619
|
-
* @private
|
|
1620
|
-
* @param {Function} fn - input function
|
|
1621
|
-
* @param {number} j - array index
|
|
1622
|
-
* @returns {Function} partially applied function
|
|
1623
|
-
*/
|
|
1624
|
-
function partial( fn, j ) {
|
|
1625
|
-
return function accessor( d, i ) {
|
|
1626
|
-
return fn( d, i, j );
|
|
1627
|
-
};
|
|
1628
|
-
}
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
// MAIN //
|
|
1632
|
-
|
|
1633
|
-
/**
|
|
1634
|
-
* Computes the cosine similarity between two arrays.
|
|
1635
|
-
*
|
|
1636
|
-
* @param {number[]|Array} x - input array
|
|
1637
|
-
* @param {number[]|Array} y - input array
|
|
1638
|
-
* @param {Function} [accessor] - accessor function for accessing array values
|
|
1639
|
-
* @returns {number|null} cosine similarity or null
|
|
1640
|
-
*/
|
|
1641
|
-
function similarity( x, y, clbk ) {
|
|
1642
|
-
var a, b, c;
|
|
1643
|
-
if ( !isArray( x ) ) {
|
|
1644
|
-
throw new TypeError( 'cosine-similarity()::invalid input argument. First argument must be an array. Value: `' + x + '`.' );
|
|
1645
|
-
}
|
|
1646
|
-
if ( !isArray( y ) ) {
|
|
1647
|
-
throw new TypeError( 'cosine-similarity()::invalid input argument. Second argument must be an array. Value: `' + y + '`.' );
|
|
1648
|
-
}
|
|
1649
|
-
if ( arguments.length > 2 ) {
|
|
1650
|
-
if ( !isFunction( clbk ) ) {
|
|
1651
|
-
throw new TypeError( 'cosine-similarity()::invalid input argument. Accessor must be a function. Value: `' + clbk + '`.' );
|
|
1652
|
-
}
|
|
1653
|
-
}
|
|
1654
|
-
if ( x.length !== y.length ) {
|
|
1655
|
-
throw new Error( 'cosine-similarity()::invalid input argument. Input arrays must have the same length.' );
|
|
1656
|
-
}
|
|
1657
|
-
if ( !x.length ) {
|
|
1658
|
-
return null;
|
|
1659
|
-
}
|
|
1660
|
-
if ( clbk ) {
|
|
1661
|
-
a = dot( x, y, clbk );
|
|
1662
|
-
b = l2norm( x, partial( clbk, 0 ) );
|
|
1663
|
-
c = l2norm( y, partial( clbk, 1 ) );
|
|
1664
|
-
} else {
|
|
1665
|
-
a = dot( x, y );
|
|
1666
|
-
b = l2norm( x );
|
|
1667
|
-
c = l2norm( y );
|
|
1668
|
-
}
|
|
1669
|
-
return a / ( b*c );
|
|
1670
|
-
}
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
// EXPORTS //
|
|
1674
|
-
|
|
1675
|
-
var lib = similarity;
|
|
1676
|
-
|
|
1677
|
-
var similarity$1 = /*@__PURE__*/getDefaultExportFromCjs(lib);
|
|
1678
|
-
|
|
1679
1423
|
// Take the embeddings, and lookup entities using graph
|
|
1680
1424
|
// embeddings, add embedding to each entity row, just an easy
|
|
1681
1425
|
// place to put it
|
|
@@ -1795,7 +1539,7 @@ const addRowEmbeddings = (socket, add, remove) => (entities) => {
|
|
|
1795
1539
|
};
|
|
1796
1540
|
// Rest of the procecess is not async, so not adding progress
|
|
1797
1541
|
const computeCosineSimilarity = () => (entities) => entities.map((ent) => {
|
|
1798
|
-
const sim = similarity
|
|
1542
|
+
const sim = similarity(ent.target, ent.embeddings);
|
|
1799
1543
|
return {
|
|
1800
1544
|
uri: ent.uri,
|
|
1801
1545
|
label: ent.label,
|
|
@@ -1965,11 +1709,27 @@ const useInference = () => {
|
|
|
1965
1709
|
* Graph RAG inference with entity discovery
|
|
1966
1710
|
*/
|
|
1967
1711
|
const graphRagMutation = reactQuery.useMutation({
|
|
1968
|
-
mutationFn: async ({ input, options, collection, }) => {
|
|
1969
|
-
//
|
|
1970
|
-
const response =
|
|
1971
|
-
|
|
1972
|
-
|
|
1712
|
+
mutationFn: async ({ input, options, collection, callbacks, }) => {
|
|
1713
|
+
// If callbacks provided, use streaming API
|
|
1714
|
+
const response = callbacks
|
|
1715
|
+
? await new Promise((resolve, reject) => {
|
|
1716
|
+
let accumulated = "";
|
|
1717
|
+
const onChunk = (chunk, complete) => {
|
|
1718
|
+
accumulated += chunk;
|
|
1719
|
+
callbacks?.onChunk?.(chunk, complete);
|
|
1720
|
+
if (complete) {
|
|
1721
|
+
resolve(accumulated);
|
|
1722
|
+
}
|
|
1723
|
+
};
|
|
1724
|
+
const onError = (error) => {
|
|
1725
|
+
callbacks?.onError?.(error);
|
|
1726
|
+
reject(new Error(error));
|
|
1727
|
+
};
|
|
1728
|
+
socket
|
|
1729
|
+
.flow(flowId)
|
|
1730
|
+
.graphRagStreaming(input, onChunk, onError, options, collection);
|
|
1731
|
+
})
|
|
1732
|
+
: await socket.flow(flowId).graphRag(input, options || {}, collection);
|
|
1973
1733
|
// Get embeddings for entity discovery
|
|
1974
1734
|
const embeddings = await socket.flow(flowId).embeddings(input);
|
|
1975
1735
|
// Query graph embeddings to find entities
|
|
@@ -1983,8 +1743,27 @@ const useInference = () => {
|
|
|
1983
1743
|
* Basic LLM text completion
|
|
1984
1744
|
*/
|
|
1985
1745
|
const textCompletionMutation = reactQuery.useMutation({
|
|
1986
|
-
mutationFn: async ({ systemPrompt, input, }) => {
|
|
1987
|
-
|
|
1746
|
+
mutationFn: async ({ systemPrompt, input, callbacks, }) => {
|
|
1747
|
+
// If callbacks provided, use streaming API
|
|
1748
|
+
return callbacks
|
|
1749
|
+
? await new Promise((resolve, reject) => {
|
|
1750
|
+
let accumulated = "";
|
|
1751
|
+
const onChunk = (chunk, complete) => {
|
|
1752
|
+
accumulated += chunk;
|
|
1753
|
+
callbacks?.onChunk?.(chunk, complete);
|
|
1754
|
+
if (complete) {
|
|
1755
|
+
resolve(accumulated);
|
|
1756
|
+
}
|
|
1757
|
+
};
|
|
1758
|
+
const onError = (error) => {
|
|
1759
|
+
callbacks?.onError?.(error);
|
|
1760
|
+
reject(new Error(error));
|
|
1761
|
+
};
|
|
1762
|
+
socket
|
|
1763
|
+
.flow(flowId)
|
|
1764
|
+
.textCompletionStreaming(systemPrompt, input, onChunk, onError);
|
|
1765
|
+
})
|
|
1766
|
+
: await socket.flow(flowId).textCompletion(systemPrompt, input);
|
|
1988
1767
|
},
|
|
1989
1768
|
});
|
|
1990
1769
|
/**
|
|
@@ -1993,15 +1772,19 @@ const useInference = () => {
|
|
|
1993
1772
|
const agentMutation = reactQuery.useMutation({
|
|
1994
1773
|
mutationFn: async ({ input, callbacks, }) => {
|
|
1995
1774
|
return new Promise((resolve, reject) => {
|
|
1996
|
-
|
|
1997
|
-
|
|
1775
|
+
let fullAnswer = "";
|
|
1776
|
+
const onThink = (thought, complete) => {
|
|
1777
|
+
callbacks?.onThink?.(thought, complete);
|
|
1998
1778
|
};
|
|
1999
|
-
const onObserve = (observation) => {
|
|
2000
|
-
callbacks?.onObserve?.(observation);
|
|
1779
|
+
const onObserve = (observation, complete) => {
|
|
1780
|
+
callbacks?.onObserve?.(observation, complete);
|
|
2001
1781
|
};
|
|
2002
|
-
const onAnswer = (answer) => {
|
|
2003
|
-
|
|
2004
|
-
|
|
1782
|
+
const onAnswer = (answer, complete) => {
|
|
1783
|
+
fullAnswer += answer;
|
|
1784
|
+
callbacks?.onAnswer?.(answer, complete);
|
|
1785
|
+
if (complete) {
|
|
1786
|
+
resolve(fullAnswer);
|
|
1787
|
+
}
|
|
2005
1788
|
};
|
|
2006
1789
|
const onError = (error) => {
|
|
2007
1790
|
callbacks?.onError?.(error);
|
|
@@ -2033,6 +1816,7 @@ const useChatSession = () => {
|
|
|
2033
1816
|
const notify = useNotification();
|
|
2034
1817
|
// Conversation state
|
|
2035
1818
|
const addMessage = useConversation((state) => state.addMessage);
|
|
1819
|
+
const updateLastMessage = useConversation((state) => state.updateLastMessage);
|
|
2036
1820
|
const setInput = useConversation((state) => state.setInput);
|
|
2037
1821
|
const chatMode = useConversation((state) => state.chatMode);
|
|
2038
1822
|
// Progress and activity management
|
|
@@ -2052,8 +1836,10 @@ const useChatSession = () => {
|
|
|
2052
1836
|
const ragActivity = "Graph RAG: " + input;
|
|
2053
1837
|
const embActivity = "Find entities: " + input;
|
|
2054
1838
|
addActivity(ragActivity);
|
|
1839
|
+
let accumulated = "";
|
|
1840
|
+
let messageAdded = false;
|
|
2055
1841
|
try {
|
|
2056
|
-
// Execute Graph RAG with entity discovery
|
|
1842
|
+
// Execute Graph RAG with streaming and entity discovery
|
|
2057
1843
|
const result = await inference.graphRag({
|
|
2058
1844
|
input,
|
|
2059
1845
|
options: {
|
|
@@ -2063,8 +1849,21 @@ const useChatSession = () => {
|
|
|
2063
1849
|
pathLength: settings.graphrag.pathLength,
|
|
2064
1850
|
},
|
|
2065
1851
|
collection: settings.collection,
|
|
1852
|
+
callbacks: {
|
|
1853
|
+
onChunk: (chunk, complete) => {
|
|
1854
|
+
accumulated += chunk;
|
|
1855
|
+
if (!messageAdded) {
|
|
1856
|
+
// Add empty message on first chunk
|
|
1857
|
+
addMessage("ai", accumulated);
|
|
1858
|
+
messageAdded = true;
|
|
1859
|
+
}
|
|
1860
|
+
else {
|
|
1861
|
+
// Update existing message with accumulated text
|
|
1862
|
+
updateLastMessage(accumulated);
|
|
1863
|
+
}
|
|
1864
|
+
},
|
|
1865
|
+
},
|
|
2066
1866
|
});
|
|
2067
|
-
addMessage("ai", result.response);
|
|
2068
1867
|
removeActivity(ragActivity);
|
|
2069
1868
|
// Start embeddings activity
|
|
2070
1869
|
addActivity(embActivity);
|
|
@@ -2108,12 +1907,27 @@ const useChatSession = () => {
|
|
|
2108
1907
|
const handleBasicLlm = async (input) => {
|
|
2109
1908
|
const activity = "Text completion: " + input;
|
|
2110
1909
|
addActivity(activity);
|
|
1910
|
+
let accumulated = "";
|
|
1911
|
+
let messageAdded = false;
|
|
2111
1912
|
try {
|
|
2112
1913
|
const response = await inference.textCompletion({
|
|
2113
1914
|
systemPrompt: "You are a helpful assistant. Provide clear and concise responses.",
|
|
2114
1915
|
input,
|
|
1916
|
+
callbacks: {
|
|
1917
|
+
onChunk: (chunk, complete) => {
|
|
1918
|
+
accumulated += chunk;
|
|
1919
|
+
if (!messageAdded) {
|
|
1920
|
+
// Add empty message on first chunk
|
|
1921
|
+
addMessage("ai", accumulated);
|
|
1922
|
+
messageAdded = true;
|
|
1923
|
+
}
|
|
1924
|
+
else {
|
|
1925
|
+
// Update existing message with accumulated text
|
|
1926
|
+
updateLastMessage(accumulated);
|
|
1927
|
+
}
|
|
1928
|
+
},
|
|
1929
|
+
},
|
|
2115
1930
|
});
|
|
2116
|
-
addMessage("ai", response);
|
|
2117
1931
|
removeActivity(activity);
|
|
2118
1932
|
setEntities([]);
|
|
2119
1933
|
return response;
|
|
@@ -2129,13 +1943,54 @@ const useChatSession = () => {
|
|
|
2129
1943
|
const handleAgent = async (input) => {
|
|
2130
1944
|
const activity = "Agent: " + input;
|
|
2131
1945
|
addActivity(activity);
|
|
1946
|
+
let thinkingAccumulated = "";
|
|
1947
|
+
let thinkingMessageAdded = false;
|
|
1948
|
+
let observationAccumulated = "";
|
|
1949
|
+
let observationMessageAdded = false;
|
|
1950
|
+
let answerAccumulated = "";
|
|
1951
|
+
let answerMessageAdded = false;
|
|
2132
1952
|
try {
|
|
2133
1953
|
const response = await inference.agent({
|
|
2134
1954
|
input,
|
|
2135
1955
|
callbacks: {
|
|
2136
|
-
onThink: (thought) =>
|
|
2137
|
-
|
|
2138
|
-
|
|
1956
|
+
onThink: (thought, complete) => {
|
|
1957
|
+
thinkingAccumulated += thought;
|
|
1958
|
+
if (!thinkingMessageAdded) {
|
|
1959
|
+
addMessage("ai", thinkingAccumulated, "thinking");
|
|
1960
|
+
thinkingMessageAdded = true;
|
|
1961
|
+
}
|
|
1962
|
+
else {
|
|
1963
|
+
updateLastMessage(thinkingAccumulated);
|
|
1964
|
+
}
|
|
1965
|
+
if (complete) {
|
|
1966
|
+
thinkingAccumulated = "";
|
|
1967
|
+
thinkingMessageAdded = false;
|
|
1968
|
+
}
|
|
1969
|
+
},
|
|
1970
|
+
onObserve: (observation, complete) => {
|
|
1971
|
+
observationAccumulated += observation;
|
|
1972
|
+
if (!observationMessageAdded) {
|
|
1973
|
+
addMessage("ai", observationAccumulated, "observation");
|
|
1974
|
+
observationMessageAdded = true;
|
|
1975
|
+
}
|
|
1976
|
+
else {
|
|
1977
|
+
updateLastMessage(observationAccumulated);
|
|
1978
|
+
}
|
|
1979
|
+
if (complete) {
|
|
1980
|
+
observationAccumulated = "";
|
|
1981
|
+
observationMessageAdded = false;
|
|
1982
|
+
}
|
|
1983
|
+
},
|
|
1984
|
+
onAnswer: (answer, complete) => {
|
|
1985
|
+
answerAccumulated += answer;
|
|
1986
|
+
if (!answerMessageAdded) {
|
|
1987
|
+
addMessage("ai", answerAccumulated, "answer");
|
|
1988
|
+
answerMessageAdded = true;
|
|
1989
|
+
}
|
|
1990
|
+
else {
|
|
1991
|
+
updateLastMessage(answerAccumulated);
|
|
1992
|
+
}
|
|
1993
|
+
},
|
|
2139
1994
|
},
|
|
2140
1995
|
});
|
|
2141
1996
|
removeActivity(activity);
|
|
@@ -3570,7 +3425,7 @@ const useTokenCosts = () => {
|
|
|
3570
3425
|
* Uses React Query for caching and background refetching
|
|
3571
3426
|
*/
|
|
3572
3427
|
const query = reactQuery.useQuery({
|
|
3573
|
-
queryKey: ["token-
|
|
3428
|
+
queryKey: ["token-cost"],
|
|
3574
3429
|
enabled: isSocketReady,
|
|
3575
3430
|
queryFn: () => {
|
|
3576
3431
|
return socket
|
|
@@ -3586,17 +3441,17 @@ const useTokenCosts = () => {
|
|
|
3586
3441
|
},
|
|
3587
3442
|
});
|
|
3588
3443
|
/**
|
|
3589
|
-
* Mutation for deleting a specific model's token
|
|
3444
|
+
* Mutation for deleting a specific model's token cost
|
|
3590
3445
|
* Removes the token cost configuration for a given model
|
|
3591
3446
|
*/
|
|
3592
|
-
const
|
|
3447
|
+
const deleteTokenCostMutation = reactQuery.useMutation({
|
|
3593
3448
|
mutationFn: ({ model, onSuccess }) => {
|
|
3594
3449
|
// Delete the token cost configuration for the specified model
|
|
3595
3450
|
return socket
|
|
3596
3451
|
.config()
|
|
3597
3452
|
.deleteConfig([
|
|
3598
3453
|
{
|
|
3599
|
-
type: "token-
|
|
3454
|
+
type: "token-cost",
|
|
3600
3455
|
key: model,
|
|
3601
3456
|
},
|
|
3602
3457
|
])
|
|
@@ -3617,20 +3472,20 @@ const useTokenCosts = () => {
|
|
|
3617
3472
|
},
|
|
3618
3473
|
onSuccess: () => {
|
|
3619
3474
|
// Invalidate cache to trigger refetch
|
|
3620
|
-
queryClient.invalidateQueries({ queryKey: ["token-
|
|
3475
|
+
queryClient.invalidateQueries({ queryKey: ["token-cost"] });
|
|
3621
3476
|
// Show success notification
|
|
3622
3477
|
notify.success("Successful deletion");
|
|
3623
3478
|
},
|
|
3624
3479
|
});
|
|
3625
3480
|
/**
|
|
3626
|
-
* Mutation for updating token
|
|
3481
|
+
* Mutation for updating token cost for a specific model
|
|
3627
3482
|
* Converts per-million token prices to per-token prices and saves
|
|
3628
3483
|
* configuration
|
|
3629
3484
|
*/
|
|
3630
3485
|
const updateTokenCostMutation = reactQuery.useMutation({
|
|
3631
3486
|
mutationFn: ({ model, input_price, output_price, onSuccess }) => {
|
|
3632
3487
|
// Convert per-million token prices to per-token prices
|
|
3633
|
-
const
|
|
3488
|
+
const tokenCosts = {
|
|
3634
3489
|
input_price: input_price / 1000000,
|
|
3635
3490
|
output_price: output_price / 1000000,
|
|
3636
3491
|
};
|
|
@@ -3639,9 +3494,9 @@ const useTokenCosts = () => {
|
|
|
3639
3494
|
.config()
|
|
3640
3495
|
.putConfig([
|
|
3641
3496
|
{
|
|
3642
|
-
type: "token-
|
|
3497
|
+
type: "token-cost",
|
|
3643
3498
|
key: model,
|
|
3644
|
-
value: JSON.stringify(
|
|
3499
|
+
value: JSON.stringify(tokenCosts),
|
|
3645
3500
|
},
|
|
3646
3501
|
])
|
|
3647
3502
|
.then((x) => {
|
|
@@ -3661,14 +3516,14 @@ const useTokenCosts = () => {
|
|
|
3661
3516
|
},
|
|
3662
3517
|
onSuccess: () => {
|
|
3663
3518
|
// Invalidate cache to refresh the token costs list
|
|
3664
|
-
queryClient.invalidateQueries({ queryKey: ["token-
|
|
3519
|
+
queryClient.invalidateQueries({ queryKey: ["token-cost"] });
|
|
3665
3520
|
notify.success("Token costs updated");
|
|
3666
3521
|
},
|
|
3667
3522
|
});
|
|
3668
3523
|
// Show loading indicators for long-running operations
|
|
3669
3524
|
useActivity(query.isLoading, "Loading token costs");
|
|
3670
|
-
useActivity(
|
|
3671
|
-
useActivity(updateTokenCostMutation.isPending, "Updating token
|
|
3525
|
+
useActivity(deleteTokenCostMutation.isPending, "Deleting token cost");
|
|
3526
|
+
useActivity(updateTokenCostMutation.isPending, "Updating token cost");
|
|
3672
3527
|
// Return token cost state and operations for use in components
|
|
3673
3528
|
return {
|
|
3674
3529
|
// Token cost query state
|
|
@@ -3677,9 +3532,9 @@ const useTokenCosts = () => {
|
|
|
3677
3532
|
isError: query.isError,
|
|
3678
3533
|
error: query.error,
|
|
3679
3534
|
// Token cost deletion operations
|
|
3680
|
-
|
|
3681
|
-
isDeleting:
|
|
3682
|
-
deleteError:
|
|
3535
|
+
deleteTokenCost: deleteTokenCostMutation.mutate,
|
|
3536
|
+
isDeleting: deleteTokenCostMutation.isPending,
|
|
3537
|
+
deleteError: deleteTokenCostMutation.error,
|
|
3683
3538
|
// Token cost update operations
|
|
3684
3539
|
updateTokenCost: updateTokenCostMutation.mutate,
|
|
3685
3540
|
isSubmitting: updateTokenCostMutation.isPending,
|
|
@@ -3704,7 +3559,7 @@ const useLLMModels = () => {
|
|
|
3704
3559
|
queryFn: async () => {
|
|
3705
3560
|
const response = await socket
|
|
3706
3561
|
.config()
|
|
3707
|
-
.getConfig([{ type: "parameter-
|
|
3562
|
+
.getConfig([{ type: "parameter-type", key: "llm-model" }]);
|
|
3708
3563
|
if (!response.values || response.values.length === 0) {
|
|
3709
3564
|
return [];
|
|
3710
3565
|
}
|
|
@@ -3740,7 +3595,7 @@ const useLLMModels = () => {
|
|
|
3740
3595
|
};
|
|
3741
3596
|
await socket.config().putConfig([
|
|
3742
3597
|
{
|
|
3743
|
-
type: "parameter-
|
|
3598
|
+
type: "parameter-type",
|
|
3744
3599
|
key: name,
|
|
3745
3600
|
value: JSON.stringify(updatedDef),
|
|
3746
3601
|
},
|
|
@@ -3769,11 +3624,11 @@ const useLLMModels = () => {
|
|
|
3769
3624
|
|
|
3770
3625
|
// @ts-nocheck
|
|
3771
3626
|
/**
|
|
3772
|
-
* Custom hook for managing flow
|
|
3773
|
-
* Provides functionality for fetching, creating, updating, and deleting flow
|
|
3774
|
-
* @returns {Object} Flow
|
|
3627
|
+
* Custom hook for managing flow blueprint operations
|
|
3628
|
+
* Provides functionality for fetching, creating, updating, and deleting flow blueprintes
|
|
3629
|
+
* @returns {Object} Flow blueprint state and operations
|
|
3775
3630
|
*/
|
|
3776
|
-
const
|
|
3631
|
+
const useFlowBlueprints = () => {
|
|
3777
3632
|
// WebSocket connection for communicating with the config service
|
|
3778
3633
|
const socket = reactProvider.useSocket();
|
|
3779
3634
|
const connectionState = reactProvider.useConnectionState();
|
|
@@ -3785,11 +3640,11 @@ const useFlowClasses = () => {
|
|
|
3785
3640
|
const isSocketReady = connectionState?.status === "authenticated" ||
|
|
3786
3641
|
connectionState?.status === "unauthenticated";
|
|
3787
3642
|
/**
|
|
3788
|
-
* Query for fetching all flow
|
|
3643
|
+
* Query for fetching all flow blueprintes
|
|
3789
3644
|
* Uses React Query for caching and background refetching
|
|
3790
3645
|
*/
|
|
3791
3646
|
const query = reactQuery.useQuery({
|
|
3792
|
-
queryKey: ["flow-
|
|
3647
|
+
queryKey: ["flow-blueprints"],
|
|
3793
3648
|
enabled: isSocketReady,
|
|
3794
3649
|
staleTime: 0, // Force fresh data
|
|
3795
3650
|
gcTime: 0, // Don't cache (React Query v5 uses gcTime instead of cacheTime)
|
|
@@ -3798,54 +3653,54 @@ const useFlowClasses = () => {
|
|
|
3798
3653
|
try {
|
|
3799
3654
|
const response = await socket.config().getConfigAll();
|
|
3800
3655
|
// Handle both array and object responses
|
|
3801
|
-
const config = response.config["flow-
|
|
3656
|
+
const config = response.config["flow-blueprints"];
|
|
3802
3657
|
if (Array.isArray(config)) {
|
|
3803
3658
|
// If it's already an array, check if it's an array of [key, value] pairs
|
|
3804
3659
|
if (config.length > 0 &&
|
|
3805
3660
|
Array.isArray(config[0]) &&
|
|
3806
3661
|
config[0].length === 2) {
|
|
3807
|
-
// It's an array of [id,
|
|
3808
|
-
const converted = config.map(([id,
|
|
3809
|
-
let
|
|
3810
|
-
// If the
|
|
3811
|
-
if (typeof
|
|
3662
|
+
// It's an array of [id, flowBlueprint] pairs - convert to objects
|
|
3663
|
+
const converted = config.map(([id, flowBlueprintData]) => {
|
|
3664
|
+
let flowBlueprint = flowBlueprintData;
|
|
3665
|
+
// If the flowBlueprint is a JSON string, parse it
|
|
3666
|
+
if (typeof flowBlueprintData === "string") {
|
|
3812
3667
|
try {
|
|
3813
|
-
|
|
3668
|
+
flowBlueprint = JSON.parse(flowBlueprintData);
|
|
3814
3669
|
}
|
|
3815
3670
|
catch (error) {
|
|
3816
|
-
console.error(`Failed to parse flow
|
|
3817
|
-
|
|
3671
|
+
console.error(`Failed to parse flow blueprint JSON for ${id}:`, error);
|
|
3672
|
+
flowBlueprint = flowBlueprintData;
|
|
3818
3673
|
}
|
|
3819
3674
|
}
|
|
3820
3675
|
return {
|
|
3821
3676
|
id,
|
|
3822
|
-
...
|
|
3677
|
+
...flowBlueprint,
|
|
3823
3678
|
};
|
|
3824
3679
|
});
|
|
3825
3680
|
return converted;
|
|
3826
3681
|
}
|
|
3827
3682
|
else {
|
|
3828
|
-
// It's already an array of flow
|
|
3683
|
+
// It's already an array of flow blueprint objects
|
|
3829
3684
|
return config;
|
|
3830
3685
|
}
|
|
3831
3686
|
}
|
|
3832
3687
|
else if (config && typeof config === "object") {
|
|
3833
|
-
// Convert object to array of flow
|
|
3834
|
-
const converted = Object.entries(config).map(([id,
|
|
3835
|
-
let
|
|
3836
|
-
// If the
|
|
3837
|
-
if (typeof
|
|
3688
|
+
// Convert object to array of flow blueprintes
|
|
3689
|
+
const converted = Object.entries(config).map(([id, flowBlueprintData]) => {
|
|
3690
|
+
let flowBlueprint = flowBlueprintData;
|
|
3691
|
+
// If the flowBlueprint is a JSON string, parse it
|
|
3692
|
+
if (typeof flowBlueprintData === "string") {
|
|
3838
3693
|
try {
|
|
3839
|
-
|
|
3694
|
+
flowBlueprint = JSON.parse(flowBlueprintData);
|
|
3840
3695
|
}
|
|
3841
3696
|
catch (error) {
|
|
3842
|
-
console.error(`Failed to parse flow
|
|
3843
|
-
|
|
3697
|
+
console.error(`Failed to parse flow blueprint JSON for ${id}:`, error);
|
|
3698
|
+
flowBlueprint = flowBlueprintData;
|
|
3844
3699
|
}
|
|
3845
3700
|
}
|
|
3846
3701
|
return {
|
|
3847
3702
|
id,
|
|
3848
|
-
...
|
|
3703
|
+
...flowBlueprint,
|
|
3849
3704
|
};
|
|
3850
3705
|
});
|
|
3851
3706
|
return converted;
|
|
@@ -3853,171 +3708,171 @@ const useFlowClasses = () => {
|
|
|
3853
3708
|
return [];
|
|
3854
3709
|
}
|
|
3855
3710
|
catch (error) {
|
|
3856
|
-
console.error("Failed to fetch flow
|
|
3857
|
-
throw new Error("Failed to fetch flow
|
|
3711
|
+
console.error("Failed to fetch flow blueprintes:", error);
|
|
3712
|
+
throw new Error("Failed to fetch flow blueprintes");
|
|
3858
3713
|
}
|
|
3859
3714
|
},
|
|
3860
3715
|
});
|
|
3861
3716
|
// Track loading state
|
|
3862
|
-
useActivity(query.isLoading, "Loading flow
|
|
3717
|
+
useActivity(query.isLoading, "Loading flow blueprintes");
|
|
3863
3718
|
/**
|
|
3864
|
-
* Mutation for creating a new flow
|
|
3719
|
+
* Mutation for creating a new flow blueprint
|
|
3865
3720
|
*/
|
|
3866
3721
|
const createMutation = reactQuery.useMutation({
|
|
3867
|
-
mutationFn: async ({ id,
|
|
3722
|
+
mutationFn: async ({ id, flowBlueprint, }) => {
|
|
3868
3723
|
try {
|
|
3869
3724
|
await socket.config().putConfig([
|
|
3870
3725
|
{
|
|
3871
|
-
type: "flow-
|
|
3726
|
+
type: "flow-blueprints",
|
|
3872
3727
|
key: id,
|
|
3873
|
-
value: JSON.stringify(
|
|
3728
|
+
value: JSON.stringify(flowBlueprint),
|
|
3874
3729
|
},
|
|
3875
3730
|
]);
|
|
3876
3731
|
return {
|
|
3877
3732
|
id,
|
|
3878
|
-
...
|
|
3733
|
+
...flowBlueprint,
|
|
3879
3734
|
};
|
|
3880
3735
|
}
|
|
3881
3736
|
catch (error) {
|
|
3882
|
-
console.error(`Failed to create flow
|
|
3883
|
-
throw new Error(`Failed to create flow
|
|
3737
|
+
console.error(`Failed to create flow blueprint ${id}:`, error);
|
|
3738
|
+
throw new Error(`Failed to create flow blueprint: ${id}`);
|
|
3884
3739
|
}
|
|
3885
3740
|
},
|
|
3886
|
-
onSuccess: (
|
|
3887
|
-
// Invalidate and refetch flow
|
|
3888
|
-
queryClient.invalidateQueries({ queryKey: ["flow-
|
|
3889
|
-
notify.success(`Flow
|
|
3741
|
+
onSuccess: (flowBlueprint) => {
|
|
3742
|
+
// Invalidate and refetch flow blueprintes
|
|
3743
|
+
queryClient.invalidateQueries({ queryKey: ["flow-blueprints"] });
|
|
3744
|
+
notify.success(`Flow blueprint "${flowBlueprint.id}" created successfully`);
|
|
3890
3745
|
},
|
|
3891
3746
|
onError: (error) => {
|
|
3892
|
-
notify.error(`Failed to create flow
|
|
3747
|
+
notify.error(`Failed to create flow blueprint: ${error.message}`);
|
|
3893
3748
|
},
|
|
3894
3749
|
});
|
|
3895
3750
|
/**
|
|
3896
|
-
* Mutation for updating an existing flow
|
|
3751
|
+
* Mutation for updating an existing flow blueprint
|
|
3897
3752
|
*/
|
|
3898
3753
|
const updateMutation = reactQuery.useMutation({
|
|
3899
|
-
mutationFn: async ({ id,
|
|
3754
|
+
mutationFn: async ({ id, flowBlueprint, }) => {
|
|
3900
3755
|
try {
|
|
3901
|
-
// Get current flow
|
|
3756
|
+
// Get current flow blueprint to merge changes
|
|
3902
3757
|
const currentResponse = await socket.config().getConfig([
|
|
3903
3758
|
{
|
|
3904
|
-
type: "flow-
|
|
3759
|
+
type: "flow-blueprints",
|
|
3905
3760
|
key: id,
|
|
3906
3761
|
},
|
|
3907
3762
|
]);
|
|
3908
|
-
const
|
|
3909
|
-
...currentResponse.config["flow-
|
|
3910
|
-
...
|
|
3763
|
+
const updatedFlowBlueprint = {
|
|
3764
|
+
...currentResponse.config["flow-blueprints"][id],
|
|
3765
|
+
...flowBlueprint,
|
|
3911
3766
|
};
|
|
3912
3767
|
await socket.config().putConfig([
|
|
3913
3768
|
{
|
|
3914
|
-
type: "flow-
|
|
3769
|
+
type: "flow-blueprints",
|
|
3915
3770
|
key: id,
|
|
3916
|
-
value: JSON.stringify(
|
|
3771
|
+
value: JSON.stringify(updatedFlowBlueprint),
|
|
3917
3772
|
},
|
|
3918
3773
|
]);
|
|
3919
3774
|
return {
|
|
3920
3775
|
id,
|
|
3921
|
-
...
|
|
3776
|
+
...updatedFlowBlueprint,
|
|
3922
3777
|
};
|
|
3923
3778
|
}
|
|
3924
3779
|
catch (error) {
|
|
3925
|
-
console.error(`Failed to update flow
|
|
3926
|
-
throw new Error(`Failed to update flow
|
|
3780
|
+
console.error(`Failed to update flow blueprint ${id}:`, error);
|
|
3781
|
+
throw new Error(`Failed to update flow blueprint: ${id}`);
|
|
3927
3782
|
}
|
|
3928
3783
|
},
|
|
3929
|
-
onSuccess: (
|
|
3784
|
+
onSuccess: (flowBlueprint) => {
|
|
3930
3785
|
// Update cache
|
|
3931
|
-
queryClient.invalidateQueries({ queryKey: ["flow-
|
|
3932
|
-
notify.success(`Flow
|
|
3786
|
+
queryClient.invalidateQueries({ queryKey: ["flow-blueprints"] });
|
|
3787
|
+
notify.success(`Flow blueprint "${flowBlueprint.id}" updated successfully`);
|
|
3933
3788
|
},
|
|
3934
3789
|
onError: (error) => {
|
|
3935
|
-
notify.error(`Failed to update flow
|
|
3790
|
+
notify.error(`Failed to update flow blueprint: ${error.message}`);
|
|
3936
3791
|
},
|
|
3937
3792
|
});
|
|
3938
3793
|
/**
|
|
3939
|
-
* Mutation for deleting a flow
|
|
3794
|
+
* Mutation for deleting a flow blueprint
|
|
3940
3795
|
*/
|
|
3941
3796
|
const deleteMutation = reactQuery.useMutation({
|
|
3942
3797
|
mutationFn: async (id) => {
|
|
3943
3798
|
try {
|
|
3944
|
-
await socket.flows().
|
|
3799
|
+
await socket.flows().deleteFlowBlueprint(id);
|
|
3945
3800
|
}
|
|
3946
3801
|
catch (error) {
|
|
3947
|
-
console.error(`Failed to delete flow
|
|
3802
|
+
console.error(`Failed to delete flow blueprint ${id}:`, error);
|
|
3948
3803
|
// Re-throw the original error to preserve the API error message
|
|
3949
3804
|
throw error;
|
|
3950
3805
|
}
|
|
3951
3806
|
},
|
|
3952
3807
|
onSuccess: (_, id) => {
|
|
3953
3808
|
// Remove from cache
|
|
3954
|
-
queryClient.invalidateQueries({ queryKey: ["flow-
|
|
3955
|
-
notify.success(`Flow
|
|
3809
|
+
queryClient.invalidateQueries({ queryKey: ["flow-blueprints"] });
|
|
3810
|
+
notify.success(`Flow blueprint "${id}" deleted successfully`);
|
|
3956
3811
|
},
|
|
3957
3812
|
onError: (error) => {
|
|
3958
3813
|
// Show the actual API error message without additional prefixes
|
|
3959
|
-
notify.error(error.message || "Unknown error occurred while deleting flow
|
|
3814
|
+
notify.error(error.message || "Unknown error occurred while deleting flow blueprint");
|
|
3960
3815
|
},
|
|
3961
3816
|
});
|
|
3962
3817
|
/**
|
|
3963
|
-
* Mutation for duplicating a flow
|
|
3818
|
+
* Mutation for duplicating a flow blueprint
|
|
3964
3819
|
*/
|
|
3965
3820
|
const duplicateMutation = reactQuery.useMutation({
|
|
3966
3821
|
mutationFn: async ({ sourceId, targetId, }) => {
|
|
3967
3822
|
try {
|
|
3968
|
-
// Get source flow
|
|
3823
|
+
// Get source flow blueprint
|
|
3969
3824
|
const sourceResponse = await socket.config().getConfig([
|
|
3970
3825
|
{
|
|
3971
|
-
type: "flow-
|
|
3826
|
+
type: "flow-blueprints",
|
|
3972
3827
|
key: sourceId,
|
|
3973
3828
|
},
|
|
3974
3829
|
]);
|
|
3975
|
-
const
|
|
3830
|
+
const sourceFlowBlueprint = sourceResponse.config["flow-blueprints"][sourceId];
|
|
3976
3831
|
// Create duplicate with updated description
|
|
3977
|
-
const
|
|
3978
|
-
...
|
|
3979
|
-
description: `${
|
|
3980
|
-
tags: [...(
|
|
3832
|
+
const duplicatedFlowBlueprint = {
|
|
3833
|
+
...sourceFlowBlueprint,
|
|
3834
|
+
description: `${sourceFlowBlueprint.description || sourceId} (Copy)`,
|
|
3835
|
+
tags: [...(sourceFlowBlueprint.tags || []), "copy"],
|
|
3981
3836
|
};
|
|
3982
|
-
// Save as new flow
|
|
3837
|
+
// Save as new flow blueprint
|
|
3983
3838
|
await socket.config().putConfig([
|
|
3984
3839
|
{
|
|
3985
|
-
type: "flow-
|
|
3840
|
+
type: "flow-blueprints",
|
|
3986
3841
|
key: targetId,
|
|
3987
|
-
value: JSON.stringify(
|
|
3842
|
+
value: JSON.stringify(duplicatedFlowBlueprint),
|
|
3988
3843
|
},
|
|
3989
3844
|
]);
|
|
3990
3845
|
return {
|
|
3991
3846
|
id: targetId,
|
|
3992
|
-
...
|
|
3847
|
+
...duplicatedFlowBlueprint,
|
|
3993
3848
|
};
|
|
3994
3849
|
}
|
|
3995
3850
|
catch (error) {
|
|
3996
|
-
console.error(`Failed to duplicate flow
|
|
3997
|
-
throw new Error(`Failed to duplicate flow
|
|
3851
|
+
console.error(`Failed to duplicate flow blueprint ${sourceId}:`, error);
|
|
3852
|
+
throw new Error(`Failed to duplicate flow blueprint: ${sourceId}`);
|
|
3998
3853
|
}
|
|
3999
3854
|
},
|
|
4000
|
-
onSuccess: (
|
|
4001
|
-
queryClient.invalidateQueries({ queryKey: ["flow-
|
|
4002
|
-
notify.success(`Flow
|
|
3855
|
+
onSuccess: (flowBlueprint) => {
|
|
3856
|
+
queryClient.invalidateQueries({ queryKey: ["flow-blueprints"] });
|
|
3857
|
+
notify.success(`Flow blueprint duplicated as "${flowBlueprint.id}"`);
|
|
4003
3858
|
},
|
|
4004
3859
|
onError: (error) => {
|
|
4005
|
-
notify.error(`Failed to duplicate flow
|
|
3860
|
+
notify.error(`Failed to duplicate flow blueprint: ${error.message}`);
|
|
4006
3861
|
},
|
|
4007
3862
|
});
|
|
4008
3863
|
// Track mutation loading states
|
|
4009
|
-
useActivity(createMutation.isPending, "Creating flow
|
|
4010
|
-
useActivity(updateMutation.isPending, "Updating flow
|
|
4011
|
-
useActivity(deleteMutation.isPending, "Deleting flow
|
|
4012
|
-
useActivity(duplicateMutation.isPending, "Duplicating flow
|
|
3864
|
+
useActivity(createMutation.isPending, "Creating flow blueprint");
|
|
3865
|
+
useActivity(updateMutation.isPending, "Updating flow blueprint");
|
|
3866
|
+
useActivity(deleteMutation.isPending, "Deleting flow blueprint");
|
|
3867
|
+
useActivity(duplicateMutation.isPending, "Duplicating flow blueprint");
|
|
4013
3868
|
return {
|
|
4014
3869
|
// Query state
|
|
4015
|
-
|
|
3870
|
+
flowBlueprints: query.data || [],
|
|
4016
3871
|
isLoading: query.isLoading,
|
|
4017
3872
|
error: query.error,
|
|
4018
3873
|
refetch: query.refetch,
|
|
4019
3874
|
// Utilities
|
|
4020
|
-
|
|
3875
|
+
getFlowBlueprint: (id) => {
|
|
4021
3876
|
const found = query.data?.find((fc) => {
|
|
4022
3877
|
return fc.id === id;
|
|
4023
3878
|
});
|
|
@@ -4027,10 +3882,10 @@ const useFlowClasses = () => {
|
|
|
4027
3882
|
return query.data?.some((fc) => fc.id === id) ?? false;
|
|
4028
3883
|
},
|
|
4029
3884
|
// Mutations
|
|
4030
|
-
|
|
4031
|
-
|
|
4032
|
-
|
|
4033
|
-
|
|
3885
|
+
createFlowBlueprint: createMutation.mutateAsync,
|
|
3886
|
+
updateFlowBlueprint: updateMutation.mutateAsync,
|
|
3887
|
+
deleteFlowBlueprint: deleteMutation.mutateAsync,
|
|
3888
|
+
duplicateFlowBlueprint: duplicateMutation.mutateAsync,
|
|
4034
3889
|
// Mutation states
|
|
4035
3890
|
isCreating: createMutation.isPending,
|
|
4036
3891
|
isUpdating: updateMutation.isPending,
|
|
@@ -4039,9 +3894,9 @@ const useFlowClasses = () => {
|
|
|
4039
3894
|
};
|
|
4040
3895
|
};
|
|
4041
3896
|
/**
|
|
4042
|
-
* Generate a unique flow
|
|
3897
|
+
* Generate a unique flow blueprint ID
|
|
4043
3898
|
*/
|
|
4044
|
-
const
|
|
3899
|
+
const generateFlowBlueprintId = (baseName = "flow-class") => {
|
|
4045
3900
|
const timestamp = Date.now();
|
|
4046
3901
|
const random = Math.random().toString(36).substring(2, 8);
|
|
4047
3902
|
return `${baseName}-${timestamp}-${random}`;
|
|
@@ -4049,29 +3904,29 @@ const generateFlowClassId = (baseName = "flow-class") => {
|
|
|
4049
3904
|
|
|
4050
3905
|
// @ts-nocheck
|
|
4051
3906
|
/**
|
|
4052
|
-
* Custom hook for fetching parameter definitions for a flow
|
|
4053
|
-
* @param
|
|
3907
|
+
* Custom hook for fetching parameter definitions for a flow blueprint
|
|
3908
|
+
* @param flowBlueprintName - The name of the flow blueprint to fetch parameters for
|
|
4054
3909
|
* @returns Parameter definitions, mapping, and loading states
|
|
4055
3910
|
*/
|
|
4056
|
-
const useFlowParameters = (
|
|
3911
|
+
const useFlowParameters = (flowBlueprintName) => {
|
|
4057
3912
|
const socket = reactProvider.useSocket();
|
|
4058
3913
|
const connectionState = reactProvider.useConnectionState();
|
|
4059
3914
|
const isSocketReady = connectionState?.status === "authenticated" ||
|
|
4060
3915
|
connectionState?.status === "unauthenticated";
|
|
4061
3916
|
/**
|
|
4062
|
-
* Query for fetching parameter definitions for a flow
|
|
3917
|
+
* Query for fetching parameter definitions for a flow blueprint
|
|
4063
3918
|
*/
|
|
4064
3919
|
const parametersQuery = reactQuery.useQuery({
|
|
4065
|
-
queryKey: ["flow-parameters",
|
|
4066
|
-
enabled: isSocketReady && !!
|
|
3920
|
+
queryKey: ["flow-parameters", flowBlueprintName],
|
|
3921
|
+
enabled: isSocketReady && !!flowBlueprintName,
|
|
4067
3922
|
queryFn: async () => {
|
|
4068
|
-
if (!
|
|
3923
|
+
if (!flowBlueprintName)
|
|
4069
3924
|
return null;
|
|
4070
3925
|
try {
|
|
4071
|
-
// Get flow
|
|
4072
|
-
const
|
|
3926
|
+
// Get flow blueprint definition first
|
|
3927
|
+
const flowBlueprint = await socket.flows().getFlowBlueprint(flowBlueprintName);
|
|
4073
3928
|
// Extract parameter metadata with new structure
|
|
4074
|
-
const parameterMetadata =
|
|
3929
|
+
const parameterMetadata = flowBlueprint.parameters || {};
|
|
4075
3930
|
if (Object.keys(parameterMetadata).length === 0) {
|
|
4076
3931
|
return {
|
|
4077
3932
|
parameterDefinitions: {},
|
|
@@ -4087,14 +3942,14 @@ const useFlowParameters = (flowClassName) => {
|
|
|
4087
3942
|
// Fetch parameter definitions from config
|
|
4088
3943
|
const definitionNames = Object.values(parameterMapping);
|
|
4089
3944
|
const configKeys = definitionNames.map((name) => ({
|
|
4090
|
-
type: "parameter-
|
|
3945
|
+
type: "parameter-type",
|
|
4091
3946
|
key: name,
|
|
4092
3947
|
}));
|
|
4093
3948
|
const configResponse = await socket.config().getConfig(configKeys);
|
|
4094
3949
|
const parameterDefinitions = {};
|
|
4095
3950
|
// Parse config response to get parameter definitions
|
|
4096
3951
|
configResponse.values?.forEach((item) => {
|
|
4097
|
-
if (item.type === "parameter-
|
|
3952
|
+
if (item.type === "parameter-type") {
|
|
4098
3953
|
try {
|
|
4099
3954
|
parameterDefinitions[item.key] = JSON.parse(item.value);
|
|
4100
3955
|
}
|
|
@@ -4687,7 +4542,7 @@ exports.RDFS_LABEL = RDFS_LABEL;
|
|
|
4687
4542
|
exports.SETTINGS_STORAGE_KEY = SETTINGS_STORAGE_KEY;
|
|
4688
4543
|
exports.createDocId = createDocId;
|
|
4689
4544
|
exports.fileToBase64 = fileToBase64;
|
|
4690
|
-
exports.
|
|
4545
|
+
exports.generateFlowBlueprintId = generateFlowBlueprintId;
|
|
4691
4546
|
exports.getTriples = getTriples;
|
|
4692
4547
|
exports.prepareMetadata = prepareMetadata;
|
|
4693
4548
|
exports.textToBase64 = textToBase64;
|
|
@@ -4699,7 +4554,7 @@ exports.useCollections = useCollections;
|
|
|
4699
4554
|
exports.useConversation = useConversation;
|
|
4700
4555
|
exports.useEmbeddings = useEmbeddings;
|
|
4701
4556
|
exports.useEntityDetail = useEntityDetail;
|
|
4702
|
-
exports.
|
|
4557
|
+
exports.useFlowBlueprints = useFlowBlueprints;
|
|
4703
4558
|
exports.useFlowParameters = useFlowParameters;
|
|
4704
4559
|
exports.useFlows = useFlows;
|
|
4705
4560
|
exports.useGraphEmbeddings = useGraphEmbeddings;
|