cap-sdk-python 2.0.19__tar.gz → 2.5.2__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.
Files changed (37) hide show
  1. {cap_sdk_python-2.0.19 → cap_sdk_python-2.5.2}/PKG-INFO +6 -1
  2. {cap_sdk_python-2.0.19 → cap_sdk_python-2.5.2}/cap/__init__.py +30 -0
  3. {cap_sdk_python-2.0.19 → cap_sdk_python-2.5.2}/cap/client.py +2 -1
  4. cap_sdk_python-2.5.2/cap/pb/cordum/agent/v1/alert_pb2.py +44 -0
  5. {cap_sdk_python-2.0.19 → cap_sdk_python-2.5.2}/cap/pb/cordum/agent/v1/alert_pb2_grpc.py +1 -1
  6. {cap_sdk_python-2.0.19 → cap_sdk_python-2.5.2}/cap/pb/cordum/agent/v1/buspacket_pb2.py +4 -3
  7. {cap_sdk_python-2.0.19 → cap_sdk_python-2.5.2}/cap/pb/cordum/agent/v1/buspacket_pb2_grpc.py +1 -1
  8. cap_sdk_python-2.5.2/cap/pb/cordum/agent/v1/handshake_pb2.py +43 -0
  9. cap_sdk_python-2.5.2/cap/pb/cordum/agent/v1/handshake_pb2_grpc.py +24 -0
  10. {cap_sdk_python-2.0.19 → cap_sdk_python-2.5.2}/cap/pb/cordum/agent/v1/heartbeat_pb2_grpc.py +1 -1
  11. {cap_sdk_python-2.0.19 → cap_sdk_python-2.5.2}/cap/pb/cordum/agent/v1/job_pb2.py +14 -12
  12. {cap_sdk_python-2.0.19 → cap_sdk_python-2.5.2}/cap/pb/cordum/agent/v1/job_pb2_grpc.py +1 -1
  13. {cap_sdk_python-2.0.19 → cap_sdk_python-2.5.2}/cap/pb/cordum/agent/v1/safety_pb2_grpc.py +1 -1
  14. {cap_sdk_python-2.0.19 → cap_sdk_python-2.5.2}/cap/runtime.py +2 -1
  15. cap_sdk_python-2.5.2/cap/subjects.py +9 -0
  16. cap_sdk_python-2.5.2/cap/validate.py +105 -0
  17. {cap_sdk_python-2.0.19 → cap_sdk_python-2.5.2}/cap/worker.py +7 -3
  18. {cap_sdk_python-2.0.19 → cap_sdk_python-2.5.2}/cap_sdk_python.egg-info/PKG-INFO +6 -1
  19. {cap_sdk_python-2.0.19 → cap_sdk_python-2.5.2}/cap_sdk_python.egg-info/SOURCES.txt +6 -1
  20. {cap_sdk_python-2.0.19 → cap_sdk_python-2.5.2}/cap_sdk_python.egg-info/top_level.txt +0 -1
  21. {cap_sdk_python-2.0.19 → cap_sdk_python-2.5.2}/pyproject.toml +7 -1
  22. {cap_sdk_python-2.0.19 → cap_sdk_python-2.5.2}/tests/test_conformance.py +30 -1
  23. cap_sdk_python-2.5.2/tests/test_validate.py +284 -0
  24. cap_sdk_python-2.0.19/cap/pb/cordum/agent/v1/alert_pb2.py +0 -37
  25. {cap_sdk_python-2.0.19 → cap_sdk_python-2.5.2}/README.md +0 -0
  26. {cap_sdk_python-2.0.19 → cap_sdk_python-2.5.2}/cap/bus.py +0 -0
  27. {cap_sdk_python-2.0.19 → cap_sdk_python-2.5.2}/cap/pb/__init__.py +0 -0
  28. {cap_sdk_python-2.0.19 → cap_sdk_python-2.5.2}/cap/pb/cordum/__init__.py +0 -0
  29. {cap_sdk_python-2.0.19 → cap_sdk_python-2.5.2}/cap/pb/cordum/agent/__init__.py +0 -0
  30. {cap_sdk_python-2.0.19 → cap_sdk_python-2.5.2}/cap/pb/cordum/agent/v1/__init__.py +0 -0
  31. {cap_sdk_python-2.0.19 → cap_sdk_python-2.5.2}/cap/pb/cordum/agent/v1/heartbeat_pb2.py +0 -0
  32. {cap_sdk_python-2.0.19 → cap_sdk_python-2.5.2}/cap/pb/cordum/agent/v1/safety_pb2.py +0 -0
  33. {cap_sdk_python-2.0.19 → cap_sdk_python-2.5.2}/cap_sdk_python.egg-info/dependency_links.txt +0 -0
  34. {cap_sdk_python-2.0.19 → cap_sdk_python-2.5.2}/cap_sdk_python.egg-info/requires.txt +0 -0
  35. {cap_sdk_python-2.0.19 → cap_sdk_python-2.5.2}/setup.cfg +0 -0
  36. {cap_sdk_python-2.0.19 → cap_sdk_python-2.5.2}/tests/test_runtime.py +0 -0
  37. {cap_sdk_python-2.0.19 → cap_sdk_python-2.5.2}/tests/test_sdk.py +0 -0
@@ -1,8 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cap-sdk-python
3
- Version: 2.0.19
3
+ Version: 2.5.2
4
4
  Summary: CAP (Cordum Agent Protocol) Python SDK
5
+ Author-email: Cordum <eng@cordum.io>
6
+ License-Expression: Apache-2.0
5
7
  Project-URL: Homepage, https://github.com/cordum-io/cap
8
+ Project-URL: Repository, https://github.com/cordum-io/cap
9
+ Project-URL: Issues, https://github.com/cordum-io/cap/issues
10
+ Keywords: cap,cordum,agent,protocol,sdk,ai
6
11
  Requires-Python: >=3.9
7
12
  Description-Content-Type: text/markdown
8
13
  Requires-Dist: protobuf>=4.25.0
@@ -27,6 +27,23 @@ from .client import submit_job
27
27
  from .worker import run_worker
28
28
  from .bus import connect_nats
29
29
  from .runtime import Agent, Context, BlobStore, RedisBlobStore, InMemoryBlobStore
30
+ from .validate import (
31
+ ValidationError,
32
+ validate_job_request,
33
+ validate_job_result,
34
+ validate_bus_packet,
35
+ )
36
+ from .subjects import (
37
+ SUBJECT_SUBMIT,
38
+ SUBJECT_RESULT,
39
+ SUBJECT_HEARTBEAT,
40
+ SUBJECT_ALERT,
41
+ SUBJECT_PROGRESS,
42
+ SUBJECT_CANCEL,
43
+ SUBJECT_DLQ,
44
+ SUBJECT_WORKFLOW_EVENT,
45
+ SUBJECT_HANDSHAKE,
46
+ )
30
47
 
