alloy-runtime-sdk 0.2.97__tar.gz → 0.2.99__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 (32) hide show
  1. {alloy_runtime_sdk-0.2.97 → alloy_runtime_sdk-0.2.99}/PKG-INFO +2 -2
  2. {alloy_runtime_sdk-0.2.97 → alloy_runtime_sdk-0.2.99}/alloy_runtime_sdk/api_client/client.py +40 -4
  3. {alloy_runtime_sdk-0.2.97 → alloy_runtime_sdk-0.2.99}/alloy_runtime_sdk/pipeline/local_runner.py +57 -1
  4. {alloy_runtime_sdk-0.2.97 → alloy_runtime_sdk-0.2.99}/alloy_runtime_sdk.egg-info/PKG-INFO +2 -2
  5. {alloy_runtime_sdk-0.2.97 → alloy_runtime_sdk-0.2.99}/alloy_runtime_sdk.egg-info/requires.txt +1 -1
  6. {alloy_runtime_sdk-0.2.97 → alloy_runtime_sdk-0.2.99}/pyproject.toml +2 -2
  7. {alloy_runtime_sdk-0.2.97 → alloy_runtime_sdk-0.2.99}/MANIFEST.in +0 -0
  8. {alloy_runtime_sdk-0.2.97 → alloy_runtime_sdk-0.2.99}/README.md +0 -0
  9. {alloy_runtime_sdk-0.2.97 → alloy_runtime_sdk-0.2.99}/alloy_runtime_sdk/__init__.py +0 -0
  10. {alloy_runtime_sdk-0.2.97 → alloy_runtime_sdk-0.2.99}/alloy_runtime_sdk/api_client/__init__.py +0 -0
  11. {alloy_runtime_sdk-0.2.97 → alloy_runtime_sdk-0.2.99}/alloy_runtime_sdk/api_client/pagination.py +0 -0
  12. {alloy_runtime_sdk-0.2.97 → alloy_runtime_sdk-0.2.99}/alloy_runtime_sdk/concurrency.py +0 -0
  13. {alloy_runtime_sdk-0.2.97 → alloy_runtime_sdk-0.2.99}/alloy_runtime_sdk/exceptions/__init__.py +0 -0
  14. {alloy_runtime_sdk-0.2.97 → alloy_runtime_sdk-0.2.99}/alloy_runtime_sdk/exceptions/errors.py +0 -0
  15. {alloy_runtime_sdk-0.2.97 → alloy_runtime_sdk-0.2.99}/alloy_runtime_sdk/logging/__init__.py +0 -0
  16. {alloy_runtime_sdk-0.2.97 → alloy_runtime_sdk-0.2.99}/alloy_runtime_sdk/logging/config.py +0 -0
  17. {alloy_runtime_sdk-0.2.97 → alloy_runtime_sdk-0.2.99}/alloy_runtime_sdk/logging/protocol.py +0 -0
  18. {alloy_runtime_sdk-0.2.97 → alloy_runtime_sdk-0.2.99}/alloy_runtime_sdk/markdown.py +0 -0
  19. {alloy_runtime_sdk-0.2.97 → alloy_runtime_sdk-0.2.99}/alloy_runtime_sdk/pipeline/__init__.py +0 -0
  20. {alloy_runtime_sdk-0.2.97 → alloy_runtime_sdk-0.2.99}/alloy_runtime_sdk/pipeline/context.py +0 -0
  21. {alloy_runtime_sdk-0.2.97 → alloy_runtime_sdk-0.2.99}/alloy_runtime_sdk/pipeline/db.py +0 -0
  22. {alloy_runtime_sdk-0.2.97 → alloy_runtime_sdk-0.2.99}/alloy_runtime_sdk/pipeline/decorators.py +0 -0
  23. {alloy_runtime_sdk-0.2.97 → alloy_runtime_sdk-0.2.99}/alloy_runtime_sdk/pipeline/exceptions.py +0 -0
  24. {alloy_runtime_sdk-0.2.97 → alloy_runtime_sdk-0.2.99}/alloy_runtime_sdk/pipeline/http_context.py +0 -0
  25. {alloy_runtime_sdk-0.2.97 → alloy_runtime_sdk-0.2.99}/alloy_runtime_sdk/pipeline/runner.py +0 -0
  26. {alloy_runtime_sdk-0.2.97 → alloy_runtime_sdk-0.2.99}/alloy_runtime_sdk/pipeline/runtime.py +0 -0
  27. {alloy_runtime_sdk-0.2.97 → alloy_runtime_sdk-0.2.99}/alloy_runtime_sdk/pipeline/schema_extractor.py +0 -0
  28. {alloy_runtime_sdk-0.2.97 → alloy_runtime_sdk-0.2.99}/alloy_runtime_sdk/pipeline/types.py +0 -0
  29. {alloy_runtime_sdk-0.2.97 → alloy_runtime_sdk-0.2.99}/alloy_runtime_sdk.egg-info/SOURCES.txt +0 -0
  30. {alloy_runtime_sdk-0.2.97 → alloy_runtime_sdk-0.2.99}/alloy_runtime_sdk.egg-info/dependency_links.txt +0 -0
  31. {alloy_runtime_sdk-0.2.97 → alloy_runtime_sdk-0.2.99}/alloy_runtime_sdk.egg-info/top_level.txt +0 -0
  32. {alloy_runtime_sdk-0.2.97 → alloy_runtime_sdk-0.2.99}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: alloy-runtime-sdk
