Chat with any SQLite database using natural language. Built on AnyLanguageModel (HuggingFace) for LLM-agnostic provider support and GRDB for SQLite access. Core features: - Auto schema introspection from sqlite_master (zero config) - NL → SQL generation via any AnyLanguageModel provider - Three rendering modes: text summary, data table, Swift Charts - Drop-in DataChatView (SwiftUI) and headless ChatEngine - Operation allowlist with read-only default - Mutation policy with per-table control - ToolExecutionDelegate for destructive operation confirmation - Multi-turn conversation context - 352 tests across 24 suites, all passing Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
192 lines
8.1 KiB
YAML
192 lines
8.1 KiB
YAML
###############################################################################
|
|
# SwiftDBAI — Seed Specification
|
|
# Generated from Socratic interview on 2026-04-03
|
|
###############################################################################
|
|
|
|
goal: >
|
|
Build SwiftDBAI — a Swift package that lets users chat with any SQLite
|
|
database using natural language. Built on AnyLanguageModel (HuggingFace)
|
|
for LLM-agnostic provider support and GRDB for SQLite access. Ships a
|
|
drop-in SwiftUI ChatView, a headless ChatEngine, auto-schema introspection,
|
|
and result rendering with text, tables, and Swift Charts.
|
|
|
|
constraints:
|
|
- Swift 6.1+ with strict concurrency checking
|
|
- Swift Package Manager only (no CocoaPods/Carthage)
|
|
- iOS 17.0+, macOS 14.0+, visionOS 1.0+
|
|
- GRDB for all SQLite access (no raw sqlite3 C API)
|
|
- AnyLanguageModel (HuggingFace) as the sole LLM abstraction layer
|
|
- Any SQLite database supported (not limited to SwiftData)
|
|
- No UIKit dependency — pure SwiftUI for the view layer
|
|
- No Apple Intelligence / Foundation Models dependency
|
|
- Developer provides their own GRDB DatabasePool or DatabaseQueue
|
|
- SQL operation allowlist configured by developer (SELECT, INSERT, UPDATE, DELETE)
|
|
- No SQL parser — allowlist check is sufficient for validation
|
|
- Zero telemetry — the package collects nothing
|
|
|
|
acceptance_criteria:
|
|
- Auto-introspects any SQLite database schema from sqlite_master (tables, columns, types, foreign keys)
|
|
- LLM generates valid SQL queries from natural language input
|
|
- Query results render as natural language text summaries
|
|
- Query results render as scrollable data tables
|
|
- Aggregate/numeric results render as Swift Charts
|
|
- Drop-in DataChatView works with minimal setup (< 10 lines of code)
|
|
- Headless ChatEngine supports programmatic query/response without UI
|
|
- Multi-turn conversation context maintained (follow-up queries work)
|
|
- Mutation operations (INSERT, UPDATE, DELETE) work when allowlisted
|
|
- Destructive operations require confirmation via ToolExecutionDelegate
|
|
- All AnyLanguageModel providers work (OpenAI, Anthropic, Gemini, Ollama, CoreML, MLX, llama.cpp)
|
|
- Error states (bad SQL, LLM failure, schema mismatch) handled gracefully in UI
|
|
- Package binary adds < 2 MB to app (excluding LLM model weights)
|
|
|
|
ontology_schema:
|
|
name: SwiftDBAI
|
|
description: >
|
|
Domain model for a conversational SQLite query engine that bridges
|
|
natural language, LLM tool calls, SQL generation, and result rendering.
|
|
fields:
|
|
- name: database_schema
|
|
type: object
|
|
description: >
|
|
Auto-introspected SQLite schema containing tables, columns
|
|
(name, type, nullable, default), primary keys, foreign keys,
|
|
and indexes. Derived from sqlite_master at init time.
|
|
|
|
- name: chat_engine
|
|
type: object
|
|
description: >
|
|
Orchestrator that manages the conversation loop: accepts user
|
|
messages, injects schema context into the LLM system prompt,
|
|
calls AnyLanguageModel LanguageModelSession with registered
|
|
SQL tools, executes resulting SQL, and formats responses.
|
|
|
|
- name: sql_tools
|
|
type: array
|
|
description: >
|
|
AnyLanguageModel Tool conformances: QueryTool (SELECT),
|
|
InsertTool (INSERT), UpdateTool (UPDATE), DeleteTool (DELETE),
|
|
AggregateTool (COUNT/SUM/AVG/MIN/MAX). Each uses @Generable
|
|
arguments. Developer's allowlist controls which tools are active.
|
|
|
|
- name: query_result
|
|
type: object
|
|
description: >
|
|
Structured result from SQL execution containing: raw rows
|
|
(array of dictionaries), column metadata, row count, execution
|
|
time, and the generated SQL string for transparency.
|
|
|
|
- name: chat_message
|
|
type: object
|
|
description: >
|
|
A single message in the conversation. Has a role (user/assistant/system),
|
|
text content, optional query_result attachment, optional chart_data
|
|
for Swift Charts rendering, and a timestamp.
|
|
|
|
- name: chat_view
|
|
type: object
|
|
description: >
|
|
Drop-in SwiftUI view that renders chat_messages with three
|
|
result modes: text summary, data table, and Swift Charts.
|
|
Handles input, loading states, error display, and confirmation
|
|
dialogs for mutations. Themeable.
|
|
|
|
- name: operation_allowlist
|
|
type: object
|
|
description: >
|
|
Developer-configured set of permitted SQL operations. Maps to
|
|
mutationPolicy: readOnly (SELECT only), standard (SELECT + INSERT +
|
|
UPDATE), unrestricted (all including DELETE), or custom set.
|
|
|
|
- name: llm_provider
|
|
type: object
|
|
description: >
|
|
Any AnyLanguageModel-compatible language model instance passed
|
|
by the developer. The kit never instantiates providers itself —
|
|
developer chooses and configures their preferred backend.
|
|
|
|
evaluation_principles:
|
|
- name: zero_config_reads
|
|
description: >
|
|
A developer with an existing SQLite database should be able to
|
|
chat with their data by providing only a GRDB connection and an
|
|
AnyLanguageModel instance. No schema files, no annotations, no setup.
|
|
weight: 0.25
|
|
|
|
- name: sql_correctness
|
|
description: >
|
|
Generated SQL must be valid for the target schema. Column names,
|
|
table names, and types must match the introspected schema. Queries
|
|
should not reference non-existent tables or columns.
|
|
weight: 0.25
|
|
|
|
- name: safety_by_default
|
|
description: >
|
|
The default configuration must be read-only (SELECT only). Write
|
|
operations require explicit opt-in via the allowlist. Destructive
|
|
operations (DELETE, DROP) must require confirmation even when allowed.
|
|
weight: 0.20
|
|
|
|
- name: provider_agnosticism
|
|
description: >
|
|
All features must work identically regardless of which AnyLanguageModel
|
|
provider is used. No provider-specific code paths in the core kit.
|
|
Tool definitions must use standard AnyLanguageModel Tool protocol.
|
|
weight: 0.15
|
|
|
|
- name: rendering_quality
|
|
description: >
|
|
Results must be presented clearly: text summaries are natural and
|
|
concise, data tables are scrollable and readable, charts are
|
|
auto-selected based on data shape (bar for categories, line for
|
|
time series, pie for proportions).
|
|
weight: 0.15
|
|
|
|
exit_conditions:
|
|
- name: core_query_loop
|
|
description: User can type a natural language question and get correct SQL results
|
|
criteria: >
|
|
End-to-end works: NL input → schema context → LLM tool call →
|
|
SQL generation → GRDB execution → formatted response in ChatView
|
|
|
|
- name: all_result_modes
|
|
description: All three rendering modes (text, table, chart) work
|
|
criteria: >
|
|
Text summaries render for all queries. Data tables render for
|
|
multi-row results. Swift Charts render for numeric/aggregate data.
|
|
|
|
- name: mutation_safety
|
|
description: Write operations are safe and controllable
|
|
criteria: >
|
|
Allowlist correctly blocks disallowed operations. Confirmation
|
|
dialog appears for destructive ops. Mutations execute correctly
|
|
when confirmed.
|
|
|
|
- name: multi_provider
|
|
description: Works with at least 3 different AnyLanguageModel providers
|
|
criteria: >
|
|
Tested with OpenAI, Anthropic, and Ollama. Same queries produce
|
|
equivalent results across providers.
|
|
|
|
- name: integration_time
|
|
description: New developer can integrate in under 5 minutes
|
|
criteria: >
|
|
README example compiles and runs. DataChatView renders and
|
|
responds to queries with < 10 lines of setup code.
|
|
|
|
metadata:
|
|
version: "1.0"
|
|
generated: "2026-04-03"
|
|
source: socratic_interview
|
|
ambiguity_score: 0.15
|
|
interview_decisions:
|
|
data_layer: "All SQL via GRDB (not SwiftData APIs)"
|
|
scope: "Any SQLite database"
|
|
schema_discovery: "Auto-introspect from sqlite_master"
|
|
safety_model: "Developer-configured operation allowlist"
|
|
sql_validation: "Allowlist check only (no SQL parser)"
|
|
connection_model: "Developer passes GRDB DatabasePool/DatabaseQueue"
|
|
ui_rendering: "Text + data table + Swift Charts"
|
|
target_audience: "Both app developers (ChatView) and debuggers (headless)"
|
|
timeline: "6-8 weeks, polished release"
|
|
llm_layer: "AnyLanguageModel (HuggingFace)"
|