scion-sdk 0.5.6__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 (415) hide show
  1. agent_connector_sdk/__init__.py +23 -0
  2. agent_connector_sdk/_contract_fields.py +92 -0
  3. agent_connector_sdk/_extras.py +22 -0
  4. agent_connector_sdk/_turtle.py +116 -0
  5. agent_connector_sdk/_version.py +8 -0
  6. agent_connector_sdk/a2a/__init__.py +46 -0
  7. agent_connector_sdk/a2a/app.py +83 -0
  8. agent_connector_sdk/a2a/client.py +117 -0
  9. agent_connector_sdk/a2a/models.py +112 -0
  10. agent_connector_sdk/access_contract.py +125 -0
  11. agent_connector_sdk/adapters/__init__.py +1 -0
  12. agent_connector_sdk/adapters/document_sources.py +441 -0
  13. agent_connector_sdk/adapters/event_envelope.py +109 -0
  14. agent_connector_sdk/adapters/event_errors.py +51 -0
  15. agent_connector_sdk/adapters/event_feed.py +192 -0
  16. agent_connector_sdk/adapters/event_feed_bindings.py +27 -0
  17. agent_connector_sdk/adapters/event_feed_records.py +171 -0
  18. agent_connector_sdk/adapters/event_identity.py +46 -0
  19. agent_connector_sdk/adapters/mcp_tool.py +253 -0
  20. agent_connector_sdk/adapters/mcp_tool_extract.py +130 -0
  21. agent_connector_sdk/adapters/mcp_tool_fanout.py +198 -0
  22. agent_connector_sdk/adapters/mcp_tool_lifecycle.py +246 -0
  23. agent_connector_sdk/adapters/mcp_tool_paging.py +173 -0
  24. agent_connector_sdk/adapters/mcp_tool_records.py +111 -0
  25. agent_connector_sdk/adapters/tool_contract.py +77 -0
  26. agent_connector_sdk/adapters/web_fetch.py +221 -0
  27. agent_connector_sdk/adapters/web_fetch_helpers.py +73 -0
  28. agent_connector_sdk/artifacts/__init__.py +17 -0
  29. agent_connector_sdk/artifacts/annotations.py +109 -0
  30. agent_connector_sdk/artifacts/common.py +57 -0
  31. agent_connector_sdk/artifacts/ontology_imports.py +132 -0
  32. agent_connector_sdk/artifacts/pack.py +199 -0
  33. agent_connector_sdk/artifacts/prompts.py +129 -0
  34. agent_connector_sdk/artifacts/prompts_helpers.py +128 -0
  35. agent_connector_sdk/artifacts/resource_derivation.py +313 -0
  36. agent_connector_sdk/artifacts/resource_descriptor.py +252 -0
  37. agent_connector_sdk/artifacts/resources.py +70 -0
  38. agent_connector_sdk/artifacts/skills.py +64 -0
  39. agent_connector_sdk/artifacts/tools.py +74 -0
  40. agent_connector_sdk/auth/__init__.py +22 -0
  41. agent_connector_sdk/auth/browser.py +570 -0
  42. agent_connector_sdk/auth/client_credentials.py +165 -0
  43. agent_connector_sdk/auth/declare.py +393 -0
  44. agent_connector_sdk/auth/delegation.py +266 -0
  45. agent_connector_sdk/auth/oidc.py +151 -0
  46. agent_connector_sdk/auth/refresh_token.py +101 -0
  47. agent_connector_sdk/auth/rotating.py +117 -0
  48. agent_connector_sdk/auth/static.py +85 -0
  49. agent_connector_sdk/auth/tokens.py +96 -0
  50. agent_connector_sdk/auth/values.py +33 -0
  51. agent_connector_sdk/certify/__init__.py +1 -0
  52. agent_connector_sdk/certify/certification.py +102 -0
  53. agent_connector_sdk/certify/checkout.py +58 -0
  54. agent_connector_sdk/certify/cli.py +185 -0
  55. agent_connector_sdk/certify/declared_coverage.py +50 -0
  56. agent_connector_sdk/certify/fingerprints.py +106 -0
  57. agent_connector_sdk/certify/listing.py +65 -0
  58. agent_connector_sdk/certify/options.py +46 -0
  59. agent_connector_sdk/certify/verdicts.py +90 -0
  60. agent_connector_sdk/cli.py +27 -0
  61. agent_connector_sdk/compute/__init__.py +25 -0
  62. agent_connector_sdk/compute/engine.py +203 -0
  63. agent_connector_sdk/config.py +274 -0
  64. agent_connector_sdk/config_git.py +20 -0
  65. agent_connector_sdk/config_mounts.py +137 -0
  66. agent_connector_sdk/connector.py +355 -0
  67. agent_connector_sdk/connector_hooks.py +196 -0
  68. agent_connector_sdk/connector_identity.py +249 -0
  69. agent_connector_sdk/contracts.py +146 -0
  70. agent_connector_sdk/credentials/__init__.py +17 -0
  71. agent_connector_sdk/credentials/openbao.py +128 -0
  72. agent_connector_sdk/credentials/provider.py +68 -0
  73. agent_connector_sdk/credentials/provider_profile.py +315 -0
  74. agent_connector_sdk/credentials/references.py +93 -0
  75. agent_connector_sdk/credentials/resolution.py +86 -0
  76. agent_connector_sdk/credentials/resolver.py +55 -0
  77. agent_connector_sdk/credentials/runtime_references.py +105 -0
  78. agent_connector_sdk/credentials/sensitivity.py +111 -0
  79. agent_connector_sdk/credentials/source.py +487 -0
  80. agent_connector_sdk/current_plan.py +67 -0
  81. agent_connector_sdk/data_prep/__init__.py +128 -0
  82. agent_connector_sdk/data_prep/_base.py +11 -0
  83. agent_connector_sdk/data_prep/_classification.py +14 -0
  84. agent_connector_sdk/data_prep/certification/__init__.py +47 -0
  85. agent_connector_sdk/data_prep/certification/adapters.py +128 -0
  86. agent_connector_sdk/data_prep/certification/job.py +226 -0
  87. agent_connector_sdk/data_prep/certification/models.py +242 -0
  88. agent_connector_sdk/data_prep/kernel.py +1285 -0
  89. agent_connector_sdk/data_prep/models.py +516 -0
  90. agent_connector_sdk/data_prep/profiling.py +178 -0
  91. agent_connector_sdk/decide/__init__.py +110 -0
  92. agent_connector_sdk/decide/consumers.py +115 -0
  93. agent_connector_sdk/decide/epistemic_graph.py +190 -0
  94. agent_connector_sdk/decide/options.py +78 -0
  95. agent_connector_sdk/decide/outcome.py +137 -0
  96. agent_connector_sdk/decide/points.py +121 -0
  97. agent_connector_sdk/decide/transport.py +120 -0
  98. agent_connector_sdk/discovery.py +170 -0
  99. agent_connector_sdk/earth_observations/__init__.py +8 -0
  100. agent_connector_sdk/earth_observations/records.py +113 -0
  101. agent_connector_sdk/embeddings.py +264 -0
  102. agent_connector_sdk/entitlements.py +217 -0
  103. agent_connector_sdk/exceptions.py +69 -0
  104. agent_connector_sdk/exposure.py +22 -0
  105. agent_connector_sdk/file_lock.py +263 -0
  106. agent_connector_sdk/finance/__init__.py +7 -0
  107. agent_connector_sdk/finance/account.py +79 -0
  108. agent_connector_sdk/finance/alpaca_account.py +71 -0
  109. agent_connector_sdk/finance/alpaca_stocks.py +107 -0
  110. agent_connector_sdk/finance/banking.py +206 -0
  111. agent_connector_sdk/finance/central_bank_calendar.py +106 -0
  112. agent_connector_sdk/finance/crypto.py +99 -0
  113. agent_connector_sdk/finance/csv_import.py +189 -0
  114. agent_connector_sdk/finance/errors.py +29 -0
  115. agent_connector_sdk/finance/etf_flows.py +89 -0
  116. agent_connector_sdk/finance/feeds.py +244 -0
  117. agent_connector_sdk/finance/fred_series.py +109 -0
  118. agent_connector_sdk/finance/market_data.py +286 -0
  119. agent_connector_sdk/finance/multi_asset.py +103 -0
  120. agent_connector_sdk/finance/records.py +134 -0
  121. agent_connector_sdk/finance/strategy_export.py +297 -0
  122. agent_connector_sdk/http/__init__.py +20 -0
  123. agent_connector_sdk/http/bodies.py +81 -0
  124. agent_connector_sdk/http/client.py +142 -0
  125. agent_connector_sdk/http/egress.py +508 -0
  126. agent_connector_sdk/http/errors.py +136 -0
  127. agent_connector_sdk/http/flow.py +112 -0
  128. agent_connector_sdk/http/options.py +124 -0
  129. agent_connector_sdk/http/pagination.py +139 -0
  130. agent_connector_sdk/http/problems.py +126 -0
  131. agent_connector_sdk/http/redaction.py +54 -0
  132. agent_connector_sdk/http/responses.py +112 -0
  133. agent_connector_sdk/http/retry.py +145 -0
  134. agent_connector_sdk/http/safe_post.py +70 -0
  135. agent_connector_sdk/http/support.py +453 -0
  136. agent_connector_sdk/http/transport.py +136 -0
  137. agent_connector_sdk/httpsupport/__init__.py +11 -0
  138. agent_connector_sdk/httpsupport/auth.py +137 -0
  139. agent_connector_sdk/httpsupport/client_protocol.py +176 -0
  140. agent_connector_sdk/httpsupport/pagination.py +434 -0
  141. agent_connector_sdk/httpsupport/rate_limit.py +246 -0
  142. agent_connector_sdk/httpsupport/redaction.py +145 -0
  143. agent_connector_sdk/identifiers.py +55 -0
  144. agent_connector_sdk/identity.py +87 -0
  145. agent_connector_sdk/ingest/__init__.py +162 -0
  146. agent_connector_sdk/ingest/channel.py +64 -0
  147. agent_connector_sdk/ingest/engine.py +170 -0
  148. agent_connector_sdk/ingest/errors.py +17 -0
  149. agent_connector_sdk/ingest/for_each.py +67 -0
  150. agent_connector_sdk/ingest/live_declaration.py +298 -0
  151. agent_connector_sdk/ingest/mapping.py +272 -0
  152. agent_connector_sdk/ingest/model.py +196 -0
  153. agent_connector_sdk/ingest/paging.py +143 -0
  154. agent_connector_sdk/ingest/privacy.py +122 -0
  155. agent_connector_sdk/ingest/records.py +48 -0
  156. agent_connector_sdk/ingest/request.py +227 -0
  157. agent_connector_sdk/ingest/service.py +196 -0
  158. agent_connector_sdk/ingest/source_sync.py +671 -0
  159. agent_connector_sdk/ingest/sources.py +126 -0
  160. agent_connector_sdk/ingest/stream.py +424 -0
  161. agent_connector_sdk/ingest/tools.py +126 -0
  162. agent_connector_sdk/ingest/transport.py +82 -0
  163. agent_connector_sdk/library_state.py +76 -0
  164. agent_connector_sdk/manifest/__init__.py +1 -0
  165. agent_connector_sdk/manifest/declaration.py +123 -0
  166. agent_connector_sdk/manifest/live_contract.py +229 -0
  167. agent_connector_sdk/manifest/model.py +64 -0
  168. agent_connector_sdk/manifest/presets.py +272 -0
  169. agent_connector_sdk/manifest/provider_runtime.py +64 -0
  170. agent_connector_sdk/manifest/tool_schema.py +174 -0
  171. agent_connector_sdk/mcp/__init__.py +9 -0
  172. agent_connector_sdk/mcp/action_dispatch.py +235 -0
  173. agent_connector_sdk/mcp/action_split.py +753 -0
  174. agent_connector_sdk/mcp/auth/__init__.py +14 -0
  175. agent_connector_sdk/mcp/auth/factory.py +60 -0
  176. agent_connector_sdk/mcp/auth/jwt.py +140 -0
  177. agent_connector_sdk/mcp/auth/policy.py +103 -0
  178. agent_connector_sdk/mcp/auth/proxies.py +127 -0
  179. agent_connector_sdk/mcp/auth/static.py +113 -0
  180. agent_connector_sdk/mcp/auth/verifiers.py +74 -0
  181. agent_connector_sdk/mcp/body_boundary.py +99 -0
  182. agent_connector_sdk/mcp/change_events.py +78 -0
  183. agent_connector_sdk/mcp/concurrency.py +98 -0
  184. agent_connector_sdk/mcp/confirmation.py +141 -0
  185. agent_connector_sdk/mcp/content.py +322 -0
  186. agent_connector_sdk/mcp/context.py +145 -0
  187. agent_connector_sdk/mcp/env_drift.py +619 -0
  188. agent_connector_sdk/mcp/exposure.py +7 -0
  189. agent_connector_sdk/mcp/graphql.py +107 -0
  190. agent_connector_sdk/mcp/http_boundary.py +126 -0
  191. agent_connector_sdk/mcp/method_tools.py +655 -0
  192. agent_connector_sdk/mcp/middleware.py +51 -0
  193. agent_connector_sdk/mcp/network.py +225 -0
  194. agent_connector_sdk/mcp/network_inputs.py +197 -0
  195. agent_connector_sdk/mcp/network_validation.py +133 -0
  196. agent_connector_sdk/mcp/parser.py +134 -0
  197. agent_connector_sdk/mcp/registry.py +162 -0
  198. agent_connector_sdk/mcp/schema_disclosure.py +157 -0
  199. agent_connector_sdk/mcp/schema_disclosure_models.py +62 -0
  200. agent_connector_sdk/mcp/schema_disclosure_provider.py +112 -0
  201. agent_connector_sdk/mcp/served_security.py +166 -0
  202. agent_connector_sdk/mcp/server.py +187 -0
  203. agent_connector_sdk/mcp/tool_surface.py +443 -0
  204. agent_connector_sdk/mcp/versioning.py +33 -0
  205. agent_connector_sdk/mcp/visibility.py +62 -0
  206. agent_connector_sdk/mcp/visibility_filters.py +61 -0
  207. agent_connector_sdk/mcp/visibility_policy.py +148 -0
  208. agent_connector_sdk/ontology/access_contract.ttl +50 -0
  209. agent_connector_sdk/paths.py +185 -0
  210. agent_connector_sdk/payments.py +289 -0
  211. agent_connector_sdk/ports/__init__.py +21 -0
  212. agent_connector_sdk/ports/artifact_kind.py +27 -0
  213. agent_connector_sdk/ports/audit_reservation.py +26 -0
  214. agent_connector_sdk/ports/authorization_verifier.py +23 -0
  215. agent_connector_sdk/ports/change_source.py +43 -0
  216. agent_connector_sdk/ports/connector_registry.py +30 -0
  217. agent_connector_sdk/ports/decide_runner.py +80 -0
  218. agent_connector_sdk/ports/errors.py +39 -0
  219. agent_connector_sdk/ports/repair_proposals.py +28 -0
  220. agent_connector_sdk/ports/session.py +103 -0
  221. agent_connector_sdk/ports/sink.py +59 -0
  222. agent_connector_sdk/ports/source_adapter.py +44 -0
  223. agent_connector_sdk/ports/transport.py +23 -0
  224. agent_connector_sdk/ports/web_source.py +318 -0
  225. agent_connector_sdk/ports/writeback.py +36 -0
  226. agent_connector_sdk/ports/writeback_ledger.py +50 -0
  227. agent_connector_sdk/ports/writeback_transport.py +46 -0
  228. agent_connector_sdk/privacy.py +169 -0
  229. agent_connector_sdk/privacy_pii.py +82 -0
  230. agent_connector_sdk/privacy_reference.py +44 -0
  231. agent_connector_sdk/privacy_rules.py +251 -0
  232. agent_connector_sdk/progress.py +38 -0
  233. agent_connector_sdk/py.typed +0 -0
  234. agent_connector_sdk/repository/__init__.py +54 -0
  235. agent_connector_sdk/repository/errors.py +7 -0
  236. agent_connector_sdk/repository/identity.py +43 -0
  237. agent_connector_sdk/repository/indexing.py +107 -0
  238. agent_connector_sdk/repository/local_git.py +178 -0
  239. agent_connector_sdk/repository/manifest.py +65 -0
  240. agent_connector_sdk/repository/models.py +163 -0
  241. agent_connector_sdk/repository/provider.py +37 -0
  242. agent_connector_sdk/repository/ref_walk_provider.py +42 -0
  243. agent_connector_sdk/repository/refs.py +59 -0
  244. agent_connector_sdk/repository/transport.py +144 -0
  245. agent_connector_sdk/repository/tree_batch.py +117 -0
  246. agent_connector_sdk/repository/walk.py +104 -0
  247. agent_connector_sdk/runner/__init__.py +16 -0
  248. agent_connector_sdk/runner/backoff.py +26 -0
  249. agent_connector_sdk/runner/cli.py +189 -0
  250. agent_connector_sdk/runner/composition.py +212 -0
  251. agent_connector_sdk/runner/credentialed_endpoint.py +31 -0
  252. agent_connector_sdk/runner/descriptors.py +107 -0
  253. agent_connector_sdk/runner/endpoints.py +99 -0
  254. agent_connector_sdk/runner/errors.py +57 -0
  255. agent_connector_sdk/runner/health_reporting.py +58 -0
  256. agent_connector_sdk/runner/health_server.py +142 -0
  257. agent_connector_sdk/runner/health_state.py +185 -0
  258. agent_connector_sdk/runner/logs.py +53 -0
  259. agent_connector_sdk/runner/plans.py +196 -0
  260. agent_connector_sdk/runner/provisioning.py +85 -0
  261. agent_connector_sdk/runner/services.py +34 -0
  262. agent_connector_sdk/runner/sink_probe.py +25 -0
  263. agent_connector_sdk/runner/static_registry.py +63 -0
  264. agent_connector_sdk/runner/supervisor.py +126 -0
  265. agent_connector_sdk/runner/syncing.py +226 -0
  266. agent_connector_sdk/runner/worker.py +203 -0
  267. agent_connector_sdk/schema_contract.py +108 -0
  268. agent_connector_sdk/schema_drift.py +202 -0
  269. agent_connector_sdk/schema_repair.py +61 -0
  270. agent_connector_sdk/signing.py +110 -0
  271. agent_connector_sdk/sinks/__init__.py +1 -0
  272. agent_connector_sdk/sinks/epistemic_graph.py +198 -0
  273. agent_connector_sdk/skills/__init__.py +9 -0
  274. agent_connector_sdk/skills/agent-connector-sdk-development/SKILL.md +203 -0
  275. agent_connector_sdk/source_connectors/__init__.py +71 -0
  276. agent_connector_sdk/source_connectors/base.py +224 -0
  277. agent_connector_sdk/source_connectors/checkpoint.py +73 -0
  278. agent_connector_sdk/source_connectors/connectors/__init__.py +21 -0
  279. agent_connector_sdk/source_connectors/connectors/arxiv.py +294 -0
  280. agent_connector_sdk/source_connectors/connectors/database.py +350 -0
  281. agent_connector_sdk/source_connectors/connectors/graphql_document.py +2943 -0
  282. agent_connector_sdk/source_connectors/connectors/mcp_package.py +326 -0
  283. agent_connector_sdk/source_connectors/connectors/package_manifest.py +262 -0
  284. agent_connector_sdk/source_connectors/connectors/rest.py +259 -0
  285. agent_connector_sdk/source_connectors/connectors/rss.py +252 -0
  286. agent_connector_sdk/source_connectors/connectors/web.py +195 -0
  287. agent_connector_sdk/source_connectors/http_safety.py +1114 -0
  288. agent_connector_sdk/source_connectors/registry.py +173 -0
  289. agent_connector_sdk/source_connectors/universal.py +977 -0
  290. agent_connector_sdk/streaming.py +271 -0
  291. agent_connector_sdk/taxonomy/__init__.py +8 -0
  292. agent_connector_sdk/taxonomy/records.py +78 -0
  293. agent_connector_sdk/testing/__init__.py +19 -0
  294. agent_connector_sdk/testing/artifact_kinds.py +125 -0
  295. agent_connector_sdk/testing/certificates.py +113 -0
  296. agent_connector_sdk/testing/conformance.py +287 -0
  297. agent_connector_sdk/testing/duplicate_symbol_scan.py +88 -0
  298. agent_connector_sdk/testing/fleet_migration.py +106 -0
  299. agent_connector_sdk/testing/http_clients.py +144 -0
  300. agent_connector_sdk/testing/http_server.py +198 -0
  301. agent_connector_sdk/testing/ontology_rollup.py +80 -0
  302. agent_connector_sdk/testing/plugin.py +85 -0
  303. agent_connector_sdk/testing/readiness.py +10 -0
  304. agent_connector_sdk/testing/repair_proposals.py +27 -0
  305. agent_connector_sdk/testing/results.py +41 -0
  306. agent_connector_sdk/testing/sinks.py +278 -0
  307. agent_connector_sdk/testing/source_adapters.py +174 -0
  308. agent_connector_sdk/testing/web_source_conformance.py +250 -0
  309. agent_connector_sdk/testing/writeback.py +219 -0
  310. agent_connector_sdk/testing/writeback_audit.py +41 -0
  311. agent_connector_sdk/tls/__init__.py +16 -0
  312. agent_connector_sdk/tls/context.py +62 -0
  313. agent_connector_sdk/tls/errors.py +13 -0
  314. agent_connector_sdk/tls/material.py +108 -0
  315. agent_connector_sdk/tls/profile.py +116 -0
  316. agent_connector_sdk/tls/resolve.py +244 -0
  317. agent_connector_sdk/tls/selection.py +205 -0
  318. agent_connector_sdk/transports/__init__.py +1 -0
  319. agent_connector_sdk/transports/graphql.py +329 -0
  320. agent_connector_sdk/transports/mcp.py +91 -0
  321. agent_connector_sdk/transports/mcp_changes.py +130 -0
  322. agent_connector_sdk/transports/mcp_session.py +140 -0
  323. agent_connector_sdk/utilities.py +134 -0
  324. agent_connector_sdk/vendor_extractors/__init__.py +36 -0
  325. agent_connector_sdk/vendor_extractors/_records.py +66 -0
  326. agent_connector_sdk/vendor_extractors/a2a.py +125 -0
  327. agent_connector_sdk/vendor_extractors/a2a_helpers.py +101 -0
  328. agent_connector_sdk/vendor_extractors/ansible.py +70 -0
  329. agent_connector_sdk/vendor_extractors/archer.py +118 -0
  330. agent_connector_sdk/vendor_extractors/archimate.py +103 -0
  331. agent_connector_sdk/vendor_extractors/aris.py +110 -0
  332. agent_connector_sdk/vendor_extractors/caddy.py +93 -0
  333. agent_connector_sdk/vendor_extractors/camunda.py +169 -0
  334. agent_connector_sdk/vendor_extractors/ciso_assistant.py +167 -0
  335. agent_connector_sdk/vendor_extractors/ciso_assistant_helpers.py +73 -0
  336. agent_connector_sdk/vendor_extractors/contract.py +97 -0
  337. agent_connector_sdk/vendor_extractors/egeria.py +254 -0
  338. agent_connector_sdk/vendor_extractors/egeria_helpers.py +79 -0
  339. agent_connector_sdk/vendor_extractors/emerald.py +126 -0
  340. agent_connector_sdk/vendor_extractors/erpnext.py +113 -0
  341. agent_connector_sdk/vendor_extractors/erpnext_helpers.py +196 -0
  342. agent_connector_sdk/vendor_extractors/grafana.py +152 -0
  343. agent_connector_sdk/vendor_extractors/grafana_helpers.py +50 -0
  344. agent_connector_sdk/vendor_extractors/home_assistant.py +86 -0
  345. agent_connector_sdk/vendor_extractors/infra.py +105 -0
  346. agent_connector_sdk/vendor_extractors/infra_helpers.py +95 -0
  347. agent_connector_sdk/vendor_extractors/kafka.py +98 -0
  348. agent_connector_sdk/vendor_extractors/keycloak.py +121 -0
  349. agent_connector_sdk/vendor_extractors/leanix.py +226 -0
  350. agent_connector_sdk/vendor_extractors/lgtm.py +129 -0
  351. agent_connector_sdk/vendor_extractors/mealie.py +128 -0
  352. agent_connector_sdk/vendor_extractors/microsoft.py +106 -0
  353. agent_connector_sdk/vendor_extractors/nextcloud.py +136 -0
  354. agent_connector_sdk/vendor_extractors/odoo.py +127 -0
  355. agent_connector_sdk/vendor_extractors/okta.py +161 -0
  356. agent_connector_sdk/vendor_extractors/portainer.py +136 -0
  357. agent_connector_sdk/vendor_extractors/salesforce.py +102 -0
  358. agent_connector_sdk/vendor_extractors/servicenow.py +163 -0
  359. agent_connector_sdk/vendor_extractors/servicenow_helpers.py +111 -0
  360. agent_connector_sdk/vendor_extractors/social.py +201 -0
  361. agent_connector_sdk/vendor_extractors/technitium_dns.py +111 -0
  362. agent_connector_sdk/vendor_extractors/twenty.py +122 -0
  363. agent_connector_sdk/vendor_extractors/twenty_helpers.py +88 -0
  364. agent_connector_sdk/vendor_extractors/uptime_kuma.py +74 -0
  365. agent_connector_sdk/vendor_extractors/wger.py +140 -0
  366. agent_connector_sdk/voice_supply_chain/__init__.py +14 -0
  367. agent_connector_sdk/voice_supply_chain/license_registry.py +110 -0
  368. agent_connector_sdk/voice_supply_chain/manifest.py +178 -0
  369. agent_connector_sdk/voice_supply_chain/store.py +14 -0
  370. agent_connector_sdk/writeback/__init__.py +1 -0
  371. agent_connector_sdk/writeback/authorization.py +95 -0
  372. agent_connector_sdk/writeback/connector.py +122 -0
  373. agent_connector_sdk/writeback/durable_files.py +33 -0
  374. agent_connector_sdk/writeback/durable_ledger.py +151 -0
  375. agent_connector_sdk/writeback/durable_transport.py +167 -0
  376. agent_connector_sdk/writeback/epistemic_graph.py +121 -0
  377. agent_connector_sdk/writeback/errors.py +56 -0
  378. agent_connector_sdk/writeback/memory.py +184 -0
  379. agent_connector_sdk/writeback/models.py +33 -0
  380. agent_connector_sdk/writeback/recovery.py +175 -0
  381. agent_connector_sdk/writeback/service.py +152 -0
  382. agent_connector_sdk/writeback/validation.py +97 -0
  383. agent_connector_sdk/writeback_sinks/__init__.py +63 -0
  384. agent_connector_sdk/writeback_sinks/_env.py +66 -0
  385. agent_connector_sdk/writeback_sinks/core.py +506 -0
  386. agent_connector_sdk/writeback_sinks/governed.py +420 -0
  387. agent_connector_sdk/writeback_sinks/models.py +15 -0
  388. agent_connector_sdk/writeback_sinks/sinks/__init__.py +1 -0
  389. agent_connector_sdk/writeback_sinks/sinks/ansible.py +64 -0
  390. agent_connector_sdk/writeback_sinks/sinks/archimate.py +93 -0
  391. agent_connector_sdk/writeback_sinks/sinks/capability.py +215 -0
  392. agent_connector_sdk/writeback_sinks/sinks/ciso_assistant.py +95 -0
  393. agent_connector_sdk/writeback_sinks/sinks/egeria.py +92 -0
  394. agent_connector_sdk/writeback_sinks/sinks/emerald.py +103 -0
  395. agent_connector_sdk/writeback_sinks/sinks/erpnext.py +144 -0
  396. agent_connector_sdk/writeback_sinks/sinks/home_assistant.py +74 -0
  397. agent_connector_sdk/writeback_sinks/sinks/identity.py +158 -0
  398. agent_connector_sdk/writeback_sinks/sinks/issue_tracker.py +258 -0
  399. agent_connector_sdk/writeback_sinks/sinks/leanix.py +195 -0
  400. agent_connector_sdk/writeback_sinks/sinks/legal.py +81 -0
  401. agent_connector_sdk/writeback_sinks/sinks/mealie.py +90 -0
  402. agent_connector_sdk/writeback_sinks/sinks/nextcloud.py +108 -0
  403. agent_connector_sdk/writeback_sinks/sinks/ops.py +155 -0
  404. agent_connector_sdk/writeback_sinks/sinks/process.py +438 -0
  405. agent_connector_sdk/writeback_sinks/sinks/salesforce.py +98 -0
  406. agent_connector_sdk/writeback_sinks/sinks/servicenow.py +271 -0
  407. agent_connector_sdk/writeback_sinks/sinks/twenty.py +105 -0
  408. agent_connector_sdk/writeback_sinks/sinks/wger.py +108 -0
  409. agent_connector_sdk/writeback_sinks/spec_link.py +262 -0
  410. scion_sdk-0.5.6.dist-info/METADATA +198 -0
  411. scion_sdk-0.5.6.dist-info/RECORD +415 -0
  412. scion_sdk-0.5.6.dist-info/WHEEL +5 -0
  413. scion_sdk-0.5.6.dist-info/entry_points.txt +25 -0
  414. scion_sdk-0.5.6.dist-info/licenses/LICENSE +21 -0
  415. scion_sdk-0.5.6.dist-info/top_level.txt +1 -0
