conductor_ruby 0.1.0 → 0.1.1

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.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -0
  3. data/examples/agents/01_basic_agent.rb +36 -0
  4. data/examples/agents/02a_simple_tools.rb +47 -0
  5. data/examples/agents/02c_tool_retry_config.rb +52 -0
  6. data/examples/agents/04_http_and_mcp_tools.rb +58 -0
  7. data/examples/agents/05_handoffs.rb +71 -0
  8. data/examples/agents/06_sequential_pipeline.rb +47 -0
  9. data/examples/agents/07_parallel_agents.rb +52 -0
  10. data/examples/agents/09_human_in_the_loop.rb +59 -0
  11. data/examples/agents/09c_hitl_streaming.rb +65 -0
  12. data/examples/agents/103_plan_and_compile.rb +85 -0
  13. data/examples/agents/10_guardrails.rb +61 -0
  14. data/examples/agents/13_hierarchical_agents.rb +79 -0
  15. data/examples/agents/16e_credentials_http_tool.rb +44 -0
  16. data/examples/agents/17_swarm_orchestration.rb +56 -0
  17. data/examples/agents/21_regex_guardrails.rb +69 -0
  18. data/examples/agents/22_llm_guardrails.rb +51 -0
  19. data/examples/agents/33_external_workers.rb +65 -0
  20. data/examples/agents/64_swarm_with_tools.rb +71 -0
  21. data/examples/agents/66_handoff_to_parallel.rb +62 -0
  22. data/examples/agents/bug_desk.rb +50 -0
  23. data/examples/agents/catalog.rb +32 -0
  24. data/examples/agents/dump_agent_configs.rb +30 -0
  25. data/examples/agents/external_workers.rb +39 -0
  26. data/examples/agents/golden_agents.rb +385 -0
  27. data/examples/agents/support_approval.rb +51 -0
  28. data/examples/agents/weather.rb +27 -0
  29. data/lib/conductor/agents/agent.rb +324 -0
  30. data/lib/conductor/agents/callback_handler.rb +64 -0
  31. data/lib/conductor/agents/config_serializer.rb +246 -0
  32. data/lib/conductor/agents/errors.rb +26 -0
  33. data/lib/conductor/agents/guardrail.rb +142 -0
  34. data/lib/conductor/agents/handoff.rb +94 -0
  35. data/lib/conductor/agents/memory.rb +75 -0
  36. data/lib/conductor/agents/plans.rb +22 -0
  37. data/lib/conductor/agents/prompt_template.rb +23 -0
  38. data/lib/conductor/agents/runtime/agent_config.rb +52 -0
  39. data/lib/conductor/agents/runtime/agent_runtime.rb +260 -0
  40. data/lib/conductor/agents/runtime/approval_request.rb +111 -0
  41. data/lib/conductor/agents/runtime/dispatch.rb +137 -0
  42. data/lib/conductor/agents/runtime/execution.rb +265 -0
  43. data/lib/conductor/agents/runtime/secrets.rb +54 -0
  44. data/lib/conductor/agents/runtime/sse_client.rb +175 -0
  45. data/lib/conductor/agents/runtime/status_poller.rb +49 -0
  46. data/lib/conductor/agents/runtime/system_workers.rb +115 -0
  47. data/lib/conductor/agents/runtime/tool_call.rb +13 -0
  48. data/lib/conductor/agents/runtime/tool_registry.rb +164 -0
  49. data/lib/conductor/agents/termination.rb +192 -0
  50. data/lib/conductor/agents/tool.rb +283 -0
  51. data/lib/conductor/agents/tools/schema_builder.rb +190 -0
  52. data/lib/conductor/agents/tools/secret_scanner.rb +45 -0
  53. data/lib/conductor/agents/tools.rb +173 -0
  54. data/lib/conductor/agents.rb +75 -0
  55. data/lib/conductor/client/agent_client.rb +117 -0
  56. data/lib/conductor/client/task_client.rb +7 -0
  57. data/lib/conductor/configuration.rb +43 -10
  58. data/lib/conductor/exceptions.rb +36 -0
  59. data/lib/conductor/http/api/agent_resource_api.rb +138 -0
  60. data/lib/conductor/http/api/scheduler_resource_api.rb +31 -12
  61. data/lib/conductor/http/api/task_resource_api.rb +15 -0
  62. data/lib/conductor/http/models/task.rb +10 -2
  63. data/lib/conductor/http/models/task_def.rb +14 -3
  64. data/lib/conductor/http/rest_client.rb +9 -0
  65. data/lib/conductor/orkes/orkes_clients.rb +5 -1
  66. data/lib/conductor/version.rb +1 -1
  67. data/lib/conductor/worker/lease_renewer.rb +55 -0
  68. data/lib/conductor/worker/ractor_task_runner.rb +1 -1
  69. data/lib/conductor/worker/task_definition_registrar.rb +2 -2
  70. data/lib/conductor/worker/task_runner.rb +43 -10
  71. data/lib/conductor/worker/worker.rb +3 -2
  72. data/lib/conductor/worker/worker_config.rb +2 -1
  73. data/lib/conductor.rb +3 -1
  74. metadata +71 -16
