From 41c9b1547c2e348fd6c5b46e8413c37ac77db3dd Mon Sep 17 00:00:00 2001 From: shivammittal274 <56757235+shivammittal274@users.noreply.github.com> Date: Mon, 16 Mar 2026 18:03:21 +0530 Subject: [PATCH] feat: add per-task LLM provider selection for scheduled tasks (#450) * feat: add per-task LLM provider selection for scheduled tasks Allow users to choose which AI provider a scheduled task runs with, using the same ChatProviderSelector component from the new-tab page. Falls back to the global default provider when none is selected or if the selected provider has been deleted. * fix: lint issues * chore: updated to latest schema.graphql file --------- Co-authored-by: Dani Akash --- .../NewScheduledTaskDialog.tsx | 88 +- .../app/scheduled-tasks/ScheduledTaskCard.tsx | 34 +- .../background/scheduledJobRuns.ts | 1 + .../sidepanel/index/useChatSession.ts | 3 +- .../lib/llm-providers/useLlmProviders.ts | 4 +- .../lib/schedules/getChatServerResponse.ts | 15 +- .../graphql/syncSchedulesDocument.ts | 1 + .../apps/agent/lib/schedules/scheduleTypes.ts | 1 + .../lib/schedules/syncSchedulesToBackend.ts | 6 + .../apps/agent/schema/schema.graphql | 960 ++++++++++++++++++ 10 files changed, 1106 insertions(+), 7 deletions(-) diff --git a/packages/browseros-agent/apps/agent/entrypoints/app/scheduled-tasks/NewScheduledTaskDialog.tsx b/packages/browseros-agent/apps/agent/entrypoints/app/scheduled-tasks/NewScheduledTaskDialog.tsx index 9a80b9f08..e6fe67cb1 100644 --- a/packages/browseros-agent/apps/agent/entrypoints/app/scheduled-tasks/NewScheduledTaskDialog.tsx +++ b/packages/browseros-agent/apps/agent/entrypoints/app/scheduled-tasks/NewScheduledTaskDialog.tsx @@ -1,8 +1,11 @@ import { zodResolver } from '@hookform/resolvers/zod' +import { ChevronDown } from 'lucide-react' import type { FC } from 'react' -import { useEffect } from 'react' +import { useEffect, useState } from 'react' import { useForm } from 'react-hook-form' import { z } from 'zod/v3' +import { ChatProviderSelector } from '@/components/chat/ChatProviderSelector' +import type { Provider } from '@/components/chat/chatComponentTypes' import { Button } from '@/components/ui/button' import { Checkbox } from '@/components/ui/checkbox' import { @@ -31,6 +34,12 @@ import { SelectValue, } from '@/components/ui/select' import { Textarea } from '@/components/ui/textarea' +import { BrowserOSIcon, ProviderIcon } from '@/lib/llm-providers/providerIcons' +import { + defaultProviderIdStorage, + providersStorage, +} from '@/lib/llm-providers/storage' +import type { LlmProviderConfig, ProviderType } from '@/lib/llm-providers/types' import type { ScheduledJob } from './types' const formSchema = z @@ -43,6 +52,7 @@ const formSchema = z scheduleType: z.enum(['daily', 'hourly', 'minutes']), scheduleTime: z.string().optional(), scheduleInterval: z.number().int().min(1).max(60).optional(), + providerId: z.string().optional(), enabled: z.boolean(), }) .superRefine((data, ctx) => { @@ -81,6 +91,8 @@ export const NewScheduledTaskDialog: FC = ({ onSave, }) => { const isEditing = !!initialValues + const [providers, setProviders] = useState([]) + const [defaultProviderId, setDefaultProviderId] = useState('') const form = useForm({ resolver: zodResolver(formSchema), @@ -90,11 +102,25 @@ export const NewScheduledTaskDialog: FC = ({ scheduleType: 'daily', scheduleTime: '09:00', scheduleInterval: 1, + providerId: undefined, enabled: true, }, }) const scheduleType = form.watch('scheduleType') + const selectedProviderId = form.watch('providerId') + + // Load providers from storage + useEffect(() => { + if (!open) return + Promise.all([ + providersStorage.getValue(), + defaultProviderIdStorage.getValue(), + ]).then(([providerList, defId]) => { + setProviders(providerList ?? []) + setDefaultProviderId(defId ?? '') + }) + }, [open]) useEffect(() => { if (open) { @@ -105,6 +131,7 @@ export const NewScheduledTaskDialog: FC = ({ scheduleType: initialValues.scheduleType, scheduleTime: initialValues.scheduleTime || '09:00', scheduleInterval: initialValues.scheduleInterval || 1, + providerId: initialValues.providerId, enabled: initialValues.enabled, }) } else { @@ -114,12 +141,33 @@ export const NewScheduledTaskDialog: FC = ({ scheduleType: 'daily', scheduleTime: '09:00', scheduleInterval: 1, + providerId: undefined, enabled: true, }) } } }, [open, initialValues, form]) + // Resolve the currently selected provider for the selector display + const resolvedProvider: Provider | null = (() => { + const id = selectedProviderId ?? defaultProviderId + const found = providers.find((p) => p.id === id) + if (found) return { id: found.id, name: found.name, type: found.type } + if (providers[0]) + return { + id: providers[0].id, + name: providers[0].name, + type: providers[0].type, + } + return null + })() + + const providerOptions: Provider[] = providers.map((p) => ({ + id: p.id, + name: p.name, + type: p.type, + })) + const onSubmit = (values: FormValues) => { onSave({ name: values.name.trim(), @@ -129,6 +177,7 @@ export const NewScheduledTaskDialog: FC = ({ values.scheduleType === 'daily' ? values.scheduleTime : undefined, scheduleInterval: values.scheduleType !== 'daily' ? values.scheduleInterval : undefined, + providerId: values.providerId, enabled: values.enabled, }) form.reset() @@ -185,6 +234,43 @@ export const NewScheduledTaskDialog: FC = ({ )} /> + {providers.length > 0 && resolvedProvider && ( + + AI Provider + + form.setValue('providerId', provider.id) + } + > + + + + The AI provider used to run this task + + + )} +
= ({ onRetryRun, }) => { const [isOpen, setIsOpen] = useState(false) + const [providerInfo, setProviderInfo] = useState<{ + name: string + type: ProviderType + } | null>(null) const { jobRuns } = useScheduledJobRuns() + // Load provider info for display + useEffect(() => { + if (!job.providerId) { + setProviderInfo(null) + return + } + providersStorage.getValue().then((providers) => { + const match = providers?.find((p) => p.id === job.providerId) + setProviderInfo(match ? { name: match.name, type: match.type } : null) + }) + }, [job.providerId]) + const runs = useMemo( () => jobRuns @@ -117,6 +136,19 @@ export const ScheduledTaskCard: FC = ({

{formatSchedule(job)} + {providerInfo && ( + <> + + + {providerInfo.type === 'browseros' ? ( + + ) : ( + + )} + {providerInfo.name} + + + )} {job.lastRunAt && ( <> diff --git a/packages/browseros-agent/apps/agent/entrypoints/background/scheduledJobRuns.ts b/packages/browseros-agent/apps/agent/entrypoints/background/scheduledJobRuns.ts index 0257048bb..7fc8cf45f 100644 --- a/packages/browseros-agent/apps/agent/entrypoints/background/scheduledJobRuns.ts +++ b/packages/browseros-agent/apps/agent/entrypoints/background/scheduledJobRuns.ts @@ -117,6 +117,7 @@ export const scheduledJobRuns = async () => { const response = await getChatServerResponse({ message: job.query, signal: abortController.signal, + providerId: job.providerId, }) await updateJobRun(jobRun.id, { diff --git a/packages/browseros-agent/apps/agent/entrypoints/sidepanel/index/useChatSession.ts b/packages/browseros-agent/apps/agent/entrypoints/sidepanel/index/useChatSession.ts index 3c0a502bf..f8eb9697c 100644 --- a/packages/browseros-agent/apps/agent/entrypoints/sidepanel/index/useChatSession.ts +++ b/packages/browseros-agent/apps/agent/entrypoints/sidepanel/index/useChatSession.ts @@ -209,7 +209,8 @@ export const useChatSession = (options?: ChatSessionOptions) => { }) const activeTab = activeTabsList?.[0] ?? undefined const message = getLastMessageText(messages) - const provider = selectedLlmProviderRef.current ?? createDefaultBrowserOSProvider() + const provider = + selectedLlmProviderRef.current ?? createDefaultBrowserOSProvider() const currentMode = modeRef.current const enabledMcpServers = enabledMcpServersRef.current const customMcpServers = enabledCustomServersRef.current diff --git a/packages/browseros-agent/apps/agent/lib/llm-providers/useLlmProviders.ts b/packages/browseros-agent/apps/agent/lib/llm-providers/useLlmProviders.ts index 905094f45..8834a32fa 100644 --- a/packages/browseros-agent/apps/agent/lib/llm-providers/useLlmProviders.ts +++ b/packages/browseros-agent/apps/agent/lib/llm-providers/useLlmProviders.ts @@ -158,9 +158,7 @@ export function useLlmProviders(): UseLlmProvidersReturn { // Fall back to first provider if defaultProviderId is stale/invalid const selectedProvider = useMemo( () => - providers.find((p) => p.id === defaultProviderId) ?? - providers[0] ?? - null, + providers.find((p) => p.id === defaultProviderId) ?? providers[0] ?? null, [providers, defaultProviderId], ) diff --git a/packages/browseros-agent/apps/agent/lib/schedules/getChatServerResponse.ts b/packages/browseros-agent/apps/agent/lib/schedules/getChatServerResponse.ts index 64ff28961..8883dccbf 100644 --- a/packages/browseros-agent/apps/agent/lib/schedules/getChatServerResponse.ts +++ b/packages/browseros-agent/apps/agent/lib/schedules/getChatServerResponse.ts @@ -25,6 +25,7 @@ interface ChatServerRequest { windowId?: number activeTab?: ActiveTab signal?: AbortSignal + providerId?: string } interface ChatServerResponse { @@ -75,11 +76,23 @@ const getDefaultProvider = async (): Promise => { return defaultProvider ?? providers[0] ?? null } +// Resolve provider by ID, falling back to global default +const resolveProvider = async ( + providerId?: string, +): Promise => { + if (providerId) { + const providers = await providersStorage.getValue() + const match = providers?.find((p) => p.id === providerId) + if (match) return match + } + return (await getDefaultProvider()) ?? createDefaultBrowserOSProvider() +} + export async function getChatServerResponse( request: ChatServerRequest, ): Promise { const agentServerUrl = await getAgentServerUrl() - const provider = (await getDefaultProvider()) ?? createDefaultBrowserOSProvider() + const provider = await resolveProvider(request.providerId) const conversationId = request.conversationId ?? crypto.randomUUID() const personalization = await personalizationStorage.getValue() diff --git a/packages/browseros-agent/apps/agent/lib/schedules/graphql/syncSchedulesDocument.ts b/packages/browseros-agent/apps/agent/lib/schedules/graphql/syncSchedulesDocument.ts index 66f56065f..2cb8254d2 100644 --- a/packages/browseros-agent/apps/agent/lib/schedules/graphql/syncSchedulesDocument.ts +++ b/packages/browseros-agent/apps/agent/lib/schedules/graphql/syncSchedulesDocument.ts @@ -11,6 +11,7 @@ export const GetScheduledJobsByProfileIdDocument = graphql(` scheduleTime scheduleInterval enabled + llmProviderId createdAt updatedAt lastRunAt diff --git a/packages/browseros-agent/apps/agent/lib/schedules/scheduleTypes.ts b/packages/browseros-agent/apps/agent/lib/schedules/scheduleTypes.ts index 18924e640..54b139d47 100644 --- a/packages/browseros-agent/apps/agent/lib/schedules/scheduleTypes.ts +++ b/packages/browseros-agent/apps/agent/lib/schedules/scheduleTypes.ts @@ -6,6 +6,7 @@ export interface ScheduledJob { scheduleTime?: string scheduleInterval?: number enabled: boolean + providerId?: string createdAt: string updatedAt: string lastRunAt?: string diff --git a/packages/browseros-agent/apps/agent/lib/schedules/syncSchedulesToBackend.ts b/packages/browseros-agent/apps/agent/lib/schedules/syncSchedulesToBackend.ts index 68aade358..41e7dede5 100644 --- a/packages/browseros-agent/apps/agent/lib/schedules/syncSchedulesToBackend.ts +++ b/packages/browseros-agent/apps/agent/lib/schedules/syncSchedulesToBackend.ts @@ -19,6 +19,7 @@ type RemoteScheduledJob = { scheduleTime: string | null scheduleInterval: number | null enabled: boolean + llmProviderId: string | null createdAt: string updatedAt: string lastRunAt: string | null @@ -32,6 +33,7 @@ function toComparable(job: ScheduledJob) { ...data, scheduleTime: data.scheduleTime ?? null, scheduleInterval: data.scheduleInterval ?? null, + providerId: data.providerId ?? null, } } @@ -43,6 +45,7 @@ function remoteToComparable(job: RemoteScheduledJob) { scheduleTime: job.scheduleTime, scheduleInterval: job.scheduleInterval, enabled: job.enabled, + providerId: job.llmProviderId, } } @@ -59,6 +62,7 @@ function remoteToLocal(remote: RemoteScheduledJob): ScheduledJob { scheduleTime: remote.scheduleTime ?? undefined, scheduleInterval: remote.scheduleInterval ?? undefined, enabled: remote.enabled, + providerId: remote.llmProviderId ?? undefined, createdAt: normalizeTimestamp(remote.createdAt), updatedAt: normalizeTimestamp(remote.updatedAt), lastRunAt: remote.lastRunAt @@ -163,6 +167,7 @@ export async function syncSchedulesToBackend( scheduleTime: job.scheduleTime ?? null, scheduleInterval: job.scheduleInterval ?? null, enabled: job.enabled, + llmProviderId: job.providerId ?? null, lastRunAt: job.lastRunAt ? new Date(job.lastRunAt).toISOString() : null, @@ -182,6 +187,7 @@ export async function syncSchedulesToBackend( scheduleTime: job.scheduleTime ?? null, scheduleInterval: job.scheduleInterval ?? null, enabled: job.enabled, + llmProviderId: job.providerId ?? null, createdAt: new Date(job.createdAt).toISOString(), updatedAt: job.updatedAt || new Date().toISOString(), lastRunAt: job.lastRunAt diff --git a/packages/browseros-agent/apps/agent/schema/schema.graphql b/packages/browseros-agent/apps/agent/schema/schema.graphql index 48789d628..3d93d5918 100644 --- a/packages/browseros-agent/apps/agent/schema/schema.graphql +++ b/packages/browseros-agent/apps/agent/schema/schema.graphql @@ -253,6 +253,17 @@ enum ConversationMessageOrderBy { ROW_ID_DESC } +""" +Represents an update to a `ConversationMessage`. Fields that are set will be updated. +""" +input ConversationMessagePatch { + conversationId: String + createdAt: Datetime + message: JSON + orderIndex: Int + rowId: String +} + """ Methods to use when ordering `Conversation`. """ @@ -407,6 +418,49 @@ type CreateLlmProviderPayload { query: Query } +""" +All input for the create `Profile` mutation. +""" +input CreateProfileInput { + """ + An arbitrary string value with no semantic meaning. Will be included in the + payload verbatim. May be used to track mutations by the client. + """ + clientMutationId: String + """ + The `Profile` to be created by this mutation. + """ + profile: ProfileInput! +} + +""" +The output of our create `Profile` mutation. +""" +type CreateProfilePayload { + """ + The exact same `clientMutationId` that was provided in the mutation input, + unchanged and unused. May be used by a client to track mutations. + """ + clientMutationId: String + """ + The `Profile` that was created by this mutation. + """ + profile: Profile + """ + An edge for our `Profile`. May be used by Relay 1. + """ + profileEdge( + """ + The method to use when ordering `Profile`. + """ + orderBy: [ProfileOrderBy!]! = [PRIMARY_KEY_ASC] + ): ProfileEdge + """ + Our root query field type. Allows us to run any query from our mutation payload. + """ + query: Query +} + """ All input for the create `ScheduledJob` mutation. """ @@ -450,6 +504,49 @@ type CreateScheduledJobPayload { ): ScheduledJobEdge } +""" +All input for the create `ScheduledJobRun` mutation. +""" +input CreateScheduledJobRunInput { + """ + An arbitrary string value with no semantic meaning. Will be included in the + payload verbatim. May be used to track mutations by the client. + """ + clientMutationId: String + """ + The `ScheduledJobRun` to be created by this mutation. + """ + scheduledJobRun: ScheduledJobRunInput! +} + +""" +The output of our create `ScheduledJobRun` mutation. +""" +type CreateScheduledJobRunPayload { + """ + The exact same `clientMutationId` that was provided in the mutation input, + unchanged and unused. May be used by a client to track mutations. + """ + clientMutationId: String + """ + Our root query field type. Allows us to run any query from our mutation payload. + """ + query: Query + """ + The `ScheduledJobRun` that was created by this mutation. + """ + scheduledJobRun: ScheduledJobRun + """ + An edge for our `ScheduledJobRun`. May be used by Relay 1. + """ + scheduledJobRunEdge( + """ + The method to use when ordering `ScheduledJobRun`. + """ + orderBy: [ScheduledJobRunOrderBy!]! = [PRIMARY_KEY_ASC] + ): ScheduledJobRunEdge +} + """ A location in a connection that can be used for resuming pagination. """ @@ -464,6 +561,21 @@ to unexpected results. """ scalar Datetime +""" +All input for the `deleteConversationById` mutation. +""" +input DeleteConversationByIdInput { + """ + An arbitrary string value with no semantic meaning. Will be included in the + payload verbatim. May be used to track mutations by the client. + """ + clientMutationId: String + """ + The globally unique `ID` which will identify a single `Conversation` to be deleted. + """ + id: ID! +} + """ All input for the `deleteConversation` mutation. """ @@ -476,6 +588,62 @@ input DeleteConversationInput { rowId: String! } +""" +All input for the `deleteConversationMessageById` mutation. +""" +input DeleteConversationMessageByIdInput { + """ + An arbitrary string value with no semantic meaning. Will be included in the + payload verbatim. May be used to track mutations by the client. + """ + clientMutationId: String + """ + The globally unique `ID` which will identify a single `ConversationMessage` to be deleted. + """ + id: ID! +} + +""" +All input for the `deleteConversationMessage` mutation. +""" +input DeleteConversationMessageInput { + """ + An arbitrary string value with no semantic meaning. Will be included in the + payload verbatim. May be used to track mutations by the client. + """ + clientMutationId: String + rowId: String! +} + +""" +The output of our delete `ConversationMessage` mutation. +""" +type DeleteConversationMessagePayload { + """ + The exact same `clientMutationId` that was provided in the mutation input, + unchanged and unused. May be used by a client to track mutations. + """ + clientMutationId: String + """ + The `ConversationMessage` that was deleted by this mutation. + """ + conversationMessage: ConversationMessage + """ + An edge for our `ConversationMessage`. May be used by Relay 1. + """ + conversationMessageEdge( + """ + The method to use when ordering `ConversationMessage`. + """ + orderBy: [ConversationMessageOrderBy!]! = [PRIMARY_KEY_ASC] + ): ConversationMessageEdge + deletedConversationMessageId: ID + """ + Our root query field type. Allows us to run any query from our mutation payload. + """ + query: Query +} + """ The output of our delete `Conversation` mutation. """ @@ -505,6 +673,21 @@ type DeleteConversationPayload { query: Query } +""" +All input for the `deleteLlmProviderById` mutation. +""" +input DeleteLlmProviderByIdInput { + """ + An arbitrary string value with no semantic meaning. Will be included in the + payload verbatim. May be used to track mutations by the client. + """ + clientMutationId: String + """ + The globally unique `ID` which will identify a single `LlmProvider` to be deleted. + """ + id: ID! +} + """ All input for the `deleteLlmProvider` mutation. """ @@ -546,6 +729,89 @@ type DeleteLlmProviderPayload { query: Query } +""" +All input for the `deleteProfileById` mutation. +""" +input DeleteProfileByIdInput { + """ + An arbitrary string value with no semantic meaning. Will be included in the + payload verbatim. May be used to track mutations by the client. + """ + clientMutationId: String + """ + The globally unique `ID` which will identify a single `Profile` to be deleted. + """ + id: ID! +} + +""" +All input for the `deleteProfileByUserId` mutation. +""" +input DeleteProfileByUserIdInput { + """ + An arbitrary string value with no semantic meaning. Will be included in the + payload verbatim. May be used to track mutations by the client. + """ + clientMutationId: String + userId: String! +} + +""" +All input for the `deleteProfile` mutation. +""" +input DeleteProfileInput { + """ + An arbitrary string value with no semantic meaning. Will be included in the + payload verbatim. May be used to track mutations by the client. + """ + clientMutationId: String + rowId: String! +} + +""" +The output of our delete `Profile` mutation. +""" +type DeleteProfilePayload { + """ + The exact same `clientMutationId` that was provided in the mutation input, + unchanged and unused. May be used by a client to track mutations. + """ + clientMutationId: String + deletedProfileId: ID + """ + The `Profile` that was deleted by this mutation. + """ + profile: Profile + """ + An edge for our `Profile`. May be used by Relay 1. + """ + profileEdge( + """ + The method to use when ordering `Profile`. + """ + orderBy: [ProfileOrderBy!]! = [PRIMARY_KEY_ASC] + ): ProfileEdge + """ + Our root query field type. Allows us to run any query from our mutation payload. + """ + query: Query +} + +""" +All input for the `deleteScheduledJobById` mutation. +""" +input DeleteScheduledJobByIdInput { + """ + An arbitrary string value with no semantic meaning. Will be included in the + payload verbatim. May be used to track mutations by the client. + """ + clientMutationId: String + """ + The globally unique `ID` which will identify a single `ScheduledJob` to be deleted. + """ + id: ID! +} + """ All input for the `deleteScheduledJob` mutation. """ @@ -587,6 +853,62 @@ type DeleteScheduledJobPayload { ): ScheduledJobEdge } +""" +All input for the `deleteScheduledJobRunById` mutation. +""" +input DeleteScheduledJobRunByIdInput { + """ + An arbitrary string value with no semantic meaning. Will be included in the + payload verbatim. May be used to track mutations by the client. + """ + clientMutationId: String + """ + The globally unique `ID` which will identify a single `ScheduledJobRun` to be deleted. + """ + id: ID! +} + +""" +All input for the `deleteScheduledJobRun` mutation. +""" +input DeleteScheduledJobRunInput { + """ + An arbitrary string value with no semantic meaning. Will be included in the + payload verbatim. May be used to track mutations by the client. + """ + clientMutationId: String + rowId: String! +} + +""" +The output of our delete `ScheduledJobRun` mutation. +""" +type DeleteScheduledJobRunPayload { + """ + The exact same `clientMutationId` that was provided in the mutation input, + unchanged and unused. May be used by a client to track mutations. + """ + clientMutationId: String + deletedScheduledJobRunId: ID + """ + Our root query field type. Allows us to run any query from our mutation payload. + """ + query: Query + """ + The `ScheduledJobRun` that was deleted by this mutation. + """ + scheduledJobRun: ScheduledJobRun + """ + An edge for our `ScheduledJobRun`. May be used by Relay 1. + """ + scheduledJobRunEdge( + """ + The method to use when ordering `ScheduledJobRun`. + """ + orderBy: [ScheduledJobRunOrderBy!]! = [PRIMARY_KEY_ASC] + ): ScheduledJobRunEdge +} + """ Represents JSON values as specified by [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf). """ @@ -759,6 +1081,15 @@ type Mutation { input: CreateLlmProviderInput! ): CreateLlmProviderPayload """ + Creates a single `Profile`. + """ + createProfile( + """ + The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. + """ + input: CreateProfileInput! + ): CreateProfilePayload + """ Creates a single `ScheduledJob`. """ createScheduledJob( @@ -768,6 +1099,15 @@ type Mutation { input: CreateScheduledJobInput! ): CreateScheduledJobPayload """ + Creates a single `ScheduledJobRun`. + """ + createScheduledJobRun( + """ + The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. + """ + input: CreateScheduledJobRunInput! + ): CreateScheduledJobRunPayload + """ Deletes a single `Conversation` using a unique key. """ deleteConversation( @@ -777,6 +1117,33 @@ type Mutation { input: DeleteConversationInput! ): DeleteConversationPayload """ + Deletes a single `Conversation` using its globally unique id. + """ + deleteConversationById( + """ + The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. + """ + input: DeleteConversationByIdInput! + ): DeleteConversationPayload + """ + Deletes a single `ConversationMessage` using a unique key. + """ + deleteConversationMessage( + """ + The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. + """ + input: DeleteConversationMessageInput! + ): DeleteConversationMessagePayload + """ + Deletes a single `ConversationMessage` using its globally unique id. + """ + deleteConversationMessageById( + """ + The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. + """ + input: DeleteConversationMessageByIdInput! + ): DeleteConversationMessagePayload + """ Deletes a single `LlmProvider` using a unique key. """ deleteLlmProvider( @@ -786,6 +1153,42 @@ type Mutation { input: DeleteLlmProviderInput! ): DeleteLlmProviderPayload """ + Deletes a single `LlmProvider` using its globally unique id. + """ + deleteLlmProviderById( + """ + The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. + """ + input: DeleteLlmProviderByIdInput! + ): DeleteLlmProviderPayload + """ + Deletes a single `Profile` using a unique key. + """ + deleteProfile( + """ + The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. + """ + input: DeleteProfileInput! + ): DeleteProfilePayload + """ + Deletes a single `Profile` using its globally unique id. + """ + deleteProfileById( + """ + The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. + """ + input: DeleteProfileByIdInput! + ): DeleteProfilePayload + """ + Deletes a single `Profile` using a unique key. + """ + deleteProfileByUserId( + """ + The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. + """ + input: DeleteProfileByUserIdInput! + ): DeleteProfilePayload + """ Deletes a single `ScheduledJob` using a unique key. """ deleteScheduledJob( @@ -795,6 +1198,33 @@ type Mutation { input: DeleteScheduledJobInput! ): DeleteScheduledJobPayload """ + Deletes a single `ScheduledJob` using its globally unique id. + """ + deleteScheduledJobById( + """ + The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. + """ + input: DeleteScheduledJobByIdInput! + ): DeleteScheduledJobPayload + """ + Deletes a single `ScheduledJobRun` using a unique key. + """ + deleteScheduledJobRun( + """ + The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. + """ + input: DeleteScheduledJobRunInput! + ): DeleteScheduledJobRunPayload + """ + Deletes a single `ScheduledJobRun` using its globally unique id. + """ + deleteScheduledJobRunById( + """ + The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. + """ + input: DeleteScheduledJobRunByIdInput! + ): DeleteScheduledJobRunPayload + """ Updates a single `Conversation` using a unique key and a patch. """ updateConversation( @@ -804,6 +1234,33 @@ type Mutation { input: UpdateConversationInput! ): UpdateConversationPayload """ + Updates a single `Conversation` using its globally unique id and a patch. + """ + updateConversationById( + """ + The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. + """ + input: UpdateConversationByIdInput! + ): UpdateConversationPayload + """ + Updates a single `ConversationMessage` using a unique key and a patch. + """ + updateConversationMessage( + """ + The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. + """ + input: UpdateConversationMessageInput! + ): UpdateConversationMessagePayload + """ + Updates a single `ConversationMessage` using its globally unique id and a patch. + """ + updateConversationMessageById( + """ + The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. + """ + input: UpdateConversationMessageByIdInput! + ): UpdateConversationMessagePayload + """ Updates a single `LlmProvider` using a unique key and a patch. """ updateLlmProvider( @@ -813,6 +1270,33 @@ type Mutation { input: UpdateLlmProviderInput! ): UpdateLlmProviderPayload """ + Updates a single `LlmProvider` using its globally unique id and a patch. + """ + updateLlmProviderById( + """ + The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. + """ + input: UpdateLlmProviderByIdInput! + ): UpdateLlmProviderPayload + """ + Updates a single `Profile` using a unique key and a patch. + """ + updateProfile( + """ + The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. + """ + input: UpdateProfileInput! + ): UpdateProfilePayload + """ + Updates a single `Profile` using its globally unique id and a patch. + """ + updateProfileById( + """ + The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. + """ + input: UpdateProfileByIdInput! + ): UpdateProfilePayload + """ Updates a single `Profile` using a unique key and a patch. """ updateProfileByUserId( @@ -830,6 +1314,33 @@ type Mutation { """ input: UpdateScheduledJobInput! ): UpdateScheduledJobPayload + """ + Updates a single `ScheduledJob` using its globally unique id and a patch. + """ + updateScheduledJobById( + """ + The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. + """ + input: UpdateScheduledJobByIdInput! + ): UpdateScheduledJobPayload + """ + Updates a single `ScheduledJobRun` using a unique key and a patch. + """ + updateScheduledJobRun( + """ + The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. + """ + input: UpdateScheduledJobRunInput! + ): UpdateScheduledJobRunPayload + """ + Updates a single `ScheduledJobRun` using its globally unique id and a patch. + """ + updateScheduledJobRunById( + """ + The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. + """ + input: UpdateScheduledJobRunByIdInput! + ): UpdateScheduledJobRunPayload } """ @@ -987,6 +1498,42 @@ type Profile implements Node { userId: String! } +""" +A condition to be used against `Profile` object types. All fields are tested for equality and combined with a logical ‘and.’ +""" +input ProfileCondition { + """ + Checks for equality with the object’s `rowId` field. + """ + rowId: String + """ + Checks for equality with the object’s `userId` field. + """ + userId: String +} + +""" +A connection to a list of `Profile` values. +""" +type ProfileConnection { + """ + A list of edges which contains the `Profile` and cursor to aid in pagination. + """ + edges: [ProfileEdge]! + """ + A list of `Profile` objects. + """ + nodes: [Profile]! + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! + """ + The count of *all* `Profile` you could get from the connection. + """ + totalCount: Int! +} + """ A `Profile` edge in the connection. """ @@ -1001,6 +1548,20 @@ type ProfileEdge { node: Profile } +""" +An input for mutations affecting `Profile` +""" +input ProfileInput { + avatarUrl: String + createdAt: Datetime + firstName: String + lastName: String + preferences: JSON + rowId: String! + updatedAt: Datetime + userId: String! +} + """ Methods to use when ordering `Profile`. """ @@ -1037,10 +1598,32 @@ type Query implements Node { """ conversation(rowId: String!): Conversation """ + Reads a single `Conversation` using its globally unique `ID`. + """ + conversationById( + """ + The globally unique `ID` to be used in selecting a single `Conversation`. + """ + id: ID! + ): Conversation + """ Check if a conversation exists and is accessible to the current user. """ conversationExists(pConversationId: String): Boolean """ + Get a single `ConversationMessage`. + """ + conversationMessage(rowId: String!): ConversationMessage + """ + Reads a single `ConversationMessage` using its globally unique `ID`. + """ + conversationMessageById( + """ + The globally unique `ID` to be used in selecting a single `ConversationMessage`. + """ + id: ID! + ): ConversationMessage + """ Reads and enables pagination through a set of `ConversationMessage`. """ conversationMessages( @@ -1117,6 +1700,19 @@ type Query implements Node { """ id: ID! """ + Get a single `LlmProvider`. + """ + llmProvider(rowId: String!): LlmProvider + """ + Reads a single `LlmProvider` using its globally unique `ID`. + """ + llmProviderById( + """ + The globally unique `ID` to be used in selecting a single `LlmProvider`. + """ + id: ID! + ): LlmProvider + """ Reads and enables pagination through a set of `LlmProvider`. """ llmProviders( @@ -1164,13 +1760,124 @@ type Query implements Node { """ Get a single `Profile`. """ + profile(rowId: String!): Profile + """ + Reads a single `Profile` using its globally unique `ID`. + """ + profileById( + """ + The globally unique `ID` to be used in selecting a single `Profile`. + """ + id: ID! + ): Profile + """ + Get a single `Profile`. + """ profileByUserId(userId: String!): Profile """ + Reads and enables pagination through a set of `Profile`. + """ + profiles( + """ + Read all values in the set after (below) this cursor. + """ + after: Cursor + """ + Read all values in the set before (above) this cursor. + """ + before: Cursor + """ + A condition to be used in determining which values should be returned by the collection. + """ + condition: ProfileCondition + """ + Only read the first `n` values of the set. + Max: 100 + """ + first: Int = 10 + """ + Only read the last `n` values of the set. + Max: 100 + """ + last: Int + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + """ + The method to use when ordering `Profile`. + """ + orderBy: [ProfileOrderBy!] = [PRIMARY_KEY_ASC] + ): ProfileConnection + """ Exposes the root query type nested one level down. This is helpful for Relay 1 which can only query top level fields if they are in a particular form. """ query: Query! """ + Get a single `ScheduledJob`. + """ + scheduledJob(rowId: String!): ScheduledJob + """ + Reads a single `ScheduledJob` using its globally unique `ID`. + """ + scheduledJobById( + """ + The globally unique `ID` to be used in selecting a single `ScheduledJob`. + """ + id: ID! + ): ScheduledJob + """ + Get a single `ScheduledJobRun`. + """ + scheduledJobRun(rowId: String!): ScheduledJobRun + """ + Reads a single `ScheduledJobRun` using its globally unique `ID`. + """ + scheduledJobRunById( + """ + The globally unique `ID` to be used in selecting a single `ScheduledJobRun`. + """ + id: ID! + ): ScheduledJobRun + """ + Reads and enables pagination through a set of `ScheduledJobRun`. + """ + scheduledJobRuns( + """ + Read all values in the set after (below) this cursor. + """ + after: Cursor + """ + Read all values in the set before (above) this cursor. + """ + before: Cursor + """ + A condition to be used in determining which values should be returned by the collection. + """ + condition: ScheduledJobRunCondition + """ + Only read the first `n` values of the set. + Max: 100 + """ + first: Int = 10 + """ + Only read the last `n` values of the set. + Max: 100 + """ + last: Int + """ + Skip the first `n` values from our `after` cursor, an alternative to cursor + based pagination. May not be used with `last`. + """ + offset: Int + """ + The method to use when ordering `ScheduledJobRun`. + """ + orderBy: [ScheduledJobRunOrderBy!] = [PRIMARY_KEY_ASC] + ): ScheduledJobRunConnection + """ Reads and enables pagination through a set of `ScheduledJob`. """ scheduledJobs( @@ -1216,6 +1923,7 @@ type ScheduledJob implements Node { """ id: ID! lastRunAt: Datetime + llmProviderId: String name: String! """ Reads a single `Profile` that is related to this `ScheduledJob`. @@ -1324,6 +2032,7 @@ input ScheduledJobInput { createdAt: Datetime enabled: Boolean lastRunAt: Datetime + llmProviderId: String name: String! profileId: String! query: String! @@ -1354,6 +2063,7 @@ input ScheduledJobPatch { createdAt: Datetime enabled: Boolean lastRunAt: Datetime + llmProviderId: String name: String profileId: String query: String @@ -1436,6 +2146,22 @@ type ScheduledJobRunEdge { node: ScheduledJobRun } +""" +An input for mutations affecting `ScheduledJobRun` +""" +input ScheduledJobRunInput { + completedAt: Datetime + error: String + executionLog: String + finalResult: String + jobId: String! + result: String + rowId: String! + startedAt: Datetime + status: String! + toolCalls: JSON +} + """ Methods to use when ordering `ScheduledJobRun`. """ @@ -1449,6 +2175,41 @@ enum ScheduledJobRunOrderBy { ROW_ID_DESC } +""" +Represents an update to a `ScheduledJobRun`. Fields that are set will be updated. +""" +input ScheduledJobRunPatch { + completedAt: Datetime + error: String + executionLog: String + finalResult: String + jobId: String + result: String + rowId: String + startedAt: Datetime + status: String + toolCalls: JSON +} + +""" +All input for the `updateConversationById` mutation. +""" +input UpdateConversationByIdInput { + """ + An arbitrary string value with no semantic meaning. Will be included in the + payload verbatim. May be used to track mutations by the client. + """ + clientMutationId: String + """ + The globally unique `ID` which will identify a single `Conversation` to be updated. + """ + id: ID! + """ + An object where the defined keys will be set on the `Conversation` being updated. + """ + patch: ConversationPatch! +} + """ All input for the `updateConversation` mutation. """ @@ -1465,6 +2226,69 @@ input UpdateConversationInput { rowId: String! } +""" +All input for the `updateConversationMessageById` mutation. +""" +input UpdateConversationMessageByIdInput { + """ + An arbitrary string value with no semantic meaning. Will be included in the + payload verbatim. May be used to track mutations by the client. + """ + clientMutationId: String + """ + The globally unique `ID` which will identify a single `ConversationMessage` to be updated. + """ + id: ID! + """ + An object where the defined keys will be set on the `ConversationMessage` being updated. + """ + patch: ConversationMessagePatch! +} + +""" +All input for the `updateConversationMessage` mutation. +""" +input UpdateConversationMessageInput { + """ + An arbitrary string value with no semantic meaning. Will be included in the + payload verbatim. May be used to track mutations by the client. + """ + clientMutationId: String + """ + An object where the defined keys will be set on the `ConversationMessage` being updated. + """ + patch: ConversationMessagePatch! + rowId: String! +} + +""" +The output of our update `ConversationMessage` mutation. +""" +type UpdateConversationMessagePayload { + """ + The exact same `clientMutationId` that was provided in the mutation input, + unchanged and unused. May be used by a client to track mutations. + """ + clientMutationId: String + """ + The `ConversationMessage` that was updated by this mutation. + """ + conversationMessage: ConversationMessage + """ + An edge for our `ConversationMessage`. May be used by Relay 1. + """ + conversationMessageEdge( + """ + The method to use when ordering `ConversationMessage`. + """ + orderBy: [ConversationMessageOrderBy!]! = [PRIMARY_KEY_ASC] + ): ConversationMessageEdge + """ + Our root query field type. Allows us to run any query from our mutation payload. + """ + query: Query +} + """ The output of our update `Conversation` mutation. """ @@ -1493,6 +2317,25 @@ type UpdateConversationPayload { query: Query } +""" +All input for the `updateLlmProviderById` mutation. +""" +input UpdateLlmProviderByIdInput { + """ + An arbitrary string value with no semantic meaning. Will be included in the + payload verbatim. May be used to track mutations by the client. + """ + clientMutationId: String + """ + The globally unique `ID` which will identify a single `LlmProvider` to be updated. + """ + id: ID! + """ + An object where the defined keys will be set on the `LlmProvider` being updated. + """ + patch: LlmProviderPatch! +} + """ All input for the `updateLlmProvider` mutation. """ @@ -1537,6 +2380,25 @@ type UpdateLlmProviderPayload { query: Query } +""" +All input for the `updateProfileById` mutation. +""" +input UpdateProfileByIdInput { + """ + An arbitrary string value with no semantic meaning. Will be included in the + payload verbatim. May be used to track mutations by the client. + """ + clientMutationId: String + """ + The globally unique `ID` which will identify a single `Profile` to be updated. + """ + id: ID! + """ + An object where the defined keys will be set on the `Profile` being updated. + """ + patch: ProfilePatch! +} + """ All input for the `updateProfileByUserId` mutation. """ @@ -1553,6 +2415,22 @@ input UpdateProfileByUserIdInput { userId: String! } +""" +All input for the `updateProfile` mutation. +""" +input UpdateProfileInput { + """ + An arbitrary string value with no semantic meaning. Will be included in the + payload verbatim. May be used to track mutations by the client. + """ + clientMutationId: String + """ + An object where the defined keys will be set on the `Profile` being updated. + """ + patch: ProfilePatch! + rowId: String! +} + """ The output of our update `Profile` mutation. """ @@ -1581,6 +2459,25 @@ type UpdateProfilePayload { query: Query } +""" +All input for the `updateScheduledJobById` mutation. +""" +input UpdateScheduledJobByIdInput { + """ + An arbitrary string value with no semantic meaning. Will be included in the + payload verbatim. May be used to track mutations by the client. + """ + clientMutationId: String + """ + The globally unique `ID` which will identify a single `ScheduledJob` to be updated. + """ + id: ID! + """ + An object where the defined keys will be set on the `ScheduledJob` being updated. + """ + patch: ScheduledJobPatch! +} + """ All input for the `updateScheduledJob` mutation. """ @@ -1624,3 +2521,66 @@ type UpdateScheduledJobPayload { orderBy: [ScheduledJobOrderBy!]! = [PRIMARY_KEY_ASC] ): ScheduledJobEdge } + +""" +All input for the `updateScheduledJobRunById` mutation. +""" +input UpdateScheduledJobRunByIdInput { + """ + An arbitrary string value with no semantic meaning. Will be included in the + payload verbatim. May be used to track mutations by the client. + """ + clientMutationId: String + """ + The globally unique `ID` which will identify a single `ScheduledJobRun` to be updated. + """ + id: ID! + """ + An object where the defined keys will be set on the `ScheduledJobRun` being updated. + """ + patch: ScheduledJobRunPatch! +} + +""" +All input for the `updateScheduledJobRun` mutation. +""" +input UpdateScheduledJobRunInput { + """ + An arbitrary string value with no semantic meaning. Will be included in the + payload verbatim. May be used to track mutations by the client. + """ + clientMutationId: String + """ + An object where the defined keys will be set on the `ScheduledJobRun` being updated. + """ + patch: ScheduledJobRunPatch! + rowId: String! +} + +""" +The output of our update `ScheduledJobRun` mutation. +""" +type UpdateScheduledJobRunPayload { + """ + The exact same `clientMutationId` that was provided in the mutation input, + unchanged and unused. May be used by a client to track mutations. + """ + clientMutationId: String + """ + Our root query field type. Allows us to run any query from our mutation payload. + """ + query: Query + """ + The `ScheduledJobRun` that was updated by this mutation. + """ + scheduledJobRun: ScheduledJobRun + """ + An edge for our `ScheduledJobRun`. May be used by Relay 1. + """ + scheduledJobRunEdge( + """ + The method to use when ordering `ScheduledJobRun`. + """ + orderBy: [ScheduledJobRunOrderBy!]! = [PRIMARY_KEY_ASC] + ): ScheduledJobRunEdge +}