gaard-api 0.1.2__tar.gz → 0.1.3__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_api-0.1.2/src/gaard_api.egg-info → gaard_api-0.1.3}/PKG-INFO +1 -1
- {gaard_api-0.1.2 → gaard_api-0.1.3}/pyproject.toml +1 -1
- {gaard_api-0.1.2 → gaard_api-0.1.3}/src/gaard_api/admin/services.py +98 -0
- gaard_api-0.1.3/src/gaard_api/admin-web/assets/main.js +2215 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3}/src/gaard_api/admin-web/assets/styles.css +62 -2
- {gaard_api-0.1.2 → gaard_api-0.1.3}/src/gaard_api/admin-web/src/main.ts +351 -36
- {gaard_api-0.1.2 → gaard_api-0.1.3}/src/gaard_api/api/v1/admin.py +144 -1
- gaard_api-0.1.3/src/gaard_api/api_registry.py +266 -0
- gaard_api-0.1.3/src/gaard_api/extension_services.py +82 -0
- gaard_api-0.1.3/src/gaard_api/extensions.py +50 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3}/src/gaard_api/main.py +3 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3/src/gaard_api.egg-info}/PKG-INFO +1 -1
- {gaard_api-0.1.2 → gaard_api-0.1.3}/src/gaard_api.egg-info/SOURCES.txt +3 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3}/tests/test_admin_api.py +226 -0
- gaard_api-0.1.3/tests/test_api_registry.py +101 -0
- gaard_api-0.1.2/src/gaard_api/admin-web/assets/main.js +0 -2111
- gaard_api-0.1.2/src/gaard_api/extensions.py +0 -18
- {gaard_api-0.1.2 → gaard_api-0.1.3}/MANIFEST.in +0 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3}/README.md +0 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3}/setup.cfg +0 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3}/src/gaard_api/__init__.py +0 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3}/src/gaard_api/admin/__init__.py +0 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3}/src/gaard_api/admin/database.py +0 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3}/src/gaard_api/admin/defaults.py +0 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3}/src/gaard_api/admin/models.py +0 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3}/src/gaard_api/admin/prompt_runtime.py +0 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3}/src/gaard_api/admin/security.py +0 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3}/src/gaard_api/admin-web/index.html +0 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3}/src/gaard_api/admin-web/package.json +0 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3}/src/gaard_api/api/__init__.py +0 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3}/src/gaard_api/api/v1/__init__.py +0 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3}/src/gaard_api/api/v1/prompts.py +0 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3}/src/gaard_api/api/v1/query.py +0 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3}/src/gaard_api/api/v1/schema.py +0 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3}/src/gaard_api/cli.py +0 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3}/src/gaard_api/cli_commands.py +0 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3}/src/gaard_api/core/__init__.py +0 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3}/src/gaard_api/core/error_handlers.py +0 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3}/src/gaard_api/core/schema_cache.py +0 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3}/src/gaard_api/core/settings.py +0 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3}/src/gaard_api/example_data/__init__.py +0 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3}/src/gaard_api/example_data/medical_poc/__init__.py +0 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3}/src/gaard_api/example_data/medical_poc/schema.sql +0 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3}/src/gaard_api/example_data/medical_poc/seed.sql +0 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3}/src/gaard_api/example_database.py +0 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3}/src/gaard_api/server_cli.py +0 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3}/src/gaard_api.egg-info/dependency_links.txt +0 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3}/src/gaard_api.egg-info/entry_points.txt +0 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3}/src/gaard_api.egg-info/requires.txt +0 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3}/src/gaard_api.egg-info/top_level.txt +0 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3}/tests/test_error_handlers.py +0 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3}/tests/test_investigation_error_messages.py +0 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3}/tests/test_prompt_runtime.py +0 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3}/tests/test_server_cli.py +0 -0
- {gaard_api-0.1.2 → gaard_api-0.1.3}/tests/test_settings.py +0 -0
|
@@ -818,6 +818,104 @@ def set_llm_runtime_config(
|
|
|
818
818
|
return get_llm_runtime_config(session)
|
|
819
819
|
|
|
820
820
|
|
|
821
|
+
def build_llm_runtime_config(
|
|
822
|
+
session: Session,
|
|
823
|
+
*,
|
|
824
|
+
provider: str,
|
|
825
|
+
base_url: str,
|
|
826
|
+
api_key: str | None,
|
|
827
|
+
clear_api_key: bool,
|
|
828
|
+
model: str,
|
|
829
|
+
timeout_seconds: int | None,
|
|
830
|
+
extra_body: dict[str, Any],
|
|
831
|
+
) -> LlmRuntimeConfig:
|
|
832
|
+
if provider != "openai-compatible":
|
|
833
|
+
raise ValueError("Only openai-compatible LLM provider is supported.")
|
|
834
|
+
|
|
835
|
+
current_config = get_llm_runtime_config(session)
|
|
836
|
+
normalized_base_url = str(base_url or "").strip()
|
|
837
|
+
normalized_model = str(model or "").strip()
|
|
838
|
+
if not normalized_base_url:
|
|
839
|
+
raise ValueError("LLM Base URL is required.")
|
|
840
|
+
if not normalized_model:
|
|
841
|
+
raise ValueError("LLM model is required.")
|
|
842
|
+
if timeout_seconds is not None and timeout_seconds < 1:
|
|
843
|
+
raise ValueError("LLM timeout seconds must be greater than 0.")
|
|
844
|
+
if not isinstance(extra_body, dict):
|
|
845
|
+
raise ValueError("LLM Extra body JSON must be an object.")
|
|
846
|
+
|
|
847
|
+
next_api_key = current_config.api_key
|
|
848
|
+
if clear_api_key:
|
|
849
|
+
next_api_key = "change-me"
|
|
850
|
+
elif api_key is not None and api_key.strip():
|
|
851
|
+
next_api_key = api_key.strip()
|
|
852
|
+
|
|
853
|
+
return LlmRuntimeConfig(
|
|
854
|
+
provider=provider,
|
|
855
|
+
base_url=normalized_base_url,
|
|
856
|
+
api_key=next_api_key,
|
|
857
|
+
model=normalized_model,
|
|
858
|
+
timeout_seconds=timeout_seconds or current_config.timeout_seconds,
|
|
859
|
+
extra_body=extra_body,
|
|
860
|
+
)
|
|
861
|
+
|
|
862
|
+
|
|
863
|
+
def test_llm_runtime_config(
|
|
864
|
+
session: Session,
|
|
865
|
+
*,
|
|
866
|
+
provider: str,
|
|
867
|
+
base_url: str,
|
|
868
|
+
api_key: str | None,
|
|
869
|
+
clear_api_key: bool,
|
|
870
|
+
model: str,
|
|
871
|
+
timeout_seconds: int | None,
|
|
872
|
+
extra_body: dict[str, Any],
|
|
873
|
+
) -> dict[str, Any]:
|
|
874
|
+
config = build_llm_runtime_config(
|
|
875
|
+
session,
|
|
876
|
+
provider=provider,
|
|
877
|
+
base_url=base_url,
|
|
878
|
+
api_key=api_key,
|
|
879
|
+
clear_api_key=clear_api_key,
|
|
880
|
+
model=model,
|
|
881
|
+
timeout_seconds=timeout_seconds,
|
|
882
|
+
extra_body=extra_body,
|
|
883
|
+
)
|
|
884
|
+
if not config.api_key or config.api_key == "change-me":
|
|
885
|
+
raise ValueError("LLM API key is required for the connection test.")
|
|
886
|
+
|
|
887
|
+
client = OpenAICompatibleClient(
|
|
888
|
+
base_url=config.base_url,
|
|
889
|
+
api_key=config.api_key,
|
|
890
|
+
timeout_seconds=config.timeout_seconds,
|
|
891
|
+
)
|
|
892
|
+
|
|
893
|
+
try:
|
|
894
|
+
response = client.create_chat_completion(
|
|
895
|
+
ChatCompletionRequest(
|
|
896
|
+
model=config.model,
|
|
897
|
+
messages=[
|
|
898
|
+
ChatMessage(
|
|
899
|
+
role="user",
|
|
900
|
+
content="GAARD LLM connection test. Reply with OK.",
|
|
901
|
+
)
|
|
902
|
+
],
|
|
903
|
+
temperature=0,
|
|
904
|
+
extra_body=config.extra_body,
|
|
905
|
+
)
|
|
906
|
+
)
|
|
907
|
+
except LlmProviderError as exc:
|
|
908
|
+
raise ValueError(str(exc)) from exc
|
|
909
|
+
|
|
910
|
+
if not response.content.strip():
|
|
911
|
+
raise ValueError("LLM provider returned an empty response.")
|
|
912
|
+
|
|
913
|
+
return {
|
|
914
|
+
"ok": True,
|
|
915
|
+
"model": response.model or config.model,
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
|
|
821
919
|
def get_data_query_audit_retention_days(session: Session) -> int:
|
|
822
920
|
value = get_setting(
|
|
823
921
|
session,
|