ap-client 0.2.1__tar.gz → 0.3.0.dev0__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: ap-client
3
- Version: 0.2.1
3
+ Version: 0.3.0.dev0
4
4
  Summary: Agent Platform API Client & CLI
5
5
  Requires-Python: >=3.10
6
6
  Requires-Dist: pyyaml>=6.0
@@ -991,6 +991,7 @@ class APIClient:
991
991
  runner: Optional[str] = None,
992
992
  runner_options: Optional[dict] = None,
993
993
  idempotency_key: Optional[str] = None,
994
+ max_failure_retries: int = 0,
994
995
  # ─── Scheduling hints ─────────────────────────────────────────
995
996
  priority: Optional[str] = None,
996
997
  priority_weight: Optional[int] = None,
@@ -1043,6 +1044,7 @@ class APIClient:
1043
1044
  runner=runner,
1044
1045
  runner_options=runner_options,
1045
1046
  idempotency_key=idempotency_key,
1047
+ max_failure_retries=max_failure_retries,
1046
1048
  priority=priority,
1047
1049
  priority_weight=priority_weight,
1048
1050
  resource_mode=resource_mode,
@@ -1093,6 +1095,7 @@ class APIClient:
1093
1095
  runner: Optional[str] = None,
1094
1096
  runner_options: Optional[dict] = None,
1095
1097
  idempotency_key: Optional[str] = None,
1098
+ max_failure_retries: int = 0,
1096
1099
  # ─── Scheduling hints ─────────────────────────────────────────
1097
1100
  priority: Optional[str] = None,
1098
1101
  priority_weight: Optional[int] = None,
@@ -1179,6 +1182,8 @@ class APIClient:
1179
1182
  body["runner_options"] = runner_options
1180
1183
  if idempotency_key is not None:
1181
1184
  body["idempotency_key"] = idempotency_key
1185
+ if max_failure_retries:
1186
+ body["max_failure_retries"] = max_failure_retries
1182
1187
 
1183
1188
  # Scheduling hints
1184
1189
  if priority is not None:
