@superinterface/server 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -0
- package/eslint.config.mjs +31 -0
- package/next.config.ts +7 -0
- package/package.json +176 -0
- package/prisma/Account.prisma +18 -0
- package/prisma/ApiKey.prisma +13 -0
- package/prisma/Assistant.prisma +32 -0
- package/prisma/AssistantHandler.prisma +12 -0
- package/prisma/Avatar.prisma +10 -0
- package/prisma/ClientToolHandler.prisma +13 -0
- package/prisma/CodeInterpreterTool.prisma +7 -0
- package/prisma/ComputerUseTool.prisma +12 -0
- package/prisma/CreateTaskHandler.prisma +10 -0
- package/prisma/DeleteTaskHandler.prisma +10 -0
- package/prisma/FileSearchTool.prisma +9 -0
- package/prisma/FirecrawlHandler.prisma +13 -0
- package/prisma/Function.prisma +13 -0
- package/prisma/Handler.prisma +19 -0
- package/prisma/HttpTransport.prisma +12 -0
- package/prisma/IconAvatar.prisma +8 -0
- package/prisma/ImageAvatar.prisma +8 -0
- package/prisma/ImageGenerationTool.prisma +11 -0
- package/prisma/InitialMessage.prisma +17 -0
- package/prisma/Invitation.prisma +15 -0
- package/prisma/ListTasksHandler.prisma +10 -0
- package/prisma/Log.prisma +21 -0
- package/prisma/McpServer.prisma +14 -0
- package/prisma/Message.prisma +30 -0
- package/prisma/ModelProvider.prisma +15 -0
- package/prisma/Organization.prisma +10 -0
- package/prisma/OrganizationApiKey.prisma +12 -0
- package/prisma/OrganizationInvitation.prisma +15 -0
- package/prisma/OrganizationUserRole.prisma +14 -0
- package/prisma/ReplicateHandler.prisma +14 -0
- package/prisma/RequestHandler.prisma +15 -0
- package/prisma/Run.prisma +36 -0
- package/prisma/RunStep.prisma +30 -0
- package/prisma/Session.prisma +7 -0
- package/prisma/SseTransport.prisma +12 -0
- package/prisma/StdioTransport.prisma +11 -0
- package/prisma/Task.prisma +15 -0
- package/prisma/Thread.prisma +20 -0
- package/prisma/Tool.prisma +13 -0
- package/prisma/UpdateTaskHandler.prisma +10 -0
- package/prisma/User.prisma +16 -0
- package/prisma/UserRole.prisma +14 -0
- package/prisma/VerificationToken.prisma +7 -0
- package/prisma/WebSearchTool.prisma +7 -0
- package/prisma/Workspace.prisma +14 -0
- package/prisma/enums/ApiKeyType.prisma +4 -0
- package/prisma/enums/AvatarType.prisma +5 -0
- package/prisma/enums/ClientToolHandlerType.prisma +3 -0
- package/prisma/enums/ComputerUseToolEnvironment.prisma +6 -0
- package/prisma/enums/FirecrawlHandlerType.prisma +6 -0
- package/prisma/enums/HandlerType.prisma +11 -0
- package/prisma/enums/IconAvatarName.prisma +14 -0
- package/prisma/enums/ImageGenerationToolOutputFormat.prisma +5 -0
- package/prisma/enums/ImageGenerationToolQuality.prisma +6 -0
- package/prisma/enums/ImageGenerationToolSize.prisma +6 -0
- package/prisma/enums/LogLevel.prisma +5 -0
- package/prisma/enums/LogRequestMethod.prisma +7 -0
- package/prisma/enums/LogRequestRoute.prisma +6 -0
- package/prisma/enums/MessageRole.prisma +4 -0
- package/prisma/enums/MessageStatus.prisma +5 -0
- package/prisma/enums/MethodType.prisma +7 -0
- package/prisma/enums/ModelProviderType.prisma +13 -0
- package/prisma/enums/OrganizationUserRoleType.prisma +3 -0
- package/prisma/enums/ReplicateHandlerType.prisma +3 -0
- package/prisma/enums/RunStatus.prisma +10 -0
- package/prisma/enums/RunStepStatus.prisma +7 -0
- package/prisma/enums/RunStepType.prisma +4 -0
- package/prisma/enums/StorageProviderType.prisma +7 -0
- package/prisma/enums/ToolType.prisma +7 -0
- package/prisma/enums/TransportType.prisma +5 -0
- package/prisma/enums/TruncationType.prisma +5 -0
- package/prisma/enums/UserRoleType.prisma +3 -0
- package/prisma/migrations/20251006235143_initial_setup/migration.sql +986 -0
- package/prisma/migrations/20251007163926_add_truncation_type/migration.sql +6 -0
- package/prisma/migrations/20251007190703_add_organizations/migration.sql +97 -0
- package/prisma/migrations/migration_lock.toml +3 -0
- package/prisma/schema.prisma +13 -0
- package/prisma.config.ts +6 -0
- package/scripts/cli.ts +84 -0
- package/scripts/commands/organizations/api-keys/create.ts +159 -0
- package/scripts/commands/organizations/create.ts +82 -0
- package/scripts/utils/env.ts +31 -0
- package/scripts/utils/errors.ts +6 -0
- package/src/app/api/api-keys/[apiKeyId]/route.ts +178 -0
- package/src/app/api/api-keys/route.ts +147 -0
- package/src/app/api/assistants/[assistantId]/functions/[functionId]/route.ts +245 -0
- package/src/app/api/assistants/[assistantId]/functions/route.ts +157 -0
- package/src/app/api/assistants/[assistantId]/initial-messages/route.ts +127 -0
- package/src/app/api/assistants/[assistantId]/mcp-servers/[mcpServerId]/route.ts +243 -0
- package/src/app/api/assistants/[assistantId]/mcp-servers/route.ts +163 -0
- package/src/app/api/assistants/[assistantId]/route.ts +336 -0
- package/src/app/api/assistants/route.ts +196 -0
- package/src/app/api/files/[fileId]/contents/route.ts +145 -0
- package/src/app/api/files/route.ts +117 -0
- package/src/app/api/messages/lib/getWorkspaceId.ts +12 -0
- package/src/app/api/messages/lib/initialMessagesResponse.ts +90 -0
- package/src/app/api/messages/lib/serializeThread.ts +22 -0
- package/src/app/api/messages/route.ts +710 -0
- package/src/app/api/providers/[modelProviderId]/assistants/route.ts +68 -0
- package/src/app/api/providers/[modelProviderId]/models/route.ts +68 -0
- package/src/app/api/providers/[modelProviderId]/route.ts +202 -0
- package/src/app/api/providers/route.ts +105 -0
- package/src/app/api/tasks/[taskId]/route.ts +213 -0
- package/src/app/api/tasks/callback/route.ts +280 -0
- package/src/app/api/tasks/route.ts +121 -0
- package/src/app/api/threads/runs/submit-client-tool-outputs/route.ts +54 -0
- package/src/app/api/workspaces/[workspaceId]/route.ts +137 -0
- package/src/app/api/workspaces/route.ts +139 -0
- package/src/app/layout.tsx +9 -0
- package/src/app/page.tsx +3 -0
- package/src/lib/apiKeys/formatApiKeyName.ts +13 -0
- package/src/lib/apiKeys/getApiKey.ts +25 -0
- package/src/lib/apiKeys/serializeApiKey.ts +11 -0
- package/src/lib/apiKeys/workspaceAccessWhere.ts +21 -0
- package/src/lib/assistants/assistantClientAdapter/buildGetOpenaiAssistant.ts +96 -0
- package/src/lib/assistants/assistantClientAdapter/index.ts +165 -0
- package/src/lib/assistants/formatName.ts +9 -0
- package/src/lib/assistants/serializeApiAssistant.ts +40 -0
- package/src/lib/assistants/serializeAssistant.ts +31 -0
- package/src/lib/assistants/storageAssistantId.ts +29 -0
- package/src/lib/avatars/defaultAvatar.ts +15 -0
- package/src/lib/avatars/serializeAvatar.ts +26 -0
- package/src/lib/cache/cacheHeaders.ts +5 -0
- package/src/lib/computerCalls/handleComputerCall/index.ts +173 -0
- package/src/lib/errors/index.ts +10 -0
- package/src/lib/errors/serializeError.ts +11 -0
- package/src/lib/functions/createFunction.ts +32 -0
- package/src/lib/functions/functionSchema.ts +201 -0
- package/src/lib/functions/handleFunction/getFunction.ts +43 -0
- package/src/lib/functions/handleFunction/handleAssistant.ts +399 -0
- package/src/lib/functions/handleFunction/handleClientTool.ts +127 -0
- package/src/lib/functions/handleFunction/handleFirecrawl.ts +212 -0
- package/src/lib/functions/handleFunction/handleReplicate.ts +109 -0
- package/src/lib/functions/handleFunction/handleRequest.ts +272 -0
- package/src/lib/functions/handleFunction/index.ts +474 -0
- package/src/lib/functions/handleFunction/tasks/handleCreateTask.ts +58 -0
- package/src/lib/functions/handleFunction/tasks/handleDeleteTask.ts +62 -0
- package/src/lib/functions/handleFunction/tasks/handleListTasks.ts +53 -0
- package/src/lib/functions/handleFunction/tasks/handleUpdateTask.ts +70 -0
- package/src/lib/functions/interpolateFunctionValue.ts +26 -0
- package/src/lib/functions/serializeApiFunction.ts +32 -0
- package/src/lib/functions/updateFunction.ts +42 -0
- package/src/lib/handlers/handlerPrismaInput.tsx +141 -0
- package/src/lib/handlers/serializeApiHandler.ts +94 -0
- package/src/lib/iconAvatars/serializeIconAvatar.ts +9 -0
- package/src/lib/imageAvatars/serializeImageAvatar.ts +9 -0
- package/src/lib/initialMessages/schema.ts +11 -0
- package/src/lib/initialMessages/serializeApiInitialMessage.ts +15 -0
- package/src/lib/initialMessages/updateInitialMessages.ts +33 -0
- package/src/lib/logs/createLog.ts +17 -0
- package/src/lib/mcpServers/closeMcpConnection.ts +16 -0
- package/src/lib/mcpServers/connectMcpServer.ts +117 -0
- package/src/lib/mcpServers/getToolCallMcpServer.ts +62 -0
- package/src/lib/mcpServers/headers.ts +113 -0
- package/src/lib/mcpServers/mcpServerSchema.ts +77 -0
- package/src/lib/mcpServers/serializeApiMcpServer.ts +51 -0
- package/src/lib/mcpServers/url.ts +98 -0
- package/src/lib/messages/content.ts +60 -0
- package/src/lib/messages/textContent.ts +13 -0
- package/src/lib/metadata/serializeMetadata.ts +34 -0
- package/src/lib/misc/isJSON.ts +9 -0
- package/src/lib/misc/merge/customizer.ts +8 -0
- package/src/lib/misc/merge/index.ts +6 -0
- package/src/lib/modelProviders/buildAzureOpenaiClientAdapter.ts +33 -0
- package/src/lib/modelProviders/buildOpenaiClient.ts +14 -0
- package/src/lib/modelProviders/buildOpenaiClientAdapter.ts +30 -0
- package/src/lib/modelProviders/clientAdapter.ts +121 -0
- package/src/lib/modelProviders/isModelProviderValid.ts +23 -0
- package/src/lib/modelProviders/modelProviderConfigs.ts +221 -0
- package/src/lib/modelProviders/serializeModelProvider.ts +19 -0
- package/src/lib/models/getModels.ts +27 -0
- package/src/lib/models/serializeApiModel.ts +5 -0
- package/src/lib/openai/getOpenaiAssistants.ts +30 -0
- package/src/lib/organizationApiKeys/getOrganizationApiKey.ts +23 -0
- package/src/lib/prisma/index.ts +29 -0
- package/src/lib/redis/index.ts +3 -0
- package/src/lib/runs/createRunOpts.ts +80 -0
- package/src/lib/storageProviders/getStorageProviderAssistants.ts +19 -0
- package/src/lib/storageProviders/getStorageProviderType.ts +21 -0
- package/src/lib/storageProviders/isOpenaiAssistantsStorageProvider.ts +8 -0
- package/src/lib/storageProviders/isResponsesStorageProvider.ts +8 -0
- package/src/lib/storageProviders/openaiAssistantsStorageProviderTypes.ts +6 -0
- package/src/lib/storageProviders/responsesStorageProviderTypes.ts +6 -0
- package/src/lib/storageProviders/serializeApiStorageProviderAssistant.ts +14 -0
- package/src/lib/tasks/cancelScheduledTask.ts +13 -0
- package/src/lib/tasks/getNextOccurrence.ts +77 -0
- package/src/lib/tasks/getTaskToolKey.ts +49 -0
- package/src/lib/tasks/parseTaskToolArgs.ts +101 -0
- package/src/lib/tasks/scheduleSchema.ts +34 -0
- package/src/lib/tasks/scheduleTask.ts +37 -0
- package/src/lib/tasks/schemas.ts +25 -0
- package/src/lib/tasks/serializeTask.ts +14 -0
- package/src/lib/tasks/validateSchedule.ts +23 -0
- package/src/lib/themes/defaultTheme.ts +7 -0
- package/src/lib/themes/serializeAccentColor.ts +9 -0
- package/src/lib/themes/serializeTheme/index.ts +25 -0
- package/src/lib/themes/serializeTheme/serializeScaling.ts +14 -0
- package/src/lib/threads/createThread/index.ts +185 -0
- package/src/lib/threads/createThread/initialMessages.ts +36 -0
- package/src/lib/threads/managedOpenaiThreadId.ts +72 -0
- package/src/lib/threads/storageThreadId.ts +49 -0
- package/src/lib/threads/validThreadId.ts +10 -0
- package/src/lib/toolCalls/handleToolCall.ts +121 -0
- package/src/lib/toolCalls/messagesToOutput.ts +8 -0
- package/src/lib/toolCalls/streamOutput.ts +106 -0
- package/src/lib/tools/tools/index.ts +316 -0
- package/src/lib/upstash/qstash.ts +5 -0
- package/src/lib/upstash/upstashWorkflowClient.ts +5 -0
- package/src/lib/workspaces/serializeApiWorkspace.ts +12 -0
- package/src/types/index.ts +133 -0
- package/tsconfig.build.json +13 -0
- package/tsconfig.json +27 -0
- package/types/prisma.d.ts +4 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { headers } from 'next/headers'
|
|
2
|
+
import { ApiKeyType } from '@prisma/client'
|
|
3
|
+
import { NextResponse } from 'next/server'
|
|
4
|
+
import { z } from 'zod'
|
|
5
|
+
import { cacheHeaders } from '@/lib/cache/cacheHeaders'
|
|
6
|
+
import { prisma } from '@/lib/prisma'
|
|
7
|
+
import { serializeApiKey } from '@/lib/apiKeys/serializeApiKey'
|
|
8
|
+
import { getApiKey } from '@/lib/apiKeys/getApiKey'
|
|
9
|
+
import { getOrganizationApiKey } from '@/lib/organizationApiKeys/getOrganizationApiKey'
|
|
10
|
+
|
|
11
|
+
export const GET = async () => {
|
|
12
|
+
const headersList = await headers()
|
|
13
|
+
const authorization = headersList.get('authorization')
|
|
14
|
+
if (!authorization) {
|
|
15
|
+
return NextResponse.json(
|
|
16
|
+
{ error: 'No authorization header found' },
|
|
17
|
+
{ status: 400 },
|
|
18
|
+
)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const privateApiKey = await getApiKey({
|
|
22
|
+
type: ApiKeyType.PRIVATE,
|
|
23
|
+
authorization,
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
if (!privateApiKey) {
|
|
27
|
+
return NextResponse.json({ error: 'Invalid api key' }, { status: 400 })
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const apiKeys = await prisma.apiKey.findMany({
|
|
31
|
+
where: {
|
|
32
|
+
type: ApiKeyType.PUBLIC,
|
|
33
|
+
workspaceId: privateApiKey.workspaceId,
|
|
34
|
+
},
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
return NextResponse.json(
|
|
38
|
+
{
|
|
39
|
+
apiKeys: apiKeys.map((apiKey) => serializeApiKey({ apiKey })),
|
|
40
|
+
},
|
|
41
|
+
{ headers: cacheHeaders },
|
|
42
|
+
)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export const POST = async (request: Request) => {
|
|
46
|
+
const headersList = await headers()
|
|
47
|
+
const authorization = headersList.get('authorization')
|
|
48
|
+
if (!authorization) {
|
|
49
|
+
return NextResponse.json(
|
|
50
|
+
{ error: 'No authorization header found' },
|
|
51
|
+
{ status: 400 },
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const body = await request.json().catch(() => null)
|
|
56
|
+
|
|
57
|
+
const organizationApiKey = await getOrganizationApiKey({
|
|
58
|
+
authorization,
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
if (organizationApiKey) {
|
|
62
|
+
const createSchemaOrganizationApiKey = z.object({
|
|
63
|
+
name: z.string().min(1).optional(),
|
|
64
|
+
type: z.nativeEnum(ApiKeyType),
|
|
65
|
+
workspaceId: z.string().min(1).optional(),
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
const parsedOrganizationApiKey =
|
|
69
|
+
createSchemaOrganizationApiKey.safeParse(body)
|
|
70
|
+
|
|
71
|
+
if (!parsedOrganizationApiKey.success) {
|
|
72
|
+
return NextResponse.json({ error: 'Invalid body' }, { status: 400 })
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const workspace = await prisma.workspace.findUnique({
|
|
76
|
+
where: {
|
|
77
|
+
id: parsedOrganizationApiKey.data.workspaceId,
|
|
78
|
+
organizationId: organizationApiKey.organizationId,
|
|
79
|
+
},
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
if (!workspace) {
|
|
83
|
+
return NextResponse.json({ error: 'Invalid workspace' }, { status: 400 })
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const apiKey = await prisma.apiKey.create({
|
|
87
|
+
data: {
|
|
88
|
+
type: parsedOrganizationApiKey.data.type,
|
|
89
|
+
name: parsedOrganizationApiKey.data.name,
|
|
90
|
+
workspaceId: workspace.id,
|
|
91
|
+
},
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
return NextResponse.json(
|
|
95
|
+
{
|
|
96
|
+
apiKey: serializeApiKey({ apiKey }),
|
|
97
|
+
},
|
|
98
|
+
{ headers: cacheHeaders },
|
|
99
|
+
)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const privateApiKey = await getApiKey({
|
|
103
|
+
type: ApiKeyType.PRIVATE,
|
|
104
|
+
authorization,
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
if (!privateApiKey) {
|
|
108
|
+
return NextResponse.json({ error: 'Invalid api key' }, { status: 400 })
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const createSchema = z.object({
|
|
112
|
+
name: z.string().min(1).optional(),
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
const parsed = createSchema.safeParse(body)
|
|
116
|
+
|
|
117
|
+
if (!parsed.success) {
|
|
118
|
+
return NextResponse.json({ error: 'Invalid body' }, { status: 400 })
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const { name } = parsed.data
|
|
122
|
+
|
|
123
|
+
const workspaceId = privateApiKey.workspaceId
|
|
124
|
+
|
|
125
|
+
const apiKey = await prisma.apiKey.create({
|
|
126
|
+
data: {
|
|
127
|
+
type: ApiKeyType.PUBLIC,
|
|
128
|
+
name,
|
|
129
|
+
workspaceId,
|
|
130
|
+
},
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
return NextResponse.json(
|
|
134
|
+
{
|
|
135
|
+
apiKey: serializeApiKey({ apiKey }),
|
|
136
|
+
},
|
|
137
|
+
{ headers: cacheHeaders },
|
|
138
|
+
)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export const OPTIONS = () =>
|
|
142
|
+
NextResponse.json(
|
|
143
|
+
{},
|
|
144
|
+
{
|
|
145
|
+
headers: cacheHeaders,
|
|
146
|
+
},
|
|
147
|
+
)
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import { headers } from 'next/headers'
|
|
2
|
+
import { ApiKeyType } from '@prisma/client'
|
|
3
|
+
import { NextResponse, type NextRequest } from 'next/server'
|
|
4
|
+
import { cacheHeaders } from '@/lib/cache/cacheHeaders'
|
|
5
|
+
import { prisma } from '@/lib/prisma'
|
|
6
|
+
import { getApiKey } from '@/lib/apiKeys/getApiKey'
|
|
7
|
+
import { validate } from 'uuid'
|
|
8
|
+
import { serializeApiFunction } from '@/lib/functions/serializeApiFunction'
|
|
9
|
+
import { functionSchema } from '@/lib/functions/functionSchema'
|
|
10
|
+
import { updateFunction } from '@/lib/functions/updateFunction'
|
|
11
|
+
|
|
12
|
+
export const GET = async (
|
|
13
|
+
_request: NextRequest,
|
|
14
|
+
props: { params: Promise<{ assistantId: string; functionId: string }> },
|
|
15
|
+
) => {
|
|
16
|
+
const { assistantId, functionId } = await props.params
|
|
17
|
+
|
|
18
|
+
const headersList = await headers()
|
|
19
|
+
const authorization = headersList.get('authorization')
|
|
20
|
+
if (!authorization) {
|
|
21
|
+
return NextResponse.json(
|
|
22
|
+
{ error: 'No authorization header found' },
|
|
23
|
+
{ status: 400 },
|
|
24
|
+
)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const privateApiKey = await getApiKey({
|
|
28
|
+
type: ApiKeyType.PRIVATE,
|
|
29
|
+
authorization,
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
if (!privateApiKey) {
|
|
33
|
+
return NextResponse.json({ error: 'Invalid api key' }, { status: 400 })
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (!validate(assistantId)) {
|
|
37
|
+
return NextResponse.json({ error: 'Invalid assistant id' }, { status: 400 })
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (!validate(functionId)) {
|
|
41
|
+
return NextResponse.json({ error: 'Invalid function id' }, { status: 400 })
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const fn = await prisma.function.findFirst({
|
|
45
|
+
where: {
|
|
46
|
+
id: functionId,
|
|
47
|
+
assistant: {
|
|
48
|
+
id: assistantId,
|
|
49
|
+
workspaceId: privateApiKey.workspaceId,
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
include: {
|
|
53
|
+
handler: {
|
|
54
|
+
include: {
|
|
55
|
+
requestHandler: true,
|
|
56
|
+
firecrawlHandler: true,
|
|
57
|
+
replicateHandler: true,
|
|
58
|
+
clientToolHandler: true,
|
|
59
|
+
assistantHandler: true,
|
|
60
|
+
createTaskHandler: true,
|
|
61
|
+
listTasksHandler: true,
|
|
62
|
+
updateTaskHandler: true,
|
|
63
|
+
deleteTaskHandler: true,
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
if (!fn) {
|
|
70
|
+
return NextResponse.json({ error: 'No function found' }, { status: 400 })
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return NextResponse.json(
|
|
74
|
+
{
|
|
75
|
+
function: serializeApiFunction({ fn }),
|
|
76
|
+
},
|
|
77
|
+
{ headers: cacheHeaders },
|
|
78
|
+
)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export const PATCH = async (
|
|
82
|
+
request: NextRequest,
|
|
83
|
+
props: { params: Promise<{ assistantId: string; functionId: string }> },
|
|
84
|
+
) => {
|
|
85
|
+
const { assistantId, functionId } = await props.params
|
|
86
|
+
|
|
87
|
+
const headersList = await headers()
|
|
88
|
+
const authorization = headersList.get('authorization')
|
|
89
|
+
if (!authorization) {
|
|
90
|
+
return NextResponse.json(
|
|
91
|
+
{ error: 'No authorization header found' },
|
|
92
|
+
{ status: 400 },
|
|
93
|
+
)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const privateApiKey = await getApiKey({
|
|
97
|
+
authorization,
|
|
98
|
+
type: ApiKeyType.PRIVATE,
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
if (!privateApiKey) {
|
|
102
|
+
return NextResponse.json({ error: 'Invalid api key' }, { status: 400 })
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (!validate(assistantId)) {
|
|
106
|
+
return NextResponse.json({ error: 'Invalid assistant id' }, { status: 400 })
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (!validate(functionId)) {
|
|
110
|
+
return NextResponse.json({ error: 'Invalid function id' }, { status: 400 })
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const body = await request.json()
|
|
114
|
+
|
|
115
|
+
const parsed = functionSchema.safeParse(body)
|
|
116
|
+
|
|
117
|
+
if (!parsed.success) {
|
|
118
|
+
return NextResponse.json({ error: 'Invalid payload' }, { status: 400 })
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const fn = await prisma.function.findFirst({
|
|
122
|
+
where: {
|
|
123
|
+
id: functionId,
|
|
124
|
+
assistant: {
|
|
125
|
+
id: assistantId,
|
|
126
|
+
workspaceId: privateApiKey.workspaceId,
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
include: {
|
|
130
|
+
assistant: true,
|
|
131
|
+
},
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
if (!fn) {
|
|
135
|
+
return NextResponse.json({ error: 'No function found' }, { status: 400 })
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const updatedFunction = await updateFunction({
|
|
139
|
+
fn,
|
|
140
|
+
parsedInput: parsed.data,
|
|
141
|
+
include: {
|
|
142
|
+
handler: {
|
|
143
|
+
include: {
|
|
144
|
+
requestHandler: true,
|
|
145
|
+
firecrawlHandler: true,
|
|
146
|
+
replicateHandler: true,
|
|
147
|
+
clientToolHandler: true,
|
|
148
|
+
assistantHandler: true,
|
|
149
|
+
createTaskHandler: true,
|
|
150
|
+
listTasksHandler: true,
|
|
151
|
+
updateTaskHandler: true,
|
|
152
|
+
deleteTaskHandler: true,
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
return NextResponse.json(
|
|
159
|
+
{
|
|
160
|
+
function: serializeApiFunction({ fn: updatedFunction }),
|
|
161
|
+
},
|
|
162
|
+
{ headers: cacheHeaders },
|
|
163
|
+
)
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export const DELETE = async (
|
|
167
|
+
_request: NextRequest,
|
|
168
|
+
props: { params: Promise<{ assistantId: string; functionId: string }> },
|
|
169
|
+
) => {
|
|
170
|
+
const { assistantId, functionId } = await props.params
|
|
171
|
+
|
|
172
|
+
const headersList = await headers()
|
|
173
|
+
const authorization = headersList.get('authorization')
|
|
174
|
+
if (!authorization) {
|
|
175
|
+
return NextResponse.json(
|
|
176
|
+
{ error: 'No authorization header found' },
|
|
177
|
+
{ status: 400 },
|
|
178
|
+
)
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const privateApiKey = await getApiKey({
|
|
182
|
+
authorization,
|
|
183
|
+
type: ApiKeyType.PRIVATE,
|
|
184
|
+
})
|
|
185
|
+
|
|
186
|
+
if (!privateApiKey) {
|
|
187
|
+
return NextResponse.json({ error: 'Invalid api key' }, { status: 400 })
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (!validate(assistantId)) {
|
|
191
|
+
return NextResponse.json({ error: 'Invalid assistant id' }, { status: 400 })
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (!validate(functionId)) {
|
|
195
|
+
return NextResponse.json({ error: 'Invalid function id' }, { status: 400 })
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const fn = await prisma.function.findFirst({
|
|
199
|
+
where: {
|
|
200
|
+
id: functionId,
|
|
201
|
+
assistant: {
|
|
202
|
+
id: assistantId,
|
|
203
|
+
workspaceId: privateApiKey.workspaceId,
|
|
204
|
+
},
|
|
205
|
+
},
|
|
206
|
+
})
|
|
207
|
+
|
|
208
|
+
if (!fn) {
|
|
209
|
+
return NextResponse.json({ error: 'No function found' }, { status: 400 })
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
const deletedFunction = await prisma.function.delete({
|
|
213
|
+
where: { id: fn.id },
|
|
214
|
+
include: {
|
|
215
|
+
handler: {
|
|
216
|
+
include: {
|
|
217
|
+
requestHandler: true,
|
|
218
|
+
firecrawlHandler: true,
|
|
219
|
+
replicateHandler: true,
|
|
220
|
+
clientToolHandler: true,
|
|
221
|
+
assistantHandler: true,
|
|
222
|
+
createTaskHandler: true,
|
|
223
|
+
listTasksHandler: true,
|
|
224
|
+
updateTaskHandler: true,
|
|
225
|
+
deleteTaskHandler: true,
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
},
|
|
229
|
+
})
|
|
230
|
+
|
|
231
|
+
return NextResponse.json(
|
|
232
|
+
{
|
|
233
|
+
mcpServer: serializeApiFunction({ fn: deletedFunction }),
|
|
234
|
+
},
|
|
235
|
+
{ headers: cacheHeaders },
|
|
236
|
+
)
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
export const OPTIONS = () =>
|
|
240
|
+
NextResponse.json(
|
|
241
|
+
{},
|
|
242
|
+
{
|
|
243
|
+
headers: cacheHeaders,
|
|
244
|
+
},
|
|
245
|
+
)
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { type NextRequest, NextResponse } from 'next/server'
|
|
2
|
+
import { ApiKeyType } from '@prisma/client'
|
|
3
|
+
import { headers } from 'next/headers'
|
|
4
|
+
import { cacheHeaders } from '@/lib/cache/cacheHeaders'
|
|
5
|
+
import { prisma } from '@/lib/prisma'
|
|
6
|
+
import { getApiKey } from '@/lib/apiKeys/getApiKey'
|
|
7
|
+
import { serializeApiFunction } from '@/lib/functions/serializeApiFunction'
|
|
8
|
+
import { functionSchema } from '@/lib/functions/functionSchema'
|
|
9
|
+
import { createFunction } from '@/lib/functions/createFunction'
|
|
10
|
+
|
|
11
|
+
export const GET = async (
|
|
12
|
+
_request: NextRequest,
|
|
13
|
+
props: { params: Promise<{ assistantId: string }> },
|
|
14
|
+
) => {
|
|
15
|
+
const { assistantId } = await props.params
|
|
16
|
+
|
|
17
|
+
const headersList = await headers()
|
|
18
|
+
const authorization = headersList.get('authorization')
|
|
19
|
+
if (!authorization) {
|
|
20
|
+
return NextResponse.json(
|
|
21
|
+
{ error: 'No authorization header found' },
|
|
22
|
+
{ status: 400 },
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const privateApiKey = await getApiKey({
|
|
27
|
+
type: ApiKeyType.PRIVATE,
|
|
28
|
+
authorization,
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
if (!privateApiKey) {
|
|
32
|
+
return NextResponse.json({ error: 'Invalid api key' }, { status: 400 })
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const assistant = await prisma.assistant.findFirst({
|
|
36
|
+
where: {
|
|
37
|
+
id: assistantId,
|
|
38
|
+
workspaceId: privateApiKey.workspaceId,
|
|
39
|
+
},
|
|
40
|
+
include: {
|
|
41
|
+
functions: {
|
|
42
|
+
include: {
|
|
43
|
+
handler: {
|
|
44
|
+
include: {
|
|
45
|
+
requestHandler: true,
|
|
46
|
+
firecrawlHandler: true,
|
|
47
|
+
replicateHandler: true,
|
|
48
|
+
clientToolHandler: true,
|
|
49
|
+
assistantHandler: true,
|
|
50
|
+
createTaskHandler: true,
|
|
51
|
+
listTasksHandler: true,
|
|
52
|
+
updateTaskHandler: true,
|
|
53
|
+
deleteTaskHandler: true,
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
orderBy: {
|
|
58
|
+
createdAt: 'desc',
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
if (!assistant) {
|
|
65
|
+
return NextResponse.json({ error: 'No assistant found' }, { status: 400 })
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return NextResponse.json(
|
|
69
|
+
{
|
|
70
|
+
functions: assistant.functions.map((fn) =>
|
|
71
|
+
serializeApiFunction({
|
|
72
|
+
fn,
|
|
73
|
+
}),
|
|
74
|
+
),
|
|
75
|
+
},
|
|
76
|
+
{ headers: cacheHeaders },
|
|
77
|
+
)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export const POST = async (
|
|
81
|
+
request: NextRequest,
|
|
82
|
+
props: { params: Promise<{ assistantId: string }> },
|
|
83
|
+
) => {
|
|
84
|
+
const { assistantId } = await props.params
|
|
85
|
+
|
|
86
|
+
const headersList = await headers()
|
|
87
|
+
const authorization = headersList.get('authorization')
|
|
88
|
+
if (!authorization) {
|
|
89
|
+
return NextResponse.json(
|
|
90
|
+
{ error: 'No authorization header found' },
|
|
91
|
+
{ status: 400 },
|
|
92
|
+
)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const privateApiKey = await getApiKey({
|
|
96
|
+
authorization,
|
|
97
|
+
type: ApiKeyType.PRIVATE,
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
if (!privateApiKey) {
|
|
101
|
+
return NextResponse.json({ error: 'Invalid api key' }, { status: 400 })
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const assistant = await prisma.assistant.findFirst({
|
|
105
|
+
where: {
|
|
106
|
+
id: assistantId,
|
|
107
|
+
workspaceId: privateApiKey.workspaceId,
|
|
108
|
+
},
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
if (!assistant) {
|
|
112
|
+
return NextResponse.json({ error: 'No assistant found' }, { status: 400 })
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const body = await request.json()
|
|
116
|
+
const parsed = functionSchema.safeParse(body)
|
|
117
|
+
|
|
118
|
+
if (!parsed.success) {
|
|
119
|
+
console.error('Function creation error:', parsed.error)
|
|
120
|
+
return NextResponse.json({ error: 'Invalid payload' }, { status: 400 })
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const fn = await createFunction({
|
|
124
|
+
parsedInput: parsed.data,
|
|
125
|
+
assistant,
|
|
126
|
+
include: {
|
|
127
|
+
handler: {
|
|
128
|
+
include: {
|
|
129
|
+
requestHandler: true,
|
|
130
|
+
firecrawlHandler: true,
|
|
131
|
+
replicateHandler: true,
|
|
132
|
+
clientToolHandler: true,
|
|
133
|
+
assistantHandler: true,
|
|
134
|
+
createTaskHandler: true,
|
|
135
|
+
listTasksHandler: true,
|
|
136
|
+
updateTaskHandler: true,
|
|
137
|
+
deleteTaskHandler: true,
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
return NextResponse.json(
|
|
144
|
+
{
|
|
145
|
+
function: serializeApiFunction({ fn }),
|
|
146
|
+
},
|
|
147
|
+
{ headers: cacheHeaders },
|
|
148
|
+
)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export const OPTIONS = () =>
|
|
152
|
+
NextResponse.json(
|
|
153
|
+
{},
|
|
154
|
+
{
|
|
155
|
+
headers: cacheHeaders,
|
|
156
|
+
},
|
|
157
|
+
)
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { type NextRequest, NextResponse } from 'next/server'
|
|
2
|
+
import { ApiKeyType, InitialMessage } from '@prisma/client'
|
|
3
|
+
import { headers } from 'next/headers'
|
|
4
|
+
import { cacheHeaders } from '@/lib/cache/cacheHeaders'
|
|
5
|
+
import { prisma } from '@/lib/prisma'
|
|
6
|
+
import { serializeApiInitialMessage } from '@/lib/initialMessages/serializeApiInitialMessage'
|
|
7
|
+
import { initialMessagesSchema } from '@/lib/initialMessages/schema'
|
|
8
|
+
import { updateInitialMessages } from '@/lib/initialMessages/updateInitialMessages'
|
|
9
|
+
import { getApiKey } from '@/lib/apiKeys/getApiKey'
|
|
10
|
+
|
|
11
|
+
export const GET = async (
|
|
12
|
+
_request: NextRequest,
|
|
13
|
+
props: { params: Promise<{ assistantId: string }> },
|
|
14
|
+
) => {
|
|
15
|
+
const { assistantId } = await props.params
|
|
16
|
+
|
|
17
|
+
const headersList = await headers()
|
|
18
|
+
const authorization = headersList.get('authorization')
|
|
19
|
+
if (!authorization) {
|
|
20
|
+
return NextResponse.json(
|
|
21
|
+
{ error: 'No authorization header found' },
|
|
22
|
+
{ status: 400 },
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const privateApiKey = await getApiKey({
|
|
27
|
+
type: ApiKeyType.PRIVATE,
|
|
28
|
+
authorization,
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
if (!privateApiKey) {
|
|
32
|
+
return NextResponse.json({ error: 'Invalid api key' }, { status: 400 })
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const assistant = await prisma.assistant.findFirst({
|
|
36
|
+
where: {
|
|
37
|
+
id: assistantId,
|
|
38
|
+
workspaceId: privateApiKey.workspaceId,
|
|
39
|
+
},
|
|
40
|
+
include: {
|
|
41
|
+
initialMessages: {
|
|
42
|
+
orderBy: {
|
|
43
|
+
orderNumber: 'asc',
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
if (!assistant) {
|
|
50
|
+
return NextResponse.json({ error: 'No assistant found' }, { status: 400 })
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return NextResponse.json(
|
|
54
|
+
{
|
|
55
|
+
initialMessages: assistant.initialMessages.map((m) =>
|
|
56
|
+
serializeApiInitialMessage({ initialMessage: m }),
|
|
57
|
+
),
|
|
58
|
+
},
|
|
59
|
+
{ headers: cacheHeaders },
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export const PUT = async (
|
|
64
|
+
request: NextRequest,
|
|
65
|
+
props: { params: Promise<{ assistantId: string }> },
|
|
66
|
+
) => {
|
|
67
|
+
const { assistantId } = await props.params
|
|
68
|
+
|
|
69
|
+
const headersList = await headers()
|
|
70
|
+
const authorization = headersList.get('authorization')
|
|
71
|
+
if (!authorization) {
|
|
72
|
+
return NextResponse.json(
|
|
73
|
+
{ error: 'No authorization header found' },
|
|
74
|
+
{ status: 400 },
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const privateApiKey = await getApiKey({
|
|
79
|
+
authorization,
|
|
80
|
+
type: ApiKeyType.PRIVATE,
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
if (!privateApiKey) {
|
|
84
|
+
return NextResponse.json({ error: 'Invalid api key' }, { status: 400 })
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const body = await request.json()
|
|
88
|
+
const bodyParse = initialMessagesSchema.safeParse(body)
|
|
89
|
+
|
|
90
|
+
if (!bodyParse.success) {
|
|
91
|
+
return NextResponse.json({ error: 'Invalid body' }, { status: 400 })
|
|
92
|
+
}
|
|
93
|
+
const { initialMessages } = bodyParse.data
|
|
94
|
+
|
|
95
|
+
const assistant = await prisma.assistant.findFirst({
|
|
96
|
+
where: {
|
|
97
|
+
id: assistantId,
|
|
98
|
+
workspaceId: privateApiKey.workspaceId,
|
|
99
|
+
},
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
if (!assistant) {
|
|
103
|
+
return NextResponse.json({ error: 'No assistant found' }, { status: 400 })
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const messages = await updateInitialMessages({
|
|
107
|
+
assistantId: assistant.id,
|
|
108
|
+
initialMessages,
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
return NextResponse.json(
|
|
112
|
+
{
|
|
113
|
+
initialMessages: messages.map((m: InitialMessage) =>
|
|
114
|
+
serializeApiInitialMessage({ initialMessage: m }),
|
|
115
|
+
),
|
|
116
|
+
},
|
|
117
|
+
{ headers: cacheHeaders },
|
|
118
|
+
)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export const OPTIONS = () =>
|
|
122
|
+
NextResponse.json(
|
|
123
|
+
{},
|
|
124
|
+
{
|
|
125
|
+
headers: cacheHeaders,
|
|
126
|
+
},
|
|
127
|
+
)
|