digitalkin 0.3.2a2__py3-none-any.whl → 0.3.2a3__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.
digitalkin/__version__.py CHANGED
@@ -5,4 +5,4 @@ from importlib.metadata import PackageNotFoundError, version
5
5
  try:
6
6
  __version__ = version("digitalkin")
7
7
  except PackageNotFoundError:
8
- __version__ = "0.3.2.a2"
8
+ __version__ = "0.3.2.a3"
@@ -145,10 +145,26 @@ class SurrealDBConnection(Generic[TSurreal]):
145
145
 
146
146
  Returns:
147
147
  Dict[str, Any]: The created record as returned by the database
148
+
149
+ Raises:
150
+ RuntimeError: If the database returns an error response
148
151
  """
149
152
  logger.debug("Creating record in %s with data: %s", table_name, data)
150
153
  result = await self.db.create(table_name, data)
151
154
  logger.debug("create result: %s", result)
155
+
156
+ # Check for error response from SurrealDB
157
+ if isinstance(result, dict) and "code" in result:
158
+ error_msg = result.get("message", result.get("information", "Unknown error"))
159
+ logger.error(
160
+ "SurrealDB create failed: %s (code: %s)",
161
+ error_msg,
162
+ result.get("code"),
163
+ extra={"table": table_name, "error": result},
164
+ )
165
+ msg = f"SurrealDB create failed in '{table_name}': {error_msg}"
166
+ raise RuntimeError(msg)
167
+
152
168
  return cast("list[dict[str, Any]] | dict[str, Any]", result)
153
169
 
154
170
  async def merge(
@@ -55,7 +55,9 @@ class TaskExecutor:
55
55
  async def signal_wrapper() -> None:
56
56
  """Create initial signal record and listen for signals."""
57
57
  try:
58
- await channel.create(
58
+ # Create task record and capture the record ID directly
59
+ # This avoids a race condition where SELECT might run before CREATE completes
60
+ result = await channel.create(
59
61
  "tasks",
60
62
  SignalMessage(
61
63
  task_id=task_id,
@@ -66,7 +68,22 @@ class TaskExecutor:
66
68
  action=SignalType.START,
67
69
  ).model_dump(),
68
70
  )
69
- await session.listen_signals()
71
+ # Store the record ID in session - required before starting live query
72
+ if isinstance(result, dict) and "id" in result:
73
+ session.signal_record_id = result["id"]
74
+ logger.debug(
75
+ "Task signal record created",
76
+ extra={"mission_id": mission_id, "task_id": task_id, "record_id": result["id"]},
77
+ )
78
+ # Only start listening if we have a valid record ID
79
+ await session.listen_signals()
80
+ else:
81
+ # Create failed - wait for cancellation instead of listening
82
+ logger.error(
83
+ "Failed to get record ID from task creation, waiting for cancellation",
84
+ extra={"mission_id": mission_id, "task_id": task_id, "result": result},
85
+ )
86
+ await session.is_cancelled.wait()
70
87
  except asyncio.CancelledError:
71
88
  logger.debug("Signal listener cancelled", extra={"mission_id": mission_id, "task_id": task_id})
72
89
  finally:
@@ -229,17 +229,25 @@ class TaskSession:
229
229
  """Enhanced signal listener with comprehensive handling.
230
230
 
231
231
  Raises:
