@hyperframes/gcp-cloud-run 0.7.71 → 0.7.72

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.
@@ -26,9 +26,23 @@ main:
26
26
  - planOutputGcsPrefix: ${args.PlanOutputGcsPrefix}
27
27
  - outputGcsUri: ${args.OutputGcsUri}
28
28
  - config: ${args.Config}
29
+ # Backward-compatible default. v2 is accepted only through an
30
+ # explicit top-level PlanProtocol opt-in.
31
+ - planProtocol: ${default(map.get(args, "PlanProtocol"), "v1")}
29
32
 
30
33
  # ── Plan (Activity A) ────────────────────────────────────────────────────
31
- - plan:
34
+ - selectPlanProtocol:
35
+ switch:
36
+ - condition: ${planProtocol == "v1"}
37
+ next: planV1
38
+ - condition: ${planProtocol == "v2"}
39
+ next: planV2
40
+ next: unsupportedPlanProtocol
41
+ - unsupportedPlanProtocol:
42
+ raise:
43
+ code: PLAN_PROTOCOL_UNSUPPORTED
44
+ message: ${"PlanProtocol must be v1 or v2; got " + string(planProtocol)}
45
+ - planV1:
32
46
  try:
33
47
  call: http.post
34
48
  args:
@@ -36,22 +50,69 @@ main:
36
50
  timeout: 1800
37
51
  auth:
38
52
  type: OIDC
53
+ audience: ${serviceUrl}
39
54
  body:
40
55
  Action: plan
56
+ PlanProtocol: v1
41
57
  ProjectGcsUri: ${projectGcsUri}
42
58
  PlanOutputGcsPrefix: ${planOutputGcsPrefix}
43
59
  Config: ${config}
44
- result: planResp
60
+ result: planRespV1
45
61
  retry:
46
62
  predicate: ${retryable}
47
- max_retries: 4
63
+ max_retries: 6
48
64
  backoff:
49
65
  initial_delay: 2
50
66
  max_delay: 60
51
67
  multiplier: 2
52
- - capturePlan:
68
+ next: capturePlanV1
69
+ - capturePlanV1:
70
+ assign:
71
+ - planResult: ${planRespV1.body}
72
+ next: validatePlanResult
73
+ - planV2:
74
+ try:
75
+ call: http.post
76
+ args:
77
+ url: ${serviceUrl}
78
+ timeout: 1800
79
+ auth:
80
+ type: OIDC
81
+ audience: ${serviceUrl}
82
+ body:
83
+ Action: plan
84
+ PlanProtocol: v2
85
+ ProjectGcsUri: ${projectGcsUri}
86
+ PlanOutputGcsPrefix: ${planOutputGcsPrefix}
87
+ Config: ${config}
88
+ result: planRespV2
89
+ retry:
90
+ predicate: ${retryable}
91
+ max_retries: 6
92
+ backoff:
93
+ initial_delay: 2
94
+ max_delay: 60
95
+ multiplier: 2
96
+ next: capturePlanV2
97
+ - capturePlanV2:
98
+ assign:
99
+ - planResult: ${planRespV2.body}
100
+ next: validatePlanResult
101
+ - validatePlanResult:
102
+ # Fail closed before fan-out. A v2 render may never fall back to a
103
+ # v1 PlanGcsUri, and a v1 render may never consume v2 locators.
104
+ switch:
105
+ - condition: ${planProtocol == "v1" and (not("PlanProtocol" in planResult) or planResult.PlanProtocol == "v1") and ("PlanGcsUri" in planResult) and not("PlanV2ManifestGcsUri" in planResult) and not("PlanV2ArtifactGcsPrefix" in planResult)}
106
+ next: captureChunkCount
107
+ - condition: ${planProtocol == "v2" and ("PlanProtocol" in planResult) and planResult.PlanProtocol == "v2" and ("PlanV2ManifestGcsUri" in planResult) and ("PlanV2ArtifactGcsPrefix" in planResult) and not("PlanGcsUri" in planResult)}
108
+ next: captureChunkCount
109
+ next: planProtocolLocatorMismatch
110
+ - planProtocolLocatorMismatch:
111
+ raise:
112
+ code: PLAN_PROTOCOL_LOCATOR_MISMATCH
113
+ message: "Plan response did not match the selected protocol's disjoint locator contract."
114
+ - captureChunkCount:
53
115
  assign:
54
- - planResult: ${planResp.body}
55
116
  - chunkCount: ${planResult.ChunkCount}
56
117
 
57
118
  # ── BuildChunkList + AssertChunkCount ──────────────────────────────────────
@@ -98,7 +159,12 @@ main:
98
159
  value: idx
99
160
  in: ${chunkIndexes}
100
161
  steps:
101
- - renderOneChunk:
162
+ - selectChunkProtocol:
163
+ switch:
164
+ - condition: ${planProtocol == "v2"}
165
+ next: renderOneChunkV2
166
+ next: renderOneChunkV1
167
+ - renderOneChunkV1:
102
168
  try:
103
169
  call: http.post
104
170
  args:
@@ -106,8 +172,10 @@ main:
106
172
  timeout: 1800
107
173
  auth:
108
174
  type: OIDC
175
+ audience: ${serviceUrl}
109
176
  body:
110
177
  Action: renderChunk
