phronomy 0.16.0 → 0.18.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/.mutant.yml +8 -9
- data/CHANGELOG.md +151 -1134
- data/CONTRIBUTING.md +28 -16
- data/README.md +69 -1249
- data/benchmark/baseline.json +2 -3
- data/benchmark/bench_agent_invoke.rb +4 -4
- data/benchmark/bench_context_assembler.rb +134 -34
- data/benchmark/bench_regression.rb +26 -6
- data/benchmark/bench_tool_schema.rb +2 -35
- data/docs/changelog/0.14-and-earlier.md +1137 -0
- data/docs/decisions/005-static-knowledge-class-level-cache.md +12 -1
- data/docs/decisions/008-orchestrator-uses-os-threads.md +46 -48
- data/docs/decisions/010-cooperative-first-concurrency.md +155 -228
- data/docs/decisions/011-build-context-as-single-llm-input-authority.md +2 -2
- data/docs/decisions/013-journal-backed-knowledge-as-context-candidates.md +122 -0
- data/docs/features.md +87 -0
- data/docs/getting-started.md +351 -0
- data/docs/migrations/0.15.md +35 -0
- data/docs/migrations/0.16.md +43 -0
- data/docs/runtime-and-concurrency.md +258 -0
- data/examples/workflows/generic_task_event_mapping.rb +14 -6
- data/lib/phronomy/agent/agent_invocation.rb +2 -36
- data/lib/phronomy/agent/agent_invocation_session_builder.rb +157 -94
- data/lib/phronomy/agent/agent_root.rb +1 -2
- data/lib/phronomy/agent/async_event_api.rb +3 -3
- data/lib/phronomy/agent/base.rb +170 -333
- data/lib/phronomy/agent/context/capability/base.rb +177 -298
- data/lib/phronomy/agent/context_assembler.rb +65 -29
- data/lib/phronomy/agent/context_parts/unit_builders/dependency_aware_unit_builder.rb +19 -89
- data/lib/phronomy/agent/context_plan_validator.rb +0 -33
- data/lib/phronomy/agent/execution_coordinator.rb +6 -7
- data/lib/phronomy/agent/journal_projection.rb +28 -2
- data/lib/phronomy/agent/ruby_llm_materializer.rb +2 -111
- data/lib/phronomy/agent/shared_state.rb +48 -138
- data/lib/phronomy/agent/token_budget_resolver.rb +5 -4
- data/lib/phronomy/agent/tool_executor.rb +29 -71
- data/lib/phronomy/agent/tool_invocation.rb +180 -336
- data/lib/phronomy/agent/tool_invocation_session_builder.rb +55 -161
- data/lib/phronomy/agent.rb +6 -10
- data/lib/phronomy/configuration.rb +4 -171
- data/lib/phronomy/diagnostics.rb +12 -41
- data/lib/phronomy/engine/concurrency/async_queue.rb +5 -188
- data/lib/phronomy/engine/concurrency/cancellation_scope.rb +6 -7
- data/lib/phronomy/engine/concurrency/cancellation_token.rb +51 -79
- data/lib/phronomy/engine/concurrency/deadline.rb +2 -3
- data/lib/phronomy/engine/concurrency/offload_pool.rb +696 -0
- data/lib/phronomy/engine/concurrency/pool_registry.rb +5 -5
- data/lib/phronomy/engine/event_loop.rb +89 -190
- data/lib/phronomy/engine/runtime/timer_queue.rb +48 -71
- data/lib/phronomy/engine/runtime/timer_service.rb +13 -21
- data/lib/phronomy/engine/runtime.rb +49 -377
- data/lib/phronomy/engine/task.rb +136 -277
- data/lib/phronomy/llm_adapter/base.rb +14 -14
- data/lib/phronomy/llm_adapter/ruby_llm.rb +3 -4
- data/lib/phronomy/llm_adapter.rb +2 -2
- data/lib/phronomy/llm_context_window/token_budget.rb +8 -79
- data/lib/phronomy/metrics.rb +15 -30
- data/lib/phronomy/multi_agent/fan_out_invocation.rb +146 -0
- data/lib/phronomy/multi_agent/fan_out_session_builder.rb +125 -0
- data/lib/phronomy/multi_agent/handoff.rb +1 -0
- data/lib/phronomy/multi_agent/orchestrator.rb +252 -256
- data/lib/phronomy/multi_agent/team_coordinator.rb +44 -133
- data/lib/phronomy/testing/eval/comparison.rb +23 -0
- data/lib/phronomy/testing/eval/dataset.rb +27 -0
- data/lib/phronomy/testing/eval/eval_case.rb +13 -0
- data/lib/phronomy/testing/eval/eval_result.rb +16 -0
- data/lib/phronomy/testing/eval/metrics.rb +43 -0
- data/lib/phronomy/testing/eval/runner.rb +52 -0
- data/lib/phronomy/testing/eval/scorer/base.rb +15 -0
- data/lib/phronomy/testing/eval/scorer/exact_match.rb +25 -0
- data/lib/phronomy/testing/eval/scorer/includes_scorer.rb +25 -0
- data/lib/phronomy/testing/eval/scorer/llm_judge.rb +46 -0
- data/lib/phronomy/testing/eval/scorer.rb +10 -0
- data/lib/phronomy/testing/eval.rb +9 -0
- data/lib/phronomy/testing/fake_clock.rb +6 -53
- data/lib/phronomy/testing.rb +2 -6
- data/lib/phronomy/tools/agent.rb +141 -6
- data/lib/phronomy/vector_store/async_backend.rb +21 -17
- data/lib/phronomy/vector_store/base.rb +2 -2
- data/lib/phronomy/vector_store/embeddings/base.rb +6 -5
- data/lib/phronomy/vector_store/in_memory.rb +2 -2
- data/lib/phronomy/version.rb +1 -1
- data/lib/phronomy/workflow_runner.rb +2 -4
- data/lib/phronomy.rb +7 -121
- data/scripts/api_snapshot.rb +4 -15
- metadata +24 -38
- data/lib/phronomy/agent/context/knowledge/base.rb +0 -58
- data/lib/phronomy/agent/context/knowledge/entity_knowledge.rb +0 -102
- data/lib/phronomy/agent/context/knowledge/static_knowledge.rb +0 -58
- data/lib/phronomy/agent/fsm_runtime_adapter.rb +0 -210
- data/lib/phronomy/engine/concurrency/blocking_adapter_pool.rb +0 -561
- data/lib/phronomy/engine/runtime/deterministic_scheduler.rb +0 -439
- data/lib/phronomy/engine/runtime/fake_scheduler.rb +0 -165
- data/lib/phronomy/engine/runtime/runtime_metrics.rb +0 -116
- data/lib/phronomy/engine/runtime/scheduler.rb +0 -98
- data/lib/phronomy/engine/runtime/scheduler_timer_adapter.rb +0 -79
- data/lib/phronomy/engine/runtime/task_registry.rb +0 -95
- data/lib/phronomy/engine/runtime/thread_scheduler.rb +0 -30
- data/lib/phronomy/engine/task/backend.rb +0 -80
- data/lib/phronomy/engine/task/deferred_backend.rb +0 -73
- data/lib/phronomy/engine/task/fiber_backend.rb +0 -157
- data/lib/phronomy/engine/task/immediate_backend.rb +0 -89
- data/lib/phronomy/engine/task/mapped_backend.rb +0 -90
- data/lib/phronomy/engine/task/thread_backend.rb +0 -84
- data/lib/phronomy/engine/task_group.rb +0 -265
- data/lib/phronomy/eval/comparison.rb +0 -47
- data/lib/phronomy/eval/dataset.rb +0 -45
- data/lib/phronomy/eval/eval_case.rb +0 -17
- data/lib/phronomy/eval/eval_result.rb +0 -29
- data/lib/phronomy/eval/metrics.rb +0 -66
- data/lib/phronomy/eval/runner.rb +0 -94
- data/lib/phronomy/eval/scorer/base.rb +0 -22
- data/lib/phronomy/eval/scorer/exact_match.rb +0 -31
- data/lib/phronomy/eval/scorer/includes_scorer.rb +0 -32
- data/lib/phronomy/eval/scorer/llm_judge.rb +0 -72
- data/lib/phronomy/eval/scorer.rb +0 -9
- data/lib/phronomy/eval.rb +0 -7
- data/lib/phronomy/knowledge_source.rb +0 -12
- data/lib/phronomy/llm_context_window/assembler.rb +0 -191
- data/lib/phronomy/llm_context_window/context_version_cache.rb +0 -52
- data/lib/phronomy/testing/fake_scheduler.rb +0 -104
- data/lib/phronomy/testing/scheduler_helpers.rb +0 -68
data/benchmark/baseline.json
CHANGED
|
@@ -4,6 +4,5 @@
|
|
|
4
4
|
"tool_params_schema_definition": 19534379.159046534,
|
|
5
5
|
"dispatch_parallel_10": 886.0,
|
|
6
6
|
"cancellation_token_cancelled": 4335060.97443425,
|
|
7
|
-
"cancellation_token_raise_if_cancelled_noop": 3566903.189098373
|
|
8
|
-
|
|
9
|
-
}
|
|
7
|
+
"cancellation_token_raise_if_cancelled_noop": 3566903.189098373
|
|
8
|
+
}
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
# bench_agent_invoke.rb — Agent#invoke framework overhead benchmark.
|
|
4
4
|
#
|
|
5
5
|
# Measures the per-invoke cost of the Phronomy::Agent::Base framework path
|
|
6
|
-
# (context assembly,
|
|
7
|
-
#
|
|
6
|
+
# (context assembly, filter checks, before_llm_input hooks, response handling)
|
|
7
|
+
# with a fully stubbed LLM. No network calls are made.
|
|
8
8
|
#
|
|
9
9
|
# Scenarios:
|
|
10
|
-
# 1. Minimal agent (no tools, no
|
|
10
|
+
# 1. Minimal agent (no tools, no persistent Knowledge) — baseline framework overhead.
|
|
11
11
|
# 2. Tool-aware agent with a registered stub Tool.
|
|
12
12
|
# 3. Agent#stream setup latency (first-chunk time with stubbed stream).
|
|
13
13
|
|
|
@@ -81,7 +81,7 @@ end
|
|
|
81
81
|
bench_tool_class = Class.new(Phronomy::Agent::Base) do
|
|
82
82
|
agent_definition id: "bench-tool", version: 1
|
|
83
83
|
model "stub-model"
|
|
84
|
-
tools
|
|
84
|
+
tools(BenchNullTool => nil)
|
|
85
85
|
|
|
86
86
|
define_method(:build_chat) { |*| BenchStubChat.new(BENCH_RESP) }
|
|
87
87
|
end
|
|
@@ -1,54 +1,154 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# Benchmark: Context
|
|
3
|
+
# Benchmark: Manifest-first Context assembly and Default Context Policy.
|
|
4
4
|
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
5
|
+
# Usage:
|
|
6
|
+
# ruby benchmark/bench_context_assembler.rb
|
|
7
|
+
#
|
|
8
|
+
# Measures:
|
|
9
|
+
# 1. ContextPolicies::Default selection cost for growing canonical candidate sets.
|
|
10
|
+
# 2. ContextAssembler#build_initial end-to-end Manifest construction.
|
|
11
|
+
#
|
|
12
|
+
# No provider call is performed.
|
|
7
13
|
|
|
8
14
|
require "benchmark"
|
|
9
15
|
require_relative "../lib/phronomy"
|
|
10
16
|
|
|
11
|
-
|
|
17
|
+
module BenchContextAssembler
|
|
18
|
+
module_function
|
|
12
19
|
|
|
13
|
-
def
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
def candidate(index)
|
|
21
|
+
category, role = if (index % 10).zero?
|
|
22
|
+
[:knowledge, :user]
|
|
23
|
+
elsif index.even?
|
|
24
|
+
[:assistant_message, :assistant]
|
|
25
|
+
else
|
|
26
|
+
[:external_message, :user]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
Phronomy::Agent::ContextCandidate.new(
|
|
30
|
+
candidate_id: "candidate-#{index}",
|
|
31
|
+
source_kind: :journal,
|
|
32
|
+
category: category,
|
|
33
|
+
role: role,
|
|
34
|
+
content_ref: "content-#{index}",
|
|
35
|
+
record_id: "record-#{index}",
|
|
36
|
+
agent_id: "bench-agent",
|
|
37
|
+
execution_id: "execution-#{index / 4}",
|
|
38
|
+
llm_call_id: nil,
|
|
39
|
+
tool_call_id: nil,
|
|
40
|
+
sequence: index,
|
|
41
|
+
requirement: :optional,
|
|
42
|
+
priority: 0,
|
|
43
|
+
metadata: {
|
|
44
|
+
"estimated_tokens" => 8,
|
|
45
|
+
"source_sequence" => index
|
|
46
|
+
}
|
|
47
|
+
)
|
|
21
48
|
end
|
|
22
|
-
msgs = Array.new(n_messages) { BenchAsmMessage.new("This is a conversation message.") }
|
|
23
|
-
asm.add_messages(msgs)
|
|
24
|
-
asm
|
|
25
|
-
end
|
|
26
49
|
|
|
27
|
-
|
|
50
|
+
def parts
|
|
51
|
+
{
|
|
52
|
+
unit_builder:
|
|
53
|
+
Phronomy::Agent::ContextParts::UnitBuilders::DependencyAwareUnitBuilder.new,
|
|
54
|
+
required_context_resolver:
|
|
55
|
+
Phronomy::Agent::ContextParts::Requirements::RequiredContextResolver.new,
|
|
56
|
+
recent_first_selector:
|
|
57
|
+
Phronomy::Agent::ContextParts::Selectors::RecentFirstSelector.new,
|
|
58
|
+
token_budget_packer:
|
|
59
|
+
Phronomy::Agent::ContextParts::Budget::TokenBudgetPacker.new
|
|
60
|
+
}.freeze
|
|
61
|
+
end
|
|
28
62
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
63
|
+
def request(candidate_count)
|
|
64
|
+
candidates = Array.new(candidate_count) { |i| candidate(i) }
|
|
65
|
+
Phronomy::Agent::ContextRequest.new(
|
|
66
|
+
agent_id: "bench-agent",
|
|
67
|
+
execution_id: "bench-execution",
|
|
68
|
+
call_sequence: 2,
|
|
69
|
+
call_mode: :complete,
|
|
70
|
+
candidates: candidates,
|
|
71
|
+
token_budget: Phronomy::LlmContextWindow::TokenBudget.new(
|
|
72
|
+
context_window: [candidate_count * 16, 4_096].max,
|
|
73
|
+
max_output_tokens: 512
|
|
74
|
+
),
|
|
75
|
+
model_config: {},
|
|
76
|
+
previous_manifest: nil,
|
|
77
|
+
required_coverage: [],
|
|
78
|
+
parts: parts,
|
|
79
|
+
metadata: {"mandatory_token_estimate" => 32}
|
|
80
|
+
)
|
|
33
81
|
end
|
|
34
82
|
|
|
35
|
-
|
|
36
|
-
|
|
83
|
+
def assembler_fixture
|
|
84
|
+
persistence = Phronomy::Persistence::InMemory.new
|
|
85
|
+
agent_class = Class.new(Phronomy::Agent::Base) do
|
|
86
|
+
agent_definition id: "bench-manifest-context-assembler", version: 1
|
|
87
|
+
model "local-model"
|
|
88
|
+
context_window 16_384
|
|
89
|
+
max_output_tokens 1_024
|
|
90
|
+
instructions "Benchmark instruction"
|
|
91
|
+
end
|
|
92
|
+
agent = agent_class.new(
|
|
93
|
+
persistence: persistence,
|
|
94
|
+
knowledge: ["Persistent benchmark knowledge"]
|
|
95
|
+
)
|
|
96
|
+
root = agent.agent_root
|
|
97
|
+
input_ref = persistence.contents.put_text("benchmark input")
|
|
98
|
+
input_record = Phronomy::Agent::JournalRecord.new(
|
|
99
|
+
agent_id: agent.agent_id,
|
|
100
|
+
kind: :external_message,
|
|
101
|
+
channel: :external,
|
|
102
|
+
role: :user,
|
|
103
|
+
content_ref: input_ref,
|
|
104
|
+
context_generation: root.transcript_generation,
|
|
105
|
+
context_candidate: true
|
|
106
|
+
)
|
|
107
|
+
execution = Phronomy::Agent::AgentExecution.start(
|
|
108
|
+
agent_root: root,
|
|
109
|
+
input_record: input_record,
|
|
110
|
+
metadata: {
|
|
111
|
+
"current_input_ref" => input_ref,
|
|
112
|
+
"current_input_record_id" => input_record.record_id
|
|
113
|
+
}
|
|
114
|
+
).with(
|
|
115
|
+
execution_revision: 0,
|
|
116
|
+
working_records: [input_record]
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
[
|
|
120
|
+
Phronomy::Agent::ContextAssembler.new(agent: agent, persistence: persistence),
|
|
121
|
+
root,
|
|
122
|
+
execution
|
|
123
|
+
]
|
|
37
124
|
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
puts "Manifest-first Context benchmark"
|
|
128
|
+
puts "Ruby #{RUBY_VERSION} on #{RUBY_PLATFORM}"
|
|
129
|
+
puts "=" * 72
|
|
38
130
|
|
|
39
|
-
|
|
40
|
-
|
|
131
|
+
policy = Phronomy::Agent::ContextPolicies::Default.new
|
|
132
|
+
policy_requests = [10, 100, 1_000].to_h do |count|
|
|
133
|
+
[count, BenchContextAssembler.request(count)]
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
Benchmark.bm(46) do |x|
|
|
137
|
+
policy_requests.each do |count, request|
|
|
138
|
+
iterations = (count >= 1_000) ? 200 : 1_000
|
|
139
|
+
x.report("DefaultContextPolicy #{count} candidates x#{iterations}") do
|
|
140
|
+
iterations.times { policy.call(request) }
|
|
141
|
+
end
|
|
41
142
|
end
|
|
42
143
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
# expected — budget exceeded
|
|
144
|
+
assembler, root, execution = BenchContextAssembler.assembler_fixture
|
|
145
|
+
x.report("ContextAssembler#build_initial x500") do
|
|
146
|
+
500.times do
|
|
147
|
+
assembler.build_initial(
|
|
148
|
+
input: "benchmark input",
|
|
149
|
+
agent_root: root,
|
|
150
|
+
execution: execution
|
|
151
|
+
)
|
|
52
152
|
end
|
|
53
153
|
end
|
|
54
154
|
end
|
|
@@ -2,12 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
# bench_regression.rb — Targeted regression benchmarks.
|
|
4
4
|
#
|
|
5
|
-
# Measures the
|
|
5
|
+
# Measures the six minimum regression targets:
|
|
6
6
|
# 1. WorkflowContext#merge throughput
|
|
7
7
|
# 2. Workflow.define (graph build) time
|
|
8
8
|
# 3. Tool::Base#params_schema generation (10 params)
|
|
9
9
|
# 4. Orchestrator#dispatch_parallel overhead (10 stub agents, no LLM)
|
|
10
|
-
# 5. CancellationToken#cancelled? throughput
|
|
10
|
+
# 5. CancellationToken#cancelled? throughput under deliberate Thread contention
|
|
11
|
+
# 6. CancellationToken#raise_if_cancelled! hot path
|
|
12
|
+
#
|
|
13
|
+
# Target 4 deliberately uses thread-free completion handles so the benchmark
|
|
14
|
+
# measures EventLoop/FanOut coordination rather than fake per-child Thread.new
|
|
15
|
+
# overhead. Target 5 intentionally uses Threads because cross-thread token access
|
|
16
|
+
# is the behavior being measured there; it is not a Phronomy runtime execution
|
|
17
|
+
# path.
|
|
11
18
|
#
|
|
12
19
|
# Results are stored in a global REGRESSION_RESULTS hash (keyed by metric name,
|
|
13
20
|
# value = iterations per second) for use by run_all.rb baseline comparison.
|
|
@@ -89,10 +96,20 @@ end
|
|
|
89
96
|
# ---------------------------------------------------------------------------
|
|
90
97
|
stub_agent_class = Class.new(Phronomy::Agent::Base) do
|
|
91
98
|
agent_definition id: "bench-stub", version: 1
|
|
92
|
-
|
|
99
|
+
|
|
100
|
+
define_method(:invoke) do |_input, thread_id: nil, config: {}|
|
|
93
101
|
{output: "stub", messages: []}
|
|
94
102
|
end
|
|
95
|
-
|
|
103
|
+
|
|
104
|
+
define_method(:invoke_async) do |input, **_kw|
|
|
105
|
+
task = Phronomy::Task.deferred(name: "bench-stub")
|
|
106
|
+
begin
|
|
107
|
+
task.complete(invoke(input))
|
|
108
|
+
rescue => error
|
|
109
|
+
task.fail(error)
|
|
110
|
+
end
|
|
111
|
+
task
|
|
112
|
+
end
|
|
96
113
|
end
|
|
97
114
|
|
|
98
115
|
orchestrator_class = Class.new(Phronomy::MultiAgent::Orchestrator)
|
|
@@ -108,8 +125,11 @@ t4 = Benchmark.measure("Orchestrator#dispatch_parallel (10 agents)") do
|
|
|
108
125
|
end
|
|
109
126
|
|
|
110
127
|
# ---------------------------------------------------------------------------
|
|
111
|
-
# Target 5: CancellationToken#cancelled? throughput (8
|
|
128
|
+
# Target 5: CancellationToken#cancelled? throughput (8 application Threads)
|
|
112
129
|
# ---------------------------------------------------------------------------
|
|
130
|
+
# Threads are intentional here: the benchmark specifically measures concurrent
|
|
131
|
+
# access to one shared CancellationToken. They are not used to execute Phronomy
|
|
132
|
+
# Agent/Workflow/Tool lifecycle work.
|
|
113
133
|
CANCEL_TOKEN = Phronomy::Concurrency::CancellationToken.new
|
|
114
134
|
CANCEL_ITERATIONS = 10_000
|
|
115
135
|
|
|
@@ -123,7 +143,7 @@ end
|
|
|
123
143
|
# ---------------------------------------------------------------------------
|
|
124
144
|
# Target 6: CancellationToken#raise_if_cancelled! hot path (no-op, single thread)
|
|
125
145
|
# ---------------------------------------------------------------------------
|
|
126
|
-
RAISE_TOKEN = Phronomy::Concurrency::CancellationToken.new
|
|
146
|
+
RAISE_TOKEN = Phronomy::Concurrency::CancellationToken.new # not cancelled — no-op path
|
|
127
147
|
RAISE_ITERATIONS = 200_000
|
|
128
148
|
|
|
129
149
|
t6 = Benchmark.measure("CancellationToken#raise_if_cancelled! (no-op)") do
|
|
@@ -1,16 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# Benchmark: Tool::Base params_schema generation
|
|
3
|
+
# Benchmark: Tool::Base params_schema generation.
|
|
4
4
|
#
|
|
5
|
-
# Tool schema generation happens once per tool class
|
|
6
|
-
# static_knowledge_chunks is cached at the class level; cache-hit overhead
|
|
7
|
-
# should be negligible compared to cache-miss (which calls the knowledge source).
|
|
5
|
+
# Tool schema generation happens once per tool class and is lazily memoized.
|
|
8
6
|
|
|
9
7
|
require "benchmark"
|
|
10
8
|
require_relative "../lib/phronomy"
|
|
11
9
|
|
|
12
|
-
# --- Tool schema ---
|
|
13
|
-
|
|
14
10
|
class BenchTool10Params < Phronomy::Agent::Context::Capability::Base
|
|
15
11
|
description "A tool with 10 parameters for benchmarking purposes"
|
|
16
12
|
param :param1, type: :string, desc: "First parameter"
|
|
@@ -29,7 +25,6 @@ class BenchTool10Params < Phronomy::Agent::Context::Capability::Base
|
|
|
29
25
|
end
|
|
30
26
|
end
|
|
31
27
|
|
|
32
|
-
# Warm up memoisation
|
|
33
28
|
BenchTool10Params.params_schema_definition
|
|
34
29
|
|
|
35
30
|
BENCH_TOOL_ITERATIONS = 50_000
|
|
@@ -40,31 +35,3 @@ Benchmark.bm(35) do |x|
|
|
|
40
35
|
BENCH_TOOL_ITERATIONS.times { BenchTool10Params.params_schema_definition }
|
|
41
36
|
end
|
|
42
37
|
end
|
|
43
|
-
|
|
44
|
-
# --- static_knowledge_chunks cache ---
|
|
45
|
-
|
|
46
|
-
class BenchKnowledgeSource < Phronomy::Agent::Context::Knowledge::Base
|
|
47
|
-
def fetch(query: nil)
|
|
48
|
-
[{content: "Cached knowledge fact.", type: :static}]
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def static?
|
|
52
|
-
true
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
class BenchAgentWithKnowledge < Phronomy::Agent::Base
|
|
57
|
-
agent_definition id: "bench-knowledge", version: 1
|
|
58
|
-
model "gpt-4o-mini"
|
|
59
|
-
static_knowledge BenchKnowledgeSource.new
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
# Warm up cache
|
|
63
|
-
BenchAgentWithKnowledge.static_knowledge_chunks
|
|
64
|
-
|
|
65
|
-
puts "\n=== bench_static_knowledge_cache ==="
|
|
66
|
-
Benchmark.bm(35) do |x|
|
|
67
|
-
x.report("static_knowledge_chunks (hit)") do
|
|
68
|
-
BENCH_TOOL_ITERATIONS.times { BenchAgentWithKnowledge.static_knowledge_chunks }
|
|
69
|
-
end
|
|
70
|
-
end
|