@@ -0,0 +1,23 @@
1
+ """Scion SDK: the connector-facing SDK for the agent-packages fleet.
2
+
3
+ Public modules are imported by their own path (``agent_connector_sdk.mcp.server``,
4
+ ``agent_connector_sdk.ports`` and so on). The package root exports the version
5
+ and, lazily, :class:`Connector` and :func:`run`, so importing it never pulls in
6
+ the MCP server stack.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from typing import Any
12
+
13
+ from agent_connector_sdk._version import __version__
14
+
15
+ __all__ = ["Connector", "__version__", "run"]
16
+
17
+
18
+ def __getattr__(name: str) -> Any:
19
+ if name in ("Connector", "run"):
20
+ from agent_connector_sdk import connector
21
+
22
+ return getattr(connector, name)
23
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
@@ -0,0 +1,92 @@
1
+ """Typed field readers for ``ac:AccessContract`` subjects."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from ._turtle import AccessContractError, Term
6
+ from .credentials.references import SecretReferenceError, parse_secret_reference
7
+
8
+ AC = "https://knuckles-team.github.io/agent-connector-sdk/access#"
9
+ ACCESS_KINDS = frozenset({"mcp_tool", "http_endpoint", "graphql_query", "a2a_skill"})
10
+ PAGINATION_MODES = frozenset({"none", "cursor", "offset", "page"})
11
+ PUSHDOWN_OPS = frozenset({"filter", "sort", "limit", "project"})
12
+ COST_HINTS = frozenset({"low", "medium", "high"})
13
+
14
+ Props = dict[str, list[Term]]
15
+
16
+
17
+ def _one(props: Props, name: str, subject: str) -> Term | None:
18
+ values = props.get(AC + name, [])
19
+ if len(values) > 1:
20
+ raise AccessContractError(f"{subject}: ac:{name} appears more than once")
21
+ return values[0] if values else None
22
+
23
+
24
+ def text(props: Props, name: str, subject: str) -> str:
25
+ """Return a required non-empty string property."""
26
+ value = _one(props, name, subject)
27
+ if not isinstance(value, str) or not value.strip():
28
+ raise AccessContractError(f"{subject}: missing ac:{name}")
29
+ return value
30
+
31
+
32
+ def integer(props: Props, name: str, subject: str) -> int | None:
33
+ """Return an optional non-negative integer property."""
34
+ value = _one(props, name, subject)
35
+ if value is not None and (not isinstance(value, int) or value < 0):
36
+ raise AccessContractError(
37
+ f"{subject}: ac:{name} must be a non-negative integer"
38
+ )
39
+ return value
40
+
41
+
42
+ def choice(
43
+ props: Props,
44
+ name: str,
45
+ subject: str,
46
+ *,
47
+ allowed: frozenset[str],
48
+ default: str | None = None,
49
+ ) -> str:
50
+ """Return a property constrained to ``allowed``; ``default`` makes it optional."""
51
+ raw = _one(props, name, subject) if default is not None else None
52
+ value = text(props, name, subject) if default is None else str(raw or default)
53
+ if value not in allowed:
54
+ raise AccessContractError(f"{subject}: unknown ac:{name} {value!r}")
55
+ return value
56
+
57
+
58
+ def pushdown(props: Props, subject: str) -> frozenset[str]:
59
+ """Return the declared pushdown operations, refusing unknown ones."""
60
+ ops = frozenset(str(op) for op in props.get(AC + "pushdown", []))
61
+ unknown = sorted(ops - PUSHDOWN_OPS)
62
+ if unknown:
63
+ raise AccessContractError(f"{subject}: unknown ac:pushdown {unknown}")
64
+ return ops
65
+
66
+
67
+ def parameters(props: Props) -> tuple[str, ...]:
68
+ """Return the declared operation parameters in sorted order."""
69
+ return tuple(sorted(str(p) for p in props.get(AC + "parameter", [])))
70
+
71
+
72
+ def auth_ref(props: Props, subject: str) -> str | None:
73
+ """Return a rendered credential reference, refusing a literal secret."""
74
+ value = _one(props, "authRef", subject)
75
+ if value is None:
76
+ return None
77
+ try:
78
+ return parse_secret_reference(str(value)).render()
79
+ except SecretReferenceError:
80
+ raise AccessContractError(
81
+ f"{subject}: ac:authRef must be a credential reference, not a secret"
82
+ ) from None
83
+
84
+
85
+ def bindings(graph: dict[str, Props], contract: str) -> tuple[tuple[str, str], ...]:
86
+ """Return the sorted (property, field) pairs bound to ``contract``."""
87
+ pairs = []
88
+ for subject, props in graph.items():
89
+ if contract in props.get(AC + "contract", []):
90
+ prop = text(props, "property", subject)
91
+ pairs.append((prop, text(props, "field", subject)))
92
+ return tuple(sorted(pairs))
@@ -0,0 +1,22 @@
1
+ """Clear errors for features that need an optional extra of the base install."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import importlib
6
+
7
+ __all__ = ["require_mcp_extra"]
8
+
9
+
10
+ def require_mcp_extra(feature: str) -> None:
11
+ """Raise ``ImportError`` naming the ``mcp`` extra when fastmcp or mcp is absent."""
12
+ missing = []
13
+ for name in ("fastmcp", "mcp"):
14
+ try:
15
+ importlib.import_module(name)
16
+ except ImportError:
17
+ missing.append(name)
18
+ if missing:
19
+ raise ImportError(
20
+ f"{feature} needs {' and '.join(missing)}, which the base install of "
21
+ 'scion-sdk leaves out; install "scion-sdk[mcp]"'
22
+ )
@@ -0,0 +1,116 @@
1
+ """Flat Turtle reader used by the access-contract parser.
2
+
3
+ It tokenizes one restricted profile (see :mod:`agent_connector_sdk.access_contract`)
4
+ and raises :class:`AccessContractError` on anything outside it.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import re
10
+ from collections import defaultdict
11
+
12
+ RDF_TYPE = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
13
+
14
+ _TOKEN_RE = re.compile(
15
+ r"(?P<ws>\s+|#[^\n]*)"
16
+ r"|(?P<iri><[^<>\s]*>)"
17
+ r'|(?P<str>"(?:[^"\\\n]|\\.)*")'
18
+ r"|(?P<int>-?\d+)"
19
+ r"|(?P<prefix>@prefix)"
20
+ r"|(?P<pname>[A-Za-z_]?[\w-]*:(?:[\w-](?:[\w.-]*[\w-])?)?)"
21
+ r"|(?P<a>a(?=\s))"
22
+ r"|(?P<punct>[;,.])"
23
+ )
24
+
25
+ Term = str | int
26
+ Triple = tuple[str, str, Term]
27
+
28
+
29
+ class AccessContractError(ValueError):
30
+ """A connector ontology declares an invalid access contract."""
31
+
32
+
33
+ def _tokens(text: str) -> list[tuple[str, str]]:
34
+ out: list[tuple[str, str]] = []
35
+ pos = 0
36
+ while pos < len(text):
37
+ match = _TOKEN_RE.match(text, pos)
38
+ if match is None or match.end() == pos:
39
+ raise AccessContractError(f"unsupported Turtle at offset {pos}")
40
+ kind = match.lastgroup or ""
41
+ if kind != "ws":
42
+ out.append((kind, match.group()))
43
+ pos = match.end()
44
+ return out
45
+
46
+
47
+ class _Reader:
48
+ def __init__(self, text: str) -> None:
49
+ self.toks = _tokens(text)
50
+ self.pos = 0
51
+ self.prefixes: dict[str, str] = {}
52
+ self.triples: list[Triple] = []
53
+
54
+ def next(self) -> tuple[str, str]:
55
+ if self.pos >= len(self.toks):
56
+ raise AccessContractError("unexpected end of Turtle")
57
+ self.pos += 1
58
+ return self.toks[self.pos - 1]
59
+
60
+ def expect(self, value: str) -> None:
61
+ if self.next()[1] != value:
62
+ raise AccessContractError(f"expected {value!r}")
63
+
64
+ def term(self) -> Term:
65
+ kind, value = self.next()
66
+ if kind == "iri":
67
+ return value[1:-1]
68
+ if kind == "a":
69
+ return RDF_TYPE
70
+ if kind == "pname":
71
+ prefix, _, local = value.partition(":")
72
+ if prefix not in self.prefixes:
73
+ raise AccessContractError(f"undeclared prefix {prefix!r}")
74
+ return self.prefixes[prefix] + local
75
+ if kind == "str":
76
+ return value[1:-1].replace('\\"', '"').replace("\\\\", "\\")
77
+ if kind == "int":
78
+ return int(value)
79
+ raise AccessContractError(f"unexpected token {value!r}")
80
+
81
+ def prefix(self) -> None:
82
+ kind, name = self.next()
83
+ iri = self.next()
84
+ if kind != "pname" or not name.endswith(":") or iri[0] != "iri":
85
+ raise AccessContractError("malformed @prefix")
86
+ self.prefixes[name[:-1]] = iri[1][1:-1]
87
+ self.expect(".")
88
+
89
+ def statement(self) -> None:
90
+ subject = str(self.term())
91
+ sep = ";"
92
+ while sep == ";":
93
+ predicate = str(self.term())
94
+ sep = ","
95
+ while sep == ",":
96
+ self.triples.append((subject, predicate, self.term()))
97
+ sep = self.next()[1]
98
+ if sep != ".":
99
+ raise AccessContractError("statement must end with '.'")
100
+
101
+ def read(self) -> list[Triple]:
102
+ while self.pos < len(self.toks):
103
+ if self.toks[self.pos][0] == "prefix":
104
+ self.pos += 1
105
+ self.prefix()
106
+ else:
107
+ self.statement()
108
+ return self.triples
109
+
110
+
111
+ def parse_graph(text: str) -> dict[str, dict[str, list[Term]]]:
112
+ """Read flat Turtle into a subject -> predicate -> objects index."""
113
+ graph: dict[str, dict[str, list[Term]]] = defaultdict(lambda: defaultdict(list))
114
+ for subject, predicate, obj in _Reader(text).read():
115
+ graph[subject][predicate].append(obj)
116
+ return graph
@@ -0,0 +1,8 @@
1
+ """The SDK version, read from installed package metadata.
2
+
3
+ ``pyproject.toml`` is the only file that spells it (SDK-CONNECTOR-CONTROL-R071.2).
4
+ """
5
+
6
+ from agent_connector_sdk.connector_identity import distribution_version
7
+
8
+ __version__ = distribution_version("scion-sdk")
@@ -0,0 +1,46 @@
1
+ """Agent-to-Agent (A2A) protocol pieces any connector or host can reuse.
2
+
3
+ CONCEPT:SDK-CONNECTOR-CONTROL-R014.21
4
+
5
+ The base install carries the wire models and the JSON-RPC client (pydantic and
6
+ httpx only). The server-side application factory needs the optional ``a2a``
7
+ extra (fasta2a and starlette); a host such as arbora mounts it behind its own
8
+ admission and authentication. Nothing here stores tasks or builds cards from a
9
+ graph: durable task state and graph-derived cards belong to the host.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ from typing import Any
15
+
16
+ from .client import A2AClient, A2AResult
17
+ from .models import (
18
+ A2AMessage,
19
+ A2ATask,
20
+ A2ATaskStatus,
21
+ AgentCard,
22
+ AgentSkill,
23
+ TaskState,
24
+ TextPart,
25
+ )
26
+
27
+ __all__ = [
28
+ "A2AClient",
29
+ "A2AMessage",
30
+ "A2AResult",
31
+ "A2ATask",
32
+ "A2ATaskStatus",
33
+ "AgentCard",
34
+ "AgentSkill",
35
+ "TaskState",
36
+ "TextPart",
37
+ "create_a2a_app",
38
+ ]
39
+
40
+
41
+ def __getattr__(name: str) -> Any:
42
+ if name == "create_a2a_app":
43
+ from .app import create_a2a_app
44
+
45
+ return create_a2a_app
46
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
@@ -0,0 +1,83 @@
1
+ """Server-side A2A application factory (needs the ``a2a`` extra).
2
+
3
+ CONCEPT:SDK-CONNECTOR-CONTROL-R014.21
4
+
5
+ Builds a fasta2a ASGI app for a pydantic-ai agent. The caller supplies the
6
+ broker and storage; this SDK holds no task store. A host mounts the returned
7
+ app behind its own admission and authentication.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import importlib
13
+ from collections.abc import AsyncIterator
14
+ from typing import Any
15
+
16
+ from .models import AgentSkill
17
+
18
+ __all__ = ["create_a2a_app", "require_a2a_extra"]
19
+
20
+
21
+ def require_a2a_extra(feature: str) -> None:
22
+ """Raise ``ImportError`` naming the ``a2a`` extra when it is absent."""
23
+ missing = []
24
+ for name in ("fasta2a", "starlette"):
25
+ try:
26
+ importlib.import_module(name)
27
+ except ImportError:
28
+ missing.append(name)
29
+ if missing:
30
+ raise ImportError(
31
+ f"{feature} needs {' and '.join(missing)}, which the base install of "
32
+ 'scion-sdk leaves out; install "scion-sdk[a2a]"'
33
+ )
34
+
35
+
36
+ def create_a2a_app(
37
+ agent: Any,
38
+ *,
39
+ name: str,
40
+ url: str,
41
+ version: str,
42
+ description: str = "",
43
+ skills: list[AgentSkill] | None = None,
44
+ storage: Any,
45
+ broker: Any,
46
+ ) -> Any:
47
+ """Return the fasta2a application for ``agent`` with the given card fields."""
48
+ require_a2a_extra("create_a2a_app")
49
+ from fasta2a import FastA2A, Skill
50
+ from fasta2a.pydantic_ai import AgentWorker
51
+ from starlette.types import ASGIApp # noqa: F401 - the extra's contract
52
+
53
+ worker = AgentWorker(agent=agent, broker=broker, storage=storage)
54
+ card_skills = [
55
+ Skill(
56
+ id=skill.id,
57
+ name=skill.name,
58
+ description=skill.description,
59
+ tags=list(skill.tags),
60
+ input_modes=list(skill.input_modes),
61
+ output_modes=list(skill.output_modes),
62
+ )
63
+ for skill in skills or []
64
+ ]
65
+
66
+ async def lifespan(
67
+ app: Any,
68
+ ) -> AsyncIterator[None]: # pragma: no cover - exercised by the host
69
+ async with app.task_manager, worker.run():
70
+ yield
71
+
72
+ from contextlib import asynccontextmanager
73
+
74
+ return FastA2A(
75
+ storage=storage,
76
+ broker=broker,
77
+ name=name,
78
+ url=url,
79
+ version=version,
80
+ description=description or None,
81
+ skills=card_skills,
82
+ lifespan=asynccontextmanager(lifespan),
83
+ )
@@ -0,0 +1,117 @@
1
+ """Bounded JSON-RPC client for one A2A exchange.
2
+
3
+ CONCEPT:SDK-CONNECTOR-CONTROL-R014.21
4
+
5
+ ``message/send`` then ``tasks/get`` polling until the task leaves a pending
6
+ state or the deadline passes. Failures come back as an :class:`A2AResult` with
7
+ a fixed message; remote error bodies are never echoed.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import asyncio
13
+ from dataclasses import dataclass, field
14
+ from typing import Any
15
+
16
+ import httpx
17
+ from pydantic import ValidationError
18
+
19
+ from .models import A2AMessage, A2ATask, AgentCard
20
+
21
+ CARD_PATH = "/.well-known/agent-card.json"
22
+ _MAX_RESPONSE_BYTES = 4 * 1024 * 1024
23
+
24
+
25
+ @dataclass(frozen=True)
26
+ class A2AResult:
27
+ content: str = ""
28
+ metadata: dict[str, Any] = field(default_factory=dict)
29
+ error: str | None = None
30
+
31
+ @property
32
+ def ok(self) -> bool:
33
+ return self.error is None
34
+
35
+
36
+ class A2AClient:
37
+ """Call one remote A2A agent. Supply ``transport`` to reuse a host's egress."""
38
+
39
+ def __init__(
40
+ self,
41
+ *,
42
+ timeout: float = 300.0,
43
+ poll_interval: float = 2.0,
44
+ request_timeout: float = 60.0,
45
+ transport: httpx.AsyncBaseTransport | None = None,
46
+ ) -> None:
47
+ if timeout <= 0 or poll_interval <= 0 or request_timeout <= 0:
48
+ raise ValueError("A2A client timeouts must be positive")
49
+ self.timeout = timeout
50
+ self.poll_interval = poll_interval
51
+ self.request_timeout = min(request_timeout, timeout)
52
+ self._transport = transport
53
+
54
+ def _client(self) -> httpx.AsyncClient:
55
+ return httpx.AsyncClient(
56
+ timeout=self.request_timeout,
57
+ transport=self._transport,
58
+ follow_redirects=False,
59
+ )
60
+
61
+ @staticmethod
62
+ def _json(response: httpx.Response) -> Any:
63
+ response.raise_for_status()
64
+ if len(response.content) > _MAX_RESPONSE_BYTES:
65
+ raise ValueError("A2A response exceeds its bound")
66
+ return response.json()
67
+
68
+ async def fetch_card(self, base_url: str) -> AgentCard | None:
69
+ """Fetch and validate a peer's agent card; ``None`` when unusable."""
70
+ try:
71
+ async with self._client() as client:
72
+ data = self._json(await client.get(base_url.rstrip("/") + CARD_PATH))
73
+ return AgentCard.model_validate(data)
74
+ except (httpx.HTTPError, ValueError, ValidationError):
75
+ return None
76
+
77
+ async def _rpc(
78
+ self,
79
+ client: httpx.AsyncClient,
80
+ url: str,
81
+ method: str,
82
+ params: dict[str, Any],
83
+ rid: int,
84
+ ) -> dict[str, Any]:
85
+ payload = {"jsonrpc": "2.0", "method": method, "params": params, "id": rid}
86
+ data = self._json(await client.post(url, json=payload))
87
+ if not isinstance(data, dict):
88
+ raise ValueError("A2A response root must be an object")
89
+ return data
90
+
91
+ async def send(self, url: str, text: str) -> A2AResult:
92
+ """Send one user text message and wait for the task's agent reply."""
93
+ message = A2AMessage.user_text(text)
94
+ try:
95
+ async with asyncio.timeout(self.timeout), self._client() as client:
96
+ sent = await self._rpc(
97
+ client, url, "message/send", {"message": message.wire()}, 1
98
+ )
99
+ if "error" in sent:
100
+ return A2AResult(error="A2A peer rejected the request")
101
+ task = A2ATask.model_validate(sent.get("result"))
102
+ while task.pending:
103
+ await asyncio.sleep(self.poll_interval)
104
+ polled = await self._rpc(
105
+ client, url, "tasks/get", {"id": task.id}, 2
106
+ )
107
+ if "error" in polled:
108
+ return A2AResult(error="A2A peer rejected task polling")
109
+ task = A2ATask.model_validate(polled.get("result"))
110
+ except TimeoutError:
111
+ return A2AResult(error="A2A execution deadline exceeded")
112
+ except (httpx.HTTPError, ValueError, ValidationError) as exc:
113
+ return A2AResult(error=f"A2A communication failed ({type(exc).__name__})")
114
+ reply = task.last_agent_message()
115
+ if task.status.state != "completed" or reply is None:
116
+ return A2AResult(error=f"A2A task ended {task.status.state}")
117
+ return A2AResult(content=reply.text(), metadata=dict(reply.metadata))
@@ -0,0 +1,112 @@
1
+ """A2A wire models: agent card, skills, messages and tasks.
2
+
3
+ CONCEPT:SDK-CONNECTOR-CONTROL-R014.21
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ import uuid
9
+ from typing import Any, Literal
10
+
11
+ from pydantic import BaseModel, ConfigDict, Field
12
+
13
+ TaskState = Literal[
14
+ "submitted",
15
+ "working",
16
+ "input-required",
17
+ "completed",
18
+ "canceled",
19
+ "failed",
20
+ "rejected",
21
+ "auth-required",
22
+ "unknown",
23
+ ]
24
+ TERMINAL_STATES: frozenset[str] = frozenset(
25
+ {"completed", "canceled", "failed", "rejected"}
26
+ )
27
+ PENDING_STATES: frozenset[str] = frozenset({"submitted", "working"})
28
+
29
+
30
+ class _Wire(BaseModel):
31
+ model_config = ConfigDict(populate_by_name=True, extra="ignore")
32
+
33
+
34
+ class AgentSkill(_Wire):
35
+ """One skill an agent card advertises."""
36
+
37
+ id: str = Field(min_length=1, max_length=256)
38
+ name: str = Field(min_length=1, max_length=256)
39
+ description: str = Field(default="", max_length=4096)
40
+ tags: list[str] = Field(default_factory=list, max_length=64)
41
+ input_modes: list[str] = Field(default_factory=lambda: ["text"], alias="inputModes")
42
+ output_modes: list[str] = Field(
43
+ default_factory=lambda: ["text"], alias="outputModes"
44
+ )
45
+
46
+
47
+ class AgentCard(_Wire):
48
+ """The document an agent serves at ``/.well-known/agent-card.json``."""
49
+
50
+ name: str = Field(min_length=1, max_length=256)
51
+ url: str = Field(min_length=1, max_length=2048)
52
+ version: str = Field(default="0.0.0", max_length=64)
53
+ description: str = Field(default="", max_length=4096)
54
+ protocol_version: str = Field(default="0.3.0", alias="protocolVersion")
55
+ skills: list[AgentSkill] = Field(default_factory=list, max_length=256)
56
+ default_input_modes: list[str] = Field(
57
+ default_factory=lambda: ["text"], alias="defaultInputModes"
58
+ )
59
+ default_output_modes: list[str] = Field(
60
+ default_factory=lambda: ["text"], alias="defaultOutputModes"
61
+ )
62
+ capabilities: dict[str, Any] = Field(default_factory=dict)
63
+
64
+ def wire(self) -> dict[str, Any]:
65
+ return self.model_dump(by_alias=True)
66
+
67
+
68
+ class TextPart(_Wire):
69
+ kind: Literal["text"] = "text"
70
+ text: str
71
+
72
+
73
+ class A2AMessage(_Wire):
74
+ kind: Literal["message"] = "message"
75
+ role: Literal["user", "agent"]
76
+ parts: list[TextPart] = Field(default_factory=list)
77
+ message_id: str = Field(
78
+ default_factory=lambda: str(uuid.uuid4()), alias="messageId"
79
+ )
80
+ metadata: dict[str, Any] = Field(default_factory=dict)
81
+
82
+ @classmethod
83
+ def user_text(cls, text: str) -> A2AMessage:
84
+ return cls(role="user", parts=[TextPart(text=text)])
85
+
86
+ def text(self) -> str:
87
+ return "".join(part.text for part in self.parts)
88
+
89
+ def wire(self) -> dict[str, Any]:
90
+ return self.model_dump(by_alias=True, exclude_defaults=False)
91
+
92
+
93
+ class A2ATaskStatus(_Wire):
94
+ state: TaskState = "unknown"
95
+
96
+
97
+ class A2ATask(_Wire):
98
+ kind: Literal["task"] = "task"
99
+ id: str = Field(min_length=1)
100
+ context_id: str | None = Field(default=None, alias="contextId")
101
+ status: A2ATaskStatus = Field(default_factory=A2ATaskStatus)
102
+ history: list[A2AMessage] = Field(default_factory=list)
103
+
104
+ @property
105
+ def pending(self) -> bool:
106
+ return self.status.state in PENDING_STATES
107
+
108
+ def last_agent_message(self) -> A2AMessage | None:
109
+ for message in reversed(self.history):
110
+ if message.role != "user":
111
+ return message
112
+ return None