HsbcJone opened a new pull request, #1386:
URL: https://github.com/apache/flink-agents/pull/1386

   Linked issue: Closes #1384. Relates to #1378.
   
   ### Purpose of change
   
   Callers set `retry-wait-interval`, `async.batch.timeout`, and 
`short-term-memory.state-ttl` with `java.time.Duration` or 
`datetime.timedelta`. In YAML the value is an integer plus a unit, such as `30 
s` or `5 min`.
   
   These three framework settings used bare numbers with different units 
(milliseconds, milliseconds, and seconds). A duration type keeps the unit in 
the value. This is only the framework slice. Built-in resource and SDK timeout 
parameters are unchanged. No other numeric framework duration option was found.
   
   `AgentConfiguration.get` parses a stored string, or returns a duration the 
option already holds. `set` writes a canonical string (`60 s` becomes `1 min`) 
so agent-plan JSON stays text. A positive `async.batch.timeout` is the 
`ctx.gather` deadline; zero or negative disables it. A positive 
`short-term-memory.state-ttl` is passed to Flink state TTL; zero or negative 
leaves TTL off. Chat and decision retries sleep for `interval * 2^(N-1)` and 
still record whole seconds on `retryWaitSec` and `total_retry_wait_sec`.
   
   The `.ms` suffix is dropped from the timeout and TTL keys, and from 
`ASYNC_BATCH_TIMEOUT_MS` and `SHORT_TERM_MEMORY_STATE_TTL_MS`. 
`retry-wait-interval` keeps its key. Old keys are rejected rather than read or 
ignored. A bare number is rejected: treating it as milliseconds would keep the 
unit ambiguity this change removes. ISO-8601 is not accepted as a second 
syntax. Values must be whole microseconds so `Duration` and `timedelta` accept 
the same strings (`1000 ns` is `1 us`; `1 ns` is rejected). `m` means minutes. 
A leading `-` is kept so the default `-1 ms` timeout still disables the batch 
timeout.
   
   ### Behavioral Semantics
   
   | Batch timeout | TTL | Retry wait | Result |
   | --- | --- | --- | --- |
   | positive | positive | positive | deadline and state TTL use those 
durations; retry N waits `interval * 2^(N-1)` |
   | zero or negative | zero or negative | zero or negative | timeout off, TTL 
off, retries do not sleep |
   | positive | zero | positive | timeout on, TTL off, retries wait |
   | unset | unset | unset | timeout `-1 ms` (off), TTL `0 ms` (off), retry `1 
s` |
   
   A value cannot be both positive and a disable sentinel. If a removed key is 
present, construction fails before either key is applied.
   
   1. Keys, types, and defaults match on both sides: `async.batch.timeout` `-1 
ms`, `short-term-memory.state-ttl` `0 ms`, `retry-wait-interval` `1 s`.
   2. `30 s`, `30s`, `5 min`, `5m`, `1 h`, `1 d`, `1500 ms`, `60 s` (canonical 
`1 min`), `1000 ns` (canonical `1 us`), `0 s` (canonical `0 ms`), and `-1 ms` 
parse to the same duration on both sides.
   3. A positive batch timeout is the gather deadline. Zero, negative, and the 
default disable it.
   4. A positive TTL is the Flink state TTL. Zero and negative disable it.
   5. Retry N sleeps for `interval * 2^(N-1)` when that product is positive. 
Zero and negative do not sleep. Each reported wait adds only the whole seconds 
of that sleep.
   6. `async.batch.timeout.ms` and `short-term-memory.state-ttl.ms` fail 
construction and `setStr` / `set_str`.
   7. A bare number, a fraction, an unknown unit, or a sub-microsecond value 
fails with a message that names the value and an example such as `30 s`.
   
   Invalid duration text fails when the option is set or read 
(`IllegalArgumentException` / `ValueError`). Removed keys fail at construction 
or on write. A duration that overflows, or a retry product that overflows 
`Duration.multipliedBy` or `toMillis`, raises instead of sleeping a wrapped 
value. Other unknown keys are still ignored. A file that only sets a removed 
timeout key now fails to load.
   
   ### Tests
   
   | Contract | Tests |
   | --- | --- |
   | 1. Keys, types, defaults | 
`DurationFormatTest.optionDefaultsMatchTheDisableSentinels`, 
`test_option_defaults_match_the_disable_sentinels`, 
`test_agent_execution_options_include_parallel_tool_call_options`; parity 
script maps `Duration` to `timedelta` |
   | 2. Shared parse table | `DurationFormatTest.parsesAndFormats`, 
`knownValuesMatchDurationFactories`, `test_parse_and_format` |
   | 3. Timeout disable | 
`durationStringsKeepDisableSentinelsAndRejectBareNumbers`, 
`test_duration_strings_keep_disable_sentinels_and_reject_bare_numbers`; gather 
tests still pass with `-1 ms` and `100 ms` |
   | 4. TTL disable | same configuration tests; `OperatorStateManager` enables 
TTL only when `DurationFormat.isPositive` |
   | 5. Retry sleep and whole seconds | `ChatModelActionRetryTest`, 
`DecisionModelActionTest`, `test_chat_model_action_retry.py`, 
`test_decision_model_action.py` |
   | 6. Removed keys | `removedDurationKeysAreRejected`, 
`test_removed_duration_keys_are_rejected` |
   | 7. Invalid values | `DurationFormatTest.rejectsUnusableText`, 
`rejectsBareNumbersAndSubMicrosecondDurations`, `test_rejects_unusable_text`, 
`test_rejects_bare_numbers` |
   
   Not verified: `check_java_python_config_options_parity.py` was not run (it 
needs a PyFlink gateway). End-to-end jobs and 
`ShortTermMemoryTTLIntegrationTest` were compiled, not executed. A sub-second 
retry was not driven through a model call.
   
   <details>
   <summary>Implementation invariants and supporting evidence</summary>
   
   Canonical form uses the largest unit that divides the value: `d`, `h`, 
`min`, `s`, `ms`, `us`. Zero is `0 ms`. Plan JSON stores that string, not a 
`Duration` object. Java `set` accepts `Duration` only; YAML and map 
construction supply the string that `get` parses. Python `set` accepts 
`timedelta` or the same string. `configuredRetryWait` clamps a negative wait to 
zero. The gather path passes a positive duration through and passes null when 
it is not positive. Labels match Flink (`ns`, `us`/`µs`, `ms`, `s`, `min`/`m`, 
`h`, `d`, plus singular and plural forms).
   
   </details>
   
   ### API
   
   Breaking, before the 1.0 compatibility guarantee. Removed Java constants: 
`ASYNC_BATCH_TIMEOUT_MS`, `SHORT_TERM_MEMORY_STATE_TTL_MS`. Use 
`ASYNC_BATCH_TIMEOUT` and `SHORT_TERM_MEMORY_STATE_TTL`. 
`configuredRetryWaitSec` is `configuredRetryWait` and returns `Duration`. 
`chatWithRetries` takes a `Duration` backoff. Programmatic callers pass 
`Duration` or `timedelta`, not a raw number. YAML `retry-wait-interval: 1` must 
become `1 s`. There is no adapter for the old numbers. Resource and SDK timeout 
parameters are unchanged. `retryWaitSec`, `total_retry_wait_sec`, and the retry 
event fields stay whole seconds.
   
   ### Documentation
   
   - [x] `doc-included`
   - [ ] `doc-needed`
   - [ ] `doc-not-needed`
   
   ### Was this patch authored or co-authored using generative AI tooling?
   
   - [x] Yes
   - [ ] No
   
   Generated-by: Cursor Grok 4.7 (Grok 4.7)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to