178
+ PlanProtocol: v1
111
179
  ChunkIndex: ${idx}
112
180
  PlanGcsUri: ${planResult.PlanGcsUri}
113
181
  PlanHash: ${planResult.PlanHash}
@@ -121,13 +189,46 @@ main:
121
189
  initial_delay: 2
122
190
  max_delay: 60
123
191
  multiplier: 2
192
+ next: storeChunk
193
+ - renderOneChunkV2:
194
+ try:
195
+ call: http.post
196
+ args:
197
+ url: ${serviceUrl}
198
+ timeout: 1800
199
+ auth:
200
+ type: OIDC
201
+ audience: ${serviceUrl}
202
+ body:
203
+ Action: renderChunk
204
+ PlanProtocol: v2
205
+ ChunkIndex: ${idx}
206
+ PlanV2ManifestGcsUri: ${planResult.PlanV2ManifestGcsUri}
207
+ PlanV2ArtifactGcsPrefix: ${planResult.PlanV2ArtifactGcsPrefix}
208
+ PlanHash: ${planResult.PlanHash}
209
+ ChunkOutputGcsPrefix: ${planOutputGcsPrefix}
210
+ Format: ${planResult.Format}
211
+ result: chunkResp
212
+ retry:
213
+ predicate: ${retryable}
214
+ max_retries: 4
215
+ backoff:
216
+ initial_delay: 2
217
+ max_delay: 60
218
+ multiplier: 2
219
+ next: storeChunk
124
220
  - storeChunk:
125
221
  assign:
126
222
  - chunkUris[idx]: ${chunkResp.body.ChunkGcsUri}
127
223
  - chunkResults[idx]: ${chunkResp.body}
128
224
 
129
225
  # ── Assemble (Activity C) ──────────────────────────────────────────────────
130
- - assemble:
226
+ - selectAssembleProtocol:
227
+ switch:
228
+ - condition: ${planProtocol == "v2"}
229
+ next: assembleV2
230
+ next: assembleV1
231
+ - assembleV1:
131
232
  try:
132
233
  call: http.post
133
234
  args:
@@ -135,8 +236,10 @@ main:
135
236
  timeout: 1800
136
237
  auth:
137
238
  type: OIDC
239
+ audience: ${serviceUrl}
138
240
  body:
139
241
  Action: assemble
242
+ PlanProtocol: v1
140
243
  PlanGcsUri: ${planResult.PlanGcsUri}
141
244
  ChunkGcsUris: ${chunkUris}
142
245
  AudioGcsUri: ${planResult.AudioGcsUri}
@@ -154,6 +257,38 @@ main:
154
257
  initial_delay: 2
155
258
  max_delay: 60
156
259
  multiplier: 2
260
+ next: done
261
+ - assembleV2:
262
+ try:
263
+ call: http.post
264
+ args:
265
+ url: ${serviceUrl}
266
+ timeout: 1800
267
+ auth:
268
+ type: OIDC
269
+ audience: ${serviceUrl}
270
+ body:
271
+ Action: assemble
272
+ PlanProtocol: v2
273
+ PlanV2ManifestGcsUri: ${planResult.PlanV2ManifestGcsUri}
274
+ PlanV2ArtifactGcsPrefix: ${planResult.PlanV2ArtifactGcsPrefix}
275
+ PlanHash: ${planResult.PlanHash}
276
+ ChunkGcsUris: ${chunkUris}
277
+ # Audio is an assembler-scoped v2 artifact and is materialized
278
+ # from the manifest, never carried through a v1 AudioGcsUri.
279
+ AudioGcsUri: null
280
+ OutputGcsUri: ${outputGcsUri}
281
+ Format: ${planResult.Format}
282
+ Cfr: ${("cfr" in config) and config.cfr}
283
+ result: assembleResp
284
+ retry:
285
+ predicate: ${retryable}
286
+ max_retries: 4
287
+ backoff:
288
+ initial_delay: 2
289
+ max_delay: 60
290
+ multiplier: 2
291
+ next: done
157
292
 
158
293
  - done:
159
294
  return:
@@ -161,9 +296,11 @@ main:
161
296
  Chunks: ${chunkResults}
162
297
  Assemble: ${assembleResp.body}
163
298
 
164
- # Retry predicate: retry transient/server failures (429 + 5xx), never the
165
- # handler's non-retryable 400s (bad input, plan-hash mismatch, unsupported
166
- # format, …). Connection / timeout errors carry no `.code`; retry those too.
299
+ # Retry predicate: retry transient/server failures (403 from Cloud Run IAM
300
+ # propagation, 429, and 5xx), never the handler's non-retryable 400s (bad
301
+ # input, plan-hash mismatch, unsupported format, …). The handler does not emit
302
+ # 403, so that status is always from Cloud Run's authentication edge.
303
+ # Connection / timeout errors carry no `.code`; retry those too.
167
304
  retryable:
168
305
  params: [e]
169
306
  steps:
@@ -173,6 +310,8 @@ retryable:
173
310
  return: true
174
311
  - condition: ${e.code == 429}
175
312
  return: true
313
+ - condition: ${e.code == 403}
314
+ return: true
176
315
  - condition: ${e.code >= 500 and e.code < 600}
177
316
  return: true
178
317
  - nonRetryable: