oz-agent-sdk 0.1.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.
data/Rakefile ADDED
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require_relative 'lib/oz/version'
5
+
6
+ begin
7
+ require 'rspec/core/rake_task'
8
+ RSpec::Core::RakeTask.new(:spec)
9
+ rescue LoadError
10
+ task :spec do
11
+ abort 'rspec is not available. Run `bundle install` first.'
12
+ end
13
+ end
14
+
15
+ begin
16
+ require 'rubocop/rake_task'
17
+ RuboCop::RakeTask.new(:rubocop)
18
+ rescue LoadError
19
+ task :rubocop do
20
+ abort 'rubocop is not available. Run `bundle install` first.'
21
+ end
22
+ end
23
+
24
+ desc 'Run the full check suite (rubocop + specs)'
25
+ task ci: %i[rubocop spec]
26
+
27
+ desc 'Release gem to RubyGems'
28
+ task release_gem: [:build] do
29
+ sh "gem push pkg/oz-agent-sdk-#{Oz::VERSION}.gem"
30
+ end
31
+
32
+ task default: %i[rubocop spec]
@@ -0,0 +1,156 @@
1
+ # API Reference
2
+
3
+ All operations hang off `client.agent`. Responses are `Oz::Model` instances (see
4
+ [Responses](#responses)); list endpoints that paginate return an `Oz::CursorPage`.
5
+
6
+ ## Agent
7
+
8
+ ### `client.agent.run(**params)` → `Oz::Model`
9
+
10
+ `POST /agent/runs` — start a new agent run.
11
+
12
+ | Param | Type | Notes |
13
+ | -------------------- | -------------- | -------------------------------------------------------------- |
14
+ | `prompt` | String | Instruction. Required unless a skill is supplied. |
15
+ | `config` | Hash | Cloud run config (`AmbientAgentConfig`), see below. |
16
+ | `conversation_id` | String | Continue an existing conversation. |
17
+ | `attachments` | Array<Hash> | Up to 5 `{ data:, file_name:, mime_type: }` (base64 `data`). |
18
+ | `interactive` | Boolean | Whether the run is interactive (default false). |
19
+ | `mode` | String | `"normal"`, `"plan"`, or `"orchestrate"`. |
20
+ | `parent_run_id` | String | Parent run for orchestration trees. |
21
+ | `skill` | String | Skill spec used as the base prompt. |
22
+ | `team` | Boolean | Create a team-owned run. |
23
+ | `title` | String | Custom run title. |
24
+ | `agent_identity_uid` | String | Execution principal (team runs only). |
25
+
26
+ Returns `{ run_id, state, task_id, at_capacity }`.
27
+
28
+ Common `config` keys: `environment_id`, `model_id`, `name`, `base_prompt`, `mcp_servers`,
29
+ `harness`, `harness_auth_secrets`, `inference_providers`, `memory_stores`, `skills`,
30
+ `skill_spec`, `computer_use_enabled`, `idle_timeout_minutes`, `session_sharing`,
31
+ `worker_host`.
32
+
33
+ ```ruby
34
+ client.agent.run(
35
+ prompt: 'Fix the failing test',
36
+ config: { environment_id: 'env-123', model_id: 'claude-sonnet-4', name: 'ci-fix' }
37
+ )
38
+ ```
39
+
40
+ ### `client.agent.list(**params)` → `Oz::Model`
41
+
42
+ `GET /agent` — list available agents (skills). Params: `include_malformed_skills`,
43
+ `refresh`, `repo` (`"owner/repo"`), `sort_by` (`"name"` | `"last_run"`). Returns
44
+ `{ agents: [...] }`.
45
+
46
+ ### `client.agent.get_artifact(artifact_uid)` → `Oz::Model`
47
+
48
+ `GET /agent/artifacts/{uid}` — retrieve a `PLAN`, `SCREENSHOT`, or `FILE` artifact. The
49
+ response shape depends on `artifact_type`.
50
+
51
+ ### `client.agent.list_environments(sort_by: nil)` → `Oz::Model`
52
+
53
+ `GET /agent/environments` — list cloud environments. `sort_by`: `"last_updated"` (default)
54
+ or `"name"`. Returns `{ environments: [...] }`.
55
+
56
+ ## Runs — `client.agent.runs`
57
+
58
+ ### `retrieve(run_id)` → `Oz::Model`
59
+
60
+ `GET /agent/runs/{id}` — a single run (`RunItem`).
61
+
62
+ ### `list(**params)` → `Oz::CursorPage`
63
+
64
+ `GET /agent/runs` — cursor-paginated runs. Filters: `ancestor_run_id`, `artifact_type`,
65
+ `created_after`, `created_before`, `creator`, `cursor`, `environment_id`,
66
+ `execution_location`, `executor`, `limit`, `model_id`, `name`, `q`, `schedule_id`, `skill`,
67
+ `skill_spec`, `sort_by`, `sort_order`, `source`, `state` (Array), `updated_after`.
68
+
69
+ Time-valued filters accept a `Time`/`Date` or an ISO-8601 String. `state` is encoded as
70
+ repeated query keys.
71
+
72
+ ```ruby
73
+ page = client.agent.runs.list(state: %w[INPROGRESS], created_after: Time.now - 86_400)
74
+ page.auto_paging_each { |run| puts run.run_id }
75
+ ```
76
+
77
+ ### `cancel(run_id)` → `String`
78
+
79
+ `POST /agent/runs/{id}/cancel` — cancel an in-progress run. Returns a confirmation string.
80
+
81
+ ### `list_handoff_attachments(run_id)` → `Oz::Model`
82
+
83
+ `GET /agent/runs/{id}/handoff/attachments`.
84
+
85
+ ### `submit_followup(run_id, message: nil, mode: nil)` → `Oz::Model`
86
+
87
+ `POST /agent/runs/{id}/followups` — send a follow-up message (`mode`: `"normal"` | `"plan"`
88
+ | `"orchestrate"`).
89
+
90
+ ## Schedules — `client.agent.schedules`
91
+
92
+ ### `create(cron_schedule:, name:, **params)` → `Oz::Model`
93
+
94
+ `POST /agent/schedules`. Optional: `agent_config`, `agent_uid`, `enabled`, `mode`, `prompt`,
95
+ `team`.
96
+
97
+ ### `retrieve(schedule_id)` / `update(schedule_id, **params)` / `list` → `Oz::Model`
98
+
99
+ `GET` / `PUT /agent/schedules/{id}`, and `GET /agent/schedules` (returns `{ schedules: [...] }`).
100
+
101
+ ### `delete(schedule_id)` → `Oz::Model`
102
+
103
+ `DELETE /agent/schedules/{id}` — returns `{ success: Boolean }`.
104
+
105
+ ### `pause(schedule_id)` / `resume(schedule_id)` → `Oz::Model`
106
+
107
+ `POST /agent/schedules/{id}/pause` and `.../resume`.
108
+
109
+ ## Agent identities — `client.agent.identities`
110
+
111
+ ### `create(name:, **params)` → `Oz::Model`
112
+
113
+ `POST /agent/identities`. Optional: `description`, `prompt`, `base_model`, `base_harness`,
114
+ `environment_id`, `mcp_servers`, `memory_stores`, `secrets`, `skills`, `inference_providers`,
115
+ `harness_auth_secrets`.
116
+
117
+ ### `update(uid, **params)` / `list` / `retrieve(uid)` / `delete(uid)`
118
+
119
+ `PUT /agent/identities/{uid}`, `GET /agent/identities` (`{ agents: [...] }`),
120
+ `GET /agent/identities/{uid}` (aliased as `get`), and `DELETE /agent/identities/{uid}`
121
+ (returns `nil`).
122
+
123
+ ## Sessions & Conversations
124
+
125
+ ### `client.agent.sessions.check_redirect(session_uuid)` → `Oz::Model`
126
+
127
+ `GET /agent/sessions/{uuid}/redirect`.
128
+
129
+ ### `client.agent.conversations.check_redirect(conversation_id)` → `Oz::Model`
130
+
131
+ `GET /agent/conversations/{id}/redirect`.
132
+
133
+ ## Responses
134
+
135
+ `Oz::Model` wraps decoded JSON. Fields are reachable as methods and via `[]`; nested
136
+ objects/arrays are wrapped recursively; booleans get a `?` predicate; unknown/absent fields
137
+ return `nil`.
138
+
139
+ ```ruby
140
+ run.state # method access
141
+ run['run_id'] # bracket access (String or Symbol key)
142
+ run.at_capacity? # predicate
143
+ run.agent_config.model_id # nested
144
+ run.key?('schedule') # presence check
145
+ run.to_h # plain Hash (string keys, deep)
146
+ ```
147
+
148
+ ## Pagination
149
+
150
+ `Oz::CursorPage` is `Enumerable` over the current page and provides:
151
+
152
+ - `data` — Array of `Oz::Model` for the page.
153
+ - `next_page?` / `next_page` — fetch the next page (reuses filters + new cursor).
154
+ - `auto_paging_each` — iterate every item across all pages (returns an `Enumerator`
155
+ without a block).
156
+ - `has_next_page`, `next_cursor`, `size`, `empty?`.
@@ -0,0 +1,84 @@
1
+ # Configuration
2
+
3
+ ## Client options
4
+
5
+ `Oz::Client.new` accepts the following keyword arguments:
6
+
7
+ | Option | Default | Description |
8
+ | ----------------- | ---------------------------------- | ---------------------------------------------------- |
9
+ | `api_key` | `ENV['WARP_API_KEY']` | Bearer token for authentication. |
10
+ | `base_url` | `https://app.warp.dev/api/v1` | API base URL (or `ENV['OZ_API_BASE_URL']`). |
11
+ | `timeout` | `60` | Per-request timeout in seconds. |
12
+ | `max_retries` | `2` | Retries for transient failures (`0` disables). |
13
+ | `default_headers` | `{}` | Extra headers sent on every request. |
14
+ | `logger` | `nil` | A `Logger`; enables Faraday request/response logging.|
15
+ | `adapter` | `Faraday.default_adapter` | Faraday adapter override. |
16
+
17
+ ```ruby
18
+ require 'logger'
19
+
20
+ client = Oz::Client.new(
21
+ api_key: ENV.fetch('WARP_API_KEY'),
22
+ timeout: 120,
23
+ max_retries: 4,
24
+ default_headers: { 'X-Request-Source' => 'my-app' },
25
+ logger: Logger.new($stdout)
26
+ )
27
+ ```
28
+
29
+ ## Global configuration
30
+
31
+ Set defaults once at boot. Every `Oz::Client.new` (and the shared `Oz.client`) inherits them
32
+ unless overridden per call.
33
+
34
+ ```ruby
35
+ Oz.configure do |config|
36
+ config.api_key = ENV.fetch('WARP_API_KEY')
37
+ config.base_url = 'https://app.warp.dev/api/v1'
38
+ config.timeout = 60
39
+ config.max_retries = 3
40
+ config.default_headers = { 'X-Request-Source' => 'my-app' }
41
+ end
42
+
43
+ # Lazily-built shared client using the global configuration:
44
+ Oz.client.agent.list
45
+ ```
46
+
47
+ ## Environment variables
48
+
49
+ | Variable | Description |
50
+ | ----------------------- | ----------------------------------------------------------------- |
51
+ | `WARP_API_KEY` | Bearer token used to authenticate requests. |
52
+ | `OZ_API_BASE_URL` | Override the API base URL. |
53
+ | `OZ_API_CUSTOM_HEADERS` | Extra headers, one `Key: Value` per line, added to every request. |
54
+
55
+ Precedence for each setting is: **explicit argument → environment variable → global
56
+ configuration → built-in default**.
57
+
58
+ `OZ_API_CUSTOM_HEADERS` is parsed as newline-separated `Key: Value` pairs:
59
+
60
+ ```sh
61
+ export OZ_API_CUSTOM_HEADERS="X-Team: platform
62
+ X-Trace: enabled"
63
+ ```
64
+
65
+ ## Retries and backoff
66
+
67
+ Transient failures are retried automatically:
68
+
69
+ - Connection errors and timeouts.
70
+ - HTTP `408`, `409`, `429`, and any `5xx` response.
71
+
72
+ Backoff is exponential with jitter, starting at 0.5s and capped at 8s. A numeric
73
+ `Retry-After` response header is honoured when present. Disable retries with
74
+ `max_retries: 0`.
75
+
76
+ ## Timeouts
77
+
78
+ `timeout` sets the overall request timeout (seconds). The connection-open timeout is derived
79
+ as `min(timeout, 10)`.
80
+
81
+ ## Thread safety
82
+
83
+ A client is safe to share for sequential use. For heavily concurrent workloads, prefer one
84
+ client per thread.
@@ -0,0 +1,87 @@
1
+ # Error Handling
2
+
3
+ Every failure raised by the SDK descends from `Oz::Error`. API failures specifically raise
4
+ `Oz::APIError` subclasses that carry useful metadata.
5
+
6
+ ## Hierarchy
7
+
8
+ ```
9
+ StandardError
10
+ └── Oz::Error
11
+ ├── Oz::ConfigurationError
12
+ └── Oz::APIError
13
+ ├── Oz::APIConnectionError
14
+ │ └── Oz::APITimeoutError
15
+ └── Oz::APIStatusError
16
+ ├── Oz::BadRequestError (400)
17
+ ├── Oz::AuthenticationError (401)
18
+ ├── Oz::PermissionDeniedError (403)
19
+ ├── Oz::NotFoundError (404)
20
+ ├── Oz::ConflictError (409)
21
+ ├── Oz::UnprocessableEntityError (422)
22
+ ├── Oz::RateLimitError (429)
23
+ └── Oz::InternalServerError (5xx)
24
+ ```
25
+
26
+ ## Error metadata
27
+
28
+ `Oz::APIError` exposes:
29
+
30
+ | Method | Description |
31
+ | ------------- | -------------------------------------------------------------- |
32
+ | `message` | Human-readable message (includes server `detail`/`title`). |
33
+ | `status_code` | HTTP status code (`nil` for connection/timeout errors). |
34
+ | `code` | Machine-readable error code (e.g. `"resource_not_found"`). |
35
+ | `body` | The parsed response body (Hash/String), when available. |
36
+ | `request_id` | The `X-Request-Id` header, for correlating with server logs. |
37
+ | `response` | The raw Faraday response, when available. |
38
+
39
+ ## Handling errors
40
+
41
+ Rescue from the most specific to the most general:
42
+
43
+ ```ruby
44
+ begin
45
+ client.agent.run(prompt: 'do the thing')
46
+ rescue Oz::RateLimitError => e
47
+ warn "Rate limited; retry later. request_id=#{e.request_id}"
48
+ rescue Oz::AuthenticationError
49
+ warn 'Authentication failed — check WARP_API_KEY.'
50
+ rescue Oz::NotFoundError
51
+ warn 'Resource not found.'
52
+ rescue Oz::APIStatusError => e
53
+ warn "API error #{e.status_code} (#{e.code}): #{e.message}"
54
+ rescue Oz::APITimeoutError
55
+ warn 'Request timed out.'
56
+ rescue Oz::APIConnectionError => e
57
+ warn "Connection problem: #{e.message}"
58
+ rescue Oz::APIError => e
59
+ warn "Unexpected API error: #{e.message}"
60
+ end
61
+ ```
62
+
63
+ ## Machine-readable error codes
64
+
65
+ The platform returns a stable `code` for many failures. Common values include
66
+ `insufficient_credits`, `feature_not_available`, `external_authentication_required`,
67
+ `not_authorized`, `invalid_request`, `resource_not_found`, `budget_exceeded`,
68
+ `integration_disabled`, `integration_not_configured`, `operation_not_supported`,
69
+ `environment_setup_failed`, `content_policy_violation`, `conflict`,
70
+ `authentication_required`, `resource_unavailable`, and `internal_error`.
71
+
72
+ ```ruby
73
+ rescue Oz::APIStatusError => e
74
+ case e.code
75
+ when 'insufficient_credits' then notify_billing
76
+ when 'content_policy_violation' then log_and_skip(e)
77
+ else raise
78
+ end
79
+ end
80
+ ```
81
+
82
+ ## Automatic retries
83
+
84
+ The client retries transient failures before raising — connection errors, timeouts, and
85
+ HTTP `408`, `409`, `429`, and `5xx` responses — with exponential backoff and jitter (honouring
86
+ a numeric `Retry-After` header). The error is only raised after retries are exhausted.
87
+ Configure with `max_retries:` (default `2`; `0` disables).
@@ -0,0 +1,92 @@
1
+ # Getting Started
2
+
3
+ ## Requirements
4
+
5
+ - Ruby >= 3.1 (the project defaults to **Ruby 4.0**, managed with
6
+ [mise](https://mise.jdx.dev) via [`mise.toml`](../mise.toml))
7
+ - A Warp API key (set as the `WARP_API_KEY` environment variable)
8
+
9
+ ## Installation
10
+
11
+ With Bundler, add to your `Gemfile`:
12
+
13
+ ```ruby
14
+ gem 'oz-agent-sdk'
15
+ ```
16
+
17
+ and run `bundle install`. Without Bundler:
18
+
19
+ ```sh
20
+ gem install oz-agent-sdk
21
+ ```
22
+
23
+ ## Authentication
24
+
25
+ The client authenticates with a Bearer token. By default it reads `WARP_API_KEY` from the
26
+ environment:
27
+
28
+ ```sh
29
+ export WARP_API_KEY="sk-..."
30
+ ```
31
+
32
+ ```ruby
33
+ require 'oz'
34
+
35
+ client = Oz::Client.new # picks up WARP_API_KEY
36
+ # or pass it explicitly:
37
+ client = Oz::Client.new(api_key: 'sk-...')
38
+ ```
39
+
40
+ If no key is available, the constructor raises `Oz::AuthenticationError`.
41
+
42
+ ## Your first agent run
43
+
44
+ ```ruby
45
+ require 'oz'
46
+
47
+ client = Oz::Client.new
48
+
49
+ run = client.agent.run(prompt: 'Add tests for the user model')
50
+ puts "Started run #{run.run_id} (#{run.state})"
51
+ ```
52
+
53
+ `run` is an `Oz::Model`; access fields as methods or with `[]`:
54
+
55
+ ```ruby
56
+ run.run_id # => "a1b2c3..."
57
+ run.state # => "QUEUED"
58
+ run['task_id'] # => "a1b2c3..." (deprecated alias of run_id)
59
+ run.at_capacity? # => false
60
+ ```
61
+
62
+ ## Polling for completion
63
+
64
+ The run starts asynchronously. Poll `runs.retrieve` until it reaches a terminal state:
65
+
66
+ ```ruby
67
+ TERMINAL = %w[SUCCEEDED FAILED ERROR CANCELLED].freeze
68
+
69
+ run = client.agent.run(prompt: 'Add tests for the user model')
70
+
71
+ loop do
72
+ current = client.agent.runs.retrieve(run.run_id)
73
+ puts current.state
74
+ break if TERMINAL.include?(current.state)
75
+
76
+ sleep 5
77
+ end
78
+ ```
79
+
80
+ ## Continuing a conversation
81
+
82
+ Pass `conversation_id` to continue from a previous run, or use a follow-up message:
83
+
84
+ ```ruby
85
+ client.agent.runs.submit_followup(run.run_id, message: 'Also update the changelog')
86
+ ```
87
+
88
+ ## Next steps
89
+
90
+ - [Configuration](configuration.md) — timeouts, retries, custom headers, logging.
91
+ - [API Reference](api_reference.md) — the full surface area.
92
+ - [Error Handling](error_handling.md) — robust failure handling.
data/docs/index.md ADDED
@@ -0,0 +1,56 @@
1
+ # Oz Ruby SDK Documentation
2
+
3
+ The Oz Ruby SDK is an idiomatic, resource-oriented client for the
4
+ [Oz API](https://docs.warp.dev) — Warp's cloud agent platform.
5
+
6
+ ## Contents
7
+
8
+ - [Getting Started](getting_started.md) — installation, authentication, your first run.
9
+ - [Configuration](configuration.md) — client options, environment variables, retries, logging.
10
+ - [API Reference](api_reference.md) — every resource and method.
11
+ - [Error Handling](error_handling.md) — the exception hierarchy and retry behaviour.
12
+
13
+ ## At a glance
14
+
15
+ ```ruby
16
+ require 'oz'
17
+
18
+ client = Oz::Client.new(api_key: ENV['WARP_API_KEY'])
19
+
20
+ run = client.agent.run(prompt: 'Fix the bug in auth.rb')
21
+ puts run.run_id
22
+
23
+ client.agent.runs.list(limit: 20).auto_paging_each do |r|
24
+ puts "#{r.run_id} #{r.state} #{r.title}"
25
+ end
26
+ ```
27
+
28
+ ## Resource map
29
+
30
+ | Ruby | HTTP |
31
+ | --------------------------------------------- | ------------------------------------------------ |
32
+ | `client.agent.run` | `POST /agent/runs` |
33
+ | `client.agent.list` | `GET /agent` |
34
+ | `client.agent.get_artifact` | `GET /agent/artifacts/{uid}` |
35
+ | `client.agent.list_environments` | `GET /agent/environments` |
36
+ | `client.agent.runs.retrieve` | `GET /agent/runs/{id}` |
37
+ | `client.agent.runs.list` | `GET /agent/runs` |
38
+ | `client.agent.runs.cancel` | `POST /agent/runs/{id}/cancel` |
39
+ | `client.agent.runs.list_handoff_attachments` | `GET /agent/runs/{id}/handoff/attachments` |
40
+ | `client.agent.runs.submit_followup` | `POST /agent/runs/{id}/followups` |
41
+ | `client.agent.schedules.create` | `POST /agent/schedules` |
42
+ | `client.agent.schedules.retrieve` | `GET /agent/schedules/{id}` |
43
+ | `client.agent.schedules.update` | `PUT /agent/schedules/{id}` |
44
+ | `client.agent.schedules.list` | `GET /agent/schedules` |
45
+ | `client.agent.schedules.delete` | `DELETE /agent/schedules/{id}` |
46
+ | `client.agent.schedules.pause` | `POST /agent/schedules/{id}/pause` |
47
+ | `client.agent.schedules.resume` | `POST /agent/schedules/{id}/resume` |
48
+ | `client.agent.identities.create` | `POST /agent/identities` |
49
+ | `client.agent.identities.update` | `PUT /agent/identities/{uid}` |
50
+ | `client.agent.identities.list` | `GET /agent/identities` |
51
+ | `client.agent.identities.retrieve` | `GET /agent/identities/{uid}` |
52
+ | `client.agent.identities.delete` | `DELETE /agent/identities/{uid}` |
53
+ | `client.agent.sessions.check_redirect` | `GET /agent/sessions/{uuid}/redirect` |
54
+ | `client.agent.conversations.check_redirect` | `GET /agent/conversations/{id}/redirect` |
55
+
56
+ See the [examples](../examples/) directory for runnable scripts.
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Manage agent identities (team-owned execution principals).
4
+ #
5
+ # WARP_API_KEY=sk-... ruby examples/identities.rb
6
+
7
+ require 'oz'
8
+
9
+ client = Oz::Client.new
10
+
11
+ identity = client.agent.identities.create(
12
+ name: 'ci-bot',
13
+ description: 'Runs nightly maintenance tasks',
14
+ skills: ['warpdotdev/warp-server:.claude/skills/deploy/SKILL.md']
15
+ )
16
+ puts "Created identity #{identity.uid}"
17
+
18
+ puts 'All identities:'
19
+ client.agent.identities.list.agents.each do |agent|
20
+ puts " #{agent.uid} #{agent.name}"
21
+ end
22
+
23
+ client.agent.identities.update(identity.uid, description: 'Updated description')
24
+ puts 'Updated.'
25
+
26
+ # Use the identity as the execution principal for a team-owned run:
27
+ run = client.agent.run(
28
+ prompt: 'Run the nightly checks',
29
+ team: true,
30
+ agent_identity_uid: identity.uid
31
+ )
32
+ puts "Started run #{run.run_id} as identity #{identity.uid}"
33
+
34
+ client.agent.identities.delete(identity.uid)
35
+ puts 'Deleted identity.'
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ # List recent runs, paging through all results.
4
+ #
5
+ # WARP_API_KEY=sk-... ruby examples/list_runs.rb
6
+
7
+ require 'oz'
8
+
9
+ client = Oz::Client.new
10
+
11
+ # A single page:
12
+ page = client.agent.runs.list(limit: 25, sort_by: 'created_at', sort_order: 'desc')
13
+ puts "First page: #{page.size} run(s), more available: #{page.next_page?}"
14
+ page.each do |run|
15
+ puts format(' %-38s %-11s %s', run.run_id, run.state, run.title)
16
+ end
17
+
18
+ puts
19
+ puts 'All runs created in the last 24h that are in progress:'
20
+
21
+ filtered = client.agent.runs.list(
22
+ state: %w[INPROGRESS QUEUED],
23
+ created_after: Time.now - (24 * 60 * 60)
24
+ )
25
+
26
+ count = 0
27
+ filtered.auto_paging_each do |run|
28
+ count += 1
29
+ puts " #{run.run_id} #{run.state}"
30
+ end
31
+ puts "Total: #{count}"
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Run a cloud agent and poll until it finishes.
4
+ #
5
+ # WARP_API_KEY=sk-... ruby examples/run_agent.rb "Fix the bug in auth.rb"
6
+ #
7
+ # Requires the gem to be installed, or run with `bundle exec` from the repo root.
8
+
9
+ require 'oz'
10
+
11
+ prompt = ARGV.first || 'Summarize the README and suggest improvements'
12
+
13
+ client = Oz::Client.new # reads WARP_API_KEY from the environment
14
+
15
+ run = client.agent.run(
16
+ prompt: prompt,
17
+ config: {
18
+ # environment_id: "your-environment-id",
19
+ model_id: 'claude-sonnet-4',
20
+ name: 'sdk-example'
21
+ }
22
+ )
23
+
24
+ puts "Started run #{run.run_id} (state: #{run.state})"
25
+
26
+ TERMINAL = %w[SUCCEEDED FAILED ERROR CANCELLED].freeze
27
+
28
+ loop do
29
+ current = client.agent.runs.retrieve(run.run_id)
30
+ puts " #{Time.now.strftime('%H:%M:%S')} #{current.state}"
31
+ break if TERMINAL.include?(current.state)
32
+
33
+ sleep 5
34
+ end
35
+
36
+ final = client.agent.runs.retrieve(run.run_id)
37
+ puts "Finished: #{final.state}"
38
+ puts "Session: #{final.session_link}" if final.session_link
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Create, inspect, pause/resume, and delete a scheduled agent.
4
+ #
5
+ # WARP_API_KEY=sk-... ruby examples/schedules.rb
6
+
7
+ require 'oz'
8
+
9
+ client = Oz::Client.new
10
+
11
+ schedule = client.agent.schedules.create(
12
+ cron_schedule: '0 9 * * *', # daily at 09:00 UTC
13
+ name: 'nightly-dependency-check',
14
+ prompt: 'Check for outdated dependencies and open a PR if needed',
15
+ enabled: true
16
+ )
17
+ puts "Created schedule #{schedule.schedule_id} (#{schedule.name})"
18
+
19
+ puts 'All schedules:'
20
+ client.agent.schedules.list.schedules.each do |s|
21
+ puts " #{s.schedule_id} #{s.name} #{s.cron_schedule}"
22
+ end
23
+
24
+ client.agent.schedules.pause(schedule.schedule_id)
25
+ puts 'Paused.'
26
+
27
+ client.agent.schedules.resume(schedule.schedule_id)
28
+ puts 'Resumed.'
29
+
30
+ result = client.agent.schedules.delete(schedule.schedule_id)
31
+ puts "Deleted: #{result.success}"