7da5ffb92a
docs(02-agent-features): create phase plan
2026-03-23 14:23:11 -06:00
ac54d819f8
docs(02): add research and validation strategy
2026-03-23 14:16:42 -06:00
3fe334b702
docs(02-agent-features): research phase domain
2026-03-23 14:15:40 -06:00
e48fbaa3d4
docs(state): record phase 2 context session
2026-03-23 13:12:16 -06:00
1f070e2a64
docs(02): capture phase context
2026-03-23 13:12:09 -06:00
6f4445f982
docs(phase-1): complete phase execution
2026-03-23 10:39:30 -06:00
44f5b98890
docs(01-03): complete Channel Gateway + Message Router plan
2026-03-23 10:34:50 -06:00
74326dfc3d
feat(01-03): integration tests for Slack flow, rate limiting, and agent persona
...
- tests/unit/test_ratelimit.py: 11 tests for Redis token bucket (CHAN-05)
- allows requests under limit, rejects 31st request
- per-tenant isolation, per-channel isolation
- TTL key expiry and window reset
- tests/integration/test_slack_flow.py: 15 tests for end-to-end Slack flow (CHAN-02)
- normalization: bot token stripped, channel=slack, thread_id set
- @mention: placeholder posted in-thread, Celery dispatched with placeholder_ts
- DM flow: same pipeline triggered for channel_type=im
- bot messages silently ignored (no infinite loop)
- unknown workspace_id silently ignored
- duplicate events (Slack retries) skipped via idempotency
- tests/integration/test_agent_persona.py: 15 tests for persona in prompts (AGNT-01)
- system prompt contains name, role, persona, AI transparency clause
- model_preference forwarded to LLM pool
- full messages array: [system, user] structure verified
- tests/integration/test_ratelimit.py: 4 tests for rate limit integration
- over-limit -> ephemeral rejection posted
- over-limit -> Celery NOT dispatched, placeholder NOT posted
- within-limit -> no rejection
- ephemeral message includes actionable retry hint
All 45 tests pass
2026-03-23 10:32:48 -06:00
6f30705e1a
feat(01-03): Channel Gateway (Slack adapter) and Message Router
...
- gateway/normalize.py: normalize_slack_event -> KonstructMessage (strips bot mention)
- gateway/channels/slack.py: register_slack_handlers for app_mention + DM events
- rate limit check -> ephemeral rejection on exceeded
- idempotency dedup (Slack retry protection)
- placeholder 'Thinking...' message posted in-thread before Celery dispatch
- auto-follow engaged threads with 30-minute TTL
- HTTP 200 returned immediately; all LLM work dispatched to Celery
- gateway/main.py: FastAPI on port 8001, /slack/events + /health
- router/tenant.py: resolve_tenant workspace_id -> tenant_id (RLS-bypass query)
- router/ratelimit.py: check_rate_limit Redis token bucket, RateLimitExceeded exception
- router/idempotency.py: is_duplicate + mark_processed (SET NX, 24h TTL)
- router/context.py: load_agent_for_tenant with RLS ContextVar setup
- orchestrator/tasks.py: handle_message now extracts placeholder_ts/channel_id,
calls _update_slack_placeholder via chat.update after LLM response
- docker-compose.yml: gateway service on port 8001
- pyproject.toml: added redis, konstruct-router, konstruct-orchestrator deps
2026-03-23 10:27:59 -06:00
dcd89cc8fd
docs(01-04): complete portal plan — tenant/agent CRUD and Agent Designer
...
- Create 01-04-SUMMARY.md documenting FastAPI portal API and Next.js portal
- Update STATE.md: advance plan, record metrics, add decisions
- Update ROADMAP.md: phase 1 plan progress (3/4 summaries)
- Update REQUIREMENTS.md: mark PRTA-01, PRTA-02 complete
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-03-23 10:22:22 -06:00
cec7180fb0
feat(01-04): Next.js 16 admin portal with Auth.js v5, tenant CRUD, and Agent Designer
...
- Initialize Next.js 16 project in packages/portal/ with TypeScript, Tailwind 4, shadcn/ui
- Auth.js v5 with Credentials provider calling FastAPI /auth/verify endpoint
- proxy.ts (Next.js 16 replacement for middleware.ts) protects all routes
- Login page with React Hook Form + zod validation (standard-schema resolver for zod v4 compat)
- Agent Designer: prominent dedicated module with Identity, Personality, Configuration,
Capabilities, Escalation, and Status sections; employee-centric language throughout
- Tenant CRUD: list, create (slug auto-gen), view/edit, delete with confirmation
- TanStack Query hooks for all API operations with proper cache invalidation
- Route group (dashboard) provides shared Nav sidebar + QueryClientProvider
- Update docker-compose.yml to add portal service on port 3000
- Deviations: middleware.ts renamed to proxy.ts in Next.js 16; zodResolver replaced with
standardSchemaResolver for zod v4 + @hookform/resolvers v5 compatibility
2026-03-23 10:19:40 -06:00
0eae48699f
docs(01-02): complete LLM pool and orchestrator plan
2026-03-23 10:08:55 -06:00
8257c554d7
feat(01-02): Celery orchestrator — handle_message task, system prompt builder, LLM pool runner
...
- Create orchestrator/main.py: Celery app with Redis broker/backend, task_acks_late=True, 10-min timeout
- Create orchestrator/tasks.py: SYNC def handle_message (critical pattern: asyncio.run for async work)
- Deserializes KonstructMessage, sets RLS context, loads agent from DB, calls run_agent
- Retries up to 3x on deserialization failure
- Create orchestrator/agents/builder.py: build_system_prompt assembles system_prompt + identity + persona + AI transparency clause
- Create orchestrator/agents/runner.py: run_agent posts to llm-pool /complete via httpx, returns polite fallback on error
- Add Celery[redis] dependency to orchestrator pyproject.toml
- Create tests/integration/test_llm_fallback.py: 7 tests for fallback routing and 503 on total failure (LLM-01)
- Create tests/integration/test_llm_providers.py: 12 tests verifying all three providers configured correctly (LLM-02)
- All 19 integration tests pass
2026-03-23 10:06:44 -06:00
7b348b97e9
feat(01-04): FastAPI portal API endpoints with tenant/agent CRUD and auth
...
- Add packages/shared/shared/api/portal.py with APIRouter at /api/portal
- POST /auth/verify validates bcrypt credentials against portal_users table
- POST /auth/register creates new portal users with hashed passwords
- Tenant CRUD: GET/POST /tenants, GET/PUT/DELETE /tenants/{id}
- Agent CRUD: full CRUD under /tenants/{tenant_id}/agents/{id}
- Agent endpoints set RLS current_tenant_id context for policy compliance
- Pydantic v2 schemas with slug validation (lowercase, hyphens, 2-50 chars)
- Add bcrypt>=4.0.0 dependency to konstruct-shared
- Integration tests: 38 tests covering all CRUD, validation, and isolation
2026-03-23 10:05:07 -06:00
ee2f88e13b
feat(01-02): LLM Backend Pool — LiteLLM Router with Ollama + Anthropic + OpenAI fallback
...
- Create llm_pool/router.py: LiteLLM Router with fast (Ollama) and quality (Anthropic/OpenAI) model groups
- Configure fallback chain: quality providers fail -> fast group
- Pin LiteLLM to ==1.82.5 (avoid September 2025 OOM regression in later releases)
- Create llm_pool/main.py: FastAPI service on port 8004 with /complete and /health endpoints
- Add providers/__init__.py: reserved for future per-provider customization
- Update docker-compose.yml: add llm-pool and celery-worker service stubs
2026-03-23 10:03:05 -06:00
0054383be0
docs(01-foundation-01): complete monorepo scaffolding and RLS tenant isolation plan
2026-03-23 09:59:55 -06:00
47e78627fd
feat(01-foundation-01): Alembic migrations with RLS and tenant isolation tests
...
- alembic.ini + migrations/env.py: async SQLAlchemy migration setup using asyncpg
- migrations/versions/001_initial_schema.py: creates tenants, agents, channel_connections, portal_users
- ENABLE + FORCE ROW LEVEL SECURITY on agents and channel_connections
- RLS policy: tenant_id = current_setting('app.current_tenant', TRUE)::uuid
- konstruct_app role created with SELECT/INSERT/UPDATE/DELETE on all tables
- packages/shared/shared/rls.py: idempotent configure_rls_hook, UUID-sanitized SET LOCAL
- tests/conftest.py: test_db_name (session-scoped), db_engine + db_session as konstruct_app
- tests/unit/test_normalize.py: 11 tests for KonstructMessage Slack normalization (CHAN-01)
- tests/unit/test_tenant_resolution.py: 7 tests for workspace_id → tenant resolution (TNNT-02)
- tests/unit/test_redis_namespacing.py: 15 tests for Redis key namespace isolation (TNNT-03)
- tests/integration/test_tenant_isolation.py: 7 tests proving RLS tenant isolation (TNNT-01)
- tenant_b cannot see tenant_a's agents or channel_connections
- FORCE ROW LEVEL SECURITY verified via pg_class.relforcerowsecurity
2026-03-23 09:57:29 -06:00
5714acf741
feat(01-foundation-01): monorepo scaffolding, Docker Compose, and shared data models
...
- pyproject.toml: uv workspace with 5 member packages (shared, gateway, router, orchestrator, llm-pool)
- docker-compose.yml: PostgreSQL 16 + Redis 7 + Ollama services on konstruct-net
- .env.example: all required env vars documented, konstruct_app role (not superuser)
- scripts/init-db.sh: creates konstruct_app role at DB init time
- packages/shared/shared/config.py: Pydantic Settings loading all env vars
- packages/shared/shared/models/message.py: KonstructMessage, ChannelType, SenderInfo, MessageContent
- packages/shared/shared/models/tenant.py: Tenant, Agent, ChannelConnection SQLAlchemy 2.0 models
- packages/shared/shared/models/auth.py: PortalUser model for admin portal auth
- packages/shared/shared/db.py: async SQLAlchemy engine, session factory, get_session dependency
- packages/shared/shared/rls.py: current_tenant_id ContextVar and configure_rls_hook with parameterized SET LOCAL
- packages/shared/shared/redis_keys.py: tenant-namespaced key constructors (rate_limit, idempotency, session, engaged_thread)
2026-03-23 09:49:28 -06:00
d611a07cc2
docs(01-foundation): create phase plan
2026-03-23 09:32:44 -06:00
60080980da
docs(01): add research and validation strategy
2026-03-23 09:26:15 -06:00
2ab18fde4f
docs(01): research phase 1 foundation domain
2026-03-23 09:25:20 -06:00
fe3b36be16
docs(state): record phase 1 context session
2026-03-23 09:20:02 -06:00
d032d81171
docs(01): capture phase context
2026-03-23 09:19:53 -06:00
f39508d297
docs: create roadmap (3 phases)
2026-03-23 09:06:16 -06:00
353f9b3f12
docs: define v1 requirements
2026-03-23 08:53:20 -06:00
376982f16f
docs: complete project research
2026-03-22 00:12:58 -06:00
320da9df87
chore: add project config
2026-03-22 00:03:51 -06:00
fa3aea5f29
docs: initialize project
2026-03-22 00:01:49 -06:00