gaard-core 0.2.7__tar.gz → 0.2.8__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {gaard_core-0.2.7 → gaard_core-0.2.8}/PKG-INFO +2 -2
- {gaard_core-0.2.7 → gaard_core-0.2.8}/pyproject.toml +2 -2
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/query_pipeline/llm_sql_generator.py +26 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/query_pipeline/models.py +1 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/query_pipeline/pipeline.py +46 -13
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core.egg-info/PKG-INFO +2 -2
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core.egg-info/requires.txt +1 -1
- {gaard_core-0.2.7 → gaard_core-0.2.8}/README.md +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/setup.cfg +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/__init__.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/conversation_context/__init__.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/conversation_context/llm_classifier.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/conversation_context/mock_classifier.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/errors.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/execution/__init__.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/execution/mock_executor.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/json_utils.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/llm_output.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/prompt_compiler/__init__.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/prompt_compiler/conversation_context_prompt.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/prompt_compiler/intent_classification_prompt.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/prompt_compiler/models.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/prompt_compiler/result_classification_prompt.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/prompt_compiler/result_interpretation_prompt.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/prompt_compiler/schema_formatter.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/prompt_compiler/sql_generation_prompt.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/py.typed +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/query_intent/__init__.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/query_intent/llm_classifier.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/query_intent/mock_classifier.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/query_pipeline/__init__.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/query_pipeline/mock_sql_generator.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/result_classifier/__init__.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/result_classifier/llm_classifier.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/result_classifier/mock_classifier.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/result_interpreter/__init__.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/result_interpreter/llm_interpreter.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/result_interpreter/mock_interpreter.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/schema/__init__.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/schema/cache.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/schema/context.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/schema/models.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/sql_validator/__init__.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/sql_validator/select_only.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core.egg-info/SOURCES.txt +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core.egg-info/dependency_links.txt +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core.egg-info/top_level.txt +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/tests/test_conversation_context_classifier.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/tests/test_json_utils.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/tests/test_llm_output.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/tests/test_llm_query_intent_classifier.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/tests/test_llm_result_classifier.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/tests/test_llm_result_interpreter.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/tests/test_llm_sql_generator.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/tests/test_query_pipeline.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/tests/test_result_classification_prompt_compiler.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/tests/test_result_interpretation_prompt_compiler.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/tests/test_schema_context_cache.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/tests/test_schema_context_service.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/tests/test_schema_prompt_formatter.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/tests/test_sql_generation_prompt_compiler.py +0 -0
- {gaard_core-0.2.7 → gaard_core-0.2.8}/tests/test_sql_validator.py +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gaard-core
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.8
|
|
4
4
|
Summary: Core GAARD query pipeline, prompt compiler, policies and SQL validation
|
|
5
5
|
Requires-Python: >=3.11
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
7
|
-
Requires-Dist: gaard-plugin-api<0.3.0,>=0.2.
|
|
7
|
+
Requires-Dist: gaard-plugin-api<0.3.0,>=0.2.8
|
|
8
8
|
Requires-Dist: pydantic>=2.7.0
|
|
9
9
|
Requires-Dist: sqlglot>=25.0.0
|
|
10
10
|
Provides-Extra: dev
|
|
@@ -4,12 +4,12 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "gaard-core"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.8"
|
|
8
8
|
description = "Core GAARD query pipeline, prompt compiler, policies and SQL validation"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
11
11
|
dependencies = [
|
|
12
|
-
"gaard-plugin-api>=0.2.
|
|
12
|
+
"gaard-plugin-api>=0.2.8,<0.3.0",
|
|
13
13
|
"pydantic>=2.7.0",
|
|
14
14
|
"sqlglot>=25.0.0",
|
|
15
15
|
]
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import logging
|
|
1
2
|
from typing import Any, Protocol
|
|
2
3
|
|
|
3
4
|
from gaard_core.prompt_compiler.models import CompiledPrompt, SqlGenerationPromptRequest
|
|
@@ -8,6 +9,9 @@ from gaard_llm.openai_compatible.client import OpenAICompatibleClient
|
|
|
8
9
|
from gaard_llm.providers.models import ChatCompletionRequest, ChatMessage
|
|
9
10
|
|
|
10
11
|
|
|
12
|
+
logger = logging.getLogger(__name__)
|
|
13
|
+
|
|
14
|
+
|
|
11
15
|
class SqlPromptCompiler(Protocol):
|
|
12
16
|
def compile(self, request: SqlGenerationPromptRequest) -> CompiledPrompt:
|
|
13
17
|
pass
|
|
@@ -42,6 +46,20 @@ class LlmSqlGenerator:
|
|
|
42
46
|
)
|
|
43
47
|
)
|
|
44
48
|
|
|
49
|
+
# This is deliberately logged as separate fields so a failed text-to-SQL
|
|
50
|
+
# request can be reconstructed from the service log without guessing
|
|
51
|
+
# which dialect or schema context reached the model.
|
|
52
|
+
logger.info(
|
|
53
|
+
"SQL generation request: model=%r dialect=%r max_rows=%s question=%r "
|
|
54
|
+
"system_prompt=%r user_prompt=%r",
|
|
55
|
+
self.model,
|
|
56
|
+
self.dialect,
|
|
57
|
+
self.max_rows,
|
|
58
|
+
request.question,
|
|
59
|
+
compiled_prompt.system_prompt,
|
|
60
|
+
compiled_prompt.user_prompt,
|
|
61
|
+
)
|
|
62
|
+
|
|
45
63
|
response = self.client.create_chat_completion(
|
|
46
64
|
ChatCompletionRequest(
|
|
47
65
|
model=self.model,
|
|
@@ -62,12 +80,20 @@ class LlmSqlGenerator:
|
|
|
62
80
|
|
|
63
81
|
sql = self._clean_sql(response.content)
|
|
64
82
|
|
|
83
|
+
logger.info(
|
|
84
|
+
"SQL generation response: model=%r raw_response=%r cleaned_sql=%r",
|
|
85
|
+
self.model,
|
|
86
|
+
response.content,
|
|
87
|
+
sql,
|
|
88
|
+
)
|
|
89
|
+
|
|
65
90
|
return GeneratedSql(
|
|
66
91
|
sql=sql,
|
|
67
92
|
confidence=0.0,
|
|
68
93
|
assumptions=[
|
|
69
94
|
"SQL generated by OpenAI-compatible LLM provider.",
|
|
70
95
|
],
|
|
96
|
+
prompt_metadata=compiled_prompt.metadata,
|
|
71
97
|
)
|
|
72
98
|
|
|
73
99
|
def _clean_sql(self, value: str) -> str:
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import logging
|
|
1
2
|
import time
|
|
3
|
+
from collections.abc import Callable
|
|
2
4
|
from typing import Protocol
|
|
3
5
|
|
|
4
6
|
from gaard_core.execution.mock_executor import MockQueryExecutor
|
|
@@ -16,6 +18,9 @@ from gaard_core.result_interpreter.mock_interpreter import MockResultInterpreter
|
|
|
16
18
|
from gaard_core.sql_validator.select_only import SelectOnlySqlValidator
|
|
17
19
|
|
|
18
20
|
|
|
21
|
+
logger = logging.getLogger(__name__)
|
|
22
|
+
|
|
23
|
+
|
|
19
24
|
class SqlGenerator(Protocol):
|
|
20
25
|
def generate(self, request: QueryRequest) -> GeneratedSql:
|
|
21
26
|
pass
|
|
@@ -57,7 +62,11 @@ class QueryPipeline:
|
|
|
57
62
|
self.result_interpretation_mode = result_interpretation_mode
|
|
58
63
|
self.output_classification_mode = output_classification_mode
|
|
59
64
|
|
|
60
|
-
def handle(
|
|
65
|
+
def handle(
|
|
66
|
+
self,
|
|
67
|
+
request: QueryRequest,
|
|
68
|
+
on_stage: Callable[[str], None] | None = None,
|
|
69
|
+
) -> QueryResponse:
|
|
61
70
|
started_at = time.perf_counter()
|
|
62
71
|
|
|
63
72
|
try:
|
|
@@ -70,28 +79,49 @@ class QueryPipeline:
|
|
|
70
79
|
error_detail=exc.message,
|
|
71
80
|
) from exc
|
|
72
81
|
|
|
82
|
+
logger.info(
|
|
83
|
+
"SQL pipeline generated query: datasource_id=%r datasource_ids=%r sql=%r "
|
|
84
|
+
"validator=%s executor=%s",
|
|
85
|
+
request.datasource_id,
|
|
86
|
+
request.datasource_ids,
|
|
87
|
+
generated_sql.sql,
|
|
88
|
+
type(self.sql_validator).__name__,
|
|
89
|
+
type(self.executor).__name__,
|
|
90
|
+
)
|
|
73
91
|
self.sql_validator.validate(generated_sql.sql)
|
|
92
|
+
logger.info("SQL pipeline validation passed: sql=%r", generated_sql.sql)
|
|
74
93
|
|
|
94
|
+
if on_stage is not None:
|
|
95
|
+
on_stage("waiting_on_data_server")
|
|
75
96
|
result = self.executor.execute(generated_sql.sql)
|
|
97
|
+
logger.info(
|
|
98
|
+
"SQL pipeline execution completed: sql=%r columns=%r row_count=%s",
|
|
99
|
+
generated_sql.sql,
|
|
100
|
+
result.columns,
|
|
101
|
+
len(result.rows),
|
|
102
|
+
)
|
|
76
103
|
if not request.interpret:
|
|
77
104
|
duration_ms = round((time.perf_counter() - started_at) * 1000, 2)
|
|
105
|
+
metadata = {
|
|
106
|
+
"duration_ms": duration_ms,
|
|
107
|
+
"datasource_id": request.datasource_id,
|
|
108
|
+
"user_id": request.user_id,
|
|
109
|
+
"confidence": generated_sql.confidence,
|
|
110
|
+
"assumptions": generated_sql.assumptions,
|
|
111
|
+
"sql_generation_mode": self.sql_generation_mode,
|
|
112
|
+
"result_interpretation_mode": "none",
|
|
113
|
+
"output_classification_mode": "none",
|
|
114
|
+
"output_classification": OutputClassification.UNKNOWN.value,
|
|
115
|
+
"raw_sql_output": True,
|
|
116
|
+
}
|
|
117
|
+
if generated_sql.prompt_metadata:
|
|
118
|
+
metadata["sql_generation_prompt_metadata"] = generated_sql.prompt_metadata
|
|
78
119
|
return QueryResponse(
|
|
79
120
|
question=request.question,
|
|
80
121
|
answer="",
|
|
81
122
|
sql=generated_sql.sql,
|
|
82
123
|
rows=result.rows,
|
|
83
|
-
metadata=
|
|
84
|
-
"duration_ms": duration_ms,
|
|
85
|
-
"datasource_id": request.datasource_id,
|
|
86
|
-
"user_id": request.user_id,
|
|
87
|
-
"confidence": generated_sql.confidence,
|
|
88
|
-
"assumptions": generated_sql.assumptions,
|
|
89
|
-
"sql_generation_mode": self.sql_generation_mode,
|
|
90
|
-
"result_interpretation_mode": "none",
|
|
91
|
-
"output_classification_mode": "none",
|
|
92
|
-
"output_classification": OutputClassification.UNKNOWN.value,
|
|
93
|
-
"raw_sql_output": True,
|
|
94
|
-
},
|
|
124
|
+
metadata=metadata,
|
|
95
125
|
)
|
|
96
126
|
|
|
97
127
|
try:
|
|
@@ -135,6 +165,9 @@ class QueryPipeline:
|
|
|
135
165
|
if classification_error:
|
|
136
166
|
metadata["output_classification_error"] = classification_error
|
|
137
167
|
|
|
168
|
+
if generated_sql.prompt_metadata:
|
|
169
|
+
metadata["sql_generation_prompt_metadata"] = generated_sql.prompt_metadata
|
|
170
|
+
|
|
138
171
|
return QueryResponse(
|
|
139
172
|
question=request.question,
|
|
140
173
|
answer=answer,
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gaard-core
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.8
|
|
4
4
|
Summary: Core GAARD query pipeline, prompt compiler, policies and SQL validation
|
|
5
5
|
Requires-Python: >=3.11
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
7
|
-
Requires-Dist: gaard-plugin-api<0.3.0,>=0.2.
|
|
7
|
+
Requires-Dist: gaard-plugin-api<0.3.0,>=0.2.8
|
|
8
8
|
Requires-Dist: pydantic>=2.7.0
|
|
9
9
|
Requires-Dist: sqlglot>=25.0.0
|
|
10
10
|
Provides-Extra: dev
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/conversation_context/mock_classifier.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/prompt_compiler/conversation_context_prompt.py
RENAMED
|
File without changes
|
{gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/prompt_compiler/intent_classification_prompt.py
RENAMED
|
File without changes
|
|
File without changes
|
{gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/prompt_compiler/result_classification_prompt.py
RENAMED
|
File without changes
|
{gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/prompt_compiler/result_interpretation_prompt.py
RENAMED
|
File without changes
|
|
File without changes
|
{gaard_core-0.2.7 → gaard_core-0.2.8}/src/gaard_core/prompt_compiler/sql_generation_prompt.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|