pretensor 0.1.0__py3-none-any.whl
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.
- pretensor/__init__.py +50 -0
- pretensor/benchmark/__init__.py +54 -0
- pretensor/benchmark/cli.py +294 -0
- pretensor/benchmark/fixtures.py +84 -0
- pretensor/benchmark/l1/__init__.py +23 -0
- pretensor/benchmark/l1/metrics.py +141 -0
- pretensor/benchmark/l1/pipeline.py +188 -0
- pretensor/benchmark/l1/runner.py +245 -0
- pretensor/benchmark/l2/__init__.py +27 -0
- pretensor/benchmark/l2/gold.py +236 -0
- pretensor/benchmark/l2/metrics.py +146 -0
- pretensor/benchmark/l2/pipeline.py +124 -0
- pretensor/benchmark/l2/runner.py +530 -0
- pretensor/benchmark/l3/__init__.py +73 -0
- pretensor/benchmark/l3/agent.py +316 -0
- pretensor/benchmark/l3/db.py +188 -0
- pretensor/benchmark/l3/gold.py +85 -0
- pretensor/benchmark/l3/llm_client.py +395 -0
- pretensor/benchmark/l3/mcp_client.py +357 -0
- pretensor/benchmark/l3/pretensor_runner.py +456 -0
- pretensor/benchmark/l3/prompt.py +132 -0
- pretensor/benchmark/l3/runner.py +358 -0
- pretensor/benchmark/l3/sql_equivalence.py +176 -0
- pretensor/benchmark/release_gate.py +448 -0
- pretensor/benchmark/results.py +298 -0
- pretensor/benchmark/runner.py +109 -0
- pretensor/cli/__init__.py +1 -0
- pretensor/cli/commands/_source_runner.py +147 -0
- pretensor/cli/commands/analyze.py +201 -0
- pretensor/cli/commands/connections/__init__.py +7 -0
- pretensor/cli/commands/connections/add_remove.py +126 -0
- pretensor/cli/commands/connections/register.py +12 -0
- pretensor/cli/commands/export.py +131 -0
- pretensor/cli/commands/index.py +559 -0
- pretensor/cli/commands/list.py +76 -0
- pretensor/cli/commands/quickstart.py +207 -0
- pretensor/cli/commands/reindex.py +646 -0
- pretensor/cli/commands/semantic.py +190 -0
- pretensor/cli/commands/serve.py +144 -0
- pretensor/cli/commands/sync_grants.py +149 -0
- pretensor/cli/commands/validate.py +176 -0
- pretensor/cli/config_file.py +442 -0
- pretensor/cli/constants.py +10 -0
- pretensor/cli/dbt_enrichment.py +96 -0
- pretensor/cli/main.py +109 -0
- pretensor/cli/paths.py +43 -0
- pretensor/cli/plugin.py +52 -0
- pretensor/config.py +226 -0
- pretensor/connectors/__init__.py +29 -0
- pretensor/connectors/base.py +165 -0
- pretensor/connectors/bigquery.py +468 -0
- pretensor/connectors/inspect.py +321 -0
- pretensor/connectors/lineage_sqlglot.py +97 -0
- pretensor/connectors/models.py +130 -0
- pretensor/connectors/mysql.py +402 -0
- pretensor/connectors/pg_array_parse.py +53 -0
- pretensor/connectors/postgres.py +938 -0
- pretensor/connectors/registry.py +93 -0
- pretensor/connectors/snapshot.py +244 -0
- pretensor/connectors/snowflake.py +908 -0
- pretensor/core/__init__.py +1 -0
- pretensor/core/builder.py +307 -0
- pretensor/core/dsn_crypto.py +51 -0
- pretensor/core/graph_schema_manager.py +246 -0
- pretensor/core/graph_store.py +1226 -0
- pretensor/core/ids.py +101 -0
- pretensor/core/portable_export.py +276 -0
- pretensor/core/query_runner.py +67 -0
- pretensor/core/registry.py +209 -0
- pretensor/core/schema.py +473 -0
- pretensor/core/secure_io.py +93 -0
- pretensor/core/store.py +469 -0
- pretensor/enrichment/__init__.py +1 -0
- pretensor/enrichment/analyze/__init__.py +0 -0
- pretensor/enrichment/analyze/classify.py +49 -0
- pretensor/enrichment/analyze/extract_python.py +196 -0
- pretensor/enrichment/analyze/parse.py +141 -0
- pretensor/enrichment/analyze/pipeline.py +195 -0
- pretensor/enrichment/analyze/summary.py +38 -0
- pretensor/enrichment/analyze/walker.py +98 -0
- pretensor/enrichment/analyze/writers.py +214 -0
- pretensor/enrichment/dbt/__init__.py +30 -0
- pretensor/enrichment/dbt/lineage.py +100 -0
- pretensor/enrichment/dbt/manifest.py +300 -0
- pretensor/enrichment/dbt/metadata.py +263 -0
- pretensor/enrichment/dbt/pipeline.py +77 -0
- pretensor/enrichment/dbt/resolution.py +101 -0
- pretensor/enrichment/dbt/signals.py +305 -0
- pretensor/entities/__init__.py +27 -0
- pretensor/entities/builder.py +63 -0
- pretensor/entities/classifier.py +383 -0
- pretensor/entities/llm_extract.py +66 -0
- pretensor/errors.py +35 -0
- pretensor/graph_models/__init__.py +17 -0
- pretensor/graph_models/base.py +11 -0
- pretensor/graph_models/consumer.py +71 -0
- pretensor/graph_models/edge.py +35 -0
- pretensor/graph_models/entity.py +21 -0
- pretensor/graph_models/node.py +79 -0
- pretensor/graph_models/relationship.py +33 -0
- pretensor/integrations/__init__.py +42 -0
- pretensor/integrations/_base.py +138 -0
- pretensor/integrations/google_adk.py +49 -0
- pretensor/integrations/langchain.py +55 -0
- pretensor/integrations/llamaindex.py +53 -0
- pretensor/intelligence/__init__.py +33 -0
- pretensor/intelligence/cluster_labeler.py +425 -0
- pretensor/intelligence/clustering.py +168 -0
- pretensor/intelligence/combining.py +32 -0
- pretensor/intelligence/discovery.py +114 -0
- pretensor/intelligence/embeddings.py +317 -0
- pretensor/intelligence/graph_export.py +200 -0
- pretensor/intelligence/heuristic.py +544 -0
- pretensor/intelligence/join_paths/__init__.py +130 -0
- pretensor/intelligence/join_paths/on_demand.py +516 -0
- pretensor/intelligence/join_paths/storage.py +70 -0
- pretensor/intelligence/llm_infer.py +78 -0
- pretensor/intelligence/llm_runtime.py +62 -0
- pretensor/intelligence/metric_templates.py +193 -0
- pretensor/intelligence/pipeline.py +364 -0
- pretensor/intelligence/role_exemplars.py +263 -0
- pretensor/intelligence/schema_classification.py +360 -0
- pretensor/intelligence/scoring.py +76 -0
- pretensor/intelligence/semantic.py +240 -0
- pretensor/intelligence/shadow_alias.py +101 -0
- pretensor/intelligence/statistical.py +50 -0
- pretensor/intelligence/steps.py +191 -0
- pretensor/intelligence/steps_embedding.py +168 -0
- pretensor/introspection/__init__.py +6 -0
- pretensor/introspection/inspector.py +5 -0
- pretensor/introspection/models/__init__.py +0 -0
- pretensor/introspection/models/base.py +5 -0
- pretensor/introspection/models/config.py +237 -0
- pretensor/introspection/models/dsn.py +550 -0
- pretensor/introspection/models/plan.py +116 -0
- pretensor/introspection/models/schema.py +10 -0
- pretensor/introspection/models/semantic.py +121 -0
- pretensor/introspection/models/validation.py +116 -0
- pretensor/introspection/snapshot.py +46 -0
- pretensor/mcp/__init__.py +16 -0
- pretensor/mcp/config_json.py +24 -0
- pretensor/mcp/payload_types.py +274 -0
- pretensor/mcp/resources/__init__.py +17 -0
- pretensor/mcp/resources/markdown.py +314 -0
- pretensor/mcp/server.py +285 -0
- pretensor/mcp/service.py +49 -0
- pretensor/mcp/service_context.py +142 -0
- pretensor/mcp/service_registry.py +294 -0
- pretensor/mcp/store_cache.py +43 -0
- pretensor/mcp/tool_registry.py +136 -0
- pretensor/mcp/tools/__init__.py +1 -0
- pretensor/mcp/tools/_rank.py +244 -0
- pretensor/mcp/tools/_timed.py +26 -0
- pretensor/mcp/tools/compile_metric.py +144 -0
- pretensor/mcp/tools/consumers.py +161 -0
- pretensor/mcp/tools/context.py +1121 -0
- pretensor/mcp/tools/cypher.py +509 -0
- pretensor/mcp/tools/detect_changes.py +254 -0
- pretensor/mcp/tools/impact.py +271 -0
- pretensor/mcp/tools/list.py +131 -0
- pretensor/mcp/tools/schema.py +170 -0
- pretensor/mcp/tools/search.py +316 -0
- pretensor/mcp/tools/semantic_search.py +282 -0
- pretensor/mcp/tools/traverse.py +1027 -0
- pretensor/mcp/tools/validate_sql.py +150 -0
- pretensor/observability.py +203 -0
- pretensor/py.typed +0 -0
- pretensor/quickstart/README.md +29 -0
- pretensor/quickstart/__init__.py +6 -0
- pretensor/quickstart/docker-compose.yml +18 -0
- pretensor/quickstart/pagila_data.sql +63 -0
- pretensor/quickstart/pagila_ddl.sql +92 -0
- pretensor/search/__init__.py +6 -0
- pretensor/search/base.py +80 -0
- pretensor/search/index.py +435 -0
- pretensor/semantic/__init__.py +24 -0
- pretensor/semantic/base.py +123 -0
- pretensor/semantic/compiler.py +487 -0
- pretensor/semantic/yaml_layer.py +180 -0
- pretensor/skills/__init__.py +5 -0
- pretensor/skills/generator.py +235 -0
- pretensor/staleness/__init__.py +15 -0
- pretensor/staleness/graph_patcher.py +355 -0
- pretensor/staleness/impact_analyzer.py +162 -0
- pretensor/staleness/snapshot_store.py +38 -0
- pretensor/validation/__init__.py +9 -0
- pretensor/validation/query_validator.py +436 -0
- pretensor/visibility/__init__.py +23 -0
- pretensor/visibility/config.py +126 -0
- pretensor/visibility/filter.py +143 -0
- pretensor/visibility/kuzu_helpers.py +32 -0
- pretensor/visibility/runtime.py +36 -0
- pretensor/visibility/sync_grants.py +188 -0
- pretensor-0.1.0.dist-info/METADATA +251 -0
- pretensor-0.1.0.dist-info/RECORD +198 -0
- pretensor-0.1.0.dist-info/WHEEL +4 -0
- pretensor-0.1.0.dist-info/entry_points.txt +2 -0
- pretensor-0.1.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"""Graph node payload used when writing to Kuzu."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from pydantic import Field
|
|
6
|
+
|
|
7
|
+
from pretensor.graph_models.base import GraphModel
|
|
8
|
+
|
|
9
|
+
__all__ = ["GraphNode"]
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class GraphNode(GraphModel):
|
|
13
|
+
"""A table (or future entity type) represented as a node in the graph."""
|
|
14
|
+
|
|
15
|
+
node_id: str = Field(
|
|
16
|
+
description="Stable primary key in the Kuzu SchemaTable node table."
|
|
17
|
+
)
|
|
18
|
+
connection_name: str
|
|
19
|
+
database: str
|
|
20
|
+
schema_name: str
|
|
21
|
+
table_name: str
|
|
22
|
+
row_count: int | None = None
|
|
23
|
+
row_count_source: str | None = Field(
|
|
24
|
+
default=None,
|
|
25
|
+
description=(
|
|
26
|
+
"Provenance: 'stat', 'view_count', or 'view_timeout' (row_count = -1)."
|
|
27
|
+
),
|
|
28
|
+
)
|
|
29
|
+
comment: str | None = None
|
|
30
|
+
description: str | None = Field(
|
|
31
|
+
default=None,
|
|
32
|
+
description="Human-authored description (e.g. dbt); distinct from DB comment.",
|
|
33
|
+
)
|
|
34
|
+
tags: list[str] | None = Field(
|
|
35
|
+
default=None,
|
|
36
|
+
description="Tag names merged onto the graph node (e.g. dbt tags).",
|
|
37
|
+
)
|
|
38
|
+
table_type: str | None = None
|
|
39
|
+
entity_type: str | None = Field(
|
|
40
|
+
default=None,
|
|
41
|
+
description="Business entity label from extraction (e.g. Customer).",
|
|
42
|
+
)
|
|
43
|
+
seq_scan_count: int | None = None
|
|
44
|
+
idx_scan_count: int | None = None
|
|
45
|
+
insert_count: int | None = None
|
|
46
|
+
update_count: int | None = None
|
|
47
|
+
delete_count: int | None = None
|
|
48
|
+
is_partitioned: bool | None = None
|
|
49
|
+
partition_key: str | None = None
|
|
50
|
+
grants_json: str | None = None
|
|
51
|
+
access_read_count: int | None = None
|
|
52
|
+
access_write_count: int | None = None
|
|
53
|
+
days_since_last_access: int | None = None
|
|
54
|
+
potentially_unused: bool | None = None
|
|
55
|
+
table_bytes: int | None = None
|
|
56
|
+
clustering_key: str | None = None
|
|
57
|
+
role: str | None = Field(
|
|
58
|
+
default=None,
|
|
59
|
+
description="Data modeling role from schema classifier (fact, dimension, …).",
|
|
60
|
+
)
|
|
61
|
+
role_confidence: float | None = Field(
|
|
62
|
+
default=None, description="Classifier confidence in ``[0, 1]``."
|
|
63
|
+
)
|
|
64
|
+
classification_signals: str | None = Field(
|
|
65
|
+
default=None,
|
|
66
|
+
description="JSON array string of human-readable classification signals.",
|
|
67
|
+
)
|
|
68
|
+
has_external_consumers: bool | None = Field(
|
|
69
|
+
default=None,
|
|
70
|
+
description="True when dbt lineage marks downstream exposure outside the project.",
|
|
71
|
+
)
|
|
72
|
+
test_count: int | None = Field(
|
|
73
|
+
default=None,
|
|
74
|
+
description="Number of dbt tests attached to this model (when known).",
|
|
75
|
+
)
|
|
76
|
+
embedding: list[float] | None = Field(
|
|
77
|
+
default=None,
|
|
78
|
+
description="Dense vector embedding of table identity text (dim=384).",
|
|
79
|
+
)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""Relationship discovery candidates (heuristic, LLM, statistical, explicit FK)."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Literal
|
|
6
|
+
|
|
7
|
+
from pydantic import Field
|
|
8
|
+
|
|
9
|
+
from pretensor.graph_models.base import GraphModel
|
|
10
|
+
|
|
11
|
+
__all__ = ["RelationshipCandidate", "RelationshipSource"]
|
|
12
|
+
|
|
13
|
+
RelationshipSource = Literal[
|
|
14
|
+
"explicit_fk",
|
|
15
|
+
"heuristic",
|
|
16
|
+
"llm_inferred",
|
|
17
|
+
"statistical",
|
|
18
|
+
"embedding",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class RelationshipCandidate(GraphModel):
|
|
23
|
+
"""A directed join hypothesis between two ``SchemaTable`` nodes."""
|
|
24
|
+
|
|
25
|
+
candidate_id: str
|
|
26
|
+
source_node_id: str
|
|
27
|
+
target_node_id: str
|
|
28
|
+
source_column: str
|
|
29
|
+
target_column: str
|
|
30
|
+
source: RelationshipSource
|
|
31
|
+
reasoning: str = ""
|
|
32
|
+
confidence: float = Field(ge=0.0, le=1.0, default=0.0)
|
|
33
|
+
status: Literal["suggested", "confirmed", "rejected"] = "suggested"
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"""Agent-framework SDK adapters for Pretensor graph tools.
|
|
2
|
+
|
|
3
|
+
Exposes the six graph tools (schema, context, traverse, impact, query,
|
|
4
|
+
validate_sql) as native tool objects for LangChain, LlamaIndex, and Google ADK.
|
|
5
|
+
No MCP server process is required.
|
|
6
|
+
|
|
7
|
+
Usage::
|
|
8
|
+
|
|
9
|
+
from pretensor.integrations import load_langchain_tools
|
|
10
|
+
from pretensor.integrations import load_llamaindex_tools
|
|
11
|
+
from pretensor.integrations import load_adk_tools
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
# pyright: reportUnsupportedDunderAll=false
|
|
15
|
+
# Names in __all__ are provided via __getattr__; Pyright does not model that.
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
from typing import Any
|
|
20
|
+
|
|
21
|
+
__all__ = [
|
|
22
|
+
"load_langchain_tools",
|
|
23
|
+
"load_llamaindex_tools",
|
|
24
|
+
"load_adk_tools",
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def __getattr__(name: str) -> Any:
|
|
29
|
+
if name == "load_langchain_tools":
|
|
30
|
+
from pretensor.integrations.langchain import load_langchain_tools
|
|
31
|
+
|
|
32
|
+
return load_langchain_tools
|
|
33
|
+
if name == "load_llamaindex_tools":
|
|
34
|
+
from pretensor.integrations.llamaindex import load_llamaindex_tools
|
|
35
|
+
|
|
36
|
+
return load_llamaindex_tools
|
|
37
|
+
if name == "load_adk_tools":
|
|
38
|
+
from pretensor.integrations.google_adk import load_adk_tools
|
|
39
|
+
|
|
40
|
+
return load_adk_tools
|
|
41
|
+
msg = f"module {__name__!r} has no attribute {name!r}"
|
|
42
|
+
raise AttributeError(msg)
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"""Shared tool-function factory for all agent-framework adapters.
|
|
2
|
+
|
|
3
|
+
Each returned callable has a typed signature and docstring so that
|
|
4
|
+
LangChain, LlamaIndex, and Google ADK can automatically infer the
|
|
5
|
+
tool schema without any manual JSON Schema duplication.
|
|
6
|
+
|
|
7
|
+
The functions delegate directly to the same payload functions used by
|
|
8
|
+
the MCP server — no logic is duplicated.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
from typing import Any, Callable
|
|
15
|
+
|
|
16
|
+
from pretensor.mcp.tools.context import context_payload
|
|
17
|
+
from pretensor.mcp.tools.impact import impact_payload
|
|
18
|
+
from pretensor.mcp.tools.schema import schema_payload
|
|
19
|
+
from pretensor.mcp.tools.search import query_payload
|
|
20
|
+
from pretensor.mcp.tools.traverse import traverse_payload
|
|
21
|
+
from pretensor.mcp.tools.validate_sql import validate_sql_payload
|
|
22
|
+
|
|
23
|
+
__all__ = ["make_tool_functions"]
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _make_schema(graph_dir: Path) -> Callable[..., dict[str, Any]]:
|
|
27
|
+
def schema(database: str, label: str | None = None) -> dict[str, Any]:
|
|
28
|
+
"""Discover node labels, edge types, and properties in the graph. Call before writing Cypher."""
|
|
29
|
+
return schema_payload(graph_dir, database=database, label=label)
|
|
30
|
+
|
|
31
|
+
return schema
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _make_context(graph_dir: Path) -> Callable[..., dict[str, Any]]:
|
|
35
|
+
def context(
|
|
36
|
+
table: str,
|
|
37
|
+
db: str | None = None,
|
|
38
|
+
detail: str = "standard",
|
|
39
|
+
) -> dict[str, Any]:
|
|
40
|
+
"""Full context for one physical table: columns, relationships, lineage, cluster. detail: summary | standard | full."""
|
|
41
|
+
return context_payload(graph_dir, table=table, db=db, detail=detail) # type: ignore[arg-type]
|
|
42
|
+
|
|
43
|
+
return context
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _make_traverse(graph_dir: Path) -> Callable[..., dict[str, Any]]:
|
|
47
|
+
def traverse(
|
|
48
|
+
from_table: str,
|
|
49
|
+
to_table: str,
|
|
50
|
+
database: str,
|
|
51
|
+
max_depth: int = 4,
|
|
52
|
+
top_k: int = 3,
|
|
53
|
+
edge_types: list[str] | None = None,
|
|
54
|
+
max_inferred_hops: int = 2,
|
|
55
|
+
) -> dict[str, Any]:
|
|
56
|
+
"""Find a join path between two physical tables with SQL JOIN hints. edge_types: fk | inferred (default: both)."""
|
|
57
|
+
et: tuple[str, ...] | None = None
|
|
58
|
+
if edge_types:
|
|
59
|
+
et = tuple(edge_types)
|
|
60
|
+
return traverse_payload(
|
|
61
|
+
graph_dir,
|
|
62
|
+
from_table=from_table,
|
|
63
|
+
to_table=to_table,
|
|
64
|
+
database=database,
|
|
65
|
+
max_depth=max_depth,
|
|
66
|
+
top_k=max(1, min(10, top_k)),
|
|
67
|
+
edge_types=et,
|
|
68
|
+
max_inferred_hops=max(0, min(8, max_inferred_hops)),
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
return traverse
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def _make_impact(graph_dir: Path) -> Callable[..., dict[str, Any]]:
|
|
75
|
+
def impact(
|
|
76
|
+
table: str,
|
|
77
|
+
database: str,
|
|
78
|
+
column: str | None = None,
|
|
79
|
+
max_depth: int = 3,
|
|
80
|
+
) -> dict[str, Any]:
|
|
81
|
+
"""Downstream tables reachable via FK and inferred join edges from a table, grouped by hop depth."""
|
|
82
|
+
return impact_payload(
|
|
83
|
+
graph_dir,
|
|
84
|
+
table=table,
|
|
85
|
+
database=database,
|
|
86
|
+
column=column,
|
|
87
|
+
max_depth=max_depth,
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
return impact
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def _make_query(graph_dir: Path) -> Callable[..., dict[str, Any]]:
|
|
94
|
+
def query(
|
|
95
|
+
q: str,
|
|
96
|
+
db: str | None = None,
|
|
97
|
+
limit: int = 10,
|
|
98
|
+
) -> dict[str, Any]:
|
|
99
|
+
"""BM25 keyword search over table and entity metadata."""
|
|
100
|
+
return query_payload(graph_dir, q=q, db=db, limit=limit)
|
|
101
|
+
|
|
102
|
+
return query
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def _make_validate_sql(graph_dir: Path) -> Callable[..., dict[str, Any]]:
|
|
106
|
+
def validate_sql(
|
|
107
|
+
sql: str,
|
|
108
|
+
database: str,
|
|
109
|
+
dialect: str = "postgres",
|
|
110
|
+
) -> dict[str, Any]:
|
|
111
|
+
"""Validate a SQL statement against the indexed graph: unknown tables/columns, invalid joins, fuzzy suggestions."""
|
|
112
|
+
return validate_sql_payload(graph_dir, sql=sql, database=database, dialect=dialect)
|
|
113
|
+
|
|
114
|
+
return validate_sql
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def make_tool_functions(graph_dir: Path) -> list[Callable[..., dict[str, Any]]]:
|
|
118
|
+
"""Return six graph-tool callables bound to ``graph_dir``.
|
|
119
|
+
|
|
120
|
+
Each callable has typed parameters and a docstring so that LangChain,
|
|
121
|
+
LlamaIndex, and Google ADK can automatically derive the tool schema.
|
|
122
|
+
|
|
123
|
+
Args:
|
|
124
|
+
graph_dir: Root directory of the Pretensor graph store (must be
|
|
125
|
+
pre-indexed via ``pretensor index``).
|
|
126
|
+
|
|
127
|
+
Returns:
|
|
128
|
+
[schema, context, traverse, impact, query, validate_sql]
|
|
129
|
+
"""
|
|
130
|
+
resolved = Path(graph_dir).resolve()
|
|
131
|
+
return [
|
|
132
|
+
_make_schema(resolved),
|
|
133
|
+
_make_context(resolved),
|
|
134
|
+
_make_traverse(resolved),
|
|
135
|
+
_make_impact(resolved),
|
|
136
|
+
_make_query(resolved),
|
|
137
|
+
_make_validate_sql(resolved),
|
|
138
|
+
]
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"""Google ADK adapter — wraps Pretensor graph tools as ADK ``FunctionTool`` objects.
|
|
2
|
+
|
|
3
|
+
Install the optional extra before use::
|
|
4
|
+
|
|
5
|
+
pip install 'pretensor[google-adk]'
|
|
6
|
+
|
|
7
|
+
Usage::
|
|
8
|
+
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from pretensor.integrations.google_adk import load_adk_tools
|
|
11
|
+
from google.adk.agents import LlmAgent
|
|
12
|
+
|
|
13
|
+
tools = load_adk_tools(Path(".pretensor"))
|
|
14
|
+
agent = LlmAgent(model="gemini-2.0-flash", tools=tools)
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import importlib
|
|
20
|
+
from pathlib import Path
|
|
21
|
+
from typing import Any
|
|
22
|
+
|
|
23
|
+
from pretensor.integrations._base import make_tool_functions
|
|
24
|
+
|
|
25
|
+
__all__ = ["load_adk_tools"]
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def load_adk_tools(graph_dir: Path | str) -> list[Any]:
|
|
29
|
+
"""Return Pretensor graph tools as Google ADK ``FunctionTool`` objects.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
graph_dir: Root directory of the Pretensor graph store.
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
List of six ``google.adk.tools.FunctionTool`` instances:
|
|
36
|
+
schema, context, traverse, impact, query, validate_sql.
|
|
37
|
+
|
|
38
|
+
Raises:
|
|
39
|
+
ImportError: If ``google-adk`` is not installed.
|
|
40
|
+
"""
|
|
41
|
+
try:
|
|
42
|
+
adk_tools = importlib.import_module("google.adk.tools")
|
|
43
|
+
except ImportError as exc:
|
|
44
|
+
raise ImportError(
|
|
45
|
+
"Google ADK is not installed. Run: pip install 'pretensor[google-adk]'"
|
|
46
|
+
) from exc
|
|
47
|
+
|
|
48
|
+
function_tool = adk_tools.FunctionTool
|
|
49
|
+
return [function_tool(fn) for fn in make_tool_functions(Path(graph_dir))]
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"""LangChain adapter — wraps Pretensor graph tools as ``StructuredTool`` objects.
|
|
2
|
+
|
|
3
|
+
Install the optional extra before use::
|
|
4
|
+
|
|
5
|
+
pip install 'pretensor[langchain]'
|
|
6
|
+
|
|
7
|
+
Usage::
|
|
8
|
+
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from pretensor.integrations.langchain import load_langchain_tools
|
|
11
|
+
from langchain_openai import ChatOpenAI
|
|
12
|
+
from langchain.agents import create_tool_calling_agent, AgentExecutor
|
|
13
|
+
|
|
14
|
+
tools = load_langchain_tools(Path(".pretensor"))
|
|
15
|
+
llm = ChatOpenAI(model="gpt-4o")
|
|
16
|
+
agent = AgentExecutor(
|
|
17
|
+
agent=create_tool_calling_agent(llm, tools, prompt), tools=tools
|
|
18
|
+
)
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
from __future__ import annotations
|
|
22
|
+
|
|
23
|
+
import importlib
|
|
24
|
+
from pathlib import Path
|
|
25
|
+
from typing import Any
|
|
26
|
+
|
|
27
|
+
from pretensor.integrations._base import make_tool_functions
|
|
28
|
+
|
|
29
|
+
__all__ = ["load_langchain_tools"]
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def load_langchain_tools(graph_dir: Path | str) -> list[Any]:
|
|
33
|
+
"""Return Pretensor graph tools as LangChain ``StructuredTool`` objects.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
graph_dir: Root directory of the Pretensor graph store.
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
List of six ``langchain_core.tools.StructuredTool`` instances:
|
|
40
|
+
schema, context, traverse, impact, query, validate_sql.
|
|
41
|
+
|
|
42
|
+
Raises:
|
|
43
|
+
ImportError: If ``langchain-core`` is not installed.
|
|
44
|
+
"""
|
|
45
|
+
try:
|
|
46
|
+
lc_tools = importlib.import_module("langchain_core.tools")
|
|
47
|
+
except ImportError as exc:
|
|
48
|
+
raise ImportError(
|
|
49
|
+
"LangChain is not installed. Run: pip install 'pretensor[langchain]'"
|
|
50
|
+
) from exc
|
|
51
|
+
|
|
52
|
+
structured_tool = lc_tools.StructuredTool
|
|
53
|
+
return [
|
|
54
|
+
structured_tool.from_function(fn) for fn in make_tool_functions(Path(graph_dir))
|
|
55
|
+
]
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"""LlamaIndex adapter — wraps Pretensor graph tools as ``FunctionTool`` objects.
|
|
2
|
+
|
|
3
|
+
Install the optional extra before use::
|
|
4
|
+
|
|
5
|
+
pip install 'pretensor[llama-index]'
|
|
6
|
+
|
|
7
|
+
Usage::
|
|
8
|
+
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from pretensor.integrations.llamaindex import load_llamaindex_tools
|
|
11
|
+
from llama_index.core.agent import ReActAgent
|
|
12
|
+
from llama_index.llms.openai import OpenAI
|
|
13
|
+
|
|
14
|
+
tools = load_llamaindex_tools(Path(".pretensor"))
|
|
15
|
+
agent = ReActAgent.from_tools(tools, llm=OpenAI(model="gpt-4o"), verbose=True)
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from __future__ import annotations
|
|
19
|
+
|
|
20
|
+
import importlib
|
|
21
|
+
from pathlib import Path
|
|
22
|
+
from typing import Any
|
|
23
|
+
|
|
24
|
+
from pretensor.integrations._base import make_tool_functions
|
|
25
|
+
|
|
26
|
+
__all__ = ["load_llamaindex_tools"]
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def load_llamaindex_tools(graph_dir: Path | str) -> list[Any]:
|
|
30
|
+
"""Return Pretensor graph tools as LlamaIndex ``FunctionTool`` objects.
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
graph_dir: Root directory of the Pretensor graph store.
|
|
34
|
+
|
|
35
|
+
Returns:
|
|
36
|
+
List of six ``llama_index.core.tools.FunctionTool`` instances:
|
|
37
|
+
schema, context, traverse, impact, query, validate_sql.
|
|
38
|
+
|
|
39
|
+
Raises:
|
|
40
|
+
ImportError: If ``llama-index-core`` is not installed.
|
|
41
|
+
"""
|
|
42
|
+
try:
|
|
43
|
+
li_tools = importlib.import_module("llama_index.core.tools")
|
|
44
|
+
except ImportError as exc:
|
|
45
|
+
raise ImportError(
|
|
46
|
+
"LlamaIndex is not installed. Run: pip install 'pretensor[llama-index]'"
|
|
47
|
+
) from exc
|
|
48
|
+
|
|
49
|
+
function_tool = li_tools.FunctionTool
|
|
50
|
+
return [
|
|
51
|
+
function_tool.from_defaults(fn=fn)
|
|
52
|
+
for fn in make_tool_functions(Path(graph_dir))
|
|
53
|
+
]
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""Graph intelligence: relationship discovery, clustering, and join paths."""
|
|
2
|
+
|
|
3
|
+
from pretensor.intelligence.cluster_labeler import ClusterLabeler, LabeledCluster
|
|
4
|
+
from pretensor.intelligence.clustering import Cluster, ClusteringEngine
|
|
5
|
+
from pretensor.intelligence.graph_export import GraphExporter
|
|
6
|
+
from pretensor.intelligence.join_paths import JoinPathEngine
|
|
7
|
+
from pretensor.intelligence.pipeline import (
|
|
8
|
+
build_oss_pipeline,
|
|
9
|
+
run_intelligence_layer,
|
|
10
|
+
run_intelligence_layer_sync,
|
|
11
|
+
)
|
|
12
|
+
from pretensor.intelligence.steps import (
|
|
13
|
+
CyclicDependencyError,
|
|
14
|
+
PipelineContext,
|
|
15
|
+
PipelineRunner,
|
|
16
|
+
PipelineStep,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
__all__ = [
|
|
20
|
+
"Cluster",
|
|
21
|
+
"ClusteringEngine",
|
|
22
|
+
"ClusterLabeler",
|
|
23
|
+
"LabeledCluster",
|
|
24
|
+
"GraphExporter",
|
|
25
|
+
"JoinPathEngine",
|
|
26
|
+
"build_oss_pipeline",
|
|
27
|
+
"run_intelligence_layer",
|
|
28
|
+
"run_intelligence_layer_sync",
|
|
29
|
+
"CyclicDependencyError",
|
|
30
|
+
"PipelineContext",
|
|
31
|
+
"PipelineRunner",
|
|
32
|
+
"PipelineStep",
|
|
33
|
+
]
|