devtorch-core 3.0.1__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 (193) hide show
  1. devtorch_core/__init__.py +158 -0
  2. devtorch_core/aggphi_textual.py +275 -0
  3. devtorch_core/alerts/__init__.py +23 -0
  4. devtorch_core/alerts/base.py +46 -0
  5. devtorch_core/alerts/config.py +60 -0
  6. devtorch_core/alerts/dispatcher.py +110 -0
  7. devtorch_core/alerts/jira.py +96 -0
  8. devtorch_core/alerts/linear.py +72 -0
  9. devtorch_core/alerts/pagerduty.py +66 -0
  10. devtorch_core/alerts/slack.py +81 -0
  11. devtorch_core/alerts/teams.py +70 -0
  12. devtorch_core/audit/__init__.py +43 -0
  13. devtorch_core/audit/exporter.py +297 -0
  14. devtorch_core/audit/privacy.py +101 -0
  15. devtorch_core/audit/scrubber.py +149 -0
  16. devtorch_core/audit/service.py +67 -0
  17. devtorch_core/audit/signing.py +127 -0
  18. devtorch_core/broadcast/__init__.py +4 -0
  19. devtorch_core/broadcast/broadcaster.py +100 -0
  20. devtorch_core/broadcast/watcher.py +71 -0
  21. devtorch_core/capability.py +639 -0
  22. devtorch_core/cloud/__init__.py +1 -0
  23. devtorch_core/cloud/client_config.py +472 -0
  24. devtorch_core/cloud/client_configs/.claude-opencode-fallback.json +8 -0
  25. devtorch_core/cloud/client_configs/.claude-stdio.json +13 -0
  26. devtorch_core/cloud/client_configs/.cursor-mcp.json +13 -0
  27. devtorch_core/cloud/client_configs/.opencode-bridge.json +13 -0
  28. devtorch_core/cloud/client_configs/.opencode.json +15 -0
  29. devtorch_core/cloud/client_configs/.vscode-mcp.json +13 -0
  30. devtorch_core/cloud/devtorch-mcp-bridge.js +357 -0
  31. devtorch_core/cloud/mcp_client.py +229 -0
  32. devtorch_core/cloud/setup.py +144 -0
  33. devtorch_core/cloud/sync.py +143 -0
  34. devtorch_core/cloud/sync_bundle.py +603 -0
  35. devtorch_core/cloud/sync_conflicts.py +159 -0
  36. devtorch_core/cloud/sync_state.py +159 -0
  37. devtorch_core/cloud/team_sync.py +283 -0
  38. devtorch_core/codex/__init__.py +9 -0
  39. devtorch_core/codex/__main__.py +97 -0
  40. devtorch_core/codex/capture.py +208 -0
  41. devtorch_core/codex/proxy.py +412 -0
  42. devtorch_core/concept_catalog.py +209 -0
  43. devtorch_core/consolidation/__init__.py +3 -0
  44. devtorch_core/consolidation/synthesizer.py +87 -0
  45. devtorch_core/consolidation/workflow.py +175 -0
  46. devtorch_core/daemon/__init__.py +27 -0
  47. devtorch_core/daemon/supervisor.py +293 -0
  48. devtorch_core/daemon/watcher.py +244 -0
  49. devtorch_core/dashboard_api.py +2012 -0
  50. devtorch_core/deltaf.py +97 -0
  51. devtorch_core/disclosure.py +50 -0
  52. devtorch_core/divergence/__init__.py +3 -0
  53. devtorch_core/divergence/detector.py +166 -0
  54. devtorch_core/gateway/__init__.py +32 -0
  55. devtorch_core/gateway/key_manager.py +124 -0
  56. devtorch_core/gateway/metrics_webhook.py +252 -0
  57. devtorch_core/gateway/policy.py +262 -0
  58. devtorch_core/gateway/server.py +727 -0
  59. devtorch_core/gateway/sso.py +233 -0
  60. devtorch_core/gcc.py +1246 -0
  61. devtorch_core/github/__init__.py +35 -0
  62. devtorch_core/github/app.py +240 -0
  63. devtorch_core/github/comment_builder.py +113 -0
  64. devtorch_core/github/pat.py +76 -0
  65. devtorch_core/github/pr_parser.py +82 -0
  66. devtorch_core/github/pr_reporter.py +555 -0
  67. devtorch_core/gitlab/__init__.py +177 -0
  68. devtorch_core/hitl/__init__.py +4 -0
  69. devtorch_core/hitl/channels.py +129 -0
  70. devtorch_core/hitl/orchestrator.py +95 -0
  71. devtorch_core/hooks/__init__.py +17 -0
  72. devtorch_core/hooks/claude_code.py +228 -0
  73. devtorch_core/hooks/git_capture.py +341 -0
  74. devtorch_core/hooks/git_commit.py +182 -0
  75. devtorch_core/hooks/installer.py +733 -0
  76. devtorch_core/hooks/pre_commit.py +157 -0
  77. devtorch_core/hooks/runner.py +344 -0
  78. devtorch_core/identity/__init__.py +4 -0
  79. devtorch_core/identity/agent.py +86 -0
  80. devtorch_core/identity/providers.py +85 -0
  81. devtorch_core/invariants.py +182 -0
  82. devtorch_core/mcp/__init__.py +10 -0
  83. devtorch_core/mcp/auth.py +177 -0
  84. devtorch_core/mcp/server.py +1049 -0
  85. devtorch_core/metrics/__init__.py +35 -0
  86. devtorch_core/metrics/aggregate.py +215 -0
  87. devtorch_core/metrics/calibrate.py +198 -0
  88. devtorch_core/metrics/calibration.py +125 -0
  89. devtorch_core/metrics/credibility.py +288 -0
  90. devtorch_core/metrics/delivery_time.py +70 -0
  91. devtorch_core/metrics/dhs.py +126 -0
  92. devtorch_core/metrics/mcs.py +96 -0
  93. devtorch_core/metrics/roi.py +88 -0
  94. devtorch_core/metrics/session_writer.py +81 -0
  95. devtorch_core/metrics/shadow_ai.py +117 -0
  96. devtorch_core/metrics/sprint_writer.py +243 -0
  97. devtorch_core/observability/__init__.py +78 -0
  98. devtorch_core/observability/datadog.py +157 -0
  99. devtorch_core/observability/formatter.py +119 -0
  100. devtorch_core/observability/report.py +264 -0
  101. devtorch_core/observability/servicenow.py +147 -0
  102. devtorch_core/observability/splunk.py +218 -0
  103. devtorch_core/observability/webhook.py +227 -0
  104. devtorch_core/parser/__init__.py +30 -0
  105. devtorch_core/parser/blocks.py +216 -0
  106. devtorch_core/parser/inference.py +159 -0
  107. devtorch_core/parser/thinking.py +112 -0
  108. devtorch_core/projects.py +169 -0
  109. devtorch_core/prompt_artifact.py +76 -0
  110. devtorch_core/proxy/__init__.py +9 -0
  111. devtorch_core/proxy/routes/__init__.py +1 -0
  112. devtorch_core/proxy/routes/anthropic.py +264 -0
  113. devtorch_core/proxy/routes/azure_openai.py +336 -0
  114. devtorch_core/proxy/routes/gemini.py +331 -0
  115. devtorch_core/proxy/routes/groq.py +284 -0
  116. devtorch_core/proxy/routes/ollama.py +279 -0
  117. devtorch_core/proxy/routes/openai.py +287 -0
  118. devtorch_core/proxy/server.py +356 -0
  119. devtorch_core/query/__init__.py +15 -0
  120. devtorch_core/query/grep.py +181 -0
  121. devtorch_core/query/hybrid.py +86 -0
  122. devtorch_core/query/semantic.py +157 -0
  123. devtorch_core/rdp.py +105 -0
  124. devtorch_core/reasoning/__init__.py +4 -0
  125. devtorch_core/reasoning/entry.py +31 -0
  126. devtorch_core/reasoning/store.py +122 -0
  127. devtorch_core/reasoning_plus/__init__.py +70 -0
  128. devtorch_core/reasoning_plus/augmenter.py +326 -0
  129. devtorch_core/reasoning_plus/capture.py +51 -0
  130. devtorch_core/reasoning_plus/config.py +256 -0
  131. devtorch_core/reasoning_plus/context.py +262 -0
  132. devtorch_core/reasoning_plus/learning/__init__.py +72 -0
  133. devtorch_core/reasoning_plus/learning/analytics.py +141 -0
  134. devtorch_core/reasoning_plus/learning/api.py +313 -0
  135. devtorch_core/reasoning_plus/learning/chain.py +285 -0
  136. devtorch_core/reasoning_plus/learning/composer.py +74 -0
  137. devtorch_core/reasoning_plus/learning/cross_project.py +234 -0
  138. devtorch_core/reasoning_plus/learning/embeddings.py +209 -0
  139. devtorch_core/reasoning_plus/learning/extractor.py +207 -0
  140. devtorch_core/reasoning_plus/learning/models.py +116 -0
  141. devtorch_core/reasoning_plus/learning/provenance.py +126 -0
  142. devtorch_core/reasoning_plus/learning/recorder.py +81 -0
  143. devtorch_core/reasoning_plus/learning/relevance.py +122 -0
  144. devtorch_core/reasoning_plus/learning/state.py +86 -0
  145. devtorch_core/reasoning_plus/learning/store.py +160 -0
  146. devtorch_core/reasoning_plus/learning/theta_learning_bridge.py +94 -0
  147. devtorch_core/reasoning_plus/prompt.py +90 -0
  148. devtorch_core/rep.py +134 -0
  149. devtorch_core/rep_network/__init__.py +25 -0
  150. devtorch_core/rep_network/merge.py +70 -0
  151. devtorch_core/rep_network/node.py +137 -0
  152. devtorch_core/rep_network/server.py +140 -0
  153. devtorch_core/rep_network/sync.py +207 -0
  154. devtorch_core/sensitivity.py +182 -0
  155. devtorch_core/serve.py +258 -0
  156. devtorch_core/session/__init__.py +39 -0
  157. devtorch_core/session/disagreement.py +188 -0
  158. devtorch_core/session/models.py +114 -0
  159. devtorch_core/session/orchestrator.py +182 -0
  160. devtorch_core/session/planner.py +169 -0
  161. devtorch_core/session/simulator.py +132 -0
  162. devtorch_core/signing.py +290 -0
  163. devtorch_core/sis.py +197 -0
  164. devtorch_core/storage.py +308 -0
  165. devtorch_core/templates/__init__.py +6 -0
  166. devtorch_core/templates/engine.py +122 -0
  167. devtorch_core/templates/go.py +18 -0
  168. devtorch_core/templates/infra.py +19 -0
  169. devtorch_core/templates/library/__init__.py +18 -0
  170. devtorch_core/templates/library/api_design.md +27 -0
  171. devtorch_core/templates/library/bug_fix.md +27 -0
  172. devtorch_core/templates/library/decision_record.md +27 -0
  173. devtorch_core/templates/library/engine.py +228 -0
  174. devtorch_core/templates/library/security_review.md +30 -0
  175. devtorch_core/templates/python.py +19 -0
  176. devtorch_core/templates/react.py +18 -0
  177. devtorch_core/templates/typescript.py +18 -0
  178. devtorch_core/theta.py +221 -0
  179. devtorch_core/theta_synthesis.py +268 -0
  180. devtorch_core/topics.py +320 -0
  181. devtorch_core/variance.py +219 -0
  182. devtorch_core/wrapper/__init__.py +52 -0
  183. devtorch_core/wrapper/anthropic.py +487 -0
  184. devtorch_core/wrapper/base.py +562 -0
  185. devtorch_core/wrapper/bedrock.py +342 -0
  186. devtorch_core/wrapper/gemini.py +422 -0
  187. devtorch_core/wrapper/ollama.py +527 -0
  188. devtorch_core/wrapper/openai.py +461 -0
  189. devtorch_core-3.0.1.dist-info/METADATA +867 -0
  190. devtorch_core-3.0.1.dist-info/RECORD +193 -0
  191. devtorch_core-3.0.1.dist-info/WHEEL +5 -0
  192. devtorch_core-3.0.1.dist-info/entry_points.txt +2 -0
  193. devtorch_core-3.0.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,97 @@
