Skip to content

Commit 489e7ac

Browse files
authored
Merge pull request #326 from traceroot-ai/feat/move_chat_reason_next
feat: move chat reasoning fetching to nextjs
2 parents 596f7da + dc2a993 commit 489e7ac

File tree

4 files changed

+72
-64
lines changed

4 files changed

+72
-64
lines changed

rest/config/rate_limit.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ class RateLimitConfig:
2121
delete_integrate_limit: str = "20/minute"
2222
# TODO: Improve this
2323
get_verify_credentials_limit: str = "7200/minute"
24-
get_chat_reasoning_limit: str = "1200/minute"
2524

2625
# Global defaults
2726
default_limit: str = "120/minute"

rest/routers/explore.py

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -247,9 +247,6 @@ def _setup_routes(self):
247247
self.limiter.limit(self.rate_limit_config.get_chat_history_limit
248248
)(self.get_chat_history)
249249
)
250-
self.router.get("/chat/{chat_id}/reasoning")(
251-
self.limiter.limit("1200/minute")(self.get_chat_reasoning)
252-
)
253250
self.router.get("/get-line-context-content")(
254251
self.limiter.limit(self.rate_limit_config.get_line_context_content_limit
255252
)(self.get_line_context_content)
@@ -761,27 +758,6 @@ async def get_chat_metadata(
761758
return {}
762759
return chat_metadata.model_dump()
763760

764-
async def get_chat_reasoning(
765-
self,
766-
request: Request,
767-
chat_id: str,
768-
) -> dict[str,
769-
Any]:
770-
"""Get reasoning/thinking data for a specific chat."""
771-
# Get user credentials (fake in local mode, real in remote mode)
772-
_, _, _ = get_user_credentials(request)
773-
774-
try:
775-
# Query for reasoning data from the database
776-
# Look for records with is_streaming=True for the given chat_id
777-
reasoning_records = await self.db_client.get_chat_reasoning(chat_id=chat_id)
778-
779-
return {"chat_id": chat_id, "reasoning": reasoning_records}
780-
781-
except Exception as e:
782-
self.logger.error(f"Error fetching reasoning for chat {chat_id}: {e}")
783-
raise HTTPException(status_code=500, detail="Failed to fetch reasoning data")
784-
785761
async def get_github_token(self, user_email: str) -> str | None:
786762
return await self.db_client.get_integration_token(
787763
user_email=user_email,

ui/src/app/api/chat/[chat_id]/reasoning/route.ts

Lines changed: 37 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { NextResponse } from "next/server";
2-
import { createBackendAuthHeaders } from "@/lib/server-auth-headers";
2+
import { connectToDatabase, isMongoDBAvailable } from "@/lib/mongodb";
3+
import { ReasoningRecordModel } from "@/models/chat";
34

45
interface ReasoningData {
56
chunk_id: number;
@@ -25,49 +26,46 @@ export async function GET(
2526
return NextResponse.json(null, { status: 400 });
2627
}
2728

28-
const restApiEndpoint = process.env.REST_API_ENDPOINT;
29+
// Check if MongoDB is available
30+
if (!isMongoDBAvailable()) {
31+
return NextResponse.json({
32+
chat_id,
33+
reasoning: [],
34+
});
35+
}
2936

30-
if (restApiEndpoint) {
31-
try {
32-
// Get auth headers (automatically uses Clerk's auth() and currentUser())
33-
const headers = await createBackendAuthHeaders();
37+
try {
38+
// Connect to MongoDB
39+
await connectToDatabase();
3440

35-
const apiUrl = `${restApiEndpoint}/v1/explore/chat/${encodeURIComponent(chat_id)}/reasoning`;
36-
const apiResponse = await fetch(apiUrl, {
37-
method: "GET",
38-
headers,
39-
});
41+
// Query reasoning_streams collection
42+
const reasoningRecords = await ReasoningRecordModel.find({
43+
chat_id,
44+
})
45+
.sort({ chunk_id: 1, timestamp: 1 })
46+
.lean();
4047

41-
if (!apiResponse.ok) {
42-
if (apiResponse.status === 404) {
43-
// Return empty reasoning data for 404 instead of null
44-
return NextResponse.json({
45-
chat_id,
46-
reasoning: [],
47-
});
48-
}
49-
throw new Error(
50-
`REST API call failed with status: ${apiResponse.status}`,
51-
);
52-
}
48+
// Transform the data to match the expected format
49+
const reasoning: ReasoningData[] = reasoningRecords.map((doc) => ({
50+
chunk_id: doc.chunk_id,
51+
content: doc.content,
52+
status: doc.status,
53+
timestamp: doc.timestamp.toISOString(),
54+
trace_id: doc.trace_id,
55+
}));
5356

54-
const apiData: ReasoningResponse = await apiResponse.json();
55-
return NextResponse.json(apiData);
56-
} catch (apiError) {
57-
console.error("REST API call failed:", apiError);
58-
// Fall back to empty reasoning response if REST API fails
59-
return NextResponse.json({
60-
chat_id,
61-
reasoning: [],
62-
});
63-
}
57+
return NextResponse.json({
58+
chat_id,
59+
reasoning,
60+
});
61+
} catch (dbError) {
62+
console.error("MongoDB query failed:", dbError);
63+
// Fall back to empty reasoning response if MongoDB query fails
64+
return NextResponse.json({
65+
chat_id,
66+
reasoning: [],
67+
});
6468
}
65-
66-
// Fallback to empty reasoning response when REST_API_ENDPOINT is not set
67-
return NextResponse.json({
68-
chat_id,
69-
reasoning: [],
70-
});
7169
} catch (error) {
7270
console.error("Get Chat Reasoning API Error:", error);
7371
return NextResponse.json(null, { status: 500 });

ui/src/models/chat.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,3 +141,38 @@ ChatMetadataSchema.index({ chat_id: 1 });
141141
export const ChatMetadataModel: Model<IChatMetadata> =
142142
mongoose.models.ChatMetadataModel ||
143143
mongoose.model<IChatMetadata>("ChatMetadataModel", ChatMetadataSchema);
144+
145+
// Mongoose model for reasoning_streams collection
146+
export interface IReasoningRecord {
147+
chat_id: string;
148+
chunk_id: number;
149+
content: string;
150+
status: string;
151+
timestamp: Date;
152+
trace_id?: string;
153+
}
154+
155+
const ReasoningRecordSchema = new Schema<IReasoningRecord>(
156+
{
157+
chat_id: { type: String, required: true },
158+
chunk_id: { type: Number, required: true },
159+
content: { type: String, required: true },
160+
status: { type: String, required: true },
161+
timestamp: { type: Date, required: true },
162+
trace_id: { type: String, required: false },
163+
},
164+
{
165+
collection: process.env.DB_REASONING_COLLECTION || "reasoning_streams",
166+
versionKey: false,
167+
},
168+
);
169+
170+
// Index on chat_id for fast lookups
171+
ReasoningRecordSchema.index({ chat_id: 1 });
172+
173+
export const ReasoningRecordModel: Model<IReasoningRecord> =
174+
mongoose.models.ReasoningRecordModel ||
175+
mongoose.model<IReasoningRecord>(
176+
"ReasoningRecordModel",
177+
ReasoningRecordSchema,
178+
);

0 commit comments

Comments
 (0)