arcp 1.0.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 +7 -0
- data/CHANGELOG.md +31 -0
- data/CONFORMANCE.md +71 -0
- data/LICENSE +202 -0
- data/README.md +135 -0
- data/lib/arcp/auth/auth_scheme.rb +16 -0
- data/lib/arcp/auth/bearer.rb +38 -0
- data/lib/arcp/auth.rb +4 -0
- data/lib/arcp/client.rb +354 -0
- data/lib/arcp/clock.rb +35 -0
- data/lib/arcp/credential.rb +65 -0
- data/lib/arcp/credential_provisioner.rb +132 -0
- data/lib/arcp/envelope.rb +115 -0
- data/lib/arcp/errors.rb +154 -0
- data/lib/arcp/ids.rb +18 -0
- data/lib/arcp/job/accepted.rb +37 -0
- data/lib/arcp/job/agent_ref.rb +18 -0
- data/lib/arcp/job/cancel.rb +18 -0
- data/lib/arcp/job/event.rb +68 -0
- data/lib/arcp/job/event_body/delegate.rb +24 -0
- data/lib/arcp/job/event_body/log.rb +20 -0
- data/lib/arcp/job/event_body/metric.rb +20 -0
- data/lib/arcp/job/event_body/progress.rb +27 -0
- data/lib/arcp/job/event_body/result_chunk.rb +42 -0
- data/lib/arcp/job/event_body/status.rb +25 -0
- data/lib/arcp/job/event_body/thought.rb +12 -0
- data/lib/arcp/job/event_body/tool_call.rb +16 -0
- data/lib/arcp/job/event_body/tool_result.rb +23 -0
- data/lib/arcp/job/event_body/trace_span.rb +30 -0
- data/lib/arcp/job/handle.rb +16 -0
- data/lib/arcp/job/job_error.rb +31 -0
- data/lib/arcp/job/result.rb +30 -0
- data/lib/arcp/job/submit.rb +32 -0
- data/lib/arcp/job/subscribe.rb +22 -0
- data/lib/arcp/job/subscribed.rb +14 -0
- data/lib/arcp/job/summary.rb +27 -0
- data/lib/arcp/job/unsubscribe.rb +10 -0
- data/lib/arcp/job.rb +15 -0
- data/lib/arcp/lease.rb +212 -0
- data/lib/arcp/message_types.rb +35 -0
- data/lib/arcp/runtime/credential_registry.rb +67 -0
- data/lib/arcp/runtime/event_log.rb +62 -0
- data/lib/arcp/runtime/job_context.rb +167 -0
- data/lib/arcp/runtime/job_manager.rb +256 -0
- data/lib/arcp/runtime/lease_manager.rb +88 -0
- data/lib/arcp/runtime/runtime.rb +125 -0
- data/lib/arcp/runtime/session_actor.rb +300 -0
- data/lib/arcp/runtime/subscription_manager.rb +57 -0
- data/lib/arcp/runtime.rb +10 -0
- data/lib/arcp/serializer.rb +43 -0
- data/lib/arcp/session/ack.rb +14 -0
- data/lib/arcp/session/agent_inventory.rb +51 -0
- data/lib/arcp/session/bye.rb +10 -0
- data/lib/arcp/session/capability_set.rb +29 -0
- data/lib/arcp/session/feature.rb +25 -0
- data/lib/arcp/session/hello.rb +34 -0
- data/lib/arcp/session/jobs_response.rb +18 -0
- data/lib/arcp/session/list_jobs.rb +19 -0
- data/lib/arcp/session/ping.rb +14 -0
- data/lib/arcp/session/pong.rb +14 -0
- data/lib/arcp/session/session_error.rb +23 -0
- data/lib/arcp/session/welcome.rb +38 -0
- data/lib/arcp/session.rb +26 -0
- data/lib/arcp/trace.rb +51 -0
- data/lib/arcp/transport/base.rb +29 -0
- data/lib/arcp/transport/memory_transport.rb +54 -0
- data/lib/arcp/transport/stdio_transport.rb +56 -0
- data/lib/arcp/transport/websocket_transport.rb +47 -0
- data/lib/arcp/transport.rb +6 -0
- data/lib/arcp/version.rb +7 -0
- data/lib/arcp.rb +19 -0
- data/sig/arcp/client.rbs +16 -0
- data/sig/arcp/credential.rbs +51 -0
- data/sig/arcp/envelope.rbs +25 -0
- data/sig/arcp/errors.rbs +40 -0
- data/sig/arcp/job.rbs +83 -0
- data/sig/arcp/lease.rbs +41 -0
- data/sig/arcp/runtime.rbs +41 -0
- data/sig/arcp/serializer.rbs +8 -0
- data/sig/arcp/session.rbs +56 -0
- data/sig/arcp/transport.rbs +18 -0
- data/sig/arcp.rbs +5 -0
- metadata +226 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Arcp
|
|
4
|
+
module Session
|
|
5
|
+
Welcome = Data.define(
|
|
6
|
+
:runtime_name, :runtime_version, :capabilities,
|
|
7
|
+
:heartbeat_interval_sec, :resume_token, :resume_window_sec
|
|
8
|
+
) do
|
|
9
|
+
def self.from_h(h)
|
|
10
|
+
h = h.transform_keys(&:to_s)
|
|
11
|
+
caps = h['capabilities'] || {}
|
|
12
|
+
new(
|
|
13
|
+
runtime_name: h['runtime_name'],
|
|
14
|
+
runtime_version: h['runtime_version'],
|
|
15
|
+
capabilities: CapabilitySet.new(
|
|
16
|
+
features: Array(caps['features']).freeze,
|
|
17
|
+
encodings: Array(caps['encodings']).freeze,
|
|
18
|
+
agents: caps['agents'] ? AgentInventory.from_array(caps['agents']) : nil
|
|
19
|
+
),
|
|
20
|
+
heartbeat_interval_sec: h['heartbeat_interval_sec'],
|
|
21
|
+
resume_token: h['resume_token'],
|
|
22
|
+
resume_window_sec: h['resume_window_sec']
|
|
23
|
+
)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def to_h
|
|
27
|
+
{
|
|
28
|
+
'runtime_name' => runtime_name,
|
|
29
|
+
'runtime_version' => runtime_version,
|
|
30
|
+
'capabilities' => capabilities.to_h,
|
|
31
|
+
'heartbeat_interval_sec' => heartbeat_interval_sec,
|
|
32
|
+
'resume_token' => resume_token,
|
|
33
|
+
'resume_window_sec' => resume_window_sec
|
|
34
|
+
}
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
data/lib/arcp/session.rb
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'session/feature'
|
|
4
|
+
require_relative 'session/capability_set'
|
|
5
|
+
require_relative 'session/agent_inventory'
|
|
6
|
+
require_relative 'session/hello'
|
|
7
|
+
require_relative 'session/welcome'
|
|
8
|
+
require_relative 'session/bye'
|
|
9
|
+
require_relative 'session/session_error'
|
|
10
|
+
require_relative 'session/ping'
|
|
11
|
+
require_relative 'session/pong'
|
|
12
|
+
require_relative 'session/ack'
|
|
13
|
+
require_relative 'session/list_jobs'
|
|
14
|
+
require_relative 'session/jobs_response'
|
|
15
|
+
|
|
16
|
+
module Arcp
|
|
17
|
+
module Session
|
|
18
|
+
# Immutable snapshot of session state after the welcome envelope.
|
|
19
|
+
Info = Data.define(
|
|
20
|
+
:id, :runtime_version, :capabilities, :agents,
|
|
21
|
+
:heartbeat_interval_sec, :resume_token, :resume_window_sec
|
|
22
|
+
) do
|
|
23
|
+
def supports?(feature) = capabilities.supports?(feature)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
data/lib/arcp/trace.rb
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'ids'
|
|
4
|
+
|
|
5
|
+
module Arcp
|
|
6
|
+
module Trace
|
|
7
|
+
KEY = :arcp_trace_context
|
|
8
|
+
|
|
9
|
+
Context = Data.define(:trace_id, :span_id, :attributes)
|
|
10
|
+
|
|
11
|
+
module_function
|
|
12
|
+
|
|
13
|
+
def current
|
|
14
|
+
Fiber[KEY] || Context.new(trace_id: nil, span_id: nil, attributes: {}.freeze)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def current=(ctx)
|
|
18
|
+
Fiber[KEY] = ctx
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def with(trace_id: nil, span_id: nil, attributes: {})
|
|
22
|
+
prev = current
|
|
23
|
+
Fiber[KEY] = Context.new(
|
|
24
|
+
trace_id: trace_id || prev.trace_id || Arcp::Ids.trace_id,
|
|
25
|
+
span_id: span_id || Arcp::Ids.span_id,
|
|
26
|
+
attributes: prev.attributes.merge(attributes).freeze
|
|
27
|
+
)
|
|
28
|
+
yield current
|
|
29
|
+
ensure
|
|
30
|
+
Fiber[KEY] = prev
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# @return [String] new 32-hex trace id.
|
|
34
|
+
def new_trace_id = Arcp::Ids.trace_id
|
|
35
|
+
|
|
36
|
+
def in_span(name, attributes: {}, &)
|
|
37
|
+
tracer = begin
|
|
38
|
+
require 'opentelemetry'
|
|
39
|
+
OpenTelemetry.tracer_provider.tracer('arcp')
|
|
40
|
+
rescue LoadError
|
|
41
|
+
nil
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
if tracer
|
|
45
|
+
tracer.in_span(name, attributes: attributes, &)
|
|
46
|
+
else
|
|
47
|
+
with(attributes: attributes, &)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../envelope'
|
|
4
|
+
|
|
5
|
+
module Arcp
|
|
6
|
+
module Transport
|
|
7
|
+
# Abstract transport interface. Implementations carry frames, not
|
|
8
|
+
# message types — decoding is `Arcp::Envelope.from_h`.
|
|
9
|
+
#
|
|
10
|
+
# `#send` accepts an `Arcp::Envelope` and serializes it.
|
|
11
|
+
# `#receive` suspends the calling fiber until an envelope arrives,
|
|
12
|
+
# then returns it (or nil on clean close).
|
|
13
|
+
class Base
|
|
14
|
+
def send(envelope)
|
|
15
|
+
raise NotImplementedError
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def receive
|
|
19
|
+
raise NotImplementedError
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def close(reason: nil)
|
|
23
|
+
raise NotImplementedError
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def closed? = false
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'async/queue'
|
|
4
|
+
|
|
5
|
+
module Arcp
|
|
6
|
+
module Transport
|
|
7
|
+
# In-process transport backed by a pair of `Async::Queue`s. Used for
|
|
8
|
+
# tests and same-process server/client wiring.
|
|
9
|
+
class MemoryTransport < Base
|
|
10
|
+
attr_reader :sent
|
|
11
|
+
|
|
12
|
+
def initialize(incoming:, outgoing:)
|
|
13
|
+
super()
|
|
14
|
+
@incoming = incoming
|
|
15
|
+
@outgoing = outgoing
|
|
16
|
+
@sent = []
|
|
17
|
+
@closed = false
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self.pair
|
|
21
|
+
a = Async::Queue.new
|
|
22
|
+
b = Async::Queue.new
|
|
23
|
+
[new(incoming: a, outgoing: b), new(incoming: b, outgoing: a)]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def send(envelope)
|
|
27
|
+
raise IOError, 'transport closed' if @closed
|
|
28
|
+
|
|
29
|
+
@sent << envelope
|
|
30
|
+
@outgoing.enqueue(envelope)
|
|
31
|
+
nil
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def receive
|
|
35
|
+
return nil if @closed && @incoming.empty?
|
|
36
|
+
|
|
37
|
+
value = @incoming.dequeue
|
|
38
|
+
return nil if value.equal?(:__arcp_close__)
|
|
39
|
+
|
|
40
|
+
value
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def close(reason: nil)
|
|
44
|
+
return if @closed
|
|
45
|
+
|
|
46
|
+
@closed = true
|
|
47
|
+
@outgoing.enqueue(:__arcp_close__)
|
|
48
|
+
@incoming.enqueue(:__arcp_close__) if @incoming.empty?
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def closed? = @closed
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../serializer'
|
|
4
|
+
|
|
5
|
+
module Arcp
|
|
6
|
+
module Transport
|
|
7
|
+
# Newline-delimited JSON over a pair of IOs. The child process reads
|
|
8
|
+
# from stdin and writes to stdout; the parent connects with its
|
|
9
|
+
# pipe ends. Exit on EOF.
|
|
10
|
+
class StdioTransport < Base
|
|
11
|
+
def initialize(input: $stdin, output: $stdout)
|
|
12
|
+
super()
|
|
13
|
+
@input = input
|
|
14
|
+
@output = output
|
|
15
|
+
@closed = false
|
|
16
|
+
@write_mutex = Mutex.new
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def send(envelope)
|
|
20
|
+
raise IOError, 'transport closed' if @closed
|
|
21
|
+
|
|
22
|
+
line = Arcp::Serializer.dump(envelope.to_h)
|
|
23
|
+
@write_mutex.synchronize do
|
|
24
|
+
@output.write(line)
|
|
25
|
+
@output.write("\n")
|
|
26
|
+
@output.flush
|
|
27
|
+
end
|
|
28
|
+
nil
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def receive
|
|
32
|
+
return nil if @closed
|
|
33
|
+
|
|
34
|
+
line = @input.gets
|
|
35
|
+
if line.nil?
|
|
36
|
+
@closed = true
|
|
37
|
+
return nil
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
Arcp::Envelope.from_json(line)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def close(reason: nil)
|
|
44
|
+
return if @closed
|
|
45
|
+
|
|
46
|
+
@closed = true
|
|
47
|
+
@output.close unless @output.closed? || @output == $stdout
|
|
48
|
+
@input.close unless @input.closed? || @input == $stdin
|
|
49
|
+
rescue IOError
|
|
50
|
+
nil
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def closed? = @closed
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../serializer'
|
|
4
|
+
|
|
5
|
+
module Arcp
|
|
6
|
+
module Transport
|
|
7
|
+
# WebSocket transport built on `async-websocket`. The `connection`
|
|
8
|
+
# argument is an open `Async::WebSocket::Connection`.
|
|
9
|
+
class WebSocketTransport < Base
|
|
10
|
+
def initialize(connection:)
|
|
11
|
+
super()
|
|
12
|
+
@connection = connection
|
|
13
|
+
@closed = false
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def send(envelope)
|
|
17
|
+
raise IOError, 'transport closed' if @closed
|
|
18
|
+
|
|
19
|
+
@connection.write(envelope.to_json)
|
|
20
|
+
@connection.flush if @connection.respond_to?(:flush)
|
|
21
|
+
nil
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def receive
|
|
25
|
+
message = @connection.read
|
|
26
|
+
return nil if message.nil?
|
|
27
|
+
|
|
28
|
+
bytes = message.respond_to?(:buffer) ? message.buffer : message.to_s
|
|
29
|
+
Arcp::Envelope.from_json(bytes)
|
|
30
|
+
rescue EOFError
|
|
31
|
+
@closed = true
|
|
32
|
+
nil
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def close(reason: nil)
|
|
36
|
+
return if @closed
|
|
37
|
+
|
|
38
|
+
@closed = true
|
|
39
|
+
@connection.close if @connection.respond_to?(:close)
|
|
40
|
+
rescue StandardError
|
|
41
|
+
nil
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def closed? = @closed
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
data/lib/arcp/version.rb
ADDED
data/lib/arcp.rb
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'arcp/version'
|
|
4
|
+
require_relative 'arcp/ids'
|
|
5
|
+
require_relative 'arcp/clock'
|
|
6
|
+
require_relative 'arcp/errors'
|
|
7
|
+
require_relative 'arcp/serializer'
|
|
8
|
+
require_relative 'arcp/message_types'
|
|
9
|
+
require_relative 'arcp/envelope'
|
|
10
|
+
require_relative 'arcp/trace'
|
|
11
|
+
require_relative 'arcp/lease'
|
|
12
|
+
require_relative 'arcp/credential'
|
|
13
|
+
require_relative 'arcp/credential_provisioner'
|
|
14
|
+
require_relative 'arcp/session'
|
|
15
|
+
require_relative 'arcp/job'
|
|
16
|
+
require_relative 'arcp/auth'
|
|
17
|
+
require_relative 'arcp/transport'
|
|
18
|
+
require_relative 'arcp/client'
|
|
19
|
+
require_relative 'arcp/runtime'
|
data/sig/arcp/client.rbs
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Arcp
|
|
2
|
+
class Client
|
|
3
|
+
attr_reader session: Arcp::Session::Info
|
|
4
|
+
attr_reader transport: Arcp::Transport::Base
|
|
5
|
+
|
|
6
|
+
def self.open: (transport: Arcp::Transport::Base, auth: Hash[String, untyped], ?client_name: String, ?client_version: String, ?capabilities: Arcp::Session::CapabilitySet?, ?resume: Hash[String, untyped]?, ?clock: untyped) -> Client
|
|
7
|
+
|
|
8
|
+
def list_jobs: (?status: untyped, ?agent: String?, ?created_after: String?, ?limit: Integer?, ?cursor: String?) -> Enumerator::Lazy[Arcp::Job::Summary, untyped]
|
|
9
|
+
def submit_job: (agent: String, ?input: untyped, ?lease_request: Arcp::Lease::LeaseRequest?, ?lease_constraints: Arcp::Lease::LeaseConstraints?, ?idempotency_key: String?, ?max_runtime_sec: Integer?) -> Arcp::Job::Handle
|
|
10
|
+
def subscribe_job: (job_id: String, ?from_event_seq: Integer?, ?history: bool) -> Enumerator[Arcp::Job::Event, void]
|
|
11
|
+
def cancel_job: (job_id: String, ?reason: String?) -> Arcp::Envelope
|
|
12
|
+
def get_result: (job_id: String) -> Arcp::Job::Result
|
|
13
|
+
def ack: (Integer) -> void
|
|
14
|
+
def close: (?reason: String?) -> void
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
module Arcp
|
|
2
|
+
class Credential
|
|
3
|
+
SCHEME_BEARER: String
|
|
4
|
+
|
|
5
|
+
attr_reader id: String
|
|
6
|
+
attr_reader scheme: String
|
|
7
|
+
attr_reader value: String
|
|
8
|
+
attr_reader endpoint: String
|
|
9
|
+
attr_reader profile: String?
|
|
10
|
+
attr_reader constraints: Hash[String, untyped]
|
|
11
|
+
|
|
12
|
+
def self.from_h: (Hash[String | Symbol, untyped]) -> Credential
|
|
13
|
+
def to_h: () -> Hash[String, untyped]
|
|
14
|
+
def to_redacted_h: () -> Hash[String, untyped]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
module ModelPattern
|
|
18
|
+
def self.match?: (Array[String]?, String) -> bool
|
|
19
|
+
def self.implied_by?: (Array[String]?, String) -> bool
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
module CredentialProvisioner
|
|
23
|
+
def issue: (lease: Arcp::Lease::Lease?, job_id: String, agent: String, principal_id: String) -> Array[Credential]
|
|
24
|
+
def revoke: (credential_id: String) -> void
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
module Credentials
|
|
28
|
+
def self.translate_upstream_error: (StandardError) -> StandardError
|
|
29
|
+
def self.budget_exhausted?: (StandardError) -> bool
|
|
30
|
+
|
|
31
|
+
class InMemoryProvisioner
|
|
32
|
+
include CredentialProvisioner
|
|
33
|
+
|
|
34
|
+
attr_reader issued: Array[Hash[Symbol, untyped]]
|
|
35
|
+
attr_reader revoked: Array[String]
|
|
36
|
+
|
|
37
|
+
def initialize: (?endpoint: String, ?profile: String) -> void
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
class CredentialStore
|
|
41
|
+
def record: (job_id: String, credential_id: String) -> void
|
|
42
|
+
def forget: (job_id: String, credential_id: String) -> void
|
|
43
|
+
def outstanding: (job_id: String) -> Array[String]
|
|
44
|
+
def all_outstanding: () -> Hash[String, Array[String]]
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
class InMemoryStore < CredentialStore
|
|
48
|
+
def initialize: () -> void
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module Arcp
|
|
2
|
+
class Envelope
|
|
3
|
+
attr_reader arcp: String
|
|
4
|
+
attr_reader id: String
|
|
5
|
+
attr_reader type: String
|
|
6
|
+
attr_reader session_id: String
|
|
7
|
+
attr_reader trace_id: String?
|
|
8
|
+
attr_reader job_id: String?
|
|
9
|
+
attr_reader event_seq: Integer?
|
|
10
|
+
attr_reader payload: Hash[String, untyped]
|
|
11
|
+
|
|
12
|
+
def self.build: (type: String, session_id: String, payload: Hash[String | Symbol, untyped], ?trace_id: String?, ?job_id: String?, ?event_seq: Integer?, ?id: String?) -> Envelope
|
|
13
|
+
def self.from_h: (Hash[String | Symbol, untyped]) -> Envelope
|
|
14
|
+
def self.from_json: (String) -> Envelope
|
|
15
|
+
def to_h: () -> Hash[String, untyped]
|
|
16
|
+
def to_json: (*untyped) -> String
|
|
17
|
+
def known?: () -> bool
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
class UnknownEnvelope
|
|
21
|
+
attr_reader envelope: Envelope
|
|
22
|
+
def type: () -> String
|
|
23
|
+
def payload: () -> Hash[String, untyped]
|
|
24
|
+
end
|
|
25
|
+
end
|
data/sig/arcp/errors.rbs
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module Arcp
|
|
2
|
+
class Error < StandardError
|
|
3
|
+
CODE: String
|
|
4
|
+
attr_reader details: Hash[untyped, untyped]
|
|
5
|
+
def initialize: (?String?, ?details: Hash[untyped, untyped]) -> void
|
|
6
|
+
def code: () -> String
|
|
7
|
+
def retryable?: () -> bool
|
|
8
|
+
def to_payload: (?trace_id: String?) -> Hash[Symbol, untyped]
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
module Errors
|
|
12
|
+
class Cancelled < Arcp::Error end
|
|
13
|
+
class InvalidRequest < Arcp::Error end
|
|
14
|
+
class Unauthenticated < Arcp::Error end
|
|
15
|
+
class PermissionDenied < Arcp::Error end
|
|
16
|
+
class JobNotFound < Arcp::Error end
|
|
17
|
+
class AgentNotAvailable < Arcp::Error end
|
|
18
|
+
class DuplicateKey < Arcp::Error end
|
|
19
|
+
class RateLimited < Arcp::Error end
|
|
20
|
+
class Internal < Arcp::Error end
|
|
21
|
+
class HeartbeatLost < Arcp::Error end
|
|
22
|
+
class Backpressure < Arcp::Error end
|
|
23
|
+
class ProtocolViolation < Arcp::Error end
|
|
24
|
+
class Timeout < Arcp::Error end
|
|
25
|
+
class ResumeWindowExpired < Arcp::Error end
|
|
26
|
+
class LeaseSubsetViolation < Arcp::Error end
|
|
27
|
+
class AgentVersionNotAvailable < Arcp::Error end
|
|
28
|
+
class LeaseExpired < Arcp::Error end
|
|
29
|
+
class BudgetExhausted < Arcp::Error end
|
|
30
|
+
class UnnegotiatedFeature < Arcp::Error end
|
|
31
|
+
|
|
32
|
+
ALL: Array[singleton(Arcp::Error)]
|
|
33
|
+
WIRE_CODES: Array[String]
|
|
34
|
+
BY_CODE: Hash[String, singleton(Arcp::Error)]
|
|
35
|
+
RETRYABLE_BY_DEFAULT: Array[String]
|
|
36
|
+
NON_RETRYABLE_BY_DEFAULT: Array[String]
|
|
37
|
+
|
|
38
|
+
def self.for: (String, ?message: String?, ?details: Hash[untyped, untyped]) -> Arcp::Error
|
|
39
|
+
end
|
|
40
|
+
end
|
data/sig/arcp/job.rbs
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
module Arcp
|
|
2
|
+
module Job
|
|
3
|
+
module EventKind
|
|
4
|
+
PROGRESS: String
|
|
5
|
+
RESULT_CHUNK: String
|
|
6
|
+
LOG: String
|
|
7
|
+
THOUGHT: String
|
|
8
|
+
TOOL_CALL: String
|
|
9
|
+
TOOL_RESULT: String
|
|
10
|
+
STATUS: String
|
|
11
|
+
METRIC: String
|
|
12
|
+
TRACE_SPAN: String
|
|
13
|
+
DELEGATE: String
|
|
14
|
+
ALL: Array[String]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
class AgentRef
|
|
18
|
+
attr_reader name: String
|
|
19
|
+
attr_reader version: String?
|
|
20
|
+
def self.parse: (String?) -> AgentRef?
|
|
21
|
+
def to_s: () -> String
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
class Event
|
|
25
|
+
attr_reader kind: String
|
|
26
|
+
attr_reader body: untyped
|
|
27
|
+
def self.from_h: (Hash[String | Symbol, untyped]) -> Event
|
|
28
|
+
def to_h: () -> Hash[String, untyped]
|
|
29
|
+
def known?: () -> bool
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
class Handle
|
|
33
|
+
attr_reader job_id: String
|
|
34
|
+
attr_reader agent: String
|
|
35
|
+
attr_reader submitted_at: String?
|
|
36
|
+
attr_reader lease: Arcp::Lease::Lease?
|
|
37
|
+
attr_reader credentials: Array[Arcp::Credential]?
|
|
38
|
+
def subscribe: (client: Arcp::Client, **untyped) -> Enumerator[Event, void]
|
|
39
|
+
def cancel: (client: Arcp::Client, ?reason: String?) -> Envelope
|
|
40
|
+
def get_result: (client: Arcp::Client) -> Result
|
|
41
|
+
def credential_for: (endpoint: String) -> Arcp::Credential?
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
class Accepted
|
|
45
|
+
attr_reader job_id: String
|
|
46
|
+
attr_reader agent: String
|
|
47
|
+
attr_reader accepted_at: String?
|
|
48
|
+
attr_reader lease: Arcp::Lease::Lease?
|
|
49
|
+
attr_reader credentials: Array[Arcp::Credential]?
|
|
50
|
+
def self.from_h: (Hash[String | Symbol, untyped]) -> Accepted
|
|
51
|
+
def to_h: () -> Hash[String, untyped]
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
class Summary
|
|
55
|
+
attr_reader job_id: String
|
|
56
|
+
attr_reader agent: String
|
|
57
|
+
attr_reader status: String
|
|
58
|
+
attr_reader created_at: String?
|
|
59
|
+
attr_reader lease_expires_at: String?
|
|
60
|
+
attr_reader budget_remaining: Hash[String, String]?
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
class Result
|
|
64
|
+
attr_reader job_id: String
|
|
65
|
+
attr_reader final_status: String
|
|
66
|
+
attr_reader result: untyped
|
|
67
|
+
attr_reader result_id: String?
|
|
68
|
+
attr_reader result_size: Integer?
|
|
69
|
+
attr_reader completed_at: String?
|
|
70
|
+
def chunked?: () -> bool
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
class JobError
|
|
74
|
+
attr_reader job_id: String
|
|
75
|
+
attr_reader final_status: String
|
|
76
|
+
attr_reader code: String
|
|
77
|
+
attr_reader message: String?
|
|
78
|
+
attr_reader retryable: bool
|
|
79
|
+
attr_reader details: Hash[String, untyped]
|
|
80
|
+
def to_exception: () -> Arcp::Error
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
data/sig/arcp/lease.rbs
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module Arcp
|
|
2
|
+
module Lease
|
|
3
|
+
class LeaseConstraints
|
|
4
|
+
attr_reader expires_at: String?
|
|
5
|
+
attr_reader max_budget: Hash[String, untyped]?
|
|
6
|
+
def self.from_h: (Hash[String | Symbol, untyped]?) -> LeaseConstraints?
|
|
7
|
+
def to_h: () -> Hash[String, untyped]
|
|
8
|
+
def validate!: () -> void
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class CostBudget
|
|
12
|
+
attr_reader per_currency: Hash[String, BigDecimal]
|
|
13
|
+
def self.parse: (Array[String]) -> CostBudget
|
|
14
|
+
def to_a: () -> Array[String]
|
|
15
|
+
def to_h: () -> Hash[String, untyped]
|
|
16
|
+
def remaining: (String) -> BigDecimal
|
|
17
|
+
def currencies: () -> Array[String]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
class LeaseRequest
|
|
21
|
+
attr_reader capabilities: Array[String]
|
|
22
|
+
attr_reader budget: CostBudget?
|
|
23
|
+
attr_reader model_use: Array[String]?
|
|
24
|
+
attr_reader expires_at: String?
|
|
25
|
+
def self.from_h: (Hash[String | Symbol, untyped]?) -> LeaseRequest?
|
|
26
|
+
def to_h: () -> Hash[String, untyped]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
class Lease
|
|
30
|
+
attr_reader id: String
|
|
31
|
+
attr_reader capabilities: Array[String]
|
|
32
|
+
attr_reader budget: CostBudget?
|
|
33
|
+
attr_reader model_use: Array[String]?
|
|
34
|
+
attr_reader expires_at: String?
|
|
35
|
+
attr_reader issued_at: String
|
|
36
|
+
def self.from_h: (Hash[String | Symbol, untyped]) -> Lease
|
|
37
|
+
def to_h: () -> Hash[String, untyped]
|
|
38
|
+
def expired?: (Time) -> bool
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module Arcp
|
|
2
|
+
module Runtime
|
|
3
|
+
class Runtime
|
|
4
|
+
attr_reader auth_verifier: untyped
|
|
5
|
+
attr_reader name: String
|
|
6
|
+
attr_reader version: String
|
|
7
|
+
attr_reader heartbeat_interval_sec: Integer?
|
|
8
|
+
attr_reader resume_window_sec: Integer
|
|
9
|
+
attr_reader clock: untyped
|
|
10
|
+
attr_reader job_manager: JobManager
|
|
11
|
+
attr_reader lease_manager: LeaseManager
|
|
12
|
+
attr_reader subscription_manager: SubscriptionManager
|
|
13
|
+
attr_reader event_log: EventLog
|
|
14
|
+
attr_reader credential_registry: CredentialRegistry?
|
|
15
|
+
attr_reader enforce_model_use: bool
|
|
16
|
+
|
|
17
|
+
def initialize: (auth_verifier: untyped, ?name: String, ?version: String, ?heartbeat_interval_sec: Integer?, ?resume_window_sec: Integer, ?clock: untyped, ?credential_provisioner: Arcp::CredentialProvisioner?, ?credential_store: Arcp::Credentials::CredentialStore?, ?require_durable_store: bool, ?enforce_model_use: bool) -> void
|
|
18
|
+
def register_agent: (name: String, versions: Array[String], default: String, handler: ^(JobContext) -> void) -> void
|
|
19
|
+
def local_capabilities: (?agents_inventory: bool) -> Arcp::Session::CapabilitySet
|
|
20
|
+
def accept: (Arcp::Transport::Base) -> untyped
|
|
21
|
+
def shutdown: (?reason: String?) -> void
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
class JobManager end
|
|
25
|
+
class LeaseManager
|
|
26
|
+
def check_model!: (String, model_id: String) -> bool
|
|
27
|
+
end
|
|
28
|
+
class CredentialRegistry
|
|
29
|
+
def issue_for: (job_id: String, lease: Arcp::Lease::Lease?, agent: String, principal_id: String) -> Array[Arcp::Credential]
|
|
30
|
+
def rotate: (job_id: String, credential_id: String, new_value: String) -> String
|
|
31
|
+
def revoke_all: (job_id: String) -> Integer
|
|
32
|
+
def reconcile_on_startup!: () -> void
|
|
33
|
+
end
|
|
34
|
+
class SubscriptionManager end
|
|
35
|
+
class EventLog end
|
|
36
|
+
class JobContext
|
|
37
|
+
def rotate_credential: (id: String, new_value: String) -> untyped
|
|
38
|
+
end
|
|
39
|
+
class SessionActor end
|
|
40
|
+
end
|
|
41
|
+
end
|