232
- CancelledError: Asyncio when task cancelling
232
+ CancelledError: If task is cancelled during signal listening.
233
233
  """
234
234
  logger.info("Signal listener started", extra=self.session_ids)
235
+
236
+ # signal_record_id must be set by TaskExecutor before calling this method.
237
+ # If not set, we cannot filter signals correctly - abort early.
235
238
  if self.signal_record_id is None:
236
- self.signal_record_id = (await self.db.select_by_task_id("tasks", self.task_id)).get("id")
239
+ logger.error(
240
+ "signal_record_id not set - cannot start signal listener without valid record ID",
241
+ extra=self.session_ids,
242
+ )
243
+ return
237
244
 
238
245
  live_id, live_signals = await self.db.start_live("tasks")
239
246
  try:
240
247
  async for signal in live_signals:
241
248
  logger.debug("Signal received", extra={**self.session_ids, "signal": signal})
242
- if self.cancelled:
249
+ # Check both cancelled and stream_closed to ensure clean shutdown
250
+ if self.cancelled or self.stream_closed:
243
251
  break
244
252
 
245
253
  if signal is None or signal["id"] == self.signal_record_id or "payload" not in signal:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: digitalkin
3
- Version: 0.3.2a2
3
+ Version: 0.3.2a3
4
4
  Summary: SDK to build kin used in DigitalKin
5
5
  Author-email: "DigitalKin.ai" <contact@digitalkin.ai>
6
6
  License: Attribution-NonCommercial-ShareAlike 4.0 International
@@ -7,7 +7,7 @@ base_server/mock/__init__.py,sha256=YZFT-F1l_TpvJYuIPX-7kTeE1CfOjhx9YmNRXVoi-jQ,
7
7
  base_server/mock/mock_pb2.py,sha256=sETakcS3PAAm4E-hTCV1jIVaQTPEAIoVVHupB8Z_k7Y,1843
8
8
  base_server/mock/mock_pb2_grpc.py,sha256=BbOT70H6q3laKgkHfOx1QdfmCS_HxCY4wCOX84YAdG4,3180
9
9
  digitalkin/__init__.py,sha256=7LLBAba0th-3SGqcpqFO-lopWdUkVLKzLZiMtB-mW3M,162
10
- digitalkin/__version__.py,sha256=Ax_aYd7TkL4irPiANTsxbqr0Wwn-cJMP8BvBEqQjCzE,193
10
+ digitalkin/__version__.py,sha256=9skx1vQVp8GGSDC8y9Ukcx2HKYinpCJ_xSH3ODFDgXs,193
11
11
  digitalkin/logger.py,sha256=8ze_tjt2G6mDTuQcsf7-UTXWP3UHZ7LZVSs_iqF4rX4,4685
12
12
  digitalkin/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
13
  digitalkin/core/__init__.py,sha256=FJRcJ-B1Viyn-38L8XpOpZ8KOnf1I7PCDOAmKXLQhqc,71
@@ -22,9 +22,9 @@ digitalkin/core/task_manager/__init__.py,sha256=k9i-qIoee_1yXogyQolaVFDUQBIZU3EN
22
22
  digitalkin/core/task_manager/base_task_manager.py,sha256=9njUerhlJ7s3KA7IKgpVC3DYxq_HMHSqOcDhtZKkDiU,19439
23
23
  digitalkin/core/task_manager/local_task_manager.py,sha256=Z1gv4dCGD32LBSfMZJ4dGyYDe80lZRAyowTgGC6E4Vk,3534
24
24
  digitalkin/core/task_manager/remote_task_manager.py,sha256=zgccmnwwtB0nyeIZlL5Ji8SY1J89z_vjA4JD9ur7HzY,3082
25
- digitalkin/core/task_manager/surrealdb_repository.py,sha256=rUNPGK_flDdOl3-ritZif97zYHxQ7SIt_Aq_P2dymTQ,10092
26
- digitalkin/core/task_manager/task_executor.py,sha256=ByON-CxRBMbaDUgL6z5XYjbrUwV9X4DGktUBa0jqIPE,12005
27
- digitalkin/core/task_manager/task_session.py,sha256=iujisx6SHTP7qqQxZbMHG9xQTiDsGOsblg35zsejt30,14739
25
+ digitalkin/core/task_manager/surrealdb_repository.py,sha256=VhgQBCvcclUmx9jyr6WCklf9iLXT2YfQN-YlKpApWWc,10712
26
+ digitalkin/core/task_manager/task_executor.py,sha256=rPimQaGQTRwuRs9fUq8lySyZHlpXB-nEJDfYizXgm8w,13087
27
+ digitalkin/core/task_manager/task_session.py,sha256=FWlFsS1we9-WVtT4_upOXj5l1pZcboKLpG2N35m56eA,15111
28
28
  digitalkin/grpc_servers/__init__.py,sha256=ZIRMJ1Lcas8yQ106GCup6hn2UBOsx1sNk8ap0lpEDnY,72
29
29
  digitalkin/grpc_servers/_base_server.py,sha256=ZVeCDwI7w7fFbPTXPkeJb_SOuLfd2T7za3T4oCu2UWY,18680
30
30
  digitalkin/grpc_servers/module_server.py,sha256=JE1hn1JTUPFakQOmhcTLTohC9n5-kVYUZD6ZKZKQBx8,7035
@@ -123,7 +123,7 @@ digitalkin/utils/dynamic_schema.py,sha256=y5csxjuqVHjWDpnTUzxbcUuI_wou9-ibRVHQlB
123
123
  digitalkin/utils/llm_ready_schema.py,sha256=JjMug_lrQllqFoanaC091VgOqwAd-_YzcpqFlS7p778,2375
124
124
  digitalkin/utils/package_discover.py,sha256=sa6Zp5Kape1Zr4iYiNrnZxiHDnqM06ODk6yfWHom53w,13465
125
125
  digitalkin/utils/schema_splitter.py,sha256=lMaReyLD4kGAZSQ9MSxpNZ4D4luWANVArFqNWV_bsko,14040
126
- digitalkin-0.3.2a2.dist-info/licenses/LICENSE,sha256=Ies4HFv2r2hzDRakJYxk3Y60uDFLiG-orIgeTpstnIo,20327
126
+ digitalkin-0.3.2a3.dist-info/licenses/LICENSE,sha256=Ies4HFv2r2hzDRakJYxk3Y60uDFLiG-orIgeTpstnIo,20327
127
127
  modules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
128
128
  modules/archetype_with_tools_module.py,sha256=kJkVhAFWG0aDDqzupOXOnV3l8j3z5bEdWos_6Z9rUP8,7303
129
129
  modules/cpu_intensive_module.py,sha256=GZlirQDZdYuXrI46sv1q4RNAHZjL4EptHVQTvgK9zz8,8363
@@ -138,7 +138,7 @@ monitoring/digitalkin_observability/prometheus.py,sha256=gDmM9ySaVwPAe7Yg84pLxmE
138
138
  monitoring/tests/test_metrics.py,sha256=ugnYfAwqBPO6zA8z4afKTlyBWECTivacYSN-URQCn2E,5856
139
139
  services/filesystem_module.py,sha256=U4dgqtuDadaXz8PJ1d_uQ_1EPncBqudAQCLUICF9yL4,7421
140
140
  services/storage_module.py,sha256=Wz2MzLvqs2D_bnBBgtnujYcAKK2V2KFMk8K21RoepSE,6972
141
- digitalkin-0.3.2a2.dist-info/METADATA,sha256=H_Vj7SYn9cFu8jpO3-zwsiQFB_NC4x_xsQT1I746tYU,29721
142
- digitalkin-0.3.2a2.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
143
- digitalkin-0.3.2a2.dist-info/top_level.txt,sha256=AYVIesKrO0jnedQ-Muog9JBehG81WeTCNeOFoJgwsgE,51
144
- digitalkin-0.3.2a2.dist-info/RECORD,,
141
+ digitalkin-0.3.2a3.dist-info/METADATA,sha256=GYGoIv2BFuAYj8A2nSXB2366r0zSznUar8x6JRHEVzc,29721
142
+ digitalkin-0.3.2a3.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
143
+ digitalkin-0.3.2a3.dist-info/top_level.txt,sha256=AYVIesKrO0jnedQ-Muog9JBehG81WeTCNeOFoJgwsgE,51
144
+ digitalkin-0.3.2a3.dist-info/RECORD,,