3
- Version: 0.2.97
3
+ Version: 0.2.99
4
4
  Summary: Python SDK for Alloy Runtime - client, pipeline, and logging
5
5
  Keywords: alloy,api,client,python,sdk
6
6
  Classifier: Development Status :: 3 - Alpha
@@ -13,7 +13,7 @@ Description-Content-Type: text/markdown
13
13
  Requires-Dist: httpx==0.28.1
14
14
  Requires-Dist: pydantic==2.12.5
15
15
  Requires-Dist: structlog==25.5.0
16
- Requires-Dist: alloy-runtime-types==0.2.97
16
+ Requires-Dist: alloy-runtime-types==0.2.99
17
17
  Requires-Dist: uuid-extension==0.2.0
18
18
  Requires-Dist: psycopg[binary]==3.3.3
19
19
 
@@ -2180,12 +2180,16 @@ class ApiClient:
2180
2180
  timeout: float | None = None,
2181
2181
  poll_interval: float = 2.0,
2182
2182
  include_tool_call_details: bool = False,
2183
+ max_poll_request_errors: int = 3,
2183
2184
  ) -> GenerateTextResponse:
2184
2185
  """Submit async generation, poll until terminal, and return final JSON result.
2185
2186
 
2186
2187
  By default this method has no client-side generation wait deadline. The
2187
2188
  server owns generation lifecycle and terminal status. Pass ``timeout``
2188
2189
  only when the caller explicitly wants the local wait to stop early.
2190
+ ``max_poll_request_errors`` controls how many consecutive transient
2191
+ status polling transport failures are allowed before the local wait
2192
+ fails while leaving the server-side generation running.
2189
2193
  """
2190
2194
  submit = await self.generate_text_async(
2191
2195
  request,
@@ -2199,6 +2203,7 @@ class ApiClient:
2199
2203
  timeout=timeout,
2200
2204
  poll_interval=poll_interval,
2201
2205
  include_tool_call_details=include_tool_call_details,
2206
+ max_poll_request_errors=max_poll_request_errors,
2202
2207
  )
2203
2208
  except asyncio.CancelledError as exc:
2204
2209
  raise GenerationWaitCancelledError(execution_id) from exc
@@ -2479,6 +2484,7 @@ class ApiClient:
2479
2484
  timeout: float | None = None,
2480
2485
  poll_interval: float = 2.0,
