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
43 changes: 43 additions & 0 deletions .github/workflows/spec-registry-validation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Spec Registry Validation

on:
pull_request:
paths:
- 'specs/**'
- 'docs/ARCHITECTURE_REGISTRY.md'
- '.github/workflows/spec-registry-validation.yml'
- 'package.json'
workflow_dispatch:

permissions:
contents: read

jobs:
validate-registry:
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: npm

- name: Install dependencies
run: npm ci

- name: Validate specs
run: npm run specs:validate

- name: Build registry index
run: npm run specs:index

- name: Generate architecture docs
run: npm run specs:docs

- name: Check generated artifacts are committed
run: |
git diff --exit-code -- specs/registries/index.json docs/ARCHITECTURE_REGISTRY.md
37 changes: 33 additions & 4 deletions app/api/chat/route.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,39 @@
import { groq } from "@ai-sdk/groq"
import { streamText, convertToCoreMessages } from "ai"
import { awardTokens, saveConversation } from "@/lib/db"
import { z } from "zod"

const ChatRequestSchema = z.object({
messages: z.array(z.object({
role: z.enum(["user", "assistant"]),
content: z.string().min(1),
})).min(1),
userId: z.string().optional(),
sessionId: z.string().optional(),
orchestration: z.object({
mode: z.enum(["visual-chat", "realtime-collaboration", "agent-loop"]).default("visual-chat"),
interfaceProfile: z.enum(["vr4deaf", "vuri-ai"]).default("vr4deaf"),
collaboration: z.boolean().default(false),
loopSchedule: z.enum(["single", "5m", "15m"]).default("single"),
ragResearchFocus: z.boolean().default(true),
}).optional(),
})

export const maxDuration = 30

