withruntime 0.18.0 → 0.20.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/lib/withruntime/agents.rb +62 -4
- data/lib/withruntime/ci.rb +6 -1
- data/lib/withruntime/client.rb +2 -1
- data/lib/withruntime/errors.rb +1 -1
- data/lib/withruntime/products.rb +18 -0
- data/lib/withruntime/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a7812f8e62878add0f508438d590167776350a52b7f9c213e77fee8447afadac
|
|
4
|
+
data.tar.gz: 84b04befc8a18f0420a1026fed88a7a29d4e10efc01dbad3b3632ea4ea515829
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ad569904e75cd01d9a9725a85a77cbdb0e5a44fa709e5bec3e6c40919a0db3675b94b2c8ad6fd8b8f99a50e666147667229f26814be9cdf142396ac6eee27db6
|
|
7
|
+
data.tar.gz: ba71b0cae765bfc87c8645587abd698643e96087452aa8e499630632e955df8f72cd0c961e37b798bd7dfa795827d498d84a1da455d4e742326f2aa5fad76cd8
|
data/lib/withruntime/agents.rb
CHANGED
|
@@ -10,13 +10,31 @@ module WithRuntime
|
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
# One entry of a session's log: +seq+, +kind+ (input, answer, reply, ask,
|
|
13
|
-
# status, result, error, note,
|
|
14
|
-
# its parent's log
|
|
15
|
-
# +body
|
|
13
|
+
# status, result, error, note, child: a child session's end, posted into
|
|
14
|
+
# its parent's log, turn: a model turn, or tool: a tool call, the trace's
|
|
15
|
+
# spans with their fields in +body+), +actor+, +body+ and +created_at+.
|
|
16
|
+
# +text+ is its words, +body.text+.
|
|
16
17
|
class AgentEvent < Record
|
|
17
18
|
def text = self["body"].is_a?(Hash) ? self["body"]["text"] : nil
|
|
18
19
|
end
|
|
19
20
|
|
|
21
|
+
# A session's trace (+AgentSession#trace+): +session_id+; +totals+ (turns,
|
|
22
|
+
# tool_calls, input_tokens (uncached), output_tokens, cache_read_tokens,
|
|
23
|
+
# cache_write_tokens, cost_usd at the provider's list price,
|
|
24
|
+
# unpriced_turns, failed_turns, failed_tool_calls, model_ms, tool_ms);
|
|
25
|
+
# +models+ and +tools+, the same by model and by tool; and +spans+, each
|
|
26
|
+
# turn and tool call in order. A turn has its +model+, +started_at+,
|
|
27
|
+
# +duration_ms+, +first_token_ms+, token counts, +cost_usd+ (nil for an
|
|
28
|
+
# unpriced model), +stop_reason+, +status+, +error+ and +tool_calls+; a
|
|
29
|
+
# tool call its +name+, +turn+, +started_at+, +duration_ms+, +input+,
|
|
30
|
+
# +output+ and +error+.
|
|
31
|
+
class AgentTrace < Record
|
|
32
|
+
def totals = Record.new(self["totals"])
|
|
33
|
+
def models = (self["models"] || []).map { |row| Record.new(row) }
|
|
34
|
+
def tools = (self["tools"] || []).map { |row| Record.new(row) }
|
|
35
|
+
def spans = (self["spans"] || []).map { |row| Record.new(row) }
|
|
36
|
+
end
|
|
37
|
+
|
|
20
38
|
# A session as the API answers it. Times are ISO 8601 strings.
|
|
21
39
|
#
|
|
22
40
|
# +id+, +agent_id+, +agent_version+, +key+, +trigger+ (api, slack, github,
|
|
@@ -69,7 +87,9 @@ module WithRuntime
|
|
|
69
87
|
# each an egress secret's name: each session takes the one with the most
|
|
70
88
|
# usage left, and the review template moves to the next when one is out
|
|
71
89
|
# of usage), +mcp+ ([{ name:, url: }]), +volumes+
|
|
72
|
-
# ([{ volume:, path: }]), +
|
|
90
|
+
# ([{ volume:, path: }]), +network+ ({ internet:, allow: }: with allow,
|
|
91
|
+
# each session's sandbox reaches only those hosts), +idle_pause_seconds+,
|
|
92
|
+
# +max_session_seconds+,
|
|
73
93
|
# +max_concurrent+, +max_session_dollars+ (more than 0, at most 10000, 5
|
|
74
94
|
# unless set: the session and every session under it, the root's covering
|
|
75
95
|
# its tree; a tree at it stops, reason "budget"), +max_day_dollars+ (more
|
|
@@ -89,6 +109,16 @@ module WithRuntime
|
|
|
89
109
|
@asks = AgentAsks.new(transport)
|
|
90
110
|
end
|
|
91
111
|
|
|
112
|
+
# Claude Managed Agents' API on Runtime: the options Anthropic's Ruby SDK
|
|
113
|
+
# takes, so code written for it runs here unchanged:
|
|
114
|
+
#
|
|
115
|
+
# client = Anthropic::Client.new(**runtime.agents.anthropic)
|
|
116
|
+
#
|
|
117
|
+
# Sessions call the model with the account's own Anthropic key, the egress
|
|
118
|
+
# secret ANTHROPIC_API_KEY (runtime secrets set ANTHROPIC_API_KEY --host
|
|
119
|
+
# api.anthropic.com).
|
|
120
|
+
def anthropic = { base_url: "#{@t.base_url}/anthropic", api_key: @t.api_key }
|
|
121
|
+
|
|
92
122
|
# Makes an agent at version 1. A name already used is a ConflictError
|
|
93
123
|
# (name_taken); the names sessions, triggers, templates and approvals are
|
|
94
124
|
# refused, since they are paths beside the agents.
|
|
@@ -241,6 +271,22 @@ module WithRuntime
|
|
|
241
271
|
end
|
|
242
272
|
end
|
|
243
273
|
|
|
274
|
+
# A page of its trace, an AgentTrace: every model turn and tool call its
|
|
275
|
+
# harness made, with timing, tokens and cost. Its totals cover the whole
|
|
276
|
+
# session; its spans are up to +limit+ (200 by default, 500 at most)
|
|
277
|
+
# after +after+: call again with +after: page.next_after+ until it is nil.
|
|
278
|
+
# +format: "otlp"+ returns the same page as OpenTelemetry traces instead,
|
|
279
|
+
# OTLP/JSON (GenAI semantic conventions) as a Hash with "nextAfter", to
|
|
280
|
+
# POST without it to any collector's /v1/traces.
|
|
281
|
+
def trace(format: "json", after: 0, limit: nil)
|
|
282
|
+
raise ArgumentError, "format is json or otlp" unless %w[json otlp].include?(format.to_s)
|
|
283
|
+
|
|
284
|
+
query = { "format" => format.to_s, "after" => after }
|
|
285
|
+
query["limit"] = limit if limit
|
|
286
|
+
body = @t.json("GET", path("/trace"), query: query)
|
|
287
|
+
format.to_s == "otlp" ? body : AgentTrace.new(body)
|
|
288
|
+
end
|
|
289
|
+
|
|
244
290
|
# Asks the session to stop and keeps the answer. A running session ends
|
|
245
291
|
# once its sandbox is deleted; this does not wait for that (+wait+ does).
|
|
246
292
|
def stop
|
|
@@ -371,6 +417,11 @@ module WithRuntime
|
|
|
371
417
|
# one agent's sessions sharing a memory, with the same +step+, are one
|
|
372
418
|
# row while it is open, and one answer reaches every session asking. +state+: open, answered,
|
|
373
419
|
# withdrawn, expired (no pick) or closed (every asking session ended).
|
|
420
|
+
#
|
|
421
|
+
# A tool call the agent's +permissions+ hold is an ask too, with the
|
|
422
|
+
# options Allow and Deny and the call in +toolCall+ ({tool, input,
|
|
423
|
+
# toolUseId, seq, policy, reasonCode}): +approve+ lets it run, +deny+ keeps
|
|
424
|
+
# it from running.
|
|
374
425
|
class AgentAsks < Product
|
|
375
426
|
# The first page, newest first: open asks unless +state+ (one or a list)
|
|
376
427
|
# says otherwise; of one +agent+; carrying every one of +labels+ (who sees
|
|
@@ -393,6 +444,13 @@ module WithRuntime
|
|
|
393
444
|
Record.new(@t.json("POST", "/v1/agents/asks/#{seg(id)}/answer", body: body, key: idempotency_key))
|
|
394
445
|
end
|
|
395
446
|
|
|
447
|
+
# Lets a tool call the agent's permissions held run (its ask's Allow).
|
|
448
|
+
def approve(id, idempotency_key: nil) = answer(id, "Allow", idempotency_key: idempotency_key)
|
|
449
|
+
|
|
450
|
+
# Keeps a held tool call from running (its ask's Deny); +message+ is told
|
|
451
|
+
# to the agent as the reason.
|
|
452
|
+
def deny(id, message = nil, idempotency_key: nil) = answer(id, "Deny", text: message, idempotency_key: idempotency_key)
|
|
453
|
+
|
|
396
454
|
private
|
|
397
455
|
|
|
398
456
|
def asks_page(query, cursor)
|
data/lib/withruntime/ci.rb
CHANGED
|
@@ -32,7 +32,8 @@ module WithRuntime
|
|
|
32
32
|
class CIRepositories < Product
|
|
33
33
|
# Connects +repository+ ("owner/name"), read through Runtime's GitHub App.
|
|
34
34
|
# Pushes and pull requests then run the checks written in +config_path:+
|
|
35
|
-
# (runtime.yml
|
|
35
|
+
# (runtime.yml; a cloudbuild.yaml or buildspec.yml runs as Cloud Build or
|
|
36
|
+
# CodeBuild runs it). Optional: production_branch (main), config_path,
|
|
36
37
|
# installation (the GitHub App installation to read it through; the newest
|
|
37
38
|
# when left out), name and labels.
|
|
38
39
|
def connect(repository, production_branch: nil, config_path: nil, installation: nil, name: nil, labels: nil,
|
|
@@ -97,6 +98,10 @@ module WithRuntime
|
|
|
97
98
|
# has its +review+: the verdict (pass or block), summary, findings (kind,
|
|
98
99
|
# file, line, what, fix), notes, and the agent, the model the step asked
|
|
99
100
|
# for (nil when none) and the session that gave it; nil otherwise.
|
|
101
|
+
# +annotations+ are the lines of the repository's files its log reports
|
|
102
|
+
# (path, start_line, end_line, start_column, level: notice, warning or
|
|
103
|
+
# failure, message, title), at most 50, failures first, as its own GitHub
|
|
104
|
+
# check run (+github_check_run+, "runtime / <name>") shows them.
|
|
100
105
|
def get(id) = Record.new(@t.json("GET", "/v1/ci/jobs/#{seg(id)}"))
|
|
101
106
|
end
|
|
102
107
|
|
data/lib/withruntime/client.rb
CHANGED
|
@@ -23,7 +23,7 @@ module WithRuntime
|
|
|
23
23
|
RENAME_RETIRES = nil
|
|
24
24
|
|
|
25
25
|
class Client
|
|
26
|
-
attr_reader :transport, :sandboxes, :snapshots, :images, :volumes, :secrets, :reservations, :limits, :emails, :referrals, :plans,
|
|
26
|
+
attr_reader :transport, :sandboxes, :snapshots, :images, :volumes, :secrets, :reservations, :limits, :jobs, :emails, :referrals, :plans,
|
|
27
27
|
:switching, :events, :webhooks, :otel, :audit, :feedback, :support, :domains, :ports, :ips, :networks, :sso, :mcp, :agents,
|
|
28
28
|
:apps, :functions, :builds, :ci, :containers
|
|
29
29
|
|
|
@@ -58,6 +58,7 @@ module WithRuntime
|
|
|
58
58
|
@secrets = Secrets.new(@transport)
|
|
59
59
|
@reservations = Reservations.new(@transport)
|
|
60
60
|
@limits = Limits.new(@transport)
|
|
61
|
+
@jobs = Jobs.new(@transport)
|
|
61
62
|
@emails = Emails.new(@transport)
|
|
62
63
|
@referrals = Referrals.new(@transport)
|
|
63
64
|
@plans = Plans.new(@transport)
|
data/lib/withruntime/errors.rb
CHANGED
|
@@ -19,7 +19,7 @@ module WithRuntime
|
|
|
19
19
|
# account without credit stops.
|
|
20
20
|
PASSING = %w[no_capacity no_credit_running_limit no_credit_total_limit].freeze
|
|
21
21
|
# Refusals of a create that clear when a sandbox stops or a host frees room.
|
|
22
|
-
WAITS_FOR_ROOM = %w[no_credit_running_limit no_credit_total_limit no_credit_domain_limit no_credit_capacity_full quota_exceeded no_capacity volume_releasing].freeze
|
|
22
|
+
WAITS_FOR_ROOM = %w[no_credit_running_limit no_credit_total_limit no_credit_domain_limit no_credit_capacity_full quota_exceeded account_share_full no_capacity volume_releasing].freeze
|
|
23
23
|
# Refusals that say nothing ran (a guest still busy, the API briefly
|
|
24
24
|
# busy, the caller's rate): sent again past max_retries, with growing
|
|
25
25
|
# waits, until the call's deadline.
|
data/lib/withruntime/products.rb
CHANGED
|
@@ -186,6 +186,24 @@ module WithRuntime
|
|
|
186
186
|
def get = Record.new(@t.json("GET", "/v1/limits"))
|
|
187
187
|
end
|
|
188
188
|
|
|
189
|
+
# +runtime.jobs+: other platforms' jobs read into Runtime jobs. Create and manage
|
|
190
|
+
# jobs with the CLI (+runtime jobs+), the TypeScript or Python SDK, or the HTTP API.
|
|
191
|
+
class Jobs < Product
|
|
192
|
+
# Reads a Google Cloud Run job's YAML (with the Cloud Scheduler job that runs it)
|
|
193
|
+
# or an AWS Batch job definition (API JSON, describe-job-definitions output or a
|
|
194
|
+
# CloudFormation template, with the EventBridge schedule or rule that submits it)
|
|
195
|
+
# into the Runtime jobs that run the same container. +files+ is
|
|
196
|
+
# <tt>[{ "path" => "job.yaml", "text" => ... }]</tt>; +from+ is "cloud-run" or
|
|
197
|
+
# "aws-batch" (found from the files when nil); +parameters+ are a CloudFormation
|
|
198
|
+
# template's values. Changes nothing: +runtime jobs import+ builds and creates it.
|
|
199
|
+
def import_plan(files, from: nil, parameters: nil)
|
|
200
|
+
body = { "files" => files }
|
|
201
|
+
body["from"] = from if from
|
|
202
|
+
body["parameters"] = parameters if parameters && !parameters.empty?
|
|
203
|
+
Record.new(@t.json("POST", "/v1/job-imports", body: body))
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
|
|
189
207
|
# +runtime.referrals+: the account's referral link and what it earned. Money is
|
|
190
208
|
# integer microdollars in strings.
|
|
191
209
|
class Referrals < Product
|
data/lib/withruntime/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: withruntime
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.20.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Runtime
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-10-
|
|
11
|
+
date: 2026-10-26 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: 'Linux sandboxes for agents, and every other Runtime Cloud product: streaming
|
|
14
14
|
commands and terminals, files and watches, images, durable volumes and backups,
|