1
+ """
2
+ Entry point for: python -m devtorch_core.codex
3
+
4
+ Usage:
5
+ python -m devtorch_core.codex start [--port PORT]
6
+ python -m devtorch_core.codex install [--project PATH]
7
+ python -m devtorch_core.codex status [--project PATH]
8
+ """
9
+ from __future__ import annotations
10
+
11
+ import argparse
12
+ import json
13
+ import sys
14
+
15
+
16
+ def _cmd_start(args: argparse.Namespace) -> None:
17
+ from devtorch_core.codex.proxy import CodexProxy
18
+
19
+ port: int = args.port
20
+ print(f"DevTorch Codex proxy running on http://localhost:{port}")
21
+ print(f"Configure Codex CLI: set OPENAI_BASE_URL=http://localhost:{port}/v1")
22
+
23
+ proxy = CodexProxy(port=port)
24
+ proxy.start() # blocks
25
+
26
+
27
+ def _cmd_install(args: argparse.Namespace) -> None:
28
+ import os
29
+ from devtorch_core.codex.proxy import install_codex_hook
30
+
31
+ project = args.project or os.getcwd()
32
+ ok, result = install_codex_hook(project)
33
+ if ok:
34
+ print(f"Codex config installed: {result}")
35
+ else:
36
+ print(f"Install failed: {result}", file=sys.stderr)
37
+ sys.exit(1)
38
+
39
+
40
+ def _cmd_status(args: argparse.Namespace) -> None:
41
+ import os
42
+ from devtorch_core.codex.proxy import get_codex_hook_status
43
+
44
+ project = args.project or os.getcwd()
45
+ status = get_codex_hook_status(project)
46
+ print(json.dumps(status, indent=2))
47
+
48
+
49
+ def main() -> None:
50
+ parser = argparse.ArgumentParser(
51
+ prog="python -m devtorch_core.codex",
52
+ description="DevTorch OpenAI Codex CLI proxy",
53
+ )
54
+ sub = parser.add_subparsers(dest="command")
55
+
56
+ # start
57
+ start_p = sub.add_parser("start", help="Start the Codex proxy (blocking)")
58
+ start_p.add_argument(
59
+ "--port",
60
+ type=int,
61
+ default=8766,
62
+ help="Port to listen on (default: 8766)",
63
+ )
64
+
65
+ # install
66
+ install_p = sub.add_parser(
67
+ "install", help="Install .codex/config.json for the current project"
68
+ )
69
+ install_p.add_argument(
70
+ "--project",
71
+ default=None,
72
+ help="Project root directory (default: cwd)",
73
+ )
74
+
75
+ # status
76
+ status_p = sub.add_parser("status", help="Show proxy and hook install status")
77
+ status_p.add_argument(
78
+ "--project",
79
+ default=None,
80
+ help="Project root directory (default: cwd)",
81
+ )
82
+
83
+ args = parser.parse_args()
84
+
85
+ if args.command == "start":
86
+ _cmd_start(args)
87
+ elif args.command == "install":
88
+ _cmd_install(args)
89
+ elif args.command == "status":
90
+ _cmd_status(args)
91
+ else:
92
+ parser.print_help()
93
+ sys.exit(1)
94
+
95
+
96
+ if __name__ == "__main__":
97
+ main()
@@ -0,0 +1,208 @@
1
+ """
2
+ devtorch_core.codex.capture
3
+ ===========================
4
+ Handles RACP prefix injection and reasoning capture for the Codex CLI proxy.
5
+
6
+ CodexCaptureHandler:
7
+ - pre_execute — injects RACP system prefix into the request body before
8
+ forwarding to OpenAI.
9
+ - post_execute — fires CaptureOrchestrator and appends a POST_TOOL_USE event
10
+ to .GCC/ after the response arrives.
11
+ - find_gcc_repo — walks cwd upward to find an initialised .GCC/ directory.
12
+
13
+ All methods degrade silently; never raises.
14
+ """
15
+ from __future__ import annotations
16
+
17
+ import logging
18
+ import threading
19
+ from pathlib import Path
20
+ from typing import Any
21
+
22
+ from devtorch_core.wrapper.base import (
23
+ CaptureOrchestrator,
24
+ RACPInjector,
25
+ is_disabled,
26
+ )
27
+
28
+ logger = logging.getLogger("devtorch.codex.capture")
29
+
30
+
31
+ class CodexCaptureHandler:
32
+ """Injects RACP context into Codex CLI requests and captures reasoning."""
33
+
34
+ # ------------------------------------------------------------------
35
+ # Public API
36
+ # ------------------------------------------------------------------
37
+
38
+ def pre_execute(self, request_body: dict, session_id: str) -> dict:
39
+ """
40
+ Inject the RACP system prefix into *request_body* before forwarding.
41
+
42
+ Returns the modified request_body with a system message prepended, or
43
+ the original request_body unchanged if:
44
+ - DEVTORCH_DISABLE is set, or
45
+ - no initialised .GCC/ repo is found, or
46
+ - any error occurs.
47
+ """
48
+ if is_disabled():
49
+ return request_body
50
+
51
+ try:
52
+ repo = self.find_gcc_repo()
53
+ if repo is None:
54
+ return request_body
55
+
56
+ injector = RACPInjector(repo)
57
+ prefix = injector.build_system_prefix()
58
+ if not prefix:
59
+ return request_body
60
+
61
+ import copy
62
+ modified = copy.deepcopy(request_body)
63
+ messages = modified.get("messages", [])
64
+
65
+ # Prepend a system message with the RACP prefix
66
+ racp_msg = {"role": "system", "content": prefix}
67
+ # If the first message is already a system message, prepend our
68
+ # prefix to its content rather than inserting a second system msg
69
+ if messages and messages[0].get("role") == "system":
70
+ existing_content = messages[0].get("content", "")
71
+ messages[0]["content"] = prefix + "\n\n" + existing_content
72
+ else:
73
+ messages.insert(0, racp_msg)
74
+
75
+ modified["messages"] = messages
76
+ return modified
77
+
78
+ except Exception as exc:
79
+ logger.warning("devtorch codex pre_execute error — %s", exc)
80
+ return request_body
81
+
82
+ def post_execute(
83
+ self,
84
+ request_body: dict,
85
+ response_body: dict,
86
+ session_id: str,
87
+ ) -> None:
88
+ """
89
+ Capture reasoning from the response into .GCC/ and append a
90
+ POST_TOOL_USE event to the event log.
91
+
92
+ Silent on all errors — never raises.
93
+ """
94
+ if is_disabled():
95
+ return
96
+
97
+ try:
98
+ repo = self.find_gcc_repo()
99
+ if repo is None:
100
+ return
101
+
102
+ # Extract response text from OpenAI chat completion format
103
+ response_text = _extract_response_text(response_body)
104
+ thinking_blocks: list = []
105
+
106
+ # Fire CaptureOrchestrator
107
+ orchestrator = CaptureOrchestrator(repo)
108
+ orchestrator.capture(response_text, thinking_blocks, session_id)
109
+
110
+ # Append POST_TOOL_USE event
111
+ _append_post_tool_use_event(repo, session_id, request_body)
112
+
113
+ except Exception as exc:
114
+ logger.warning("devtorch codex post_execute error — %s", exc)
115
+
116
+ def find_gcc_repo(self) -> Any | None:
117
+ """
118
+ Walk cwd upward looking for an initialised .GCC/ directory.
119
+ Returns a GCCRepository instance or None if not found.
120
+ """
121
+ try:
122
+ from devtorch_core import GCCRepository
123
+ except ImportError:
124
+ logger.warning("devtorch: devtorch_core not importable — codex wrapper disabled")
125
+ return None
126
+
127
+ for parent in [Path.cwd()] + list(Path.cwd().parents):
128
+ try:
129
+ candidate = GCCRepository.at(parent)
130
+ if candidate.is_initialized():
131
+ return candidate
132
+ except Exception:
133
+ continue
134
+ return None
135
+
136
+
137
+ # ---------------------------------------------------------------------------
138
+ # Module-level helpers
139
+ # ---------------------------------------------------------------------------
140
+
141
+ def _extract_response_text(response_body: dict) -> str:
142
+ """
143
+ Extract text content from an OpenAI chat completion response body.
144
+ Returns empty string on any error.
145
+ """
146
+ try:
147
+ choices = response_body.get("choices", [])
148
+ if not choices:
149
+ return ""
150
+ first_choice = choices[0]
151
+ message = first_choice.get("message", {})
152
+ content = message.get("content", "")
153
+ return content or ""
154
+ except Exception:
155
+ return ""
156
+
157
+
158
+ def _append_post_tool_use_event(repo: Any, session_id: str, request_body: dict) -> None:
159
+ """
160
+ Append a POST_TOOL_USE event to the repo's event log.
161
+ Mirrors the pattern in devtorch_core.hooks.runner.handle_post_tool_use.
162
+ """
163
+ try:
164
+ import json
165
+ import hashlib
166
+ import time
167
+ from pathlib import Path as _Path
168
+
169
+ payload = {
170
+ "tool_name": "codex_cli",
171
+ "session_id": session_id,
172
+ "model": request_body.get("model", "unknown"),
173
+ }
174
+
175
+ # Try the public _append_event method first
176
+ try:
177
+ repo._append_event("POST_TOOL_USE", payload)
178
+ return
179
+ except Exception:
180
+ pass
181
+
182
+ # Fallback: write directly to events.log.jsonl
183
+ log_path = _Path(repo.gcc_dir) / "events.log.jsonl"
184
+ prev_hash = "0" * 64
185
+ if log_path.exists():
186
+ lines = log_path.read_text(encoding="utf-8").strip().splitlines()
187
+ if lines:
188
+ try:
189
+ last = json.loads(lines[-1])
190
+ prev_hash = last.get("hash", prev_hash)
191
+ except Exception:
192
+ pass
193
+
194
+ entry = {
195
+ "type": "POST_TOOL_USE",
196
+ "ts": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
197
+ **payload,
198
+ }
199
+ entry_str = json.dumps(entry, sort_keys=True)
200
+ entry["hash"] = hashlib.sha256(
201
+ (prev_hash + entry_str).encode()
202
+ ).hexdigest()
203
+
204
+ with log_path.open("a", encoding="utf-8") as f:
205
+ f.write(json.dumps(entry) + "\n")
206
+
207
+ except Exception as exc:
208
+ logger.warning("devtorch codex append_event failed — %s", exc)