Skip to content

Commit ab27941

Browse files
committed
feat(visualization): better visualization graph
1 parent 57442cd commit ab27941

17 files changed

+121
-97
lines changed

src/__tests__/db-query/unit/connectors/pg.connector.unit.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ describe(`PgConnector Unit`, () => {
2525
expect(ddl).to.be.equal(`-- Model representing an employee in the system.
2626
CREATE TABLE public.employees (
2727
-- Unique identifier for the employee record
28-
id UUID NOT NULL,
28+
id UUID,
2929
-- Name of the employee
3030
name TEXT NOT NULL,
3131
-- Unique code for the employee, used for identification

src/__tests__/db-query/unit/nodes/semantic-validator.node.unit.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ describe('SemanticValidatorNode Unit', function () {
7272
fromCache: false,
7373
resultArray: undefined,
7474
description: undefined,
75+
directCall: false,
7576
};
7677
llmStub.resolves({
7778
content: 'valid',
@@ -110,6 +111,7 @@ describe('SemanticValidatorNode Unit', function () {
110111
sampleSql: '',
111112
fromCache: false,
112113
resultArray: undefined,
114+
directCall: false,
113115
description: undefined,
114116
};
115117
llmStub.resolves({
@@ -193,6 +195,7 @@ valid
193195
sampleSql: '',
194196
fromCache: false,
195197
description: undefined,
198+
directCall: false,
196199
resultArray: undefined,
197200
};
198201
llmStub.resolves({

src/__tests__/db-query/unit/nodes/sql-generation.node.unit.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ describe('SqlGenerationNode Unit', function () {
8787
datasetId: undefined,
8888
fromCache: false,
8989
resultArray: undefined,
90+
directCall: false,
9091
description: undefined,
9192
};
9293

@@ -180,6 +181,7 @@ Do not use any DB concepts like enum numbers, joins, CTEs, subqueries etc. in th
180181
datasetId: undefined,
181182
fromCache: false,
182183
resultArray: undefined,
184+
directCall: false,
183185
description: undefined,
184186
};
185187

@@ -291,6 +293,7 @@ Do not use any DB concepts like enum numbers, joins, CTEs, subqueries etc. in th
291293
datasetId: undefined,
292294
fromCache: false,
293295
resultArray: undefined,
296+
directCall: false,
294297
description: undefined,
295298
};
296299

@@ -402,6 +405,7 @@ Do not use any DB concepts like enum numbers, joins, CTEs, subqueries etc. in th
402405
datasetId: undefined,
403406
fromCache: true,
404407
resultArray: undefined,
408+
directCall: false,
405409
description: undefined,
406410
};
407411

@@ -454,6 +458,7 @@ Do not use any DB concepts like enum numbers, joins, CTEs, subqueries etc. in th
454458
datasetId: undefined,
455459
fromCache: false,
456460
resultArray: undefined,
461+
directCall: false,
457462
description: undefined,
458463
};
459464

src/components/db-query/connectors/pg/pg.connector.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ export class PgConnector implements IDbConnector {
8585
const columnDefinitions = Object.keys(columns).map(columnName => {
8686
const column = columns[columnName];
8787
const dataType = this.mapColumnToDbType(columnName, column);
88-
const notNull = column.required || column.id ? ' NOT NULL' : '';
88+
const notNull = column.required ? ' NOT NULL' : '';
8989
let descriptionString = '';
9090
if (column.description) {
9191
descriptionString = ` -- ${column.description.replace(/'/g, "''")}\n`;

src/components/db-query/nodes/check-cache.node.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -148,15 +148,18 @@ If no queries are relevant, return '${CacheResults.NotRelevant}' and nothing els
148148
return state;
149149
}
150150
const datasetId = relevantDocs[indexNum].metadata.datasetId;
151-
config.writer?.({
152-
type: LLMStreamEventType.ToolStatus,
153-
data: {
154-
status: ToolStatus.Completed,
151+
if (!state.directCall) {
152+
config.writer?.({
153+
type: LLMStreamEventType.ToolStatus,
155154
data: {
156-
datasetId,
155+
status: ToolStatus.Completed,
156+
data: {
157+
datasetId,
158+
},
157159
},
158-
},
159-
});
160+
});
161+
}
162+
160163
return {
161164
...state,
162165
fromCache: true,

src/components/db-query/nodes/save-dataset-node.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -90,15 +90,17 @@ export class SaveDataSetNode implements IGraphNode<DbQueryState> {
9090
votes: 0,
9191
});
9292

93-
config.writer?.({
94-
type: LLMStreamEventType.ToolStatus,
95-
data: {
96-
status: ToolStatus.Completed,
93+
if (!state.directCall) {
94+
config.writer?.({
95+
type: LLMStreamEventType.ToolStatus,
9796
data: {
98-
datasetId: dataset.id,
97+
status: ToolStatus.Completed,
98+
data: {
99+
datasetId: dataset.id,
100+
},
99101
},
100-
},
101-
});
102+
});
103+
}
102104

103105
let result: undefined | AnyObject[] = undefined;
104106
if (this.config.readAccessForAI && dataset.id) {

src/components/db-query/state.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export const DbQueryGraphStateAnnotation = Annotation.Root({
1717
done: Annotation<boolean | undefined>,
1818
resultArray: Annotation<AnyObject[string][] | undefined>,
1919
description: Annotation<string | undefined>,
20+
directCall: Annotation<boolean | undefined>,
2021
});
2122

2223
export type DbQueryState = typeof DbQueryGraphStateAnnotation.State;

src/components/db-query/testing/get-table.node.builder.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export function getTableNodeTests(cases: GetTableNodeTestCase[]) {
2424
fromCache: undefined,
2525
done: false,
2626
resultArray: undefined,
27+
directCall: false,
2728
description: undefined,
2829
},
2930
{

src/components/visualization/nodes.enum.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ export enum VisualizationGraphNodes {
22
GetDatasetData = 'get_dataset_data',
33
SelectVisualisation = 'select_visualization',
44
RenderVisualization = 'render_visualization',
5+
CallQueryGeneration = 'call_query_generation',
56
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import {service} from '@loopback/core';
2+
import {graphNode} from '../../../decorators';
3+
import {IGraphNode, LLMStreamEventType, RunnableConfig} from '../../../graphs';
4+
import {DbQueryGraph, POST_DATASET_TAG} from '../../db-query';
5+
import {VisualizationGraphNodes} from '../nodes.enum';
6+
import {VisualizationGraphState} from '../state';
7+
8+
@graphNode(VisualizationGraphNodes.CallQueryGeneration, {
9+
[POST_DATASET_TAG]: true,
10+
})
11+
export class CallQueryGenerationNode
12+
implements IGraphNode<VisualizationGraphState>
13+
{
14+
constructor(
15+
@service(DbQueryGraph)
16+
private readonly queryPipeline: DbQueryGraph,
17+
) {}
18+
async execute(
19+
state: VisualizationGraphState,
20+
config: RunnableConfig,
21+
): Promise<VisualizationGraphState> {
22+
if (state.datasetId) {
23+
return state;
24+
}
25+
26+
const queryGraph = await this.queryPipeline.build();
27+
28+
const result = await queryGraph.invoke(
29+
{
30+
datasetId: state.datasetId,
31+
directCall: true,
32+
prompt: `Generate a query to fetch data for visualization based on the following user prompt: ${state.prompt}.${state.visualizer?.context ? ` Ensure that the query structure satisfies the following context: ${state.visualizer.context}` : ''}`,
33+
},
34+
config,
35+
);
36+
37+
if (!result.datasetId) {
38+
config.writer?.({
39+
type: LLMStreamEventType.Error,
40+
data: {
41+
status: `Failed to create dataset for visualization: ${result.replyToUser ?? 'Unknown error'}`,
42+
},
43+
});
44+
return {
45+
...state,
46+
error:
47+
result.replyToUser ?? 'Failed to create dataset for visualization',
48+
};
49+
}
50+
51+
return {
52+
...state,
53+
datasetId: result.datasetId,
54+
};
55+
}
56+
}

0 commit comments

Comments
 (0)