voiceml 0.8.1 β 0.9.2
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/README.md +13 -6
- data/lib/voiceml/client.rb +29 -2
- data/lib/voiceml/hosts.rb +62 -0
- data/lib/voiceml/models/accounts.rb +54 -0
- data/lib/voiceml/models/assistants_v1.rb +239 -0
- data/lib/voiceml/models/conversations_v1.rb +610 -0
- data/lib/voiceml/models/media.rb +48 -0
- data/lib/voiceml/models/messaging_v1.rb +40 -0
- data/lib/voiceml/models/notifications.rb +39 -0
- data/lib/voiceml/models/outgoing_caller_ids.rb +70 -0
- data/lib/voiceml/models/pricing.rb +231 -0
- data/lib/voiceml/models/routes_v2.rb +14 -0
- data/lib/voiceml/models/sip.rb +22 -0
- data/lib/voiceml/models/user_defined_messages.rb +31 -0
- data/lib/voiceml/models/voice_v1.rb +152 -0
- data/lib/voiceml/resources/assistants_v1.rb +508 -0
- data/lib/voiceml/resources/conversations_v1.rb +1175 -0
- data/lib/voiceml/resources/messaging_v1.rb +87 -0
- data/lib/voiceml/resources/pricing.rb +140 -0
- data/lib/voiceml/resources/routes_v2.rb +22 -2
- data/lib/voiceml/resources/voice_v1.rb +250 -0
- data/lib/voiceml/transport.rb +44 -4
- data/lib/voiceml/version.rb +1 -1
- data/lib/voiceml.rb +11 -0
- metadata +18 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ce6f40c38ff553e748881a1b57f940e977cd24983da928988a7dcc77640cc32d
|
|
4
|
+
data.tar.gz: d6d26a2ab6ee10d9df572f24c6b667cb87cb03bb68ef40234fb05308db3d3789
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 28fe625cbe02ccd47894507e8c28d8eecd06f0caae4aea040f5e21af82980072e39a74aa7cb788fc885f9b24e58239099a87dac639a79b9f3a3c248769e0a652
|
|
7
|
+
data.tar.gz: 85fd838a671b848768a791d590fbcdefa40c49e89d80b8f2c2c98f475af7035489a727ca3d1ecd7e5988296a5a62f32e3784344fc9fcc11f24beec16d5d9619e
|
data/README.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# π VoiceML Ruby SDK
|
|
2
2
|
|
|
3
|
-
The official Ruby client for the [VoiceML REST API](https://voicetel.com/docs/api/v0.
|
|
3
|
+
The official Ruby client for the [VoiceML REST API](https://voicetel.com/docs/api/v0.9/voiceml/) β Twilio-compatible outbound voice and answering-machine-detection from VoiceTel, with idiomatic snake_case kwargs, structured errors, and a Twilio-compatible wire format.
|
|
4
4
|
|
|
5
|
-

|
|
6
6
|

|
|
7
7
|

|
|
8
|
-

|
|
9
9
|

|
|
10
10
|
|
|
11
11
|
## π Table of Contents
|
|
@@ -49,10 +49,15 @@ The official Ruby client for the [VoiceML REST API](https://voicetel.com/docs/ap
|
|
|
49
49
|
- **Notifications** β fetch, list.
|
|
50
50
|
- **SIP** β SIP Trunking: Domains (CRUD), CredentialLists + Credentials (CRUD), IpAccessControlLists + IpAddresses (CRUD), DomainβACL/CredentialList mappings (historical, Auth/Calls, Auth/Registrations namespaces).
|
|
51
51
|
- **Routes V2** β Twilio Inbound Processing Region API: `client.routes_v2.sip_domains.fetch(name)` / `update(name, voice_region:, friendly_name:)`.
|
|
52
|
+
- **Messaging Service** β `client.messaging_v1.services` CRUD (`MG...` services), routed automatically at the `messaging.voicetel.com` product host.
|
|
53
|
+
- **Pricing** β read-only `client.pricing.v1` / `client.pricing.v2` for Voice, Messaging, PhoneNumbers, and Trunking country + number lookups.
|
|
52
54
|
- **Diagnostics** β `/health` deep probe, OpenAPI spec.
|
|
53
55
|
|
|
56
|
+
### π Per-product hosts
|
|
57
|
+
VoiceML mirrors Twilio's product-per-subdomain model. The whole `conversations_v1` group is routed to `conversations.voicetel.com` and `messaging_v1` to `messaging.voicetel.com`, while everything else stays on the default `voiceml.voicetel.com`. These hosts are derived automatically from `base_url`; a non-`voicetel.com` base (e.g. a self-hosted instance) keeps every product on that single host. Override per product with `messaging_base_url:` / `conversations_base_url:` on the client constructor.
|
|
58
|
+
|
|
54
59
|
### π§ͺ Tested
|
|
55
|
-
- **
|
|
60
|
+
- **188 examples** with mocked HTTP layer (`webmock`) covering every resource and pagination edge cases β spec drift gets caught at parse time.
|
|
56
61
|
- Integration smoke spec gated by env vars β safe for CI.
|
|
57
62
|
|
|
58
63
|
### π¦ Clean Distribution
|
|
@@ -110,7 +115,7 @@ client = VoiceML::Client.new(account_sid: 'AC...', api_key: '...')
|
|
|
110
115
|
client.diagnostics.health # uses your AccountSid + key on every call
|
|
111
116
|
```
|
|
112
117
|
|
|
113
|
-
> Don't have credentials yet? See **[voicetel.com/docs/api/v0.
|
|
118
|
+
> Don't have credentials yet? See **[voicetel.com/docs/api/v0.9/voiceml/](https://voicetel.com/docs/api/v0.9/voiceml/)** for issuance and rotation.
|
|
114
119
|
|
|
115
120
|
## πΊοΈ Resource Reference
|
|
116
121
|
|
|
@@ -124,6 +129,8 @@ client.diagnostics.health # uses your AccountSid + key on every call
|
|
|
124
129
|
| `client.messages` | create, fetch, list, update, delete | To/From/DateSent filters; Body redaction; Status=canceled |
|
|
125
130
|
| `client.incoming_phone_numbers` | list, fetch, update | |
|
|
126
131
|
| `client.notifications` | fetch, list | |
|
|
132
|
+
| `client.messaging_v1.services` | create, list, fetch, update, delete | Messaging Service (`MG...`); routed at `messaging.voicetel.com` |
|
|
133
|
+
| `client.pricing.v1` / `.v2` | countries.list / fetch, numbers.fetch | Voice, Messaging, PhoneNumbers, Trunking (read-only, default host) |
|
|
127
134
|
| `client.diagnostics` | `/health`, OpenAPI spec | |
|
|
128
135
|
|
|
129
136
|
Methods accept idiomatic snake_case keyword arguments β they're translated to Twilio's PascalCase wire field names internally:
|
|
@@ -245,7 +252,7 @@ gem build voiceml.gemspec
|
|
|
245
252
|
|
|
246
253
|
## π API Documentation
|
|
247
254
|
|
|
248
|
-
- **Reference docs:** [voicetel.com/docs/api/v0.
|
|
255
|
+
- **Reference docs:** [voicetel.com/docs/api/v0.9/voiceml/](https://voicetel.com/docs/api/v0.9/voiceml/)
|
|
249
256
|
- **Validator:** [voicetel.com/voiceml/validator/](https://voicetel.com/voiceml/validator/)
|
|
250
257
|
- **SDK catalogue:** [voicetel.com/docs/voiceml-sdks/](https://voicetel.com/docs/voiceml-sdks/)
|
|
251
258
|
- **YARD comments:** every resource method carries `@param` / `@return` docs β `yard doc lib` builds them locally.
|
data/lib/voiceml/client.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require_relative 'transport'
|
|
4
|
+
require_relative 'hosts'
|
|
4
5
|
require_relative 'resources/calls'
|
|
5
6
|
require_relative 'resources/conferences'
|
|
6
7
|
require_relative 'resources/queues'
|
|
@@ -12,6 +13,11 @@ require_relative 'resources/diagnostics'
|
|
|
12
13
|
require_relative 'resources/messages'
|
|
13
14
|
require_relative 'resources/sip'
|
|
14
15
|
require_relative 'resources/routes_v2'
|
|
16
|
+
require_relative 'resources/voice_v1'
|
|
17
|
+
require_relative 'resources/conversations_v1'
|
|
18
|
+
require_relative 'resources/assistants_v1'
|
|
19
|
+
require_relative 'resources/messaging_v1'
|
|
20
|
+
require_relative 'resources/pricing'
|
|
15
21
|
|
|
16
22
|
module VoiceML
|
|
17
23
|
# Synchronous client for the VoiceML REST API.
|
|
@@ -31,7 +37,8 @@ module VoiceML
|
|
|
31
37
|
class Client
|
|
32
38
|
attr_reader :calls, :conferences, :queues, :applications, :recordings,
|
|
33
39
|
:incoming_phone_numbers, :notifications, :diagnostics, :messages,
|
|
34
|
-
:sip, :routes_v2
|
|
40
|
+
:sip, :routes_v2, :voice_v1, :conversations_v1, :assistants_v1,
|
|
41
|
+
:messaging_v1, :pricing
|
|
35
42
|
|
|
36
43
|
# @param account_sid [String] Twilio-format AccountSid (`AC` + 32 hex).
|
|
37
44
|
# @param api_key [String, nil] per-tenant API key. Pass either `api_key:` or the
|
|
@@ -43,11 +50,16 @@ module VoiceML
|
|
|
43
50
|
# @param max_retries [Integer] retry attempts for 429/5xx and transport errors. Defaults to 2.
|
|
44
51
|
# @param user_agent [String, nil] override the `User-Agent` header. Defaults to
|
|
45
52
|
# `"voiceml-ruby/#{VERSION}"`.
|
|
53
|
+
# @param messaging_base_url [String, nil] override the host for `messaging_v1`. Defaults to
|
|
54
|
+
# the `messaging.*.voicetel.com` subdomain derived from `base_url` (else `base_url` itself).
|
|
55
|
+
# @param conversations_base_url [String, nil] override the host for `conversations_v1`. Defaults
|
|
56
|
+
# to the `conversations.*.voicetel.com` subdomain derived from `base_url` (else `base_url`).
|
|
46
57
|
def initialize(account_sid:, api_key: nil, auth_token: nil,
|
|
47
58
|
base_url: Transport::DEFAULT_BASE_URL,
|
|
48
59
|
timeout: Transport::DEFAULT_TIMEOUT,
|
|
49
60
|
max_retries: Transport::DEFAULT_MAX_RETRIES,
|
|
50
|
-
user_agent: nil, http_client: nil
|
|
61
|
+
user_agent: nil, http_client: nil,
|
|
62
|
+
messaging_base_url: nil, conversations_base_url: nil)
|
|
51
63
|
if !api_key.nil? && !auth_token.nil?
|
|
52
64
|
raise ArgumentError, 'pass either api_key: or auth_token:, not both'
|
|
53
65
|
end
|
|
@@ -64,6 +76,16 @@ module VoiceML
|
|
|
64
76
|
http_client: http_client
|
|
65
77
|
)
|
|
66
78
|
|
|
79
|
+
# VoiceML mirrors Twilio's product-per-subdomain model: the whole Conversations group
|
|
80
|
+
# rides `conversations.voicetel.com` and Messaging Service rides `messaging.voicetel.com`,
|
|
81
|
+
# while everything else stays on the default host. See VoiceML::Hosts.
|
|
82
|
+
_default, messaging_host, conversations_host =
|
|
83
|
+
Hosts.resolve_product_base_urls(base_url,
|
|
84
|
+
messaging_base_url: messaging_base_url,
|
|
85
|
+
conversations_base_url: conversations_base_url)
|
|
86
|
+
messaging_transport = ScopedTransport.new(@transport, messaging_host)
|
|
87
|
+
conversations_transport = ScopedTransport.new(@transport, conversations_host)
|
|
88
|
+
|
|
67
89
|
@calls = CallsResource.new(@transport)
|
|
68
90
|
@conferences = ConferencesResource.new(@transport)
|
|
69
91
|
@queues = QueuesResource.new(@transport)
|
|
@@ -75,6 +97,11 @@ module VoiceML
|
|
|
75
97
|
@messages = MessagesResource.new(@transport)
|
|
76
98
|
@sip = SipResource.new(@transport)
|
|
77
99
|
@routes_v2 = RoutesV2Resource.new(@transport)
|
|
100
|
+
@voice_v1 = VoiceV1Resource.new(@transport)
|
|
101
|
+
@conversations_v1 = ConversationsV1Resource.new(conversations_transport)
|
|
102
|
+
@assistants_v1 = AssistantsV1Resource.new(@transport)
|
|
103
|
+
@messaging_v1 = MessagingV1Resource.new(messaging_transport)
|
|
104
|
+
@pricing = PricingResource.new(@transport)
|
|
78
105
|
end
|
|
79
106
|
|
|
80
107
|
def account_sid
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'uri'
|
|
4
|
+
|
|
5
|
+
require_relative 'transport'
|
|
6
|
+
|
|
7
|
+
module VoiceML
|
|
8
|
+
# Per-product host resolution for the VoiceML API.
|
|
9
|
+
#
|
|
10
|
+
# Twilio splits its products across dedicated subdomains (`api.twilio.com`,
|
|
11
|
+
# `conversations.twilio.com`, `messaging.twilio.com`, ...). VoiceML mirrors that
|
|
12
|
+
# shape on `voicetel.com`: the Conversations product answers on
|
|
13
|
+
# `conversations.voicetel.com` and the Messaging Service product on
|
|
14
|
+
# `messaging.voicetel.com`, while everything else stays on the default
|
|
15
|
+
# `voiceml.voicetel.com` host. Conversation Service and Messaging Service share
|
|
16
|
+
# the identical `/v1/Services` path shape, so the *host* is what disambiguates
|
|
17
|
+
# them on the wire.
|
|
18
|
+
#
|
|
19
|
+
# Given the configured `base_url` this module derives the two product hosts by
|
|
20
|
+
# swapping the leftmost `voiceml` label β but only for recognised
|
|
21
|
+
# `*.voicetel.com` hosts. For any other base URL (a self-hosted callBroadcast
|
|
22
|
+
# instance, a test stub, a regional override) the product hosts fall back to the
|
|
23
|
+
# configured host unchanged, so a single-host deployment keeps working. A caller
|
|
24
|
+
# who needs Messaging Service against a custom host points `messaging_base_url`
|
|
25
|
+
# (or `conversations_base_url`) at their own subdomain explicitly.
|
|
26
|
+
module Hosts
|
|
27
|
+
module_function
|
|
28
|
+
|
|
29
|
+
# Swap the `voiceml` label of a `*.voicetel.com` host for `product`.
|
|
30
|
+
#
|
|
31
|
+
# Returns `base_url` unchanged when the host is not a `voiceml.*.voicetel.com`
|
|
32
|
+
# style host (e.g. a self-hosted instance), so single-host deployments keep
|
|
33
|
+
# working without special-casing.
|
|
34
|
+
def derive_product_host(base_url, product)
|
|
35
|
+
uri = URI.parse(base_url)
|
|
36
|
+
host = uri.host
|
|
37
|
+
return base_url if host.nil? || !host.end_with?('.voicetel.com')
|
|
38
|
+
|
|
39
|
+
labels = host.split('.')
|
|
40
|
+
idx = labels.index('voiceml')
|
|
41
|
+
return base_url if idx.nil?
|
|
42
|
+
|
|
43
|
+
labels[idx] = product
|
|
44
|
+
uri.host = labels.join('.')
|
|
45
|
+
uri.query = nil
|
|
46
|
+
uri.fragment = nil
|
|
47
|
+
uri.to_s
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Return `[default, messaging, conversations]` base URLs.
|
|
51
|
+
#
|
|
52
|
+
# Explicit overrides win; otherwise each product host is derived from
|
|
53
|
+
# `base_url` (see module docstring). All three are returned without a
|
|
54
|
+
# trailing slash.
|
|
55
|
+
def resolve_product_base_urls(base_url, messaging_base_url: nil, conversations_base_url: nil)
|
|
56
|
+
default = Transport.strip_trailing_slashes(base_url)
|
|
57
|
+
messaging = Transport.strip_trailing_slashes(messaging_base_url || derive_product_host(default, 'messaging'))
|
|
58
|
+
conversations = Transport.strip_trailing_slashes(conversations_base_url || derive_product_host(default, 'conversations'))
|
|
59
|
+
[default, messaging, conversations]
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'common'
|
|
4
|
+
|
|
5
|
+
module VoiceML
|
|
6
|
+
# Twilio-compatible Account resource. The voiceml SDK is single-account
|
|
7
|
+
# (the credential's account is implicit on every call), so this model
|
|
8
|
+
# exists primarily to decode `GET/POST /Accounts/{Sid}.json` responses
|
|
9
|
+
# round-trip with the Twilio shape β useful for migration tooling that
|
|
10
|
+
# echoes the account record back to the caller.
|
|
11
|
+
class Account
|
|
12
|
+
ATTRIBUTES = %w[
|
|
13
|
+
sid friendly_name status type auth_token owner_account_sid
|
|
14
|
+
date_created date_updated subresource_uris uri
|
|
15
|
+
].freeze
|
|
16
|
+
|
|
17
|
+
attr_reader(*ATTRIBUTES.map(&:to_sym))
|
|
18
|
+
|
|
19
|
+
def initialize(attrs = {})
|
|
20
|
+
ATTRIBUTES.each do |field|
|
|
21
|
+
value = attrs.key?(field) ? attrs[field] : attrs[field.to_sym]
|
|
22
|
+
instance_variable_set("@#{field}", value)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.from_hash(hash)
|
|
27
|
+
return nil if hash.nil?
|
|
28
|
+
|
|
29
|
+
new(hash)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# `GET /Accounts/{Sid}/Balance.json` β running balance for the account in
|
|
34
|
+
# the account's settlement currency. No `sid` field on the wire (the
|
|
35
|
+
# balance is account-scoped, not its own resource).
|
|
36
|
+
class Balance
|
|
37
|
+
ATTRIBUTES = %w[account_sid balance currency].freeze
|
|
38
|
+
|
|
39
|
+
attr_reader(*ATTRIBUTES.map(&:to_sym))
|
|
40
|
+
|
|
41
|
+
def initialize(attrs = {})
|
|
42
|
+
ATTRIBUTES.each do |field|
|
|
43
|
+
value = attrs.key?(field) ? attrs[field] : attrs[field.to_sym]
|
|
44
|
+
instance_variable_set("@#{field}", value)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def self.from_hash(hash)
|
|
49
|
+
return nil if hash.nil?
|
|
50
|
+
|
|
51
|
+
new(hash)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'common'
|
|
4
|
+
require_relative 'voice_v1' # V1Pageable lives here; Assistants v1 reuses the same `meta` envelope
|
|
5
|
+
|
|
6
|
+
module VoiceML
|
|
7
|
+
# Assistants v1 (`/v1/Assistants`, `/v1/Tools`, `/v1/Knowledge`, `/v1/Sessions`,
|
|
8
|
+
# `/v1/Policies`) β Twilio AI-Assistants surface. Same /v1 conventions as Voice v1
|
|
9
|
+
# and Conversations v1: Basic-auth account resolution, ISO-8601 dates, `meta`
|
|
10
|
+
# list envelope (V1Pageable). 7 families for v0.9.1:
|
|
11
|
+
# - Assistant (aia_asst_...)
|
|
12
|
+
# - Tool (aia_tool_...) + ToolWithPolicies fetch shape
|
|
13
|
+
# - Knowledge (aia_know_...) + KnowledgeStatus + KnowledgeChunk
|
|
14
|
+
# - Session
|
|
15
|
+
# - Message (aia_msg_...) + SendMessageResponse
|
|
16
|
+
# - Feedback (aia_fdbk_...)
|
|
17
|
+
# - Policy (aia_plcy_...)
|
|
18
|
+
|
|
19
|
+
# AssistantsV1Assistant β `aia_asst_...`. Used by list/create/update/delete responses.
|
|
20
|
+
class AssistantsV1Assistant
|
|
21
|
+
ATTRIBUTES = %w[
|
|
22
|
+
account_sid customer_ai id model name owner url personality_prompt
|
|
23
|
+
date_created date_updated
|
|
24
|
+
].freeze
|
|
25
|
+
attr_reader(*ATTRIBUTES.map(&:to_sym))
|
|
26
|
+
def initialize(attrs = {})
|
|
27
|
+
ATTRIBUTES.each { |f| instance_variable_set("@#{f}", attrs.key?(f) ? attrs[f] : attrs[f.to_sym]) }
|
|
28
|
+
end
|
|
29
|
+
def self.from_hash(h); h.nil? ? nil : new(h); end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
class AssistantsV1AssistantList
|
|
33
|
+
include V1Pageable
|
|
34
|
+
attr_reader :assistants
|
|
35
|
+
def initialize(hash = {})
|
|
36
|
+
assign_meta_fields(hash)
|
|
37
|
+
@assistants = (hash['assistants'] || []).map { |h| AssistantsV1Assistant.from_hash(h) }
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# AssistantsV1AssistantWithToolsAndKnowledge β fetch-one shape that includes the
|
|
42
|
+
# attached tools and knowledge arrays inline.
|
|
43
|
+
class AssistantsV1AssistantWithToolsAndKnowledge
|
|
44
|
+
ATTRIBUTES = %w[
|
|
45
|
+
account_sid customer_ai id model name owner url personality_prompt
|
|
46
|
+
date_created date_updated tools knowledge
|
|
47
|
+
].freeze
|
|
48
|
+
attr_reader(*ATTRIBUTES.map(&:to_sym))
|
|
49
|
+
def initialize(attrs = {})
|
|
50
|
+
ATTRIBUTES.each { |f| instance_variable_set("@#{f}", attrs.key?(f) ? attrs[f] : attrs[f.to_sym]) }
|
|
51
|
+
end
|
|
52
|
+
def self.from_hash(h); h.nil? ? nil : new(h); end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# AssistantsV1Tool β `aia_tool_...`.
|
|
56
|
+
class AssistantsV1Tool
|
|
57
|
+
ATTRIBUTES = %w[
|
|
58
|
+
account_sid description enabled id meta name requires_auth type url
|
|
59
|
+
date_created date_updated
|
|
60
|
+
].freeze
|
|
61
|
+
attr_reader(*ATTRIBUTES.map(&:to_sym))
|
|
62
|
+
def initialize(attrs = {})
|
|
63
|
+
ATTRIBUTES.each { |f| instance_variable_set("@#{f}", attrs.key?(f) ? attrs[f] : attrs[f.to_sym]) }
|
|
64
|
+
end
|
|
65
|
+
def self.from_hash(h); h.nil? ? nil : new(h); end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
class AssistantsV1ToolList
|
|
69
|
+
include V1Pageable
|
|
70
|
+
attr_reader :tools
|
|
71
|
+
def initialize(hash = {})
|
|
72
|
+
assign_meta_fields(hash)
|
|
73
|
+
@tools = (hash['tools'] || []).map { |h| AssistantsV1Tool.from_hash(h) }
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# AssistantsV1ToolWithPolicies β fetch-one shape that includes the policies array inline.
|
|
78
|
+
class AssistantsV1ToolWithPolicies
|
|
79
|
+
ATTRIBUTES = %w[
|
|
80
|
+
account_sid description enabled id meta name requires_auth type url
|
|
81
|
+
date_created date_updated policies
|
|
82
|
+
].freeze
|
|
83
|
+
attr_reader(*ATTRIBUTES.map(&:to_sym))
|
|
84
|
+
def initialize(attrs = {})
|
|
85
|
+
ATTRIBUTES.each { |f| instance_variable_set("@#{f}", attrs.key?(f) ? attrs[f] : attrs[f.to_sym]) }
|
|
86
|
+
end
|
|
87
|
+
def self.from_hash(h); h.nil? ? nil : new(h); end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# AssistantsV1Knowledge β `aia_know_...`.
|
|
91
|
+
class AssistantsV1Knowledge
|
|
92
|
+
ATTRIBUTES = %w[
|
|
93
|
+
account_sid description id knowledge_source_details name status type url
|
|
94
|
+
embedding_model date_created date_updated
|
|
95
|
+
].freeze
|
|
96
|
+
attr_reader(*ATTRIBUTES.map(&:to_sym))
|
|
97
|
+
def initialize(attrs = {})
|
|
98
|
+
ATTRIBUTES.each { |f| instance_variable_set("@#{f}", attrs.key?(f) ? attrs[f] : attrs[f.to_sym]) }
|
|
99
|
+
end
|
|
100
|
+
def self.from_hash(h); h.nil? ? nil : new(h); end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
class AssistantsV1KnowledgeList
|
|
104
|
+
include V1Pageable
|
|
105
|
+
attr_reader :knowledge
|
|
106
|
+
def initialize(hash = {})
|
|
107
|
+
assign_meta_fields(hash)
|
|
108
|
+
@knowledge = (hash['knowledge'] || []).map { |h| AssistantsV1Knowledge.from_hash(h) }
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# AssistantsV1KnowledgeStatus β read-only ingestion status snapshot.
|
|
113
|
+
class AssistantsV1KnowledgeStatus
|
|
114
|
+
ATTRIBUTES = %w[account_sid status last_status date_updated].freeze
|
|
115
|
+
attr_reader(*ATTRIBUTES.map(&:to_sym))
|
|
116
|
+
def initialize(attrs = {})
|
|
117
|
+
ATTRIBUTES.each { |f| instance_variable_set("@#{f}", attrs.key?(f) ? attrs[f] : attrs[f.to_sym]) }
|
|
118
|
+
end
|
|
119
|
+
def self.from_hash(h); h.nil? ? nil : new(h); end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# AssistantsV1KnowledgeChunk β single retrieved chunk of indexed Knowledge content.
|
|
123
|
+
class AssistantsV1KnowledgeChunk
|
|
124
|
+
ATTRIBUTES = %w[account_sid content metadata date_created date_updated].freeze
|
|
125
|
+
attr_reader(*ATTRIBUTES.map(&:to_sym))
|
|
126
|
+
def initialize(attrs = {})
|
|
127
|
+
ATTRIBUTES.each { |f| instance_variable_set("@#{f}", attrs.key?(f) ? attrs[f] : attrs[f.to_sym]) }
|
|
128
|
+
end
|
|
129
|
+
def self.from_hash(h); h.nil? ? nil : new(h); end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
class AssistantsV1KnowledgeChunkList
|
|
133
|
+
include V1Pageable
|
|
134
|
+
attr_reader :chunks
|
|
135
|
+
def initialize(hash = {})
|
|
136
|
+
assign_meta_fields(hash)
|
|
137
|
+
@chunks = (hash['chunks'] || []).map { |h| AssistantsV1KnowledgeChunk.from_hash(h) }
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# AssistantsV1Session β a chat session between an identity and an Assistant.
|
|
142
|
+
class AssistantsV1Session
|
|
143
|
+
ATTRIBUTES = %w[
|
|
144
|
+
id account_sid assistant_id verified identity date_created date_updated
|
|
145
|
+
].freeze
|
|
146
|
+
attr_reader(*ATTRIBUTES.map(&:to_sym))
|
|
147
|
+
def initialize(attrs = {})
|
|
148
|
+
ATTRIBUTES.each { |f| instance_variable_set("@#{f}", attrs.key?(f) ? attrs[f] : attrs[f.to_sym]) }
|
|
149
|
+
end
|
|
150
|
+
def self.from_hash(h); h.nil? ? nil : new(h); end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
class AssistantsV1SessionList
|
|
154
|
+
include V1Pageable
|
|
155
|
+
attr_reader :sessions
|
|
156
|
+
def initialize(hash = {})
|
|
157
|
+
assign_meta_fields(hash)
|
|
158
|
+
@sessions = (hash['sessions'] || []).map { |h| AssistantsV1Session.from_hash(h) }
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# AssistantsV1Message β `aia_msg_...`. One message in an Assistant session.
|
|
163
|
+
class AssistantsV1Message
|
|
164
|
+
ATTRIBUTES = %w[
|
|
165
|
+
id account_sid assistant_id session_id identity role content meta
|
|
166
|
+
date_created date_updated
|
|
167
|
+
].freeze
|
|
168
|
+
attr_reader(*ATTRIBUTES.map(&:to_sym))
|
|
169
|
+
def initialize(attrs = {})
|
|
170
|
+
ATTRIBUTES.each { |f| instance_variable_set("@#{f}", attrs.key?(f) ? attrs[f] : attrs[f.to_sym]) }
|
|
171
|
+
end
|
|
172
|
+
def self.from_hash(h); h.nil? ? nil : new(h); end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
class AssistantsV1MessageList
|
|
176
|
+
include V1Pageable
|
|
177
|
+
attr_reader :messages
|
|
178
|
+
def initialize(hash = {})
|
|
179
|
+
assign_meta_fields(hash)
|
|
180
|
+
@messages = (hash['messages'] || []).map { |h| AssistantsV1Message.from_hash(h) }
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
# AssistantsV1SendMessageResponse β POST /v1/Assistants/{id}/Messages return shape.
|
|
185
|
+
# Distinct from AssistantsV1Message: carries the model's reply body + flag/abort signals.
|
|
186
|
+
class AssistantsV1SendMessageResponse
|
|
187
|
+
ATTRIBUTES = %w[status flagged aborted session_id account_sid body error].freeze
|
|
188
|
+
attr_reader(*ATTRIBUTES.map(&:to_sym))
|
|
189
|
+
def initialize(attrs = {})
|
|
190
|
+
ATTRIBUTES.each { |f| instance_variable_set("@#{f}", attrs.key?(f) ? attrs[f] : attrs[f.to_sym]) }
|
|
191
|
+
end
|
|
192
|
+
def self.from_hash(h); h.nil? ? nil : new(h); end
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
# AssistantsV1Feedback β `aia_fdbk_...`. Numeric score + text feedback on a message.
|
|
196
|
+
class AssistantsV1Feedback
|
|
197
|
+
ATTRIBUTES = %w[
|
|
198
|
+
assistant_id id account_sid user_sid message_id score session_id text
|
|
199
|
+
date_created date_updated
|
|
200
|
+
].freeze
|
|
201
|
+
attr_reader(*ATTRIBUTES.map(&:to_sym))
|
|
202
|
+
def initialize(attrs = {})
|
|
203
|
+
ATTRIBUTES.each { |f| instance_variable_set("@#{f}", attrs.key?(f) ? attrs[f] : attrs[f.to_sym]) }
|
|
204
|
+
end
|
|
205
|
+
def self.from_hash(h); h.nil? ? nil : new(h); end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
class AssistantsV1FeedbackList
|
|
209
|
+
include V1Pageable
|
|
210
|
+
attr_reader :feedbacks
|
|
211
|
+
def initialize(hash = {})
|
|
212
|
+
assign_meta_fields(hash)
|
|
213
|
+
@feedbacks = (hash['feedbacks'] || []).map { |h| AssistantsV1Feedback.from_hash(h) }
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
# AssistantsV1Policy β `aia_plcy_...`. Read-only β listed under /v1/Policies (filterable
|
|
218
|
+
# by ToolId/KnowledgeId) and embedded inline on Tool fetch responses.
|
|
219
|
+
class AssistantsV1Policy
|
|
220
|
+
ATTRIBUTES = %w[
|
|
221
|
+
id name description account_sid user_sid type policy_details
|
|
222
|
+
date_created date_updated
|
|
223
|
+
].freeze
|
|
224
|
+
attr_reader(*ATTRIBUTES.map(&:to_sym))
|
|
225
|
+
def initialize(attrs = {})
|
|
226
|
+
ATTRIBUTES.each { |f| instance_variable_set("@#{f}", attrs.key?(f) ? attrs[f] : attrs[f.to_sym]) }
|
|
227
|
+
end
|
|
228
|
+
def self.from_hash(h); h.nil? ? nil : new(h); end
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
class AssistantsV1PolicyList
|
|
232
|
+
include V1Pageable
|
|
233
|
+
attr_reader :policies
|
|
234
|
+
def initialize(hash = {})
|
|
235
|
+
assign_meta_fields(hash)
|
|
236
|
+
@policies = (hash['policies'] || []).map { |h| AssistantsV1Policy.from_hash(h) }
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
end
|