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.
Files changed (198) hide show
  1. pretensor/__init__.py +50 -0
  2. pretensor/benchmark/__init__.py +54 -0
  3. pretensor/benchmark/cli.py +294 -0
  4. pretensor/benchmark/fixtures.py +84 -0
  5. pretensor/benchmark/l1/__init__.py +23 -0
  6. pretensor/benchmark/l1/metrics.py +141 -0
  7. pretensor/benchmark/l1/pipeline.py +188 -0
  8. pretensor/benchmark/l1/runner.py +245 -0
  9. pretensor/benchmark/l2/__init__.py +27 -0
  10. pretensor/benchmark/l2/gold.py +236 -0
  11. pretensor/benchmark/l2/metrics.py +146 -0
  12. pretensor/benchmark/l2/pipeline.py +124 -0
  13. pretensor/benchmark/l2/runner.py +530 -0
  14. pretensor/benchmark/l3/__init__.py +73 -0
  15. pretensor/benchmark/l3/agent.py +316 -0
  16. pretensor/benchmark/l3/db.py +188 -0
  17. pretensor/benchmark/l3/gold.py +85 -0
  18. pretensor/benchmark/l3/llm_client.py +395 -0
  19. pretensor/benchmark/l3/mcp_client.py +357 -0
  20. pretensor/benchmark/l3/pretensor_runner.py +456 -0
  21. pretensor/benchmark/l3/prompt.py +132 -0
  22. pretensor/benchmark/l3/runner.py +358 -0
  23. pretensor/benchmark/l3/sql_equivalence.py +176 -0
  24. pretensor/benchmark/release_gate.py +448 -0
  25. pretensor/benchmark/results.py +298 -0
  26. pretensor/benchmark/runner.py +109 -0
  27. pretensor/cli/__init__.py +1 -0
  28. pretensor/cli/commands/_source_runner.py +147 -0
  29. pretensor/cli/commands/analyze.py +201 -0
  30. pretensor/cli/commands/connections/__init__.py +7 -0
  31. pretensor/cli/commands/connections/add_remove.py +126 -0
  32. pretensor/cli/commands/connections/register.py +12 -0
  33. pretensor/cli/commands/export.py +131 -0
  34. pretensor/cli/commands/index.py +559 -0
  35. pretensor/cli/commands/list.py +76 -0
  36. pretensor/cli/commands/quickstart.py +207 -0
  37. pretensor/cli/commands/reindex.py +646 -0
  38. pretensor/cli/commands/semantic.py +190 -0
  39. pretensor/cli/commands/serve.py +144 -0
  40. pretensor/cli/commands/sync_grants.py +149 -0
  41. pretensor/cli/commands/validate.py +176 -0
  42. pretensor/cli/config_file.py +442 -0
  43. pretensor/cli/constants.py +10 -0
  44. pretensor/cli/dbt_enrichment.py +96 -0
  45. pretensor/cli/main.py +109 -0
  46. pretensor/cli/paths.py +43 -0
  47. pretensor/cli/plugin.py +52 -0
  48. pretensor/config.py +226 -0
  49. pretensor/connectors/__init__.py +29 -0
  50. pretensor/connectors/base.py +165 -0
  51. pretensor/connectors/bigquery.py +468 -0
  52. pretensor/connectors/inspect.py +321 -0
  53. pretensor/connectors/lineage_sqlglot.py +97 -0
  54. pretensor/connectors/models.py +130 -0
  55. pretensor/connectors/mysql.py +402 -0
  56. pretensor/connectors/pg_array_parse.py +53 -0
  57. pretensor/connectors/postgres.py +938 -0
  58. pretensor/connectors/registry.py +93 -0
  59. pretensor/connectors/snapshot.py +244 -0
  60. pretensor/connectors/snowflake.py +908 -0
  61. pretensor/core/__init__.py +1 -0
  62. pretensor/core/builder.py +307 -0
  63. pretensor/core/dsn_crypto.py +51 -0
  64. pretensor/core/graph_schema_manager.py +246 -0
  65. pretensor/core/graph_store.py +1226 -0
  66. pretensor/core/ids.py +101 -0
  67. pretensor/core/portable_export.py +276 -0
  68. pretensor/core/query_runner.py +67 -0
  69. pretensor/core/registry.py +209 -0
  70. pretensor/core/schema.py +473 -0
  71. pretensor/core/secure_io.py +93 -0
  72. pretensor/core/store.py +469 -0
  73. pretensor/enrichment/__init__.py +1 -0
  74. pretensor/enrichment/analyze/__init__.py +0 -0
  75. pretensor/enrichment/analyze/classify.py +49 -0
  76. pretensor/enrichment/analyze/extract_python.py +196 -0
  77. pretensor/enrichment/analyze/parse.py +141 -0
  78. pretensor/enrichment/analyze/pipeline.py +195 -0
  79. pretensor/enrichment/analyze/summary.py +38 -0
  80. pretensor/enrichment/analyze/walker.py +98 -0
  81. pretensor/enrichment/analyze/writers.py +214 -0
  82. pretensor/enrichment/dbt/__init__.py +30 -0
  83. pretensor/enrichment/dbt/lineage.py +100 -0
  84. pretensor/enrichment/dbt/manifest.py +300 -0
  85. pretensor/enrichment/dbt/metadata.py +263 -0
  86. pretensor/enrichment/dbt/pipeline.py +77 -0
  87. pretensor/enrichment/dbt/resolution.py +101 -0
  88. pretensor/enrichment/dbt/signals.py +305 -0
  89. pretensor/entities/__init__.py +27 -0
  90. pretensor/entities/builder.py +63 -0
  91. pretensor/entities/classifier.py +383 -0
  92. pretensor/entities/llm_extract.py +66 -0
  93. pretensor/errors.py +35 -0
  94. pretensor/graph_models/__init__.py +17 -0
  95. pretensor/graph_models/base.py +11 -0
  96. pretensor/graph_models/consumer.py +71 -0
  97. pretensor/graph_models/edge.py +35 -0
  98. pretensor/graph_models/entity.py +21 -0
  99. pretensor/graph_models/node.py +79 -0
  100. pretensor/graph_models/relationship.py +33 -0
  101. pretensor/integrations/__init__.py +42 -0
  102. pretensor/integrations/_base.py +138 -0
  103. pretensor/integrations/google_adk.py +49 -0
  104. pretensor/integrations/langchain.py +55 -0
  105. pretensor/integrations/llamaindex.py +53 -0
  106. pretensor/intelligence/__init__.py +33 -0
  107. pretensor/intelligence/cluster_labeler.py +425 -0
  108. pretensor/intelligence/clustering.py +168 -0
  109. pretensor/intelligence/combining.py +32 -0
  110. pretensor/intelligence/discovery.py +114 -0
  111. pretensor/intelligence/embeddings.py +317 -0
  112. pretensor/intelligence/graph_export.py +200 -0
  113. pretensor/intelligence/heuristic.py +544 -0
  114. pretensor/intelligence/join_paths/__init__.py +130 -0
  115. pretensor/intelligence/join_paths/on_demand.py +516 -0
  116. pretensor/intelligence/join_paths/storage.py +70 -0
  117. pretensor/intelligence/llm_infer.py +78 -0
  118. pretensor/intelligence/llm_runtime.py +62 -0
  119. pretensor/intelligence/metric_templates.py +193 -0
  120. pretensor/intelligence/pipeline.py +364 -0
  121. pretensor/intelligence/role_exemplars.py +263 -0
  122. pretensor/intelligence/schema_classification.py +360 -0
  123. pretensor/intelligence/scoring.py +76 -0
  124. pretensor/intelligence/semantic.py +240 -0
  125. pretensor/intelligence/shadow_alias.py +101 -0
  126. pretensor/intelligence/statistical.py +50 -0
  127. pretensor/intelligence/steps.py +191 -0
  128. pretensor/intelligence/steps_embedding.py +168 -0
  129. pretensor/introspection/__init__.py +6 -0
  130. pretensor/introspection/inspector.py +5 -0
  131. pretensor/introspection/models/__init__.py +0 -0
  132. pretensor/introspection/models/base.py +5 -0
  133. pretensor/introspection/models/config.py +237 -0
  134. pretensor/introspection/models/dsn.py +550 -0
  135. pretensor/introspection/models/plan.py +116 -0
  136. pretensor/introspection/models/schema.py +10 -0
  137. pretensor/introspection/models/semantic.py +121 -0
  138. pretensor/introspection/models/validation.py +116 -0
  139. pretensor/introspection/snapshot.py +46 -0
  140. pretensor/mcp/__init__.py +16 -0
  141. pretensor/mcp/config_json.py +24 -0
  142. pretensor/mcp/payload_types.py +274 -0
  143. pretensor/mcp/resources/__init__.py +17 -0
  144. pretensor/mcp/resources/markdown.py +314 -0
  145. pretensor/mcp/server.py +285 -0
  146. pretensor/mcp/service.py +49 -0
  147. pretensor/mcp/service_context.py +142 -0
  148. pretensor/mcp/service_registry.py +294 -0
  149. pretensor/mcp/store_cache.py +43 -0
  150. pretensor/mcp/tool_registry.py +136 -0
  151. pretensor/mcp/tools/__init__.py +1 -0
  152. pretensor/mcp/tools/_rank.py +244 -0
  153. pretensor/mcp/tools/_timed.py +26 -0
  154. pretensor/mcp/tools/compile_metric.py +144 -0
  155. pretensor/mcp/tools/consumers.py +161 -0
  156. pretensor/mcp/tools/context.py +1121 -0
  157. pretensor/mcp/tools/cypher.py +509 -0
  158. pretensor/mcp/tools/detect_changes.py +254 -0
  159. pretensor/mcp/tools/impact.py +271 -0
  160. pretensor/mcp/tools/list.py +131 -0
  161. pretensor/mcp/tools/schema.py +170 -0
  162. pretensor/mcp/tools/search.py +316 -0
  163. pretensor/mcp/tools/semantic_search.py +282 -0
  164. pretensor/mcp/tools/traverse.py +1027 -0
  165. pretensor/mcp/tools/validate_sql.py +150 -0
  166. pretensor/observability.py +203 -0
  167. pretensor/py.typed +0 -0
  168. pretensor/quickstart/README.md +29 -0
  169. pretensor/quickstart/__init__.py +6 -0
  170. pretensor/quickstart/docker-compose.yml +18 -0
  171. pretensor/quickstart/pagila_data.sql +63 -0
  172. pretensor/quickstart/pagila_ddl.sql +92 -0
  173. pretensor/search/__init__.py +6 -0
  174. pretensor/search/base.py +80 -0
  175. pretensor/search/index.py +435 -0
  176. pretensor/semantic/__init__.py +24 -0
  177. pretensor/semantic/base.py +123 -0
  178. pretensor/semantic/compiler.py +487 -0
  179. pretensor/semantic/yaml_layer.py +180 -0
  180. pretensor/skills/__init__.py +5 -0
  181. pretensor/skills/generator.py +235 -0
  182. pretensor/staleness/__init__.py +15 -0
  183. pretensor/staleness/graph_patcher.py +355 -0
  184. pretensor/staleness/impact_analyzer.py +162 -0
  185. pretensor/staleness/snapshot_store.py +38 -0
  186. pretensor/validation/__init__.py +9 -0
  187. pretensor/validation/query_validator.py +436 -0
  188. pretensor/visibility/__init__.py +23 -0
  189. pretensor/visibility/config.py +126 -0
  190. pretensor/visibility/filter.py +143 -0
  191. pretensor/visibility/kuzu_helpers.py +32 -0
  192. pretensor/visibility/runtime.py +36 -0
  193. pretensor/visibility/sync_grants.py +188 -0
  194. pretensor-0.1.0.dist-info/METADATA +251 -0
  195. pretensor-0.1.0.dist-info/RECORD +198 -0
  196. pretensor-0.1.0.dist-info/WHEEL +4 -0
  197. pretensor-0.1.0.dist-info/entry_points.txt +2 -0
  198. 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
+ ]