rusticai-forge 0.2.2__tar.gz → 0.2.4__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.
- {rusticai_forge-0.2.2 → rusticai_forge-0.2.4}/PKG-INFO +2 -2
- {rusticai_forge-0.2.2 → rusticai_forge-0.2.4}/pyproject.toml +2 -2
- {rusticai_forge-0.2.2 → rusticai_forge-0.2.4}/src/rustic_ai/forge/agent_runner.py +12 -4
- {rusticai_forge-0.2.2 → rusticai_forge-0.2.4}/src/rustic_ai/forge/messaging/backend.py +40 -14
- {rusticai_forge-0.2.2 → rusticai_forge-0.2.4}/src/rusticai_forge.egg-info/PKG-INFO +2 -2
- {rusticai_forge-0.2.2 → rusticai_forge-0.2.4}/src/rusticai_forge.egg-info/requires.txt +1 -1
- {rusticai_forge-0.2.2 → rusticai_forge-0.2.4}/README.md +0 -0
- {rusticai_forge-0.2.2 → rusticai_forge-0.2.4}/setup.cfg +0 -0
- {rusticai_forge-0.2.2 → rusticai_forge-0.2.4}/src/rustic_ai/forge/agent_wrapper.py +0 -0
- {rusticai_forge-0.2.2 → rusticai_forge-0.2.4}/src/rustic_ai/forge/agents/system/guild_manager_agent.py +0 -0
- {rusticai_forge-0.2.2 → rusticai_forge-0.2.4}/src/rustic_ai/forge/agents/system/guild_manager_agent_props.py +0 -0
- {rusticai_forge-0.2.2 → rusticai_forge-0.2.4}/src/rustic_ai/forge/execution_engine.py +0 -0
- {rusticai_forge-0.2.2 → rusticai_forge-0.2.4}/src/rustic_ai/forge/messaging/__init__.py +0 -0
- {rusticai_forge-0.2.2 → rusticai_forge-0.2.4}/src/rustic_ai/forge/messaging/supervisor_backend.py +0 -0
- {rusticai_forge-0.2.2 → rusticai_forge-0.2.4}/src/rustic_ai/forge/metastore/manager_client.py +0 -0
- {rusticai_forge-0.2.2 → rusticai_forge-0.2.4}/src/rustic_ai/forge/testutils/file_manager_agent.py +0 -0
- {rusticai_forge-0.2.2 → rusticai_forge-0.2.4}/src/rustic_ai/forge/testutils/mock_llm_agent.py +0 -0
- {rusticai_forge-0.2.2 → rusticai_forge-0.2.4}/src/rusticai_forge.egg-info/SOURCES.txt +0 -0
- {rusticai_forge-0.2.2 → rusticai_forge-0.2.4}/src/rusticai_forge.egg-info/dependency_links.txt +0 -0
- {rusticai_forge-0.2.2 → rusticai_forge-0.2.4}/src/rusticai_forge.egg-info/top_level.txt +0 -0
- {rusticai_forge-0.2.2 → rusticai_forge-0.2.4}/tests/test_execution_engine.py +0 -0
- {rusticai_forge-0.2.2 → rusticai_forge-0.2.4}/tests/test_forge_api_contract.py +0 -0
- {rusticai_forge-0.2.2 → rusticai_forge-0.2.4}/tests/test_forge_integration.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rusticai-forge
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.4
|
|
4
4
|
Summary: Python agent wrapper and execution engine for Forge
|
|
5
5
|
Requires-Python: <3.14,>=3.13
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
@@ -8,7 +8,7 @@ Requires-Dist: pydantic<3.0.0,>=2.12.5
|
|
|
8
8
|
Requires-Dist: redis<7.0.0,>=6.4.0
|
|
9
9
|
Requires-Dist: nats-py<3.0.0,>=2.9.0
|
|
10
10
|
Requires-Dist: pyzmq<27.0.0,>=26.0.0
|
|
11
|
-
Requires-Dist: rusticai-core<2.0.0,>=1.
|
|
11
|
+
Requires-Dist: rusticai-core<2.0.0,>=1.2.0
|
|
12
12
|
Requires-Dist: rusticai-redis<2.0.0,>=1.1.0
|
|
13
13
|
Requires-Dist: psycopg[binary]<4.0.0,>=3.3.3
|
|
14
14
|
Requires-Dist: httpx<1.0.0,>=0.28.1
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "rusticai-forge"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.4"
|
|
4
4
|
description = "Python agent wrapper and execution engine for Forge"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.13,<3.14"
|
|
@@ -10,7 +10,7 @@ dependencies = [
|
|
|
10
10
|
"nats-py>=2.9.0,<3.0.0",
|
|
11
11
|
"pyzmq>=26.0.0,<27.0.0",
|
|
12
12
|
# DO NOT CHANGE THESE TO LOCAL FILE PATHS. Always use package references.
|
|
13
|
-
"rusticai-core>=1.
|
|
13
|
+
"rusticai-core>=1.2.0,<2.0.0",
|
|
14
14
|
"rusticai-redis>=1.1.0,<2.0.0",
|
|
15
15
|
"psycopg[binary]>=3.3.3,<4.0.0",
|
|
16
16
|
"httpx>=0.28.1,<1.0.0",
|
|
@@ -204,10 +204,14 @@ def _load_backend_config(client_props: dict, client_type_str: str) -> dict:
|
|
|
204
204
|
raw_backend_config = client_props["backend_config"]
|
|
205
205
|
else:
|
|
206
206
|
raw_backend_config = {
|
|
207
|
-
key: value
|
|
207
|
+
key: value
|
|
208
|
+
for key, value in client_props.items()
|
|
209
|
+
if key != "organization_id"
|
|
208
210
|
}
|
|
209
211
|
if not isinstance(raw_backend_config, dict):
|
|
210
|
-
raise ValueError(
|
|
212
|
+
raise ValueError(
|
|
213
|
+
"FORGE_CLIENT_PROPERTIES_JSON backend_config must be a JSON object."
|
|
214
|
+
)
|
|
211
215
|
|
|
212
216
|
backend_config = dict(raw_backend_config)
|
|
213
217
|
|
|
@@ -216,7 +220,9 @@ def _load_backend_config(client_props: dict, client_type_str: str) -> dict:
|
|
|
216
220
|
if raw_supervisor_config:
|
|
217
221
|
supervisor_config = json.loads(raw_supervisor_config)
|
|
218
222
|
if not isinstance(supervisor_config, dict):
|
|
219
|
-
raise ValueError(
|
|
223
|
+
raise ValueError(
|
|
224
|
+
f"{SUPERVISOR_ZMQ_CONFIG_ENV} must decode to a JSON object."
|
|
225
|
+
)
|
|
220
226
|
backend_config = supervisor_config | backend_config
|
|
221
227
|
|
|
222
228
|
endpoint = os.getenv(SUPERVISOR_ZMQ_ENDPOINT_ENV, "")
|
|
@@ -248,7 +254,9 @@ def main():
|
|
|
248
254
|
client_module_str = os.getenv("FORGE_CLIENT_MODULE", "")
|
|
249
255
|
client_props = json.loads(os.getenv("FORGE_CLIENT_PROPERTIES_JSON", "{}"))
|
|
250
256
|
if not isinstance(client_props, dict):
|
|
251
|
-
raise ValueError(
|
|
257
|
+
raise ValueError(
|
|
258
|
+
"FORGE_CLIENT_PROPERTIES_JSON must decode to a JSON object."
|
|
259
|
+
)
|
|
252
260
|
|
|
253
261
|
backend_config = _load_backend_config(client_props, client_type_str)
|
|
254
262
|
|
|
@@ -93,14 +93,18 @@ class SupervisorZmqMessagingBackend(MessagingBackend):
|
|
|
93
93
|
response = self._send_request("get_messages", {"topic": topic})
|
|
94
94
|
return [_normalize_message(msg) for msg in response.get("messages", [])]
|
|
95
95
|
|
|
96
|
-
def get_messages_for_topic_since(
|
|
96
|
+
def get_messages_for_topic_since(
|
|
97
|
+
self, topic: str, msg_id_since: int
|
|
98
|
+
) -> List[Message]:
|
|
97
99
|
response = self._send_request(
|
|
98
100
|
"get_since",
|
|
99
101
|
{"topic": topic, "since_id": msg_id_since},
|
|
100
102
|
)
|
|
101
103
|
return [_normalize_message(msg) for msg in response.get("messages", [])]
|
|
102
104
|
|
|
103
|
-
def get_next_message_for_topic_since(
|
|
105
|
+
def get_next_message_for_topic_since(
|
|
106
|
+
self, topic: str, last_message_id: int
|
|
107
|
+
) -> Optional[Message]:
|
|
104
108
|
response = self._send_request(
|
|
105
109
|
"get_next",
|
|
106
110
|
{"topic": topic, "since_id": last_message_id},
|
|
@@ -142,7 +146,9 @@ class SupervisorZmqMessagingBackend(MessagingBackend):
|
|
|
142
146
|
timeout_ms=min(self.request_timeout_ms, 2_000),
|
|
143
147
|
)
|
|
144
148
|
except Exception:
|
|
145
|
-
logger.debug(
|
|
149
|
+
logger.debug(
|
|
150
|
+
"Supervisor cleanup request failed during shutdown", exc_info=True
|
|
151
|
+
)
|
|
146
152
|
|
|
147
153
|
self._shutdown_event.set()
|
|
148
154
|
self._reconnect_event.set()
|
|
@@ -200,7 +206,9 @@ class SupervisorZmqMessagingBackend(MessagingBackend):
|
|
|
200
206
|
|
|
201
207
|
def _heartbeat_loop(self) -> None:
|
|
202
208
|
interval = self.heartbeat_interval_ms / 1000.0
|
|
203
|
-
timeout_ms = max(
|
|
209
|
+
timeout_ms = max(
|
|
210
|
+
1_000, min(self.request_timeout_ms, self.heartbeat_interval_ms)
|
|
211
|
+
)
|
|
204
212
|
|
|
205
213
|
while not self._shutdown_event.wait(interval):
|
|
206
214
|
try:
|
|
@@ -231,8 +239,9 @@ class SupervisorZmqMessagingBackend(MessagingBackend):
|
|
|
231
239
|
self._drain_outbound(socket)
|
|
232
240
|
|
|
233
241
|
if self._reconnect_event.is_set():
|
|
234
|
-
reconnect_cause =
|
|
235
|
-
|
|
242
|
+
reconnect_cause = (
|
|
243
|
+
self._consume_transport_error()
|
|
244
|
+
or RuntimeError("supervisor ZeroMQ reconnect requested")
|
|
236
245
|
)
|
|
237
246
|
socket, poller = self._reset_socket(socket, poller)
|
|
238
247
|
self._reconnect_event.clear()
|
|
@@ -257,7 +266,9 @@ class SupervisorZmqMessagingBackend(MessagingBackend):
|
|
|
257
266
|
finally:
|
|
258
267
|
self._close_socket(socket, poller)
|
|
259
268
|
|
|
260
|
-
def _connect_with_retry(
|
|
269
|
+
def _connect_with_retry(
|
|
270
|
+
self, initial_cause: Exception
|
|
271
|
+
) -> tuple[Optional[zmq.Socket], Optional[zmq.Poller]]:
|
|
261
272
|
attempt = 0
|
|
262
273
|
delay = self.retry_initial_delay
|
|
263
274
|
start_time = time.monotonic()
|
|
@@ -340,9 +351,14 @@ class SupervisorZmqMessagingBackend(MessagingBackend):
|
|
|
340
351
|
continue
|
|
341
352
|
|
|
342
353
|
incoming = socket.recv_json()
|
|
343
|
-
if
|
|
354
|
+
if (
|
|
355
|
+
incoming.get("kind") == "response"
|
|
356
|
+
and incoming.get("request_id") == request_id
|
|
357
|
+
):
|
|
344
358
|
if not incoming.get("ok", False):
|
|
345
|
-
raise RuntimeError(
|
|
359
|
+
raise RuntimeError(
|
|
360
|
+
incoming.get("error", f"Supervisor {op} request failed")
|
|
361
|
+
)
|
|
346
362
|
return incoming
|
|
347
363
|
|
|
348
364
|
self._handle_envelope(incoming)
|
|
@@ -390,7 +406,9 @@ class SupervisorZmqMessagingBackend(MessagingBackend):
|
|
|
390
406
|
try:
|
|
391
407
|
handler(message)
|
|
392
408
|
except Exception:
|
|
393
|
-
logger.exception(
|
|
409
|
+
logger.exception(
|
|
410
|
+
"Supervisor ZeroMQ delivery handler failed for topic %s", topic
|
|
411
|
+
)
|
|
394
412
|
|
|
395
413
|
def _send_request(
|
|
396
414
|
self,
|
|
@@ -409,14 +427,20 @@ class SupervisorZmqMessagingBackend(MessagingBackend):
|
|
|
409
427
|
with self._pending_lock:
|
|
410
428
|
self._pending[request_id] = queue
|
|
411
429
|
|
|
412
|
-
self._outbound.put(
|
|
430
|
+
self._outbound.put(
|
|
431
|
+
{"kind": "request", "op": op, "request_id": request_id} | payload
|
|
432
|
+
)
|
|
413
433
|
|
|
414
434
|
try:
|
|
415
|
-
response = queue.get(
|
|
435
|
+
response = queue.get(
|
|
436
|
+
timeout=(timeout_ms or self.request_timeout_ms) / 1000.0
|
|
437
|
+
)
|
|
416
438
|
except Empty as exc:
|
|
417
439
|
if allow_reconnect:
|
|
418
440
|
self._mark_transport_unhealthy(exc)
|
|
419
|
-
raise TimeoutError(
|
|
441
|
+
raise TimeoutError(
|
|
442
|
+
f"Timed out waiting for supervisor response to {op}"
|
|
443
|
+
) from exc
|
|
420
444
|
finally:
|
|
421
445
|
with self._pending_lock:
|
|
422
446
|
self._pending.pop(request_id, None)
|
|
@@ -451,7 +475,9 @@ class SupervisorZmqMessagingBackend(MessagingBackend):
|
|
|
451
475
|
self._close_socket(socket, poller)
|
|
452
476
|
return None, None
|
|
453
477
|
|
|
454
|
-
def _close_socket(
|
|
478
|
+
def _close_socket(
|
|
479
|
+
self, socket: Optional[zmq.Socket], poller: Optional[zmq.Poller]
|
|
480
|
+
) -> None:
|
|
455
481
|
if socket is None:
|
|
456
482
|
return
|
|
457
483
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rusticai-forge
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.4
|
|
4
4
|
Summary: Python agent wrapper and execution engine for Forge
|
|
5
5
|
Requires-Python: <3.14,>=3.13
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
@@ -8,7 +8,7 @@ Requires-Dist: pydantic<3.0.0,>=2.12.5
|
|
|
8
8
|
Requires-Dist: redis<7.0.0,>=6.4.0
|
|
9
9
|
Requires-Dist: nats-py<3.0.0,>=2.9.0
|
|
10
10
|
Requires-Dist: pyzmq<27.0.0,>=26.0.0
|
|
11
|
-
Requires-Dist: rusticai-core<2.0.0,>=1.
|
|
11
|
+
Requires-Dist: rusticai-core<2.0.0,>=1.2.0
|
|
12
12
|
Requires-Dist: rusticai-redis<2.0.0,>=1.1.0
|
|
13
13
|
Requires-Dist: psycopg[binary]<4.0.0,>=3.3.3
|
|
14
14
|
Requires-Dist: httpx<1.0.0,>=0.28.1
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rusticai_forge-0.2.2 → rusticai_forge-0.2.4}/src/rustic_ai/forge/messaging/supervisor_backend.py
RENAMED
|
File without changes
|
{rusticai_forge-0.2.2 → rusticai_forge-0.2.4}/src/rustic_ai/forge/metastore/manager_client.py
RENAMED
|
File without changes
|
{rusticai_forge-0.2.2 → rusticai_forge-0.2.4}/src/rustic_ai/forge/testutils/file_manager_agent.py
RENAMED
|
File without changes
|
{rusticai_forge-0.2.2 → rusticai_forge-0.2.4}/src/rustic_ai/forge/testutils/mock_llm_agent.py
RENAMED
|
File without changes
|
|
File without changes
|
{rusticai_forge-0.2.2 → rusticai_forge-0.2.4}/src/rusticai_forge.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|