devops-bot-sdk 1.4.149__tar.gz → 1.4.150__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.
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/PKG-INFO +1 -1
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/devops_bot_sdk.egg-info/PKG-INFO +1 -1
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/__init__.py +2 -2
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/agents/prompt_studio.py +51 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/ui/api.py +61 -5
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/README.md +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/devops_bot_sdk.egg-info/SOURCES.txt +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/devops_bot_sdk.egg-info/dependency_links.txt +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/devops_bot_sdk.egg-info/entry_points.txt +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/devops_bot_sdk.egg-info/requires.txt +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/devops_bot_sdk.egg-info/top_level.txt +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/pyproject.toml +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/agentd.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/agents/__init__.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/agents/builder.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/agents/chat.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/agents/connectors.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/agents/engines/__init__.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/agents/engines/claude_code.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/agents/engines/http.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/agents/engines/mcp.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/agents/engines/n8n.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/agents/engines/shell.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/agents/integrations.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/agents/inventory.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/agents/library/__init__.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/agents/manifest.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/agents/prompt_template.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/agents/prompt_vars.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/agents/run_log.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/agents/secrets.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/agents/usage.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/agents/varstore.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/cli.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/client.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/collectors/__init__.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/collectors/files.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/collectors/process.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/collectors/screenshot.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/config.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/crucial.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/design_verify/__init__.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/design_verify/assets.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/design_verify/bootstrap.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/design_verify/browser.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/design_verify/compare.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/design_verify/loop.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/exceptions.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/git_ops.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/graphify.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/hooks/__init__.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/hooks/crucial_guard.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/ipc/__init__.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/ipc/electron_bridge.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/ipc/handlers.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/local_exec.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/models/__init__.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/models/envelope.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/models/requests.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/models/responses.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/models/snapshots.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/platform_compat.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/py.typed +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/run_auto.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/sse.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/test.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/test_pipeline.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/ui/__init__.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/ui/dashboard.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/ui/health.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/ui/ip_allowlist.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/ui/jobs.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/ui/models.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/ui/runner.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/ui/security.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/ui/server.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/ui/service.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/ui/setup_manager.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/ui/static/agents.html +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/ui/static/app.js +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/ui/static/custom-agents.html +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/ui/static/default-agents.html +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/ui/static/index.html +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/ui/static/runs.html +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/ui/static/setup.html +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/ui/static/styles.css +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/ui/static/tickets.html +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/sdk/updater.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/setup.cfg +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/tests/test_agent_chat_features.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/tests/test_agent_prompt_models.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/tests/test_agents_connectors_builder.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/tests/test_git_action.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/tests/test_health.py +0 -0
- {devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/tests/test_updater_extras.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""AgentOS Desktop SDK — thin HTTPS/SSE client for the Electron app.
|
|
2
2
|
|
|
3
|
-
Version: 1.4.
|
|
3
|
+
Version: 1.4.150
|
|
4
4
|
|
|
5
5
|
Public surface:
|
|
6
6
|
BackendClient.from_config() — create client from ~/.agentos/config.toml
|
|
@@ -30,7 +30,7 @@ Rules:
|
|
|
30
30
|
- All data egress through submit_webhook only
|
|
31
31
|
"""
|
|
32
32
|
|
|
33
|
-
__version__ = "1.4.
|
|
33
|
+
__version__ = "1.4.150" # SINGLE SOURCE OF TRUTH — bump on every change; pyproject,
|
|
34
34
|
__author__ = "AgentOS" # sdk.client.SDK_VERSION and the UI server version all read this.
|
|
35
35
|
|
|
36
36
|
from sdk.client import BackendClient
|
|
@@ -164,6 +164,57 @@ def build_regenerate_prompt(system_prompt: str, feedback: str = "",
|
|
|
164
164
|
)
|
|
165
165
|
|
|
166
166
|
|
|
167
|
+
_VALIDATE_INPUTS_INSTRUCTION = """You are screening the inputs a user typed to CREATE an AI work agent, BEFORE a system prompt is generated. Decide whether each field is appropriate and meaningful.
|
|
168
|
+
|
|
169
|
+
Mark a field invalid when it is:
|
|
170
|
+
- offensive, abusive, hateful, harassing, or sexual;
|
|
171
|
+
- gibberish, random characters, or meaningless filler;
|
|
172
|
+
- clearly not what the field is for — in particular a JOB that does not describe an actual task/objective (e.g. a personal message like "shabana I love u", a person's name, or random words), an AGENT NAME that is not a plausible name for an agent, or an AGENT TYPE that is not a sensible category (e.g. developer, documentation, qa, support, data).
|
|
173
|
+
|
|
174
|
+
Ignore any field whose value is empty. Be reasonable: a short-but-genuine job (e.g. "summarise a repo") is VALID. Only flag inputs that are clearly wrong.
|
|
175
|
+
|
|
176
|
+
Return ONLY a JSON object, no prose:
|
|
177
|
+
{"valid": true|false, "issues": {"agent_name": "<short polite fix instruction>", "agent_type": "<...>", "job": "<...>"}}
|
|
178
|
+
Include a key in "issues" ONLY for a field you marked invalid; each message is a short, polite instruction to the user (e.g. "Kindly update the Job — it should describe the task the agent will perform."). If everything is fine, return {"valid": true, "issues": {}}.
|
|
179
|
+
|
|
180
|
+
INPUTS TO SCREEN:
|
|
181
|
+
AGENT NAME: __NAME__
|
|
182
|
+
AGENT TYPE: __TYPE__
|
|
183
|
+
MAIN JOB: __JOB__
|
|
184
|
+
"""
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def build_validate_inputs_prompt(agent_name: str, agent_type: str, job: str) -> str:
|
|
188
|
+
"""Prompt that asks the engine to screen agent_name/agent_type/job for
|
|
189
|
+
offensive or meaningless input before generation/regeneration."""
|
|
190
|
+
return (
|
|
191
|
+
_VALIDATE_INPUTS_INSTRUCTION
|
|
192
|
+
.replace("__NAME__", (agent_name or "").strip() or "(empty)")
|
|
193
|
+
.replace("__TYPE__", (agent_type or "").strip() or "(empty)")
|
|
194
|
+
.replace("__JOB__", (job or "").strip() or "(empty)")
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def parse_validation(model_output: str) -> dict:
|
|
199
|
+
"""Parse the input-screening reply into ``{"valid": bool, "issues": {field: msg}}``.
|
|
200
|
+
|
|
201
|
+
Tolerant of fences/prose. Only the three known fields are kept. Defaults to
|
|
202
|
+
VALID on an unparseable reply so the caller can fail-open (proceed to generate).
|
|
203
|
+
"""
|
|
204
|
+
data = _extract_json(model_output)
|
|
205
|
+
if not isinstance(data, dict):
|
|
206
|
+
return {"valid": True, "issues": {}}
|
|
207
|
+
raw_issues = data.get("issues") if isinstance(data.get("issues"), dict) else {}
|
|
208
|
+
issues = {
|
|
209
|
+
k: str(v).strip()
|
|
210
|
+
for k, v in raw_issues.items()
|
|
211
|
+
if k in ("agent_name", "agent_type", "job") and str(v or "").strip()
|
|
212
|
+
}
|
|
213
|
+
# Trust an explicit False, but also treat "issues present" as invalid.
|
|
214
|
+
valid = bool(data.get("valid", True)) and not issues
|
|
215
|
+
return {"valid": valid, "issues": issues}
|
|
216
|
+
|
|
217
|
+
|
|
167
218
|
def parse_generation(model_output: str) -> dict:
|
|
168
219
|
"""Parse a generate/regenerate model reply into ``{system_prompt, variables}``.
|
|
169
220
|
|
|
@@ -929,6 +929,41 @@ async def _run_prompt_engine(prompt: str) -> str:
|
|
|
929
929
|
return result.get("result", "") or ""
|
|
930
930
|
|
|
931
931
|
|
|
932
|
+
# ── Unified revision format ───────────────────────────────────────────────────
|
|
933
|
+
# Missing / empty required fields → HTTP 422 (Pydantic on the request model,
|
|
934
|
+
# unchanged). When the inputs are PRESENT but need human revision (offensive /
|
|
935
|
+
# meaningless input, or a prompt missing required sections) EVERY endpoint returns
|
|
936
|
+
# the SAME shape — all messages collected into one ``ai_comments`` list:
|
|
937
|
+
# {"status": "needs_revision", "engine": "claude_code",
|
|
938
|
+
# "ai_comments": ["<message>", "<message>", ...]}
|
|
939
|
+
# Success responses carry status="ok" and ai_comments=[] so the client always reads
|
|
940
|
+
# the same two fields.
|
|
941
|
+
|
|
942
|
+
def _needs_revision(ai_comments: list[str]) -> dict:
|
|
943
|
+
"""The single revision envelope used by every agent-prompt endpoint."""
|
|
944
|
+
return {"status": "needs_revision", "engine": "claude_code", "ai_comments": ai_comments}
|
|
945
|
+
|
|
946
|
+
|
|
947
|
+
async def _screen_agent_inputs(agent_name: str, agent_type: str, job: str) -> list[str]:
|
|
948
|
+
"""LLM screen for offensive / meaningless inputs → list of comment messages
|
|
949
|
+
(empty when the inputs are fine).
|
|
950
|
+
|
|
951
|
+
FAIL-OPEN: any engine/parse error → ``[]`` (proceed), so a validator hiccup
|
|
952
|
+
never blocks a legitimate request.
|
|
953
|
+
"""
|
|
954
|
+
from sdk.agents.prompt_studio import build_validate_inputs_prompt, parse_validation
|
|
955
|
+
|
|
956
|
+
try:
|
|
957
|
+
verdict = parse_validation(
|
|
958
|
+
await _run_prompt_engine(build_validate_inputs_prompt(agent_name, agent_type, job))
|
|
959
|
+
)
|
|
960
|
+
except Exception: # noqa: BLE001 — fail-open
|
|
961
|
+
return []
|
|
962
|
+
if verdict.get("valid", True):
|
|
963
|
+
return []
|
|
964
|
+
return [str(msg).strip() for msg in (verdict.get("issues") or {}).values() if str(msg or "").strip()]
|
|
965
|
+
|
|
966
|
+
|
|
932
967
|
@router.post("/agent-prompt/generate", dependencies=[_auth])
|
|
933
968
|
async def agent_prompt_generate(body: AgentPromptGenerateRequest) -> dict:
|
|
934
969
|
"""name + type + job → a structured system prompt + {{variables}} (claude_code).
|
|
@@ -938,17 +973,24 @@ async def agent_prompt_generate(body: AgentPromptGenerateRequest) -> dict:
|
|
|
938
973
|
"""
|
|
939
974
|
from sdk.agents.prompt_studio import build_generate_prompt, parse_generation
|
|
940
975
|
|
|
976
|
+
# Empty agent_name/agent_type/job already 422'd by the request model.
|
|
941
977
|
agent_name = body.agent_name
|
|
942
978
|
agent_type = body.agent_type
|
|
943
979
|
job = body.job
|
|
944
980
|
|
|
981
|
+
# Semantic screen (offensive / meaningless) → unified needs_revision. Fail-open.
|
|
982
|
+
comments = await _screen_agent_inputs(agent_name, agent_type, job)
|
|
983
|
+
if comments:
|
|
984
|
+
return _needs_revision(comments)
|
|
985
|
+
|
|
945
986
|
text = await _run_prompt_engine(
|
|
946
987
|
build_generate_prompt(agent_name, agent_type, job, body.context)
|
|
947
988
|
)
|
|
948
989
|
parsed = parse_generation(text)
|
|
949
990
|
if not parsed["system_prompt"]:
|
|
950
991
|
raise HTTPException(status_code=502, detail="generation returned no system_prompt")
|
|
951
|
-
return {"
|
|
992
|
+
return {"status": "ok", "engine": "claude_code", "ai_comments": [],
|
|
993
|
+
"agent_name": agent_name, "agent_type": agent_type, **parsed}
|
|
952
994
|
|
|
953
995
|
|
|
954
996
|
@router.post("/agent-prompt/regenerate", dependencies=[_auth])
|
|
@@ -960,6 +1002,12 @@ async def agent_prompt_regenerate(body: PromptRegenerateRequest) -> dict:
|
|
|
960
1002
|
"""
|
|
961
1003
|
from sdk.agents.prompt_studio import build_regenerate_prompt, parse_generation
|
|
962
1004
|
|
|
1005
|
+
# Empty system_prompt already 422'd by the request model. Screen the agent
|
|
1006
|
+
# metadata (blank fields ignored by the screener; fail-open).
|
|
1007
|
+
comments = await _screen_agent_inputs(body.agent_name, body.agent_type, body.job)
|
|
1008
|
+
if comments:
|
|
1009
|
+
return _needs_revision(comments)
|
|
1010
|
+
|
|
963
1011
|
text = await _run_prompt_engine(build_regenerate_prompt(
|
|
964
1012
|
body.system_prompt, body.feedback,
|
|
965
1013
|
body.agent_name, body.agent_type, body.job,
|
|
@@ -967,9 +1015,8 @@ async def agent_prompt_regenerate(body: PromptRegenerateRequest) -> dict:
|
|
|
967
1015
|
parsed = parse_generation(text)
|
|
968
1016
|
if not parsed["system_prompt"]:
|
|
969
1017
|
raise HTTPException(status_code=502, detail="regeneration returned no system_prompt")
|
|
970
|
-
return {"
|
|
971
|
-
"agent_type": body.agent_type,
|
|
972
|
-
"engine": "claude_code", **parsed}
|
|
1018
|
+
return {"status": "ok", "engine": "claude_code", "ai_comments": [],
|
|
1019
|
+
"agent_name": body.agent_name, "agent_type": body.agent_type, **parsed}
|
|
973
1020
|
|
|
974
1021
|
|
|
975
1022
|
@router.post("/agent-prompt/verify", dependencies=[_auth])
|
|
@@ -985,6 +1032,7 @@ async def agent_prompt_verify(body: PromptVerifyRequest) -> dict:
|
|
|
985
1032
|
from sdk.agents.prompt_template import check_system_prompt
|
|
986
1033
|
from sdk.agents.prompt_vars import extract_variables
|
|
987
1034
|
|
|
1035
|
+
# Too-short system_prompt already 422'd by the request model.
|
|
988
1036
|
system_prompt = body.system_prompt
|
|
989
1037
|
|
|
990
1038
|
standards = check_system_prompt(system_prompt)
|
|
@@ -1008,13 +1056,21 @@ async def agent_prompt_verify(body: PromptVerifyRequest) -> dict:
|
|
|
1008
1056
|
"type": str(m.get("type", "string")).strip() or "string",
|
|
1009
1057
|
})
|
|
1010
1058
|
|
|
1059
|
+
# Structural gaps → the SAME unified ai_comments list (all messages together).
|
|
1060
|
+
ai_comments = (
|
|
1061
|
+
[f"Missing required section: {s}." for s in standards["missing_required"]]
|
|
1062
|
+
+ [f"Recommended section missing: {s}." for s in standards["missing_recommended"]]
|
|
1063
|
+
)
|
|
1064
|
+
|
|
1011
1065
|
return {
|
|
1066
|
+
"status": "needs_revision" if standards["missing_required"] else "ok",
|
|
1067
|
+
"engine": "claude_code",
|
|
1068
|
+
"ai_comments": ai_comments,
|
|
1012
1069
|
"valid": not standards["missing_required"],
|
|
1013
1070
|
"missing_required": standards["missing_required"],
|
|
1014
1071
|
"missing_recommended": standards["missing_recommended"],
|
|
1015
1072
|
"variables": variables,
|
|
1016
1073
|
"secrets": analysis.get("secrets", []),
|
|
1017
|
-
"engine": "claude_code",
|
|
1018
1074
|
}
|
|
1019
1075
|
|
|
1020
1076
|
|
|
File without changes
|
|
File without changes
|
{devops_bot_sdk-1.4.149 → devops_bot_sdk-1.4.150}/devops_bot_sdk.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|