Skip to content

Commit 476654a

Browse files
Feature/copilot trigger creation (#274)
* feat: Add Copilot trigger creation support - Add support for One-Time and Recurring triggers in Copilot - Extend CopilotAssistantMessageActionPart schema with trigger config types - Update Copilot instructions with trigger creation examples and guidelines - Implement trigger action handling in messages.tsx component - Add trigger icons (⏰ for one-time, 🔄 for recurring) in action cards - Update workflow reducer to handle trigger creation via existing APIs - Fix action parser to recognize trigger config types in comment format - Add async trigger processing using createScheduledJobRule and createRecurringJobRule APIs Users can now ask Copilot to create triggers with natural language requests like: 'Create a daily report trigger at 9 AM' or 'Set up a one-time reminder for next Friday' * feat: Enhance Copilot message handling and trigger actions - Pass projectId to Messages and AssistantMessage components for better context - Refactor applyAction to handle one-time and recurring triggers with improved error handling - Update handleApplyAll and handleSingleApply to support async action processing - Remove deprecated pending trigger logic from workflow editor This update improves the Copilot's ability to manage triggers and enhances the overall message processing flow. * refactor: route trigger actions via copilot helper Keep workflow reducer synchronous by removing trigger jobs from the switch and moving job rule API calls into a dedicated helper in messages.tsx. Cache dynamic imports and guard types so Copilot Apply/Apply All handle trigger creation without touching reducer state. * feat: Add current time to the copilot context * added conext of triggers to the copilot along with being able to edit and delete triggers * bug fix for deleting composio triggers * Add the edit function that allows editing triggers and lets copilot edit triggers too without losing previous jobs feat: Add update functionality for recurring and scheduled job rules - Implemented update actions for recurring job rules and scheduled job rules, allowing users to modify existing rules with new input and scheduling configurations. - Enhanced the UI components to support editing of job rules, including forms for both creating and updating rules. - Updated the repository interfaces and MongoDB implementations to handle the new update operations for job rules. This update improves the flexibility of managing job rules within the application. * Add trigger context to copilot feat: Enhance trigger management in Copilot - Added functionality to search for relevant external triggers using the new `search_relevant_triggers` tool, allowing users to discover available triggers based on toolkit slugs and optional query keywords. - Updated the Copilot context to include detailed descriptions of various external trigger toolkits, enhancing user guidance for trigger creation. - Improved the overall trigger handling process, ensuring that users can effectively integrate external triggers into their workflows. This update significantly enhances the Copilot's capabilities in managing and utilizing external triggers. * Let copilot add external triggers feat: Enhance external trigger handling in Copilot - Added support for flexible schemas in external triggers, allowing configuration changes without stripping any data. - Introduced a new `onRequestTriggerSetup` callback in the Action component to facilitate trigger setup requests. - Implemented a modal for trigger configuration, improving user experience when setting up external triggers. - Updated the ComposioTriggerTypesPanel to auto-select trigger types based on initial configuration. This update significantly improves the management and setup of external triggers within the Copilot interface. * External trigger cant be edited so we delete and recreate for this feat: Improve external trigger handling in Copilot - Added validation for editing external triggers, ensuring users are informed that existing triggers must be deleted and recreated for changes. - Updated documentation to clarify the limitations of external trigger modifications. This update enhances user experience by providing clear guidance on managing external triggers within the Copilot interface. * preventing message.tsx from ballooning up in size feat: Refactor Copilot message handling and trigger actions - Removed deprecated logic for loading scheduled and recurring job actions, streamlining the trigger action process. - Integrated `useCopilotTriggerActions` hook to manage trigger setup and actions more efficiently. - Enhanced parsing of action parts to improve handling of triggers and their configurations. - Updated the UI to reflect changes in action handling, ensuring a smoother user experience. This update optimizes the Copilot's ability to manage triggers and enhances the overall message processing flow. * refactor: Simplify trigger filtering in Copilot - Removed unnecessary filtering logic for triggers based on user queries, streamlining the search process. - Updated response messages to clarify the context of displayed triggers, enhancing user understanding. This update improves the efficiency of the trigger search functionality within the Copilot interface. * Revert "refactor: Simplify trigger filtering in Copilot" This reverts commit b3d0416. * simplify the filtering logic for triggers in copilot feat: Enhance external trigger creation and search functionality in Copilot - Introduced a critical flow for adding external triggers, emphasizing minimal user input and UI configuration. - Updated documentation to clarify the external trigger creation process and provided examples for better guidance. - Simplified the trigger search logic, ensuring users receive relevant results while maintaining clarity in response messages. This update improves the user experience by streamlining external trigger management and enhancing the search capabilities within the Copilot interface. --------- Co-authored-by: tusharmagar <[email protected]>
1 parent 96fd8b1 commit 476654a

39 files changed

+2779
-487
lines changed

apps/rowboat/app/actions/composio.actions.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ export async function createComposioTriggerDeployment(request: {
157157
export async function listComposioTriggerDeployments(request: {
158158
projectId: string,
159159
cursor?: string,
160+
limit?: number,
160161
}) {
161162
const user = await authCheck();
162163

@@ -166,6 +167,7 @@ export async function listComposioTriggerDeployments(request: {
166167
userId: user.id,
167168
projectId: request.projectId,
168169
cursor: request.cursor,
170+
limit: request.limit,
169171
});
170172
}
171173

@@ -191,4 +193,4 @@ export async function fetchComposioTriggerDeployment(request: { deploymentId: st
191193
userId: user.id,
192194
deploymentId: request.deploymentId,
193195
});
194-
}
196+
}

apps/rowboat/app/actions/copilot.actions.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
CopilotAPIRequest,
44
CopilotChatContext, CopilotMessage,
55
DataSourceSchemaForCopilot,
6+
TriggerSchemaForCopilot,
67
} from "../../src/entities/models/copilot";
78
import {
89
Workflow} from "../lib/types/workflow_types";
@@ -26,7 +27,8 @@ export async function getCopilotResponseStream(
2627
messages: z.infer<typeof CopilotMessage>[],
2728
current_workflow_config: z.infer<typeof Workflow>,
2829
context: z.infer<typeof CopilotChatContext> | null,
29-
dataSources?: z.infer<typeof DataSourceSchemaForCopilot>[]
30+
dataSources?: z.infer<typeof DataSourceSchemaForCopilot>[],
31+
triggers?: z.infer<typeof TriggerSchemaForCopilot>[]
3032
): Promise<{
3133
streamId: string;
3234
} | { billingError: string }> {
@@ -42,6 +44,7 @@ export async function getCopilotResponseStream(
4244
workflow: current_workflow_config,
4345
context,
4446
dataSources,
47+
triggers,
4548
}
4649
});
4750
return {

apps/rowboat/app/actions/recurring-job-rules.actions.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { IListRecurringJobRulesController } from "@/src/interface-adapters/contr
66
import { IFetchRecurringJobRuleController } from "@/src/interface-adapters/controllers/recurring-job-rules/fetch-recurring-job-rule.controller";
77
import { IToggleRecurringJobRuleController } from "@/src/interface-adapters/controllers/recurring-job-rules/toggle-recurring-job-rule.controller";
88
import { IDeleteRecurringJobRuleController } from "@/src/interface-adapters/controllers/recurring-job-rules/delete-recurring-job-rule.controller";
9+
import { IUpdateRecurringJobRuleController } from "@/src/interface-adapters/controllers/recurring-job-rules/update-recurring-job-rule.controller";
910
import { authCheck } from "./auth.actions";
1011
import { z } from "zod";
1112
import { Message } from "@/app/lib/types/types";
@@ -15,6 +16,7 @@ const listRecurringJobRulesController = container.resolve<IListRecurringJobRules
1516
const fetchRecurringJobRuleController = container.resolve<IFetchRecurringJobRuleController>('fetchRecurringJobRuleController');
1617
const toggleRecurringJobRuleController = container.resolve<IToggleRecurringJobRuleController>('toggleRecurringJobRuleController');
1718
const deleteRecurringJobRuleController = container.resolve<IDeleteRecurringJobRuleController>('deleteRecurringJobRuleController');
19+
const updateRecurringJobRuleController = container.resolve<IUpdateRecurringJobRuleController>('updateRecurringJobRuleController');
1820

1921
export async function createRecurringJobRule(request: {
2022
projectId: string,
@@ -89,3 +91,23 @@ export async function deleteRecurringJobRule(request: {
8991
ruleId: request.ruleId,
9092
});
9193
}
94+
95+
export async function updateRecurringJobRule(request: {
96+
projectId: string,
97+
ruleId: string,
98+
input: {
99+
messages: z.infer<typeof Message>[],
100+
},
101+
cron: string,
102+
}) {
103+
const user = await authCheck();
104+
105+
return await updateRecurringJobRuleController.execute({
106+
caller: 'user',
107+
userId: user.id,
108+
projectId: request.projectId,
109+
ruleId: request.ruleId,
110+
input: request.input,
111+
cron: request.cron,
112+
});
113+
}

apps/rowboat/app/actions/scheduled-job-rules.actions.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { ICreateScheduledJobRuleController } from "@/src/interface-adapters/cont
55
import { IListScheduledJobRulesController } from "@/src/interface-adapters/controllers/scheduled-job-rules/list-scheduled-job-rules.controller";
66
import { IFetchScheduledJobRuleController } from "@/src/interface-adapters/controllers/scheduled-job-rules/fetch-scheduled-job-rule.controller";
77
import { IDeleteScheduledJobRuleController } from "@/src/interface-adapters/controllers/scheduled-job-rules/delete-scheduled-job-rule.controller";
8+
import { IUpdateScheduledJobRuleController } from "@/src/interface-adapters/controllers/scheduled-job-rules/update-scheduled-job-rule.controller";
89
import { authCheck } from "./auth.actions";
910
import { z } from "zod";
1011
import { Message } from "@/app/lib/types/types";
@@ -13,6 +14,7 @@ const createScheduledJobRuleController = container.resolve<ICreateScheduledJobRu
1314
const listScheduledJobRulesController = container.resolve<IListScheduledJobRulesController>('listScheduledJobRulesController');
1415
const fetchScheduledJobRuleController = container.resolve<IFetchScheduledJobRuleController>('fetchScheduledJobRuleController');
1516
const deleteScheduledJobRuleController = container.resolve<IDeleteScheduledJobRuleController>('deleteScheduledJobRuleController');
17+
const updateScheduledJobRuleController = container.resolve<IUpdateScheduledJobRuleController>('updateScheduledJobRuleController');
1618

1719
export async function createScheduledJobRule(request: {
1820
projectId: string,
@@ -72,4 +74,24 @@ export async function deleteScheduledJobRule(request: {
7274
projectId: request.projectId,
7375
ruleId: request.ruleId,
7476
});
75-
}
77+
}
78+
79+
export async function updateScheduledJobRule(request: {
80+
projectId: string,
81+
ruleId: string,
82+
input: {
83+
messages: z.infer<typeof Message>[],
84+
},
85+
scheduledTime: string,
86+
}) {
87+
const user = await authCheck();
88+
89+
return await updateScheduledJobRuleController.execute({
90+
caller: 'user',
91+
userId: user.id,
92+
projectId: request.projectId,
93+
ruleId: request.ruleId,
94+
input: request.input,
95+
scheduledTime: request.scheduledTime,
96+
});
97+
}

apps/rowboat/app/lib/client_utils.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { WorkflowTool, WorkflowAgent, WorkflowPrompt, WorkflowPipeline } from "./types/workflow_types";
2+
import { Message } from "./types/types";
23
import { z } from "zod";
34

45
const ZFallbackSchema = z.object({}).passthrough();
@@ -62,6 +63,40 @@ export function validateConfigChanges(configType: string, configChanges: Record<
6263
testObject = {};
6364
break;
6465
}
66+
case 'one_time_trigger': {
67+
testObject = {
68+
scheduledTime: new Date(0).toISOString(),
69+
input: {
70+
messages: [],
71+
},
72+
};
73+
schema = z.object({
74+
scheduledTime: z.string().min(1),
75+
input: z.object({
76+
messages: z.array(Message),
77+
}),
78+
}).passthrough();
79+
break;
80+
}
81+
case 'recurring_trigger': {
82+
testObject = {
83+
cron: '* * * * *',
84+
input: {
85+
messages: [],
86+
},
87+
};
88+
schema = z.object({
89+
cron: z.string().min(1),
90+
input: z.object({
91+
messages: z.array(Message),
92+
}),
93+
}).passthrough();
94+
break;
95+
}
96+
case 'external_trigger': {
97+
// External triggers have flexible schemas per provider; do not strip any config.
98+
return { changes: configChanges };
99+
}
65100
default:
66101
return { error: `Unknown config type: ${configType}` };
67102
}

apps/rowboat/app/projects/[projectId]/copilot/app.tsx

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import { Button } from "@/components/ui/button";
33
import { Dropdown, DropdownItem, DropdownMenu, DropdownSection, DropdownTrigger, Spinner, Tooltip } from "@heroui/react";
44
import { useRef, useState, createContext, useContext, useCallback, forwardRef, useImperativeHandle, useEffect, Ref } from "react";
5-
import { CopilotChatContext } from "../../../../src/entities/models/copilot";
5+
import { CopilotChatContext, TriggerSchemaForCopilot } from "../../../../src/entities/models/copilot";
66
import { CopilotMessage } from "../../../../src/entities/models/copilot";
77
import { Workflow } from "@/app/lib/types/workflow_types";
88
import { DataSource } from "@/src/entities/models/data-source";
@@ -36,6 +36,8 @@ interface AppProps {
3636
onMessagesChange?: (messages: z.infer<typeof CopilotMessage>[]) => void;
3737
isInitialState?: boolean;
3838
dataSources?: z.infer<typeof DataSource>[];
39+
triggers?: z.infer<typeof TriggerSchemaForCopilot>[];
40+
onTriggersUpdated?: () => Promise<void> | void;
3941
}
4042

4143
const App = forwardRef<{ handleCopyChat: () => void; handleUserMessage: (message: string) => void }, AppProps>(function App({
@@ -47,6 +49,8 @@ const App = forwardRef<{ handleCopyChat: () => void; handleUserMessage: (message
4749
onMessagesChange,
4850
isInitialState = false,
4951
dataSources,
52+
triggers,
53+
onTriggersUpdated,
5054
}, ref) {
5155

5256

@@ -85,7 +89,8 @@ const App = forwardRef<{ handleCopyChat: () => void; handleUserMessage: (message
8589
projectId,
8690
workflow: workflowRef.current,
8791
context: effectiveContext,
88-
dataSources: dataSources
92+
dataSources: dataSources,
93+
triggers: triggers
8994
});
9095

9196
// Store latest start/cancel functions in refs
@@ -255,6 +260,7 @@ const App = forwardRef<{ handleCopyChat: () => void; handleUserMessage: (message
255260
</div>
256261
)}
257262
<Messages
263+
projectId={projectId}
258264
messages={messages}
259265
streamingResponse={streamingResponse}
260266
loadingResponse={loadingResponse}
@@ -263,6 +269,8 @@ const App = forwardRef<{ handleCopyChat: () => void; handleUserMessage: (message
263269
onStatusBarChange={handleStatusBarChange}
264270
toolCalling={toolCalling}
265271
toolQuery={toolQuery}
272+
triggers={triggers}
273+
onTriggersUpdated={onTriggersUpdated}
266274
/>
267275
</div>
268276
<div className="shrink-0 px-0 pb-10">
@@ -318,17 +326,21 @@ export const Copilot = forwardRef<{ handleUserMessage: (message: string) => void
318326
dispatch: (action: WorkflowDispatch) => void;
319327
isInitialState?: boolean;
320328
dataSources?: z.infer<typeof DataSource>[];
329+
triggers?: z.infer<typeof TriggerSchemaForCopilot>[];
321330
activePanel?: 'playground' | 'copilot';
322331
onTogglePanel?: () => void;
332+
onTriggersUpdated?: () => Promise<void> | void;
323333
}>(({
324334
projectId,
325335
workflow,
326336
chatContext = undefined,
327337
dispatch,
328338
isInitialState = false,
329339
dataSources,
340+
triggers,
330341
activePanel,
331342
onTogglePanel,
343+
onTriggersUpdated,
332344
}, ref) => {
333345
console.log('🎪 Copilot wrapper component mounted:', {
334346
projectId,
@@ -414,6 +426,8 @@ export const Copilot = forwardRef<{ handleUserMessage: (message: string) => void
414426
onMessagesChange={setMessages}
415427
isInitialState={isInitialState}
416428
dataSources={dataSources}
429+
triggers={triggers}
430+
onTriggersUpdated={onTriggersUpdated}
417431
/>
418432
</div>
419433
</Panel>

0 commit comments

Comments
 (0)