KOGRAL Forms & Configuration UI
This directory contains form definitions for the typedialog-web UI, enabling interactive configuration of KOGRAL knowledge bases.
Architecture
Forms use a fragment composition pattern for modularity and maintainability:
kogral-config.toml (main form)
├── includes: fragments/graph.toml
├── includes: fragments/storage.toml
├── includes: fragments/embeddings.toml
├── includes: fragments/query.toml
├── includes: fragments/mcp.toml
└── includes: fragments/sync.toml
File Structure
forms/
├── kogral-config.toml # Main form definition (composition)
├── README.md # This file
└── fragments/ # Reusable configuration fragments
├── graph.toml # Knowledge graph metadata
├── storage.toml # Storage backend options
├── embeddings.toml # Vector search & embedding provider
├── query.toml # Query engine tuning
├── mcp.toml # MCP server settings
└── sync.toml # Synchronization configuration
Fragment Design
Each fragment contains:
- Section Headers - Visual grouping in UI
- Field Elements - Input controls with:
nickel_path- Path in Nickel config (e.g.,["storage", "primary"])type- Field type (text, select, boolean, number, text_array)default- Default valuevisible_if- Conditional visibility ruleshelp- User help text
Example Fragment
[[elements]]
border_top = true
name = "storage_section_header"
title = "💾 Storage Backend"
type = "section_header"
[[elements]]
default = "filesystem"
help = "Primary storage backend for knowledge base"
name = "storage_primary"
nickel_path = ["storage", "primary"]
options = ["filesystem", "memory", "surrealdb"]
prompt = "Primary Storage"
type = "select"
nickel_path Mapping
The nickel_path field maps form fields to Nickel configuration structure:
nickel_path = ["storage", "primary"]
↓
Nickel: storage.primary = "filesystem"
↓
JSON export: { storage: { primary: "filesystem" } }
↓
Rust struct: config.storage.primary
Conditional Visibility
Fields can appear/disappear based on other field values:
visible_if = "storage_secondary_enabled == true"
visible_if = "embeddings_provider != 'fastembed'"
visible_if = "sync_auto_index == true && query_cross_graph == true"
Integration with typedialog-web
- Edit - User modifies form in typedialog-web
- Validate - Fields validated against nickel_path contracts
- Export - Changes written back to
.nclfiles - Generate -
generate-configs.nuexports to JSON - Load - Rust code loads from
.kogral/config.json
Adding New Configuration Sections
To add a new configuration section:
- Add new type to
core/contracts.ncl - Add defaults to
core/defaults.ncl - Create fragment file:
fragments/new-section.toml - Add
includesreference inkogral-config.toml - Run validation:
nu scripts/validate-config.nu
Fragment Naming Convention
- Use descriptive names:
storage.toml,embeddings.toml, notsection1.toml - For sub-sections:
fragments/mcp/tools.toml,fragments/storage/secondary.toml - Use lowercase with hyphens:
mcp-server.toml, notMCPServer.toml