From 583816769efc8757ee375fdc25d0fb8e63e0a935 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sat, 24 Jan 2026 02:28:46 +0000 Subject: [PATCH 1/7] feat(playground): Add raw messages view to show all thread messages separately - Add RawMessageItem component that displays individual messages with all their data - Shows role, status, order, stepOrder, model, provider, usage, etc. - Displays tool calls and tool results with badges - Expandable section showing full message content, usage details, sources, provider metadata, etc. - Add toggle in MessageList to switch between 'Raw' and 'Grouped' (UIMessages) views - Raw view shows all messages separately with full data (default) - Grouped view uses toUIMessages which combines assistant messages - Addresses issue #168 where playground was missing some response parts Fixes #168 Co-authored-by: ian --- playground/src/components/MessageList.tsx | 101 ++++- playground/src/components/RawMessageItem.tsx | 452 +++++++++++++++++++ 2 files changed, 538 insertions(+), 15 deletions(-) create mode 100644 playground/src/components/RawMessageItem.tsx diff --git a/playground/src/components/MessageList.tsx b/playground/src/components/MessageList.tsx index 49f2a8e1..a7b3af71 100644 --- a/playground/src/components/MessageList.tsx +++ b/playground/src/components/MessageList.tsx @@ -1,7 +1,16 @@ -import React, { useMemo, useRef, useEffect } from "react"; +import React, { useMemo, useRef, useEffect, useState } from "react"; import MessageItem from "./MessageItem"; +import RawMessageItem from "./RawMessageItem"; import { Message, User } from "../types"; import { toUIMessages } from "@convex-dev/agent/react"; +import { Button } from "@/components/ui/button"; +import { List, Layers } from "lucide-react"; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from "@/components/ui/tooltip"; interface MessageListProps { users: User[]; @@ -17,6 +26,8 @@ const MessageList: React.FC = ({ onSelectMessage, }) => { const messagesEndRef = useRef(null); + const [viewMode, setViewMode] = useState<"raw" | "ui">("raw"); + const uiMessages = useMemo(() => { // TODO: segment the messages by "order" so the message item can show all of // the messages that have been grouped together. Right now you can only see @@ -41,20 +52,80 @@ const MessageList: React.FC = ({ }, [messages]); // Add messages as a dependency return ( -
- {uiMessages.map((message) => ( - user._id === message.userId)} - message={message} - isSelected={message._id === selectedMessageId} - onClick={() => { - onSelectMessage(message._id); - }} - /> - ))} - {/* Add an invisible div at the bottom to scroll to */} -
+
+ {/* View mode toggle */} +
+ + {viewMode === "raw" + ? `${messages.length} messages (raw)` + : `${uiMessages.length} messages (grouped)`} + + +
+ + + + + +

Show all thread messages separately with full data

+
+
+ + + + + +

Show messages grouped as UIMessages (may hide some data)

