melaya 0.3.0 → 0.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 47fefbce18553e5a38d414eb96ad35da805b1bb4d685e9fd809206b00d2dbe68
4
- data.tar.gz: 822418410f53fc0cb03caf2fd06a8a122db8082e58ded4c68f6032dea5898965
3
+ metadata.gz: 523018c43fba39a422511cbfcc953f2a25f4dd0a2471c37a5b133544eee4ad0c
4
+ data.tar.gz: 777fe8a1777eceec586938329d36ea167c417f761282119cb3154519b60b87ca
5
5
  SHA512:
6
- metadata.gz: 7680af7ede9b7cfa4e4fa2c6860c3e40260c488f2a3b6906930382b9a44ab36862ff8117ac6ce533bcac5fe5d7b8f12c4961257a61c149ebf6c07953da84e1e7
7
- data.tar.gz: 6e929c21c54d44b99c0cfffa1d717ca85ca95bf0c95ecbc1d2e260e9343e8cc4383d47e38d7b9ffe965aa15798e7ee202ae2230f2fc4de75a21b15bdd2aa500e
6
+ metadata.gz: b32eaac6377a90e41146f33b5077eb5eb7369f277685fe2eaa5e97442a32f9393595fd5bb05cd3033376b3e5c9ff00ed93338fdeb73df5d97cf4e5f3ab03ff37
7
+ data.tar.gz: 7e0851368ebad8ee942bf1b14b7ad93a46b95da769cd75e68fd3201489b7ec53fa34f615262e15c64b1c61371548d87fb664ecf535f8fc6724c22f10f48a794d
data/README.md CHANGED
@@ -8,7 +8,7 @@ Official SDK for the **[Melaya](https://melaya.org)** Agent Builder and flagship
8
8
 
9
9
  - Zero runtime gem dependencies (stdlib `net/http`, `openssl`, `json` only).
10
10
  - Full Agent Builder lifecycle: projects, pipelines, templates, Connectors, HITL, evals, events, billing, team, and runner management.
11
- - Catalogs of **1,500+ scoped tools**, **100+ specialized subagents**, and **20+ model providers** (runtime catalog endpoints are the source of truth).
11
+ - Catalogs of **8,000+ scoped tools**, **100+ specialized subagents**, and **48 AI providers** (runtime catalog endpoints are the source of truth).
12
12
  - Pure Ruby WebSocket client (RFC 6455) — no external gem required for streaming.
13
13
 
14
14
  ## Install
@@ -146,6 +146,27 @@ outcome = melaya.agents.connector_tools.call_and_wait("gmail_send", args: { to:
146
146
  melaya.connector_tools.services
147
147
  ```
148
148
 
149
+ ### Quick start: diagnose an event trigger
150
+
151
+ Read, diagnose and dry-run the event triggers that start your pipelines.
152
+ Creating, editing and deleting a trigger stay in the Agent Builder and the MCP
153
+ server. No method returns a signing secret. `test` and `poll_test` are dry
154
+ runs: the action never executes.
155
+
156
+ ```ruby
157
+ triggers = melaya.agents.triggers.list(project: "support")
158
+ id = triggers[0]["id"]
159
+
160
+ melaya.agents.triggers.stats(id, hours: 24) # counts by verdict
161
+ melaya.agents.triggers.events(trigger_id: id, verdicts: %w[rejected failed], limit: 50)
162
+ melaya.agents.triggers.test(id, payload: { type: "refund.created" }) # dry run
163
+
164
+ # Poll triggers
165
+ melaya.agents.triggers.poll_status(id)
166
+ dry = melaya.agents.triggers.poll_test(id) # what it found and would publish
167
+ puts dry["ok"] ? "#{dry["found"]} found, #{dry["wouldPublish"]} new" : dry["error"]
168
+ ```
169
+
149
170
  ## Trading quick start (preview)
150
171
 
151
172
  ```ruby
@@ -267,6 +288,7 @@ Public market-data and account/strategy reads work with the `mk_` key alone. **L
267
288
  | Projects | `projects.list`, `create`, `rename`, `runner_projects` |
268
289
  | Connectors | `connectors.connected_services`, `set`, `delete`, `env_handle`, `google_oauth_start`, `apply_personal`, `shared_by`, `google_status`, `google_set_default`, `google_disconnect`, `db_test_start`, `db_test_status` |
269
290
  | Connector Tools | `connector_tools.services`, `search`, `describe`, `test`, `connect`, `call`, `call_status`, `call_and_wait` |
291
+ | Triggers | `triggers.list`, `get`, `deliveries`, `stats`, `pending_approvals`, `test`, `events`, `poll_status`, `poll_test`, `poll_now`, `poll_sync`, `presets`, `limits`, `sources` |
270
292
  | Credentials | `credentials.list`, `connected_services`, `get`, `set`, `delete`, `test`, `list_models`, `google_status`, `google_set_default`, `google_disconnect`, `db_test_start`, `db_test_status`, `telegram_qr_start`, `telegram_qr_poll`, `whatsapp_signup_config`, `whatsapp_signup_exchange`, `tiktok_creator_info`, `substack_email_link_send`, `substack_email_link_redeem`, plus operator-profile, OAuth, and RAG helpers |
271
293
  | Pipelines | `pipelines.create`, `get`, `update`, `delete_pipeline`, `list_pipelines`, `run`, `upload_run_file`, `run_inputs`, `run_input_file`, `run_active`, `run_ids`, `run_status`, `cancel_run`, `outputs`, `output`, `preview_code`, `tools`, `subagents`, `instantiate_template`, `build_with_ai` |
272
294
  | Pipeline docs & RAG | `pipelines.list_docs`, `upload_doc`, `delete_doc`, `upload_retrieval_doc`, `ingest_retrieval`, `delete_retrieval_doc` |
@@ -286,7 +308,7 @@ Public market-data and account/strategy reads work with the `mk_` key alone. **L
286
308
  | Assistant | `assistant.get_profile`, `set_profile` |
287
309
  | Bugs | `bugs.create`, `list_mine`, `get`, `add_comment`, `list_notifications`, `mark_notifications_read` |
288
310
 
289
- Every area is also reachable through the domain namespaces: `melaya.agents.*` (pipelines/runs, hitl, assistant, phone, evals, models, connector_tools) and `melaya.platform.*` (projects, credentials, connectors, billing, team, templates, overview, runner, auth, mfa, accounts, bugs, events).
311
+ Every area is also reachable through the domain namespaces: `melaya.agents.*` (pipelines/runs, hitl, assistant, phone, evals, models, connector_tools, triggers) and `melaya.platform.*` (projects, credentials, connectors, billing, team, templates, overview, runner, auth, mfa, accounts, bugs, events).
290
312
 
291
313
  ### Trading (preview — not generally available)
292
314
 
@@ -7,7 +7,7 @@ module Melaya
7
7
  # grouping the flat module accessors into logical planes:
8
8
  #
9
9
  # melaya.trading — market data, account, sim, strategies, backtest, stream, trade
10
- # melaya.agents — pipelines/runs, hitl, assistant, phone, evals, models, connector_tools
10
+ # melaya.agents — pipelines/runs, hitl, assistant, phone, evals, models, connector_tools, triggers
11
11
  # melaya.platform — projects, credentials, connectors, billing, team, templates,
12
12
  # overview (via pipelines), runner, auth, mfa (via auth),
13
13
  # accounts, bugs, events
@@ -63,6 +63,8 @@ module Melaya
63
63
  # - +connector_tools+ — Call already-connected connector tools directly
64
64
  # (Gmail, Slack, Stripe, ...): list, search, describe, test,
65
65
  # connect, call, call_status, call_and_wait.
66
+ # - +triggers+ — Event triggers: list, inspect, diagnose and dry-run
67
+ # triggers and poll triggers.
66
68
  AgentsNamespace = Struct.new(
67
69
  :pipelines,
68
70
  :hitl,
@@ -71,6 +73,7 @@ module Melaya
71
73
  :evals,
72
74
  :models,
73
75
  :connector_tools,
76
+ :triggers,
74
77
  keyword_init: true
75
78
  ) do
76
79
  # +runs+ is an ergonomic alias for +pipelines+ (agents call them "runs").
@@ -0,0 +1,201 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Melaya
4
+ # Triggers API: read, diagnose and dry-run the event triggers that start
5
+ # your pipelines.
6
+ #
7
+ # Maps to /api/v1/private/triggers/*.
8
+ #
9
+ # Read-only apart from the dry runs and poll controls. Creating, updating,
10
+ # deleting a trigger and rotating its signing secret stay in the Agent
11
+ # Builder and the MCP server, where push consent and autonomy grants are
12
+ # enforced. No method here returns a signing secret.
13
+ #
14
+ # +test+ and +poll_test+ are dry runs: the trigger's action never executes.
15
+ # +poll_now+ queues a real poll.
16
+ #
17
+ # @example
18
+ # triggers = melaya.agents.triggers.list(project: "support")
19
+ # stats = melaya.agents.triggers.stats(triggers[0]["id"], hours: 24)
20
+ #
21
+ # # What happened recently, including events that wrote no receipt.
22
+ # live = melaya.agents.triggers.events(verdicts: %w[rejected failed], limit: 50)
23
+ #
24
+ # # Dry run one event (the action never runs).
25
+ # test = melaya.agents.triggers.test(triggers[0]["id"], payload: { type: "ping" })
26
+ # # => { "accepted" => true, "eventId" => "test-..." }
27
+ #
28
+ # # Also reachable via the flat alias:
29
+ # melaya.triggers.limits
30
+ class TriggersAPI
31
+ BASE = "/api/v1/private/triggers"
32
+
33
+ def initialize(http)
34
+ @http = http
35
+ end
36
+
37
+ # ── Triggers ──────────────────────────────────────────────────────────────
38
+
39
+ # GET /triggers?project=&pipelineName=
40
+ # List your event triggers.
41
+ # @param project [String, nil] project name filter
42
+ # @param pipeline_name [String, nil] pipeline name filter
43
+ # @return [Array<Hash>] trigger records: id, publicId, name, kind, project,
44
+ # pipelineName, enabled, pausedReason, signingScheme, sourceId, config,
45
+ # rate caps, consecutiveFailures, lastEventAt, createdAt, updatedAt,
46
+ # webhookUrl, projectAccess
47
+ def list(project: nil, pipeline_name: nil)
48
+ @http.get(BASE, compact("project" => project, "pipelineName" => pipeline_name))
49
+ end
50
+
51
+ # GET /triggers/:id
52
+ # One trigger with its config. Secrets are never included.
53
+ # @param id [String]
54
+ # @return [Hash]
55
+ def get(id)
56
+ @http.get("#{BASE}/#{enc(id)}")
57
+ end
58
+
59
+ # GET /triggers/:id/deliveries?limit=
60
+ # Recent deliveries (receipts) of a trigger: verdict, decision answers,
61
+ # action, run id and timings.
62
+ # @param id [String]
63
+ # @param limit [Integer, nil] 1-200, server default 50
64
+ # @return [Array<Hash>]
65
+ def deliveries(id, limit: nil)
66
+ @http.get("#{BASE}/#{enc(id)}/deliveries", compact("limit" => limit))
67
+ end
68
+
69
+ # GET /triggers/:id/stats?hours=
70
+ # Delivery counts by verdict over a window.
71
+ # @param id [String]
72
+ # @param hours [Integer, nil] 1-168, server default 24
73
+ # @return [Hash] { "hours" => Integer, "byVerdict" => { verdict => { "n", "p50", "p95" } },
74
+ # "filtered" => Integer or nil, "sampled" => Boolean }
75
+ def stats(id, hours: nil)
76
+ @http.get("#{BASE}/#{enc(id)}/stats", compact("hours" => hours))
77
+ end
78
+
79
+ # GET /triggers/:id/approvals
80
+ # Approvals still waiting on this trigger's runs and tool calls. Read
81
+ # only: decide them in the Melaya app.
82
+ # @param id [String]
83
+ # @return [Array<Hash>]
84
+ def pending_approvals(id)
85
+ @http.get("#{BASE}/#{enc(id)}/approvals")
86
+ end
87
+
88
+ # POST /triggers/:id/test { payload }
89
+ # Dry run one event through the prefilter, the decide step and routing.
90
+ # The action never executes. The trigger's rate limits still apply, so a
91
+ # refused test comes back with "accepted" => false and a "reason"
92
+ # ("disabled", "rate_limited", ...). Follow the outcome with +events+
93
+ # for this trigger.
94
+ # @param id [String]
95
+ # @param payload [Object, nil] the event payload; omit for an empty object
96
+ # @return [Hash] { "accepted" => Boolean, "eventId" => String, "reason" => String (optional) }
97
+ def test(id, payload: nil)
98
+ @http.post("#{BASE}/#{enc(id)}/test", payload.nil? ? {} : { "payload" => payload })
99
+ end
100
+
101
+ # GET /triggers/events?triggerId=&since=&verdicts=&limit=
102
+ # Recent live trigger events, newest first (the last 500 events or 24
103
+ # hours), including the outcomes that write no receipt: filtered, shed,
104
+ # ingress rejections, feed refusals and push lifecycle notes. To follow
105
+ # new events, pass +since+ = the newest "at" already seen.
106
+ # @param trigger_id [String, nil] only this trigger's events
107
+ # @param since [Integer, nil] only events after this time, epoch milliseconds
108
+ # @param verdicts [Array<String>, String, nil] e.g. %w[rejected filtered failed]
109
+ # @param limit [Integer, nil] 1-200
110
+ # @return [Hash] { "events" => [Hash], "scanned" => Integer,
111
+ # "retention" => { "maxEvents" => Integer, "ttlSec" => Integer } }
112
+ def events(trigger_id: nil, since: nil, verdicts: nil, limit: nil)
113
+ v = verdicts.is_a?(Array) ? verdicts.join(",") : verdicts
114
+ v = nil if v == ""
115
+ @http.get("#{BASE}/events",
116
+ compact("triggerId" => trigger_id, "since" => since, "verdicts" => v, "limit" => limit))
117
+ end
118
+
119
+ # ── Poll triggers ─────────────────────────────────────────────────────────
120
+
121
+ # GET /triggers/:triggerId/poll
122
+ # Runtime state of a poll trigger: synced, status, lastError,
123
+ # lastPolledAt, nextPollAt, armed, baselinePending, seenCount,
124
+ # itemsPublished, consecutiveErrors, requestedIntervalSec,
125
+ # effectiveIntervalSec, tierFloorSec.
126
+ # @param trigger_id [String]
127
+ # @return [Hash]
128
+ def poll_status(trigger_id)
129
+ @http.get("#{BASE}/#{enc(trigger_id)}/poll")
130
+ end
131
+
132
+ # POST /triggers/:triggerId/poll/test { dry: true }
133
+ # Dry poll: calls the poll tool now and returns what it found and would
134
+ # publish. Nothing is published. A poll that fails is returned as
135
+ # { "dry" => true, "ok" => false, "error" => code } instead of raised.
136
+ # Dry polls are throttled to one every few seconds (HTTP 429).
137
+ # @param trigger_id [String]
138
+ # @return [Hash] { "dry", "ok", "found", "baseline", "wouldPublish",
139
+ # "items" => [{ "id", "preview" }], "samplePayload" } or { "dry", "ok" => false, "error" }
140
+ def poll_test(trigger_id)
141
+ @http.post("#{BASE}/#{enc(trigger_id)}/poll/test", "dry" => true)
142
+ rescue MelayaError => e
143
+ # A failed dry poll is a normal 200 result, not a request failure.
144
+ raise unless e.status.to_i < 400 && e.body.is_a?(Hash) && e.body.key?("dry")
145
+
146
+ e.body
147
+ end
148
+
149
+ # POST /triggers/:triggerId/poll/test { dry: false }
150
+ # Queue a real poll now. The trigger must be enabled ("trigger_disabled"
151
+ # otherwise). Follow the outcome with +poll_status+ and +events+.
152
+ # @param trigger_id [String]
153
+ # @return [Hash] { "dry" => false, "queued" => Boolean }
154
+ def poll_now(trigger_id)
155
+ @http.post("#{BASE}/#{enc(trigger_id)}/poll/test", "dry" => false)
156
+ end
157
+
158
+ # POST /triggers/:triggerId/poll/sync
159
+ # Re-create a poll trigger's runtime row from its saved config. Re-arms a
160
+ # trigger whose poller never started.
161
+ # @param trigger_id [String]
162
+ # @return [Hash] { "result" => Object }
163
+ def poll_sync(trigger_id)
164
+ @http.post("#{BASE}/#{enc(trigger_id)}/poll/sync", {})
165
+ end
166
+
167
+ # ── Account-wide ──────────────────────────────────────────────────────────
168
+
169
+ # GET /triggers/presets
170
+ # Trigger presets available to you, given your connected services and plan.
171
+ # @return [Hash] { "tier" => String, "tierFloorSec" => Integer, "presets" => [Hash], "beta" => Hash }
172
+ def presets
173
+ @http.get("#{BASE}/presets")
174
+ end
175
+
176
+ # GET /triggers/limits
177
+ # Plan caps and usage: triggers and sources used against the cap, events
178
+ # per minute, poll interval floor and approval TTL bounds.
179
+ # @return [Hash]
180
+ def limits
181
+ @http.get("#{BASE}/limits")
182
+ end
183
+
184
+ # GET /triggers/sources
185
+ # Your WebSocket and SSE stream sources.
186
+ # @return [Array<Hash>]
187
+ def sources
188
+ @http.get("#{BASE}/sources")
189
+ end
190
+
191
+ private
192
+
193
+ def enc(s)
194
+ URI.encode_www_form_component(s.to_s)
195
+ end
196
+
197
+ def compact(hash)
198
+ hash.reject { |_, v| v.nil? }
199
+ end
200
+ end
201
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Melaya
4
- VERSION = "0.3.0"
4
+ VERSION = "0.4.0"
5
5
  end
data/lib/melaya.rb CHANGED
@@ -24,6 +24,7 @@ require_relative "melaya/hitl"
24
24
  require_relative "melaya/credentials"
25
25
  require_relative "melaya/connectors"
26
26
  require_relative "melaya/connector_tools"
27
+ require_relative "melaya/triggers"
27
28
  require_relative "melaya/phone"
28
29
  require_relative "melaya/team"
29
30
  require_relative "melaya/templates"
@@ -59,7 +60,7 @@ module Melaya
59
60
  # **Namespace groupings**:
60
61
  # - +trading+ — market, account, sim, strategies, backtest, stream, trade
61
62
  # - +agents+ — pipelines (also +.runs+), hitl, assistant, phone, evals, models,
62
- # connector_tools
63
+ # connector_tools, triggers
63
64
  # - +platform+ — projects, credentials, connectors, billing, team, templates,
64
65
  # overview, runner, auth (also +.mfa+), accounts, bugs, events
65
66
  #
@@ -132,6 +133,9 @@ module Melaya
132
133
  # — the same surface the MCP server and Assistant use. Not to be confused
133
134
  # with +connectors+ (credential storage).
134
135
  attr_reader :connector_tools
136
+ # Event triggers: list, inspect, diagnose and dry-run triggers and poll
137
+ # triggers. Create, update and delete stay in the Agent Builder and MCP.
138
+ attr_reader :triggers
135
139
  # Phone device control: pair, list, screen-tree, apps.
136
140
  attr_reader :phone
137
141
  # Project team management: members, roles, invite links.
@@ -163,7 +167,7 @@ module Melaya
163
167
 
164
168
  # Agent-plane namespace.
165
169
  # Groups: pipelines (alias: runs), hitl, assistant, phone, evals, models,
166
- # connector_tools.
170
+ # connector_tools, triggers.
167
171
  #
168
172
  # @return [AgentsNamespace]
169
173
  # @example
@@ -174,6 +178,7 @@ module Melaya
174
178
  # melaya.agents.evals.list_runs
175
179
  # melaya.agents.models.list_models(provider: "anthropic")
176
180
  # melaya.agents.connector_tools.services
181
+ # melaya.agents.triggers.events(limit: 50)
177
182
  attr_reader :agents
178
183
 
179
184
  # Platform-plane namespace.
@@ -239,6 +244,7 @@ module Melaya
239
244
  @credentials = CredentialsAPI.new(http)
240
245
  @connectors = ConnectorsAPI.new(http)
241
246
  @connector_tools = ConnectorToolsAPI.new(http)
247
+ @triggers = TriggersAPI.new(http)
242
248
  @phone = PhoneAPI.new(http)
243
249
  @team = TeamAPI.new(http)
244
250
  @templates = TemplatesAPI.new(http)
@@ -278,7 +284,8 @@ module Melaya
278
284
  # credentials#list_models is the canonical "models" surface; expose the
279
285
  # full CredentialsAPI object here so callers can do agents.models.list_models(...)
280
286
  models: @credentials,
281
- connector_tools: @connector_tools
287
+ connector_tools: @connector_tools,
288
+ triggers: @triggers
282
289
  )
283
290
 
284
291
  # Platform namespace: events slot uses a lazy proxy so the Socket.IO
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: melaya
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Melaya
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-09-27 00:00:00.000000000 Z
11
+ date: 2026-09-28 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Official Ruby SDK for Melaya Agent Builder and Mobile Device Control.
14
14
  Includes preview Melaya Trading namespaces that are not yet generally available.
@@ -48,6 +48,7 @@ files:
48
48
  - lib/melaya/team.rb
49
49
  - lib/melaya/templates.rb
50
50
  - lib/melaya/trade.rb
51
+ - lib/melaya/triggers.rb
51
52
  - lib/melaya/version.rb
52
53
  - melaya.gemspec
53
54
  homepage: https://melaya.org