mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-05-12 08:42:38 +02:00
allow copilot to delete things, set start agent
This commit is contained in:
parent
d2e590956b
commit
aef3771cd5
5 changed files with 156 additions and 22 deletions
|
|
@ -1,9 +1,11 @@
|
|||
import { WorkflowTool, WorkflowAgent, WorkflowPrompt, WorkflowPipeline } from "./types/workflow_types";
|
||||
import { z } from "zod";
|
||||
|
||||
const ZFallbackSchema = z.object({}).passthrough();
|
||||
|
||||
export function validateConfigChanges(configType: string, configChanges: Record<string, unknown>, name: string) {
|
||||
let testObject: any;
|
||||
let schema: z.ZodType<any>;
|
||||
let schema: z.ZodType<any> = ZFallbackSchema;
|
||||
|
||||
switch (configType) {
|
||||
case 'tool': {
|
||||
|
|
@ -56,6 +58,10 @@ export function validateConfigChanges(configType: string, configChanges: Record<
|
|||
schema = WorkflowPipeline;
|
||||
break;
|
||||
}
|
||||
case 'start_agent': {
|
||||
testObject = {};
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return { error: `Unknown config type: ${configType}` };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,9 +51,12 @@ export function Action({
|
|||
const appliedFields = Object.keys(action.config_changes).filter(key =>
|
||||
appliedChanges[getAppliedChangeKey(msgIndex, actionIndex, key)]
|
||||
);
|
||||
const allApplied = externallyApplied || Object.keys(action.config_changes).every(key =>
|
||||
let allApplied = externallyApplied || Object.keys(action.config_changes).every(key =>
|
||||
appliedFields.includes(key)
|
||||
);
|
||||
if (!externallyApplied && (action.action === "delete" || action.config_type === 'start_agent')) {
|
||||
allApplied = false;
|
||||
}
|
||||
|
||||
// Handle applying a single field change
|
||||
const handleFieldChange = (field: string) => {
|
||||
|
|
@ -160,7 +163,8 @@ export function Action({
|
|||
'transition-shadow duration-150',
|
||||
{
|
||||
'border-l-2 border-l-blue-500': !stale && !allApplied && action.action == 'create_new',
|
||||
'border-l-2 border-l-orange-500': !stale && !allApplied && action.action == 'edit',
|
||||
'border-l-2 border-l-yellow-500': !stale && !allApplied && action.action == 'edit',
|
||||
'border-l-2 border-l-red-500': !stale && !allApplied && action.action == 'delete',
|
||||
'border-l-2 border-l-gray-400': stale || allApplied || action.error,
|
||||
}
|
||||
)}>
|
||||
|
|
@ -171,14 +175,15 @@ export function Action({
|
|||
'inline-flex items-center justify-center rounded-full h-5 w-5 text-xs',
|
||||
{
|
||||
'bg-blue-100 text-blue-600': action.action == 'create_new',
|
||||
'bg-orange-100 text-orange-600': action.action == 'edit',
|
||||
'bg-yellow-100 text-yellow-600': action.action == 'edit',
|
||||
'bg-red-100 text-red-600': action.action == 'delete',
|
||||
'bg-gray-200 text-gray-600': stale || allApplied || action.error,
|
||||
}
|
||||
)}>
|
||||
{action.config_type === 'agent' ? '🧑💼' : action.config_type === 'tool' ? '🛠️' : action.config_type === 'pipeline' ? '⚙️' : '💬'}
|
||||
{action.config_type === 'agent' ? '🧑💼' : action.config_type === 'tool' ? '🛠️' : action.config_type === 'pipeline' ? '⚙️' : action.config_type === 'start_agent' ? '🏁' : action.config_type === 'prompt' ? '💬' : '💬'}
|
||||
</span>
|
||||
<span className="font-semibold text-sm text-zinc-800 dark:text-zinc-100 truncate flex-1">
|
||||
{action.action === 'create_new' ? 'Add' : 'Edit'} {action.config_type}: {action.name}
|
||||
{action.action === 'create_new' ? 'Add' : action.action === 'edit' ? 'Edit' : 'Delete'} {action.config_type}: {action.name}
|
||||
</span>
|
||||
{/* Action buttons - compact, icon only, show text on hover */}
|
||||
<div className="flex items-center gap-1">
|
||||
|
|
@ -195,13 +200,13 @@ export function Action({
|
|||
<CheckIcon size={13} className={allApplied ? 'text-zinc-400' : 'text-green-600 group-hover:text-green-700'} />
|
||||
<span>{allApplied ? 'Applied' : 'Apply'}</span>
|
||||
</button>
|
||||
<button
|
||||
{action.action !== 'delete' && <button
|
||||
className="flex items-center gap-1 rounded-full px-2 h-7 text-xs font-medium bg-transparent text-indigo-600 hover:text-indigo-700 transition-colors"
|
||||
onClick={handleViewDiff}
|
||||
>
|
||||
<EyeIcon size={13} className="text-indigo-600 group-hover:text-indigo-700" />
|
||||
<span>View Diff</span>
|
||||
</button>
|
||||
</button>}
|
||||
</div>
|
||||
</div>
|
||||
{/* Description of what happened */}
|
||||
|
|
@ -341,8 +346,8 @@ export function StreamingAction({
|
|||
loading,
|
||||
}: {
|
||||
action: {
|
||||
action?: 'create_new' | 'edit';
|
||||
config_type?: 'tool' | 'agent' | 'prompt' | 'pipeline';
|
||||
action?: 'create_new' | 'edit' | 'delete';
|
||||
config_type?: 'tool' | 'agent' | 'prompt' | 'pipeline' | 'start_agent';
|
||||
name?: string;
|
||||
};
|
||||
loading: boolean;
|
||||
|
|
@ -354,7 +359,8 @@ export function StreamingAction({
|
|||
'transition-shadow duration-150',
|
||||
{
|
||||
'border-l-2 border-l-blue-500': action.action == 'create_new',
|
||||
'border-l-2 border-l-orange-500': action.action == 'edit',
|
||||
'border-l-2 border-l-yellow-500': action.action == 'edit',
|
||||
'border-l-2 border-l-red-500': action.action == 'delete',
|
||||
'border-l-2 border-l-gray-400': !action.action,
|
||||
}
|
||||
)}>
|
||||
|
|
@ -364,14 +370,15 @@ export function StreamingAction({
|
|||
'inline-flex items-center justify-center rounded-full h-5 w-5 text-xs',
|
||||
{
|
||||
'bg-blue-100 text-blue-600': action.action == 'create_new',
|
||||
'bg-orange-100 text-orange-600': action.action == 'edit',
|
||||
'bg-yellow-100 text-yellow-600': action.action == 'edit',
|
||||
'bg-red-100 text-red-600': action.action == 'delete',
|
||||
'bg-gray-200 text-gray-600': !action.action,
|
||||
}
|
||||
)}>
|
||||
{action.config_type === 'agent' ? '🧑💼' : action.config_type === 'tool' ? '🛠️' : action.config_type === 'pipeline' ? '⚙️' : '💬'}
|
||||
{action.config_type === 'agent' ? '🧑💼' : action.config_type === 'tool' ? '🛠️' : action.config_type === 'pipeline' ? '⚙️' : action.config_type === 'start_agent' ? '🏁' : '💬'}
|
||||
</span>
|
||||
<span className="font-semibold text-sm text-zinc-800 dark:text-zinc-100 truncate flex-1">
|
||||
{action.action === 'create_new' ? 'Add' : 'Edit'} {action.config_type}: {action.name}
|
||||
{action.action === 'create_new' ? 'Add' : action.action === 'edit' ? 'Edit' : 'Delete'} {action.config_type}: {action.name}
|
||||
</span>
|
||||
</div>
|
||||
{/* Loading state body */}
|
||||
|
|
|
|||
|
|
@ -70,8 +70,8 @@ function enrich(response: string): z.infer<typeof CopilotResponsePart> {
|
|||
return {
|
||||
type: 'action',
|
||||
action: {
|
||||
action: metadata.action as 'create_new' | 'edit',
|
||||
config_type: metadata.config_type as 'tool' | 'agent' | 'prompt' | 'pipeline',
|
||||
action: metadata.action as 'create_new' | 'edit' | 'delete',
|
||||
config_type: metadata.config_type as 'tool' | 'agent' | 'prompt' | 'pipeline' | 'start_agent',
|
||||
name: metadata.name,
|
||||
change_description: jsonData.change_description || '',
|
||||
config_changes: {},
|
||||
|
|
@ -83,8 +83,8 @@ function enrich(response: string): z.infer<typeof CopilotResponsePart> {
|
|||
return {
|
||||
type: 'action',
|
||||
action: {
|
||||
action: metadata.action as 'create_new' | 'edit',
|
||||
config_type: metadata.config_type as 'tool' | 'agent' | 'prompt' | 'pipeline',
|
||||
action: metadata.action as 'create_new' | 'edit' | 'delete',
|
||||
config_type: metadata.config_type as 'tool' | 'agent' | 'prompt' | 'pipeline' | 'start_agent',
|
||||
name: metadata.name,
|
||||
change_description: jsonData.change_description || '',
|
||||
config_changes: result.changes
|
||||
|
|
@ -99,8 +99,8 @@ function enrich(response: string): z.infer<typeof CopilotResponsePart> {
|
|||
return {
|
||||
type: 'streaming_action',
|
||||
action: {
|
||||
action: (metadata.action as 'create_new' | 'edit') || undefined,
|
||||
config_type: (metadata.config_type as 'tool' | 'agent' | 'prompt' | 'pipeline') || undefined,
|
||||
action: (metadata.action as 'create_new' | 'edit' | 'delete') || undefined,
|
||||
config_type: (metadata.config_type as 'tool' | 'agent' | 'prompt' | 'pipeline' | 'start_agent') || undefined,
|
||||
name: metadata.name
|
||||
}
|
||||
};
|
||||
|
|
@ -289,6 +289,39 @@ function AssistantMessage({
|
|||
pipeline: action.config_changes
|
||||
});
|
||||
break;
|
||||
case 'start_agent':
|
||||
dispatch({
|
||||
type: 'set_main_agent',
|
||||
name: action.name,
|
||||
})
|
||||
break;
|
||||
}
|
||||
} else if (action.action === 'delete') {
|
||||
switch (action.config_type) {
|
||||
case 'agent':
|
||||
dispatch({
|
||||
type: 'delete_agent',
|
||||
name: action.name
|
||||
});
|
||||
break;
|
||||
case 'tool':
|
||||
dispatch({
|
||||
type: 'delete_tool',
|
||||
name: action.name
|
||||
});
|
||||
break;
|
||||
case 'prompt':
|
||||
dispatch({
|
||||
type: 'delete_prompt',
|
||||
name: action.name
|
||||
});
|
||||
break;
|
||||
case 'pipeline':
|
||||
dispatch({
|
||||
type: 'delete_pipeline',
|
||||
name: action.name
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}, [dispatch, workflow.agents, workflow.tools]);
|
||||
|
|
|
|||
|
|
@ -990,4 +990,92 @@ This workflow is now ready. Once you apply the changes, it will automatically ha
|
|||
|
||||
---
|
||||
|
||||
### Example 7: Setting the start agent
|
||||
|
||||
**User Request**
|
||||
Can you set the start agent to the Meeting Prep Hub?
|
||||
|
||||
**Copilot Response**
|
||||
|
||||
Yes, I can set the start agent to the Meeting Prep Hub.
|
||||
|
||||
\`\`\`copilot_change
|
||||
|
||||
// action: edit
|
||||
// config_type: start_agent
|
||||
// name: Meeting Prep Hub
|
||||
{
|
||||
"change_description": "Set the start agent to the Meeting Prep Hub.",
|
||||
"config_changes": {},
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
|
||||
---
|
||||
|
||||
### Example 8: Delete an agent
|
||||
|
||||
**User Request:**
|
||||
Can you delete the Slack Send Agent?
|
||||
|
||||
**Copilot Response:**
|
||||
|
||||
Yes, I can delete the Slack Send Agent.
|
||||
|
||||
\`\`\`copilot_change
|
||||
// action: delete
|
||||
// config_type: agent
|
||||
// name: Slack Send Agent
|
||||
{
|
||||
"change_description": "Delete the Slack Send Agent.",
|
||||
"config_changes": {},
|
||||
}
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
---
|
||||
|
||||
### Example 9: Delete a tool
|
||||
|
||||
**User Request:**
|
||||
Can you delete the Search tool?
|
||||
|
||||
**Copilot Response:**
|
||||
|
||||
Yes, I can delete the Search tool.
|
||||
|
||||
|
||||
\`\`\`copilot_change
|
||||
// action: delete
|
||||
// config_type: tool
|
||||
// name: Search
|
||||
{
|
||||
"change_description": "Delete the Search tool.",
|
||||
"config_changes": {},
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
---
|
||||
|
||||
### Example 10: Delete a pipeline
|
||||
|
||||
**User Request:**
|
||||
Can you delete the Meeting Prep Pipeline?
|
||||
|
||||
**Copilot Response:**
|
||||
|
||||
Yes, I can delete the Meeting Prep Pipeline.
|
||||
|
||||
\`\`\`copilot_change
|
||||
// action: delete
|
||||
// config_type: pipeline
|
||||
// name: Meeting Prep Pipeline
|
||||
{
|
||||
"change_description": "Delete the Meeting Prep Pipeline.",
|
||||
"config_changes": {},
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
---
|
||||
|
||||
`;
|
||||
|
|
@ -21,8 +21,8 @@ export const CopilotAssistantMessageTextPart = z.object({
|
|||
export const CopilotAssistantMessageActionPart = z.object({
|
||||
type: z.literal("action"),
|
||||
content: z.object({
|
||||
config_type: z.union([z.literal('tool'), z.literal('agent'), z.literal('prompt'), z.literal('pipeline')]),
|
||||
action: z.union([z.literal('create_new'), z.literal('edit')]),
|
||||
config_type: z.enum(['tool', 'agent', 'prompt', 'pipeline', 'start_agent']),
|
||||
action: z.enum(['create_new', 'edit', 'delete']),
|
||||
name: z.string(),
|
||||
change_description: z.string(),
|
||||
config_changes: z.record(z.string(), z.unknown()),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue