phronomy 0.24.1 → 0.25.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/README.md +2 -0
- data/docs/features.md +2 -0
- data/lib/phronomy/blocking.rb +34 -0
- data/lib/phronomy/engine/concurrency/offload_pool.rb +8 -0
- data/lib/phronomy/engine/task.rb +23 -0
- data/lib/phronomy/version.rb +1 -1
- data/sig/phronomy/runtime.rbs +9 -0
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 636ce578204172927316a89f0f65a2bdfda49140822da98cd1eec9230d821105
|
|
4
|
+
data.tar.gz: 8d776e0ab9bf2775af4e23f77b0b29968a3d4962f8fbd877d3fe9574a3efb306
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 81a2b295d5fb03d4cd03c6f3ceabca7b62f4e635fc5dd6ed3db31b1c5f59c6031fc38958895a1fc7b8e9fc75394a81181d51529ebb86f310e85cd2300a9395af
|
|
7
|
+
data.tar.gz: f701f8fd0be60d655e9676c8cbdfec93606cca20769da90b7c67617c9d876cbde51bf18a42531b7cf70079aa12863af022acd21500fe40cff64c04d5a70df6ab
|
data/CHANGELOG.md
CHANGED
|
@@ -12,8 +12,18 @@ Release history for 0.14.0 and earlier is archived in
|
|
|
12
12
|
|
|
13
13
|
## [Unreleased]
|
|
14
14
|
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## [0.25.0] - 2026-09-12
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
- Public `Task.completed` / `Task.failed` factories for application-owned settled results.
|
|
22
|
+
- `Blocking.call_async` for non-waiting submission of synchronous application work.
|
|
23
|
+
|
|
15
24
|
### Fixed
|
|
16
25
|
|
|
26
|
+
- Reject waiting OffloadPool admission from EventLoop before creating an operation.
|
|
17
27
|
- Add runtime dependency constraint `json < 3` to prevent Faraday/RubyLLM JSON
|
|
18
28
|
parser incompatibilities from resolving in consumer environments.
|
|
19
29
|
|
data/README.md
CHANGED
|
@@ -23,6 +23,8 @@ tracking `main` directly.
|
|
|
23
23
|
- **EventLoop + FSMSession** — the framework control plane for logical lifecycle coordination.
|
|
24
24
|
- **OffloadPool** — bounded operating-system-thread execution boundary for synchronous work that must not run on EventLoop.
|
|
25
25
|
- **Task** — the common thread-free completion handle returned by Phronomy asynchronous APIs, including OffloadPool-backed work.
|
|
26
|
+
- **Task.completed / Task.failed** — already-settled application results without starting execution.
|
|
27
|
+
- **Blocking.call_async** — submits synchronous application work to the existing bounded OffloadPool without waiting for queue space.
|
|
26
28
|
- **Journal / Context Policy / Manifest** — canonical history plus per-LLM-call context selection.
|
|
27
29
|
|
|
28
30
|
See [Features and Application Programming Interface (API) stability](docs/features.md) for the full feature matrix.
|
data/docs/features.md
CHANGED
|
@@ -66,6 +66,8 @@ rather than implicitly inheriting the parent revision. The Stable
|
|
|
66
66
|
| **`stream_callback_error_policy`** — Terminal event callback error policy (`:report` / `:fail_task`) | Beta |
|
|
67
67
|
| **Task completion contract** — `Task` is the common caller-facing completion handle for EventLoop/FSMSession lifecycles and OffloadPool work | Beta |
|
|
68
68
|
| **`Task#map`** — Application-level Task result transformation and error propagation | Stable |
|
|
69
|
+
| **Settled Task factories** — Public `Task.completed` / `Task.failed` represent already available application results without starting execution | Beta |
|
|
70
|
+
| **Blocking.call_async** — Public non-waiting admission of synchronous application work to the existing OffloadPool, returning a Task | Beta |
|
|
69
71
|
| **CancellationToken** — Cooperative cancellation with explicit `cancel!`, lazy monotonic deadlines, and callback registration | Experimental |
|
|
70
72
|
| **Tool `execution_mode`** — `:cooperative` for short EventLoop-safe work; `:offloaded` for synchronous work that must stay off EventLoop | Experimental |
|
|
71
73
|
| **OffloadPool sizing** — `offload_pool_size` / `offload_queue_size`; named pools available for application-owned isolation | Beta |
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Phronomy
|
|
4
|
+
# Public adapter for synchronous application I/O or computation.
|
|
5
|
+
# This uses the existing bounded OffloadPool. It does not execute logical
|
|
6
|
+
# waits, persist work, force-stop a running block, or create a scheduler.
|
|
7
|
+
module Blocking
|
|
8
|
+
# Submits synchronous application work to the default Runtime OffloadPool.
|
|
9
|
+
# Admission never waits for queue space. Admission StandardError failures
|
|
10
|
+
# become failed Tasks; accepted work retains the pool's Task unchanged.
|
|
11
|
+
# A timeout/cancellation can settle that Task before a running worker exits.
|
|
12
|
+
# The block must not wait for another Agent, Workflow, or Task.
|
|
13
|
+
# @param timeout [Numeric, nil] operation deadline, including queue time
|
|
14
|
+
# @param cancellation_token [Phronomy::Concurrency::CancellationToken, nil]
|
|
15
|
+
# @yield synchronous application work
|
|
16
|
+
# @return [Phronomy::Task] original accepted Task or failed admission Task
|
|
17
|
+
# @raise [ArgumentError] if no block is supplied
|
|
18
|
+
# @api public
|
|
19
|
+
def self.call_async(timeout: nil, cancellation_token: nil, &block)
|
|
20
|
+
raise ArgumentError, "Blocking.call_async requires a block" unless block
|
|
21
|
+
|
|
22
|
+
begin
|
|
23
|
+
Phronomy::Runtime.instance.offload.submit(
|
|
24
|
+
on_full: :raise,
|
|
25
|
+
timeout: timeout,
|
|
26
|
+
cancellation_token: cancellation_token,
|
|
27
|
+
&block
|
|
28
|
+
)
|
|
29
|
+
rescue => error
|
|
30
|
+
Phronomy::Task.failed(error, name: "blocking-admission-failed")
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -347,6 +347,9 @@ module Phronomy
|
|
|
347
347
|
# Synchronous queue admission may delay return from this method when
|
|
348
348
|
# +on_full: :wait+ is used. EventLoop-owned framework paths therefore submit
|
|
349
349
|
# with +on_full: :raise+ and handle backpressure asynchronously.
|
|
350
|
+
# EventLoop callers requesting a waiting policy are rejected before any
|
|
351
|
+
# operation, timer, or cancellation subscription is created. Application
|
|
352
|
+
# code should use Phronomy::Blocking.call_async.
|
|
350
353
|
#
|
|
351
354
|
# @param timeout [Numeric, nil] operation-wide deadline in seconds
|
|
352
355
|
# @param cancellation_token [CancellationToken, nil] operation-wide token
|
|
@@ -359,6 +362,7 @@ module Phronomy
|
|
|
359
362
|
# @raise [Phronomy::PoolShutdownError] when the pool has been shut down
|
|
360
363
|
# @raise [Phronomy::BackpressureError] when +on_full: :raise+ and queue is full
|
|
361
364
|
# @raise [Phronomy::TimeoutError] when +on_full: :timeout+ exceeds +full_timeout+
|
|
365
|
+
# @raise [Phronomy::EventLoopReentrancyError] for waiting admission on EventLoop
|
|
362
366
|
# @api private
|
|
363
367
|
def submit(
|
|
364
368
|
timeout: nil,
|
|
@@ -367,6 +371,10 @@ module Phronomy
|
|
|
367
371
|
full_timeout: nil,
|
|
368
372
|
&block
|
|
369
373
|
)
|
|
374
|
+
if Phronomy::Runtime.in_event_loop_context? && on_full != :raise
|
|
375
|
+
raise Phronomy::EventLoopReentrancyError,
|
|
376
|
+
"OffloadPool admission cannot wait on EventLoop; use on_full: :raise"
|
|
377
|
+
end
|
|
370
378
|
raise Phronomy::PoolShutdownError, "pool has been shut down" if @shutdown
|
|
371
379
|
|
|
372
380
|
submitted_at = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
data/lib/phronomy/engine/task.rb
CHANGED
|
@@ -23,6 +23,29 @@ module Phronomy
|
|
|
23
23
|
new(name: name, parent: parent)
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
+
# Public factories for already-settled values. No execution is started.
|
|
27
|
+
# Always create a base Task: there is no physical worker to supervise.
|
|
28
|
+
# @param value [Object] already available result
|
|
29
|
+
# @param name [String, nil] optional diagnostic name
|
|
30
|
+
# @return [Phronomy::Task] a completed base Task
|
|
31
|
+
# @api public
|
|
32
|
+
def self.completed(value = nil, name: nil)
|
|
33
|
+
Phronomy::Task.deferred(name: name).tap { |task| task.complete(value) }
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Represents an already known failure without raising the stored error.
|
|
37
|
+
# Observation through wait_result raises it; on_complete receives it.
|
|
38
|
+
# @param error [Exception] original failure object
|
|
39
|
+
# @param name [String, nil] optional diagnostic name
|
|
40
|
+
# @return [Phronomy::Task] a failed base Task
|
|
41
|
+
# @raise [ArgumentError] if error is not an Exception
|
|
42
|
+
# @api public
|
|
43
|
+
def self.failed(error, name: nil)
|
|
44
|
+
raise ArgumentError, "error must be an Exception" unless error.is_a?(Exception)
|
|
45
|
+
|
|
46
|
+
Phronomy::Task.deferred(name: name).tap { |task| task.fail(error) }
|
|
47
|
+
end
|
|
48
|
+
|
|
26
49
|
attr_reader :name, :parent
|
|
27
50
|
|
|
28
51
|
# @api private
|
data/lib/phronomy/version.rb
CHANGED
data/sig/phronomy/runtime.rbs
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
module Phronomy
|
|
2
2
|
class Task[A]
|
|
3
|
+
def self.completed: [V] (V value, ?name: String?) -> Task[V]
|
|
4
|
+
| (?name: String?) -> Task[nil]
|
|
5
|
+
def self.failed: (Exception error, ?name: String?) -> Task[untyped]
|
|
3
6
|
attr_reader name: String?
|
|
4
7
|
attr_reader parent: Task[untyped]?
|
|
5
8
|
|
|
@@ -38,3 +41,9 @@ module Phronomy
|
|
|
38
41
|
def initialize: (?user_id: String?, ?cancellation_token: Concurrency::CancellationToken?, ?deadline: untyped, ?token_budget: Integer?, ?approval_policy: untyped, ?redaction_policy: untyped, ?task_id: String?, ?parent_task_id: String?) -> void
|
|
39
42
|
end
|
|
40
43
|
end
|
|
44
|
+
|
|
45
|
+
module Phronomy
|
|
46
|
+
module Blocking
|
|
47
|
+
def self.call_async: [V] (?timeout: Numeric?, ?cancellation_token: Concurrency::CancellationToken?) { () -> V } -> Task[V]
|
|
48
|
+
end
|
|
49
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: phronomy
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.25.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Raizo T.C.S
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-09-
|
|
11
|
+
date: 2026-09-12 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: ruby_llm
|
|
@@ -252,6 +252,7 @@ files:
|
|
|
252
252
|
- lib/phronomy/agent_already_exists_error.rb
|
|
253
253
|
- lib/phronomy/agent_busy_error.rb
|
|
254
254
|
- lib/phronomy/agent_purged_error.rb
|
|
255
|
+
- lib/phronomy/blocking.rb
|
|
255
256
|
- lib/phronomy/canonical_json.rb
|
|
256
257
|
- lib/phronomy/configuration.rb
|
|
257
258
|
- lib/phronomy/content_store/base.rb
|