nexus-coding-agent 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 (131) hide show
  1. nexus/__init__.py +4 -0
  2. nexus/application/__init__.py +2 -0
  3. nexus/application/approval_service.py +130 -0
  4. nexus/application/diff_service.py +177 -0
  5. nexus/application/event_publisher.py +180 -0
  6. nexus/application/execution_context.py +29 -0
  7. nexus/application/execution_ledger.py +126 -0
  8. nexus/application/model_call_context.py +29 -0
  9. nexus/application/observed_model_gateway.py +194 -0
  10. nexus/application/plan_approval_service.py +250 -0
  11. nexus/application/planning.py +668 -0
  12. nexus/application/runtime.py +624 -0
  13. nexus/application/session_service.py +411 -0
  14. nexus/application/structured_output.py +96 -0
  15. nexus/application/telemetry.py +396 -0
  16. nexus/application/telemetry_subscriber.py +216 -0
  17. nexus/application/tool_runtime.py +496 -0
  18. nexus/application/tracing_dispatcher.py +283 -0
  19. nexus/application/validation.py +293 -0
  20. nexus/config/__init__.py +17 -0
  21. nexus/config/loader.py +253 -0
  22. nexus/config/models.py +310 -0
  23. nexus/context/__init__.py +6 -0
  24. nexus/context/budget.py +24 -0
  25. nexus/context/builder.py +92 -0
  26. nexus/context/chunking.py +65 -0
  27. nexus/context/explorer.py +246 -0
  28. nexus/context/integration.py +63 -0
  29. nexus/context/manager.py +328 -0
  30. nexus/context/retrieval.py +261 -0
  31. nexus/domain/__init__.py +2 -0
  32. nexus/domain/agent_decision.py +113 -0
  33. nexus/domain/agent_state.py +49 -0
  34. nexus/domain/approvals.py +64 -0
  35. nexus/domain/context.py +108 -0
  36. nexus/domain/exploration.py +86 -0
  37. nexus/domain/mcp.py +51 -0
  38. nexus/domain/model.py +173 -0
  39. nexus/domain/observability.py +326 -0
  40. nexus/domain/persistence.py +122 -0
  41. nexus/domain/planning.py +329 -0
  42. nexus/domain/ports/__init__.py +61 -0
  43. nexus/domain/ports/agent_decision.py +9 -0
  44. nexus/domain/ports/approval_unit_of_work.py +27 -0
  45. nexus/domain/ports/checkpoint_provider.py +11 -0
  46. nexus/domain/ports/context.py +71 -0
  47. nexus/domain/ports/events.py +21 -0
  48. nexus/domain/ports/graph_runtime.py +30 -0
  49. nexus/domain/ports/mcp.py +23 -0
  50. nexus/domain/ports/model_gateway.py +21 -0
  51. nexus/domain/ports/model_input_budget.py +15 -0
  52. nexus/domain/ports/planning.py +62 -0
  53. nexus/domain/ports/repositories.py +54 -0
  54. nexus/domain/ports/repository_context.py +18 -0
  55. nexus/domain/ports/session_unit_of_work.py +33 -0
  56. nexus/domain/ports/skills.py +41 -0
  57. nexus/domain/ports/tooling.py +39 -0
  58. nexus/domain/ports/tracer.py +13 -0
  59. nexus/domain/ports/validation.py +32 -0
  60. nexus/domain/runtime_events.py +445 -0
  61. nexus/domain/skills.py +129 -0
  62. nexus/domain/tooling.py +163 -0
  63. nexus/domain/validation.py +161 -0
  64. nexus/errors/__init__.py +82 -0
  65. nexus/evaluation/__init__.py +7 -0
  66. nexus/evaluation/assertions.py +4 -0
  67. nexus/evaluation/evaluator.py +263 -0
  68. nexus/evaluation/fixtures.py +36 -0
  69. nexus/evaluation/harness.py +606 -0
  70. nexus/evaluation/loader.py +415 -0
  71. nexus/evaluation/metrics.py +27 -0
  72. nexus/evaluation/models.py +362 -0
  73. nexus/evaluation/report.py +43 -0
  74. nexus/evaluation/runner.py +480 -0
  75. nexus/infrastructure/__init__.py +2 -0
  76. nexus/infrastructure/asyncio_compat.py +13 -0
  77. nexus/infrastructure/bootstrap/__init__.py +17 -0
  78. nexus/infrastructure/bootstrap/composition.py +663 -0
  79. nexus/infrastructure/checkpoint/__init__.py +5 -0
  80. nexus/infrastructure/checkpoint/postgres.py +62 -0
  81. nexus/infrastructure/database.py +39 -0
  82. nexus/infrastructure/embedding.py +61 -0
  83. nexus/infrastructure/graph/__init__.py +6 -0
  84. nexus/infrastructure/graph/day4_runtime.py +966 -0
  85. nexus/infrastructure/graph/langgraph_runtime.py +172 -0
  86. nexus/infrastructure/mcp/__init__.py +5 -0
  87. nexus/infrastructure/mcp/manager.py +380 -0
  88. nexus/infrastructure/model_gateway/__init__.py +6 -0
  89. nexus/infrastructure/model_gateway/openai_compatible.py +345 -0
  90. nexus/infrastructure/observability/__init__.py +7 -0
  91. nexus/infrastructure/observability/console.py +31 -0
  92. nexus/infrastructure/observability/langsmith.py +236 -0
  93. nexus/infrastructure/observability/structured_logger.py +70 -0
  94. nexus/infrastructure/persistence/__init__.py +13 -0
  95. nexus/infrastructure/persistence/approval_unit_of_work.py +74 -0
  96. nexus/infrastructure/persistence/models.py +146 -0
  97. nexus/infrastructure/persistence/repositories.py +326 -0
  98. nexus/infrastructure/persistence/unit_of_work.py +82 -0
  99. nexus/infrastructure/repository_files.py +117 -0
  100. nexus/infrastructure/sandbox/__init__.py +5 -0
  101. nexus/infrastructure/sandbox/local_process.py +353 -0
  102. nexus/infrastructure/semantic.py +276 -0
  103. nexus/infrastructure/semantic_models.py +56 -0
  104. nexus/interfaces/__init__.py +2 -0
  105. nexus/interfaces/cli/__init__.py +2 -0
  106. nexus/interfaces/cli/__main__.py +6 -0
  107. nexus/interfaces/cli/app.py +266 -0
  108. nexus/interfaces/cli/renderer.py +118 -0
  109. nexus/security/__init__.py +14 -0
  110. nexus/security/approval_policies.py +73 -0
  111. nexus/security/command_policy.py +117 -0
  112. nexus/security/executables.py +107 -0
  113. nexus/security/git_commands.py +65 -0
  114. nexus/security/workspace.py +93 -0
  115. nexus/skills/__init__.py +7 -0
  116. nexus/skills/builtin/__init__.py +1 -0
  117. nexus/skills/builtin/debug-python/SKILL.md +26 -0
  118. nexus/skills/builtin/review-repository/SKILL.md +26 -0
  119. nexus/skills/builtin/write-tests/SKILL.md +26 -0
  120. nexus/skills/loader.py +439 -0
  121. nexus/skills/registry.py +146 -0
  122. nexus/skills/selector.py +152 -0
  123. nexus/tools/__init__.py +6 -0
  124. nexus/tools/editing.py +312 -0
  125. nexus/tools/mcp.py +160 -0
  126. nexus/tools/native.py +654 -0
  127. nexus/tools/registry.py +27 -0
  128. nexus_coding_agent-0.1.0.dist-info/METADATA +142 -0
  129. nexus_coding_agent-0.1.0.dist-info/RECORD +131 -0
  130. nexus_coding_agent-0.1.0.dist-info/WHEEL +4 -0
  131. nexus_coding_agent-0.1.0.dist-info/entry_points.txt +2 -0