@@ -67,27 +67,24 @@ module Conductor
67
67
  end
68
68
 
69
69
  # Pause a schedule
70
+ #
71
+ # Per-schedule pause/resume is PUT-mapped on OSS Conductor but GET-only
72
+ # on some Orkes Conductor deployments. PUT is tried first and a 405
73
+ # response falls back to GET, mirroring the python-sdk/csharp-sdk/rust-sdk
74
+ # clients.
70
75
  # @param [String] name Schedule name
71
76
  # @return [void]
72
77
  def pause_schedule(name)
73
- @api_client.call_api(
74
- '/scheduler/schedules/{name}/pause',
75
- 'GET',
76
- path_params: { name: name },
77
- return_http_data_only: true
78
- )
78
+ call_with_verb_fallback('/scheduler/schedules/{name}/pause', name)
79
79
  end
80
80
 
81
81
  # Resume a schedule
82
+ #
83
+ # See {#pause_schedule} for the PUT-with-GET-fallback rationale.
82
84
  # @param [String] name Schedule name
83
85
  # @return [void]
84
86
  def resume_schedule(name)
85
- @api_client.call_api(
86
- '/scheduler/schedules/{name}/resume',
87
- 'GET',
88
- path_params: { name: name },
89
- return_http_data_only: true
90
- )
87
+ call_with_verb_fallback('/scheduler/schedules/{name}/resume', name)
91
88
  end
92
89
 
93
90
  # Pause all schedules
@@ -205,6 +202,28 @@ module Conductor
205
202
  return_http_data_only: true
206
203
  )
207
204
  end
205
+
206
+ private
207
+
208
+ # Try PUT first (OSS dialect); fall back to GET on 405 (some Orkes
209
+ # deployments only accept GET for these two routes).
210
+ def call_with_verb_fallback(templated_path, name)
211
+ @api_client.call_api(
212
+ templated_path,
213
+ 'PUT',
214
+ path_params: { name: name },
215
+ return_http_data_only: true
216
+ )
217
+ rescue Conductor::ApiError => e
218
+ raise unless e.status == 405
219
+
220
+ @api_client.call_api(
221
+ templated_path,
222
+ 'GET',
223
+ path_params: { name: name },
224
+ return_http_data_only: true
225
+ )
226
+ end
208
227
  end
209
228
  end
210
229
  end
@@ -73,6 +73,21 @@ module Conductor
73
73
  )
74
74
  end
75
75
 
76
+ # Update task status using the v2 endpoint (POST /tasks/update-v2)
77
+ # Supports lease extension via TaskResult#extend_lease and returns the next
78
+ # task for the same worker when the server has one queued.
79
+ # @param [TaskResult] body Task result
80
+ # @return [Task, nil] Next task if the server returned one, nil on 204
81
+ def update_task_v2(body)
82
+ @api_client.call_api(
83
+ '/tasks/update-v2',
84
+ 'POST',
85
+ body: body,
86
+ return_type: 'Task',
87
+ return_http_data_only: true
88
+ )
89
+ end
90
+
76
91
  # Get task details
