opencontext-api 0.1.0__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.
- opencontext_api-0.1.0/LICENSE +22 -0
- opencontext_api-0.1.0/PKG-INFO +39 -0
- opencontext_api-0.1.0/README.md +12 -0
- opencontext_api-0.1.0/opencontext_api/__init__.py +1 -0
- opencontext_api-0.1.0/opencontext_api/main.py +314 -0
- opencontext_api-0.1.0/opencontext_api/schemas.py +184 -0
- opencontext_api-0.1.0/opencontext_api.egg-info/PKG-INFO +39 -0
- opencontext_api-0.1.0/opencontext_api.egg-info/SOURCES.txt +11 -0
- opencontext_api-0.1.0/opencontext_api.egg-info/dependency_links.txt +1 -0
- opencontext_api-0.1.0/opencontext_api.egg-info/requires.txt +4 -0
- opencontext_api-0.1.0/opencontext_api.egg-info/top_level.txt +1 -0
- opencontext_api-0.1.0/pyproject.toml +39 -0
- opencontext_api-0.1.0/setup.cfg +4 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 OpenContext Runtime contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: opencontext-api
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: FastAPI adapter for OpenContext Runtime
|
|
5
|
+
Author: OpenContext Runtime maintainers
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/CesarMSFelipe/OpenContext-Runtime
|
|
8
|
+
Project-URL: Documentation, https://github.com/CesarMSFelipe/OpenContext-Runtime#readme
|
|
9
|
+
Project-URL: Issues, https://github.com/CesarMSFelipe/OpenContext-Runtime/issues
|
|
10
|
+
Project-URL: Source, https://github.com/CesarMSFelipe/OpenContext-Runtime
|
|
11
|
+
Keywords: ai,llm,context-engineering,fastapi,security
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Framework :: FastAPI
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
|
|
18
|
+
Classifier: Topic :: Security
|
|
19
|
+
Requires-Python: >=3.12
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Requires-Dist: fastapi>=0.110
|
|
23
|
+
Requires-Dist: httpx>=0.27
|
|
24
|
+
Requires-Dist: opencontext-core>=0.1.0
|
|
25
|
+
Requires-Dist: opencontext-profiles>=0.1.0
|
|
26
|
+
Dynamic: license-file
|
|
27
|
+
|
|
28
|
+
# opencontext-api
|
|
29
|
+
|
|
30
|
+
FastAPI adapter for OpenContext Runtime.
|
|
31
|
+
|
|
32
|
+
Use this package when a non-Python host needs HTTP endpoints for runtime-first setup and context
|
|
33
|
+
preparation:
|
|
34
|
+
|
|
35
|
+
- `POST /v1/setup`
|
|
36
|
+
- `POST /v1/context`
|
|
37
|
+
- `GET /v1/traces/{trace_id}`
|
|
38
|
+
|
|
39
|
+
The API is intentionally thin and delegates context behavior to `opencontext-core`.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# opencontext-api
|
|
2
|
+
|
|
3
|
+
FastAPI adapter for OpenContext Runtime.
|
|
4
|
+
|
|
5
|
+
Use this package when a non-Python host needs HTTP endpoints for runtime-first setup and context
|
|
6
|
+
preparation:
|
|
7
|
+
|
|
8
|
+
- `POST /v1/setup`
|
|
9
|
+
- `POST /v1/context`
|
|
10
|
+
- `GET /v1/traces/{trace_id}`
|
|
11
|
+
|
|
12
|
+
The API is intentionally thin and delegates context behavior to `opencontext-core`.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""OpenContext Runtime API package."""
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
"""FastAPI adapter for OpenContext Runtime."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from fastapi import FastAPI
|
|
8
|
+
|
|
9
|
+
from opencontext_api.schemas import (
|
|
10
|
+
AgentContextRequest,
|
|
11
|
+
ContextPackRequest,
|
|
12
|
+
ContextPackResponse,
|
|
13
|
+
IndexRequest,
|
|
14
|
+
IndexResponse,
|
|
15
|
+
ManifestResponse,
|
|
16
|
+
OrchestrateRequest,
|
|
17
|
+
PreparedContextRequest,
|
|
18
|
+
PreparedContextResponse,
|
|
19
|
+
RepoMapResponse,
|
|
20
|
+
RunRequest,
|
|
21
|
+
RunResponse,
|
|
22
|
+
ScaffoldResponse,
|
|
23
|
+
SetupRequest,
|
|
24
|
+
SetupResponse,
|
|
25
|
+
TraceResponse,
|
|
26
|
+
ValidateRequest,
|
|
27
|
+
)
|
|
28
|
+
from opencontext_core.actions import ActionRequest, ActionType, evaluate_action
|
|
29
|
+
from opencontext_core.doctor.checks import run_doctor
|
|
30
|
+
from opencontext_core.dx.security_reports import scan_project
|
|
31
|
+
from opencontext_core.dx.tokens import build_token_report
|
|
32
|
+
from opencontext_core.project.profiles import TechnologyProfile
|
|
33
|
+
from opencontext_core.runtime import OpenContextRuntime
|
|
34
|
+
from opencontext_core.safety.redaction import SinkGuard
|
|
35
|
+
|
|
36
|
+
try:
|
|
37
|
+
from opencontext_profiles import first_party_profiles
|
|
38
|
+
except ModuleNotFoundError:
|
|
39
|
+
|
|
40
|
+
def first_party_profiles() -> list[TechnologyProfile]:
|
|
41
|
+
return []
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
app = FastAPI(title="OpenContext Runtime API", version="0.1.0")
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _runtime() -> OpenContextRuntime:
|
|
48
|
+
return OpenContextRuntime(technology_profiles=first_party_profiles())
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@app.post("/v1/index", response_model=IndexResponse)
|
|
52
|
+
def index_project(request: IndexRequest) -> IndexResponse:
|
|
53
|
+
"""Index a project root."""
|
|
54
|
+
|
|
55
|
+
runtime = _runtime()
|
|
56
|
+
manifest = runtime.index_project(request.root)
|
|
57
|
+
return IndexResponse(
|
|
58
|
+
project_name=manifest.project_name,
|
|
59
|
+
files=len(manifest.files),
|
|
60
|
+
symbols=len(manifest.symbols),
|
|
61
|
+
technology_profiles=manifest.technology_profiles,
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@app.post("/v1/setup", response_model=SetupResponse)
|
|
66
|
+
def setup_project(request: SetupRequest) -> SetupResponse:
|
|
67
|
+
"""Create project harness files and persist the project index without CLI commands."""
|
|
68
|
+
|
|
69
|
+
runtime = _runtime()
|
|
70
|
+
result = runtime.setup_project(
|
|
71
|
+
request.root,
|
|
72
|
+
write_config=request.write_config,
|
|
73
|
+
refresh_index=request.refresh_index,
|
|
74
|
+
)
|
|
75
|
+
return SetupResponse(**result.model_dump())
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
@app.post("/v1/runs", response_model=RunResponse)
|
|
79
|
+
def run_workflow(request: RunRequest) -> RunResponse:
|
|
80
|
+
"""Run a configured workflow."""
|
|
81
|
+
|
|
82
|
+
runtime = _runtime()
|
|
83
|
+
result = runtime.ask(request.input, request.workflow_name)
|
|
84
|
+
safe_answer, _ = SinkGuard().redact(result.answer)
|
|
85
|
+
return RunResponse(
|
|
86
|
+
answer=safe_answer,
|
|
87
|
+
trace_id=result.trace_id,
|
|
88
|
+
token_usage=result.token_usage,
|
|
89
|
+
selected_context_count=result.selected_context_count,
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
@app.get("/v1/traces/{trace_id}", response_model=TraceResponse)
|
|
94
|
+
def get_trace(trace_id: str) -> TraceResponse:
|
|
95
|
+
"""Load a persisted trace."""
|
|
96
|
+
|
|
97
|
+
runtime = _runtime()
|
|
98
|
+
trace = runtime.load_trace(trace_id)
|
|
99
|
+
return TraceResponse(trace=trace.model_dump(mode="json"))
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
@app.get("/v1/project/manifest", response_model=ManifestResponse)
|
|
103
|
+
def get_manifest() -> ManifestResponse:
|
|
104
|
+
"""Load the persisted project manifest."""
|
|
105
|
+
|
|
106
|
+
runtime = _runtime()
|
|
107
|
+
manifest = runtime.load_manifest()
|
|
108
|
+
return ManifestResponse(manifest=manifest.model_dump(mode="json"))
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
@app.get("/v1/project/repomap", response_model=RepoMapResponse)
|
|
112
|
+
def get_repo_map() -> RepoMapResponse:
|
|
113
|
+
"""Render the compact repository map."""
|
|
114
|
+
|
|
115
|
+
runtime = _runtime()
|
|
116
|
+
safe_repo_map, _ = SinkGuard().redact(runtime.render_repo_map())
|
|
117
|
+
return RepoMapResponse(repo_map=safe_repo_map)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
@app.post("/v1/context/pack", response_model=ContextPackResponse)
|
|
121
|
+
def build_context_pack(request: ContextPackRequest) -> ContextPackResponse:
|
|
122
|
+
"""Build a token-aware context pack."""
|
|
123
|
+
|
|
124
|
+
runtime = _runtime()
|
|
125
|
+
pack = runtime.build_context_pack(request.query, request.max_tokens)
|
|
126
|
+
return ContextPackResponse(pack=pack.model_dump(mode="json"))
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
@app.post("/v1/context", response_model=PreparedContextResponse)
|
|
130
|
+
def prepare_context(request: PreparedContextRequest) -> PreparedContextResponse:
|
|
131
|
+
"""Prepare and persist a compact context bundle for non-CLI callers."""
|
|
132
|
+
|
|
133
|
+
runtime = _runtime()
|
|
134
|
+
prepared = runtime.prepare_context(
|
|
135
|
+
request.query,
|
|
136
|
+
root=request.root,
|
|
137
|
+
max_tokens=request.max_tokens,
|
|
138
|
+
refresh_index=request.refresh_index,
|
|
139
|
+
)
|
|
140
|
+
safe_context, _ = SinkGuard().redact(prepared.context)
|
|
141
|
+
return PreparedContextResponse(
|
|
142
|
+
trace_id=prepared.trace_id,
|
|
143
|
+
context=safe_context,
|
|
144
|
+
included_sources=prepared.included_sources,
|
|
145
|
+
omitted_sources=prepared.omitted_sources,
|
|
146
|
+
token_usage=prepared.token_usage,
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
@app.get("/v1/security/report")
|
|
151
|
+
def security_report() -> dict[str, object]:
|
|
152
|
+
return {"status": "scaffold", "result": scan_project().model_dump()}
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
@app.post("/v1/security/scan")
|
|
156
|
+
def security_scan() -> dict[str, object]:
|
|
157
|
+
return {"status": "scaffold", "result": scan_project().model_dump()}
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
@app.get("/v1/doctor")
|
|
161
|
+
def doctor() -> dict[str, object]:
|
|
162
|
+
runtime = _runtime()
|
|
163
|
+
return {"checks": [check.model_dump() for check in run_doctor(runtime.config)]}
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
@app.get("/v1/tokens/report")
|
|
167
|
+
def tokens_report() -> dict[str, object]:
|
|
168
|
+
return build_token_report(Path(".")).model_dump()
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
@app.post("/v1/orchestrate", response_model=ScaffoldResponse)
|
|
172
|
+
def orchestrate(request: OrchestrateRequest) -> ScaffoldResponse:
|
|
173
|
+
"""Plan a permissioned orchestration run without executing actions."""
|
|
174
|
+
|
|
175
|
+
runtime = _runtime()
|
|
176
|
+
mode = runtime.config.security.mode
|
|
177
|
+
return ScaffoldResponse(
|
|
178
|
+
status="scaffold",
|
|
179
|
+
result={
|
|
180
|
+
"mode": "orchestrate",
|
|
181
|
+
"requirements_path": request.requirements_path,
|
|
182
|
+
"safe_commands": evaluate_action(
|
|
183
|
+
ActionRequest(action=ActionType.RUN_SAFE_COMMAND),
|
|
184
|
+
security_mode=mode,
|
|
185
|
+
).model_dump(mode="json"),
|
|
186
|
+
"write_file": evaluate_action(
|
|
187
|
+
ActionRequest(action=ActionType.WRITE_FILE),
|
|
188
|
+
security_mode=mode,
|
|
189
|
+
).model_dump(mode="json"),
|
|
190
|
+
},
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
@app.post("/v1/validate", response_model=ScaffoldResponse)
|
|
195
|
+
def validate(request: ValidateRequest) -> ScaffoldResponse:
|
|
196
|
+
"""Plan safe validation checks without running shell commands."""
|
|
197
|
+
|
|
198
|
+
runtime = _runtime()
|
|
199
|
+
mode = runtime.config.security.mode
|
|
200
|
+
return ScaffoldResponse(
|
|
201
|
+
status="scaffold",
|
|
202
|
+
result={
|
|
203
|
+
"profile": request.profile,
|
|
204
|
+
"run_tests": evaluate_action(
|
|
205
|
+
ActionRequest(action=ActionType.RUN_TEST),
|
|
206
|
+
security_mode=mode,
|
|
207
|
+
).model_dump(mode="json"),
|
|
208
|
+
"run_linter": evaluate_action(
|
|
209
|
+
ActionRequest(action=ActionType.RUN_LINTER),
|
|
210
|
+
security_mode=mode,
|
|
211
|
+
).model_dump(mode="json"),
|
|
212
|
+
},
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
@app.post("/v1/agent-context", response_model=ScaffoldResponse)
|
|
217
|
+
def agent_context(request: AgentContextRequest) -> ScaffoldResponse:
|
|
218
|
+
"""Return a sanitized generic agent context envelope."""
|
|
219
|
+
|
|
220
|
+
runtime = _runtime()
|
|
221
|
+
prepared = runtime.prepare_context(
|
|
222
|
+
request.query,
|
|
223
|
+
root=request.root,
|
|
224
|
+
max_tokens=request.max_tokens,
|
|
225
|
+
refresh_index=request.refresh_index,
|
|
226
|
+
)
|
|
227
|
+
safe_query, _ = SinkGuard().redact(prepared.query)
|
|
228
|
+
safe_context, _ = SinkGuard().redact(prepared.context)
|
|
229
|
+
return ScaffoldResponse(
|
|
230
|
+
status="ready",
|
|
231
|
+
result={
|
|
232
|
+
"target": request.target,
|
|
233
|
+
"mode": request.mode,
|
|
234
|
+
"max_tokens": request.max_tokens,
|
|
235
|
+
"trace_id": prepared.trace_id,
|
|
236
|
+
"query": safe_query,
|
|
237
|
+
"context": safe_context,
|
|
238
|
+
"included_sources": prepared.included_sources,
|
|
239
|
+
"omitted_sources": prepared.omitted_sources,
|
|
240
|
+
"token_usage": prepared.token_usage,
|
|
241
|
+
"raw_secrets_included": False,
|
|
242
|
+
},
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
@app.post("/v1/refactor/sdd", response_model=ScaffoldResponse)
|
|
247
|
+
def sdd_flow(request: PreparedContextRequest) -> ScaffoldResponse:
|
|
248
|
+
"""Specification-Driven Development (SDD) context engineering flow.
|
|
249
|
+
|
|
250
|
+
Unified workflow for context preparation across all technology stacks.
|
|
251
|
+
Implements the SDD flow: explore → propose → test → verify → review.
|
|
252
|
+
|
|
253
|
+
This endpoint is technology-agnostic and works with any framework,
|
|
254
|
+
language, or architecture pattern. It integrates with OpenContext's
|
|
255
|
+
agent-agnostic workflow engine to provide consistent context preparation
|
|
256
|
+
regardless of the underlying technology.
|
|
257
|
+
"""
|
|
258
|
+
|
|
259
|
+
runtime = _runtime()
|
|
260
|
+
|
|
261
|
+
# Phase 1: Explore - retrieve and rank candidates
|
|
262
|
+
prepared = runtime.prepare_context(
|
|
263
|
+
request.query,
|
|
264
|
+
root=request.root,
|
|
265
|
+
max_tokens=request.max_tokens,
|
|
266
|
+
refresh_index=request.refresh_index,
|
|
267
|
+
)
|
|
268
|
+
|
|
269
|
+
safe_query, _ = SinkGuard().redact(prepared.query)
|
|
270
|
+
safe_context, _ = SinkGuard().redact(prepared.context)
|
|
271
|
+
|
|
272
|
+
# Phase 2: Test - validate context pack safety
|
|
273
|
+
from opencontext_core.safety.firewall import ContextFirewall
|
|
274
|
+
|
|
275
|
+
firewall = ContextFirewall(runtime.config)
|
|
276
|
+
test_decision = firewall.check_context_export(
|
|
277
|
+
prepared.included_sources,
|
|
278
|
+
sink="sdd_test",
|
|
279
|
+
)
|
|
280
|
+
|
|
281
|
+
# Phase 3: Verify - security scan
|
|
282
|
+
from opencontext_core.dx.security_reports import scan_project
|
|
283
|
+
|
|
284
|
+
scan = scan_project(request.root)
|
|
285
|
+
|
|
286
|
+
# Phase 4: Review - check for high-risk patterns
|
|
287
|
+
manifest = runtime.load_manifest()
|
|
288
|
+
high_risk_count = sum(
|
|
289
|
+
1
|
|
290
|
+
for f in manifest.files
|
|
291
|
+
if any(s in f.path.lower() for s in ["secret", "key", "credential", "token", "password"])
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
return ScaffoldResponse(
|
|
295
|
+
status="completed",
|
|
296
|
+
result={
|
|
297
|
+
"mode": "sdd",
|
|
298
|
+
"trace_id": prepared.trace_id,
|
|
299
|
+
"query": safe_query,
|
|
300
|
+
"context": safe_context,
|
|
301
|
+
"included_sources": prepared.included_sources,
|
|
302
|
+
"omitted_sources": prepared.omitted_sources,
|
|
303
|
+
"token_usage": prepared.token_usage,
|
|
304
|
+
"raw_secrets_included": False,
|
|
305
|
+
"safety": {
|
|
306
|
+
"test_allowed": test_decision.allowed,
|
|
307
|
+
"test_reason": test_decision.reason,
|
|
308
|
+
"security_scan_severity": scan.severity.value,
|
|
309
|
+
"security_findings": len(scan.findings),
|
|
310
|
+
"high_risk_files": high_risk_count,
|
|
311
|
+
"review_status": "approved" if high_risk_count == 0 else "requires_review",
|
|
312
|
+
},
|
|
313
|
+
},
|
|
314
|
+
)
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"""FastAPI schemas for the OpenContext Runtime adapter."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class IndexRequest(BaseModel):
|
|
11
|
+
"""Request body for project indexing."""
|
|
12
|
+
|
|
13
|
+
model_config = ConfigDict(extra="forbid")
|
|
14
|
+
|
|
15
|
+
root: str = Field(default=".", description="Project root to index.")
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class IndexResponse(BaseModel):
|
|
19
|
+
"""Response body for project indexing."""
|
|
20
|
+
|
|
21
|
+
model_config = ConfigDict(extra="forbid")
|
|
22
|
+
|
|
23
|
+
project_name: str = Field(description="Indexed project name.")
|
|
24
|
+
files: int = Field(ge=0, description="Number of indexed files.")
|
|
25
|
+
symbols: int = Field(ge=0, description="Number of extracted symbols.")
|
|
26
|
+
technology_profiles: list[str] = Field(description="Detected technology profiles.")
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class SetupRequest(BaseModel):
|
|
30
|
+
"""Request body for non-CLI project setup."""
|
|
31
|
+
|
|
32
|
+
model_config = ConfigDict(extra="forbid")
|
|
33
|
+
|
|
34
|
+
root: str = Field(default=".", description="Project root to prepare.")
|
|
35
|
+
write_config: bool = Field(
|
|
36
|
+
default=True,
|
|
37
|
+
description="Whether to create opencontext.yaml when it is missing.",
|
|
38
|
+
)
|
|
39
|
+
refresh_index: bool = Field(
|
|
40
|
+
default=True,
|
|
41
|
+
description="Whether to rebuild and persist the project manifest.",
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class SetupResponse(BaseModel):
|
|
46
|
+
"""Response body for non-CLI project setup."""
|
|
47
|
+
|
|
48
|
+
model_config = ConfigDict(extra="forbid")
|
|
49
|
+
|
|
50
|
+
root: str = Field(description="Prepared project root.")
|
|
51
|
+
config_path: str = Field(description="OpenContext YAML configuration path.")
|
|
52
|
+
workspace_path: str = Field(description="Project-local .opencontext workspace path.")
|
|
53
|
+
manifest_path: str = Field(description="Persisted project manifest path.")
|
|
54
|
+
files: int = Field(ge=0, description="Indexed file count.")
|
|
55
|
+
symbols: int = Field(ge=0, description="Indexed symbol count.")
|
|
56
|
+
technology_profiles: list[str] = Field(description="Detected technology profiles.")
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class RunRequest(BaseModel):
|
|
60
|
+
"""Request body for workflow execution."""
|
|
61
|
+
|
|
62
|
+
model_config = ConfigDict(extra="forbid")
|
|
63
|
+
|
|
64
|
+
input: str = Field(description="User request.")
|
|
65
|
+
workflow_name: str = Field(default="code_assistant", description="Workflow name.")
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class RunResponse(BaseModel):
|
|
69
|
+
"""Response body for workflow execution."""
|
|
70
|
+
|
|
71
|
+
model_config = ConfigDict(extra="forbid")
|
|
72
|
+
|
|
73
|
+
answer: str = Field(description="Generated answer.")
|
|
74
|
+
trace_id: str = Field(description="Persisted trace id.")
|
|
75
|
+
token_usage: dict[str, int] = Field(description="Token usage summary.")
|
|
76
|
+
selected_context_count: int = Field(ge=0, description="Selected context item count.")
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class TraceResponse(BaseModel):
|
|
80
|
+
"""Response body for trace lookup."""
|
|
81
|
+
|
|
82
|
+
model_config = ConfigDict(extra="forbid")
|
|
83
|
+
|
|
84
|
+
trace: dict[str, Any] = Field(description="Serialized runtime trace.")
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
class ManifestResponse(BaseModel):
|
|
88
|
+
"""Response body for project manifest lookup."""
|
|
89
|
+
|
|
90
|
+
model_config = ConfigDict(extra="forbid")
|
|
91
|
+
|
|
92
|
+
manifest: dict[str, Any] = Field(description="Serialized project manifest.")
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
class RepoMapResponse(BaseModel):
|
|
96
|
+
"""Response body for repository map lookup."""
|
|
97
|
+
|
|
98
|
+
model_config = ConfigDict(extra="forbid")
|
|
99
|
+
|
|
100
|
+
repo_map: str = Field(description="Rendered compact repo map.")
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
class ContextPackRequest(BaseModel):
|
|
104
|
+
"""Request body for context pack generation."""
|
|
105
|
+
|
|
106
|
+
model_config = ConfigDict(extra="forbid")
|
|
107
|
+
|
|
108
|
+
query: str = Field(description="Retrieval query.")
|
|
109
|
+
max_tokens: int | None = Field(default=None, gt=0, description="Optional pack budget.")
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
class ContextPackResponse(BaseModel):
|
|
113
|
+
"""Response body for context pack generation."""
|
|
114
|
+
|
|
115
|
+
model_config = ConfigDict(extra="forbid")
|
|
116
|
+
|
|
117
|
+
pack: dict[str, Any] = Field(description="Serialized context pack result.")
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
class PreparedContextRequest(BaseModel):
|
|
121
|
+
"""Request body for simple non-CLI context preparation."""
|
|
122
|
+
|
|
123
|
+
model_config = ConfigDict(extra="forbid")
|
|
124
|
+
|
|
125
|
+
query: str = Field(description="Task or question to prepare context for.")
|
|
126
|
+
root: str = Field(default=".", description="Project root to index when needed.")
|
|
127
|
+
max_tokens: int | None = Field(default=None, gt=0, description="Optional context budget.")
|
|
128
|
+
refresh_index: bool = Field(
|
|
129
|
+
default=False,
|
|
130
|
+
description="Whether to rebuild the persisted project manifest before retrieval.",
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
class PreparedContextResponse(BaseModel):
|
|
135
|
+
"""Response body for persisted non-CLI context preparation."""
|
|
136
|
+
|
|
137
|
+
model_config = ConfigDict(extra="forbid")
|
|
138
|
+
|
|
139
|
+
trace_id: str = Field(description="Persisted trace id for this context bundle.")
|
|
140
|
+
context: str = Field(description="Compact redacted context text.")
|
|
141
|
+
included_sources: list[str] = Field(description="Sources included in the context.")
|
|
142
|
+
omitted_sources: list[str] = Field(description="Sources omitted from the context.")
|
|
143
|
+
token_usage: dict[str, int] = Field(description="Context and prompt token accounting.")
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
class OrchestrateRequest(BaseModel):
|
|
147
|
+
"""Request body for orchestration planning."""
|
|
148
|
+
|
|
149
|
+
model_config = ConfigDict(extra="forbid")
|
|
150
|
+
|
|
151
|
+
requirements_path: str = Field(description="Path to requirements used for planning.")
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
class ValidateRequest(BaseModel):
|
|
155
|
+
"""Request body for safe validation planning."""
|
|
156
|
+
|
|
157
|
+
model_config = ConfigDict(extra="forbid")
|
|
158
|
+
|
|
159
|
+
profile: str = Field(default="generic", description="Validation profile.")
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
class AgentContextRequest(BaseModel):
|
|
163
|
+
"""Request body for agent-context export planning."""
|
|
164
|
+
|
|
165
|
+
model_config = ConfigDict(extra="forbid")
|
|
166
|
+
|
|
167
|
+
query: str = Field(description="Task or question for the target agent.")
|
|
168
|
+
root: str = Field(default=".", description="Project root to index when needed.")
|
|
169
|
+
target: str = Field(default="generic", description="Target agent context format.")
|
|
170
|
+
mode: str = Field(default="plan", description="Context mode.")
|
|
171
|
+
max_tokens: int = Field(default=10000, gt=0, description="Maximum context budget.")
|
|
172
|
+
refresh_index: bool = Field(
|
|
173
|
+
default=False,
|
|
174
|
+
description="Whether to rebuild the persisted project manifest before retrieval.",
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
class ScaffoldResponse(BaseModel):
|
|
179
|
+
"""Generic response for scaffolded v0.1 endpoints."""
|
|
180
|
+
|
|
181
|
+
model_config = ConfigDict(extra="forbid")
|
|
182
|
+
|
|
183
|
+
status: str = Field(description="Endpoint implementation status.")
|
|
184
|
+
result: dict[str, Any] = Field(description="Structured scaffold result.")
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: opencontext-api
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: FastAPI adapter for OpenContext Runtime
|
|
5
|
+
Author: OpenContext Runtime maintainers
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/CesarMSFelipe/OpenContext-Runtime
|
|
8
|
+
Project-URL: Documentation, https://github.com/CesarMSFelipe/OpenContext-Runtime#readme
|
|
9
|
+
Project-URL: Issues, https://github.com/CesarMSFelipe/OpenContext-Runtime/issues
|
|
10
|
+
Project-URL: Source, https://github.com/CesarMSFelipe/OpenContext-Runtime
|
|
11
|
+
Keywords: ai,llm,context-engineering,fastapi,security
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Framework :: FastAPI
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
|
|
18
|
+
Classifier: Topic :: Security
|
|
19
|
+
Requires-Python: >=3.12
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Requires-Dist: fastapi>=0.110
|
|
23
|
+
Requires-Dist: httpx>=0.27
|
|
24
|
+
Requires-Dist: opencontext-core>=0.1.0
|
|
25
|
+
Requires-Dist: opencontext-profiles>=0.1.0
|
|
26
|
+
Dynamic: license-file
|
|
27
|
+
|
|
28
|
+
# opencontext-api
|
|
29
|
+
|
|
30
|
+
FastAPI adapter for OpenContext Runtime.
|
|
31
|
+
|
|
32
|
+
Use this package when a non-Python host needs HTTP endpoints for runtime-first setup and context
|
|
33
|
+
preparation:
|
|
34
|
+
|
|
35
|
+
- `POST /v1/setup`
|
|
36
|
+
- `POST /v1/context`
|
|
37
|
+
- `GET /v1/traces/{trace_id}`
|
|
38
|
+
|
|
39
|
+
The API is intentionally thin and delegates context behavior to `opencontext-core`.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
opencontext_api/__init__.py
|
|
5
|
+
opencontext_api/main.py
|
|
6
|
+
opencontext_api/schemas.py
|
|
7
|
+
opencontext_api.egg-info/PKG-INFO
|
|
8
|
+
opencontext_api.egg-info/SOURCES.txt
|
|
9
|
+
opencontext_api.egg-info/dependency_links.txt
|
|
10
|
+
opencontext_api.egg-info/requires.txt
|
|
11
|
+
opencontext_api.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
opencontext_api
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "opencontext-api"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "FastAPI adapter for OpenContext Runtime"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.12"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
authors = [{ name = "OpenContext Runtime maintainers" }]
|
|
14
|
+
keywords = ["ai", "llm", "context-engineering", "fastapi", "security"]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Development Status :: 3 - Alpha",
|
|
17
|
+
"Intended Audience :: Developers",
|
|
18
|
+
"Framework :: FastAPI",
|
|
19
|
+
"Programming Language :: Python :: 3",
|
|
20
|
+
"Programming Language :: Python :: 3.12",
|
|
21
|
+
"Topic :: Internet :: WWW/HTTP :: HTTP Servers",
|
|
22
|
+
"Topic :: Security",
|
|
23
|
+
]
|
|
24
|
+
dependencies = [
|
|
25
|
+
"fastapi>=0.110",
|
|
26
|
+
"httpx>=0.27",
|
|
27
|
+
"opencontext-core>=0.1.0",
|
|
28
|
+
"opencontext-profiles>=0.1.0",
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
[project.urls]
|
|
32
|
+
Homepage = "https://github.com/CesarMSFelipe/OpenContext-Runtime"
|
|
33
|
+
Documentation = "https://github.com/CesarMSFelipe/OpenContext-Runtime#readme"
|
|
34
|
+
Issues = "https://github.com/CesarMSFelipe/OpenContext-Runtime/issues"
|
|
35
|
+
Source = "https://github.com/CesarMSFelipe/OpenContext-Runtime"
|
|
36
|
+
|
|
37
|
+
[tool.setuptools.packages.find]
|
|
38
|
+
where = ["."]
|
|
39
|
+
include = ["opencontext_api*"]
|