Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
99 commits
Select commit Hold shift + click to select a range
66af47d
Enhance documentation tools integration
mantrakp04 Mar 23, 2026
30d53e8
Merge branch 'dev' into dario-likes-mcps
mantrakp04 Mar 23, 2026
5078747
Enhance error handling and API response for documentation tools
mantrakp04 Mar 24, 2026
aaf49db
Merge branch 'dev' into dario-likes-mcps
mantrakp04 Mar 24, 2026
844e916
Refactor askStackAuth key to ask_stack_auth in API documentation
mantrakp04 Mar 24, 2026
274c742
fix: register private submodule gitlink in the index
mantrakp04 Mar 25, 2026
c7a3cca
Merge branch 'dev' into dario-likes-mcps
mantrakp04 Mar 25, 2026
ef2289f
Merge branch 'dev' into dario-likes-mcps
mantrakp04 Apr 3, 2026
d8065c4
Update environment configurations and remove internal secret validati…
mantrakp04 Apr 4, 2026
3b27eee
Merge branch 'dev' into dario-likes-mcps
mantrakp04 Apr 6, 2026
b82efa4
Merge branch 'dev' into dario-likes-mcps
mantrakp04 Apr 6, 2026
158498b
Merge branch 'dev' into dario-likes-mcps
mantrakp04 Apr 8, 2026
b22d4b0
Merge branch 'dev' into dario-likes-mcps
mantrakp04 Apr 9, 2026
95ca0a2
initial commit
aadesh18 Apr 10, 2026
fbab066
Merge remote-tracking branch 'origin/dario-likes-mcps' into llm-mcp-flow
aadesh18 Apr 10, 2026
73152a1
pnpm lock
aadesh18 Apr 10, 2026
e16040c
changed port
aadesh18 Apr 10, 2026
a07dbab
spacetime db ci change
aadesh18 Apr 10, 2026
ef77edc
ci fix
aadesh18 Apr 10, 2026
84dffa2
security fix
aadesh18 Apr 10, 2026
a0486e9
security fixes
aadesh18 Apr 11, 2026
8c596ec
Merge branch 'dev' into dario-likes-mcps
mantrakp04 Apr 12, 2026
ef6963d
Merge branch 'dev' into dario-likes-mcps
N2D4 Apr 12, 2026
1c69185
Merge branch 'dario-likes-mcps' into llm-mcp-flow
aadesh18 Apr 12, 2026
f794bd6
Merge remote-tracking branch 'origin/dev' into llm-mcp-flow
aadesh18 Apr 12, 2026
59a060a
merge error
aadesh18 Apr 13, 2026
0485c73
pr comment changes
aadesh18 Apr 13, 2026
97ee052
Merge branch 'dev' into llm-mcp-flow
aadesh18 Apr 13, 2026
411f775
bug fix
aadesh18 Apr 13, 2026
c514efd
Merge branch 'llm-mcp-flow' of https://github.com/stack-auth/stack-au…
aadesh18 Apr 13, 2026
516c424
Merge branch 'dev' into llm-mcp-flow
aadesh18 Apr 13, 2026
b0e3341
pr comments
aadesh18 Apr 13, 2026
a630be1
Merge branch 'llm-mcp-flow' of https://github.com/stack-auth/stack-au…
aadesh18 Apr 13, 2026
8c7bc54
tests failing
aadesh18 Apr 13, 2026
7a54be9
comment changes
aadesh18 Apr 13, 2026
bd3925d
Merge branch 'dev' into llm-mcp-flow
aadesh18 Apr 13, 2026
ca461d4
tests fix
aadesh18 Apr 13, 2026
224468c
Merge branch 'llm-mcp-flow' of https://github.com/stack-auth/stack-au…
aadesh18 Apr 13, 2026
042e616
tests fix
aadesh18 Apr 13, 2026
149d6d7
fixed the order
aadesh18 Apr 13, 2026
574cc4a
Merge branch 'dev' into llm-mcp-flow
aadesh18 Apr 13, 2026
3293845
Merge branch 'dev' into llm-mcp-flow
aadesh18 Apr 13, 2026
d8e99d6
Merge branch 'dev' into llm-mcp-flow
aadesh18 Apr 14, 2026
fa4c814
Merge branch 'dev' into llm-mcp-flow
aadesh18 Apr 14, 2026
a4c3306
pr changes
aadesh18 Apr 14, 2026
35739af
Merge branch 'dev' into llm-mcp-flow
aadesh18 Apr 14, 2026
15e5879
Merge remote-tracking branch 'origin/dev' into llm-mcp-flow
aadesh18 Apr 15, 2026
140ee7e
Merge branch 'dev' into llm-mcp-flow
aadesh18 Apr 15, 2026
afd84bc
minor fix
aadesh18 Apr 15, 2026
b0a329f
initial commit
aadesh18 Apr 15, 2026
c819537
proxy logging implemented
aadesh18 Apr 15, 2026
7a2332f
Merge remote-tracking branch 'origin/dev' into ai-analytics
aadesh18 Apr 15, 2026
83a37d1
pr message fixes
aadesh18 Apr 17, 2026
4fb5154
internal tool security update
aadesh18 Apr 19, 2026
30e3e5c
Merge branch 'dev' into ai-analytics
aadesh18 Apr 19, 2026
edd33b1
added e2e tests
aadesh18 Apr 20, 2026
a43eb11
bot comment
aadesh18 Apr 20, 2026
1ccef9c
Update seed function to preserve existing user metadata when updating…
aadesh18 Apr 20, 2026
4965534
refactor: replace callReducer with callReducerStrict for improved err…
aadesh18 Apr 20, 2026
9ba7b5e
clean up
aadesh18 Apr 20, 2026
ddde9c6
feat: implement timeout for SpacetimeDB HTTP calls to prevent hanging…
aadesh18 Apr 20, 2026
c329a46
fix: improve error handling for missing SpacetimeDB service token in …
aadesh18 Apr 20, 2026
26ce83f
fix: encode URI components in fetch requests to prevent errors with s…
aadesh18 Apr 20, 2026
f9386a8
bot fixes
aadesh18 Apr 20, 2026
dc5ab66
fix: add log token retrieval in getServiceToken function
aadesh18 Apr 20, 2026
2532632
fix: enhance error handling in isSpacetimedbReachable and update priv…
aadesh18 Apr 20, 2026
53a9f2c
fix: update footer separator in ConversationReplay component for impr…
aadesh18 Apr 20, 2026
0eff6b2
bug fix
aadesh18 Apr 20, 2026
170b4fe
fix: refactor MCP review authorization and improve logging mechanisms
aadesh18 Apr 21, 2026
a0bab5d
tests clean up
aadesh18 Apr 21, 2026
3654af5
Merge remote-tracking branch 'origin/dev' into ai-analytics
aadesh18 Apr 21, 2026
dbc7988
bug fix
aadesh18 Apr 21, 2026
d8b7499
Custom Dashboard Improvements (#1359)
aadesh18 Apr 24, 2026
331d208
Update backend environment variables and refactor AI query route imports
aadesh18 Apr 28, 2026
49d2c04
Enhance image attachment validation in AI query route
aadesh18 Apr 28, 2026
60c538b
Add context to system prompt in AI query route
aadesh18 Apr 28, 2026
0aea8ef
edited comment
aadesh18 Apr 28, 2026
39facf4
added comment
aadesh18 Apr 28, 2026
45ff5f2
aman comment changes
aadesh18 May 4, 2026
89d43b1
Merge remote-tracking branch 'origin/dev' into ai-analytics
aadesh18 May 4, 2026
971bad9
merge changes
aadesh18 May 4, 2026
16542f1
removed mcpCorrelationId
aadesh18 May 5, 2026
10e6cfc
Enhance qaId validation in MCP review routes to ensure it is a non-ne…
aadesh18 May 5, 2026
5552bd7
Refactor reviewer handling in MCP review route to improve readability…
aadesh18 May 5, 2026
2e78347
Implement update_qa_entry_with_publish reducer to streamline QA entry…
aadesh18 May 5, 2026
0cedc49
Refactor AI query logging to handle serialization errors gracefully a…
aadesh18 May 5, 2026
a087f6b
Refactor AI query logging to encapsulate error handling within async …
aadesh18 May 5, 2026
7e850db
Update tool call instructions in AI prompts to specify usage of patch…
aadesh18 May 5, 2026
7527bcf
Enhance occurrenceIndex validation in applyDashboardPatches to ensure…
aadesh18 May 5, 2026
cfcedeb
Refactor applyDashboardPatches to use 'draft' instead of 'running' fo…
aadesh18 May 5, 2026
9500e1e
sizing fix
aadesh18 May 5, 2026
9599254
Merge branch 'dev' into ai-analytics
aadesh18 May 6, 2026
c664a1d
Merge remote-tracking branch 'origin/dev' into ai-analytics
aadesh18 May 8, 2026
1389d37
lint fix
aadesh18 May 8, 2026
185d245
update reviewer authentication and API calls
aadesh18 May 11, 2026
29a6a88
Merge remote-tracking branch 'origin/dev' into ai-analytics
aadesh18 May 11, 2026
d63bb9c
test fix
aadesh18 May 12, 2026
6b8838e
Merge branch 'dev' into ai-analytics
aadesh18 May 12, 2026
26f0ff6
bot comments
aadesh18 May 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
initial commit
  • Loading branch information
aadesh18 committed Apr 10, 2026
commit 95ca0a29618677633a24c83724e52b4eacdee8b6
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
[![Stack Logo](/.github/assets/logo.png)](https://stack-auth.com)

[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/stack-auth/stack-auth)

<h3 align="center">
<a href="https://docs.stack-auth.com">📘 Docs</a>
| <a href="https://stack-auth.com/">☁️ Hosted Version</a>
Expand Down
5 changes: 5 additions & 0 deletions apps/backend/.env
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,8 @@ STACK_TELEGRAM_CHAT_ID=# enter your telegram chat id

# Docs AI tool bundle
STACK_DOCS_INTERNAL_BASE_URL=# override the docs origin used by the backend's AI tool bundle to call the docs app's `/api/internal/docs-tools` endpoint. Defaults to http://localhost:${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}04 in dev, https://mcp.stack-auth.com in prod

# MCP review tool (SpacetimeDB)
STACK_SPACETIMEDB_URI=# SpacetimeDB host URI; default empty (logging disabled)
STACK_SPACETIMEDB_DB_NAME=# SpacetimeDB database name
STACK_MCP_LOG_TOKEN=# shared secret gating the log_mcp_call reducer; must match EXPECTED_LOG_TOKEN in apps/internal-tool/spacetimedb/src/index.ts
5 changes: 5 additions & 0 deletions apps/backend/.env.development
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,11 @@ STACK_QSTASH_TOKEN=eyJVc2VySUQiOiJkZWZhdWx0VXNlciIsIlBhc3N3b3JkIjoiZGVmYXVsdFBhc
STACK_QSTASH_CURRENT_SIGNING_KEY=sig_7kYjw48mhY7kAjqNGcy6cr29RJ6r
STACK_QSTASH_NEXT_SIGNING_KEY=sig_5ZB6DVzB1wjE8S6rZ7eenA8Pdnhs

# MCP review tool (SpacetimeDB)
STACK_SPACETIMEDB_URI=ws://localhost:${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}39
STACK_SPACETIMEDB_DB_NAME=stack-auth-llm
STACK_MCP_LOG_TOKEN=change-me

# Clickhouse
STACK_CLICKHOUSE_URL=http://localhost:${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}36
STACK_CLICKHOUSE_ADMIN_USER=stackframe
Expand Down
1 change: 1 addition & 0 deletions apps/backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
},
"dependencies": {
"@ai-sdk/mcp": "^1.0.21",
"spacetimedb": "^2.1.0",
"@ai-sdk/openai": "^3.0.29",
"@aws-sdk/client-s3": "^3.855.0",
"@clickhouse/client": "^1.14.0",
Expand Down
53 changes: 50 additions & 3 deletions apps/backend/src/app/api/latest/ai/query/[mode]/route.ts
Comment thread
nams1570 marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ import { getEnvVariable } from "@stackframe/stack-shared/dist/utils/env";
import { StatusError } from "@stackframe/stack-shared/dist/utils/errors";
import { Json } from "@stackframe/stack-shared/dist/utils/json";
import { generateText, ModelMessage, stepCountIs, streamText } from "ai";
import { logMcpCall } from "@/lib/ai/mcp-logger";
import { reviewMcpCall } from "@/lib/ai/qa-reviewer";
import { getVerifiedQaContext } from "@/lib/ai/verified-qa";
import { runAsynchronously } from "@stackframe/stack-shared/dist/utils/promises";

export const POST = createSmartRouteHandler({
metadata: {
Expand Down Expand Up @@ -61,10 +65,13 @@ export const POST = createSmartRouteHandler({
}

const model = selectModel(quality, speed, isAuthenticated);
const systemPrompt = getFullSystemPrompt(systemPromptId);
const isDocsOrSearch = systemPromptId === "docs-ask-ai" || systemPromptId === "command-center-ask-ai";
let systemPrompt = getFullSystemPrompt(systemPromptId);
if (isDocsOrSearch) {
systemPrompt += await getVerifiedQaContext();
}
const tools = await getTools(toolNames, { auth: fullReq.auth, targetProjectId: projectId });
const toolsArg = Object.keys(tools).length > 0 ? tools : undefined;
const isDocsOrSearch = systemPromptId === "docs-ask-ai" || systemPromptId === "command-center-ask-ai";
const stepLimit = toolsArg == null ? 1 : isDocsOrSearch ? 50 : 5;

if (mode === "stream") {
Expand All @@ -81,6 +88,7 @@ export const POST = createSmartRouteHandler({
body: result.toUIMessageStreamResponse(),
};
} else {
const startedAt = Date.now();
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 120_000);
const result = await generateText({
Expand Down Expand Up @@ -129,10 +137,49 @@ export const POST = createSmartRouteHandler({
});
});

let responseConversationId: string | undefined;
if (body.mcpCallMetadata != null) {
const correlationId = crypto.randomUUID();
const conversationId = body.mcpCallMetadata.conversationId ?? crypto.randomUUID();
responseConversationId = conversationId;
const firstUserMessage = messages.find(m => m.role === "user");
const question = typeof firstUserMessage?.content === "string"
? firstUserMessage.content
: JSON.stringify(firstUserMessage?.content ?? "");

const innerToolCallsJson = JSON.stringify(contentBlocks.filter(b => b.type === "tool-call"));

runAsynchronously(logMcpCall({
correlationId,
toolName: body.mcpCallMetadata.toolName,
reason: body.mcpCallMetadata.reason,
userPrompt: body.mcpCallMetadata.userPrompt,
conversationId,
question,
response: result.text,
stepCount: result.steps.length,
innerToolCallsJson,
durationMs: BigInt(Date.now() - startedAt),
modelId: String(model.modelId),
errorMessage: undefined,
}));

runAsynchronously(reviewMcpCall({
correlationId,
question,
reason: body.mcpCallMetadata.reason,
response: result.text,
}));
}

return {
statusCode: 200,
bodyType: "json" as const,
body: { content: contentBlocks, finalText: result.text },
body: {
content: contentBlocks,
finalText: result.text,
conversationId: responseConversationId ?? null,
},
};
}
},
Expand Down
51 changes: 51 additions & 0 deletions apps/backend/src/lib/ai/mcp-logger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { getEnvVariable } from "@stackframe/stack-shared/dist/utils/env";
import { captureError } from "@stackframe/stack-shared/dist/utils/errors";
import { DbConnection } from "./spacetimedb-bindings";
import type { LogMcpCallParams } from "./spacetimedb-bindings/types/reducers";

export type McpLogEntry = Omit<LogMcpCallParams, "token">;

let connectionPromise: Promise<DbConnection> | null = null;

export async function getConnection(): Promise<DbConnection | null> {
const uri = getEnvVariable("STACK_SPACETIMEDB_URI", "");
if (!uri) {
return null;
}

if (!connectionPromise) {
connectionPromise = new Promise<DbConnection>((resolve, reject) => {
DbConnection.builder()
.withUri(uri)
.withDatabaseName(getEnvVariable("STACK_SPACETIMEDB_DB_NAME"))
.onConnect((connInstance) => {
connInstance.subscriptionBuilder()
.onApplied(() => {
resolve(connInstance);
})
.subscribe("SELECT * FROM mcp_call_log");
})
.onConnectError((_: unknown, err: Error) => {
captureError("mcp-logger", err);
connectionPromise = null;
reject(err);
})
.build();
});
}

return await connectionPromise;
}

export async function logMcpCall(entry: McpLogEntry): Promise<void> {
const conn = await getConnection();
if (!conn) {
return;
}

const token = getEnvVariable("STACK_MCP_LOG_TOKEN");
await conn.reducers.logMcpCall({
token,
...entry,
});
}
11 changes: 6 additions & 5 deletions apps/backend/src/lib/ai/prompts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,12 @@ You are Stack Auth's AI assistant. You help users with Stack Auth - a complete a

Think step by step about what to say. Being wrong is 100x worse than saying you don't know.

## TOOL USAGE WORKFLOW:
1. **FIRST**, use \`search_docs\` with relevant keywords to find related documentation
2. **THEN**, use \`get_docs_by_id\` to retrieve the full content of the most relevant pages
3. Base your answer on the actual documentation content retrieved
4. When referring to API endpoints, **always cite the actual endpoint** (e.g., "GET /users/me") not the documentation URL
## PRIORITY ORDER:
1. **FIRST**, check the Human-Verified Knowledge Base (appended at the end of this prompt, if any). If the user's question matches or is similar to a verified Q&A, use that answer exactly — do not search docs or use any other source.
2. **THEN**, use \`search_docs\` with relevant keywords to find related documentation
3. **THEN**, use \`get_docs_by_id\` to retrieve the full content of the most relevant pages
4. Base your answer on the actual documentation content retrieved
5. When referring to API endpoints, **always cite the actual endpoint** (e.g., "GET /users/me") not the documentation URL

## CORE RESPONSIBILITIES:
1. Help users implement Stack Auth in their applications
Expand Down
172 changes: 172 additions & 0 deletions apps/backend/src/lib/ai/qa-reviewer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
import { createMCPClient } from "@ai-sdk/mcp";
import { getEnvVariable } from "@stackframe/stack-shared/dist/utils/env";
import { captureError } from "@stackframe/stack-shared/dist/utils/errors";
import { generateText, stepCountIs } from "ai";
import { getConnection } from "./mcp-logger";
import { createOpenRouterProvider } from "./models";
import { getVerifiedQaContext } from "./verified-qa";

const QA_SYSTEM_PROMPT = `You are a QA reviewer for Stack Auth's AI documentation assistant.
You will receive a question, the agent's stated reason for asking, and the AI's response.

Your tasks:
1. RELEVANCE: Does the response actually answer the question? Does the stated reason align with what was asked?
2. CORRECTNESS: Verify factual claims about Stack Auth. Use human-verified Q&A (appended below, if any) as the highest-priority source of truth — these are always correct. Then use the available tools to look up additional information from the Stack Auth codebase. If the AI response contradicts a human-verified answer, flag it as incorrect.

The repo name for all tool calls is "stack-auth/stack-auth". Only use the repository documentation tools (read_wiki_structure, read_wiki_contents, ask_question) — do not create sessions or modify any other resources.

You MUST respond with ONLY valid JSON matching this exact schema (no markdown, no explanation outside the JSON):
{
"needsHumanReview": boolean,
"answerCorrect": boolean,
"answerRelevant": boolean,
"flags": [{"type": string, "severity": "low" | "medium" | "high" | "critical", "explanation": string}],
"improvementSuggestions": string,
"overallScore": number
}

Flag types: "factual_error", "incomplete_answer", "off_topic", "hallucination", "outdated_info", "missing_context", "misleading", "reason_mismatch"

Scoring:
- 90-100: Excellent — factually correct, fully addresses the question
- 70-89: Good — minor issues or missing details
- 50-69: Acceptable — notable issues but core answer is present
- 30-49: Poor — significant problems
- 0-29: Unacceptable — fundamentally wrong or irrelevant

Set needsHumanReview=true if: score < 50, any critical flag, or you are uncertain about correctness.`;

const REVIEW_MODEL_ID = "anthropic/claude-haiku-4.5";

export async function reviewMcpCall(entry: {
correlationId: string;
question: string;
reason: string;
response: string;
}): Promise<void> {
const apiKey = getEnvVariable("STACK_OPENROUTER_API_KEY", "");
if (!apiKey || apiKey === "FORWARD_TO_PRODUCTION") {
return;
}

let devinClient: Awaited<ReturnType<typeof createMCPClient>> | null = null;

const failureUpdate = (err: unknown) => ({
qaNeedsHumanReview: true,
qaAnswerCorrect: false,
qaAnswerRelevant: false,
qaFlagsJson: "[]",
qaImprovementSuggestions: "",
qaOverallScore: 0,
qaConversationJson: undefined,
qaErrorMessage: String(err),
});

let update: {
qaNeedsHumanReview: boolean,
qaAnswerCorrect: boolean,
qaAnswerRelevant: boolean,
qaFlagsJson: string,
qaImprovementSuggestions: string,
qaOverallScore: number,
qaConversationJson: string | undefined,
qaErrorMessage: string | undefined,
};

try {
// Wait for the log row to be written first
await new Promise(r => setTimeout(r, 3000));

devinClient = await createMCPClient({
transport: {
type: "http",
url: "https://mcp.deepwiki.com/mcp",
},
});

const devinTools = await devinClient.tools();
const openrouter = createOpenRouterProvider();
const model = openrouter(REVIEW_MODEL_ID);

const userMessage = [
"## Question",
entry.question,
"",
"## Agent's Reason for Asking",
entry.reason,
"",
"## AI Response",
entry.response,
].join("\n");

const verifiedQa = await getVerifiedQaContext();

const result = await generateText({
model,
system: QA_SYSTEM_PROMPT + verifiedQa,
tools: devinTools as Parameters<typeof generateText>[0]["tools"],
stopWhen: stepCountIs(10),
messages: [{ role: "user", content: userMessage }],
});

const conversation = result.steps.map((step, i) => {
const toolCalls = step.toolCalls.map(tc => ({ toolName: tc.toolName, args: tc.input }));
const toolResults = step.toolResults.map(tr => ({
toolName: tr.toolName,
toolCallId: tr.toolCallId,
result: tr.output,
}));
return {
step: i + 1,
text: step.text || undefined,
toolCalls: toolCalls.length > 0 ? toolCalls : undefined,
toolResults: toolResults.length > 0 ? toolResults : undefined,
};
});

const jsonMatch = result.text.match(/\{[\s\S]*\}/);
if (!jsonMatch) {
throw new Error("No JSON found in QA review response");
}
const parsed = JSON.parse(jsonMatch[0]) as {
needsHumanReview: boolean,
answerCorrect: boolean,
answerRelevant: boolean,
flags: Array<{ type: string, severity: string, explanation: string }>,
improvementSuggestions: string,
overallScore: number,
};

update = {
qaNeedsHumanReview: parsed.needsHumanReview,
qaAnswerCorrect: parsed.answerCorrect,
qaAnswerRelevant: parsed.answerRelevant,
qaFlagsJson: JSON.stringify(parsed.flags),
qaImprovementSuggestions: parsed.improvementSuggestions,
qaOverallScore: parsed.overallScore,
qaConversationJson: JSON.stringify(conversation),
qaErrorMessage: undefined,
};
} catch (err) {
captureError("qa-reviewer", err instanceof Error ? err : new Error(String(err)));
update = failureUpdate(err);
}

if (devinClient) {
await devinClient.close().catch((err: unknown) => {
captureError("qa-reviewer", err instanceof Error ? err : new Error(String(err)));
});
}

const conn = await getConnection();
if (!conn) return;
const token = getEnvVariable("STACK_MCP_LOG_TOKEN");
await conn.reducers.updateMcpQaReview({
token,
correlationId: entry.correlationId,
qaReviewModelId: REVIEW_MODEL_ID,
...update,
}).catch((err: unknown) => {
captureError("qa-reviewer", err instanceof Error ? err : new Error(String(err)));
});
}
6 changes: 6 additions & 0 deletions apps/backend/src/lib/ai/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ export const requestBodySchema = yupObject({
}).defined()
).defined().min(1),
projectId: yupString().optional().nullable(),
mcpCallMetadata: yupObject({
toolName: yupString().defined(),
reason: yupString().defined(),
userPrompt: yupString().defined(),
conversationId: yupString().optional().nullable(),
}).optional().nullable(),
Comment thread
aadesh18 marked this conversation as resolved.
});

export type RequestBody = InferType<typeof requestBodySchema>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.

/* eslint-disable */
/* tslint:disable */
import {
TypeBuilder as __TypeBuilder,
t as __t,
type AlgebraicTypeType as __AlgebraicTypeType,
type Infer as __Infer,
} from "spacetimedb";

export default {
question: __t.string(),
answer: __t.string(),
publish: __t.bool(),
reviewedBy: __t.string(),
};
Loading