77
92
  # @param [String] task_id Task ID
78
93
  # @return [Task] Task object
@@ -50,7 +50,8 @@ module Conductor
50
50
  first_start_time: 'Integer',
51
51
  loop_over_task: 'Boolean',
52
52
  task_definition: 'TaskDef',
53
- queue_wait_time: 'Integer'
53
+ queue_wait_time: 'Integer',
54
+ runtime_metadata: 'Hash<String, String>'
54
55
  }.freeze
55
56
 
56
57
  ATTRIBUTE_MAP = {
@@ -96,7 +97,8 @@ module Conductor
96
97
  first_start_time: :firstStartTime,
97
98
  loop_over_task: :loopOverTask,
98
99
  task_definition: :taskDefinition,
99
- queue_wait_time: :queueWaitTime
100
+ queue_wait_time: :queueWaitTime,
101
+ runtime_metadata: :runtimeMetadata
100
102
  }.freeze
101
103
 
102
104
  attr_accessor :task_type, :status, :input_data, :reference_task_name,
@@ -112,6 +114,11 @@ module Conductor
112
114
  :iteration, :sub_workflow_id, :subworkflow_changed, :parent_task_id,
113
115
  :first_start_time, :loop_over_task, :task_definition, :queue_wait_time
114
116
 
117
+ # Wire-only map of secret name => resolved value. The server fills it at poll
118
+ # time from TaskDef#runtime_metadata (names) and never persists it.
119
+ # @return [Hash<String, String>]
120
+ attr_accessor :runtime_metadata
121
+
115
122
  # Initialize a new Task
116
123
  # @param [Hash] attributes Model attributes in the form of hash
117
124
  def initialize(attributes = {})
@@ -125,6 +132,7 @@ module Conductor
125
132
  # Set default values for collections
126
133
  @input_data ||= {}
127
134
  @output_data ||= {}
135
+ @runtime_metadata ||= {}
128
136
  end
129
137
 
130
138
  # Check if task is in terminal state
@@ -37,7 +37,9 @@ module Conductor
37
37
  execution_name_space: 'String',
38
38
  owner_email: 'String',
39
39
  poll_timeout_seconds: 'Integer',
40
- backoff_scale_factor: 'Integer'
40
+ backoff_scale_factor: 'Integer',
41
+ enforce_schema: 'Boolean',
42
+ runtime_metadata: 'Array<String>'
41
43
  }.freeze
42
44
 
43
45
  ATTRIBUTE_MAP = {
@@ -58,7 +60,9 @@ module Conductor
58
60
  execution_name_space: :executionNameSpace,
59
61
  owner_email: :ownerEmail,
60
62
  poll_timeout_seconds: :pollTimeoutSeconds,
61
- backoff_scale_factor: :backoffScaleFactor
63
+ backoff_scale_factor: :backoffScaleFactor,
64
+ enforce_schema: :enforceSchema,
65
+ runtime_metadata: :runtimeMetadata
62
66
  }.freeze
63
67
 
64
68
  attr_accessor :name, :description, :retry_count, :timeout_seconds,
@@ -67,7 +71,12 @@ module Conductor
67
71
  :concurrent_exec_limit, :rate_limit_per_frequency,
68
72
  :rate_limit_frequency_in_seconds, :isolation_group_id,
69
73
  :execution_name_space, :owner_email, :poll_timeout_seconds,
70
- :backoff_scale_factor
74
+ :backoff_scale_factor, :enforce_schema
75
+
76
+ # Names of secrets the server must resolve and attach to every task of this
77
+ # type (delivered as Task#runtime_metadata). Requires conductor-oss >= 3.32.0-rc.8.
78
+ # @return [Array<String>]
79
+ attr_accessor :runtime_metadata
71
80
 