@@ -205,6 +205,7 @@ def _build_job_create_retry_command(
205
205
  concurrency: Optional[int],
206
206
  batch_size: int,
207
207
  trials: Optional[int] = None,
208
+ max_failure_retries: int = 0,
208
209
  wait: bool,
209
210
  wait_interval: float,
210
211
  wait_timeout: Optional[float],
@@ -256,6 +257,8 @@ def _build_job_create_retry_command(
256
257
  args.extend(["--batch-size", str(batch_size)])
257
258
  if trials is not None:
258
259
  args.extend(["--trials", str(trials)])
260
+ if max_failure_retries:
261
+ args.extend(["--max-failure-retries", str(max_failure_retries)])
259
262
  if wait:
260
263
  args.append("--wait")
261
264
  if wait_interval != 5.0:
@@ -924,7 +927,10 @@ def _print_params_plain(params: Any, masked_params: list) -> None:
924
927
  rows: list[tuple[str, Any]] = []
925
928
  for key, value in params.items():
926
929
  display_value = _format_plain_value(value)
927
- if str(key) in masked_paths and value == "***":
930
+ # 直接信任 masked_params 路径:服务端掩码形态已扩展为保留首尾(如
931
+ # sk-***890 / ****),不能再按值严格等于 "***" 判断,否则形态变化后
932
+ # (masked) 标识静默丢失
933
+ if str(key) in masked_paths:
928
934
  display_value = f"{display_value} (masked)"
929
935
  rows.append((str(key), display_value))
930
936
  _print_key_values(rows, skip_empty=False)
@@ -1078,6 +1084,7 @@ def _idempotency_item_key(
1078
1084
  queue: Optional[str],
1079
1085
  account_pool: Optional[str],
1080
1086
  resource_profile_id: Optional[str] = None,
1087
+ max_failure_retries: int = 0,
1081
1088
  ) -> str:
1082
1089
  # Client-supplied item keys are authoritative; server hashing is only a
1083
1090
  # fallback for non-CLI callers, so this payload intentionally need not
@@ -1097,6 +1104,8 @@ def _idempotency_item_key(
1097
1104
  }
1098
1105
  if resource_profile_id is not None:
1099
1106
  payload_data["resource_profile_id"] = resource_profile_id
1107
+ if max_failure_retries:
1108
+ payload_data["max_failure_retries"] = max_failure_retries
1100
1109
  payload = json.dumps(
1101
1110
  payload_data,
1102
1111
  sort_keys=True,
@@ -2886,6 +2895,12 @@ def job_create(
2886
2895
  "--idempotency-key",
2887
2896
  help="UUID4 key for retrying the same logical submission; providing one enables idempotency",
2888
2897
  ),
2898
+ max_failure_retries: int = typer.Option(
2899
+ 0,
2900
+ "--max-failure-retries",
2901
+ min=0,
2902
+ help="Maximum automatic retries after each Job fails (default: 0)",
2903
+ ),
2889
2904
  dry_run: bool = typer.Option(
2890
2905
  False,
2891
2906
  "--dry-run",
@@ -3227,6 +3242,7 @@ def job_create(
3227
3242
  runner=runner,
3228
3243
  runner_options=runner_options_dict,
3229
3244
  idempotency_key=submission_idempotency_key,
3245
+ max_failure_retries=max_failure_retries,
3230
3246
  group_id=group_id,
3231
3247
  model_base_url_collection=model_base_url_collection_list,
3232
3248
  group_post_process=group_post_process_dict,
@@ -3281,6 +3297,7 @@ def job_create(
3281
3297
  concurrency=concurrency,
3282
3298
  batch_size=batch_size,
3283
3299
  trials=trials,
3300
+ max_failure_retries=max_failure_retries,
3284
3301
  wait=wait,
3285
3302
  wait_interval=wait_interval,
3286
3303
  wait_timeout=wait_timeout,
@@ -3328,6 +3345,7 @@ def job_create(
3328
3345
  runner=runner,
3329
3346
  runner_options=runner_options_dict,
3330
3347
  idempotency_key=submission_idempotency_key,
3348
+ max_failure_retries=max_failure_retries,
3331
3349
  group_id=group_id,
3332
3350
  model_base_url_collection=model_base_url_collection_list,
3333
3351
  priority=priority,
@@ -3521,6 +3539,7 @@ def job_create(
3521
3539
  overrides=overrides,
3522
3540
  concurrency=concurrency,
3523
3541
  batch_size=batch_size,
3542
+ max_failure_retries=max_failure_retries,
3524
3543
  wait=wait,
3525
3544
  wait_interval=wait_interval,
3526
3545
  wait_timeout=wait_timeout,
@@ -3630,6 +3649,7 @@ def job_create(
3630
3649
  queue=queue,
3631
3650
  account_pool=account_pool,
3632
3651
  resource_profile_id=resource_profile_id,
3652
+ max_failure_retries=max_failure_retries,
3633
3653
  )
3634
3654
  batch.append(item)
3635
3655
  return batch
@@ -3653,6 +3673,7 @@ def job_create(
3653
3673
  enable_otel_tracing=enable_otel_tracing,
3654
3674
  runner=runner,
3655
3675
  runner_options=runner_options_dict,
3676
+ max_failure_retries=max_failure_retries,
3656
3677
  priority=priority,
3657
3678
  priority_weight=priority_weight,
3658
3679
  resource_mode=resource_mode,
@@ -3694,6 +3715,7 @@ def job_create(
3694
3715
  runner=runner,
3695
3716
  runner_options=runner_options_dict,
3696
3717
  idempotency_key=submission_idempotency_key,
3718
+ max_failure_retries=max_failure_retries,
3697
3719
  priority=priority,
3698
3720
  priority_weight=priority_weight,
3699
3721
  resource_mode=resource_mode,
@@ -3749,6 +3771,7 @@ def job_create(
3749
3771
  runner=runner,
3750
3772
  runner_options=runner_options_dict,
3751
3773
  idempotency_key=submission_idempotency_key,
3774
+ max_failure_retries=max_failure_retries,
3752
3775
  priority=priority,
3753
3776
  priority_weight=priority_weight,
3754
3777
  resource_mode=resource_mode,
@@ -3843,6 +3866,7 @@ def job_create(
3843
3866
  enable_otel_tracing=enable_otel_tracing,
3844
3867
  runner=runner,
3845
3868
  runner_options=runner_options_dict,
3869
+ max_failure_retries=max_failure_retries,
3846
3870
  priority=priority,
3847
3871
  priority_weight=priority_weight,
3848
3872
  resource_mode=resource_mode,
@@ -3878,6 +3902,7 @@ def job_create(
3878
3902
  runner=runner,
3879
3903
  runner_options=runner_options_dict,
3880
3904
  idempotency_key=submission_idempotency_key,
3905
+ max_failure_retries=max_failure_retries,
3881
3906
  priority=priority,
3882
3907
  priority_weight=priority_weight,
3883
3908
  resource_mode=resource_mode,
@@ -3923,6 +3948,7 @@ def job_create(
3923
3948
  runner=runner,
3924
3949
  runner_options=runner_options_dict,
3925
3950
  idempotency_key=submission_idempotency_key,
3951
+ max_failure_retries=max_failure_retries,
3926
3952
  priority=priority,
3927
3953
  priority_weight=priority_weight,
3928
3954
  resource_mode=resource_mode,
@@ -164,7 +164,7 @@ def _print_profile_plain(profile: dict) -> None:
164
164
  if not isinstance(spec, dict):
165
165
  return
166
166
 
167
- # Submission control fields (underscore-prefixed and well-known scalars)
167
+ # Submission control fields (underscore-prefixed and well-known spec fields)
168
168
  submission_keys = (
169
169
  ("_submit_mode", "Submit Mode"),
170
170
  ("_dataset_key", "Dataset Key"),
@@ -172,6 +172,7 @@ def _print_profile_plain(profile: dict) -> None:
172
172
  ("batch_size", "Batch Size"),
173
173
  ("trials", "Trials"),
174
174
  ("trials_mode", "Trials Mode"),
175
+ ("job_tags", "Job Tags"),
175
176
  ("agenthub_revision", "Agenthub Revision"),
176
177
  )
177
178
  submission_rows = [
@@ -49,7 +49,7 @@ def wait_for_job(
49
49
  continue
50
50
  raise
51
51
  _print_job_status(job, printer)
52
- if job.get("status") in TERMINAL_JOB_STATUSES:
52
+ if job.get("status") in TERMINAL_JOB_STATUSES and not job.get("retry_pending", False):
53
53
  return job
54
54
  _sleep_until_next_poll(interval, deadline, "job", job_id, timeout)
55
55
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "ap-client"
7
- version = "0.2.1"
7
+ version = "0.3.0.dev0"
8
8
  description = "Agent Platform API Client & CLI"
9
9
  readme = { text = "A lightweight Python SDK and command line interface for Agent Platform. It provides helpers for configuring API access and managing templates, datasets, jobs, and groups.", content-type = "text/markdown" }
10
10
  requires-python = ">=3.10"