melaya 0.1.4 → 0.2.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/LICENSE +158 -0
- data/README.md +96 -15
- data/lib/melaya/accounts.rb +42 -0
- data/lib/melaya/assistant.rb +41 -0
- data/lib/melaya/auth.rb +137 -0
- data/lib/melaya/backtest.rb +38 -0
- data/lib/melaya/billing.rb +75 -0
- data/lib/melaya/bugs.rb +67 -0
- data/lib/melaya/connectors.rb +71 -0
- data/lib/melaya/credentials.rb +255 -0
- data/lib/melaya/errors.rb +36 -2
- data/lib/melaya/evals.rb +78 -0
- data/lib/melaya/events.rb +425 -0
- data/lib/melaya/hitl.rb +114 -0
- data/lib/melaya/http_client.rb +159 -30
- data/lib/melaya/market.rb +42 -0
- data/lib/melaya/namespaces.rb +115 -0
- data/lib/melaya/phone.rb +75 -0
- data/lib/melaya/pipelines.rb +342 -0
- data/lib/melaya/projects.rb +58 -0
- data/lib/melaya/runner.rb +44 -0
- data/lib/melaya/strategies.rb +15 -0
- data/lib/melaya/stream.rb +5 -3
- data/lib/melaya/team.rb +102 -0
- data/lib/melaya/templates.rb +148 -0
- data/lib/melaya/version.rb +1 -1
- data/lib/melaya.rb +261 -30
- data/melaya.gemspec +10 -5
- metadata +28 -7
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Melaya
|
|
4
|
+
# Templates API — create, manage, share, and assign pipeline templates.
|
|
5
|
+
#
|
|
6
|
+
# Templates bundle a pipeline definition into a reusable, shareable artifact.
|
|
7
|
+
# Visibility levels: private → team → community → assigned.
|
|
8
|
+
#
|
|
9
|
+
# Maps to:
|
|
10
|
+
# /api/v1/private/user-templates/* — CRUD + share + assignments
|
|
11
|
+
# /api/v1/private/templates/* — global/validated lists
|
|
12
|
+
#
|
|
13
|
+
# @example
|
|
14
|
+
# templates = melaya.templates.list
|
|
15
|
+
# t = melaya.templates.save(name: "My report", payload: { steps: [] })
|
|
16
|
+
# melaya.templates.share(t["id"], "team")
|
|
17
|
+
# melaya.templates.delete(t["id"])
|
|
18
|
+
class TemplatesAPI
|
|
19
|
+
def initialize(http)
|
|
20
|
+
@http = http
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# GET /api/v1/private/user-templates
|
|
24
|
+
# List all templates visible to the caller (own + team + community + assigned).
|
|
25
|
+
def list
|
|
26
|
+
@http.get("/api/v1/private/user-templates")
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# GET /api/v1/private/templates/global
|
|
30
|
+
# List all community-visibility (global) templates.
|
|
31
|
+
def list_global
|
|
32
|
+
@http.get("/api/v1/private/templates/global")
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# GET /api/v1/private/templates/validated
|
|
36
|
+
# List IDs of all validated (platform-approved) templates.
|
|
37
|
+
def list_validated
|
|
38
|
+
@http.get("/api/v1/private/templates/validated")
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# POST /api/v1/private/user-templates
|
|
42
|
+
# Create a new private user template.
|
|
43
|
+
# @param name [String]
|
|
44
|
+
# @param payload [Hash]
|
|
45
|
+
# @param description [String, nil]
|
|
46
|
+
# @param category [String, nil]
|
|
47
|
+
def save(name:, payload:, description: nil, category: nil)
|
|
48
|
+
body = compact(
|
|
49
|
+
"name" => name,
|
|
50
|
+
"payload" => payload,
|
|
51
|
+
"description" => description,
|
|
52
|
+
"category" => category
|
|
53
|
+
)
|
|
54
|
+
@http.post("/api/v1/private/user-templates", body)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# PATCH /api/v1/private/user-templates/:id
|
|
58
|
+
# Update name/description/category/payload of a private user template.
|
|
59
|
+
# @param template_id [String]
|
|
60
|
+
# @param body [Hash]
|
|
61
|
+
def update(template_id, body = {})
|
|
62
|
+
@http.patch("/api/v1/private/user-templates/#{enc(template_id)}", body)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# POST /api/v1/private/user-templates/:sourceId/duplicate
|
|
66
|
+
# Duplicate a readable template into the caller's private library.
|
|
67
|
+
# @param template_id [String] the source template to copy
|
|
68
|
+
# @param new_name [String, nil]
|
|
69
|
+
def duplicate(template_id, new_name: nil)
|
|
70
|
+
body = new_name ? { "newName" => new_name } : nil
|
|
71
|
+
@http.post("/api/v1/private/user-templates/#{enc(template_id)}/duplicate", body)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# DELETE /api/v1/private/user-templates/:id
|
|
75
|
+
# Delete (or soft-demote if shared) a template.
|
|
76
|
+
# @param template_id [String]
|
|
77
|
+
def delete(template_id)
|
|
78
|
+
@http.delete("/api/v1/private/user-templates/#{enc(template_id)}")
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# PUT /api/v1/private/user-templates/:id/visibility
|
|
82
|
+
# Change the visibility of a template.
|
|
83
|
+
# @param template_id [String]
|
|
84
|
+
# @param visibility [String] "private", "team", "community", or "assigned"
|
|
85
|
+
def share(template_id, visibility)
|
|
86
|
+
@http.put("/api/v1/private/user-templates/#{enc(template_id)}/visibility",
|
|
87
|
+
"visibility" => visibility)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# GET /api/v1/private/user-templates/share-targets
|
|
91
|
+
# List projects the caller is a member of (for the share target picker UI).
|
|
92
|
+
def share_targets
|
|
93
|
+
@http.get("/api/v1/private/user-templates/share-targets")
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# ── Assignments ────────────────────────────────────────────────────────────
|
|
97
|
+
|
|
98
|
+
# GET /api/v1/private/user-templates/:templateId/assignments
|
|
99
|
+
# List all assignments (users / projects) for a template.
|
|
100
|
+
# @param template_id [String]
|
|
101
|
+
def list_assignments(template_id)
|
|
102
|
+
@http.get("/api/v1/private/user-templates/#{enc(template_id)}/assignments")
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# POST /api/v1/private/user-templates/:templateId/assignments
|
|
106
|
+
# Assign a template to a user or project.
|
|
107
|
+
# Provide exactly one of +user_id:+ or +project_id:+ (both UUIDs);
|
|
108
|
+
# the server rejects requests carrying both or neither.
|
|
109
|
+
# @param template_id [String]
|
|
110
|
+
# @param user_id [String, nil] target user UUID
|
|
111
|
+
# @param project_id [String, nil] target project UUID
|
|
112
|
+
def assign(template_id, user_id: nil, project_id: nil)
|
|
113
|
+
@http.post("/api/v1/private/user-templates/#{enc(template_id)}/assignments",
|
|
114
|
+
assignment_target(user_id, project_id))
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# DELETE /api/v1/private/user-templates/:templateId/assignments
|
|
118
|
+
# Remove an assignment from a template.
|
|
119
|
+
# Provide exactly one of +user_id:+ or +project_id:+ (both UUIDs).
|
|
120
|
+
# The target is sent as query params — the server ignores DELETE
|
|
121
|
+
# request bodies.
|
|
122
|
+
# @param template_id [String]
|
|
123
|
+
# @param user_id [String, nil] target user UUID
|
|
124
|
+
# @param project_id [String, nil] target project UUID
|
|
125
|
+
def unassign(template_id, user_id: nil, project_id: nil)
|
|
126
|
+
@http.delete("/api/v1/private/user-templates/#{enc(template_id)}/assignments",
|
|
127
|
+
assignment_target(user_id, project_id))
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
private
|
|
131
|
+
|
|
132
|
+
# Exactly one of user_id / project_id must be given.
|
|
133
|
+
def assignment_target(user_id, project_id)
|
|
134
|
+
if user_id.nil? == project_id.nil?
|
|
135
|
+
raise ArgumentError, "Melaya: provide exactly one of user_id: or project_id:"
|
|
136
|
+
end
|
|
137
|
+
user_id ? { "userId" => user_id } : { "projectId" => project_id }
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def enc(s)
|
|
141
|
+
URI.encode_www_form_component(s.to_s)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def compact(hash)
|
|
145
|
+
hash.reject { |_, v| v.nil? }
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
data/lib/melaya/version.rb
CHANGED
data/lib/melaya.rb
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
require_relative "melaya/version"
|
|
4
4
|
require_relative "melaya/errors"
|
|
5
5
|
require_relative "melaya/http_client"
|
|
6
|
+
|
|
7
|
+
# ── Trading plane ──────────────────────────────────────────────────────────────
|
|
6
8
|
require_relative "melaya/market"
|
|
7
9
|
require_relative "melaya/account"
|
|
8
10
|
require_relative "melaya/sim"
|
|
@@ -11,28 +13,86 @@ require_relative "melaya/backtest"
|
|
|
11
13
|
require_relative "melaya/stream"
|
|
12
14
|
require_relative "melaya/trade"
|
|
13
15
|
|
|
16
|
+
# ── Platform / agents plane ────────────────────────────────────────────────────
|
|
17
|
+
require_relative "melaya/auth"
|
|
18
|
+
require_relative "melaya/accounts"
|
|
19
|
+
require_relative "melaya/billing"
|
|
20
|
+
require_relative "melaya/runner"
|
|
21
|
+
require_relative "melaya/projects"
|
|
22
|
+
require_relative "melaya/pipelines"
|
|
23
|
+
require_relative "melaya/hitl"
|
|
24
|
+
require_relative "melaya/credentials"
|
|
25
|
+
require_relative "melaya/connectors"
|
|
26
|
+
require_relative "melaya/phone"
|
|
27
|
+
require_relative "melaya/team"
|
|
28
|
+
require_relative "melaya/templates"
|
|
29
|
+
require_relative "melaya/assistant"
|
|
30
|
+
require_relative "melaya/evals"
|
|
31
|
+
require_relative "melaya/bugs"
|
|
32
|
+
require_relative "melaya/events"
|
|
33
|
+
|
|
34
|
+
# ── Domain namespace groupings ─────────────────────────────────────────────────
|
|
35
|
+
require_relative "melaya/namespaces"
|
|
36
|
+
|
|
14
37
|
module Melaya
|
|
15
|
-
# The Melaya client.
|
|
38
|
+
# The unified Melaya client.
|
|
39
|
+
#
|
|
40
|
+
# Exposes every public endpoint in the Melaya REST API surface through three
|
|
41
|
+
# domain namespaces **and** flat module accessors (for backward compatibility).
|
|
42
|
+
#
|
|
43
|
+
# **Primary API — namespaced** (recommended):
|
|
44
|
+
#
|
|
45
|
+
# melaya.trading.market.ticker(...) # market data
|
|
46
|
+
# melaya.trading.strategies.create(...) # trading strategies
|
|
47
|
+
# melaya.agents.pipelines.list(...) # agent pipeline runs
|
|
48
|
+
# melaya.agents.hitl.pending # HITL approval queue
|
|
49
|
+
# melaya.platform.projects.list # platform projects
|
|
50
|
+
# melaya.platform.billing.subscription # billing
|
|
51
|
+
#
|
|
52
|
+
# **Flat accessors** (backward-compatible aliases):
|
|
53
|
+
#
|
|
54
|
+
# melaya.market.ticker(...) # same object as melaya.trading.market
|
|
55
|
+
# melaya.pipelines.list(...) # same object as melaya.agents.pipelines
|
|
56
|
+
# melaya.projects.list # same object as melaya.platform.projects
|
|
57
|
+
#
|
|
58
|
+
# **Namespace groupings**:
|
|
59
|
+
# - +trading+ — market, account, sim, strategies, backtest, stream, trade
|
|
60
|
+
# - +agents+ — pipelines (also +.runs+), hitl, assistant, phone, evals, models
|
|
61
|
+
# - +platform+ — projects, credentials, connectors, billing, team, templates,
|
|
62
|
+
# overview, runner, auth (also +.mfa+), accounts, bugs, events
|
|
63
|
+
#
|
|
64
|
+
# Authentication: pass your +mk_*+ platform API key via +api_key:+. Every REST call
|
|
65
|
+
# sends it as an Authorization: Bearer header. For session JWT workflows
|
|
66
|
+
# (login/refresh) construct the client with the JWT instead.
|
|
67
|
+
# Never log or expose the key — it is stored opaquely in the HTTP client.
|
|
16
68
|
#
|
|
17
69
|
# @example
|
|
18
70
|
# require "melaya"
|
|
19
|
-
# melaya = Melaya::Client.new(api_key: ENV["MK"])
|
|
20
71
|
#
|
|
21
|
-
#
|
|
22
|
-
#
|
|
72
|
+
# melaya = Melaya::Client.new(api_key: ENV["MELAYA_API_KEY"])
|
|
73
|
+
#
|
|
74
|
+
# # Namespaced — primary API
|
|
75
|
+
# t = melaya.trading.market.ticker(exchange: "binance", symbol: "BTC/USDT", market: "spot")
|
|
23
76
|
# puts t["last"]
|
|
24
77
|
#
|
|
25
|
-
# #
|
|
26
|
-
#
|
|
27
|
-
#
|
|
28
|
-
#
|
|
29
|
-
#
|
|
30
|
-
#
|
|
31
|
-
#
|
|
32
|
-
# melaya.
|
|
33
|
-
#
|
|
78
|
+
# # Agent pipelines
|
|
79
|
+
# runs = melaya.agents.pipelines.list(project: "my-project", limit: 10)
|
|
80
|
+
# # or via the alias:
|
|
81
|
+
# runs = melaya.agents.runs.list(project: "my-project", limit: 10)
|
|
82
|
+
#
|
|
83
|
+
# # HITL approvals
|
|
84
|
+
# pending = melaya.agents.hitl.pending
|
|
85
|
+
# pending.each { |r| melaya.agents.hitl.approve(r["requestId"]) }
|
|
86
|
+
#
|
|
87
|
+
# # Platform
|
|
88
|
+
# projects = melaya.platform.projects.list
|
|
89
|
+
# melaya.platform.auth.login(username: "you@example.com", password: "s3cr3t")
|
|
90
|
+
#
|
|
91
|
+
# # Real-time events (Socket.IO) — also on platform namespace
|
|
92
|
+
# melaya.platform.events.on_run_update("run-123") { |e| puts e["event_type"] }
|
|
34
93
|
class Client
|
|
35
|
-
#
|
|
94
|
+
# ── Trading plane ──────────────────────────────────────────────────────────
|
|
95
|
+
# REST market-data + reference endpoints (public + authenticated).
|
|
36
96
|
attr_reader :market
|
|
37
97
|
# Authenticated account reads: connected keys, tier limits, usage.
|
|
38
98
|
attr_reader :account
|
|
@@ -44,29 +104,114 @@ module Melaya
|
|
|
44
104
|
attr_reader :backtest
|
|
45
105
|
# WebSocket streaming endpoints (public market data + private feeds).
|
|
46
106
|
attr_reader :stream
|
|
47
|
-
# Live trading — credentialed order placement
|
|
107
|
+
# Live trading — credentialed order placement on a connected exchange. WARNING: real funds.
|
|
48
108
|
attr_reader :trade
|
|
49
109
|
|
|
50
|
-
#
|
|
51
|
-
#
|
|
52
|
-
|
|
53
|
-
#
|
|
54
|
-
|
|
110
|
+
# ── Platform / agents plane ────────────────────────────────────────────────
|
|
111
|
+
# Auth: login, MFA, registration, password management, session tokens.
|
|
112
|
+
attr_reader :auth
|
|
113
|
+
# Account management: GDPR export, CEX key removal, profile updates.
|
|
114
|
+
attr_reader :accounts
|
|
115
|
+
# Billing: subscription, Stripe checkout/portal, pricing plans, credit balances.
|
|
116
|
+
attr_reader :billing
|
|
117
|
+
# Runner tokens: mint, list, revoke mel_run_ tokens.
|
|
118
|
+
attr_reader :runner
|
|
119
|
+
# Agent projects: create and list.
|
|
120
|
+
attr_reader :projects
|
|
121
|
+
# Pipeline runs, traces, schedules, and overview dashboard.
|
|
122
|
+
attr_reader :pipelines
|
|
123
|
+
# Human-in-the-loop approval queue: list pending, approve, reject.
|
|
124
|
+
attr_reader :hitl
|
|
125
|
+
# User-scoped credential storage (services, OAuth, env handles, models).
|
|
126
|
+
attr_reader :credentials
|
|
127
|
+
# Project-scoped connector credentials.
|
|
128
|
+
attr_reader :connectors
|
|
129
|
+
# Phone device control: pair, list, screen-tree, apps.
|
|
130
|
+
attr_reader :phone
|
|
131
|
+
# Project team management: members, roles, invite links.
|
|
132
|
+
attr_reader :team
|
|
133
|
+
# Pipeline templates: create, share, assign, and manage visibility.
|
|
134
|
+
attr_reader :templates
|
|
135
|
+
# Assistant onboarding profile (get + set).
|
|
136
|
+
attr_reader :assistant
|
|
137
|
+
# Agent evaluation runs and benchmarks.
|
|
138
|
+
attr_reader :evals
|
|
139
|
+
# Bug reports: submit, track, and comment.
|
|
140
|
+
attr_reader :bugs
|
|
141
|
+
# Platform real-time events over Socket.IO at /api/v1/events.
|
|
142
|
+
# Subscribe to run updates, init-phase progress, HITL notifications,
|
|
143
|
+
# and pipeline CRUD events. Opens a background polling thread.
|
|
144
|
+
attr_reader :events
|
|
145
|
+
|
|
146
|
+
# ── Domain namespace accessors (primary API) ───────────────────────────────
|
|
147
|
+
|
|
148
|
+
# Trading-plane namespace.
|
|
149
|
+
# Groups: market, account, sim, strategies, backtest, stream, trade.
|
|
150
|
+
#
|
|
151
|
+
# @return [TradingNamespace]
|
|
152
|
+
# @example
|
|
153
|
+
# melaya.trading.market.ticker(exchange: "binance", symbol: "BTC/USDT", market: "spot")
|
|
154
|
+
# melaya.trading.strategies.create(name: "bot", strategy_type: "custom", ...)
|
|
155
|
+
# melaya.trading.stream.ticker(exchange: "binance", symbol: "BTC/USDT", market: "spot") { |f| ... }
|
|
156
|
+
attr_reader :trading
|
|
157
|
+
|
|
158
|
+
# Agent-plane namespace.
|
|
159
|
+
# Groups: pipelines (alias: runs), hitl, assistant, phone, evals, models.
|
|
160
|
+
#
|
|
161
|
+
# @return [AgentsNamespace]
|
|
162
|
+
# @example
|
|
163
|
+
# melaya.agents.pipelines.list(project: "my-project")
|
|
164
|
+
# melaya.agents.runs.list(project: "my-project") # alias for pipelines
|
|
165
|
+
# melaya.agents.hitl.pending
|
|
166
|
+
# melaya.agents.assistant.get_profile
|
|
167
|
+
# melaya.agents.evals.list_runs
|
|
168
|
+
# melaya.agents.models.list_models(provider: "anthropic")
|
|
169
|
+
attr_reader :agents
|
|
170
|
+
|
|
171
|
+
# Platform-plane namespace.
|
|
172
|
+
# Groups: projects, credentials, connectors, billing, team, templates,
|
|
173
|
+
# overview, runner, auth (alias: mfa), accounts, bugs, events.
|
|
174
|
+
#
|
|
175
|
+
# @return [PlatformNamespace]
|
|
176
|
+
# @example
|
|
177
|
+
# melaya.platform.projects.list
|
|
178
|
+
# melaya.platform.billing.subscription
|
|
179
|
+
# melaya.platform.auth.login(username: "u", password: "p")
|
|
180
|
+
# melaya.platform.mfa.mfa_setup # alias for auth
|
|
181
|
+
# melaya.platform.credentials.set("openai", value: "sk-...")
|
|
182
|
+
# melaya.platform.events.on_run_update("run-123") { |e| puts e["event_type"] }
|
|
183
|
+
attr_reader :platform
|
|
184
|
+
|
|
185
|
+
# @param api_key [String] Melaya platform API key, prefixed +mk_+.
|
|
186
|
+
# Create one at melaya.org → Settings → API Keys. May also be a session
|
|
187
|
+
# JWT for auth-plane operations (login/refresh return a JWT).
|
|
188
|
+
# @param base_url [String] Override the REST base URL.
|
|
189
|
+
# @param ws_url [String] Override the WebSocket base URL.
|
|
190
|
+
# @param verify_ssl [Boolean] Retained for compatibility; false is rejected.
|
|
191
|
+
# @param connect_events [Boolean] If false, do not open a Socket.IO connection
|
|
192
|
+
# on construction. Call +events+ to connect lazily. Default: false (lazy).
|
|
55
193
|
def initialize(api_key:, base_url: HttpClient::DEFAULT_BASE_URL,
|
|
56
|
-
ws_url: StreamAPI::DEFAULT_WS_URL,
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
raise ArgumentError,
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
194
|
+
ws_url: StreamAPI::DEFAULT_WS_URL,
|
|
195
|
+
verify_ssl: nil,
|
|
196
|
+
connect_events: false)
|
|
197
|
+
raise ArgumentError,
|
|
198
|
+
"Melaya: api_key is required (create one at melaya.org → Settings → API Keys)." \
|
|
199
|
+
if api_key.nil? || api_key.to_s.empty?
|
|
200
|
+
# Allow JWTs (which don't start with mk_) for auth-plane use cases
|
|
201
|
+
# while still guiding developers who forget the prefix.
|
|
202
|
+
if !api_key.to_s.start_with?("mk_") && !api_key.to_s.start_with?("ey")
|
|
203
|
+
raise ArgumentError,
|
|
204
|
+
"Melaya: API keys must be prefixed 'mk_' (or a Bearer JWT starting with 'ey')."
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
if verify_ssl == false
|
|
208
|
+
raise ArgumentError, "Melaya: TLS certificate verification cannot be disabled."
|
|
66
209
|
end
|
|
210
|
+
ssl = true
|
|
67
211
|
|
|
68
212
|
http = HttpClient.new(api_key: api_key, base_url: base_url, verify_ssl: ssl)
|
|
69
213
|
|
|
214
|
+
# Trading plane
|
|
70
215
|
@market = MarketAPI.new(http)
|
|
71
216
|
@account = AccountAPI.new(http)
|
|
72
217
|
@sim = SimAPI.new(http)
|
|
@@ -74,6 +219,92 @@ module Melaya
|
|
|
74
219
|
@backtest = BacktestAPI.new(http)
|
|
75
220
|
@stream = StreamAPI.new(api_key, ws_url, http, verify_ssl: ssl)
|
|
76
221
|
@trade = TradeAPI.new(http)
|
|
222
|
+
|
|
223
|
+
# Platform / agents plane
|
|
224
|
+
@auth = AuthAPI.new(http)
|
|
225
|
+
@accounts = AccountsAPI.new(http)
|
|
226
|
+
@billing = BillingAPI.new(http)
|
|
227
|
+
@runner = RunnerAPI.new(http)
|
|
228
|
+
@projects = ProjectsAPI.new(http)
|
|
229
|
+
@pipelines = PipelinesAPI.new(http)
|
|
230
|
+
@hitl = HitlAPI.new(http)
|
|
231
|
+
@credentials = CredentialsAPI.new(http)
|
|
232
|
+
@connectors = ConnectorsAPI.new(http)
|
|
233
|
+
@phone = PhoneAPI.new(http)
|
|
234
|
+
@team = TeamAPI.new(http)
|
|
235
|
+
@templates = TemplatesAPI.new(http)
|
|
236
|
+
@assistant = AssistantAPI.new(http)
|
|
237
|
+
@evals = EvalsAPI.new(http)
|
|
238
|
+
@bugs = BugsAPI.new(http)
|
|
239
|
+
|
|
240
|
+
if connect_events
|
|
241
|
+
@events = Events.new(api_key: api_key, base_url: base_url, verify_ssl: ssl)
|
|
242
|
+
else
|
|
243
|
+
@_events_api_key = api_key
|
|
244
|
+
@_events_base_url = base_url
|
|
245
|
+
@_events_verify_ssl = ssl
|
|
246
|
+
@events = nil
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
# ── Domain namespaces ────────────────────────────────────────────────────
|
|
250
|
+
# Each attribute is the SAME instance as the flat accessor — no copies,
|
|
251
|
+
# no extra HTTP clients.
|
|
252
|
+
|
|
253
|
+
@trading = TradingNamespace.new(
|
|
254
|
+
market: @market,
|
|
255
|
+
account: @account,
|
|
256
|
+
sim: @sim,
|
|
257
|
+
strategies: @strategies,
|
|
258
|
+
backtest: @backtest,
|
|
259
|
+
stream: @stream,
|
|
260
|
+
trade: @trade
|
|
261
|
+
)
|
|
262
|
+
|
|
263
|
+
@agents = AgentsNamespace.new(
|
|
264
|
+
pipelines: @pipelines,
|
|
265
|
+
hitl: @hitl,
|
|
266
|
+
assistant: @assistant,
|
|
267
|
+
phone: @phone,
|
|
268
|
+
evals: @evals,
|
|
269
|
+
# credentials#list_models is the canonical "models" surface; expose the
|
|
270
|
+
# full CredentialsAPI object here so callers can do agents.models.list_models(...)
|
|
271
|
+
models: @credentials
|
|
272
|
+
)
|
|
273
|
+
|
|
274
|
+
# Platform namespace: events slot uses a lazy proxy so the Socket.IO
|
|
275
|
+
# thread is still only started on first access (same as the flat #events).
|
|
276
|
+
platform_self = self
|
|
277
|
+
@platform = PlatformNamespace.new(
|
|
278
|
+
projects: @projects,
|
|
279
|
+
credentials: @credentials,
|
|
280
|
+
connectors: @connectors,
|
|
281
|
+
billing: @billing,
|
|
282
|
+
team: @team,
|
|
283
|
+
templates: @templates,
|
|
284
|
+
overview: @pipelines, # overview dashboard lives on PipelinesAPI
|
|
285
|
+
runner: @runner,
|
|
286
|
+
auth: @auth,
|
|
287
|
+
accounts: @accounts,
|
|
288
|
+
bugs: @bugs,
|
|
289
|
+
events: nil # filled lazily below
|
|
290
|
+
)
|
|
291
|
+
|
|
292
|
+
# Patch platform#events to delegate to the lazy flat accessor.
|
|
293
|
+
# We do this with a singleton method so PlatformNamespace remains a plain
|
|
294
|
+
# Struct (no subclassing required).
|
|
295
|
+
@platform.define_singleton_method(:events) { platform_self.events }
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
# Lazily initialize and return the events client.
|
|
299
|
+
# If +connect_events: true+ was passed to the constructor, returns the
|
|
300
|
+
# already-connected client. Otherwise creates and connects on first access.
|
|
301
|
+
# Also accessible as +melaya.platform.events+.
|
|
302
|
+
def events
|
|
303
|
+
@events ||= Events.new(
|
|
304
|
+
api_key: @_events_api_key,
|
|
305
|
+
base_url: @_events_base_url,
|
|
306
|
+
verify_ssl: @_events_verify_ssl
|
|
307
|
+
)
|
|
77
308
|
end
|
|
78
309
|
end
|
|
79
310
|
end
|
data/melaya.gemspec
CHANGED
|
@@ -8,15 +8,20 @@ Gem::Specification.new do |spec|
|
|
|
8
8
|
spec.authors = ["Melaya"]
|
|
9
9
|
spec.email = ["sdk@melaya.org"]
|
|
10
10
|
|
|
11
|
-
spec.summary = "Official Ruby SDK for
|
|
12
|
-
spec.description = "
|
|
13
|
-
"Market data, strategies, backtesting, sim trading, and streaming."
|
|
11
|
+
spec.summary = "Official Ruby SDK for Melaya Agent Builder and Mobile Device Control"
|
|
12
|
+
spec.description = "Official Ruby SDK for Melaya Agent Builder and Mobile Device Control. Includes preview Melaya Trading namespaces that are not yet generally available."
|
|
14
13
|
spec.homepage = "https://melaya.org"
|
|
15
|
-
spec.license = "
|
|
14
|
+
spec.license = "Apache-2.0"
|
|
15
|
+
|
|
16
|
+
spec.metadata = {
|
|
17
|
+
"homepage_uri" => "https://melaya.org",
|
|
18
|
+
"source_code_uri" => "https://github.com/melaya-labs/melaya",
|
|
19
|
+
"changelog_uri" => "https://github.com/melaya-labs/melaya/blob/main/CHANGELOG.md"
|
|
20
|
+
}
|
|
16
21
|
|
|
17
22
|
spec.required_ruby_version = ">= 3.0.0"
|
|
18
23
|
|
|
19
|
-
spec.files = Dir["lib/**/*.rb", "README.md", "melaya.gemspec"]
|
|
24
|
+
spec.files = Dir["lib/**/*.rb", "README.md", "LICENSE", "melaya.gemspec"]
|
|
20
25
|
spec.require_paths = ["lib"]
|
|
21
26
|
|
|
22
27
|
# stdlib only — no runtime gem dependencies
|
metadata
CHANGED
|
@@ -1,40 +1,61 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: melaya
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.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-
|
|
11
|
+
date: 2026-07-24 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
|
-
description:
|
|
14
|
-
|
|
13
|
+
description: Official Ruby SDK for Melaya Agent Builder and Mobile Device Control.
|
|
14
|
+
Includes preview Melaya Trading namespaces that are not yet generally available.
|
|
15
15
|
email:
|
|
16
16
|
- sdk@melaya.org
|
|
17
17
|
executables: []
|
|
18
18
|
extensions: []
|
|
19
19
|
extra_rdoc_files: []
|
|
20
20
|
files:
|
|
21
|
+
- LICENSE
|
|
21
22
|
- README.md
|
|
22
23
|
- lib/melaya.rb
|
|
23
24
|
- lib/melaya/account.rb
|
|
25
|
+
- lib/melaya/accounts.rb
|
|
26
|
+
- lib/melaya/assistant.rb
|
|
27
|
+
- lib/melaya/auth.rb
|
|
24
28
|
- lib/melaya/backtest.rb
|
|
29
|
+
- lib/melaya/billing.rb
|
|
30
|
+
- lib/melaya/bugs.rb
|
|
31
|
+
- lib/melaya/connectors.rb
|
|
32
|
+
- lib/melaya/credentials.rb
|
|
25
33
|
- lib/melaya/errors.rb
|
|
34
|
+
- lib/melaya/evals.rb
|
|
35
|
+
- lib/melaya/events.rb
|
|
36
|
+
- lib/melaya/hitl.rb
|
|
26
37
|
- lib/melaya/http_client.rb
|
|
27
38
|
- lib/melaya/market.rb
|
|
39
|
+
- lib/melaya/namespaces.rb
|
|
40
|
+
- lib/melaya/phone.rb
|
|
41
|
+
- lib/melaya/pipelines.rb
|
|
42
|
+
- lib/melaya/projects.rb
|
|
43
|
+
- lib/melaya/runner.rb
|
|
28
44
|
- lib/melaya/sim.rb
|
|
29
45
|
- lib/melaya/strategies.rb
|
|
30
46
|
- lib/melaya/stream.rb
|
|
47
|
+
- lib/melaya/team.rb
|
|
48
|
+
- lib/melaya/templates.rb
|
|
31
49
|
- lib/melaya/trade.rb
|
|
32
50
|
- lib/melaya/version.rb
|
|
33
51
|
- melaya.gemspec
|
|
34
52
|
homepage: https://melaya.org
|
|
35
53
|
licenses:
|
|
36
|
-
-
|
|
37
|
-
metadata:
|
|
54
|
+
- Apache-2.0
|
|
55
|
+
metadata:
|
|
56
|
+
homepage_uri: https://melaya.org
|
|
57
|
+
source_code_uri: https://github.com/melaya-labs/melaya
|
|
58
|
+
changelog_uri: https://github.com/melaya-labs/melaya/blob/main/CHANGELOG.md
|
|
38
59
|
post_install_message:
|
|
39
60
|
rdoc_options: []
|
|
40
61
|
require_paths:
|
|
@@ -53,5 +74,5 @@ requirements: []
|
|
|
53
74
|
rubygems_version: 3.5.22
|
|
54
75
|
signing_key:
|
|
55
76
|
specification_version: 4
|
|
56
|
-
summary: Official Ruby SDK for
|
|
77
|
+
summary: Official Ruby SDK for Melaya Agent Builder and Mobile Device Control
|
|
57
78
|
test_files: []
|