Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 10 additions & 0 deletions next-app/app/api/chat/stream/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,16 @@ function* fakeStream(text: string) {

import { preFilter, steerPrompt, postModerate } from '@/lib/safety/pipeline';

/**
* Streams a message as a server-sent event.
*
* This function creates a ReadableStream that processes a given message through several stages:
* it applies pre-filtering, steering, and post-moderation to generate a reply. The stream emits
* metadata and each chunk of the reply as events, handling errors by sending an error event if
* any exceptions occur during processing.
*
* @param message - The input message to be processed and streamed.
*/
function streamForMessage(message: string) {
const ctrl = new AbortController();
const stream = new ReadableStream<Uint8Array>({
Expand Down
12 changes: 12 additions & 0 deletions next-app/app/api/consent/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,25 @@

export const runtime = 'nodejs';

/**
* Handles POST requests to process user consent actions.
*
* This function extracts the userId, sessionId, and action from the request body.
* It validates the action against a predefined list and returns a 400 response for invalid actions.
* If the action is valid, it appends a consent event using the appendConsentEvent function and returns the result as a JSON response.

Check warning on line 11 in next-app/app/api/consent/route.ts

View check run for this annotation

Codeac.io / Codeac Code Quality

max-line-length

Exceeds maximum line length of 120
*
* @param req - The NextRequest object containing the request data.
*/
export async function POST(req: NextRequest) {
const { userId = 'demo', sessionId, action } = await req.json();
if (!['persist_on','persist_off','export'].includes(action)) return new Response('bad action', { status: 400 });
const ev = await appendConsentEvent({ userId, sessionId, action, ts: new Date().toISOString() as any });
return Response.json(ev);
}

/**
* Handles GET requests and returns consent data for a user.
*/
export async function GET(req: NextRequest) {
const { searchParams } = new URL(req.url);
const userId = searchParams.get('userId') ?? 'demo';
Expand Down
6 changes: 6 additions & 0 deletions next-app/app/api/risk/scores/route.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
export const runtime = 'nodejs';
/**
* Handles the GET request and returns a mock time-series risk per layer.
*/
export async function GET() {
// Mock time-series risk per layer: core/operational/context
const now = Date.now();
const series = ['core','operational','context'].map((k, i) => ({
key: k,
points: Array.from({ length: 12 }, (_, j) => ({ t: now - (11 - j) * 3600_000, v: clamp(0, 100, 30 + i*20 + Math.sin(j/2+i)*15 + Math.random()*10) }))

Check warning on line 10 in next-app/app/api/risk/scores/route.ts

View check run for this annotation

Codeac.io / Codeac Code Quality

max-line-length

Exceeds maximum line length of 120
}));
return Response.json({ series });
}
/**
* Clamps a value between a minimum and maximum range.
*/
function clamp(min:number,max:number,v:number){return Math.max(min,Math.min(max,v));}
7 changes: 7 additions & 0 deletions next-app/app/chat/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@
import { useEffect, useRef, useState } from 'react';
import { ProvenanceBadge } from '@/components/ProvenanceBadge';

/**
* Renders the chat page interface and handles message sending and streaming.
*
* The function manages the state for user input, messages, and streaming status. It sets up an EventSource to listen for incoming messages and updates the message list accordingly. It also handles fallback scenarios and cleans up the EventSource on component unmount.

Check warning on line 8 in next-app/app/chat/page.tsx

View check run for this annotation

Codeac.io / Codeac Code Quality

max-line-length

Exceeds maximum line length of 120
*
* @returns {JSX.Element} The rendered chat page component.
*/
export default function ChatPage() {
const [input, setInput] = useState("");
const [messages, setMessages] = useState<{ role: 'user'|'assistant'; content: string; meta?: any }[]>([]);
Expand All @@ -15,7 +22,7 @@
setMessages(m => [...m, userMsg, { role: 'assistant', content: '' }]);
setInput("");
setStreaming(true);
const es = new EventSource(`/api/chat/stream?q=${encodeURIComponent(userMsg.content)}&s=${Date.now()}` , { withCredentials: false });

Check warning on line 25 in next-app/app/chat/page.tsx

View check run for this annotation

Codeac.io / Codeac Code Quality

max-line-length

Exceeds maximum line length of 120
eventSrc.current = es;

es.addEventListener('token', (e: MessageEvent) => {
Expand Down Expand Up @@ -49,7 +56,7 @@

return (
<div className="space-y-4">
<h1 className="text-2xl font-semibold">Chat <span className="text-xs align-middle text-slate-500">(ephemeral by default)</span></h1>

Check warning on line 59 in next-app/app/chat/page.tsx

View check run for this annotation

Codeac.io / Codeac Code Quality

max-line-length

Exceeds maximum line length of 120
<div className="rounded border bg-white p-3">
<div className="space-y-3" role="log" aria-live="polite">
{messages.map((m, i) => (
Expand All @@ -64,10 +71,10 @@
))}
</div>
<div className="mt-3 flex flex-wrap items-center gap-2">
<input value={input} onChange={e=>setInput(e.target.value)} className="flex-1 rounded border px-3 py-2" placeholder="Type a message..." />

Check warning on line 74 in next-app/app/chat/page.tsx

View check run for this annotation

Codeac.io / Codeac Code Quality

max-line-length

Exceeds maximum line length of 120
<button onClick={send} disabled={streaming} className="rounded bg-amber-600 px-4 py-2 text-white disabled:opacity-50">Send</button>
{fallback && <span className="text-xs text-slate-500">Fallback in use</span>}
<a href="/api/consent?userId=demo" target="_blank" className="text-xs text-amber-700 underline">Export consent ledger</a>

Check warning on line 77 in next-app/app/chat/page.tsx

View check run for this annotation

Codeac.io / Codeac Code Quality

max-line-length

Exceeds maximum line length of 120
</div>
</div>
</div>
Expand Down
3 changes: 3 additions & 0 deletions next-app/app/docs/governance-terms-mapping/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { readFileSync } from 'fs';
import path from 'path';
export const dynamic = 'force-static';
/**
* Renders the content of a markdown file as preformatted text.
*/
export default function Page() {
const md = readFileSync(path.join(process.cwd(), 'next-app', 'docs', 'governance-terms-mapping.md'), 'utf8');
return <pre className="whitespace-pre-wrap text-sm">{md}</pre>;
Expand Down
Loading