Synaplan
기업을 위한 오픈소스 AI 플랫폼
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Nexo Assist — conversational IT support agent (NestJS + Next.js)
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Conversational IT service desk for the Beyond the Bytes technical challenge. Employees chat with an agent that proposes actions; a deterministic policy engine decides priority, SLA, duplicity and confirmation; ticket writes happen only after an exact draft version is confirmed.
Deeper engineering notes: docs/README.md.
>=20 (see engines in root package.json)11.12.0 (see packageManager in root package.json)pnpm install
docker compose up -d postgres
cp .env.example .env
# optional: set OPENROUTER_API_KEY (default) or OPENAI_API_KEY for a real model
pnpm db:migrate
pnpm db:seed
pnpm dev
pnpm db:migrate / pnpm db:seed are root shortcuts for the API package. Re-running seed when seed_meta already has nexo-assist-demo-v4 skips without duplicating users.
cp .env.example .env
docker compose up --build
API image runs migrate + idempotent seed on start.
postgres://nexo:nexo@localhost:5432/nexo.env.example)| Variable | Role |
|---|---|
DATABASE_URL | Postgres connection |
API_PORT / NEXT_PUBLIC_API_URL | API listen port and browser base URL |
SESSION_SECRET | Session cookie signing |
CORS_ORIGIN | Allowed web origin (default http://localhost:3000) |
LLM_PROVIDER | openrouter (default) | openai | scripted |
OPENROUTER_* / OPENAI_* | Keys and models for live providers |
TICKET_FAULT | off | unavailable | fail_once — ticket gateway fault injection |
LOG_LEVEL | Nest verbosity; agent business traces use context AgentTrace (grep AgentTrace) |
We run @mastra/core (Agent + createTool + generate) inside the Nest API process. The PRD prefers Mastra (or LangGraph.js); we picked Mastra because this product needs a short tool-calling loop, not a second orchestration graph — Nest already owns session, lease, HITL and persistence. LangGraph would duplicate that job for little gain here.
Provider default is OpenRouter + a free Nemotron model on purpose: the challenge allows any LLM, and this combo is the best cost/benefit for a public demo — evaluators get real multi-turn chat without us (or them) paying per token, while Mastra still routes a normal chat model. Paid OpenAI remains available if you prefer it; CI stays on scripted so proof does not depend on a vendor.
openrouter + free Nemotron: live agent UX at near-zero cost.openai: same Mastra path when you already have an OpenAI key/model.scripted: no network and no tokens — how CI proves the pipeline. Decision quality still comes from @nexo-assist/domain and integration tests, not from hoping the model is stable in CI.Two functional profiles are seeded for evaluators. There is no public signup and no admin panel.
| Profile | Purpose | |
|---|---|---|
[email protected] | employee | Chat, ticket consult, handoff to analyst |
[email protected] | analyst | Attendance console (claim / return / close) |
[email protected] | employee | Extra employee fixture (privacy / race) |
[email protected] | employee | Extra employee fixture (console queue) |
Demo password rule (evaluation only): any non-empty password is accepted for seeded emails (for example demo). Unknown email and empty password share one generic error. Passwords are not stored — the users table has no password column.
[email protected] and any non-empty password/chat — test conversation with the agent, ticket list/consulta, draft confirmation, and handoff phrases[email protected] and any non-empty password/console — test queue filters, claim, return to agent, close, and analyst messagesRole comes from the authenticated session on the API (EmployeeGuard / AnalystGuard). Hiding menus is not the security boundary.
UsageGuard enforces 30 employee messages / conversation, 4000 chars, one in-flight execution (atomic busyUntil claim), max 4 tool steps, last-10-message context, 20s provider timeout, 600 max output tokens. An open waiting_analyst / with_analyst conversation is reused — the API never opens a fresh with_agent thread to bypass pause or the message budget.@mastra/core. Model routing: openrouter/<OPENROUTER_MODEL> or openai/<OPENAI_MODEL>. Tools are only search_help, list_my_tickets, get_ticket, and prepare_draft. LLM_PROVIDER=scripted keeps a deterministic loop for CI without calling the model.@nexo-assist/domain applies Annex A: priority, business-hour SLA (America/Sao_Paulo), duplicity thresholds, reopen window (168h inclusive), and draft confirmation phrases.TicketGateway with operationId idempotency (create runs in a DB transaction). Create / update / reopen / transfer are never model tools.high / medium / low) and shown as expandable chips (intent, tool, rule, result, grau de segurança, justification).Logger lines under context AgentTrace (turn.started → turn.event rules/tools → turn.completed / turn.failed, plus draft.confirm). Filter API stdout with grep AgentTrace. Set LOG_LEVEL=debug for more Nest verbosity (default log).| Layer | Command | What it covers |
|---|---|---|
| Domain | pnpm --filter @nexo-assist/domain test | Priority, SLA, duplicity, transitions, confirmation, out-of-IT, confidence, draft completeness |
| API + Postgres | LLM_PROVIDER=scripted pnpm --filter @nexo-assist/api test | Owner privacy, HITL, out-of-IT, unsure offer, ticket fault retry, conversation reload |
| UI unit | pnpm --filter @nexo-assist/web test | Event labels + chat derivations |
| UI e2e | Install browsers once: pnpm --filter @nexo-assist/web exec playwright install — then with apps running: pnpm --filter @nexo-assist/web test:e2e | Login, chat, console claim, consulta |
| Types / build | pnpm typecheck / pnpm build | Strict TypeScript across packages |
Traceability: docs/TRACEABILITY.md.
apps/web Next.js employee chat + analyst console
apps/api NestJS session, UsageGuard, orchestrator, TicketGateway
packages/domain Pure Annex A rules (no framework, no LLM)
packages/contracts Shared Zod schemas
PostgreSQL is the source of truth for users, sessions, conversations, messages, drafts, tickets, history, help articles, operations and execution events. localStorage is not used as authority.
Agent module layout and decision ADRs: docs/agent.md, docs/architecture.md.
Security was part of the architecture from the start. An AI agent can interpret untrusted content and call tools that touch real operations, so we assume the model can be manipulated and keep critical controls in the application—not only in the prompt.
Main measures:
[untrusted_data] on the LLM boundary; policy lives in system instructions + server code.EmployeeGuard / AnalystGuard, owner checks on TicketGateway), independent of what the model suggests.search_help, list_my_tickets, get_ticket, prepare_draft). Create / update / reopen / transfer are not model tools.INC-20150).helmet, trust proxy, and @nestjs/throttler (tighter on login and message POST; health/SSE skipped).Central premise: do not rely on the LLM behaving. Contain blast radius in Nest + domain + HITL.
Threats and controls: docs/security/threat-model.md.
America/Sao_Paulo; business hours Mon–Fri 08:00–18:00 (10h/day). No holiday calendar.now <= resolvedAt + 168h. Does not create a new ticket.httpOnly + SameSite=Lax; TTL 15 minutes.| Surface | Where | URL |
|---|---|---|
Web (apps/web) | Vercel project nexo-assist | https://nexo-assist.connexto.com.br |
API (apps/api) | FlowDeploy (connexto-nexo-assist-api on the Outcoders VPS) | https://api-nexo-assist.connexto.com.br |
API health: GET https://api-nexo-assist.connexto.com.br/health/live. Production CORS allows the web origin above. LLM keys and SESSION_SECRET stay in the host env (not in the repo). Manifests: apps/api/paasdeploy.json + Traefik labels in apps/api/docker-compose.yml.
@nexo-assist/domain so priority/SLA/duplicity stay deterministic and unit-testable without calling a model. Ticket writes only go through TicketGateway after an exact draft version is confirmed.pnpm dev
pnpm test
pnpm lint
pnpm typecheck
pnpm build
pnpm db:migrate
pnpm db:seed