-
Notifications
You must be signed in to change notification settings - Fork 117
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
enh: remove viz action and replace by viz content and system prompt #6599
Conversation
f07c50a
to
5baa734
Compare
visualization
token classThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks way better 🔥 , left a few comments. Also I'd challenge the overfit around visualization to accommodate for more usecases like this in the future.
const lastViz = v[v.length - 1]; | ||
if (lastViz) { | ||
return [ | ||
...v.slice(0, v.length - 1), | ||
{ ...lastViz, complete: true }, | ||
]; | ||
} | ||
return v; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const lastViz = v[v.length - 1]; | |
if (lastViz) { | |
return [ | |
...v.slice(0, v.length - 1), | |
{ ...lastViz, complete: true }, | |
]; | |
} | |
return v; | |
v.map((item, index) => | |
index === v.length - 1 ? { ...item, complete: true } : item | |
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fair
@@ -86,7 +77,7 @@ function useVisualizationDataHandler( | |||
if ( | |||
!isVisualizationRPCRequest(data) || | |||
!isOriginatingFromViz || | |||
data.actionId !== action.id | |||
data.index !== visualization.index |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does this work if you have two visualizations displayed on two different messages? We might have to prefix the index with the agent message to not process events multiple times.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right, we should prefix
streamedCode: string | null; | ||
isStreaming: boolean; | ||
visualization: { | ||
visualization: string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we create an interface for this type to avoid duplicating 🙏 ?
className="transition-height relative min-h-96 w-full overflow-hidden duration-500 ease-in-out" | ||
className={classNames( | ||
"transition-height relative w-full overflow-hidden duration-500 ease-in-out", | ||
codeFullyGenerated ? "min-h-96" : "" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIRC changing style like this won't rely on the CSS height animation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't notice a change but maybe you are right, I'm going to check. The main thing is I wanted to avoid the empty white space below the code block at the beginning of the generation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep def makes sense to remove it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the animation still works fine, because the style is applied before the iframe gets rendered, so when it needs to grow / shrink to switch to iframe content, the min-h-96 is already here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🙌
@@ -1502,6 +1504,7 @@ export async function* retryAgentMessage( | |||
actions: [], | |||
content: null, | |||
chainOfThought: null, | |||
visualizations: [], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering whether we should create a more generic solution that can support capabilities beyond just visualization. I don't have specific ideas for other capabilities that might not need a dedicated action implementation right now, but I'm confident we will face this need in the future. Maybe we could have a dedicated table linking an AgentMessageId
with the capability type and its result. WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand the point. For now I feel a bit antsy about creating an abstraction I'm not yet sure we'll really need
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also don't fully understand the separate table thing ? this is all stored in AgentMessageContent
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(which is already a separate table -- we don't store the extracted viz directly)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok I missed the AgentMessageContent
, which is good then wanted to make sure it does not live in the agent_messages
table.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah it's just a field on the agent message type (as in output / API type) for convenience (so consumers of the API don't need to do the content parsing themselves)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's just that boolean values in SQL tables don't scale well, and we don't want to have many columns with this type. Hence, the proposal to simply use an array of strings instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah for the visualizationEnabled
part it's another topic, array of strings could be better. I just wonder if we'll ever need to have other strings in that array. IMO it might be better to keep it as a boolean for now and only migrate to array of strings once we have the use-case for a second boolean
@@ -502,3 +504,80 @@ function getTextContentFromMessage( | |||
}) | |||
.join("\n"); | |||
} | |||
|
|||
async function getVisualizationPrompt({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit
Can we still have a dedicated file for visualization logic?
@@ -0,0 +1,263 @@ | |||
export const visualizationSystemPrompt = ` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔥
@@ -122,6 +123,10 @@ AgentConfiguration.init( | |||
type: DataTypes.INTEGER, | |||
allowNull: true, | |||
}, | |||
visualizationEnabled: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we store an array of string representing capabilities that don't require an action?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah fair 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am worried we're going to end up with an array for only one capability. I think we should wait until we need it before migrating
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright, it's up to you. It seems like it would save time to do it now, but I suppose you'll be the one to run this migration when the time comes 😛.
front/lib/resources/file_resource.ts
Outdated
const owner = auth.workspace(); | ||
if (!owner) { | ||
throw new Error("Unexpected unauthenticated call to `fetchByIds`"); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const owner = auth.workspace(); | |
if (!owner) { | |
throw new Error("Unexpected unauthenticated call to `fetchByIds`"); | |
} | |
const owner = auth.getNonNullableWorkspace(); |
b148629
to
e12e68d
Compare
e12e68d
to
ead44c0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚀
@@ -122,6 +123,10 @@ AgentConfiguration.init( | |||
type: DataTypes.INTEGER, | |||
allowNull: true, | |||
}, | |||
visualizationEnabled: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright, it's up to you. It seems like it would save time to do it now, but I suppose you'll be the one to run this migration when the time comes 😛.
@@ -122,6 +123,10 @@ AgentConfiguration.init( | |||
type: DataTypes.INTEGER, | |||
allowNull: true, | |||
}, | |||
visualizationEnabled: { | |||
type: DataTypes.BOOLEAN, | |||
allowNull: false, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't we need to set the default value here as well? Cause I see in the migration but not here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if we do, in the end it doesn't matter since it's in the migration (it will backfill), but explicit passing still required at typescript level.
But will add it here as well to be safe 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I'm not sure locally people run migrations, so in case they init through Sequelize, let's make sure it works.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed
…6599) * enh: remove viz action and replace by viz content and system prompt * review * review2 --------- Co-authored-by: Henry Fontanier <[email protected]>
Description
The current implementation of visualization uses a dust app which is responsible for generating the code.
The dust app generates event that are interpreted by our frontend.
This approach has some downsides:
This change removes the dust app and the viz action entirely. Instead, viz is now a flag on the agent configuration model. If this flag is true:
<visualization>
tag in the model output. Tokens generated between these tags are classified asvisualization
This also adds a new
visualizations
field on the agent message (so you have the viz already parsed when you come back to a conversation that has viz)The system prompt is now in the codebase. We also inject the list of available files in that prompt (used to be done right before calling the dust app)
Note: I have not done the assistant builder part yet. there's an open question regarding how we expose that (do we masquerade it as a tool ? or have a checkbox somewhere ?)
Risk
Shouldn't impact any prod features. Still there is a DB migration and some changes to the file resource to support batch get (removed a promise.all)
Deploy Plan