2481
2486
  include_tool_call_details: bool = False,
2487
+ max_poll_request_errors: int = 3,
2482
2488
  ) -> AsyncGenerationStatusResponse:
2483
2489
  """Wait for async generation to reach a terminal state.
2484
2490
 
@@ -2492,6 +2498,9 @@ class ApiClient:
2492
2498
  which waits until the server reports a terminal generation state.
2493
2499
  poll_interval: Time between polls in seconds (default: 2.0)
2494
2500
  include_tool_call_details: If True, include tool call details in response
2501
+ max_poll_request_errors: Consecutive transient polling request failures
2502
+ to tolerate before raising. The submitted server-side generation is
2503
+ left running when this limit is exceeded.
2495
2504
 
2496
2505
  Returns:
2497
2506
  Final status response when generation completes successfully
@@ -2522,15 +2531,42 @@ class ApiClient:
2522
2531
  start_time = time.monotonic()
2523
2532
  last_status: str = "pending"
2524
2533
  execution_id_str = str(execution_id)
2534
+ consecutive_poll_request_errors = 0
2535
+ if max_poll_request_errors < 1:
2536
+ raise ValueError("max_poll_request_errors must be at least 1")
2525
2537
 
2526
2538
  while True:
2527
2539
  if timeout is not None and time.monotonic() - start_time >= timeout:
2528
2540
  break
2529
2541
 
2530
- status_response = await self.get_generation(
2531
- execution_id,
2532
- include_tool_call_details=include_tool_call_details,
2533
- )
2542
+ try:
2543
+ status_response = await self.get_generation(
2544
+ execution_id,
2545
+ include_tool_call_details=include_tool_call_details,
2546
+ )
2547
+ except RequestError as exc:
2548
+ consecutive_poll_request_errors += 1
2549
+ if consecutive_poll_request_errors >= max_poll_request_errors:
2550
+ raise RequestError(
2551
+ f"Generation {execution_id_str} status polling failed after "
2552
+ f"{consecutive_poll_request_errors} consecutive request errors. "
2553
+ "The server-side generation may still be running; poll the "
2554
+ "execution ID directly before retrying the generation. "
2555
+ f"Last error: {exc}"
2556
+ ) from exc
2557
+
2558
+ sleep_seconds = poll_interval if poll_interval > 0 else 0.0
2559
+ if timeout is None:
2560
+ await asyncio.sleep(sleep_seconds)
2561
+ continue
2562
+
2563
+ remaining = timeout - (time.monotonic() - start_time)
2564
+ if remaining <= 0:
2565
+ break
2566
+ await asyncio.sleep(min(sleep_seconds, remaining))
2567
+ continue
2568
+
2569
+ consecutive_poll_request_errors = 0
2534
2570
  last_status = status_response.status
2535
2571
 
2536
2572
  if status_response.is_terminal:
@@ -1,6 +1,7 @@
1
1
  import argparse
2
2
  import asyncio
3
3
  import json
4
+ import shlex
4
5
  import sys
5
6
  import traceback
6
7
  from dataclasses import dataclass
@@ -218,9 +219,64 @@ def _build_parser() -> argparse.ArgumentParser:
218
219
  return parser
219
220
 
220
221
 
222
+ def _emit_local_pipeline_resume_instructions(
223
+ *,
224
+ module_path: str,
225
+ pipeline_name: str | None,
226
+ config: str | None,
227
+ server_url: str,
228
+ pipeline_execution_id: UUID,
229
+ pipeline_definition_id: UUID | None,
230
+ ) -> None:
231
+ command_parts = [
232
+ "python -m alloy_runtime_sdk.pipeline.local_runner",
233
+ "--file",
234
+ module_path,
235
+ ]
236
+ if pipeline_name is not None:
237
+ command_parts.extend(["--function-name", pipeline_name])
238
+ if config is not None:
239
+ command_parts.extend(["--config", config])
240
+ command_parts.extend(
241
+ [
242
+ "--server-url",
243
+ server_url,
244
+ "--api-key",
245
+ "<same api key>",
246
+ ]
247
+ )
248
+ if pipeline_definition_id is not None:
249
+ command_parts.extend(["--pipeline-definition-id", str(pipeline_definition_id)])
250
+ command_parts.extend(["--pipeline-execution-id", str(pipeline_execution_id)])
251
+
252
+ print(
253
+ "\n".join(
254
+ [
255
+ "Alloy local pipeline resume instructions:",
256
+ f" pipeline_execution_id: {pipeline_execution_id}",
257
+ " To resume this same stop-and-go pipeline run, rerun with this exact "
258
+ "pipeline execution id:",
259
+ f" {shlex.join(command_parts)}",
260
+ " Idempotency depends on reusing this pipeline_execution_id plus stable "
261
+ "ctx.generate_text(step_id=...) values.",
262
+ ]
263
+ ),
264
+ file=sys.stderr,
265
+ )
266
+
267
+
221
268
  def main(argv: list[str] | None = None) -> None:
222
269
  parser = _build_parser()
223
270
  args = parser.parse_args(argv)
271
+ pipeline_execution_id = args.pipeline_execution_id or uuid7()
272
+ _emit_local_pipeline_resume_instructions(
273
+ module_path=args.module_path,
274
+ pipeline_name=args.pipeline_name,
275
+ config=args.config,
276
+ server_url=args.server_url,
277
+ pipeline_execution_id=pipeline_execution_id,
278
+ pipeline_definition_id=args.pipeline_definition_id,
279
+ )
224
280
 
225
281
  try:
226
282
  result = asyncio.run(
@@ -230,7 +286,7 @@ def main(argv: list[str] | None = None) -> None:
230
286
  config=_parse_config(args.config),
231
287
  server_url=args.server_url,
232
288
  api_key=args.api_key,
233
- pipeline_execution_id=args.pipeline_execution_id,
289
+ pipeline_execution_id=pipeline_execution_id,
234
290
  pipeline_definition_id=args.pipeline_definition_id,
235
291
  )
236
292
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: alloy-runtime-sdk
3
- Version: 0.2.97
3
+ Version: 0.2.99
4
4
  Summary: Python SDK for Alloy Runtime - client, pipeline, and logging
5
5
  Keywords: alloy,api,client,python,sdk
6
6
  Classifier: Development Status :: 3 - Alpha
@@ -13,7 +13,7 @@ Description-Content-Type: text/markdown
13
13
  Requires-Dist: httpx==0.28.1
14
14
  Requires-Dist: pydantic==2.12.5
15
15
  Requires-Dist: structlog==25.5.0
16
- Requires-Dist: alloy-runtime-types==0.2.97
16
+ Requires-Dist: alloy-runtime-types==0.2.99
17
17
  Requires-Dist: uuid-extension==0.2.0
18
18
  Requires-Dist: psycopg[binary]==3.3.3
19
19
 
@@ -1,6 +1,6 @@
1
1
  httpx==0.28.1
2
2
  pydantic==2.12.5
3
3
  structlog==25.5.0
4
- alloy-runtime-types==0.2.97
4
+ alloy-runtime-types==0.2.99
5
5
  uuid-extension==0.2.0
6
6
  psycopg[binary]==3.3.3
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "alloy-runtime-sdk"
7
- version = "0.2.97"
7
+ version = "0.2.99"
8
8
  description = "Python SDK for Alloy Runtime - client, pipeline, and logging"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.13"
@@ -20,7 +20,7 @@ dependencies = [
20
20
  "httpx==0.28.1",
21
21
  "pydantic==2.12.5",
22
22
  "structlog==25.5.0",
23
- "alloy-runtime-types==0.2.97",
23
+ "alloy-runtime-types==0.2.99",
24
24
  "uuid-extension==0.2.0",
25
25
  "psycopg[binary]==3.3.3",
26
26
  ]