+
+
+
+
+
+ + {/* Messages list */} +
+ {viewMode === "raw" + ? messages.map((message) => ( + user._id === message.userId)} + message={message} + isSelected={message._id === selectedMessageId} + onClick={() => { + onSelectMessage(message._id); + }} + /> + )) + : uiMessages.map((message) => ( + user._id === message.userId)} + message={message} + isSelected={message._id === selectedMessageId} + onClick={() => { + onSelectMessage(message._id); + }} + /> + ))} + {/* Add an invisible div at the bottom to scroll to */} +
+
); }; diff --git a/playground/src/components/RawMessageItem.tsx b/playground/src/components/RawMessageItem.tsx new file mode 100644 index 00000000..992887ba --- /dev/null +++ b/playground/src/components/RawMessageItem.tsx @@ -0,0 +1,452 @@ +import React, { useState } from "react"; +import { formatDistanceToNow } from "date-fns"; +import type { Message, User } from "../types"; +import { Button } from "@/components/ui/button"; +import { + ChevronDown, + ChevronUp, + Bot, + User as UserIcon, + Wrench, + FileIcon, + AlertCircle, + CheckCircle, + Clock, + Zap, +} from "lucide-react"; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from "@/components/ui/tooltip"; +import { Badge } from "@/components/ui/badge"; + +interface RawMessageItemProps { + user: User | undefined; + message: Message; + isSelected: boolean; + onClick: React.MouseEventHandler; +} + +const RawMessageItem: React.FC = ({ + user, + message, + isSelected, + onClick, +}) => { + const [expanded, setExpanded] = useState(false); + + const messageDate = new Date(message._creationTime); + const relativeTime = formatDistanceToNow(messageDate, { addSuffix: true }); + + const role = message.message?.role; + const isUser = role === "user"; + const isAssistant = role === "assistant"; + const isTool = role === "tool"; + const isSystem = role === "system"; + + const toggleExpanded = (e: React.MouseEvent) => { + e.stopPropagation(); + setExpanded(!expanded); + }; + + // Get status icon and color + const getStatusInfo = () => { + switch (message.status) { + case "success": + return { + icon: , + color: "text-green-600", + bgColor: "bg-green-100", + }; + case "failed": + return { + icon: , + color: "text-red-600", + bgColor: "bg-red-100", + }; + case "pending": + return { + icon: , + color: "text-yellow-600", + bgColor: "bg-yellow-100", + }; + default: + return { + icon: null, + color: "text-gray-600", + bgColor: "bg-gray-100", + }; + } + }; + + const statusInfo = getStatusInfo(); + + // Get role icon + const getRoleIcon = () => { + if (isUser) { + return ( +
+ +
+ ); + } + if (isAssistant) { + return ( +
+ +
+ ); + } + if (isTool) { + return ( +
+ +
+ ); + } + if (isSystem) { + return ( +
+ +
+ ); + } + return null; + }; + + // Get role label + const getRoleLabel = () => { + if (isUser) return user?.name ?? "User"; + if (isAssistant) return message.agentName ?? "Assistant"; + if (isTool) return "Tool Result"; + if (isSystem) return "System"; + return "Unknown"; + }; + + // Extract text content preview + const getTextPreview = () => { + if (message.text) { + return message.text.length > 200 + ? message.text.substring(0, 200) + "..." + : message.text; + } + if ( + message.message?.content && + typeof message.message.content === "string" + ) { + const content = message.message.content; + return content.length > 200 ? content.substring(0, 200) + "..." : content; + } + return null; + }; + + // Get tool info if this is a tool message + const getToolInfo = () => { + if (!message.message) return null; + const content = message.message.content; + if (typeof content === "string") return null; + + const toolCalls = content?.filter( + (p): p is { type: "tool-call"; toolName: string; toolCallId: string } => + p.type === "tool-call", + ); + const toolResults = content?.filter( + (p): p is { type: "tool-result"; toolName: string; toolCallId: string } => + p.type === "tool-result", + ); + + return { toolCalls, toolResults }; + }; + + const toolInfo = getToolInfo(); + const textPreview = getTextPreview(); + + return ( +
+ {/* Header row */} +
+
+ {getRoleIcon()} + {getRoleLabel()} + + {role ?? "unknown"} + + {message.tool && ( + + + tool + + )} +
+ +
+ + + + + {statusInfo.icon} + {message.status} + + + +

Status: {message.status}