72
81
  def initialize(params = {})
73
82
  @name = params[:name]
@@ -88,6 +97,8 @@ module Conductor
88
97
  @owner_email = params[:owner_email]
89
98
  @poll_timeout_seconds = params[:poll_timeout_seconds]
90
99
  @backoff_scale_factor = params[:backoff_scale_factor] || 1
100
+ @enforce_schema = params.fetch(:enforce_schema, false)
101
+ @runtime_metadata = params[:runtime_metadata] || []
91
102
  end
92
103
  end
93
104
  end
@@ -112,11 +112,20 @@ module Conductor
112
112
  end
113
113
 
114
114
  # Retry middleware (3 retries with exponential backoff)
115
+ #
116
+ # `exceptions` has to be spelled out: faraday-retry's
117
+ # DEFAULT_EXCEPTIONS covers timeouts but not Faraday::ConnectionFailed,
118
+ # which is what the net_http_persistent adapter raises for
119
+ # Errno::ECONNRESET/EPIPE -- a write to a pooled socket the peer closed
120
+ # first. net-http-persistent retries stale sockets itself, but only for
121
+ # idempotent requests, so POSTs surfaced these as hard ApiErrors while
122
+ # every GET was silently protected.
115
123
  conn.request :retry,
116
124
  max: 3,
117
125
  interval: 0.5,
118
126
  backoff_factor: 2,
119
127
  retry_statuses: [408, 429, 500, 502, 503, 504],
128
+ exceptions: Faraday::Retry::Middleware::DEFAULT_EXCEPTIONS + [Faraday::ConnectionFailed],
120
129
  methods: %i[get post put patch delete]
121
130
 
122
131
  # Connection settings
@@ -8,7 +8,7 @@ module Conductor
8
8
  # Usage:
9
9
  # config = Conductor::Configuration.new
10
10
  # config.server_url = 'https://developer.orkescloud.com/api'
11
- # config.authentication_settings = Conductor::Configuration::AuthenticationSettings.new(
11
+ # config.authentication_settings = Conductor::AuthenticationSettings.new(
12
12
  # key_id: 'your_key', key_secret: 'your_secret'
13
13
  # )
14
14
  # clients = Conductor::Orkes::OrkesClients.new(config)
@@ -61,6 +61,10 @@ module Conductor
61
61
  Client::SchemaClient.new(@api_client)
62
62
  end
63
63
 
64
+ def get_agent_client
65
+ Client::AgentClient.new(@api_client)
66
+ end
67
+
64
68
  def get_workflow_executor
65
69
  Workflow::WorkflowExecutor.new(@configuration)
66
70
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Conductor
4
- VERSION = '0.1.0'
4
+ VERSION = '0.1.1'
5
5
  end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'concurrent'
4
+ require_relative '../http/models/task_result'
5
+
6
+ module Conductor
7
+ module Worker
8
+ # Renews a task's lease while its worker body runs. Each active task has one
9
+ # interruptible heartbeat thread, independent of the polling/execution pool.
10
+ class LeaseRenewer
11
+ INTERVAL_FACTOR = 0.8
12
+
13
+ def initialize(task_client:, logger:)
14
+ @task_client = task_client
15
+ @logger = logger
16
+ end
17
+
18
+ def during(task, worker_id:)
19
+ interval = task.response_timeout_seconds.to_f * INTERVAL_FACTOR
20
+ return yield unless interval.positive?
21
+
22
+ stopped = Concurrent::Event.new
23
+ heartbeat = Thread.new do
24
+ Thread.current.name = "conductor-lease-#{task.task_id}"
25
+ delay = interval
26
+ # Retry transient failures within the remaining lease window.
27
+ delay = renew(task, worker_id) ? interval : [interval / 4, 1.0].min until stopped.wait(delay)
28
+ end
29
+ yield
30
+ ensure
31
+ stopped&.set
32
+ # Drain an in-flight heartbeat before the caller can submit a final result.
33
+ heartbeat&.join
34
+ end
35
+
36
+ private
37
+
38
+ def renew(task, worker_id)
39
+ result = Http::Models::TaskResult.new(
40
+ task_id: task.task_id,
41
+ workflow_instance_id: task.workflow_instance_id,
42
+ worker_id: worker_id,
43
+ status: Http::Models::TaskResultStatus::IN_PROGRESS,
44
+ extend_lease: true
45
+ )
46
+ # The original endpoint handles lease updates without claiming more work.
47
+ @task_client.update_task(result)
48
+ true
49
+ rescue StandardError => e
50
+ @logger.warn("Lease renewal failed for task #{task.task_id}: #{e.class}: #{e.message}")
51
+ false
52
+ end
53
+ end
54
+ end
55
+ end
@@ -143,7 +143,7 @@ module Conductor
143
143
  server_api_url: @configuration_hash[:server_api_url]
