Skip to content

Commit 0ff1406

Browse files
committed
refactor: fix last 3 CodeFlow issues
Remove unused model param in _send_with_json_mode, extract _handle_validation_result to reduce _refinement_loop McCabe from 11 to ~8, eliminate SQL schema duplication in quick_demo.py by reusing build_demo_db
1 parent 831c074 commit 0ff1406

3 files changed

Lines changed: 74 additions & 95 deletions

File tree

examples/quick_demo.py

Lines changed: 24 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -12,98 +12,44 @@
1212
1313
Perfect for live demonstrations!
1414
"""
15+
1516
from __future__ import annotations
1617

1718
import sqlite3
1819
from pathlib import Path
1920

21+
from build_demo_db import build as build_demo
2022
from rich.console import Console
21-
from rich.progress import Progress, SpinnerColumn, TextColumn, BarColumn, TimeElapsedColumn, TimeRemainingColumn
23+
from rich.progress import BarColumn, Progress, SpinnerColumn, TextColumn, TimeElapsedColumn, TimeRemainingColumn
2224
from rich.table import Table
2325

2426
from sqlseed import fill
2527

2628

27-
# ── Schema ──────────────────────────────────────────────────────
28-
SCHEMA_SQL = """
29-
CREATE TABLE organizations (
30-
org_code VARCHAR(16) PRIMARY KEY,
31-
name VARCHAR(64) NOT NULL,
32-
description TEXT,
33-
is_active INTEGER DEFAULT 1,
34-
member_count INTEGER DEFAULT 0,
35-
created_at TEXT
36-
);
37-
38-
CREATE TABLE members (
39-
member_id INTEGER PRIMARY KEY AUTOINCREMENT,
40-
name VARCHAR(64) NOT NULL,
41-
email VARCHAR(128) NOT NULL UNIQUE,
42-
phone VARCHAR(20),
43-
org_code VARCHAR(16) NOT NULL,
44-
is_active INTEGER DEFAULT 1,
45-
registered_at TEXT,
46-
FOREIGN KEY (org_code) REFERENCES organizations(org_code)
47-
);
48-
49-
CREATE TABLE projects (
50-
project_id INTEGER PRIMARY KEY AUTOINCREMENT,
51-
name VARCHAR(128) NOT NULL,
52-
org_code VARCHAR(16) NOT NULL,
53-
budget REAL DEFAULT 0.0,
54-
is_public INTEGER DEFAULT 0,
55-
created_at TEXT,
56-
FOREIGN KEY (org_code) REFERENCES organizations(org_code)
57-
);
58-
59-
CREATE TABLE tasks (
60-
task_id INTEGER PRIMARY KEY AUTOINCREMENT,
61-
project_id INTEGER NOT NULL,
62-
assignee_id INTEGER NOT NULL,
63-
title VARCHAR(256) NOT NULL,
64-
priority INTEGER DEFAULT 1,
65-
status INTEGER DEFAULT 0,
66-
is_completed INTEGER DEFAULT 0,
67-
due_at TEXT,
68-
FOREIGN KEY (project_id) REFERENCES projects(project_id),
69-
FOREIGN KEY (assignee_id) REFERENCES members(member_id)
70-
);
71-
"""
72-
73-
7429
def main():
7530
console = Console()
76-
31+
7732
# Step 1: Create database
7833
console.print("\n[bold blue]🚀 QuickStart Demo: sqlseed SQLite Test Data Generator[/bold blue]")
79-
console.print("="*60)
80-
34+
console.print("=" * 60)
35+
8136
with Progress(
8237
SpinnerColumn(),
8338
TextColumn("[progress.description]{task.description}"),
8439
console=console,
8540
transient=False,
8641
) as progress:
8742
task = progress.add_task("Creating demo database...", total=None)
88-
db_path = str(Path(__file__).parent / "_demo.db")
89-
90-
# Remove old if exists
91-
if Path(db_path).exists():
92-
Path(db_path).unlink()
93-
94-
conn = sqlite3.connect(db_path)
95-
conn.executescript(SCHEMA_SQL)
96-
conn.commit()
97-
conn.close()
43+
db_path = str(build_demo(Path(__file__).parent / "_demo.db"))
9844
progress.update(task, completed=1)
99-
45+
10046
console.print(f"✅ Database created: [green]{db_path}[/green]")
101-
47+
10248
# Step 2: Fill data with progress
10349
console.print("\n[bold blue]📊 Filling test data with real-time progress:[/bold blue]")
104-
50+
10551
fill_stats = []
106-
52+
10753
with Progress(
10854
SpinnerColumn(),
10955
TextColumn("[progress.description]{task.description}"),
@@ -121,48 +67,48 @@ def main():
12167
result = fill(db_path, table="organizations", count=10)
12268
fill_stats.append(("organizations", result.count, result.elapsed))
12369
progress.update(task, completed=10)
124-
70+
12571
# members
12672
task = progress.add_task("members", total=100)
12773
result = fill(db_path, table="members", count=100)
12874
fill_stats.append(("members", result.count, result.elapsed))
12975
progress.update(task, completed=100)
130-
76+
13177
# projects
13278
task = progress.add_task("projects", total=30)
13379
result = fill(db_path, table="projects", count=30)
13480
fill_stats.append(("projects", result.count, result.elapsed))
13581
progress.update(task, completed=30)
136-
82+
13783
# tasks
13884
task = progress.add_task("tasks", total=200)
13985
result = fill(db_path, table="tasks", count=200)
14086
fill_stats.append(("tasks", result.count, result.elapsed))
14187
progress.update(task, completed=200)
142-
88+
14389
# Step 3: Show summary
14490
console.print("\n[bold blue]📈 Fill Summary:[/bold blue]")
14591
table = Table(show_header=True, header_style="bold green")
14692
table.add_column("Table")
14793
table.add_column("Rows")
14894
table.add_column("Time (s)", justify="right")
149-
95+
15096
total_rows = 0
15197
total_time = 0.0
15298
for table_name, count, elapsed in fill_stats:
15399
table.add_row(table_name, str(count), f"{elapsed:.2f}")
154100
total_rows += count
155101
total_time += elapsed
156-
102+
157103
table.add_row("[bold]Total[/bold]", str(total_rows), f"[bold]{total_time:.2f}[/bold]")
158104
console.print(table)
159-
105+
160106
# Step 4: Show sample data
161107
console.print("\n[bold blue]🔍 Sample Data Preview:[/bold blue]")
162-
108+
163109
conn = sqlite3.connect(db_path)
164110
conn.row_factory = sqlite3.Row
165-
111+
166112
# Preview members
167113
console.print("\n[bold green]members[/bold green] (3 rows):")
168114
cursor = conn.execute("SELECT member_id, name, email, org_code FROM members LIMIT 3")
@@ -173,7 +119,7 @@ def main():
173119
for row in rows:
174120
member_table.add_row(*[str(row[c]) for c in ("member_id", "name", "email", "org_code")])
175121
console.print(member_table)
176-
122+
177123
# Preview tasks
178124
console.print("\n[bold green]tasks[/bold green] (3 rows):")
179125
cursor = conn.execute("SELECT task_id, project_id, title, priority, status FROM tasks LIMIT 3")
@@ -184,11 +130,11 @@ def main():
184130
for row in rows:
185131
task_table.add_row(*[str(row[c]) for c in ("task_id", "project_id", "title", "priority", "status")])
186132
console.print(task_table)
187-
133+
188134
conn.close()
189-
135+
190136
# Step 5: Final message
191-
console.print("\n" + "="*60)
137+
console.print("\n" + "=" * 60)
192138
console.print("[bold green]🎉 Demo Complete! [/bold green]")
193139
console.print("\nKey Features Demonstrated:")
194140
console.print(" • Auto-schema detection")

plugins/sqlseed-ai/src/sqlseed_ai/analyzer.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -558,7 +558,7 @@ def _send_llm_request(
558558

559559
# Try JSON mode for cloud backends; skip for local backends
560560
if self._config.backend in (AIBackend.GOOGLE_AI_STUDIO, AIBackend.OPENAI_COMPAT):
561-
return self._send_with_json_mode(client, kwargs, model)
561+
return self._send_with_json_mode(client, kwargs)
562562

563563
# Local backends (LM Studio, Ollama): use text mode directly
564564
return self._create_with_reasoning_fallback(client, kwargs)
@@ -567,7 +567,6 @@ def _send_with_json_mode(
567567
self,
568568
client: Any,
569569
kwargs: dict[str, Any],
570-
model: str | None,
571570
) -> Any:
572571
"""Send LLM request with JSON mode, falling back to text mode on error."""
573572
kwargs["response_format"] = {"type": "json_object"}

plugins/sqlseed-ai/src/sqlseed_ai/refiner.py

Lines changed: 49 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,42 @@ def _try_prompt_levels(
158158
return None, summarize_error(e), min_prompt_level
159159
return None, None, min_prompt_level
160160

161+
def _handle_validation_result(
162+
self,
163+
orch: Any,
164+
table_name: str,
165+
schema_hash: str,
166+
config_dict: dict[str, Any],
167+
attempt: int,
168+
max_retries: int,
169+
messages_history: list[dict[str, str]],
170+
last_error_type: str | None,
171+
same_error_count: int,
172+
on_progress: Callable[[str, dict[str, Any]], None] | None = None,
173+
) -> tuple[dict[str, Any] | None, str | None, int]:
174+
"""Handle validation result: return config on success, or update retry state.
175+
176+
Returns:
177+
(config_dict if valid else None, updated last_error_type, updated same_error_count)
178+
"""
179+
val_error = self._validate_config(orch, table_name, config_dict)
180+
181+
if val_error is None:
182+
logger.info("AI config validated successfully", table_name=table_name, attempts=attempt + 1)
183+
self._cache_successful_config(table_name, config_dict, schema_hash)
184+
if on_progress:
185+
on_progress("done", {"tokens": 0, "model": "validated"})
186+
return config_dict, last_error_type, same_error_count
187+
188+
last_error_type, same_error_count = self._check_repeated_error(val_error, last_error_type, same_error_count)
189+
self._handle_validation_failure(val_error, attempt, max_retries, table_name)
190+
191+
messages_history.append({"role": "assistant", "content": json.dumps(config_dict, ensure_ascii=False)})
192+
messages_history.append(
193+
{"role": "user", "content": self._build_refinement_prompt(val_error, attempt, max_retries)}
194+
)
195+
return None, last_error_type, same_error_count
196+
161197
def _refinement_loop(
162198
self,
163199
orch: Any,
@@ -218,22 +254,20 @@ def _refinement_loop(
218254
if on_progress:
219255
on_progress("validating", {"attempt": attempt})
220256

221-
val_error = self._validate_config(orch, table_name, config_dict)
222-
223-
if val_error is None:
224-
logger.info("AI config validated successfully", table_name=table_name, attempts=attempt + 1)
225-
self._cache_successful_config(table_name, config_dict, schema_hash)
226-
if on_progress:
227-
on_progress("done", {"tokens": 0, "model": "validated"})
228-
return config_dict
229-
230-
last_error_type, same_error_count = self._check_repeated_error(val_error, last_error_type, same_error_count)
231-
self._handle_validation_failure(val_error, attempt, max_retries, table_name)
232-
233-
messages_history.append({"role": "assistant", "content": json.dumps(config_dict, ensure_ascii=False)})
234-
messages_history.append(
235-
{"role": "user", "content": self._build_refinement_prompt(val_error, attempt, max_retries)}
257+
result, last_error_type, same_error_count = self._handle_validation_result(
258+
orch,
259+
table_name,
260+
schema_hash,
261+
config_dict,
262+
attempt,
263+
max_retries,
264+
messages_history,
265+
last_error_type,
266+
same_error_count,
267+
on_progress,
236268
)
269+
if result is not None:
270+
return result
237271

238272
raise AISuggestionFailedError("Unexpected state")
239273

0 commit comments

Comments
 (0)