agenticdome-python-sdk 1.2.32__py3-none-any.whl → 1.2.34__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.
- {agenticdome_python_sdk-1.2.32.dist-info → agenticdome_python_sdk-1.2.34.dist-info}/METADATA +43 -29
- {agenticdome_python_sdk-1.2.32.dist-info → agenticdome_python_sdk-1.2.34.dist-info}/RECORD +12 -12
- agenticdome_sdk/catalog_snapshot.json +6 -6
- agenticdome_sdk/connect.py +65 -26
- agenticdome_sdk/copilot_ir.py +55 -28
- agenticdome_sdk/hook_catalog.py +22 -22
- agenticdome_sdk/onboarding_cli.py +533 -89
- {agenticdome_python_sdk-1.2.32.dist-info → agenticdome_python_sdk-1.2.34.dist-info}/WHEEL +0 -0
- {agenticdome_python_sdk-1.2.32.dist-info → agenticdome_python_sdk-1.2.34.dist-info}/entry_points.txt +0 -0
- {agenticdome_python_sdk-1.2.32.dist-info → agenticdome_python_sdk-1.2.34.dist-info}/licenses/LICENSE +0 -0
- {agenticdome_python_sdk-1.2.32.dist-info → agenticdome_python_sdk-1.2.34.dist-info}/licenses/NOTICE +0 -0
- {agenticdome_python_sdk-1.2.32.dist-info → agenticdome_python_sdk-1.2.34.dist-info}/top_level.txt +0 -0
{agenticdome_python_sdk-1.2.32.dist-info → agenticdome_python_sdk-1.2.34.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agenticdome-python-sdk
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.34
|
|
4
4
|
Summary: Official Python SDK for AgenticDome security guardrails, DLP, tool authorization, and multi-agent delegation enforcement.
|
|
5
5
|
Author: AgenticDome
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -33,20 +33,20 @@ Requires-Dist: requests>=2.31.0
|
|
|
33
33
|
Requires-Dist: urllib3>=2.0.0
|
|
34
34
|
Requires-Dist: cryptography>=42.0.0
|
|
35
35
|
Provides-Extra: crewai
|
|
36
|
-
Requires-Dist: crewai<=1.15.
|
|
36
|
+
Requires-Dist: crewai<=1.15.22,>=1.15.5; extra == "crewai"
|
|
37
37
|
Provides-Extra: redis
|
|
38
38
|
Requires-Dist: redis>=4.5.0; extra == "redis"
|
|
39
39
|
Provides-Extra: pop
|
|
40
40
|
Requires-Dist: cryptography>=42.0.0; extra == "pop"
|
|
41
41
|
Provides-Extra: pydanticai
|
|
42
|
-
Requires-Dist: pydantic-ai<=2.
|
|
42
|
+
Requires-Dist: pydantic-ai<=2.51.0,>=2.16.0; extra == "pydanticai"
|
|
43
43
|
Requires-Dist: anyio>=4.0.0; extra == "pydanticai"
|
|
44
44
|
Provides-Extra: pydantic
|
|
45
|
-
Requires-Dist: pydantic-ai<=2.
|
|
45
|
+
Requires-Dist: pydantic-ai<=2.51.0,>=2.16.0; extra == "pydantic"
|
|
46
46
|
Requires-Dist: anyio>=4.0.0; extra == "pydantic"
|
|
47
47
|
Provides-Extra: langgraph
|
|
48
|
-
Requires-Dist: langgraph<=1.2.
|
|
49
|
-
Requires-Dist: langchain-core<=1.6.
|
|
48
|
+
Requires-Dist: langgraph<=1.2.12,>=1.2.9; extra == "langgraph"
|
|
49
|
+
Requires-Dist: langchain-core<=1.6.5,>=1.5.0; extra == "langgraph"
|
|
50
50
|
Requires-Dist: langchain-openai==1.3.5; extra == "langgraph"
|
|
51
51
|
Requires-Dist: anyio>=4.0.0; extra == "langgraph"
|
|
52
52
|
Provides-Extra: microsoft
|
|
@@ -55,51 +55,51 @@ Requires-Dist: autogen-agentchat==0.7.5; extra == "autogen"
|
|
|
55
55
|
Provides-Extra: microsoft-autogen
|
|
56
56
|
Requires-Dist: autogen-agentchat==0.7.5; extra == "microsoft-autogen"
|
|
57
57
|
Provides-Extra: foundry
|
|
58
|
-
Requires-Dist: azure-ai-projects<=2.
|
|
58
|
+
Requires-Dist: azure-ai-projects<=2.7.0,>=2.3.0; extra == "foundry"
|
|
59
59
|
Requires-Dist: azure-identity==1.25.3; extra == "foundry"
|
|
60
60
|
Provides-Extra: agno
|
|
61
|
-
Requires-Dist: agno<=3.0.
|
|
61
|
+
Requires-Dist: agno<=3.0.11,>=2.8.0; extra == "agno"
|
|
62
62
|
Provides-Extra: openai-agents
|
|
63
|
-
Requires-Dist: openai-agents<=0.22.
|
|
63
|
+
Requires-Dist: openai-agents<=0.22.3,>=0.18.3; extra == "openai-agents"
|
|
64
64
|
Provides-Extra: mcp
|
|
65
65
|
Requires-Dist: mcp<=2.2.0,>=1.26.0; extra == "mcp"
|
|
66
66
|
Provides-Extra: bedrock
|
|
67
|
-
Requires-Dist: boto3<=1.43.
|
|
67
|
+
Requires-Dist: boto3<=1.43.103,>=1.43.54; extra == "bedrock"
|
|
68
68
|
Provides-Extra: aws-bedrock
|
|
69
|
-
Requires-Dist: boto3<=1.43.
|
|
69
|
+
Requires-Dist: boto3<=1.43.103,>=1.43.54; extra == "aws-bedrock"
|
|
70
70
|
Provides-Extra: llamaindex
|
|
71
|
-
Requires-Dist: llama-index<=0.14.
|
|
71
|
+
Requires-Dist: llama-index<=0.14.25,>=0.14.23; extra == "llamaindex"
|
|
72
72
|
Provides-Extra: llama-index
|
|
73
|
-
Requires-Dist: llama-index<=0.14.
|
|
73
|
+
Requires-Dist: llama-index<=0.14.25,>=0.14.23; extra == "llama-index"
|
|
74
74
|
Provides-Extra: google-adk
|
|
75
|
-
Requires-Dist: google-adk<=2.
|
|
75
|
+
Requires-Dist: google-adk<=2.10.0,>=2.5.0; extra == "google-adk"
|
|
76
76
|
Provides-Extra: adk
|
|
77
|
-
Requires-Dist: google-adk<=2.
|
|
77
|
+
Requires-Dist: google-adk<=2.10.0,>=2.5.0; extra == "adk"
|
|
78
78
|
Provides-Extra: claude
|
|
79
|
-
Requires-Dist: claude-agent-sdk<=0.2.
|
|
79
|
+
Requires-Dist: claude-agent-sdk<=0.2.160,>=0.2.126; extra == "claude"
|
|
80
80
|
Provides-Extra: claude-agent-sdk
|
|
81
|
-
Requires-Dist: claude-agent-sdk<=0.2.
|
|
81
|
+
Requires-Dist: claude-agent-sdk<=0.2.160,>=0.2.126; extra == "claude-agent-sdk"
|
|
82
82
|
Provides-Extra: smolagents
|
|
83
83
|
Requires-Dist: smolagents==1.26.0; extra == "smolagents"
|
|
84
84
|
Provides-Extra: all
|
|
85
|
-
Requires-Dist: crewai<=1.15.
|
|
85
|
+
Requires-Dist: crewai<=1.15.22,>=1.15.5; extra == "all"
|
|
86
86
|
Requires-Dist: redis>=4.5.0; extra == "all"
|
|
87
87
|
Requires-Dist: cryptography>=42.0.0; extra == "all"
|
|
88
|
-
Requires-Dist: pydantic-ai<=2.
|
|
88
|
+
Requires-Dist: pydantic-ai<=2.51.0,>=2.16.0; extra == "all"
|
|
89
89
|
Requires-Dist: anyio>=4.0.0; extra == "all"
|
|
90
|
-
Requires-Dist: langgraph<=1.2.
|
|
91
|
-
Requires-Dist: langchain-core<=1.6.
|
|
90
|
+
Requires-Dist: langgraph<=1.2.12,>=1.2.9; extra == "all"
|
|
91
|
+
Requires-Dist: langchain-core<=1.6.5,>=1.5.0; extra == "all"
|
|
92
92
|
Requires-Dist: langchain-openai==1.3.5; extra == "all"
|
|
93
93
|
Requires-Dist: autogen-agentchat==0.7.5; extra == "all"
|
|
94
|
-
Requires-Dist: agno<=3.0.
|
|
95
|
-
Requires-Dist: azure-ai-projects<=2.
|
|
94
|
+
Requires-Dist: agno<=3.0.11,>=2.8.0; extra == "all"
|
|
95
|
+
Requires-Dist: azure-ai-projects<=2.7.0,>=2.3.0; extra == "all"
|
|
96
96
|
Requires-Dist: azure-identity==1.25.3; extra == "all"
|
|
97
|
-
Requires-Dist: openai-agents<=0.22.
|
|
97
|
+
Requires-Dist: openai-agents<=0.22.3,>=0.18.3; extra == "all"
|
|
98
98
|
Requires-Dist: mcp<=2.2.0,>=1.26.0; extra == "all"
|
|
99
|
-
Requires-Dist: boto3<=1.43.
|
|
100
|
-
Requires-Dist: llama-index<=0.14.
|
|
101
|
-
Requires-Dist: google-adk<=2.
|
|
102
|
-
Requires-Dist: claude-agent-sdk<=0.2.
|
|
99
|
+
Requires-Dist: boto3<=1.43.103,>=1.43.54; extra == "all"
|
|
100
|
+
Requires-Dist: llama-index<=0.14.25,>=0.14.23; extra == "all"
|
|
101
|
+
Requires-Dist: google-adk<=2.10.0,>=2.5.0; extra == "all"
|
|
102
|
+
Requires-Dist: claude-agent-sdk<=0.2.160,>=0.2.126; extra == "all"
|
|
103
103
|
Requires-Dist: smolagents==1.26.0; extra == "all"
|
|
104
104
|
Provides-Extra: dev
|
|
105
105
|
Requires-Dist: pytest>=8.0.0; extra == "dev"
|
|
@@ -218,7 +218,10 @@ agenticdome openclaw verify --output .agenticdome/verification.json
|
|
|
218
218
|
AgenticDome plugin, explicit consent and the exact certified typed hooks.
|
|
219
219
|
`agenticdome plan` returns source-free, tenant-bound Integration Copilot
|
|
220
220
|
guidance for review. `openclaw verify` adds workspace-test and assigned-tenant
|
|
221
|
-
policy evidence.
|
|
221
|
+
policy evidence. If the same deployable workload also uses MCP, this command
|
|
222
|
+
includes the MCP transport rehearsal and both `mcp_verification` and
|
|
223
|
+
`openclaw_verification` in one report. Both sections must be ready before the
|
|
224
|
+
report is imported; `mcp verify` alone is not a combined-workload proof. The
|
|
222
225
|
customer Control Panel separately confirms tenant binding and retained
|
|
223
226
|
telemetry; neither command silently modifies customer source.
|
|
224
227
|
|
|
@@ -228,6 +231,17 @@ languages and candidate boundaries can be discovered locally; business
|
|
|
228
231
|
purpose, sensitive actions and managed-versus-sovereign deployment remain
|
|
229
232
|
explicit customer decisions and are not guessed from source code.
|
|
230
233
|
|
|
234
|
+
`agenticdome init` creates local configuration without contacting Copilot.
|
|
235
|
+
`inspect` and `plan` send source-free structural metadata to the assigned
|
|
236
|
+
tenant sidecar. A selection spanning several deployable packages is analyzed
|
|
237
|
+
as bounded, sequential workload units; successful units are checkpointed
|
|
238
|
+
locally so a retry does not resubmit them. The report lists analyzed parts
|
|
239
|
+
and any result-list caps. It does not claim that calls or guard placement
|
|
240
|
+
across separate workload units were proven; review those boundaries before
|
|
241
|
+
production. If the selection exceeds the 24-unit safety limit, select the
|
|
242
|
+
application or package that actually executes agent actions. No unexamined
|
|
243
|
+
unit is silently omitted or reported as protected.
|
|
244
|
+
|
|
231
245
|
Use **Customer Control Panel → Activate Action Firewall → Core Config** to
|
|
232
246
|
choose the Developer Integration path and import the two evidence files. This
|
|
233
247
|
path is for SDK, MCP, framework or custom-code integrations; Microsoft
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
agenticdome_python_sdk-1.2.
|
|
2
|
-
agenticdome_python_sdk-1.2.
|
|
1
|
+
agenticdome_python_sdk-1.2.34.dist-info/licenses/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
|
2
|
+
agenticdome_python_sdk-1.2.34.dist-info/licenses/NOTICE,sha256=obvKP6kV1Ny5R8_INFOpf0X5um9U2X43LGwQFobO9kg,550
|
|
3
3
|
agenticdome_sdk/__init__.py,sha256=UY__0ppEM4MlsTQoLh8alZ7AoMjtegGKe4j_Sj7CpNk,903
|
|
4
4
|
agenticdome_sdk/_framework_firewall.py,sha256=W3gy7WsK50scE7ypJrmVJhHUOBsr0zAWQ85rghqaJk4,31963
|
|
5
5
|
agenticdome_sdk/_mode.py,sha256=XvOgh5sW-FG8S39V483h3uLiFh8wSt14OmYXz_6eDO8,1283
|
|
@@ -7,16 +7,16 @@ agenticdome_sdk/agno.py,sha256=L3yfjTBHW47xzT67a1DsjtwmvrAoYBkbxADpsr85Cp0,60766
|
|
|
7
7
|
agenticdome_sdk/attestation.py,sha256=ij4cMff7nzLaIS0W02d2WURFcyKe72bcUlSz-dYkaLE,10310
|
|
8
8
|
agenticdome_sdk/autogen.py,sha256=KP4qlIcsNXB-4ZT9D7Slc1xWEeWXRIWkc5HGW0U6k2c,29018
|
|
9
9
|
agenticdome_sdk/aws_bedrock.py,sha256=2zD9j7xi0jna0sMeMf-hKZdc3Y4RPwzj6tMVOUGgIDQ,69581
|
|
10
|
-
agenticdome_sdk/catalog_snapshot.json,sha256=
|
|
10
|
+
agenticdome_sdk/catalog_snapshot.json,sha256=aOJMqz8FpPF-q1ynpM2xsEk-O-tMyUCPE5Y51dygtLQ,951
|
|
11
11
|
agenticdome_sdk/claude.py,sha256=XeY9AUu61SYcJjQVz_AtL_WaN6X4KqP5nprEbbr4Q6A,17456
|
|
12
12
|
agenticdome_sdk/client.py,sha256=2uVKZR1uXDBIvwOS-lpNPCAXl9K5vroPqsPNNYhBWeg,69473
|
|
13
|
-
agenticdome_sdk/connect.py,sha256=
|
|
14
|
-
agenticdome_sdk/copilot_ir.py,sha256=
|
|
13
|
+
agenticdome_sdk/connect.py,sha256=MY30wXYA6OaZhs__E67KcFXEy7mZMBxMSV06BnlBjRg,18766
|
|
14
|
+
agenticdome_sdk/copilot_ir.py,sha256=zT13tOX8xu11yrOtIPMRFVud8CQ81Gu3WxsXxyQ4XT0,17928
|
|
15
15
|
agenticdome_sdk/copilot_ir_collector.cjs,sha256=oxLY8ByONo7Es4YjYiJuRz_A7IKL65Sy486UXnu-4Rs,9681
|
|
16
16
|
agenticdome_sdk/crewai.py,sha256=sSJQ49O7-8kqOAD2_jrsMtMOmBOcJmFkeOv7S3-ayMs,52490
|
|
17
17
|
agenticdome_sdk/demo.py,sha256=dyfqt2N_cJoyUWKnjPYuQxuw2hb2DrCNUf1jQKeYYoc,8350
|
|
18
18
|
agenticdome_sdk/google_adk.py,sha256=2TA-tUhY0lOnkGcs1BN9CUEz67ebVX4HJ7mnNoRPcZs,57258
|
|
19
|
-
agenticdome_sdk/hook_catalog.py,sha256=
|
|
19
|
+
agenticdome_sdk/hook_catalog.py,sha256=0dfFWNDS0KCeP0IozWZb1NkNBWf1omaO2-yZKNVdTf0,29272
|
|
20
20
|
agenticdome_sdk/identity.py,sha256=mrymGgZSVsKJ9THRde54qGmMT7j_uZHmPJ-HtWk7PXE,4635
|
|
21
21
|
agenticdome_sdk/langgraph.py,sha256=FUvF6DSA5aZP3eoBoNeldgGtPrz-dO5xcVmrPPSBEhI,84312
|
|
22
22
|
agenticdome_sdk/lifecycle.py,sha256=9LvxmUU1LC_tMchb5uVFBnZIkVFUxOv3VH9wG_9gPtA,12855
|
|
@@ -27,15 +27,15 @@ agenticdome_sdk/mcp_rehearsal_server.py,sha256=cox4XqUTL8d0gaDzqxDZcEALkaz8otjOj
|
|
|
27
27
|
agenticdome_sdk/mcp_verification.py,sha256=VqQS5SpPVFI3G7qCwrT90JmG8vFE6pRJEB7PViHjKqw,14235
|
|
28
28
|
agenticdome_sdk/microsoft_agent_framework.py,sha256=GfIIuk0n-VhsZaTyoB7P6ilpz9bFLD95TWuX0rFSWeU,67219
|
|
29
29
|
agenticdome_sdk/microsoft_ai_foundry.py,sha256=YlO968s1dbAYcaEqhqufL92NFR66GuTtngnCv7-1mYc,56911
|
|
30
|
-
agenticdome_sdk/onboarding_cli.py,sha256=
|
|
30
|
+
agenticdome_sdk/onboarding_cli.py,sha256=yPPlNRPCjuDNpeJpL-0fJK3RZTOZvII8d-qFHJgTILM,120597
|
|
31
31
|
agenticdome_sdk/openai_agents.py,sha256=nNM-YcsUDcE23sGv1buLudcYFz0NLju2Mwiw_wrVaJg,57326
|
|
32
32
|
agenticdome_sdk/outcomes.py,sha256=jadWDzQaZXrHNvpPme8lQY0jihYLCoM3s4CihAq0JRo,2507
|
|
33
33
|
agenticdome_sdk/proof.py,sha256=ECKc14xSE0V1HHmcpZjfVz8-Q2H_fooah3BfdblFV8M,2878
|
|
34
34
|
agenticdome_sdk/pydantic.py,sha256=WKb8X0Fgydfid-ep8E-M8Yslz2pWcCP6w7n_aBxt1rI,54961
|
|
35
35
|
agenticdome_sdk/simulation.py,sha256=UCbZy3u9AzfxQCfY38SCV3CxGxhinV9EA4aHMPlK4mc,8426
|
|
36
36
|
agenticdome_sdk/smolagents.py,sha256=wjMA1HVAQ-9wRNM38Jr9wlCpKMhF-9vxtTk6R-kwQhs,19094
|
|
37
|
-
agenticdome_python_sdk-1.2.
|
|
38
|
-
agenticdome_python_sdk-1.2.
|
|
39
|
-
agenticdome_python_sdk-1.2.
|
|
40
|
-
agenticdome_python_sdk-1.2.
|
|
41
|
-
agenticdome_python_sdk-1.2.
|
|
37
|
+
agenticdome_python_sdk-1.2.34.dist-info/METADATA,sha256=hOOXfVmbkCRG1AKVWBUcSqHa1i6G92XEomK47iBKSiU,140120
|
|
38
|
+
agenticdome_python_sdk-1.2.34.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
|
|
39
|
+
agenticdome_python_sdk-1.2.34.dist-info/entry_points.txt,sha256=cRfCphkr5gLrkGIzXJEtL50HdHLajoZLbZtcMLE8NoY,113
|
|
40
|
+
agenticdome_python_sdk-1.2.34.dist-info/top_level.txt,sha256=LZbbjXco5mqDrGwlTJpIKI5Sp6R_njzHHjExxAs9c3s,16
|
|
41
|
+
agenticdome_python_sdk-1.2.34.dist-info/RECORD,,
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": "agenticdome.catalog-snapshot.v1",
|
|
3
3
|
"catalog_schema": "agenticdome.hook-catalog.v1",
|
|
4
|
-
"verified_at": "2026-09-
|
|
5
|
-
"python_sdk_version": "1.2.
|
|
4
|
+
"verified_at": "2026-09-26",
|
|
5
|
+
"python_sdk_version": "1.2.34",
|
|
6
6
|
"published_packages": {
|
|
7
7
|
"agenticdome-python-sdk": {
|
|
8
8
|
"registry": "pypi",
|
|
9
|
-
"version": "1.2.
|
|
10
|
-
"url": "https://pypi.org/project/agenticdome-python-sdk/1.2.
|
|
9
|
+
"version": "1.2.34",
|
|
10
|
+
"url": "https://pypi.org/project/agenticdome-python-sdk/1.2.34/"
|
|
11
11
|
},
|
|
12
12
|
"agenticdome-sdk": {
|
|
13
13
|
"registry": "npm",
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
},
|
|
22
22
|
"openclaw": {
|
|
23
23
|
"registry": "npm",
|
|
24
|
-
"version": "2026.9.
|
|
25
|
-
"url": "https://www.npmjs.com/package/openclaw/v/2026.9.
|
|
24
|
+
"version": "2026.9.6",
|
|
25
|
+
"url": "https://www.npmjs.com/package/openclaw/v/2026.9.6"
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
}
|
agenticdome_sdk/connect.py
CHANGED
|
@@ -17,9 +17,6 @@ from pathlib import Path
|
|
|
17
17
|
from typing import Any, Dict, Optional
|
|
18
18
|
|
|
19
19
|
from .attestation import ensure_attestation_key
|
|
20
|
-
from .hook_catalog import CATALOG_SCHEMA, CATALOG_VERIFIED_AT, catalog_digest
|
|
21
|
-
|
|
22
|
-
|
|
23
20
|
SCOPES = ["onboarding:read", "metadata:write", "evidence:write", "workload:write", "repository:prepare"]
|
|
24
21
|
|
|
25
22
|
|
|
@@ -124,7 +121,10 @@ def _approve_metadata(ir: Dict[str, Any], assume_yes: bool) -> None:
|
|
|
124
121
|
|
|
125
122
|
def run_connect(root: Path, args: Any) -> Dict[str, Any]:
|
|
126
123
|
# Import lazily to avoid a module cycle and keep the public client purely orchestration code.
|
|
127
|
-
from .onboarding_cli import
|
|
124
|
+
from .onboarding_cli import (
|
|
125
|
+
_active_copilot_catalog_binding, _copilot_semantic_analysis,
|
|
126
|
+
_ensure_workload_id, _installed_sdk_version, _scope_gap_message, inspect_repository,
|
|
127
|
+
)
|
|
128
128
|
|
|
129
129
|
portal = str(args.portal).rstrip("/")
|
|
130
130
|
if not portal.startswith("https://") and not getattr(args, "allow_insecure_http", False):
|
|
@@ -155,12 +155,23 @@ def run_connect(root: Path, args: Any) -> Dict[str, Any]:
|
|
|
155
155
|
if not session.get("runtime") or not session.get("copilot"):
|
|
156
156
|
raise SystemExit("Authentication succeeded, but no eligible runtime is assigned. The saved portal session can be resumed after an administrator enables an assignment policy.")
|
|
157
157
|
|
|
158
|
-
|
|
158
|
+
local_workload_id = _ensure_workload_id(root)
|
|
159
|
+
report = inspect_repository(root, remote_analysis=False)
|
|
160
|
+
if report.get("scope", {}).get("complete") is not True:
|
|
161
|
+
raise SystemExit(_scope_gap_message(report))
|
|
159
162
|
ir = report["copilot_ir"]
|
|
160
163
|
_approve_metadata(ir, bool(args.yes))
|
|
161
164
|
private_pem, public_pem = ensure_attestation_key(root / ".agenticdome")
|
|
162
165
|
del private_pem
|
|
163
|
-
workload_uuid = str(uuid.uuid5(uuid.NAMESPACE_URL, session["tenant_id"] + ":" +
|
|
166
|
+
workload_uuid = str(uuid.uuid5(uuid.NAMESPACE_URL, session["tenant_id"] + ":" + local_workload_id))
|
|
167
|
+
previous_session_path = root / ".agenticdome" / "connect-session.json"
|
|
168
|
+
if previous_session_path.is_file():
|
|
169
|
+
try:
|
|
170
|
+
previous_session = json.loads(previous_session_path.read_text(encoding="utf-8"))
|
|
171
|
+
if previous_session.get("tenant_id") == session["tenant_id"]:
|
|
172
|
+
workload_uuid = str(uuid.UUID(str(previous_session["workload_uuid"])))
|
|
173
|
+
except (OSError, ValueError, KeyError, TypeError, AttributeError, json.JSONDecodeError):
|
|
174
|
+
raise SystemExit("The previous Connect workload identity is unreadable. Restore its connect-session.json before retrying to avoid creating a duplicate workload.")
|
|
164
175
|
frameworks = [item["key"] for item in report.get("frameworks", [])]
|
|
165
176
|
_request(portal + "/api/agentguard/connect/workloads", {
|
|
166
177
|
"session_uuid": session["session_uuid"], "workload_uuid": workload_uuid,
|
|
@@ -171,38 +182,51 @@ def run_connect(root: Path, args: Any) -> Dict[str, Any]:
|
|
|
171
182
|
|
|
172
183
|
runtime_base = str(session["runtime"]["api_base"]).rstrip("/")
|
|
173
184
|
copilot_key = str(session["copilot"]["api_key"])
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
"schema": "agenticdome.copilot-request.v1", "ir": ir,
|
|
177
|
-
"catalog_binding": {"schema": CATALOG_SCHEMA, "catalog_digest": catalog_digest(), "verified_at": CATALOG_VERIFIED_AT},
|
|
178
|
-
}, headers={"X-API-Key": copilot_key, "X-Tenant-Id": session["tenant_id"], "Idempotency-Key": hashlib.sha256((session["tenant_id"] + ir_digest + catalog_digest()).encode()).hexdigest()})
|
|
179
|
-
if plan.get("schema") != "agenticdome.copilot-plan.v1" or plan.get("tenant_id") != session["tenant_id"]:
|
|
180
|
-
raise SystemExit("The assigned private Copilot returned an invalid tenant-bound plan.")
|
|
181
|
-
semantic = plan.get("semantic_analysis") or {}
|
|
182
|
-
if semantic.get("ir_sha256") != ir_digest:
|
|
183
|
-
raise SystemExit("The private Copilot plan was not bound to the submitted metadata.")
|
|
184
|
-
_request(portal + "/api/agentguard/connect/sessions/" + session["session_uuid"] + "/metadata", {"ir": ir, "signed_plan": plan}, session["access_token"])
|
|
185
|
-
|
|
185
|
+
from .onboarding_cli import _ir_sha256
|
|
186
|
+
ir_digest = _ir_sha256(ir)
|
|
186
187
|
state_dir = root / ".agenticdome"
|
|
187
188
|
state_dir.mkdir(parents=True, exist_ok=True)
|
|
188
|
-
cache = {"schema": "agenticdome.copilot-cache.v1", "source_upload": False, "tenant_id": session["tenant_id"], "api_base": runtime_base, "semantic_analysis": semantic, "catalog_binding": plan.get("catalog_binding")}
|
|
189
|
-
(state_dir / "copilot-analysis.json").write_text(json.dumps(cache, indent=2, sort_keys=True) + "\n", encoding="utf-8")
|
|
190
189
|
config_path = state_dir / "config.json"
|
|
191
190
|
if not config_path.exists():
|
|
192
191
|
config_path.write_text(json.dumps({
|
|
193
|
-
"schema": "agenticdome.project-config.v1", "
|
|
192
|
+
"schema": "agenticdome.project-config.v1", "workload_id": local_workload_id,
|
|
193
|
+
"frameworks": frameworks or ["custom-python"],
|
|
194
194
|
"execution_broker_mode": "policy",
|
|
195
195
|
"business_purpose": "REVIEW_REQUIRED_NOT_INVENTED", "sensitive_tools": [],
|
|
196
196
|
"deployment": {"preference": "managed", "region": session["runtime"].get("region") or "auto"},
|
|
197
197
|
"source_upload": False,
|
|
198
198
|
}, indent=2, sort_keys=True) + "\n", encoding="utf-8")
|
|
199
|
-
resumable = {"schema": "agenticdome.connect-state.v1", "portal": portal, "tenant_id": session["tenant_id"], "session_uuid": session["session_uuid"], "workload_uuid": workload_uuid, "token_expires_at": session["expires_at"], "access_token": session["access_token"]}
|
|
200
|
-
state_path = state_dir / "connect-session.json"
|
|
201
|
-
state_path.write_text(json.dumps(resumable, indent=2, sort_keys=True) + "\n", encoding="utf-8")
|
|
202
|
-
os.chmod(state_path, 0o600)
|
|
203
199
|
previous = {name: os.environ.get(name) for name in ("AGENTICDOME_API_BASE", "AGENTICDOME_COPILOT_API_KEY", "AGENTICDOME_TENANT_ID")}
|
|
204
200
|
os.environ.update({"AGENTICDOME_API_BASE": runtime_base, "AGENTICDOME_COPILOT_API_KEY": copilot_key, "AGENTICDOME_TENANT_ID": session["tenant_id"]})
|
|
205
201
|
try:
|
|
202
|
+
semantic = _copilot_semantic_analysis(root, ir, required=True)
|
|
203
|
+
binding = _active_copilot_catalog_binding(root)
|
|
204
|
+
if semantic.get("ir_sha256") != ir_digest or not binding:
|
|
205
|
+
raise SystemExit("The private Copilot result was not bound to this workload and the installed SDK catalog.")
|
|
206
|
+
# The portal stores a compact inventory, never the potentially large
|
|
207
|
+
# per-function graph. Every selected part was analyzed at the sidecar.
|
|
208
|
+
portal_ir = {
|
|
209
|
+
"schema": "agenticdome.copilot-ir.v1", "source_upload": False,
|
|
210
|
+
"metadata_kind": "bounded_workload_summary", "selected_ir_sha256": ir_digest,
|
|
211
|
+
"files": [], "functions": [],
|
|
212
|
+
"features": {"functions": len(ir.get("functions", []))},
|
|
213
|
+
"scope": {
|
|
214
|
+
"complete": True, "fingerprint": ir.get("scope", {}).get("fingerprint"),
|
|
215
|
+
"eligible_files_scanned": ir.get("scope", {}).get("eligible_files_scanned", 0),
|
|
216
|
+
},
|
|
217
|
+
"workload_coverage": {
|
|
218
|
+
"selected_parts": semantic.get("workload_coverage", {}).get("selected_parts", 1),
|
|
219
|
+
"analyzed_parts": semantic.get("workload_coverage", {}).get("analyzed_parts", 1),
|
|
220
|
+
"cross_part_flow_proven": semantic.get("workload_coverage", {}).get("cross_part_flow_proven", True),
|
|
221
|
+
},
|
|
222
|
+
}
|
|
223
|
+
plan = {
|
|
224
|
+
"schema": "agenticdome.copilot-plan.v1", "tenant_id": session["tenant_id"],
|
|
225
|
+
"semantic_analysis": semantic, "catalog_binding": binding,
|
|
226
|
+
"aggregation": {"kind": "sdk_local_bounded_parts", "signature_scope": "individual_sidecar_parts_only"},
|
|
227
|
+
}
|
|
228
|
+
_request(portal + "/api/agentguard/connect/sessions/" + session["session_uuid"] + "/metadata", {"ir": portal_ir, "signed_plan": plan}, session["access_token"])
|
|
229
|
+
|
|
206
230
|
from .onboarding_cli import create_scaffold
|
|
207
231
|
patch_path = create_scaffold(root)
|
|
208
232
|
finally:
|
|
@@ -211,6 +235,11 @@ def run_connect(root: Path, args: Any) -> Dict[str, Any]:
|
|
|
211
235
|
os.environ.pop(name, None)
|
|
212
236
|
else:
|
|
213
237
|
os.environ[name] = value
|
|
238
|
+
|
|
239
|
+
resumable = {"schema": "agenticdome.connect-state.v1", "portal": portal, "tenant_id": session["tenant_id"], "session_uuid": session["session_uuid"], "workload_uuid": workload_uuid, "token_expires_at": session["expires_at"], "access_token": session["access_token"]}
|
|
240
|
+
state_path = state_dir / "connect-session.json"
|
|
241
|
+
state_path.write_text(json.dumps(resumable, indent=2, sort_keys=True) + "\n", encoding="utf-8")
|
|
242
|
+
os.chmod(state_path, 0o600)
|
|
214
243
|
pull_request = None
|
|
215
244
|
if args.open_pr:
|
|
216
245
|
if not args.repository_connection:
|
|
@@ -222,6 +251,15 @@ def run_connect(root: Path, args: Any) -> Dict[str, Any]:
|
|
|
222
251
|
"next_action": "Ask AgenticDome to confirm policy-aware sidecar readiness before live verification.",
|
|
223
252
|
})
|
|
224
253
|
broker_setup["sdk_mode"] = effective_config.get("execution_broker_mode", "existing_sdk_or_environment_default")
|
|
254
|
+
cross_part_review_required = semantic.get("workload_coverage", {}).get("cross_part_flow_proven") is False
|
|
255
|
+
next_action = (
|
|
256
|
+
"Review the generated pull request and run agenticdome verify. Then review cross-part call paths and workload-specific tests in the portal before activation."
|
|
257
|
+
if args.open_pr else
|
|
258
|
+
"Review the generated patch, apply it on a branch, and run agenticdome verify. Then review cross-part call paths and workload-specific tests in the portal before activation."
|
|
259
|
+
) if cross_part_review_required else (
|
|
260
|
+
"Review the generated pull request and run agenticdome verify."
|
|
261
|
+
if args.open_pr else "Review the generated patch, apply it on a branch, then run agenticdome verify."
|
|
262
|
+
)
|
|
225
263
|
return {
|
|
226
264
|
"status": "changeset_ready", "source_upload": False, "tenant_id": session["tenant_id"],
|
|
227
265
|
"session_uuid": session["session_uuid"], "workload_uuid": workload_uuid,
|
|
@@ -229,9 +267,10 @@ def run_connect(root: Path, args: Any) -> Dict[str, Any]:
|
|
|
229
267
|
"execution_broker": broker_setup,
|
|
230
268
|
"attachment_points": len(semantic.get("attachment_points") or []),
|
|
231
269
|
"bypass_risks": len(semantic.get("bypass_risks") or []),
|
|
270
|
+
"cross_part_review_required": cross_part_review_required,
|
|
232
271
|
"patch": str(patch_path.relative_to(root)),
|
|
233
272
|
"pull_request": pull_request,
|
|
234
|
-
"next_action":
|
|
273
|
+
"next_action": next_action,
|
|
235
274
|
"sdk_version": _installed_sdk_version(),
|
|
236
275
|
}
|
|
237
276
|
|
agenticdome_sdk/copilot_ir.py
CHANGED
|
@@ -18,7 +18,9 @@ from typing import Any, Dict, List, Sequence, Tuple
|
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
IR_SCHEMA = "agenticdome.copilot-ir.v1"
|
|
21
|
-
MAX_IR_FILES =
|
|
21
|
+
MAX_IR_FILES = 5_000
|
|
22
|
+
MAX_IR_FUNCTIONS = 20_000
|
|
23
|
+
TYPESCRIPT_BATCH_FILES = 200
|
|
22
24
|
|
|
23
25
|
|
|
24
26
|
def _relative(path: Path, root: Path) -> str:
|
|
@@ -280,7 +282,7 @@ def _collect_python(root: Path, paths: Sequence[Path]) -> Tuple[List[Dict[str, A
|
|
|
280
282
|
parsed = 0
|
|
281
283
|
parse_errors = 0
|
|
282
284
|
features = {"functions": 0, "calls": 0, "returns": 0, "raises": 0}
|
|
283
|
-
for path in paths
|
|
285
|
+
for path in paths:
|
|
284
286
|
try:
|
|
285
287
|
tree = ast.parse(path.read_text(encoding="utf-8", errors="ignore"), filename=path.name)
|
|
286
288
|
except (OSError, SyntaxError, ValueError):
|
|
@@ -309,29 +311,38 @@ def _collect_typescript(root: Path, paths: Sequence[Path]) -> Tuple[List[Dict[st
|
|
|
309
311
|
helper = Path(__file__).with_name("copilot_ir_collector.cjs")
|
|
310
312
|
if not node or not helper.exists():
|
|
311
313
|
return _typescript_fallback(root, paths, "Node.js or the packaged IR collector is unavailable.")
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
314
|
+
functions: List[Dict[str, Any]] = []
|
|
315
|
+
files_parsed = 0
|
|
316
|
+
parse_errors = 0
|
|
317
|
+
compiler_version = ""
|
|
318
|
+
for offset in range(0, len(paths), TYPESCRIPT_BATCH_FILES):
|
|
319
|
+
batch = paths[offset:offset + TYPESCRIPT_BATCH_FILES]
|
|
320
|
+
try:
|
|
321
|
+
completed = subprocess.run(
|
|
322
|
+
[node, str(helper)],
|
|
323
|
+
input=json.dumps({"root": str(root), "files": [str(path) for path in batch]}),
|
|
324
|
+
text=True,
|
|
325
|
+
stdout=subprocess.PIPE,
|
|
326
|
+
stderr=subprocess.DEVNULL,
|
|
327
|
+
check=False,
|
|
328
|
+
timeout=30,
|
|
329
|
+
cwd=root,
|
|
330
|
+
)
|
|
331
|
+
result = json.loads(completed.stdout or "{}") if completed.returncode == 0 else {}
|
|
332
|
+
except (OSError, subprocess.TimeoutExpired, json.JSONDecodeError):
|
|
333
|
+
result = {}
|
|
334
|
+
if not isinstance(result, dict) or not result.get("available"):
|
|
335
|
+
return _typescript_fallback(root, paths, str(result.get("reason", "The TypeScript compiler is unavailable."))[:160] if isinstance(result, dict) else "The TypeScript compiler is unavailable.")
|
|
336
|
+
functions.extend(item for item in result.get("functions", []) if isinstance(item, dict))
|
|
337
|
+
files_parsed += max(0, int(result.get("files_parsed", 0)))
|
|
338
|
+
parse_errors += max(0, int(result.get("parse_errors", 0)))
|
|
339
|
+
compiler_version = str(result.get("typescript_version", ""))[:40]
|
|
340
|
+
return functions, {
|
|
330
341
|
"engine": "typescript-compiler-api",
|
|
331
342
|
"available": True,
|
|
332
|
-
"files_parsed":
|
|
333
|
-
"parse_errors":
|
|
334
|
-
"typescript_version":
|
|
343
|
+
"files_parsed": files_parsed,
|
|
344
|
+
"parse_errors": parse_errors,
|
|
345
|
+
"typescript_version": compiler_version,
|
|
335
346
|
"claim": "Generic compiler AST structure collection; private reasoning is performed by the assigned Copilot service",
|
|
336
347
|
}
|
|
337
348
|
|
|
@@ -339,11 +350,13 @@ def _collect_typescript(root: Path, paths: Sequence[Path]) -> Tuple[List[Dict[st
|
|
|
339
350
|
def _typescript_fallback(root: Path, paths: Sequence[Path], reason: str) -> Tuple[List[Dict[str, Any]], Dict[str, Any]]:
|
|
340
351
|
functions: List[Dict[str, Any]] = []
|
|
341
352
|
parsed = 0
|
|
353
|
+
read_errors = 0
|
|
342
354
|
call_pattern = re.compile(r"\b([A-Za-z_$][\w$]*(?:\s*\.\s*[A-Za-z_$][\w$]*)*)\s*\(")
|
|
343
|
-
for path in paths
|
|
355
|
+
for path in paths:
|
|
344
356
|
try:
|
|
345
357
|
lines = path.read_text(encoding="utf-8", errors="ignore").splitlines()
|
|
346
358
|
except OSError:
|
|
359
|
+
read_errors += 1
|
|
347
360
|
continue
|
|
348
361
|
events = []
|
|
349
362
|
for line_number, line in enumerate(lines, start=1):
|
|
@@ -357,7 +370,7 @@ def _typescript_fallback(root: Path, paths: Sequence[Path], reason: str) -> Tupl
|
|
|
357
370
|
"engine": "typescript-structural-fallback",
|
|
358
371
|
"available": False,
|
|
359
372
|
"files_parsed": parsed,
|
|
360
|
-
"parse_errors":
|
|
373
|
+
"parse_errors": read_errors,
|
|
361
374
|
"reason": reason,
|
|
362
375
|
"claim": "Generic structural collection only; install TypeScript for compiler AST evidence",
|
|
363
376
|
}
|
|
@@ -365,16 +378,30 @@ def _typescript_fallback(root: Path, paths: Sequence[Path], reason: str) -> Tupl
|
|
|
365
378
|
|
|
366
379
|
def collect_repository_ir(root: Path, paths: Sequence[Path]) -> Dict[str, Any]:
|
|
367
380
|
"""Collect bounded metadata for private reasoning without emitting source."""
|
|
368
|
-
|
|
369
|
-
|
|
381
|
+
selected = paths[:MAX_IR_FILES]
|
|
382
|
+
python_paths = [path for path in selected if path.suffix.lower() in {".py", ".pyi"}]
|
|
383
|
+
typescript_paths = [path for path in selected if path.suffix.lower() in {".js", ".jsx", ".ts", ".tsx"}]
|
|
370
384
|
python_functions, python_engine = _collect_python(root, python_paths)
|
|
371
385
|
typescript_functions, typescript_engine = _collect_typescript(root, typescript_paths)
|
|
386
|
+
functions = python_functions + typescript_functions
|
|
387
|
+
collection_errors = int(python_engine.get("parse_errors", 0)) + int(typescript_engine.get("parse_errors", 0))
|
|
388
|
+
files_parsed = int(python_engine.get("files_parsed", 0)) + int(typescript_engine.get("files_parsed", 0))
|
|
389
|
+
complete = (len(paths) <= MAX_IR_FILES and len(functions) <= MAX_IR_FUNCTIONS
|
|
390
|
+
and collection_errors == 0 and files_parsed == len(paths))
|
|
372
391
|
return {
|
|
373
392
|
"schema": IR_SCHEMA,
|
|
374
393
|
"source_upload": False,
|
|
375
394
|
"collector_mode": "generic_ast_metadata_only",
|
|
376
395
|
"engines": {"python": python_engine, "typescript": typescript_engine},
|
|
377
|
-
"functions":
|
|
396
|
+
"functions": functions[:MAX_IR_FUNCTIONS],
|
|
397
|
+
"coverage": {
|
|
398
|
+
"candidate_source_files": len(paths),
|
|
399
|
+
"files_selected": len(selected),
|
|
400
|
+
"symbols_found": len(functions),
|
|
401
|
+
"complete": complete,
|
|
402
|
+
"limit_reason": "file_limit" if len(paths) > MAX_IR_FILES else "symbol_limit" if len(functions) > MAX_IR_FUNCTIONS
|
|
403
|
+
else "parse_or_read_error" if collection_errors or files_parsed != len(paths) else None,
|
|
404
|
+
},
|
|
378
405
|
"privacy": {
|
|
379
406
|
"source_text": False,
|
|
380
407
|
"string_literals": False,
|