144
144
  )
145
145
  if @configuration_hash[:authentication_settings]
146
- config.authentication_settings = Configuration::AuthenticationSettings.new(
146
+ config.authentication_settings = AuthenticationSettings.new(
147
147
  key_id: @configuration_hash[:authentication_settings][:key_id],
148
148
  key_secret: @configuration_hash[:authentication_settings][:key_secret]
149
149
  )
@@ -210,7 +210,7 @@ module Conductor
210
210
  raise unless e.status == 404
211
211
 
212
212
  # Task def doesn't exist, create it
213
- @metadata_client.register_task_def([task_def])
213
+ @metadata_client.register_task_def(task_def)
214
214
  end
215
215
 
216
216
  # Register task def only if it doesn't exist
@@ -222,7 +222,7 @@ module Conductor
222
222
  raise unless e.status == 404
223
223
 
224
224
  # Task def doesn't exist, create it
225
- @metadata_client.register_task_def([task_def])
225
+ @metadata_client.register_task_def(task_def)
226
226
  end
227
227
  end
228
228
 
@@ -10,6 +10,7 @@ require_relative '../exceptions'
10
10
  require_relative 'task_context'
11
11
  require_relative 'task_in_progress'
12
12
  require_relative 'worker_config'
13
+ require_relative 'lease_renewer'
13
14
  require_relative 'events/task_runner_events'
14
15
  require_relative 'events/sync_event_dispatcher'
15
16
  require_relative 'events/listener_registry'
@@ -43,6 +44,7 @@ module Conductor
43
44
 
44
45
  # Create task client for API communication
45
46
  @task_client = Client::TaskClient.new(@configuration)
47
+ @lease_renewer = LeaseRenewer.new(task_client: @task_client, logger: @logger)
46
48
 
47
49
  # Resolve worker configuration
48
50
  resolved_config = WorkerConfig.resolve(
@@ -68,6 +70,9 @@ module Conductor
68
70
  @poll_count = Concurrent::AtomicFixnum.new(0)
69
71
  @shutdown = Concurrent::AtomicBoolean.new(false)
70
72
  @mutex = Mutex.new
73
+ # Prefer POST /tasks/update-v2 (lease extension, next-task return); fall back
74
+ # to POST /tasks once if the server does not serve it (404/405).
75
+ @use_update_v2 = Concurrent::AtomicBoolean.new(true)
71
76
  end
72
77
 
73
78
  # Main polling loop (runs until shutdown)
@@ -176,6 +181,7 @@ module Conductor
176
181
  @worker_id = config[:worker_id]
177
182
  @domain = config[:domain]
178
183
  @poll_timeout = config[:poll_timeout]
184
+ @lease_extend_enabled = config[:lease_extend_enabled]
179
185
  end
180
186
 
181
187
  # Cleanup completed task futures
@@ -305,16 +311,21 @@ module Conductor
305
311
  # Execute a task and update the result
306
312
  # @param task [Hash] Task data from API
307
313
  def execute_and_update(task)
308
- task_result = execute_task(task)
314
+ while task
315
+ task_result = execute_task(task)
309
316
 
310
- # Skip update for TaskInProgress (task stays in IN_PROGRESS state)
311
- return if task_result.nil?
317
+ # Skip update for TaskInProgress (task stays in IN_PROGRESS state)
318
+ return if task_result.nil?
312
319
 
313
- # Don't update if result is IN_PROGRESS (will be polled again)
314
- return if task_result.status == Http::Models::TaskResultStatus::IN_PROGRESS &&
315
- task_result.callback_after_seconds&.positive?
320
+ # Don't update if result is IN_PROGRESS (will be polled again)
321
+ return if task_result.status == Http::Models::TaskResultStatus::IN_PROGRESS &&
322
+ task_result.callback_after_seconds&.positive?
316
323
 
317
- update_task_with_retry(task_result)
324
+ # update-v2 has already claimed the returned task. Reuse this executor slot
325
+ # rather than dropping it or exceeding the worker's concurrency limit.
326
+ response = update_task_with_retry(task_result)
327
+ task = response.is_a?(Http::Models::Task) ? response : nil
328
+ end
318
329
  end
319
330
 
320
331
  # Execute a task
@@ -345,7 +356,11 @@ module Conductor
345
356
 
346
357
  begin
347
358
  # Execute worker
348
- task_result = @worker.execute(task_obj)
359
+ task_result = if @lease_extend_enabled
360
+ @lease_renewer.during(task_obj, worker_id: @worker_id) { @worker.execute(task_obj) }
361
+ else
362
+ @worker.execute(task_obj)
363
+ end
349
364
 
350
365
  duration_ms = (Time.now - start_time) * 1000
351
366
 
@@ -458,11 +473,11 @@ module Conductor
458
473
 
459
474
  start_time = Time.now
460
475
  begin
461
- @task_client.update_task(task_result)
476
+ next_task = send_task_update(task_result)
462
477
  duration_ms = (Time.now - start_time) * 1000
463
478
 
464
479
  publish_task_update_completed(task_result, duration_ms)
465
- return # Success
480
+ return next_task
466
481
  rescue StandardError => e
467
482
  duration_ms = (Time.now - start_time) * 1000
468
483
  @logger.error("Task update failed (attempt #{attempt + 1}/#{RETRY_BACKOFFS.size}): #{e.message}")
@@ -474,6 +489,24 @@ module Conductor
474
489
  end
475
490
  end
476
491
  end
492
+ nil
493
+ end
494
+
495
+ # Send the task result to the server, preferring the v2 endpoint
496
+ # @param task_result [TaskResult]
497
+ def send_task_update(task_result)
498
+ return @task_client.update_task(task_result) unless @use_update_v2.true? && running?
499
+
500
+ task_result.extend_lease = false if task_result.extend_lease.nil?
501
+ begin
502
+ @task_client.update_task_v2(task_result)
503
+ rescue ApiError => e
504
+ raise unless [404, 405].include?(e.status)
505
+
506
+ @logger.info('Server does not support /tasks/update-v2, falling back to /tasks')
507
+ @use_update_v2.make_false
508
+ @task_client.update_task(task_result)
509
+ end
477
510
  end
478
511
 
479
512
  def publish_task_update_completed(task_result, duration_ms)
@@ -22,7 +22,7 @@ module Conductor
22
22
  attr_accessor :poll_interval, :thread_count, :domain, :worker_id,
23
23
  :poll_timeout, :register_task_def, :overwrite_task_def,
24
24
  :strict_schema, :paused, :isolation, :executor,
25
- :task_def_template
25
+ :task_def_template, :lease_extend_enabled
26
26
 
27
27
  # Default configuration values
28
28
  DEFAULTS = {
@@ -36,7 +36,8 @@ module Conductor
36
36
  strict_schema: false,
37
37
  paused: false,
38
38
  isolation: :thread,
39
- executor: :thread_pool
39
+ executor: :thread_pool,
40
+ lease_extend_enabled: false
40
41
  }.freeze
41
42
 
42
43
  # Initialize a worker
@@ -22,7 +22,8 @@ module Conductor
22
22
  strict_schema: { type: :boolean, default: false },
23
23
  paused: { type: :boolean, default: false },
24
24
  isolation: { type: :symbol, default: :thread }, # :thread or :ractor
25
- executor: { type: :symbol, default: :thread_pool } # :thread_pool or :fiber
25
+ executor: { type: :symbol, default: :thread_pool }, # :thread_pool or :fiber
26
+ lease_extend_enabled: { type: :boolean, default: false }
26
27
  }.freeze
27
28
 
28
29
  class << self
data/lib/conductor.rb CHANGED
@@ -69,6 +69,7 @@ require_relative 'conductor/http/api/gateway_auth_resource_api'
69
69
  require_relative 'conductor/http/api/schema_resource_api'
70
70
  require_relative 'conductor/http/api/integration_resource_api'
71
71
  require_relative 'conductor/http/api/prompt_resource_api'
72
+ require_relative 'conductor/http/api/agent_resource_api'
72
73
  # OSS Clients
73
74
  require_relative 'conductor/client/workflow_client'
74
75
  require_relative 'conductor/client/task_client'
@@ -80,6 +81,7 @@ require_relative 'conductor/client/authorization_client'
80
81
  require_relative 'conductor/client/schema_client'
81
82
  require_relative 'conductor/client/integration_client'
82
83
  require_relative 'conductor/client/prompt_client'
84
+ require_relative 'conductor/client/agent_client'
83
85
  # Orkes-specific models
84
86
  require_relative 'conductor/orkes/models/metadata_tag'
85
87
  require_relative 'conductor/orkes/models/rate_limit_tag'
@@ -147,7 +149,7 @@ module Conductor
147
149
  # @example
148
150
  # Conductor.configure do |config|
149
151
  # config.server_url = 'http://localhost:7001/api'
150
- # config.authentication_settings = Conductor::Configuration::AuthenticationSettings.new(
152
+ # config.authentication_settings = Conductor::AuthenticationSettings.new(
151
153
  # key_id: 'my_key',
152
154
  # key_secret: 'my_secret'
153
155
  # )
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: conductor_ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Conductor OSS
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-06-29 00:00:00.000000000 Z
11
+ date: 2026-09-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '2.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: json_schemer
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '2.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '2.0'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: pry
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -150,20 +164,6 @@ dependencies:
150
164
  - - "~>"
151
165
  - !ruby/object:Gem::Version
152
166
  version: '2.0'
153
- - !ruby/object:Gem::Dependency
154
- name: vcr
155
- requirement: !ruby/object:Gem::Requirement
156
- requirements:
157
- - - "~>"
158
- - !ruby/object:Gem::Version
159
- version: '6.0'
160
- type: :development
161
- prerelease: false
162
- version_requirements: !ruby/object:Gem::Requirement
163
- requirements:
164
- - - "~>"
165
- - !ruby/object:Gem::Version
166
- version: '6.0'
167
167
  - !ruby/object:Gem::Dependency
168
168
  name: webmock
169
169
  requirement: !ruby/object:Gem::Requirement
@@ -190,6 +190,32 @@ files:
190
190
  - LICENSE
191
191
  - README.md
192
192
  - examples/agentic_workflows/llm_chat.rb
193
+ - examples/agents/01_basic_agent.rb
194
+ - examples/agents/02a_simple_tools.rb
195
+ - examples/agents/02c_tool_retry_config.rb
196
+ - examples/agents/04_http_and_mcp_tools.rb
197
+ - examples/agents/05_handoffs.rb
198
+ - examples/agents/06_sequential_pipeline.rb
199
+ - examples/agents/07_parallel_agents.rb
200
+ - examples/agents/09_human_in_the_loop.rb
201
+ - examples/agents/09c_hitl_streaming.rb
202
+ - examples/agents/103_plan_and_compile.rb
203
+ - examples/agents/10_guardrails.rb
204
+ - examples/agents/13_hierarchical_agents.rb
205
+ - examples/agents/16e_credentials_http_tool.rb
206
+ - examples/agents/17_swarm_orchestration.rb
207
+ - examples/agents/21_regex_guardrails.rb
208
+ - examples/agents/22_llm_guardrails.rb
209
+ - examples/agents/33_external_workers.rb
210
+ - examples/agents/64_swarm_with_tools.rb
211
+ - examples/agents/66_handoff_to_parallel.rb
212
+ - examples/agents/bug_desk.rb
213
+ - examples/agents/catalog.rb
214
+ - examples/agents/dump_agent_configs.rb
215
+ - examples/agents/external_workers.rb
216
+ - examples/agents/golden_agents.rb
217
+ - examples/agents/support_approval.rb
218
+ - examples/agents/weather.rb
193
219
  - examples/dynamic_workflow.rb
194
220
  - examples/event_handler.rb
195
221
  - examples/event_listener_examples.rb
@@ -213,6 +239,33 @@ files:
213
239
  - examples/workflow_dsl.rb
214
240
  - examples/workflow_ops.rb
215
241
  - lib/conductor.rb
242
+ - lib/conductor/agents.rb
243
+ - lib/conductor/agents/agent.rb
244
+ - lib/conductor/agents/callback_handler.rb
245
+ - lib/conductor/agents/config_serializer.rb
246
+ - lib/conductor/agents/errors.rb
247
+ - lib/conductor/agents/guardrail.rb
248
+ - lib/conductor/agents/handoff.rb
249
+ - lib/conductor/agents/memory.rb
250
+ - lib/conductor/agents/plans.rb
251
+ - lib/conductor/agents/prompt_template.rb
252
+ - lib/conductor/agents/runtime/agent_config.rb
253
+ - lib/conductor/agents/runtime/agent_runtime.rb
254
+ - lib/conductor/agents/runtime/approval_request.rb
255
+ - lib/conductor/agents/runtime/dispatch.rb
256
+ - lib/conductor/agents/runtime/execution.rb
257
+ - lib/conductor/agents/runtime/secrets.rb
258
+ - lib/conductor/agents/runtime/sse_client.rb
259
+ - lib/conductor/agents/runtime/status_poller.rb
260
+ - lib/conductor/agents/runtime/system_workers.rb
261
+ - lib/conductor/agents/runtime/tool_call.rb
262
+ - lib/conductor/agents/runtime/tool_registry.rb
263
+ - lib/conductor/agents/termination.rb
264
+ - lib/conductor/agents/tool.rb
265
+ - lib/conductor/agents/tools.rb
266
+ - lib/conductor/agents/tools/schema_builder.rb
267
+ - lib/conductor/agents/tools/secret_scanner.rb
268
+ - lib/conductor/client/agent_client.rb
216
269
  - lib/conductor/client/authorization_client.rb
217
270
  - lib/conductor/client/integration_client.rb
218
271
  - lib/conductor/client/metadata_client.rb
@@ -225,6 +278,7 @@ files:
225
278
  - lib/conductor/configuration.rb
226
279
  - lib/conductor/configuration/authentication_settings.rb
227
280
  - lib/conductor/exceptions.rb
281
+ - lib/conductor/http/api/agent_resource_api.rb
228
282
  - lib/conductor/http/api/application_resource_api.rb
229
283
  - lib/conductor/http/api/authorization_resource_api.rb
230
284
  - lib/conductor/http/api/event_resource_api.rb
@@ -302,6 +356,7 @@ files:
302
356
  - lib/conductor/worker/events/task_runner_events.rb
303
357
  - lib/conductor/worker/events/workflow_events.rb
304
358
  - lib/conductor/worker/fiber_executor.rb
359
+ - lib/conductor/worker/lease_renewer.rb
305
360
  - lib/conductor/worker/ractor_task_runner.rb
306
361
  - lib/conductor/worker/task_context.rb
307
362
  - lib/conductor/worker/task_definition_registrar.rb