+
+
+
+ {relativeTime} +
+
+ + {/* Metadata badges row */} +
+ + order: {message.order} + + + step: {message.stepOrder} + + {message.model && ( + + {message.model} + + )} + {message.provider && ( + + {message.provider} + + )} + {message.usage?.totalTokens && ( + + {message.usage.totalTokens} tokens + + )} + {message.finishReason && ( + + {message.finishReason} + + )} +
+ + {/* Content preview */} +
+ {/* Tool calls/results info */} + {toolInfo?.toolCalls && toolInfo.toolCalls.length > 0 && ( +
+ {toolInfo.toolCalls.map((tc) => ( + + + {tc.toolName} + + ))} +
+ )} + + {toolInfo?.toolResults && toolInfo.toolResults.length > 0 && ( +
+ {toolInfo.toolResults.map((tr) => ( + + + {tr.toolName} result + + ))} +
+ )} + + {/* Text preview */} + {textPreview && ( +
+ {textPreview} +
+ )} + + {/* Error message */} + {message.error && ( +
+ Error: {message.error} +
+ )} + + {/* Expand/collapse button */} + + + {/* Expanded details */} + {expanded && ( +
+ {/* Message content */} +
+

+ Message Content +

+
+                {JSON.stringify(message.message, null, 2)}
+              
+
+ + {/* Usage */} + {message.usage && ( +
+

+ Usage +

+
+ + Prompt: {message.usage.promptTokens} + + + Completion: {message.usage.completionTokens} + + + Total: {message.usage.totalTokens} + + {message.usage.reasoningTokens && ( + + Reasoning: {message.usage.reasoningTokens} + + )} + {message.usage.cachedInputTokens && ( + + Cached: {message.usage.cachedInputTokens} + + )} +
+
+ )} + + {/* Sources */} + {message.sources && message.sources.length > 0 && ( +
+

+ Sources +

+
+                  {JSON.stringify(message.sources, null, 2)}
+                
+
+ )} + + {/* Provider metadata */} + {message.providerMetadata && ( +
+

+ Provider Metadata +

+
+                  {JSON.stringify(message.providerMetadata, null, 2)}
+                
+
+ )} + + {/* Provider options */} + {message.providerOptions && ( +
+

+ Provider Options +

+
+                  {JSON.stringify(message.providerOptions, null, 2)}
+                
+
+ )} + + {/* Reasoning */} + {message.reasoning && ( +
+

+ Reasoning +

+
+                  {message.reasoning}
+                
+
+ )} + + {/* Warnings */} + {message.warnings && message.warnings.length > 0 && ( +
+

+ Warnings +

+
+                  {JSON.stringify(message.warnings, null, 2)}
+                
+
+ )} + + {/* IDs and metadata */} +
+

+ IDs & Metadata +

+
+
+ _id: {message._id} +
+
+ threadId:{" "} + {message.threadId} +
+ {message.userId && ( +
+ userId:{" "} + {message.userId} +
+ )} + {message.embeddingId && ( +
+ embeddingId:{" "} + {message.embeddingId} +
+ )} + {message.fileIds && message.fileIds.length > 0 && ( +
+ fileIds:{" "} + {message.fileIds.join(", ")} +
+ )} +
+
+
+ )} +
+
+ ); +}; + +export default RawMessageItem; From 428021199bb15053cdc91ebc4ef54392f5f92b25 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 29 Jan 2026 02:43:53 +0000 Subject: [PATCH 2/7] refactor(playground): Rename components and simplify expanded details - Rename MessageItem to UIMessageItem (uses UIMessage grouping) - Rename RawMessageItem to MessageDocItem (shows individual MessageDoc) - Simplify expanded details section to just JSON.stringify the whole message document - Update MessageList imports to use new component names Co-authored-by: ian --- ...{RawMessageItem.tsx => MessageDocItem.tsx} | 147 +----------------- playground/src/components/MessageList.tsx | 8 +- .../{MessageItem.tsx => UIMessageItem.tsx} | 6 +- 3 files changed, 15 insertions(+), 146 deletions(-) rename playground/src/components/{RawMessageItem.tsx => MessageDocItem.tsx} (60%) rename playground/src/components/{MessageItem.tsx => UIMessageItem.tsx} (98%) diff --git a/playground/src/components/RawMessageItem.tsx b/playground/src/components/MessageDocItem.tsx similarity index 60% rename from playground/src/components/RawMessageItem.tsx rename to playground/src/components/MessageDocItem.tsx index 992887ba..49e706d9 100644 --- a/playground/src/components/RawMessageItem.tsx +++ b/playground/src/components/MessageDocItem.tsx @@ -8,7 +8,6 @@ import { Bot, User as UserIcon, Wrench, - FileIcon, AlertCircle, CheckCircle, Clock, @@ -22,14 +21,14 @@ import { } from "@/components/ui/tooltip"; import { Badge } from "@/components/ui/badge"; -interface RawMessageItemProps { +interface MessageDocItemProps { user: User | undefined; message: Message; isSelected: boolean; onClick: React.MouseEventHandler; } -const RawMessageItem: React.FC = ({ +const MessageDocItem: React.FC = ({ user, message, isSelected, @@ -306,142 +305,12 @@ const RawMessageItem: React.FC = ({ )} - {/* Expanded details */} + {/* Expanded details - full message document JSON */} {expanded && ( -
- {/* Message content */} -
-

- Message Content -

-
-                {JSON.stringify(message.message, null, 2)}
-              
-
- - {/* Usage */} - {message.usage && ( -
-

- Usage -

-
- - Prompt: {message.usage.promptTokens} - - - Completion: {message.usage.completionTokens} - - - Total: {message.usage.totalTokens} - - {message.usage.reasoningTokens && ( - - Reasoning: {message.usage.reasoningTokens} - - )} - {message.usage.cachedInputTokens && ( - - Cached: {message.usage.cachedInputTokens} - - )} -
-
- )} - - {/* Sources */} - {message.sources && message.sources.length > 0 && ( -
-

- Sources -

-
-                  {JSON.stringify(message.sources, null, 2)}
-                
-
- )} - - {/* Provider metadata */} - {message.providerMetadata && ( -
-

- Provider Metadata -

-
-                  {JSON.stringify(message.providerMetadata, null, 2)}
-                
-
- )} - - {/* Provider options */} - {message.providerOptions && ( -
-

- Provider Options -

-
-                  {JSON.stringify(message.providerOptions, null, 2)}
-                
-
- )} - - {/* Reasoning */} - {message.reasoning && ( -
-

- Reasoning -

-
-                  {message.reasoning}
-                
-
- )} - - {/* Warnings */} - {message.warnings && message.warnings.length > 0 && ( -
-

- Warnings -

-
-                  {JSON.stringify(message.warnings, null, 2)}
-                
-
- )} - - {/* IDs and metadata */} -
-

- IDs & Metadata -

-
-
- _id: {message._id} -
-
- threadId:{" "} - {message.threadId} -
- {message.userId && ( -
- userId:{" "} - {message.userId} -
- )} - {message.embeddingId && ( -
- embeddingId:{" "} - {message.embeddingId} -
- )} - {message.fileIds && message.fileIds.length > 0 && ( -
- fileIds:{" "} - {message.fileIds.join(", ")} -
- )} -
-
+
+
+              {JSON.stringify(message, null, 2)}
+            
)}
@@ -449,4 +318,4 @@ const RawMessageItem: React.FC = ({ ); }; -export default RawMessageItem; +export default MessageDocItem; diff --git a/playground/src/components/MessageList.tsx b/playground/src/components/MessageList.tsx index a7b3af71..278f7bf6 100644 --- a/playground/src/components/MessageList.tsx +++ b/playground/src/components/MessageList.tsx @@ -1,6 +1,6 @@ import React, { useMemo, useRef, useEffect, useState } from "react"; -import MessageItem from "./MessageItem"; -import RawMessageItem from "./RawMessageItem"; +import UIMessageItem from "./UIMessageItem"; +import MessageDocItem from "./MessageDocItem"; import { Message, User } from "../types"; import { toUIMessages } from "@convex-dev/agent/react"; import { Button } from "@/components/ui/button"; @@ -102,7 +102,7 @@ const MessageList: React.FC = ({
{viewMode === "raw" ? messages.map((message) => ( - user._id === message.userId)} message={message} @@ -113,7 +113,7 @@ const MessageList: React.FC = ({ /> )) : uiMessages.map((message) => ( - user._id === message.userId)} message={message} diff --git a/playground/src/components/MessageItem.tsx b/playground/src/components/UIMessageItem.tsx similarity index 98% rename from playground/src/components/MessageItem.tsx rename to playground/src/components/UIMessageItem.tsx index e3909a17..e3634360 100644 --- a/playground/src/components/MessageItem.tsx +++ b/playground/src/components/UIMessageItem.tsx @@ -13,14 +13,14 @@ import { import { DynamicToolUIPart, ToolUIPart, UIMessage } from "ai"; import { SmoothText } from "@convex-dev/agent/react"; -interface MessageItemProps { +interface UIMessageItemProps { user: User | undefined; message: Omit & { message: UIMessage }; isSelected: boolean; onClick: React.MouseEventHandler; } -const MessageItem: React.FC = ({ +const UIMessageItem: React.FC = ({ user, message, isSelected, @@ -159,7 +159,7 @@ const MessageItem: React.FC = ({ ); }; -export default MessageItem; +export default UIMessageItem; const ToolCall: React.FC<{ part: ToolUIPart | DynamicToolUIPart; From 7bd7f9966f381301d312800f2a316f05b9904817 Mon Sep 17 00:00:00 2001 From: Ian Macartney <366683+ianmacartney@users.noreply.github.com> Date: Wed, 28 Jan 2026 23:32:49 -0800 Subject: [PATCH 3/7] use surge.sh for playground preview deploys --- .github/workflows/preview.yml | 59 +++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 .github/workflows/preview.yml diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml new file mode 100644 index 00000000..a9a9f76f --- /dev/null +++ b/.github/workflows/preview.yml @@ -0,0 +1,59 @@ +name: Preview Playground PR + +on: + pull_request: + branches: + - playground + +permissions: + contents: read + pull-requests: write + +jobs: + preview: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4 + + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 + with: + node-version: 20 + cache: "npm" + + - name: Install root dependencies & build + run: npm ci && npm run build + + - name: Install playground dependencies + run: cd playground && npm i + + - name: Build Vite project + run: cd playground && npm run build + + - name: Enable SPA routing + run: cp playground/dist/index.html playground/dist/200.html + + - name: Deploy to Surge + run: | + npm install -g surge + surge playground/dist agent-pr-${{ github.event.pull_request.number }}.surge.sh --token ${{ secrets.SURGE_TOKEN }} + + - name: Comment PR with preview URL + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7 + with: + script: | + const { data: comments } = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + }); + + if (comments.some(c => c.body.includes('🚀 Preview Deployment'))) { + return; // Already commented + } + + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: `## 🚀 Preview Deployment\n\nYour preview is ready!\n\n**URL:** https://agent-pr-${{ github.event.pull_request.number }}.surge.sh` + }); From 1b6bbb57fd44bd553641328b732c6a8f1312bfed Mon Sep 17 00:00:00 2001 From: Ian Macartney <366683+ianmacartney@users.noreply.github.com> Date: Wed, 28 Jan 2026 23:43:43 -0800 Subject: [PATCH 4/7] preview playround whenever it changes --- .github/workflows/preview.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index a9a9f76f..bb2f4f47 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -2,8 +2,8 @@ name: Preview Playground PR on: pull_request: - branches: - - playground + paths: + - "playground/**" permissions: contents: read From 4ae9c54873d66ee489b932c61df2191b8e43770c Mon Sep 17 00:00:00 2001 From: Ian Macartney <366683+ianmacartney@users.noreply.github.com> Date: Thu, 5 Feb 2026 16:12:54 -0800 Subject: [PATCH 5/7] codegen --- .cursor/rules/convex_rules.mdc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.cursor/rules/convex_rules.mdc b/.cursor/rules/convex_rules.mdc index 1d984804..7d22904e 100644 --- a/.cursor/rules/convex_rules.mdc +++ b/.cursor/rules/convex_rules.mdc @@ -180,7 +180,7 @@ Note: `paginationOpts` is an object with the following properties: ## Schema guidelines - Always define your schema in `convex/schema.ts`. -- Always import the schema definition functions from `convex/server`: +- Always import the schema definition functions from `convex/server`. - System fields are automatically added to all documents and are prefixed with an underscore. The two system fields that are automatically added to all documents are `_creationTime` which has the validator `v.number()` and `_id` which has the validator `v.id(tableName)`. - Always include all index fields in the index name. For example, if an index is defined as `["field1", "field2"]`, the index name should be "by_field1_and_field2". - Index fields must be queried in the same order they are defined. If you want to be able to query by "field1" then "field2" and by "field2" then "field1", you must create separate indexes. From 412b5c3c03e453c5df4146fd925d0bf39823d7e7 Mon Sep 17 00:00:00 2001 From: Ian Macartney <366683+ianmacartney@users.noreply.github.com> Date: Thu, 5 Feb 2026 16:12:56 -0800 Subject: [PATCH 6/7] codegen --- .cursor/rules/convex_rules.mdc | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/.cursor/rules/convex_rules.mdc b/.cursor/rules/convex_rules.mdc index 7d22904e..58f1e3a5 100644 --- a/.cursor/rules/convex_rules.mdc +++ b/.cursor/rules/convex_rules.mdc @@ -480,8 +480,8 @@ import OpenAI from "openai"; import { internal } from "./_generated/api"; /** - * Create a user with a given name. - */ + * Create a user with a given name. + */ export const createUser = mutation({ args: { name: v.string(), @@ -493,8 +493,8 @@ export const createUser = mutation({ }); /** - * Create a channel with a given name. - */ + * Create a channel with a given name. + */ export const createChannel = mutation({ args: { name: v.string(), @@ -506,8 +506,8 @@ export const createChannel = mutation({ }); /** - * List the 10 most recent messages from a channel in descending creation order. - */ + * List the 10 most recent messages from a channel in descending creation order. + */ export const listMessages = query({ args: { channelId: v.id("channels"), @@ -532,8 +532,8 @@ export const listMessages = query({ }); /** - * Send a message to a channel and schedule a response from the AI. - */ + * Send a message to a channel and schedule a response from the AI. + */ export const sendMessage = mutation({ args: { channelId: v.id("channels"), @@ -672,5 +672,4 @@ export default defineSchema({ export default function App() { return
Hello World
; } -``` - +``` \ No newline at end of file From 90f1094c632de0dd5d5bf32b1dc890c397e24d6f Mon Sep 17 00:00:00 2001 From: Ian Macartney <366683+ianmacartney@users.noreply.github.com> Date: Fri, 13 Feb 2026 11:20:28 -0800 Subject: [PATCH 7/7] codegen --- example/convex/_generated/dataModel.d.ts | 2 +- src/component/_generated/dataModel.ts | 2 +- src/component/_generated/server.ts | 5 ----- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/example/convex/_generated/dataModel.d.ts b/example/convex/_generated/dataModel.d.ts index 8541f319..f97fd194 100644 --- a/example/convex/_generated/dataModel.d.ts +++ b/example/convex/_generated/dataModel.d.ts @@ -38,7 +38,7 @@ export type Doc = DocumentByName< * Convex documents are uniquely identified by their `Id`, which is accessible * on the `_id` field. To learn more, see [Document IDs](https://docs.convex.dev/using/document-ids). * - * Documents can be loaded using `db.get(id)` in query and mutation functions. + * Documents can be loaded using `db.get(tableName, id)` in query and mutation functions. * * IDs are just strings at runtime, but this type can be used to distinguish them from other * strings when type checking. diff --git a/src/component/_generated/dataModel.ts b/src/component/_generated/dataModel.ts index 8541f319..f97fd194 100644 --- a/src/component/_generated/dataModel.ts +++ b/src/component/_generated/dataModel.ts @@ -38,7 +38,7 @@ export type Doc = DocumentByName< * Convex documents are uniquely identified by their `Id`, which is accessible * on the `_id` field. To learn more, see [Document IDs](https://docs.convex.dev/using/document-ids). * - * Documents can be loaded using `db.get(id)` in query and mutation functions. + * Documents can be loaded using `db.get(tableName, id)` in query and mutation functions. * * IDs are just strings at runtime, but this type can be used to distinguish them from other * strings when type checking. diff --git a/src/component/_generated/server.ts b/src/component/_generated/server.ts index 24994e4e..739b02f7 100644 --- a/src/component/_generated/server.ts +++ b/src/component/_generated/server.ts @@ -107,11 +107,6 @@ export const internalAction: ActionBuilder = */ export const httpAction: HttpActionBuilder = httpActionGeneric; -type GenericCtx = - | GenericActionCtx - | GenericMutationCtx - | GenericQueryCtx; - /** * A set of services for use within Convex query functions. *