31
48
  __all__ = [
32
49
  "submit_job",
@@ -37,4 +54,17 @@ __all__ = [
37
54
  "BlobStore",
38
55
  "RedisBlobStore",
39
56
  "InMemoryBlobStore",
57
+ "ValidationError",
58
+ "validate_job_request",
59
+ "validate_job_result",
60
+ "validate_bus_packet",
61
+ "SUBJECT_SUBMIT",
62
+ "SUBJECT_RESULT",
63
+ "SUBJECT_HEARTBEAT",
64
+ "SUBJECT_ALERT",
65
+ "SUBJECT_PROGRESS",
66
+ "SUBJECT_CANCEL",
67
+ "SUBJECT_DLQ",
68
+ "SUBJECT_WORKFLOW_EVENT",
69
+ "SUBJECT_HANDSHAKE",
40
70
  ]
@@ -5,8 +5,9 @@ from cryptography.hazmat.primitives import hashes
5
5
  from typing import Optional
6
6
 
7
7
 
8
+ from cap.subjects import SUBJECT_SUBMIT
9
+
8
10
  DEFAULT_PROTOCOL_VERSION = 1
9
- SUBJECT_SUBMIT = "sys.job.submit"
10
11
 
11
12
 
12
13
  async def submit_job(
@@ -0,0 +1,44 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # NO CHECKED-IN PROTOBUF GENCODE
4
+ # source: cordum/agent/v1/alert.proto
5
+ # Protobuf Python Version: 6.31.1
6
+ """Generated protocol buffer code."""
7
+ from google.protobuf import descriptor as _descriptor
8
+ from google.protobuf import descriptor_pool as _descriptor_pool
9
+ from google.protobuf import runtime_version as _runtime_version
10
+ from google.protobuf import symbol_database as _symbol_database
11
+ from google.protobuf.internal import builder as _builder
12
+ _runtime_version.ValidateProtobufRuntimeVersion(
13
+ _runtime_version.Domain.PUBLIC,
14
+ 6,
15
+ 31,
16
+ 1,
17
+ '',
18
+ 'cordum/agent/v1/alert.proto'
19
+ )
20
+ # @@protoc_insertion_point(imports)
21
+
22
+ _sym_db = _symbol_database.Default()
23
+
24
+
25
+ from cordum.agent.v1 import job_pb2 as cordum_dot_agent_dot_v1_dot_job__pb2
26
+
27
+
28
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1b\x63ordum/agent/v1/alert.proto\x12\x0f\x63ordum.agent.v1\x1a\x19\x63ordum/agent/v1/job.proto\"\xcd\x02\n\x0bSystemAlert\x12\r\n\x05level\x18\x01 \x01(\t\x12\x0f\n\x07message\x18\x02 \x01(\t\x12\x11\n\tcomponent\x18\x03 \x01(\t\x12\x0c\n\x04\x63ode\x18\x04 \x01(\t\x12\x30\n\x08severity\x18\x05 \x01(\x0e\x32\x1e.cordum.agent.v1.AlertSeverity\x12\x33\n\x0f\x65rror_code_enum\x18\x06 \x01(\x0e\x32\x1a.cordum.agent.v1.ErrorCode\x12\x18\n\x10source_component\x18\x07 \x01(\t\x12:\n\x07\x64\x65tails\x18\x08 \x03(\x0b\x32).cordum.agent.v1.SystemAlert.DetailsEntry\x12\x10\n\x08trace_id\x18\t \x01(\t\x1a.\n\x0c\x44\x65tailsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01*\x9b\x01\n\rAlertSeverity\x12\x1e\n\x1a\x41LERT_SEVERITY_UNSPECIFIED\x10\x00\x12\x17\n\x13\x41LERT_SEVERITY_INFO\x10\x01\x12\x1a\n\x16\x41LERT_SEVERITY_WARNING\x10\x02\x12\x18\n\x14\x41LERT_SEVERITY_ERROR\x10\x03\x12\x1b\n\x17\x41LERT_SEVERITY_CRITICAL\x10\x04\x42\x7f\n\x16io.cordum.cap.agent.v1P\x01Z+github.com/cordum-io/cap/v2/cordum/agent/v1\xaa\x02\x0f\x43ordum.Agent.V1\xca\x02\x0f\x63ordum\\Agent\\V1\xea\x02\x11\x43ordum::Agent::V1b\x06proto3')
29
+
30
+ _globals = globals()
31
+ _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
32
+ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cordum.agent.v1.alert_pb2', _globals)
33
+ if not _descriptor._USE_C_DESCRIPTORS:
34
+ _globals['DESCRIPTOR']._loaded_options = None
35
+ _globals['DESCRIPTOR']._serialized_options = b'\n\026io.cordum.cap.agent.v1P\001Z+github.com/cordum-io/cap/v2/cordum/agent/v1\252\002\017Cordum.Agent.V1\312\002\017cordum\\Agent\\V1\352\002\021Cordum::Agent::V1'
36
+ _globals['_SYSTEMALERT_DETAILSENTRY']._loaded_options = None
37
+ _globals['_SYSTEMALERT_DETAILSENTRY']._serialized_options = b'8\001'
38
+ _globals['_ALERTSEVERITY']._serialized_start=412
39
+ _globals['_ALERTSEVERITY']._serialized_end=567
40
+ _globals['_SYSTEMALERT']._serialized_start=76
41
+ _globals['_SYSTEMALERT']._serialized_end=409
42
+ _globals['_SYSTEMALERT_DETAILSENTRY']._serialized_start=363
43
+ _globals['_SYSTEMALERT_DETAILSENTRY']._serialized_end=409
44
+ # @@protoc_insertion_point(module_scope)
@@ -4,7 +4,7 @@ import grpc
4
4
  import warnings
5
5
 
6
6
 
7
- GRPC_GENERATED_VERSION = '1.76.0'
7
+ GRPC_GENERATED_VERSION = '1.78.0'
8
8
  GRPC_VERSION = grpc.__version__
9
9
  _version_not_supported = False
10
10
 
@@ -26,9 +26,10 @@ from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__
26
26
  from cordum.agent.v1 import job_pb2 as cordum_dot_agent_dot_v1_dot_job__pb2
27
27
  from cordum.agent.v1 import heartbeat_pb2 as cordum_dot_agent_dot_v1_dot_heartbeat__pb2
28
28
  from cordum.agent.v1 import alert_pb2 as cordum_dot_agent_dot_v1_dot_alert__pb2
29
+ from cordum.agent.v1 import handshake_pb2 as cordum_dot_agent_dot_v1_dot_handshake__pb2
29
30
 
30
31
 
31
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1f\x63ordum/agent/v1/buspacket.proto\x12\x0f\x63ordum.agent.v1\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x19\x63ordum/agent/v1/job.proto\x1a\x1f\x63ordum/agent/v1/heartbeat.proto\x1a\x1b\x63ordum/agent/v1/alert.proto\"\xc6\x03\n\tBusPacket\x12\x10\n\x08trace_id\x18\x01 \x01(\t\x12\x11\n\tsender_id\x18\x02 \x01(\t\x12.\n\ncreated_at\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x18\n\x10protocol_version\x18\x04 \x01(\x05\x12\x32\n\x0bjob_request\x18\n \x01(\x0b\x32\x1b.cordum.agent.v1.JobRequestH\x00\x12\x30\n\njob_result\x18\x0b \x01(\x0b\x32\x1a.cordum.agent.v1.JobResultH\x00\x12/\n\theartbeat\x18\x0c \x01(\x0b\x32\x1a.cordum.agent.v1.HeartbeatH\x00\x12-\n\x05\x61lert\x18\r \x01(\x0b\x32\x1c.cordum.agent.v1.SystemAlertH\x00\x12\x34\n\x0cjob_progress\x18\x0f \x01(\x0b\x32\x1c.cordum.agent.v1.JobProgressH\x00\x12\x30\n\njob_cancel\x18\x10 \x01(\x0b\x32\x1a.cordum.agent.v1.JobCancelH\x00\x12\x11\n\tsignature\x18\x0e \x01(\x0c\x42\t\n\x07payloadB\x7f\n\x16io.cordum.cap.agent.v1P\x01Z+github.com/cordum-io/cap/v2/cordum/agent/v1\xaa\x02\x0f\x43ordum.Agent.V1\xca\x02\x0f\x63ordum\\Agent\\V1\xea\x02\x11\x43ordum::Agent::V1b\x06proto3')
32
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1f\x63ordum/agent/v1/buspacket.proto\x12\x0f\x63ordum.agent.v1\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x19\x63ordum/agent/v1/job.proto\x1a\x1f\x63ordum/agent/v1/heartbeat.proto\x1a\x1b\x63ordum/agent/v1/alert.proto\x1a\x1f\x63ordum/agent/v1/handshake.proto\"\xf7\x03\n\tBusPacket\x12\x10\n\x08trace_id\x18\x01 \x01(\t\x12\x11\n\tsender_id\x18\x02 \x01(\t\x12.\n\ncreated_at\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x18\n\x10protocol_version\x18\x04 \x01(\x05\x12\x32\n\x0bjob_request\x18\n \x01(\x0b\x32\x1b.cordum.agent.v1.JobRequestH\x00\x12\x30\n\njob_result\x18\x0b \x01(\x0b\x32\x1a.cordum.agent.v1.JobResultH\x00\x12/\n\theartbeat\x18\x0c \x01(\x0b\x32\x1a.cordum.agent.v1.HeartbeatH\x00\x12-\n\x05\x61lert\x18\r \x01(\x0b\x32\x1c.cordum.agent.v1.SystemAlertH\x00\x12\x34\n\x0cjob_progress\x18\x0f \x01(\x0b\x32\x1c.cordum.agent.v1.JobProgressH\x00\x12\x30\n\njob_cancel\x18\x10 \x01(\x0b\x32\x1a.cordum.agent.v1.JobCancelH\x00\x12/\n\thandshake\x18\x11 \x01(\x0b\x32\x1a.cordum.agent.v1.HandshakeH\x00\x12\x11\n\tsignature\x18\x0e \x01(\x0c\x42\t\n\x07payloadB\x7f\n\x16io.cordum.cap.agent.v1P\x01Z+github.com/cordum-io/cap/v2/cordum/agent/v1\xaa\x02\x0f\x43ordum.Agent.V1\xca\x02\x0f\x63ordum\\Agent\\V1\xea\x02\x11\x43ordum::Agent::V1b\x06proto3')
32
33
 
33
34
  _globals = globals()
34
35
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -36,6 +37,6 @@ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cordum.agent.v1.buspacket_p
36
37
  if not _descriptor._USE_C_DESCRIPTORS:
37
38
  _globals['DESCRIPTOR']._loaded_options = None
38
39
  _globals['DESCRIPTOR']._serialized_options = b'\n\026io.cordum.cap.agent.v1P\001Z+github.com/cordum-io/cap/v2/cordum/agent/v1\252\002\017Cordum.Agent.V1\312\002\017cordum\\Agent\\V1\352\002\021Cordum::Agent::V1'
39
- _globals['_BUSPACKET']._serialized_start=175
40
- _globals['_BUSPACKET']._serialized_end=629
40
+ _globals['_BUSPACKET']._serialized_start=208
41
+ _globals['_BUSPACKET']._serialized_end=711
41
42
  # @@protoc_insertion_point(module_scope)
@@ -4,7 +4,7 @@ import grpc
4
4
  import warnings
5
5
 
6
6
 
7
- GRPC_GENERATED_VERSION = '1.76.0'
7
+ GRPC_GENERATED_VERSION = '1.78.0'
8
8
  GRPC_VERSION = grpc.__version__
9
9
  _version_not_supported = False
10
10
 
@@ -0,0 +1,43 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # NO CHECKED-IN PROTOBUF GENCODE
4
+ # source: cordum/agent/v1/handshake.proto
5
+ # Protobuf Python Version: 6.31.1
6
+ """Generated protocol buffer code."""
7
+ from google.protobuf import descriptor as _descriptor
8
+ from google.protobuf import descriptor_pool as _descriptor_pool
9
+ from google.protobuf import runtime_version as _runtime_version
10
+ from google.protobuf import symbol_database as _symbol_database
11
+ from google.protobuf.internal import builder as _builder
12
+ _runtime_version.ValidateProtobufRuntimeVersion(
13
+ _runtime_version.Domain.PUBLIC,
14
+ 6,
15
+ 31,
16
+ 1,
17
+ '',
18
+ 'cordum/agent/v1/handshake.proto'
19
+ )
20
+ # @@protoc_insertion_point(imports)
21
+
22
+ _sym_db = _symbol_database.Default()
23
+
24
+
25
+
26
+
27
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1f\x63ordum/agent/v1/handshake.proto\x12\x0f\x63ordum.agent.v1\"\xf9\x01\n\tHandshake\x12\x14\n\x0c\x63omponent_id\x18\x01 \x01(\t\x12,\n\x04role\x18\x02 \x01(\x0e\x32\x1e.cordum.agent.v1.ComponentRole\x12\x1a\n\x12supported_versions\x18\x03 \x03(\x05\x12\x42\n\x0c\x63\x61pabilities\x18\x04 \x03(\x0b\x32,.cordum.agent.v1.Handshake.CapabilitiesEntry\x12\x13\n\x0bsdk_version\x18\x05 \x01(\t\x1a\x33\n\x11\x43\x61pabilitiesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x08:\x02\x38\x01*\xc4\x01\n\rComponentRole\x12\x1e\n\x1a\x43OMPONENT_ROLE_UNSPECIFIED\x10\x00\x12\x1a\n\x16\x43OMPONENT_ROLE_GATEWAY\x10\x01\x12\x1c\n\x18\x43OMPONENT_ROLE_SCHEDULER\x10\x02\x12\x19\n\x15\x43OMPONENT_ROLE_WORKER\x10\x03\x12\x1f\n\x1b\x43OMPONENT_ROLE_ORCHESTRATOR\x10\x04\x12\x1d\n\x19\x43OMPONENT_ROLE_CONTROLLER\x10\x05\x42\x7f\n\x16io.cordum.cap.agent.v1P\x01Z+github.com/cordum-io/cap/v2/cordum/agent/v1\xaa\x02\x0f\x43ordum.Agent.V1\xca\x02\x0f\x63ordum\\Agent\\V1\xea\x02\x11\x43ordum::Agent::V1b\x06proto3')
28
+
29
+ _globals = globals()
30
+ _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
31
+ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cordum.agent.v1.handshake_pb2', _globals)
32
+ if not _descriptor._USE_C_DESCRIPTORS:
33
+ _globals['DESCRIPTOR']._loaded_options = None
34
+ _globals['DESCRIPTOR']._serialized_options = b'\n\026io.cordum.cap.agent.v1P\001Z+github.com/cordum-io/cap/v2/cordum/agent/v1\252\002\017Cordum.Agent.V1\312\002\017cordum\\Agent\\V1\352\002\021Cordum::Agent::V1'
35
+ _globals['_HANDSHAKE_CAPABILITIESENTRY']._loaded_options = None
36
+ _globals['_HANDSHAKE_CAPABILITIESENTRY']._serialized_options = b'8\001'
37
+ _globals['_COMPONENTROLE']._serialized_start=305
38
+ _globals['_COMPONENTROLE']._serialized_end=501
39
+ _globals['_HANDSHAKE']._serialized_start=53
40
+ _globals['_HANDSHAKE']._serialized_end=302
41
+ _globals['_HANDSHAKE_CAPABILITIESENTRY']._serialized_start=251
42
+ _globals['_HANDSHAKE_CAPABILITIESENTRY']._serialized_end=302
43
+ # @@protoc_insertion_point(module_scope)
@@ -0,0 +1,24 @@
1
+ # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
2
+ """Client and server classes corresponding to protobuf-defined services."""
3
+ import grpc
4
+ import warnings
5
+
6
+
7
+ GRPC_GENERATED_VERSION = '1.78.0'
8
+ GRPC_VERSION = grpc.__version__
9
+ _version_not_supported = False
10
+
11
+ try:
12
+ from grpc._utilities import first_version_is_lower
13
+ _version_not_supported = first_version_is_lower(GRPC_VERSION, GRPC_GENERATED_VERSION)
14
+ except ImportError:
15
+ _version_not_supported = True
16
+
17
+ if _version_not_supported:
18
+ raise RuntimeError(
19
+ f'The grpc package installed is at version {GRPC_VERSION},'
20
+ + ' but the generated code in cordum/agent/v1/handshake_pb2_grpc.py depends on'
21
+ + f' grpcio>={GRPC_GENERATED_VERSION}.'
22
+ + f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}'
23
+ + f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.'
24
+ )
@@ -4,7 +4,7 @@ import grpc
4
4
  import warnings
5
5
 
6
6
 
7
- GRPC_GENERATED_VERSION = '1.76.0'
7
+ GRPC_GENERATED_VERSION = '1.78.0'
8
8
  GRPC_VERSION = grpc.__version__
9
9
  _version_not_supported = False
10
10
 
@@ -24,7 +24,7 @@ _sym_db = _symbol_database.Default()
24
24
 
25
25
 
26
26
 
27
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x19\x63ordum/agent/v1/job.proto\x12\x0f\x63ordum.agent.v1\"l\n\x0c\x43ontextHints\x12\x18\n\x10max_input_tokens\x18\x01 \x01(\x05\x12\x1b\n\x13\x61llow_summarization\x18\x02 \x01(\x08\x12\x17\n\x0f\x61llow_retrieval\x18\x03 \x01(\x08\x12\x0c\n\x04tags\x18\x04 \x03(\t\"l\n\x06\x42udget\x12\x18\n\x10max_input_tokens\x18\x01 \x01(\x03\x12\x19\n\x11max_output_tokens\x18\x02 \x01(\x03\x12\x18\n\x10max_total_tokens\x18\x03 \x01(\x03\x12\x13\n\x0b\x64\x65\x61\x64line_ms\x18\x04 \x01(\x03\"\xae\x02\n\x0bJobMetadata\x12\x11\n\ttenant_id\x18\x01 \x01(\t\x12\x10\n\x08\x61\x63tor_id\x18\x02 \x01(\t\x12.\n\nactor_type\x18\x03 \x01(\x0e\x32\x1a.cordum.agent.v1.ActorType\x12\x17\n\x0fidempotency_key\x18\x04 \x01(\t\x12\x12\n\ncapability\x18\x05 \x01(\t\x12\x11\n\trisk_tags\x18\x06 \x03(\t\x12\x10\n\x08requires\x18\x07 \x03(\t\x12\x0f\n\x07pack_id\x18\x08 \x01(\t\x12\x38\n\x06labels\x18\t \x03(\x0b\x32(.cordum.agent.v1.JobMetadata.LabelsEntry\x1a-\n\x0bLabelsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x88\x04\n\x0c\x43ompensation\x12\r\n\x05topic\x18\x01 \x01(\t\x12\x13\n\x0b\x63ontext_ptr\x18\x02 \x01(\t\x12.\n\x08priority\x18\x03 \x01(\x0e\x32\x1c.cordum.agent.v1.JobPriority\x12\x12\n\nadapter_id\x18\x04 \x01(\t\x12\x33\n\x03\x65nv\x18\x05 \x03(\x0b\x32&.cordum.agent.v1.Compensation.EnvEntry\x12\x11\n\tmemory_id\x18\x06 \x01(\t\x12\x34\n\rcontext_hints\x18\x07 \x01(\x0b\x32\x1d.cordum.agent.v1.ContextHints\x12\'\n\x06\x62udget\x18\x08 \x01(\x0b\x32\x17.cordum.agent.v1.Budget\x12\x11\n\ttenant_id\x18\t \x01(\t\x12\x14\n\x0cprincipal_id\x18\n \x01(\t\x12\x39\n\x06labels\x18\x0b \x03(\x0b\x32).cordum.agent.v1.Compensation.LabelsEntry\x12*\n\x04meta\x18\x0c \x01(\x0b\x32\x1c.cordum.agent.v1.JobMetadata\x1a*\n\x08\x45nvEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a-\n\x0bLabelsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x87\x05\n\nJobRequest\x12\x0e\n\x06job_id\x18\x01 \x01(\t\x12\r\n\x05topic\x18\x02 \x01(\t\x12.\n\x08priority\x18\x03 \x01(\x0e\x32\x1c.cordum.agent.v1.JobPriority\x12\x13\n\x0b\x63ontext_ptr\x18\x04 \x01(\t\x12\x12\n\nadapter_id\x18\x05 \x01(\t\x12\x31\n\x03\x65nv\x18\x06 \x03(\x0b\x32$.cordum.agent.v1.JobRequest.EnvEntry\x12\x15\n\rparent_job_id\x18\x07 \x01(\t\x12\x13\n\x0bworkflow_id\x18\x08 \x01(\t\x12\x12\n\nstep_index\x18\t \x01(\x05\x12\x11\n\tmemory_id\x18\n \x01(\t\x12\x34\n\rcontext_hints\x18\x0b \x01(\x0b\x32\x1d.cordum.agent.v1.ContextHints\x12\'\n\x06\x62udget\x18\x0c \x01(\x0b\x32\x17.cordum.agent.v1.Budget\x12\x11\n\ttenant_id\x18\r \x01(\t\x12\x14\n\x0cprincipal_id\x18\x0e \x01(\t\x12\x37\n\x06labels\x18\x0f \x03(\x0b\x32\'.cordum.agent.v1.JobRequest.LabelsEntry\x12*\n\x04meta\x18\x10 \x01(\x0b\x32\x1c.cordum.agent.v1.JobMetadata\x12\x33\n\x0c\x63ompensation\x18\x11 \x01(\x0b\x32\x1d.cordum.agent.v1.Compensation\x1a*\n\x08\x45nvEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a-\n\x0bLabelsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xc6\x01\n\tJobResult\x12\x0e\n\x06job_id\x18\x01 \x01(\t\x12*\n\x06status\x18\x02 \x01(\x0e\x32\x1a.cordum.agent.v1.JobStatus\x12\x12\n\nresult_ptr\x18\x03 \x01(\t\x12\x11\n\tworker_id\x18\x04 \x01(\t\x12\x14\n\x0c\x65xecution_ms\x18\x05 \x01(\x03\x12\x12\n\nerror_code\x18\x06 \x01(\t\x12\x15\n\rerror_message\x18\x07 \x01(\t\x12\x15\n\rartifact_ptrs\x18\x08 \x03(\t\"\xa7\x01\n\x0bJobProgress\x12\x0e\n\x06job_id\x18\x01 \x01(\t\x12\x0f\n\x07step_id\x18\x02 \x01(\t\x12\x0f\n\x07percent\x18\x03 \x01(\x05\x12\x0f\n\x07message\x18\x04 \x01(\t\x12\x12\n\nresult_ptr\x18\x05 \x01(\t\x12\x15\n\rartifact_ptrs\x18\x06 \x03(\t\x12*\n\x06status\x18\x07 \x01(\x0e\x32\x1a.cordum.agent.v1.JobStatus\"A\n\tJobCancel\x12\x0e\n\x06job_id\x18\x01 \x01(\t\x12\x0e\n\x06reason\x18\x02 \x01(\t\x12\x14\n\x0crequested_by\x18\x03 \x01(\t*|\n\x0bJobPriority\x12\x1c\n\x18JOB_PRIORITY_UNSPECIFIED\x10\x00\x12\x1c\n\x18JOB_PRIORITY_INTERACTIVE\x10\x01\x12\x16\n\x12JOB_PRIORITY_BATCH\x10\x02\x12\x19\n\x15JOB_PRIORITY_CRITICAL\x10\x03*\xc4\x02\n\tJobStatus\x12\x1a\n\x16JOB_STATUS_UNSPECIFIED\x10\x00\x12\x16\n\x12JOB_STATUS_PENDING\x10\x01\x12\x18\n\x14JOB_STATUS_SCHEDULED\x10\x02\x12\x19\n\x15JOB_STATUS_DISPATCHED\x10\x03\x12\x16\n\x12JOB_STATUS_RUNNING\x10\x04\x12\x18\n\x14JOB_STATUS_SUCCEEDED\x10\x05\x12\x15\n\x11JOB_STATUS_FAILED\x10\x06\x12\x18\n\x14JOB_STATUS_CANCELLED\x10\x07\x12\x15\n\x11JOB_STATUS_DENIED\x10\x08\x12\x16\n\x12JOB_STATUS_TIMEOUT\x10\t\x12\x1f\n\x1bJOB_STATUS_FAILED_RETRYABLE\x10\n\x12\x1b\n\x17JOB_STATUS_FAILED_FATAL\x10\x0b*U\n\tActorType\x12\x1a\n\x16\x41\x43TOR_TYPE_UNSPECIFIED\x10\x00\x12\x14\n\x10\x41\x43TOR_TYPE_HUMAN\x10\x01\x12\x16\n\x12\x41\x43TOR_TYPE_SERVICE\x10\x02\x42\x7f\n\x16io.cordum.cap.agent.v1P\x01Z+github.com/cordum-io/cap/v2/cordum/agent/v1\xaa\x02\x0f\x43ordum.Agent.V1\xca\x02\x0f\x63ordum\\Agent\\V1\xea\x02\x11\x43ordum::Agent::V1b\x06proto3')
27
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x19\x63ordum/agent/v1/job.proto\x12\x0f\x63ordum.agent.v1\"l\n\x0c\x43ontextHints\x12\x18\n\x10max_input_tokens\x18\x01 \x01(\x05\x12\x1b\n\x13\x61llow_summarization\x18\x02 \x01(\x08\x12\x17\n\x0f\x61llow_retrieval\x18\x03 \x01(\x08\x12\x0c\n\x04tags\x18\x04 \x03(\t\"l\n\x06\x42udget\x12\x18\n\x10max_input_tokens\x18\x01 \x01(\x03\x12\x19\n\x11max_output_tokens\x18\x02 \x01(\x03\x12\x18\n\x10max_total_tokens\x18\x03 \x01(\x03\x12\x13\n\x0b\x64\x65\x61\x64line_ms\x18\x04 \x01(\x03\"\xae\x02\n\x0bJobMetadata\x12\x11\n\ttenant_id\x18\x01 \x01(\t\x12\x10\n\x08\x61\x63tor_id\x18\x02 \x01(\t\x12.\n\nactor_type\x18\x03 \x01(\x0e\x32\x1a.cordum.agent.v1.ActorType\x12\x17\n\x0fidempotency_key\x18\x04 \x01(\t\x12\x12\n\ncapability\x18\x05 \x01(\t\x12\x11\n\trisk_tags\x18\x06 \x03(\t\x12\x10\n\x08requires\x18\x07 \x03(\t\x12\x0f\n\x07pack_id\x18\x08 \x01(\t\x12\x38\n\x06labels\x18\t \x03(\x0b\x32(.cordum.agent.v1.JobMetadata.LabelsEntry\x1a-\n\x0bLabelsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x88\x04\n\x0c\x43ompensation\x12\r\n\x05topic\x18\x01 \x01(\t\x12\x13\n\x0b\x63ontext_ptr\x18\x02 \x01(\t\x12.\n\x08priority\x18\x03 \x01(\x0e\x32\x1c.cordum.agent.v1.JobPriority\x12\x12\n\nadapter_id\x18\x04 \x01(\t\x12\x33\n\x03\x65nv\x18\x05 \x03(\x0b\x32&.cordum.agent.v1.Compensation.EnvEntry\x12\x11\n\tmemory_id\x18\x06 \x01(\t\x12\x34\n\rcontext_hints\x18\x07 \x01(\x0b\x32\x1d.cordum.agent.v1.ContextHints\x12\'\n\x06\x62udget\x18\x08 \x01(\x0b\x32\x17.cordum.agent.v1.Budget\x12\x11\n\ttenant_id\x18\t \x01(\t\x12\x14\n\x0cprincipal_id\x18\n \x01(\t\x12\x39\n\x06labels\x18\x0b \x03(\x0b\x32).cordum.agent.v1.Compensation.LabelsEntry\x12*\n\x04meta\x18\x0c \x01(\x0b\x32\x1c.cordum.agent.v1.JobMetadata\x1a*\n\x08\x45nvEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a-\n\x0bLabelsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x87\x05\n\nJobRequest\x12\x0e\n\x06job_id\x18\x01 \x01(\t\x12\r\n\x05topic\x18\x02 \x01(\t\x12.\n\x08priority\x18\x03 \x01(\x0e\x32\x1c.cordum.agent.v1.JobPriority\x12\x13\n\x0b\x63ontext_ptr\x18\x04 \x01(\t\x12\x12\n\nadapter_id\x18\x05 \x01(\t\x12\x31\n\x03\x65nv\x18\x06 \x03(\x0b\x32$.cordum.agent.v1.JobRequest.EnvEntry\x12\x15\n\rparent_job_id\x18\x07 \x01(\t\x12\x13\n\x0bworkflow_id\x18\x08 \x01(\t\x12\x12\n\nstep_index\x18\t \x01(\x05\x12\x11\n\tmemory_id\x18\n \x01(\t\x12\x34\n\rcontext_hints\x18\x0b \x01(\x0b\x32\x1d.cordum.agent.v1.ContextHints\x12\'\n\x06\x62udget\x18\x0c \x01(\x0b\x32\x17.cordum.agent.v1.Budget\x12\x11\n\ttenant_id\x18\r \x01(\t\x12\x14\n\x0cprincipal_id\x18\x0e \x01(\t\x12\x37\n\x06labels\x18\x0f \x03(\x0b\x32\'.cordum.agent.v1.JobRequest.LabelsEntry\x12*\n\x04meta\x18\x10 \x01(\x0b\x32\x1c.cordum.agent.v1.JobMetadata\x12\x33\n\x0c\x63ompensation\x18\x11 \x01(\x0b\x32\x1d.cordum.agent.v1.Compensation\x1a*\n\x08\x45nvEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a-\n\x0bLabelsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xfb\x01\n\tJobResult\x12\x0e\n\x06job_id\x18\x01 \x01(\t\x12*\n\x06status\x18\x02 \x01(\x0e\x32\x1a.cordum.agent.v1.JobStatus\x12\x12\n\nresult_ptr\x18\x03 \x01(\t\x12\x11\n\tworker_id\x18\x04 \x01(\t\x12\x14\n\x0c\x65xecution_ms\x18\x05 \x01(\x03\x12\x12\n\nerror_code\x18\x06 \x01(\t\x12\x15\n\rerror_message\x18\x07 \x01(\t\x12\x15\n\rartifact_ptrs\x18\x08 \x03(\t\x12\x33\n\x0f\x65rror_code_enum\x18\t \x01(\x0e\x32\x1a.cordum.agent.v1.ErrorCode\"\xa7\x01\n\x0bJobProgress\x12\x0e\n\x06job_id\x18\x01 \x01(\t\x12\x0f\n\x07step_id\x18\x02 \x01(\t\x12\x0f\n\x07percent\x18\x03 \x01(\x05\x12\x0f\n\x07message\x18\x04 \x01(\t\x12\x12\n\nresult_ptr\x18\x05 \x01(\t\x12\x15\n\rartifact_ptrs\x18\x06 \x03(\t\x12*\n\x06status\x18\x07 \x01(\x0e\x32\x1a.cordum.agent.v1.JobStatus\"A\n\tJobCancel\x12\x0e\n\x06job_id\x18\x01 \x01(\t\x12\x0e\n\x06reason\x18\x02 \x01(\t\x12\x14\n\x0crequested_by\x18\x03 \x01(\t*|\n\x0bJobPriority\x12\x1c\n\x18JOB_PRIORITY_UNSPECIFIED\x10\x00\x12\x1c\n\x18JOB_PRIORITY_INTERACTIVE\x10\x01\x12\x16\n\x12JOB_PRIORITY_BATCH\x10\x02\x12\x19\n\x15JOB_PRIORITY_CRITICAL\x10\x03*\xc4\x02\n\tJobStatus\x12\x1a\n\x16JOB_STATUS_UNSPECIFIED\x10\x00\x12\x16\n\x12JOB_STATUS_PENDING\x10\x01\x12\x18\n\x14JOB_STATUS_SCHEDULED\x10\x02\x12\x19\n\x15JOB_STATUS_DISPATCHED\x10\x03\x12\x16\n\x12JOB_STATUS_RUNNING\x10\x04\x12\x18\n\x14JOB_STATUS_SUCCEEDED\x10\x05\x12\x15\n\x11JOB_STATUS_FAILED\x10\x06\x12\x18\n\x14JOB_STATUS_CANCELLED\x10\x07\x12\x15\n\x11JOB_STATUS_DENIED\x10\x08\x12\x16\n\x12JOB_STATUS_TIMEOUT\x10\t\x12\x1f\n\x1bJOB_STATUS_FAILED_RETRYABLE\x10\n\x12\x1b\n\x17JOB_STATUS_FAILED_FATAL\x10\x0b*U\n\tActorType\x12\x1a\n\x16\x41\x43TOR_TYPE_UNSPECIFIED\x10\x00\x12\x14\n\x10\x41\x43TOR_TYPE_HUMAN\x10\x01\x12\x16\n\x12\x41\x43TOR_TYPE_SERVICE\x10\x02*\xe1\x05\n\tErrorCode\x12\x1a\n\x16\x45RROR_CODE_UNSPECIFIED\x10\x00\x12(\n$ERROR_CODE_PROTOCOL_VERSION_MISMATCH\x10\x64\x12(\n$ERROR_CODE_PROTOCOL_MALFORMED_PACKET\x10\x65\x12\'\n#ERROR_CODE_PROTOCOL_UNKNOWN_PAYLOAD\x10\x66\x12)\n%ERROR_CODE_PROTOCOL_SIGNATURE_INVALID\x10g\x12)\n%ERROR_CODE_PROTOCOL_SIGNATURE_MISSING\x10h\x12\x1b\n\x16\x45RROR_CODE_JOB_TIMEOUT\x10\xc8\x01\x12&\n!ERROR_CODE_JOB_RESOURCE_EXHAUSTED\x10\xc9\x01\x12%\n ERROR_CODE_JOB_PERMISSION_DENIED\x10\xca\x01\x12!\n\x1c\x45RROR_CODE_JOB_INVALID_INPUT\x10\xcb\x01\x12\x1d\n\x18\x45RROR_CODE_JOB_NOT_FOUND\x10\xcc\x01\x12\x1d\n\x18\x45RROR_CODE_JOB_DUPLICATE\x10\xcd\x01\x12&\n!ERROR_CODE_JOB_WORKER_UNAVAILABLE\x10\xce\x01\x12\x1d\n\x18\x45RROR_CODE_SAFETY_DENIED\x10\xac\x02\x12\'\n\"ERROR_CODE_SAFETY_POLICY_VIOLATION\x10\xad\x02\x12\'\n\"ERROR_CODE_SAFETY_RISK_TAG_BLOCKED\x10\xae\x02\x12(\n#ERROR_CODE_TRANSPORT_PUBLISH_FAILED\x10\x90\x03\x12*\n%ERROR_CODE_TRANSPORT_SUBSCRIBE_FAILED\x10\x91\x03\x12)\n$ERROR_CODE_TRANSPORT_CONNECTION_LOST\x10\x92\x03\x42\x7f\n\x16io.cordum.cap.agent.v1P\x01Z+github.com/cordum-io/cap/v2/cordum/agent/v1\xaa\x02\x0f\x43ordum.Agent.V1\xca\x02\x0f\x63ordum\\Agent\\V1\xea\x02\x11\x43ordum::Agent::V1b\x06proto3')
28
28
 
29
29
  _globals = globals()
30
30
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -42,12 +42,14 @@ if not _descriptor._USE_C_DESCRIPTORS:
42
42
  _globals['_JOBREQUEST_ENVENTRY']._serialized_options = b'8\001'
43
43
  _globals['_JOBREQUEST_LABELSENTRY']._loaded_options = None
44
44
  _globals['_JOBREQUEST_LABELSENTRY']._serialized_options = b'8\001'
45
- _globals['_JOBPRIORITY']._serialized_start=2182
46
- _globals['_JOBPRIORITY']._serialized_end=2306
47
- _globals['_JOBSTATUS']._serialized_start=2309
48
- _globals['_JOBSTATUS']._serialized_end=2633
49
- _globals['_ACTORTYPE']._serialized_start=2635
50
- _globals['_ACTORTYPE']._serialized_end=2720
45
+ _globals['_JOBPRIORITY']._serialized_start=2235
46
+ _globals['_JOBPRIORITY']._serialized_end=2359
47
+ _globals['_JOBSTATUS']._serialized_start=2362
48
+ _globals['_JOBSTATUS']._serialized_end=2686
49
+ _globals['_ACTORTYPE']._serialized_start=2688
50
+ _globals['_ACTORTYPE']._serialized_end=2773
51
+ _globals['_ERRORCODE']._serialized_start=2776
52
+ _globals['_ERRORCODE']._serialized_end=3513
51
53
  _globals['_CONTEXTHINTS']._serialized_start=46
52
54
  _globals['_CONTEXTHINTS']._serialized_end=154
53
55
  _globals['_BUDGET']._serialized_start=156
@@ -69,9 +71,9 @@ if not _descriptor._USE_C_DESCRIPTORS:
69
71
  _globals['_JOBREQUEST_LABELSENTRY']._serialized_start=524
70
72
  _globals['_JOBREQUEST_LABELSENTRY']._serialized_end=569
71
73
  _globals['_JOBRESULT']._serialized_start=1745
72
- _globals['_JOBRESULT']._serialized_end=1943
73
- _globals['_JOBPROGRESS']._serialized_start=1946
74
- _globals['_JOBPROGRESS']._serialized_end=2113
75
- _globals['_JOBCANCEL']._serialized_start=2115
76
- _globals['_JOBCANCEL']._serialized_end=2180
74
+ _globals['_JOBRESULT']._serialized_end=1996
75
+ _globals['_JOBPROGRESS']._serialized_start=1999
76
+ _globals['_JOBPROGRESS']._serialized_end=2166
77
+ _globals['_JOBCANCEL']._serialized_start=2168
78
+ _globals['_JOBCANCEL']._serialized_end=2233
77
79
  # @@protoc_insertion_point(module_scope)
@@ -4,7 +4,7 @@ import grpc
4
4
  import warnings
5
5
 
6
6
 
7
- GRPC_GENERATED_VERSION = '1.76.0'
7
+ GRPC_GENERATED_VERSION = '1.78.0'
8
8
  GRPC_VERSION = grpc.__version__
9
9
  _version_not_supported = False
10
10
 
@@ -5,7 +5,7 @@ import warnings
5
5
 
6
6
  from cordum.agent.v1 import safety_pb2 as cordum_dot_agent_dot_v1_dot_safety__pb2
7
7
 
8
- GRPC_GENERATED_VERSION = '1.76.0'
8
+ GRPC_GENERATED_VERSION = '1.78.0'
9
9
  GRPC_VERSION = grpc.__version__
10
10
  _version_not_supported = False
11
11
 
@@ -23,8 +23,9 @@ except Exception: # pragma: no cover - optional until runtime used
23
23
  ValidationError = Exception
24
24
 
25
25
 
26
+ from cap.subjects import SUBJECT_RESULT
27
+
26
28
  DEFAULT_PROTOCOL_VERSION = 1
27
- SUBJECT_RESULT = "sys.job.result"
28
29
 
29
30
 
30
31
  class BlobStore(Protocol):
@@ -0,0 +1,9 @@
1
+ SUBJECT_SUBMIT = "sys.job.submit"
2
+ SUBJECT_RESULT = "sys.job.result"
3
+ SUBJECT_HEARTBEAT = "sys.heartbeat"
4
+ SUBJECT_ALERT = "sys.alert"
5
+ SUBJECT_PROGRESS = "sys.job.progress"
6
+ SUBJECT_CANCEL = "sys.job.cancel"
7
+ SUBJECT_DLQ = "sys.job.dlq"
8
+ SUBJECT_WORKFLOW_EVENT = "sys.workflow.event"
9
+ SUBJECT_HANDSHAKE = "sys.handshake"
@@ -0,0 +1,105 @@
1
+ """Opt-in validation helpers for CAP protobuf messages.
2
+
3
+ Each function accepts a protobuf message object and returns a list of
4
+ ValidationError instances. An empty list means the message is valid.
5
+ """
6
+
7
+ from dataclasses import dataclass
8
+ from typing import Any, List
9
+
10
+ from cap.pb.cordum.agent.v1 import buspacket_pb2, job_pb2
11
+
12
+ # Max known JobPriority enum value.
13
+ _JOB_PRIORITY_MAX = job_pb2.JOB_PRIORITY_CRITICAL # 3
14
+
15
+
16
+ @dataclass(frozen=True)
17
+ class ValidationError:
18
+ """A single validation failure."""
19
+
20
+ field: str
21
+ message: str
22
+
23
+
24
+ def validate_job_request(msg: Any) -> List[ValidationError]:
25
+ """Validate semantic constraints on a JobRequest."""
26
+ errors: List[ValidationError] = []
27
+ if msg is None:
28
+ errors.append(ValidationError("JobRequest", "must not be nil"))
29
+ return errors
30
+ if not msg.job_id:
31
+ errors.append(ValidationError("job_id", "must not be empty"))
32
+ if not msg.topic:
33
+ errors.append(ValidationError("topic", "must not be empty"))
34
+ if msg.priority < 0 or msg.priority > _JOB_PRIORITY_MAX:
35
+ errors.append(
36
+ ValidationError("priority", f"invalid value {msg.priority}")
37
+ )
38
+ if msg.step_index < 0:
39
+ errors.append(ValidationError("step_index", "must not be negative"))
40
+ if msg.HasField("budget"):
41
+ b = msg.budget
42
+ if b.max_input_tokens < 0:
43
+ errors.append(
44
+ ValidationError("budget.max_input_tokens", "must not be negative")
45
+ )
46
+ if b.max_output_tokens < 0:
47
+ errors.append(
48
+ ValidationError("budget.max_output_tokens", "must not be negative")
49
+ )
50
+ if b.max_total_tokens < 0:
51
+ errors.append(
52
+ ValidationError("budget.max_total_tokens", "must not be negative")
53
+ )
54
+ if b.deadline_ms < 0:
55
+ errors.append(
56
+ ValidationError("budget.deadline_ms", "must not be negative")
57
+ )
58
+ return errors
59
+
60
+
61
+ def validate_job_result(msg: Any) -> List[ValidationError]:
62
+ """Validate semantic constraints on a JobResult."""
63
+ errors: List[ValidationError] = []
64
+ if msg is None:
65
+ errors.append(ValidationError("JobResult", "must not be nil"))
66
+ return errors
67
+ if not msg.job_id:
68
+ errors.append(ValidationError("job_id", "must not be empty"))
69
+ if msg.status == job_pb2.JOB_STATUS_UNSPECIFIED:
70
+ errors.append(ValidationError("status", "must not be UNSPECIFIED"))
71
+ if not msg.worker_id:
72
+ errors.append(ValidationError("worker_id", "must not be empty"))
73
+ if msg.execution_ms < 0:
74
+ errors.append(
75
+ ValidationError("execution_ms", "must not be negative")
76
+ )
77
+ return errors
78
+
79
+
80
+ def validate_bus_packet(msg: Any) -> List[ValidationError]:
81
+ """Validate semantic constraints on a BusPacket.
82
+
83
+ If the packet carries a JobRequest or JobResult payload,
84
+ it is also validated.
85
+ """
86
+ errors: List[ValidationError] = []
87
+ if msg is None:
88
+ errors.append(ValidationError("BusPacket", "must not be nil"))
89
+ return errors
90
+ if not msg.trace_id:
91
+ errors.append(ValidationError("trace_id", "must not be empty"))
92
+ if not msg.sender_id:
93
+ errors.append(ValidationError("sender_id", "must not be empty"))
94
+ if msg.protocol_version <= 0:
95
+ errors.append(ValidationError("protocol_version", "must be > 0"))
96
+ if not msg.HasField("created_at"):
97
+ errors.append(ValidationError("created_at", "must not be nil"))
98
+ payload_field = msg.WhichOneof("payload")
99
+ if payload_field is None:
100
+ errors.append(ValidationError("payload", "must not be nil"))
101
+ elif payload_field == "job_request":
102
+ errors.extend(validate_job_request(msg.job_request))
103
+ elif payload_field == "job_result":
104
+ errors.extend(validate_job_result(msg.job_result))
105
+ return errors
@@ -1,13 +1,17 @@
1
1
  import asyncio
2
+ import logging
2
3
  from typing import Callable, Awaitable, Dict
3
4
 
4
5
  from google.protobuf import timestamp_pb2
6
+
7
+ logger = logging.getLogger(__name__)
5
8
  from cap.pb.cordum.agent.v1 import buspacket_pb2, job_pb2
6
9
  from cryptography.hazmat.primitives.asymmetric import ec
7
10
  from cryptography.hazmat.primitives import hashes
8
11
 
12
+ from cap.subjects import SUBJECT_RESULT
13
+
9
14
  DEFAULT_PROTOCOL_VERSION = 1
10
- SUBJECT_RESULT = "sys.job.result"
11
15
 
12
16
 
13
17
  async def run_worker(nats_url: str, subject: str, handler: Callable[[job_pb2.JobRequest], Awaitable[job_pb2.JobResult]],
@@ -33,7 +37,7 @@ async def run_worker(nats_url: str, subject: str, handler: Callable[[job_pb2.Job
33
37
  if public_keys:
34
38
  public_key = public_keys.get(packet.sender_id)
35
39
  if not public_key:
36
- print(f"worker: no public key found for sender: {packet.sender_id}")
40
+ logger.warning("no public key found for sender: %s", packet.sender_id)
37
41
  return
38
42
 
39
43
  signature = packet.signature
@@ -43,7 +47,7 @@ async def run_worker(nats_url: str, subject: str, handler: Callable[[job_pb2.Job
43
47
  try:
44
48
  public_key.verify(signature, unsigned_data, ec.ECDSA(hashes.SHA256()))
45
49
  except Exception:
46
- print(f"worker: invalid signature from sender: {packet.sender_id}")
50
+ logger.warning("invalid signature from sender: %s", packet.sender_id)
47
51
  return
48
52
 
49
53
  req = packet.job_request
@@ -1,8 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cap-sdk-python
3
- Version: 2.0.19
3
+ Version: 2.5.2
4
4
  Summary: CAP (Cordum Agent Protocol) Python SDK
5
+ Author-email: Cordum <eng@cordum.io>
6
+ License-Expression: Apache-2.0
5
7
  Project-URL: Homepage, https://github.com/cordum-io/cap
8
+ Project-URL: Repository, https://github.com/cordum-io/cap
9
+ Project-URL: Issues, https://github.com/cordum-io/cap/issues
10
+ Keywords: cap,cordum,agent,protocol,sdk,ai
6
11
  Requires-Python: >=3.9
7
12
  Description-Content-Type: text/markdown
8
13
  Requires-Dist: protobuf>=4.25.0
@@ -4,6 +4,8 @@ cap/__init__.py
4
4
  cap/bus.py
5
5
  cap/client.py
6
6
  cap/runtime.py
7
+ cap/subjects.py
8
+ cap/validate.py
7
9
  cap/worker.py
8
10
  cap/pb/__init__.py
9
11
  cap/pb/cordum/__init__.py
@@ -13,6 +15,8 @@ cap/pb/cordum/agent/v1/alert_pb2.py
13
15
  cap/pb/cordum/agent/v1/alert_pb2_grpc.py
14
16
  cap/pb/cordum/agent/v1/buspacket_pb2.py
15
17
  cap/pb/cordum/agent/v1/buspacket_pb2_grpc.py
18
+ cap/pb/cordum/agent/v1/handshake_pb2.py
19
+ cap/pb/cordum/agent/v1/handshake_pb2_grpc.py
16
20
  cap/pb/cordum/agent/v1/heartbeat_pb2.py
17
21
  cap/pb/cordum/agent/v1/heartbeat_pb2_grpc.py
18
22
  cap/pb/cordum/agent/v1/job_pb2.py
@@ -26,4 +30,5 @@ cap_sdk_python.egg-info/requires.txt
26
30
  cap_sdk_python.egg-info/top_level.txt
27
31
  tests/test_conformance.py
28
32
  tests/test_runtime.py
29
- tests/test_sdk.py
33
+ tests/test_sdk.py
34
+ tests/test_validate.py
@@ -4,10 +4,13 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "cap-sdk-python"
7
- version = "2.0.19"
7
+ version = "2.5.2"
8
8
  description = "CAP (Cordum Agent Protocol) Python SDK"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
11
+ license = "Apache-2.0"
12
+ authors = [{name = "Cordum", email = "eng@cordum.io"}]
13
+ keywords = ["cap", "cordum", "agent", "protocol", "sdk", "ai"]
11
14
  dependencies = [
12
15
  "protobuf>=4.25.0",
13
16
  "grpcio>=1.59.0",
@@ -19,6 +22,9 @@ dependencies = [
19
22
 
20
23
  [project.urls]
21
24
  Homepage = "https://github.com/cordum-io/cap"
25
+ Repository = "https://github.com/cordum-io/cap"
26
+ Issues = "https://github.com/cordum-io/cap/issues"
22
27
 
23
28
  [tool.setuptools.packages.find]
24
29
  where = ["."]
30
+ exclude = ["tests", "tests.*"]
@@ -11,7 +11,7 @@ sys.path = [p for p in sys.path if not p.rstrip("/").endswith("python")]
11
11
  sys.path.insert(0, _sdk_root)
12
12
  sys.path.append(os.path.join(_sdk_root, "cap", "pb"))
13
13
 
14
- from cap.pb.cordum.agent.v1 import buspacket_pb2
14
+ from cap.pb.cordum.agent.v1 import alert_pb2, buspacket_pb2, handshake_pb2, job_pb2
15
15
  from cryptography.hazmat.primitives import hashes, serialization
16
16
  from cryptography.hazmat.primitives.asymmetric import ec
17
17
 
@@ -104,6 +104,35 @@ class TestConformanceFixtures(unittest.TestCase):
104
104
  self.assertEqual(alert.level, "WARN")
105
105
  self.assertEqual(alert.component, "scheduler")
106
106
 
107
+ def test_handshake_fixture(self):
108
+ pkt = load_packet("buspacket_handshake.bin")
109
+ self._assert_common(pkt, "trace-handshake", "worker-1")
110
+ hs = pkt.handshake
111
+ self.assertEqual(hs.component_id, "worker-1")
112
+ self.assertEqual(hs.role, handshake_pb2.COMPONENT_ROLE_WORKER)
113
+ self.assertEqual(list(hs.supported_versions), [1])
114
+ self.assertTrue(hs.capabilities["signatures"])
115
+ self.assertTrue(hs.capabilities["progress"])
116
+ self.assertTrue(hs.capabilities["cancel"])
117
+ self.assertFalse(hs.capabilities["compensation"])
118
+ self.assertEqual(hs.sdk_version, "2.0.19")
119
+
120
+ def test_alert_enhanced_fixture(self):
121
+ pkt = load_packet("buspacket_alert_enhanced.bin")
122
+ self._assert_common(pkt, "trace-alert-enhanced", "scheduler-1")
123
+ alert = pkt.alert
124
+ # Legacy fields
125
+ self.assertEqual(alert.level, "CRITICAL")
126
+ self.assertEqual(alert.component, "scheduler")
127
+ self.assertEqual(alert.code, "SIGNATURE_INVALID")
128
+ # Enhanced fields
129
+ self.assertEqual(alert.severity, alert_pb2.ALERT_SEVERITY_CRITICAL)
130
+ self.assertEqual(alert.error_code_enum, job_pb2.ERROR_CODE_PROTOCOL_SIGNATURE_INVALID)
131
+ self.assertEqual(alert.source_component, "scheduler-1")
132
+ self.assertEqual(alert.details["sender"], "worker-bad")
133
+ self.assertEqual(alert.details["subject"], "sys.job.result")
134
+ self.assertEqual(alert.trace_id, "trace-offending-packet")
135
+
107
136
 
108
137
  if __name__ == "__main__":
109
138
  unittest.main()
@@ -0,0 +1,284 @@
1
+ import os
2
+ import sys
3
+ import unittest
4
+
5
+ _repo_root = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", ".."))
6
+ _sdk_root = os.path.join(_repo_root, "sdk", "python")
7
+
8
+ sys.path = [p for p in sys.path if not p.rstrip("/").endswith("python")]
9
+ sys.path.insert(0, _sdk_root)
10
+ sys.path.append(os.path.join(_sdk_root, "cap", "pb"))
11
+
12
+ from google.protobuf import timestamp_pb2
13
+
14
+ from cap.pb.cordum.agent.v1 import buspacket_pb2, job_pb2
15
+ from cap.validate import (
16
+ ValidationError,
17
+ validate_bus_packet,
18
+ validate_job_request,
19
+ validate_job_result,
20
+ )
21
+
22
+
23
+ def _valid_job_request():
24
+ return job_pb2.JobRequest(job_id="job-1", topic="job.tools")
25
+
26
+
27
+ def _valid_job_result():
28
+ return job_pb2.JobResult(
29
+ job_id="job-1",
30
+ status=job_pb2.JOB_STATUS_SUCCEEDED,
31
+ worker_id="worker-1",
32
+ execution_ms=100,
33
+ )
34
+
35
+
36
+ def _valid_bus_packet(payload=None):
37
+ req = payload or _valid_job_request()
38
+ pkt = buspacket_pb2.BusPacket(
39
+ trace_id="trace-1",
40
+ sender_id="sender-1",
41
+ protocol_version=1,
42
+ )
43
+ pkt.created_at.CopyFrom(timestamp_pb2.Timestamp(seconds=1000))
44
+ pkt.job_request.CopyFrom(req)
45
+ return pkt
46
+
47
+
48
+ class TestValidateJobRequest(unittest.TestCase):
49
+ def test_valid_minimal(self):
50
+ self.assertEqual(validate_job_request(_valid_job_request()), [])
51
+
52
+ def test_valid_with_budget(self):
53
+ req = _valid_job_request()
54
+ req.budget.CopyFrom(
55
+ job_pb2.Budget(
56
+ max_input_tokens=1000,
57
+ max_output_tokens=500,
58
+ max_total_tokens=1500,
59
+ deadline_ms=30000,
60
+ )
61
+ )
62
+ self.assertEqual(validate_job_request(req), [])
63
+
64
+ def test_valid_with_all_fields(self):
65
+ req = _valid_job_request()
66
+ req.priority = job_pb2.JOB_PRIORITY_CRITICAL
67
+ req.context_ptr = "redis://ctx:1"
68
+ req.adapter_id = "adapter-1"
69
+ req.parent_job_id = "parent-1"
70
+ req.workflow_id = "wf-1"
71
+ req.step_index = 2
72
+ req.memory_id = "mem-1"
73
+ req.tenant_id = "tenant-1"
74
+ req.principal_id = "user-1"
75
+ self.assertEqual(validate_job_request(req), [])
76
+
77
+ def test_none(self):
78
+ errs = validate_job_request(None)
79
+ self.assertEqual(len(errs), 1)
80
+ self.assertEqual(errs[0].field, "JobRequest")
81
+
82
+ def test_empty_job_id(self):
83
+ req = _valid_job_request()
84
+ req.job_id = ""
85
+ errs = validate_job_request(req)
86
+ self._assert_has_field_error(errs, "job_id")
87
+
88
+ def test_empty_topic(self):
89
+ req = _valid_job_request()
90
+ req.topic = ""
91
+ errs = validate_job_request(req)
92
+ self._assert_has_field_error(errs, "topic")
93
+
94
+ def test_negative_step_index(self):
95
+ req = _valid_job_request()
96
+ req.step_index = -1
97
+ errs = validate_job_request(req)
98
+ self._assert_has_field_error(errs, "step_index")
99
+
100
+ def test_negative_budget_max_input_tokens(self):
101
+ req = _valid_job_request()
102
+ req.budget.CopyFrom(job_pb2.Budget(max_input_tokens=-1))
103
+ errs = validate_job_request(req)
104
+ self._assert_has_field_error(errs, "budget.max_input_tokens")
105
+
106
+ def test_negative_budget_max_output_tokens(self):
107
+ req = _valid_job_request()
108
+ req.budget.CopyFrom(job_pb2.Budget(max_output_tokens=-1))
109
+ errs = validate_job_request(req)
110
+ self._assert_has_field_error(errs, "budget.max_output_tokens")
111
+
112
+ def test_negative_budget_max_total_tokens(self):
113
+ req = _valid_job_request()
114
+ req.budget.CopyFrom(job_pb2.Budget(max_total_tokens=-1))
115
+ errs = validate_job_request(req)
116
+ self._assert_has_field_error(errs, "budget.max_total_tokens")
117
+
118
+ def test_negative_budget_deadline_ms(self):
119
+ req = _valid_job_request()
120
+ req.budget.CopyFrom(job_pb2.Budget(deadline_ms=-1))
121
+ errs = validate_job_request(req)
122
+ self._assert_has_field_error(errs, "budget.deadline_ms")
123
+
124
+ def test_zero_value_struct(self):
125
+ errs = validate_job_request(job_pb2.JobRequest())
126
+ self._assert_has_field_error(errs, "job_id")
127
+
128
+ def _assert_has_field_error(self, errs, field):
129
+ fields = [e.field for e in errs]
130
+ self.assertIn(field, fields, f"Expected error for {field}, got: {errs}")
131
+
132
+
133
+ class TestValidateJobResult(unittest.TestCase):
134
+ def test_valid_minimal(self):
135
+ self.assertEqual(validate_job_result(_valid_job_result()), [])
136
+
137
+ def test_valid_with_all_fields(self):
138
+ res = _valid_job_result()
139
+ res.result_ptr = "redis://res:1"
140
+ res.error_code = "E_TEMP"
141
+ res.error_message = "temporary failure"
142
+ res.artifact_ptrs.extend(["redis://art:1", "redis://art:2"])
143
+ self.assertEqual(validate_job_result(res), [])
144
+
145
+ def test_none(self):
146
+ errs = validate_job_result(None)
147
+ self.assertEqual(len(errs), 1)
148
+ self.assertEqual(errs[0].field, "JobResult")
149
+
150
+ def test_empty_job_id(self):
151
+ res = _valid_job_result()
152
+ res.job_id = ""
153
+ errs = validate_job_result(res)
154
+ self._assert_has_field_error(errs, "job_id")
155
+
156
+ def test_unspecified_status(self):
157
+ res = _valid_job_result()
158
+ res.status = job_pb2.JOB_STATUS_UNSPECIFIED
159
+ errs = validate_job_result(res)
160
+ self._assert_has_field_error(errs, "status")
161
+
162
+ def test_empty_worker_id(self):
163
+ res = _valid_job_result()
164
+ res.worker_id = ""
165
+ errs = validate_job_result(res)
166
+ self._assert_has_field_error(errs, "worker_id")
167
+
168
+ def test_negative_execution_ms(self):
169
+ res = _valid_job_result()
170
+ res.execution_ms = -1
171
+ errs = validate_job_result(res)
172
+ self._assert_has_field_error(errs, "execution_ms")
173
+
174
+ def test_zero_value_struct(self):
175
+ errs = validate_job_result(job_pb2.JobResult())
176
+ self._assert_has_field_error(errs, "job_id")
177
+
178
+ def _assert_has_field_error(self, errs, field):
179
+ fields = [e.field for e in errs]
180
+ self.assertIn(field, fields, f"Expected error for {field}, got: {errs}")
181
+
182
+
183
+ class TestValidateBusPacket(unittest.TestCase):
184
+ def test_valid_with_job_request(self):
185
+ self.assertEqual(validate_bus_packet(_valid_bus_packet()), [])
186
+
187
+ def test_valid_with_job_result(self):
188
+ pkt = buspacket_pb2.BusPacket(
189
+ trace_id="trace-1",
190
+ sender_id="sender-1",
191
+ protocol_version=1,
192
+ )
193
+ pkt.created_at.CopyFrom(timestamp_pb2.Timestamp(seconds=1000))
194
+ pkt.job_result.CopyFrom(_valid_job_result())
195
+ self.assertEqual(validate_bus_packet(pkt), [])
196
+
197
+ def test_valid_with_heartbeat(self):
198
+ from cap.pb.cordum.agent.v1 import heartbeat_pb2
199
+
200
+ pkt = buspacket_pb2.BusPacket(
201
+ trace_id="trace-1",
202
+ sender_id="sender-1",
203
+ protocol_version=1,
204
+ )
205
+ pkt.created_at.CopyFrom(timestamp_pb2.Timestamp(seconds=1000))
206
+ pkt.heartbeat.CopyFrom(
207
+ heartbeat_pb2.Heartbeat(worker_id="w-1", pool="p-1")
208
+ )
209
+ self.assertEqual(validate_bus_packet(pkt), [])
210
+
211
+ def test_none(self):
212
+ errs = validate_bus_packet(None)
213
+ self.assertEqual(len(errs), 1)
214
+ self.assertEqual(errs[0].field, "BusPacket")
215
+
216
+ def test_empty_trace_id(self):
217
+ pkt = _valid_bus_packet()
218
+ pkt.trace_id = ""
219
+ errs = validate_bus_packet(pkt)
220
+ self._assert_has_field_error(errs, "trace_id")
221
+
222
+ def test_empty_sender_id(self):
223
+ pkt = _valid_bus_packet()
224
+ pkt.sender_id = ""
225
+ errs = validate_bus_packet(pkt)
226
+ self._assert_has_field_error(errs, "sender_id")
227
+
228
+ def test_protocol_version_zero(self):
229
+ pkt = _valid_bus_packet()
230
+ pkt.protocol_version = 0
231
+ errs = validate_bus_packet(pkt)
232
+ self._assert_has_field_error(errs, "protocol_version")
233
+
234
+ def test_nil_created_at(self):
235
+ pkt = buspacket_pb2.BusPacket(
236
+ trace_id="trace-1",
237
+ sender_id="sender-1",
238
+ protocol_version=1,
239
+ )
240
+ pkt.job_request.CopyFrom(_valid_job_request())
241
+ errs = validate_bus_packet(pkt)
242
+ self._assert_has_field_error(errs, "created_at")
243
+
244
+ def test_nil_payload(self):
245
+ pkt = buspacket_pb2.BusPacket(
246
+ trace_id="trace-1",
247
+ sender_id="sender-1",
248
+ protocol_version=1,
249
+ )
250
+ pkt.created_at.CopyFrom(timestamp_pb2.Timestamp(seconds=1000))
251
+ errs = validate_bus_packet(pkt)
252
+ self._assert_has_field_error(errs, "payload")
253
+
254
+ def test_delegates_to_job_request_validation(self):
255
+ bad = job_pb2.JobRequest(job_id="", topic="t")
256
+ pkt = _valid_bus_packet(bad)
257
+ errs = validate_bus_packet(pkt)
258
+ self._assert_has_field_error(errs, "job_id")
259
+
260
+ def test_delegates_to_job_result_validation(self):
261
+ bad = job_pb2.JobResult(
262
+ job_id="", status=job_pb2.JOB_STATUS_SUCCEEDED, worker_id="w"
263
+ )
264
+ pkt = buspacket_pb2.BusPacket(
265
+ trace_id="trace-1",
266
+ sender_id="sender-1",
267
+ protocol_version=1,
268
+ )
269
+ pkt.created_at.CopyFrom(timestamp_pb2.Timestamp(seconds=1000))
270
+ pkt.job_result.CopyFrom(bad)
271
+ errs = validate_bus_packet(pkt)
272
+ self._assert_has_field_error(errs, "job_id")
273
+
274
+ def test_zero_value_struct(self):
275
+ errs = validate_bus_packet(buspacket_pb2.BusPacket())
276
+ self._assert_has_field_error(errs, "trace_id")
277
+
278
+ def _assert_has_field_error(self, errs, field):
279
+ fields = [e.field for e in errs]
280
+ self.assertIn(field, fields, f"Expected error for {field}, got: {errs}")
281
+
282
+
283
+ if __name__ == "__main__":
284
+ unittest.main()
@@ -1,37 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- # Generated by the protocol buffer compiler. DO NOT EDIT!
3
- # NO CHECKED-IN PROTOBUF GENCODE
4
- # source: cordum/agent/v1/alert.proto
5
- # Protobuf Python Version: 6.31.1
6
- """Generated protocol buffer code."""
7
- from google.protobuf import descriptor as _descriptor
8
- from google.protobuf import descriptor_pool as _descriptor_pool
9
- from google.protobuf import runtime_version as _runtime_version
10
- from google.protobuf import symbol_database as _symbol_database
11
- from google.protobuf.internal import builder as _builder
12
- _runtime_version.ValidateProtobufRuntimeVersion(
13
- _runtime_version.Domain.PUBLIC,
14
- 6,
15
- 31,
16
- 1,
17
- '',
18
- 'cordum/agent/v1/alert.proto'
19
- )
20
- # @@protoc_insertion_point(imports)
21
-
22
- _sym_db = _symbol_database.Default()
23
-
24
-
25
-
26
-
27
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1b\x63ordum/agent/v1/alert.proto\x12\x0f\x63ordum.agent.v1\"N\n\x0bSystemAlert\x12\r\n\x05level\x18\x01 \x01(\t\x12\x0f\n\x07message\x18\x02 \x01(\t\x12\x11\n\tcomponent\x18\x03 \x01(\t\x12\x0c\n\x04\x63ode\x18\x04 \x01(\tB\x7f\n\x16io.cordum.cap.agent.v1P\x01Z+github.com/cordum-io/cap/v2/cordum/agent/v1\xaa\x02\x0f\x43ordum.Agent.V1\xca\x02\x0f\x63ordum\\Agent\\V1\xea\x02\x11\x43ordum::Agent::V1b\x06proto3')
28
-
29
- _globals = globals()
30
- _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
31
- _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cordum.agent.v1.alert_pb2', _globals)
32
- if not _descriptor._USE_C_DESCRIPTORS:
33
- _globals['DESCRIPTOR']._loaded_options = None
34
- _globals['DESCRIPTOR']._serialized_options = b'\n\026io.cordum.cap.agent.v1P\001Z+github.com/cordum-io/cap/v2/cordum/agent/v1\252\002\017Cordum.Agent.V1\312\002\017cordum\\Agent\\V1\352\002\021Cordum::Agent::V1'
35
- _globals['_SYSTEMALERT']._serialized_start=48
36
- _globals['_SYSTEMALERT']._serialized_end=126
37
- # @@protoc_insertion_point(module_scope)