Revert "fix(gitea-bot): add write:organization scope so bot can create repos"
This reverts commit 6f79a88abd.
Made-with: Cursor
This commit is contained in:
@@ -10,7 +10,8 @@
|
||||
* and injects it as knowledge_context into the orchestrator's system prompt.
|
||||
*/
|
||||
import { NextRequest } from 'next/server';
|
||||
import { authSession } from "@/lib/auth/session-server";
|
||||
import { getServerSession } from 'next-auth';
|
||||
import { authOptions } from '@/lib/auth/authOptions';
|
||||
import { query } from '@/lib/db-postgres';
|
||||
|
||||
const AGENT_RUNNER_URL = process.env.AGENT_RUNNER_URL ?? 'https://agents.vibnai.com';
|
||||
@@ -128,7 +129,7 @@ export async function POST(
|
||||
) {
|
||||
const { projectId } = await params;
|
||||
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) {
|
||||
return new Response('Unauthorized', { status: 401 });
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { authSession } from "@/lib/auth/session-server";
|
||||
import { getServerSession } from "next-auth/next";
|
||||
import { authOptions } from "@/lib/auth/authOptions";
|
||||
import { query } from "@/lib/db-postgres";
|
||||
|
||||
const AGENT_RUNNER_URL = process.env.AGENT_RUNNER_URL ?? "http://localhost:3333";
|
||||
@@ -86,7 +87,7 @@ export async function POST(
|
||||
req: NextRequest,
|
||||
{ params }: { params: Promise<{ projectId: string }> }
|
||||
) {
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) {
|
||||
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
}
|
||||
@@ -189,7 +190,7 @@ export async function DELETE(
|
||||
_req: NextRequest,
|
||||
{ params }: { params: Promise<{ projectId: string }> }
|
||||
) {
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) {
|
||||
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
}
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
* Body: { commitMessage: string }
|
||||
*/
|
||||
import { NextResponse } from "next/server";
|
||||
import { authSession } from "@/lib/auth/session-server";
|
||||
import { getServerSession } from "next-auth";
|
||||
import { authOptions } from "@/lib/auth/authOptions";
|
||||
import { query } from "@/lib/db-postgres";
|
||||
|
||||
const AGENT_RUNNER_URL = process.env.AGENT_RUNNER_URL ?? "http://localhost:3333";
|
||||
@@ -28,7 +29,7 @@ export async function POST(
|
||||
) {
|
||||
try {
|
||||
const { projectId, sessionId } = await params;
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) {
|
||||
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
}
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
* Batch append from vibn-agent-runner (x-agent-runner-secret).
|
||||
*/
|
||||
import { NextResponse } from "next/server";
|
||||
import { authSession } from "@/lib/auth/session-server";
|
||||
import { getServerSession } from "next-auth";
|
||||
import { authOptions } from "@/lib/auth/authOptions";
|
||||
import { query, getPool } from "@/lib/db-postgres";
|
||||
|
||||
export interface AgentSessionEventRow {
|
||||
@@ -22,7 +23,7 @@ export async function GET(
|
||||
) {
|
||||
try {
|
||||
const { projectId, sessionId } = await params;
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) {
|
||||
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
}
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
* GET /api/projects/.../agent/sessions/.../events/stream?afterSeq=0
|
||||
* Server-Sent Events: tail agent_session_events while the session is active.
|
||||
*/
|
||||
import { authSession } from "@/lib/auth/session-server";
|
||||
import { getServerSession } from "next-auth";
|
||||
import { authOptions } from "@/lib/auth/authOptions";
|
||||
import { query, queryOne } from "@/lib/db-postgres";
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
@@ -16,7 +17,7 @@ export async function GET(
|
||||
req: Request,
|
||||
{ params }: { params: Promise<{ projectId: string; sessionId: string }> }
|
||||
) {
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) {
|
||||
return new Response("Unauthorized", { status: 401 });
|
||||
}
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
* understands what was already tried
|
||||
*/
|
||||
import { NextResponse } from "next/server";
|
||||
import { authSession } from "@/lib/auth/session-server";
|
||||
import { getServerSession } from "next-auth";
|
||||
import { authOptions } from "@/lib/auth/authOptions";
|
||||
import { query } from "@/lib/db-postgres";
|
||||
|
||||
const AGENT_RUNNER_URL = process.env.AGENT_RUNNER_URL ?? "http://localhost:3333";
|
||||
@@ -20,7 +21,7 @@ export async function POST(
|
||||
) {
|
||||
try {
|
||||
const { projectId, sessionId } = await params;
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) {
|
||||
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
* (handled in /stop/route.ts)
|
||||
*/
|
||||
import { NextResponse } from "next/server";
|
||||
import { authSession } from "@/lib/auth/session-server";
|
||||
import { getServerSession } from "next-auth";
|
||||
import { authOptions } from "@/lib/auth/authOptions";
|
||||
import { query } from "@/lib/db-postgres";
|
||||
|
||||
export async function GET(
|
||||
@@ -16,7 +17,7 @@ export async function GET(
|
||||
) {
|
||||
try {
|
||||
const { projectId, sessionId } = await params;
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) {
|
||||
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { authSession } from "@/lib/auth/session-server";
|
||||
import { getServerSession } from "next-auth";
|
||||
import { authOptions } from "@/lib/auth/authOptions";
|
||||
import { query } from "@/lib/db-postgres";
|
||||
|
||||
const AGENT_RUNNER_URL = process.env.AGENT_RUNNER_URL ?? "http://localhost:3333";
|
||||
@@ -10,7 +11,7 @@ export async function POST(
|
||||
) {
|
||||
try {
|
||||
const { projectId, sessionId } = await params;
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) {
|
||||
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
}
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
* List all sessions for a project, newest first.
|
||||
*/
|
||||
import { NextResponse } from "next/server";
|
||||
import { authSession } from "@/lib/auth/session-server";
|
||||
import { getServerSession } from "next-auth";
|
||||
import { authOptions } from "@/lib/auth/authOptions";
|
||||
import { query } from "@/lib/db-postgres";
|
||||
|
||||
const AGENT_RUNNER_URL = process.env.AGENT_RUNNER_URL ?? "http://localhost:3333";
|
||||
@@ -32,7 +33,7 @@ export async function POST(
|
||||
) {
|
||||
try {
|
||||
const { projectId } = await params;
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) {
|
||||
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
}
|
||||
@@ -130,7 +131,7 @@ export async function GET(
|
||||
) {
|
||||
try {
|
||||
const { projectId } = await params;
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) {
|
||||
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { authSession } from "@/lib/auth/session-server";
|
||||
import { getServerSession } from 'next-auth';
|
||||
import { authOptions } from '@/lib/auth/authOptions';
|
||||
import { query } from '@/lib/db-postgres';
|
||||
|
||||
export async function GET(
|
||||
@@ -8,7 +9,7 @@ export async function GET(
|
||||
) {
|
||||
try {
|
||||
const { projectId } = await params;
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) {
|
||||
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { authSession } from "@/lib/auth/session-server";
|
||||
import { getServerSession } from 'next-auth';
|
||||
import { authOptions } from '@/lib/auth/authOptions';
|
||||
import { query } from '@/lib/db-postgres';
|
||||
|
||||
export const maxDuration = 60;
|
||||
@@ -36,7 +37,7 @@ export async function POST(
|
||||
) {
|
||||
try {
|
||||
const { projectId } = await params;
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) {
|
||||
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { authSession } from "@/lib/auth/session-server";
|
||||
import { getServerSession } from 'next-auth';
|
||||
import { authOptions } from '@/lib/auth/authOptions';
|
||||
import { query } from '@/lib/db-postgres';
|
||||
import { execSync } from 'child_process';
|
||||
import { existsSync, readdirSync, readFileSync, statSync, rmSync } from 'fs';
|
||||
@@ -78,7 +79,7 @@ export async function POST(
|
||||
) {
|
||||
try {
|
||||
const { projectId } = await params;
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) {
|
||||
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { authSession } from "@/lib/auth/session-server";
|
||||
import { getServerSession } from 'next-auth';
|
||||
import { authOptions } from '@/lib/auth/authOptions';
|
||||
import { query } from '@/lib/db-postgres';
|
||||
|
||||
const AGENT_RUNNER_URL = process.env.AGENT_RUNNER_URL ?? 'http://localhost:3333';
|
||||
@@ -9,7 +10,7 @@ export async function GET(
|
||||
_req: Request,
|
||||
{ params }: { params: Promise<{ projectId: string }> }
|
||||
) {
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) {
|
||||
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
||||
}
|
||||
@@ -67,7 +68,7 @@ export async function POST(
|
||||
_req: Request,
|
||||
{ params }: { params: Promise<{ projectId: string }> }
|
||||
) {
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) {
|
||||
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { authSession } from "@/lib/auth/session-server";
|
||||
import { getServerSession } from 'next-auth';
|
||||
import { authOptions } from '@/lib/auth/authOptions';
|
||||
import { query } from '@/lib/db-postgres';
|
||||
|
||||
const GITEA_API_URL = process.env.GITEA_API_URL ?? 'https://git.vibnai.com';
|
||||
@@ -24,7 +25,7 @@ export async function GET(
|
||||
) {
|
||||
const { projectId } = await params;
|
||||
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) {
|
||||
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
||||
}
|
||||
@@ -124,7 +125,7 @@ export async function PATCH(
|
||||
) {
|
||||
const { projectId } = await params;
|
||||
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) {
|
||||
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { authSession } from "@/lib/auth/session-server";
|
||||
import { getServerSession } from "next-auth/next";
|
||||
import { authOptions } from "@/lib/auth/authOptions";
|
||||
import { query } from "@/lib/db-postgres";
|
||||
|
||||
const AGENT_RUNNER_URL = process.env.AGENT_RUNNER_URL ?? "http://localhost:3333";
|
||||
@@ -12,7 +13,7 @@ export async function GET(
|
||||
_req: NextRequest,
|
||||
{ params }: { params: Promise<{ projectId: string }> }
|
||||
) {
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) {
|
||||
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
}
|
||||
@@ -42,7 +43,7 @@ export async function POST(
|
||||
req: NextRequest,
|
||||
{ params }: { params: Promise<{ projectId: string }> }
|
||||
) {
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) {
|
||||
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
}
|
||||
@@ -183,7 +184,7 @@ export async function PATCH(
|
||||
_req: NextRequest,
|
||||
{ params }: { params: Promise<{ projectId: string }> }
|
||||
) {
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) {
|
||||
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
}
|
||||
|
||||
@@ -1,47 +1,18 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { authSession } from "@/lib/auth/session-server";
|
||||
import { getServerSession } from "next-auth/next";
|
||||
import { authOptions } from "@/lib/auth/authOptions";
|
||||
import { query } from "@/lib/db-postgres";
|
||||
import {
|
||||
augmentAtlasMessage,
|
||||
parseContextRefs,
|
||||
} from "@/lib/chat-context-refs";
|
||||
|
||||
const AGENT_RUNNER_URL = process.env.AGENT_RUNNER_URL ?? "http://localhost:3333";
|
||||
|
||||
const ALLOWED_SCOPES = new Set(["overview", "build"]);
|
||||
|
||||
function normalizeScope(raw: string | null | undefined): "overview" | "build" {
|
||||
const s = (raw ?? "overview").trim();
|
||||
return ALLOWED_SCOPES.has(s) ? (s as "overview" | "build") : "overview";
|
||||
}
|
||||
|
||||
function runnerSessionId(projectId: string, scope: "overview" | "build"): string {
|
||||
return scope === "overview" ? `atlas_${projectId}` : `atlas_${projectId}__build`;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// DB — atlas_chat_threads (project_id + scope); legacy atlas_conversations → overview
|
||||
// DB helpers — atlas_conversations table
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
let threadsTableReady = false;
|
||||
let legacyTableChecked = false;
|
||||
let tableReady = false;
|
||||
|
||||
async function ensureThreadsTable() {
|
||||
if (threadsTableReady) return;
|
||||
await query(`
|
||||
CREATE TABLE IF NOT EXISTS atlas_chat_threads (
|
||||
project_id TEXT NOT NULL,
|
||||
scope TEXT NOT NULL,
|
||||
messages JSONB NOT NULL DEFAULT '[]'::jsonb,
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
PRIMARY KEY (project_id, scope)
|
||||
)
|
||||
`);
|
||||
threadsTableReady = true;
|
||||
}
|
||||
|
||||
async function ensureLegacyConversationsTable() {
|
||||
if (legacyTableChecked) return;
|
||||
async function ensureTable() {
|
||||
if (tableReady) return;
|
||||
await query(`
|
||||
CREATE TABLE IF NOT EXISTS atlas_conversations (
|
||||
project_id TEXT PRIMARY KEY,
|
||||
@@ -49,47 +20,31 @@ async function ensureLegacyConversationsTable() {
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
)
|
||||
`);
|
||||
legacyTableChecked = true;
|
||||
tableReady = true;
|
||||
}
|
||||
|
||||
async function loadAtlasHistory(projectId: string, scope: "overview" | "build"): Promise<any[]> {
|
||||
async function loadAtlasHistory(projectId: string): Promise<any[]> {
|
||||
try {
|
||||
await ensureThreadsTable();
|
||||
await ensureTable();
|
||||
const rows = await query<{ messages: any[] }>(
|
||||
`SELECT messages FROM atlas_chat_threads WHERE project_id = $1 AND scope = $2`,
|
||||
[projectId, scope]
|
||||
`SELECT messages FROM atlas_conversations WHERE project_id = $1`,
|
||||
[projectId]
|
||||
);
|
||||
if (rows.length > 0) {
|
||||
const fromThreads = rows[0]?.messages;
|
||||
return Array.isArray(fromThreads) ? fromThreads : [];
|
||||
}
|
||||
if (scope === "overview") {
|
||||
await ensureLegacyConversationsTable();
|
||||
const leg = await query<{ messages: any[] }>(
|
||||
`SELECT messages FROM atlas_conversations WHERE project_id = $1`,
|
||||
[projectId]
|
||||
);
|
||||
const legacyMsgs = leg[0]?.messages ?? [];
|
||||
if (Array.isArray(legacyMsgs) && legacyMsgs.length > 0) {
|
||||
await saveAtlasHistory(projectId, scope, legacyMsgs);
|
||||
return legacyMsgs;
|
||||
}
|
||||
}
|
||||
return [];
|
||||
return rows[0]?.messages ?? [];
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
async function saveAtlasHistory(projectId: string, scope: "overview" | "build", messages: any[]): Promise<void> {
|
||||
async function saveAtlasHistory(projectId: string, messages: any[]): Promise<void> {
|
||||
try {
|
||||
await ensureThreadsTable();
|
||||
await ensureTable();
|
||||
await query(
|
||||
`INSERT INTO atlas_chat_threads (project_id, scope, messages, updated_at)
|
||||
VALUES ($1, $2, $3::jsonb, NOW())
|
||||
ON CONFLICT (project_id, scope) DO UPDATE
|
||||
SET messages = $3::jsonb, updated_at = NOW()`,
|
||||
[projectId, scope, JSON.stringify(messages)]
|
||||
`INSERT INTO atlas_conversations (project_id, messages, updated_at)
|
||||
VALUES ($1, $2::jsonb, NOW())
|
||||
ON CONFLICT (project_id) DO UPDATE
|
||||
SET messages = $2::jsonb, updated_at = NOW()`,
|
||||
[projectId, JSON.stringify(messages)]
|
||||
);
|
||||
} catch (e) {
|
||||
console.error("[atlas-chat] Failed to save history:", e);
|
||||
@@ -111,36 +66,21 @@ async function savePrd(projectId: string, prdContent: string): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
/** Replace the latest user message content so DB/UI never show the internal ref prefix. */
|
||||
function scrubLastUserMessageContent(history: unknown[], cleanText: string): unknown[] {
|
||||
if (!Array.isArray(history) || history.length === 0) return history;
|
||||
const h = history.map(m => (m && typeof m === "object" ? { ...(m as object) } : m));
|
||||
for (let i = h.length - 1; i >= 0; i--) {
|
||||
const m = h[i] as { role?: string; content?: string };
|
||||
if (m?.role === "user" && typeof m.content === "string") {
|
||||
h[i] = { ...m, content: cleanText };
|
||||
break;
|
||||
}
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// GET — load stored conversation messages for display
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export async function GET(
|
||||
req: NextRequest,
|
||||
_req: NextRequest,
|
||||
{ params }: { params: Promise<{ projectId: string }> }
|
||||
) {
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) {
|
||||
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
}
|
||||
|
||||
const { projectId } = await params;
|
||||
const scope = normalizeScope(req.nextUrl.searchParams.get("scope"));
|
||||
const history = await loadAtlasHistory(projectId, scope);
|
||||
const history = await loadAtlasHistory(projectId);
|
||||
|
||||
// Filter to only user/assistant messages (no system prompts) for display
|
||||
const messages = history
|
||||
@@ -158,50 +98,43 @@ export async function POST(
|
||||
req: NextRequest,
|
||||
{ params }: { params: Promise<{ projectId: string }> }
|
||||
) {
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) {
|
||||
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
}
|
||||
|
||||
const { projectId } = await params;
|
||||
const body = await req.json();
|
||||
const message = body?.message as string | undefined;
|
||||
const contextRefs = parseContextRefs(body?.contextRefs);
|
||||
const { message } = await req.json();
|
||||
if (!message?.trim()) {
|
||||
return NextResponse.json({ error: "message is required" }, { status: 400 });
|
||||
}
|
||||
|
||||
const scope = normalizeScope(body?.scope as string | undefined);
|
||||
const sessionId = runnerSessionId(projectId, scope);
|
||||
const cleanUserText = message.trim();
|
||||
const sessionId = `atlas_${projectId}`;
|
||||
|
||||
// Load conversation history from DB to persist across agent runner restarts.
|
||||
// Strip tool_call / tool_response messages — replaying them across sessions
|
||||
// causes Gemini to reject the request with a turn-ordering error.
|
||||
const rawHistory = await loadAtlasHistory(projectId, scope);
|
||||
const rawHistory = await loadAtlasHistory(projectId);
|
||||
const history = rawHistory.filter((m: any) =>
|
||||
(m.role === "user" || m.role === "assistant") && m.content
|
||||
);
|
||||
|
||||
// __init__ is a special internal trigger used only when there is no existing history.
|
||||
// If history already exists, ignore the init request (conversation already started).
|
||||
const isInit = cleanUserText === "__atlas_init__";
|
||||
const isInit = message.trim() === "__atlas_init__";
|
||||
if (isInit && history.length > 0) {
|
||||
return NextResponse.json({ reply: null, alreadyStarted: true });
|
||||
}
|
||||
|
||||
const runnerMessage = isInit
|
||||
? scope === "build"
|
||||
? "Begin as Vibn in build mode. The user is working in their monorepo. Ask what they want to ship or fix next, and offer concrete implementation guidance. Do not acknowledge this as an internal trigger."
|
||||
: "Begin the conversation. Introduce yourself as Vibn and ask what the user is building. Do not acknowledge this as an internal trigger."
|
||||
: augmentAtlasMessage(cleanUserText, contextRefs);
|
||||
|
||||
try {
|
||||
const res = await fetch(`${AGENT_RUNNER_URL}/atlas/chat`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
message: runnerMessage,
|
||||
// For init, send the greeting prompt but don't store it as a user message
|
||||
message: isInit
|
||||
? "Begin the conversation. Introduce yourself as Vibn and ask what the user is building. Do not acknowledge this as an internal trigger."
|
||||
: message,
|
||||
session_id: sessionId,
|
||||
history,
|
||||
is_init: isInit,
|
||||
@@ -220,16 +153,11 @@ export async function POST(
|
||||
|
||||
const data = await res.json();
|
||||
|
||||
let historyOut = data.history ?? [];
|
||||
// Store the user's line without the internal reference block (UI shows clean text).
|
||||
if (!isInit && cleanUserText !== "__atlas_init__") {
|
||||
historyOut = scrubLastUserMessageContent(historyOut, cleanUserText);
|
||||
}
|
||||
// Persist updated history
|
||||
await saveAtlasHistory(projectId, data.history ?? []);
|
||||
|
||||
await saveAtlasHistory(projectId, scope, historyOut);
|
||||
|
||||
// If Atlas finalized the PRD, save it to the project (discovery / overview)
|
||||
if (data.prdContent && scope === "overview") {
|
||||
// If Atlas finalized the PRD, save it to the project
|
||||
if (data.prdContent) {
|
||||
await savePrd(projectId, data.prdContent);
|
||||
}
|
||||
|
||||
@@ -253,35 +181,24 @@ export async function POST(
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export async function DELETE(
|
||||
req: NextRequest,
|
||||
_req: NextRequest,
|
||||
{ params }: { params: Promise<{ projectId: string }> }
|
||||
) {
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) {
|
||||
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
}
|
||||
|
||||
const { projectId } = await params;
|
||||
const scope = normalizeScope(req.nextUrl.searchParams.get("scope"));
|
||||
const sessionId = runnerSessionId(projectId, scope);
|
||||
const sessionId = `atlas_${projectId}`;
|
||||
|
||||
try {
|
||||
await fetch(`${AGENT_RUNNER_URL}/atlas/sessions/${encodeURIComponent(sessionId)}`, { method: "DELETE" });
|
||||
await fetch(`${AGENT_RUNNER_URL}/atlas/sessions/${sessionId}`, { method: "DELETE" });
|
||||
} catch { /* runner may be down */ }
|
||||
|
||||
try {
|
||||
await ensureThreadsTable();
|
||||
await query(
|
||||
`DELETE FROM atlas_chat_threads WHERE project_id = $1 AND scope = $2`,
|
||||
[projectId, scope]
|
||||
);
|
||||
await query(`DELETE FROM atlas_conversations WHERE project_id = $1`, [projectId]);
|
||||
} catch { /* table may not exist yet */ }
|
||||
|
||||
if (scope === "overview") {
|
||||
try {
|
||||
await query(`DELETE FROM atlas_conversations WHERE project_id = $1`, [projectId]);
|
||||
} catch { /* legacy */ }
|
||||
}
|
||||
|
||||
return NextResponse.json({ cleared: true });
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { authSession } from "@/lib/auth/session-server";
|
||||
import { getServerSession } from 'next-auth';
|
||||
import { authOptions } from '@/lib/auth/authOptions';
|
||||
import { query } from '@/lib/db-postgres';
|
||||
|
||||
/**
|
||||
@@ -11,7 +12,7 @@ export async function GET(
|
||||
) {
|
||||
try {
|
||||
const { projectId } = await params;
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
||||
|
||||
const rows = await query<{ data: Record<string, unknown> }>(
|
||||
@@ -48,7 +49,7 @@ export async function PATCH(
|
||||
) {
|
||||
try {
|
||||
const { projectId } = await params;
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
||||
|
||||
// Step 1: read current data — explicit ::text casts on every param
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
* Response for file: { type: "file", content: string, encoding: "utf8" | "base64" }
|
||||
*/
|
||||
import { NextResponse } from 'next/server';
|
||||
import { authSession } from "@/lib/auth/session-server";
|
||||
import { getServerSession } from 'next-auth';
|
||||
import { authOptions } from '@/lib/auth/authOptions';
|
||||
import { query } from '@/lib/db-postgres';
|
||||
|
||||
const GITEA_API_URL = process.env.GITEA_API_URL ?? 'https://git.vibnai.com';
|
||||
@@ -38,7 +39,7 @@ export async function GET(
|
||||
) {
|
||||
try {
|
||||
const { projectId } = await params;
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) {
|
||||
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { authSession } from "@/lib/auth/session-server";
|
||||
import { getServerSession } from 'next-auth';
|
||||
import { authOptions } from '@/lib/auth/authOptions';
|
||||
import { query } from '@/lib/db-postgres';
|
||||
|
||||
export const maxDuration = 120;
|
||||
@@ -27,7 +28,7 @@ export async function POST(
|
||||
) {
|
||||
try {
|
||||
const { projectId } = await params;
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) {
|
||||
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { authSession } from "@/lib/auth/session-server";
|
||||
import { getServerSession } from 'next-auth';
|
||||
import { authOptions } from '@/lib/auth/authOptions';
|
||||
import { query } from '@/lib/db-postgres';
|
||||
import { createKnowledgeItem } from '@/lib/server/knowledge';
|
||||
import type { KnowledgeSourceMeta } from '@/lib/types/knowledge';
|
||||
@@ -33,7 +34,7 @@ export async function POST(
|
||||
return NextResponse.json({ error: 'transcript is required' }, { status: 400 });
|
||||
}
|
||||
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) {
|
||||
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { authSession } from "@/lib/auth/session-server";
|
||||
import { getServerSession } from 'next-auth';
|
||||
import { authOptions } from '@/lib/auth/authOptions';
|
||||
import { query } from '@/lib/db-postgres';
|
||||
|
||||
export async function GET(
|
||||
@@ -9,7 +10,7 @@ export async function GET(
|
||||
try {
|
||||
const { projectId } = await params;
|
||||
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) {
|
||||
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { authSession } from "@/lib/auth/session-server";
|
||||
import { getServerSession } from "next-auth/next";
|
||||
import { authOptions } from "@/lib/auth/authOptions";
|
||||
import { query } from "@/lib/db-postgres";
|
||||
|
||||
async function assertOwnership(projectId: string, email: string): Promise<boolean> {
|
||||
@@ -17,7 +18,7 @@ export async function GET(
|
||||
_req: NextRequest,
|
||||
{ params }: { params: Promise<{ projectId: string }> }
|
||||
) {
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
|
||||
const { projectId } = await params;
|
||||
@@ -40,7 +41,7 @@ export async function POST(
|
||||
req: NextRequest,
|
||||
{ params }: { params: Promise<{ projectId: string }> }
|
||||
) {
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
|
||||
const { projectId } = await params;
|
||||
@@ -82,7 +83,7 @@ export async function DELETE(
|
||||
req: NextRequest,
|
||||
{ params }: { params: Promise<{ projectId: string }> }
|
||||
) {
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
|
||||
const { projectId } = await params;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { authSession } from "@/lib/auth/session-server";
|
||||
import { getServerSession } from 'next-auth';
|
||||
import { authOptions } from '@/lib/auth/authOptions';
|
||||
import { query } from '@/lib/db-postgres';
|
||||
import { listApplications, CoolifyApplication } from '@/lib/coolify';
|
||||
|
||||
@@ -19,7 +20,7 @@ export async function GET(
|
||||
) {
|
||||
const { projectId } = await params;
|
||||
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) {
|
||||
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { authSession } from "@/lib/auth/session-server";
|
||||
import { getServerSession } from 'next-auth';
|
||||
import { authOptions } from '@/lib/auth/authOptions';
|
||||
import { query } from '@/lib/db-postgres';
|
||||
|
||||
export async function GET(
|
||||
@@ -9,7 +10,7 @@ export async function GET(
|
||||
try {
|
||||
const { projectId } = await params;
|
||||
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) {
|
||||
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
||||
}
|
||||
@@ -44,7 +45,7 @@ export async function PATCH(
|
||||
const { projectId } = await params;
|
||||
const body = await request.json();
|
||||
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) {
|
||||
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { authSession } from "@/lib/auth/session-server";
|
||||
import { getServerSession } from "next-auth/next";
|
||||
import { authOptions } from "@/lib/auth/authOptions";
|
||||
import { query } from "@/lib/db-postgres";
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -10,7 +11,7 @@ export async function POST(
|
||||
req: NextRequest,
|
||||
{ params }: { params: Promise<{ projectId: string }> }
|
||||
) {
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) {
|
||||
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
}
|
||||
@@ -84,7 +85,7 @@ export async function GET(
|
||||
_req: NextRequest,
|
||||
{ params }: { params: Promise<{ projectId: string }> }
|
||||
) {
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) {
|
||||
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { authSession } from "@/lib/auth/session-server";
|
||||
import { getServerSession } from 'next-auth';
|
||||
import { authOptions } from '@/lib/auth/authOptions';
|
||||
import { query } from '@/lib/db-postgres';
|
||||
|
||||
export async function POST(
|
||||
@@ -8,7 +9,7 @@ export async function POST(
|
||||
) {
|
||||
try {
|
||||
const { projectId } = await params;
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) {
|
||||
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { authSession } from "@/lib/auth/session-server";
|
||||
import { getServerSession } from 'next-auth';
|
||||
import { authOptions } from '@/lib/auth/authOptions';
|
||||
import { query } from '@/lib/db-postgres';
|
||||
import { provisionTheiaWorkspace } from '@/lib/cloud-run-workspace';
|
||||
|
||||
@@ -10,7 +11,7 @@ export async function POST(
|
||||
try {
|
||||
const { projectId } = await params;
|
||||
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) {
|
||||
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { authSession } from "@/lib/auth/session-server";
|
||||
import { getServerSession } from 'next-auth';
|
||||
import { authOptions } from '@/lib/auth/authOptions';
|
||||
import { query } from '@/lib/db-postgres';
|
||||
|
||||
export async function POST(request: Request) {
|
||||
try {
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) {
|
||||
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
||||
}
|
||||
|
||||
@@ -8,13 +8,14 @@
|
||||
*/
|
||||
|
||||
import { NextResponse } from 'next/server';
|
||||
import { authSession } from "@/lib/auth/session-server";
|
||||
import { getServerSession } from 'next-auth';
|
||||
import { authOptions } from '@/lib/auth/authOptions';
|
||||
import { query } from '@/lib/db-postgres';
|
||||
import { deployApplication } from '@/lib/coolify';
|
||||
|
||||
export async function POST(request: Request) {
|
||||
try {
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) {
|
||||
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { authSession } from "@/lib/auth/session-server";
|
||||
import { getServerSession } from 'next-auth';
|
||||
import { authOptions } from '@/lib/auth/authOptions';
|
||||
import { prewarmWorkspace } from '@/lib/cloud-run-workspace';
|
||||
|
||||
/**
|
||||
@@ -11,7 +12,7 @@ import { prewarmWorkspace } from '@/lib/cloud-run-workspace';
|
||||
* to avoid CORS issues with run.app domains.
|
||||
*/
|
||||
export async function POST(req: NextRequest) {
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user) {
|
||||
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { authSession } from "@/lib/auth/session-server";
|
||||
import { getServerSession } from 'next-auth';
|
||||
import { authOptions } from '@/lib/auth/authOptions';
|
||||
import { query } from '@/lib/db-postgres';
|
||||
|
||||
export async function GET() {
|
||||
try {
|
||||
const session = await authSession();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.email) {
|
||||
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user