@@ -0,0 +1,62 @@
1
+ """Lifecycle adapter for the official asynchronous PostgreSQL checkpointer."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from contextlib import AbstractAsyncContextManager
6
+
7
+ from langgraph.checkpoint.postgres.aio import AsyncPostgresSaver
8
+ from sqlalchemy.engine import make_url
9
+
10
+ from nexus.errors import NexusError
11
+
12
+
13
+ class PostgresCheckpointProvider:
14
+ """Own AsyncPostgresSaver creation, setup, and release."""
15
+
16
+ def __init__(self, database_url: str) -> None:
17
+ self._connection_string = _to_psycopg_connection_string(database_url)
18
+ self._context: AbstractAsyncContextManager[AsyncPostgresSaver] | None = None
19
+ self._checkpointer: AsyncPostgresSaver | None = None
20
+
21
+ async def setup(self) -> None:
22
+ if self._checkpointer is not None:
23
+ return
24
+ context = AsyncPostgresSaver.from_conn_string(self._connection_string)
25
+ self._context = context
26
+ try:
27
+ checkpointer = await context.__aenter__()
28
+ await checkpointer.setup()
29
+ except Exception as exc:
30
+ self._context = None
31
+ try:
32
+ await context.__aexit__(type(exc), exc, exc.__traceback__)
33
+ except Exception:
34
+ pass
35
+ raise NexusError(
36
+ "Nexus could not initialize durable graph checkpoints.",
37
+ code="CHECKPOINT_SETUP_ERROR",
38
+ retryable=True,
39
+ ) from exc
40
+ self._checkpointer = checkpointer
41
+
42
+ def get_checkpointer(self) -> object:
43
+ if self._checkpointer is None:
44
+ raise RuntimeError("CheckpointProvider.setup() must run before use.")
45
+ return self._checkpointer
46
+
47
+ async def close(self) -> None:
48
+ context = self._context
49
+ self._context = None
50
+ self._checkpointer = None
51
+ if context is not None:
52
+ await context.__aexit__(None, None, None)
53
+
54
+
55
+ def _to_psycopg_connection_string(database_url: str) -> str:
56
+ url = make_url(database_url)
57
+ if url.get_backend_name() != "postgresql":
58
+ raise NexusError(
59
+ "The checkpoint database must use PostgreSQL.",
60
+ code="CHECKPOINT_CONFIGURATION_ERROR",
61
+ )
62
+ return url.set(drivername="postgresql").render_as_string(hide_password=False)
@@ -0,0 +1,39 @@
1
+ """Day 1 PostgreSQL engine bootstrap and connectivity check."""
2
+
3
+ from sqlalchemy import text
4
+ from sqlalchemy.ext.asyncio import (
5
+ AsyncEngine,
6
+ AsyncSession,
7
+ async_sessionmaker,
8
+ create_async_engine,
9
+ )
10
+
11
+
12
+ class DatabaseBootstrap:
13
+ """Own the Day 1 async engine without introducing business persistence."""
14
+
15
+ def __init__(self, database_url: str) -> None:
16
+ self._engine: AsyncEngine = create_async_engine(
17
+ database_url,
18
+ connect_args={"timeout": 5},
19
+ hide_parameters=True,
20
+ pool_timeout=5,
21
+ )
22
+ self._session_factory = async_sessionmaker(self._engine, expire_on_commit=False)
23
+
24
+ @property
25
+ def session_factory(self) -> async_sessionmaker[AsyncSession]:
26
+ """Provide transaction-scoped sessions to infrastructure adapters."""
27
+
28
+ return self._session_factory
29
+
30
+ async def check_connection(self) -> None:
31
+ """Open a connection and execute the smallest useful smoke query."""
32
+
33
+ async with self._engine.connect() as connection:
34
+ await connection.execute(text("SELECT 1"))
35
+
36
+ async def close(self) -> None:
37
+ """Dispose the engine pool and any checked-in connections."""
38
+
39
+ await self._engine.dispose()
@@ -0,0 +1,61 @@
1
+ """Independent LangChain OpenAI-compatible embedding adapter."""
2
+
3
+ from collections.abc import Sequence
4
+ from math import isfinite
5
+
6
+ from langchain_openai import OpenAIEmbeddings
7
+
8
+ from nexus.config.models import RuntimeConfig
9
+ from nexus.domain.context import EmbeddingConfig
10
+ from nexus.errors import ContextError
11
+
12
+
13
+ class OpenAICompatibleEmbeddingGateway:
14
+ def __init__(self, config: RuntimeConfig) -> None:
15
+ config.require_embedding()
16
+ self._config = EmbeddingConfig(
17
+ config.embedding_provider,
18
+ config.embedding_model,
19
+ config.embedding_dimension,
20
+ )
21
+ self._client = OpenAIEmbeddings(
22
+ model=config.embedding_model,
23
+ base_url=config.embedding_base_url,
24
+ api_key=config.embedding_api_key,
25
+ dimensions=config.embedding_dimension,
26
+ check_embedding_ctx_length=False,
27
+ )
28
+
29
+ @property
30
+ def config(self) -> EmbeddingConfig:
31
+ return self._config
32
+
33
+ async def embed_documents(self, texts: Sequence[str]) -> tuple[tuple[float, ...], ...]:
34
+ if not texts:
35
+ return ()
36
+ try:
37
+ vectors = await self._client.aembed_documents(list(texts))
38
+ return validate_vectors(vectors, len(texts), self.config.dimension)
39
+ except Exception as exc:
40
+ raise ContextError(
41
+ "Embedding request failed or returned invalid vectors.",
42
+ code="EMBEDDING_FAILED",
43
+ retryable=True,
44
+ ) from exc
45
+
46
+ async def embed_query(self, text: str) -> tuple[float, ...]:
47
+ return (await self.embed_documents((text,)))[0]
48
+
49
+
50
+ def validate_vectors(
51
+ vectors: Sequence[Sequence[float]],
52
+ count: int,
53
+ dimension: int,
54
+ ) -> tuple[tuple[float, ...], ...]:
55
+ result = tuple(tuple(float(value) for value in vector) for vector in vectors)
56
+ if len(result) != count or any(
57
+ len(vector) != dimension or not all(isfinite(value) for value in vector) or not any(vector)
58
+ for vector in result
59
+ ):
60
+ raise ContextError("Invalid embedding shape or values.", code="EMBEDDING_FAILED")
61
+ return result
@@ -0,0 +1,6 @@
1
+ """Concrete graph runtime adapters."""
2
+
3
+ from nexus.infrastructure.graph.langgraph_runtime import LangGraphRuntime
4
+
5
+ __all__ = ["LangGraphRuntime"]
6
+