Skip to content

Commit

Permalink
enh: use table names in assistant builder (#3286)
Browse files Browse the repository at this point in the history
* use full tables in builder state

* display all datasources even if there is a dsconfig

* move files into the /components

* dont refetch DS

* lint

---------

Co-authored-by: Henry Fontanier <[email protected]>
  • Loading branch information
fontanierh and Henry Fontanier authored Jan 18, 2024
1 parent b458cd5 commit 9f60d6c
Show file tree
Hide file tree
Showing 12 changed files with 279 additions and 220 deletions.
94 changes: 11 additions & 83 deletions front/components/assistant_builder/AssistantBuilder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,14 @@ import {
} from "@app/components/assistant_builder/shared";
import TablesSelectionSection from "@app/components/assistant_builder/TablesSelectionSection";
import { TeamSharingSection } from "@app/components/assistant_builder/TeamSharingSection";
import {
type ActionMode,
ADVANCED_ACTION_MODES,
type AssistantBuilderDataSourceConfiguration,
type AssistantBuilderInitialState,
type AssistantBuilderState,
BASIC_ACTION_MODES,
} from "@app/components/assistant_builder/types";
import DataSourceResourceSelectorTree from "@app/components/DataSourceResourceSelectorTree";
import AppLayout from "@app/components/sparkle/AppLayout";
import {
Expand All @@ -68,6 +76,7 @@ import {
import { subNavigationAssistants } from "@app/components/sparkle/navigation";
import { SendNotificationsContext } from "@app/components/sparkle/Notification";
import { getSupportedModelConfig } from "@app/lib/assistant";
import { tableKey } from "@app/lib/client/tables_query";
import { CONNECTOR_CONFIGURATIONS } from "@app/lib/connector_providers";
import { isActivatedStructuredDB } from "@app/lib/development";
import { isUpgraded } from "@app/lib/plans/plan_codes";
Expand Down Expand Up @@ -98,19 +107,6 @@ const SPIRIT_AVATAR_URLS = SPIRIT_AVATAR_FILES.map((f) =>
buildAvatarUrl(SPIRIT_AVATARS_BASE_PATH, f)
);

// Actions

const BASIC_ACTION_MODES = ["GENERIC", "RETRIEVAL_SEARCH"] as const;
const ADVANCED_ACTION_MODES = [
"RETRIEVAL_EXHAUSTIVE",
"DUST_APP_RUN",
"TABLES_QUERY",
] as const;

type ActionMode =
| (typeof BASIC_ACTION_MODES)[number]
| (typeof ADVANCED_ACTION_MODES)[number];

const ACTION_MODE_TO_LABEL: Record<ActionMode, string> = {
GENERIC: "No action",
RETRIEVAL_SEARCH: "Search in data sources",
Expand All @@ -137,74 +133,6 @@ export const CONNECTOR_PROVIDER_TO_RESOURCE_NAME: Record<
webcrawler: { singular: "page", plural: "pages" },
};

export type AssistantBuilderDataSourceConfiguration = {
dataSource: DataSourceType;
selectedResources: Record<string, string>;
isSelectAll: boolean;
};

// DustAppRun Action

export type AssistantBuilderDustAppConfiguration = {
app: AppType;
};

// Tables Query Action

export type AssistantBuilderTableConfiguration = {
dataSourceId: string;
workspaceId: string;
tableId: string;
};

// Builder State

type AssistantBuilderState = {
actionMode: ActionMode;
dataSourceConfigurations: Record<
string,
AssistantBuilderDataSourceConfiguration
>;
timeFrame: {
value: number;
unit: TimeframeUnit;
};
dustAppConfiguration: AssistantBuilderDustAppConfiguration | null;
tablesQueryConfiguration: Record<string, AssistantBuilderTableConfiguration>;
handle: string | null;
description: string | null;
scope: Exclude<AgentConfigurationScope, "global">;
instructions: string | null;
avatarUrl: string | null;
generationSettings: {
modelSettings: SupportedModel;
temperature: number;
};
};

// initial state is like the state, but:
// - doesn't allow null handle/description/instructions
// - allows null timeFrame
// - allows null dataSourceConfigurations
export type AssistantBuilderInitialState = {
actionMode: AssistantBuilderState["actionMode"];
dataSourceConfigurations:
| AssistantBuilderState["dataSourceConfigurations"]
| null;
timeFrame: AssistantBuilderState["timeFrame"] | null;
dustAppConfiguration: AssistantBuilderState["dustAppConfiguration"];
tablesQueryConfiguration: AssistantBuilderState["tablesQueryConfiguration"];
handle: string;
description: string;
scope: Exclude<AgentConfigurationScope, "global">;
instructions: string;
avatarUrl: string | null;
generationSettings: {
modelSettings: SupportedModel;
temperature: number;
} | null;
};

export const BUILDER_FLOWS = [
"workspace_assistants",
"personal_assistants",
Expand Down Expand Up @@ -732,14 +660,14 @@ export default function AssistantBuilder({
isOpen={showTableModal}
setOpen={(isOpen) => setShowTableModal(isOpen)}
owner={owner}
dataSources={configurableDataSources}
dataSources={dataSources}
onSave={(t) => {
setEdited(true);
setBuilderState((state) => ({
...state,
tablesQueryConfiguration: {
...state.tablesQueryConfiguration,
[`${t.workspaceId}/${t.dataSourceId}/${t.tableId}`]: t,
[tableKey(t)]: t,
},
}));
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import { Transition } from "@headlessui/react";
import * as React from "react";
import { useCallback, useEffect, useState } from "react";

import type { AssistantBuilderDataSourceConfiguration } from "@app/components/assistant_builder/AssistantBuilder";
import { CONNECTOR_PROVIDER_TO_RESOURCE_NAME } from "@app/components/assistant_builder/AssistantBuilder";
import type { AssistantBuilderDataSourceConfiguration } from "@app/components/assistant_builder/types";
import DataSourceResourceSelectorTree from "@app/components/DataSourceResourceSelectorTree";
import { CONNECTOR_CONFIGURATIONS } from "@app/lib/connector_providers";
import type { GetConnectorResourceParentsResponseBody } from "@app/pages/api/w/[wId]/data_sources/[name]/managed/parents";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
import type { AppType } from "@dust-tt/types";
import { Transition } from "@headlessui/react";

import type { AssistantBuilderDustAppConfiguration } from "@app/components/assistant_builder/AssistantBuilder";
import type { AssistantBuilderDustAppConfiguration } from "@app/components/assistant_builder/types";

export default function AssistantBuilderDustAppModal({
isOpen,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { Transition } from "@headlessui/react";
import * as React from "react";
import { useState } from "react";

import type { AssistantBuilderTableConfiguration } from "@app/components/assistant_builder/AssistantBuilder";
import type { AssistantBuilderTableConfiguration } from "@app/components/assistant_builder/types";
import { CONNECTOR_CONFIGURATIONS } from "@app/lib/connector_providers";
import { useTables } from "@app/lib/swr";

Expand Down Expand Up @@ -75,6 +75,7 @@ export default function AssistantBuilderTablesModal({
workspaceId: owner.sId,
dataSourceId: table.data_source_id,
tableId: table.table_id,
tableName: table.name,
};
setSelectedTable(config);
onSave(config);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import {
TrashIcon,
} from "@dust-tt/sparkle";

import type { AssistantBuilderDataSourceConfiguration } from "@app/components/assistant_builder/AssistantBuilder";
import { CONNECTOR_PROVIDER_TO_RESOURCE_NAME } from "@app/components/assistant_builder/shared";
import type { AssistantBuilderDataSourceConfiguration } from "@app/components/assistant_builder/types";
import { EmptyCallToAction } from "@app/components/EmptyCallToAction";
import { CONNECTOR_CONFIGURATIONS } from "@app/lib/connector_providers";
import { getDisplayNameForDataSource } from "@app/lib/data_sources";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
} from "@dust-tt/sparkle";
import { Transition } from "@headlessui/react";

import type { AssistantBuilderDustAppConfiguration } from "@app/components/assistant_builder/AssistantBuilder";
import type { AssistantBuilderDustAppConfiguration } from "@app/components/assistant_builder/types";
import { EmptyCallToAction } from "@app/components/EmptyCallToAction";

export default function DustAppSelectionSection({
Expand Down
11 changes: 6 additions & 5 deletions front/components/assistant_builder/TablesSelectionSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import {
} from "@dust-tt/sparkle";
import { Transition } from "@headlessui/react";

import type { AssistantBuilderTableConfiguration } from "@app/components/assistant_builder/AssistantBuilder";
import type { AssistantBuilderTableConfiguration } from "@app/components/assistant_builder/types";
import { EmptyCallToAction } from "@app/components/EmptyCallToAction";
import { tableKey } from "@app/lib/client/tables_query";

export default function TablesSelectionSection({
show,
Expand Down Expand Up @@ -69,12 +70,12 @@ export default function TablesSelectionSection({
) : (
<ContextItem.List className="mt-6 border-b border-t border-structure-200">
{Object.values(tablesQueryConfiguration).map((t) => {
const tableKey = `${t.workspaceId}/${t.dataSourceId}/${t.tableId}`;
const key = tableKey(t);
return (
<ContextItem
title={t.tableId} // TODO: fetch table name
title={`${t.tableName} (${t.dataSourceId})`}
visual={<ContextItem.Visual visual={ServerIcon} />}
key={tableKey}
key={key}
action={
<Button.List>
<Button
Expand All @@ -83,7 +84,7 @@ export default function TablesSelectionSection({
label="Remove"
labelVisible={false}
onClick={() => {
onDelete?.(tableKey);
onDelete?.(key);
}}
/>
</Button.List>
Expand Down
151 changes: 151 additions & 0 deletions front/components/assistant_builder/server_side_props_helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
import type {
AgentConfigurationType,
AppType,
CoreAPITable,
DataSourceType,
} from "@dust-tt/types";
import {
ConnectorsAPI,
CoreAPI,
isDustAppRunConfiguration,
isRetrievalConfiguration,
isTablesQueryConfiguration,
} from "@dust-tt/types";

import type {
AssistantBuilderDataSourceConfiguration,
AssistantBuilderInitialState,
} from "@app/components/assistant_builder/types";
import { tableKey } from "@app/lib/client/tables_query";
import logger from "@app/logger/logger";

export async function buildInitialState({
dataSourceByName,
config,
dustApps,
}: {
dataSourceByName: Record<string, DataSourceType>;
config: AgentConfigurationType;
dustApps: AppType[];
}) {
const coreAPI = new CoreAPI(logger);

const selectedResources: {
dataSourceName: string;
resources: string[] | null;
isSelectAll: boolean;
}[] = [];

if (isRetrievalConfiguration(config.action)) {
for (const ds of config.action.dataSources) {
selectedResources.push({
dataSourceName: ds.dataSourceId,
resources: ds.filter.parents?.in ?? null,
isSelectAll: !ds.filter.parents,
});
}
}

const dataSourceConfigurationsArray: NonNullable<
AssistantBuilderInitialState["dataSourceConfigurations"]
>[string][] = await Promise.all(
selectedResources.map(
async (ds): Promise<AssistantBuilderDataSourceConfiguration> => {
const dataSource = dataSourceByName[ds.dataSourceName];
if (!dataSource.connectorId || !ds.resources) {
return {
dataSource: dataSource,
selectedResources: {},
isSelectAll: ds.isSelectAll,
};
}
const connectorsAPI = new ConnectorsAPI(logger);
const response = await connectorsAPI.getResourcesTitles({
connectorId: dataSource.connectorId,
resourceInternalIds: ds.resources,
});

if (response.isErr()) {
throw response.error;
}

// key: interalId, value: title
const selectedResources: Record<string, string> = {};
for (const resource of response.value.resources) {
selectedResources[resource.internalId] = resource.title;
}

return {
dataSource: dataSource,
selectedResources,
isSelectAll: ds.isSelectAll,
};
}
)
);

// key: dataSourceName, value: DataSourceConfig
const dataSourceConfigurations = dataSourceConfigurationsArray.reduce(
(acc, curr) => ({ ...acc, [curr.dataSource.name]: curr }),
{} as Record<string, AssistantBuilderDataSourceConfiguration>
);

let dustAppConfiguration: AssistantBuilderInitialState["dustAppConfiguration"] =
null;

if (isDustAppRunConfiguration(config.action)) {
for (const app of dustApps) {
if (app.sId === config.action.appId) {
dustAppConfiguration = {
app,
};
break;
}
}
}

let tablesQueryConfiguration: AssistantBuilderInitialState["tablesQueryConfiguration"] =
{};

if (
isTablesQueryConfiguration(config.action) &&
config.action.tables.length
) {
const coreAPITables: CoreAPITable[] = await Promise.all(
config.action.tables.map(async (t) => {
const dataSource = dataSourceByName[t.dataSourceId];
const coreAPITable = await coreAPI.getTable({
projectId: dataSource.dustAPIProjectId,
dataSourceName: dataSource.name,
tableId: t.tableId,
});

if (coreAPITable.isErr()) {
throw coreAPITable.error;
}

return coreAPITable.value.table;
})
);

tablesQueryConfiguration = config.action.tables.reduce((acc, curr, i) => {
const table = coreAPITables[i];
const key = tableKey(curr);
return {
...acc,
[key]: {
workspaceId: curr.workspaceId,
dataSourceId: curr.dataSourceId,
tableId: curr.tableId,
tableName: `${table.name}`,
},
};
}, {} as AssistantBuilderInitialState["tablesQueryConfiguration"]);
}

return {
dataSourceConfigurations,
dustAppConfiguration,
tablesQueryConfiguration,
};
}
Loading

0 comments on commit 9f60d6c

Please sign in to comment.