export async function POST(req: Request) {
try {
const { messages, userId, sessionId } = await req.json()
const payload = ChatRequestSchema.parse(await req.json())
const { messages, userId, sessionId, orchestration } = payload

const orchestrationPrompt = orchestration
? `\n\n🧭 Active session mode:
- Mode: ${orchestration.mode}
- Interface profile: ${orchestration.interfaceProfile}
- Collaboration layer: ${orchestration.collaboration ? "enabled" : "disabled"}
- Loop schedule: ${orchestration.loopSchedule}
- Deaf-first RAG research focus: ${orchestration.ragResearchFocus ? "enabled" : "disabled"}`
: ""

// Save conversation to Neon
if (userId && sessionId) {
Expand All @@ -15,7 +42,7 @@ export async function POST(req: Request) {

const result = await streamText({
model: groq("llama-3.1-70b-versatile"),
messages: convertToCoreMessages(messages),
messages: convertToCoreMessages(messages as any),
system: `You are PINKY AI, a specialized assistant for sign language interpretation and accessibility.

🎯 Your expertise includes:
Expand All @@ -42,7 +69,9 @@ export async function POST(req: Request) {
- Encourage participation in the Sign-to-Earn ecosystem
- Mention token rewards when appropriate

Always be inclusive, respectful, and focused on advancing accessibility through AI.`,
Always be inclusive, respectful, and focused on advancing accessibility through AI.

Prioritize Deaf-first initiatives, practical implementation guidance, and concise, operationally useful answers.${orchestrationPrompt}`,
onFinish: async (result) => {
// Award tokens for interaction
if (userId) {
Expand All @@ -51,7 +80,7 @@ Always be inclusive, respectful, and focused on advancing accessibility through
},
})

return result.toDataStreamResponse()
return (result as any).toDataStreamResponse()
} catch (error) {
console.error("Chat API error:", error)
return new Response("Internal Server Error", { status: 500 })
Expand Down
5 changes: 4 additions & 1 deletion app/api/health/route.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { NextResponse } from 'next/server'
import { PLATFORM_VERSION, PLATFORM_LABELS } from '@/lib/platform'

interface HealthStatus {
status: 'healthy' | 'degraded' | 'unhealthy'
version: string
labels: string[]
timestamp: string
uptime: number
services: {
Expand All @@ -18,7 +20,8 @@ const startTime = Date.now()
export async function GET(): Promise<NextResponse<HealthStatus>> {
const status: HealthStatus = {
status: 'healthy',
version: '2.0.0',
version: PLATFORM_VERSION,
labels: [...PLATFORM_LABELS],
timestamp: new Date().toISOString(),
uptime: Math.floor((Date.now() - startTime) / 1000),
services: {
Expand Down
120 changes: 119 additions & 1 deletion app/chat/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"use client"

import type React from "react"
import { useState, useRef } from "react"
import { useState, useRef, useEffect } from "react"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
Expand All @@ -16,6 +16,15 @@ interface Message {
content: string
}

type ChatMode = "visual-chat" | "realtime-collaboration" | "agent-loop"
type LoopSchedule = "single" | "5m" | "15m"
type InterfaceProfile = "vr4deaf" | "vuri-ai"

interface HealthStatus {
version: string
labels?: string[]
}

// Generate unique ID with fallback
function generateId(): string {
if (typeof crypto !== 'undefined' && crypto.randomUUID) {
Expand All @@ -37,6 +46,27 @@ export default function ChatPage() {
const [messages, setMessages] = useState<Message[]>([])
const [input, setInput] = useState('')
const [isLoading, setIsLoading] = useState(false)
const [chatMode, setChatMode] = useState<ChatMode>("visual-chat")
const [enableCollaboration, setEnableCollaboration] = useState(false)
const [loopSchedule, setLoopSchedule] = useState<LoopSchedule>("single")
const [ragResearchFocus, setRagResearchFocus] = useState(true)
const [interfaceProfile, setInterfaceProfile] = useState<InterfaceProfile>("vr4deaf")
const [health, setHealth] = useState<HealthStatus | null>(null)

useEffect(() => {
const fetchHealth = async () => {
try {
const response = await fetch("/api/health")
if (!response.ok) return
const result = await response.json() as HealthStatus
setHealth(result)
} catch {
// no-op
}
}

fetchHealth()
}, [])

const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setInput(e.target.value)
Expand Down Expand Up @@ -64,6 +94,13 @@ export default function ChatPage() {
messages: [...messages, userMessage].map(m => ({ role: m.role, content: m.content })),
userId: user?.id,
sessionId: sessionId,
orchestration: {
mode: chatMode,
interfaceProfile,
collaboration: enableCollaboration,
loopSchedule,
ragResearchFocus,
},
}),
})

Expand Down Expand Up @@ -161,6 +198,87 @@ export default function ChatPage() {
</p>
</div>

<Card className="mb-6">
<CardHeader>
<CardTitle>Visual Chat Entry Point</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
<div>
<label className="text-sm font-medium mb-1 block">Session Mode</label>
<select
value={chatMode}
onChange={(e) => setChatMode(e.target.value as ChatMode)}
className="w-full border rounded-md px-3 py-2 bg-background"
disabled={isLoading}
>
<option value="visual-chat">Visual Chat (default)</option>
<option value="realtime-collaboration">Real-time Collaboration</option>
<option value="agent-loop">Agent Loop</option>
</select>
</div>
<div>
<label className="text-sm font-medium mb-1 block">Loop Schedule</label>
<select
value={loopSchedule}
onChange={(e) => setLoopSchedule(e.target.value as LoopSchedule)}
className="w-full border rounded-md px-3 py-2 bg-background"
disabled={isLoading}
>
<option value="single">Single Run</option>
<option value="5m">Every 5 Minutes</option>
<option value="15m">Every 15 Minutes</option>
</select>
</div>
<div>
<label className="text-sm font-medium mb-1 block">Org Profile</label>
<select
value={interfaceProfile}
onChange={(e) => setInterfaceProfile(e.target.value as InterfaceProfile)}
className="w-full border rounded-md px-3 py-2 bg-background"
disabled={isLoading}
>
<option value="vr4deaf">VR4DEAF</option>
<option value="vuri-ai">Vuri AI</option>
</select>
</div>
</div>
<div className="flex flex-col gap-2 text-sm">
<label className="inline-flex items-center gap-2">
<input
type="checkbox"
checked={enableCollaboration}
onChange={(e) => setEnableCollaboration(e.target.checked)}
disabled={isLoading}
/>
Enable collaboration layer for operator + AI workflows
</label>
<label className="inline-flex items-center gap-2">
<input
type="checkbox"
checked={ragResearchFocus}
onChange={(e) => setRagResearchFocus(e.target.checked)}
disabled={isLoading}
/>
Prioritize Deaf-first research/RAG context
</label>
</div>
<div className="rounded-lg border p-3 text-sm">
<p className="font-medium mb-1">Workflow Steps</p>
<ol className="list-decimal list-inside text-muted-foreground space-y-1">
<li>Ingest visual/sign input or text request</li>
<li>Run Deaf-first analysis and context retrieval</li>
<li>Route through selected org visual panel profile</li>
<li>Generate response with collaboration/operator alignment</li>
<li>Loop per selected schedule when enabled</li>
</ol>
</div>
<div className="text-xs text-muted-foreground">
Version: {health?.version ?? "unknown"} · Labels: {(health?.labels?.join(", ") ?? "vr4deaf, deafauth, pinksync")}
</div>
</CardContent>
</Card>

<Card className="mb-6">
<CardHeader>
<CardTitle className="flex items-center gap-2">
Expand Down
32 changes: 32 additions & 0 deletions docs/ARCHITECTURE_REGISTRY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# MBTQ Studio Registry Architecture

Generated from `specs/` at 2026-08-03T01:18:10.596Z.

## Registry Summary
- Version: 1.0.0
- Total specs: 7

## Specs by Type
- agent.spec: 1
- dispatch.spec: 1
- magician.spec: 1
- provider.spec: 1
- runtime.spec: 1
- service.spec: 1
- workflow.spec: 1

## Specification Inventory

| ID | Type | Version | Lifecycle | Owner | Path |
|---|---|---|---|---|---|
| agent.spec.auditor | agent.spec | 0.1.0 | draft | MBTQ Core Team | `specs/agents/spec-auditor.agent.spec.json` |
| dispatch.spec.router | dispatch.spec | 0.1.0 | draft | MBTQ Core Team | `specs/dispatch/spec-dispatch.dispatch.spec.json` |
| magician.developer | magician.spec | 0.1.0 | draft | MBTQ Core Team | `specs/magicians/developer-magician.magician.spec.json` |
| provider.github-actions | provider.spec | 0.1.0 | draft | MBTQ Core Team | `specs/providers/github-actions.provider.spec.json` |
| runtime.multi-framework | runtime.spec | 0.1.0 | draft | MBTQ Core Team | `specs/runtimes/multi-runtime.runtime.spec.json` |
| svc.registry.foundation | service.spec | 0.1.0 | draft | MBTQ Core Team | `specs/services/foundation-registry.service.spec.json` |
| workflow.spec-governance | workflow.spec | 0.1.0 | draft | MBTQ Core Team | `specs/workflows/spec-governance.workflow.spec.json` |

## Runtime Compatibility

Framework-agnostic support targets are encoded in every spec runtime.supported array, including FastAPI, Deno, and Python workers.
58 changes: 58 additions & 0 deletions docs/INDEX.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Deaf First Platform Knowledge Hub

## Vision
- Mission: Build Deaf-first, accessibility-first AI products
- User journeys: creators, organizations, developers, and end users
- Ecosystem: web platform, AI tooling, and deployment infrastructure

## Platform
- Architecture: `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/docs/singlesource.md`
- Service registry: `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/docs/registry/services.yaml`
- APIs registry: `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/docs/registry/APIs.yaml`

## AI
- PinkyAI documentation strategy and governance
- Agent/workflow inventory: `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/docs/registry/workflows.yaml`
- Structured metadata for automation in `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/docs/registry/`

## Applications
- Business Magician (planned)
- Job Magician (planned)
- Developer Magician (planned)
- SignLanguageAssistant (prototype bundle in `SignLanguageAssistant/`)

## Operations
- CI/CD workflows in `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/.github/workflows/`
- Dependency automation in `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/.github/dependabot.yml`
- Deployment references in `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/docs/DEPLOYMENT.md`

## Documentation Inventory and Audit Status

| Path | Type | Status | Notes |
|---|---|---|---|
| `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/README.md` | Root overview | UPDATE | Strong summary, but contains legacy sections and mixed source-of-truth signals. |
| `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/docs/API.md` | API doc | UPDATE | Useful intent, but endpoint host/contracts appear placeholder and need alignment with current app routes. |
| `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/docs/CONTRIBUTING.md` | Contributor guide | UPDATE | Good structure, but references old repo names/contacts and needs normalization. |
| `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/docs/DEPLOYMENT.md` | Deployment guide | UPDATE | Valuable checklist, but includes mixed targets and environment examples needing validation. |
| `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/docs/singlesource.md` | Architecture/stack policy | KEEP | Primary architecture intent and standards baseline; should remain canonical after cleanup passes. |
| `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/docs/mbtq_architecture.html` | Legacy architecture artifact | ARCHIVE | Historical artifact; retain for reference only, not active source-of-truth. |
| `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/templates/README.md` | Template documentation | KEEP | Active template catalog and onboarding for template users. |
| `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/SignLanguageAssistant/README.md` | Prototype overview | ARCHIVE | Rich but prototype-heavy; overlaps with architecture and implementation docs. |
| `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/SignLanguageAssistant/ARCHITECTURE.md` | Prototype architecture | MERGE | Keep key ideas, merge reusable architecture parts into central platform architecture docs. |
| `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/SignLanguageAssistant/IMPLEMENTATION_SUMMARY.md` | Implementation snapshot | ARCHIVE | Session/date-bound status report; historical context only. |
| `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/SignLanguageAssistant/QUICKSTART.md` | Prototype setup guide | MERGE | Merge practical setup steps into maintained platform onboarding docs. |
| `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/SignLanguageAssistant/NEXTJS_INTEGRATION.md` | Integration guide | MERGE | Merge stable integration patterns into `docs/API.md` + platform docs to avoid drift. |
| `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/.github/dependabot.yml` | Automation config | UPDATE | Keep automation but update directories and ecosystem paths to match actual repo layout. |
| `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/.github/workflows/issue-labled.yml` | Workflow | KEEP | Active issue triage helper workflow. |
| `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/.github/workflows/jekyll-gh-pages.yml` | Workflow | ARCHIVE | Sample Pages workflow; archive unless GitHub Pages publishing is actively used. |
| `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/.github/workflows/mbtq-wcag-check.yml` | Workflow | UPDATE | Important accessibility workflow; currently requires syntax/trigger hardening. |
| `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/.github/workflows/pinkflow.yml` | Workflow | ARCHIVE | Empty placeholder file; archive or replace with real automation definition. |

## Next Documentation Governance Loop

GitHub Change
→ PinkyAI Review
→ Update docs
→ Consistency check
→ Pull Request

Loading
Loading