hexel-sdk 0.1.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.
- package/LICENSE +21 -0
- package/Makefile +28 -0
- package/README.md +123 -0
- package/dist/_internal/auth.d.ts +17 -0
- package/dist/_internal/auth.d.ts.map +1 -0
- package/dist/_internal/auth.js +50 -0
- package/dist/_internal/auth.js.map +1 -0
- package/dist/_internal/client.d.ts +15 -0
- package/dist/_internal/client.d.ts.map +1 -0
- package/dist/_internal/client.js +22 -0
- package/dist/_internal/client.js.map +1 -0
- package/dist/_internal/http.d.ts +15 -0
- package/dist/_internal/http.d.ts.map +1 -0
- package/dist/_internal/http.js +59 -0
- package/dist/_internal/http.js.map +1 -0
- package/dist/compute/agent.d.ts +18 -0
- package/dist/compute/agent.d.ts.map +1 -0
- package/dist/compute/agent.js +40 -0
- package/dist/compute/agent.js.map +1 -0
- package/dist/compute/index.d.ts +13 -0
- package/dist/compute/index.d.ts.map +1 -0
- package/dist/compute/index.js +36 -0
- package/dist/compute/index.js.map +1 -0
- package/dist/compute/instance.d.ts +18 -0
- package/dist/compute/instance.d.ts.map +1 -0
- package/dist/compute/instance.js +40 -0
- package/dist/compute/instance.js.map +1 -0
- package/dist/compute/sandbox.d.ts +20 -0
- package/dist/compute/sandbox.d.ts.map +1 -0
- package/dist/compute/sandbox.js +44 -0
- package/dist/compute/sandbox.js.map +1 -0
- package/dist/compute/types.d.ts +272 -0
- package/dist/compute/types.d.ts.map +1 -0
- package/dist/compute/types.js +4 -0
- package/dist/compute/types.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/generator/generate.py +180 -0
- package/generator/ir.json +1545 -0
- package/generator/overrides.json +66 -0
- package/generator/parser.py +180 -0
- package/package.json +21 -0
- package/specs/agent-registry-api.json +1 -0
- package/specs/agentd-api.json +1364 -0
- package/specs/compute-api.json +1 -0
- package/src/_internal/auth.ts +56 -0
- package/src/_internal/client.ts +33 -0
- package/src/_internal/http.ts +61 -0
- package/src/compute/agent.ts +41 -0
- package/src/compute/index.ts +20 -0
- package/src/compute/instance.ts +41 -0
- package/src/compute/sandbox.ts +46 -0
- package/src/compute/types.ts +310 -0
- package/src/index.ts +3 -0
- package/tsconfig.json +17 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"components":{"schemas":{"iamclient.OAuthClient":{"properties":{"client_id":{"type":"string"},"created_at":{"type":"string"},"is_active":{"type":"boolean"},"name":{"type":"string"}},"type":"object"},"iamclient.OAuthClientResponse":{"properties":{"client_id":{"type":"string"},"client_secret":{"type":"string"},"name":{"type":"string"}},"type":"object"},"models.Agent":{"properties":{"config_hash":{"type":"string"},"created_at":{"type":"string"},"endpoint":{"type":"string"},"endpoint_name":{"type":"string"},"id":{"type":"string"},"image":{"type":"string"},"manifest":{"additionalProperties":{},"type":"object"},"metadata":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"registry_id":{"type":"string"},"skills":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tier":{"type":"string"},"token":{"type":"string"},"updated_at":{"type":"string"}},"type":"object"},"models.AgentVM":{"properties":{"allocated_at":{"type":"string"},"created_at":{"type":"string"},"expires_at":{"type":"string"},"id":{"type":"string"},"metadata":{"additionalProperties":{"type":"string"},"type":"object"},"released_at":{"type":"string"},"skills":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tier":{"type":"string"},"token":{"type":"string"},"ttl_seconds":{"type":"integer"}},"type":"object"},"models.AllocateRequest":{"properties":{"env":{"additionalProperties":{"type":"string"},"type":"object"},"metadata":{"additionalProperties":{"type":"string"},"type":"object"},"org_id":{"type":"string"},"secure_runtime":{"type":"string"},"skills":{"items":{"type":"string"},"type":"array"},"tier":{"type":"string"},"ttl_seconds":{"type":"integer"}},"required":["tier"],"type":"object"},"models.AllocateResponse":{"properties":{"endpoint":{"type":"string"},"expires_at":{"type":"string"},"skills_loaded":{"items":{"type":"string"},"type":"array"},"state":{"type":"string"},"tier":{"type":"string"},"token":{"type":"string"},"vm_id":{"type":"string"},"ws_url":{"type":"string"}},"type":"object"},"models.CreateSkillRequest":{"properties":{"content":{"type":"string"},"description":{"type":"string"},"name":{"type":"string"},"resources":{"additionalProperties":{"type":"string"},"description":"Resources are files written into /workspace/skills/\u003cname\u003e/.\nInclude \"requirements.txt\" to install Python dependencies at VM boot.","type":"object"}},"required":["content","name"],"type":"object"},"models.ErrorResponse":{"properties":{"code":{"type":"integer"},"error_code":{"type":"string"},"message":{"type":"string"}},"type":"object"},"models.PoolConfig":{"properties":{"default_skills":{"items":{"type":"string"},"type":"array"},"default_tier":{"type":"string"},"idle_ttl_seconds":{"type":"integer"},"max_total":{"type":"integer"},"max_vm_ttl_seconds":{"type":"integer"},"max_warm":{"type":"integer"},"min_warm":{"type":"integer"},"recycle":{"type":"boolean"},"scale_up_threshold":{"description":"ScaleUpThreshold: when allocated/(warm+allocated) exceeds this ratio (0.0–1.0),\nproactively create more warm pods. Default 0.7 (70% utilisation triggers scale-up).","type":"number"}},"type":"object"},"models.PoolStatus":{"properties":{"allocated":{"type":"integer"},"by_tier":{"additionalProperties":{"type":"integer"},"type":"object"},"total":{"type":"integer"},"warm":{"type":"integer"}},"type":"object"},"models.ReleaseRequest":{"properties":{"recycle":{"type":"boolean"}},"type":"object"},"models.RenewRequest":{"properties":{"ttl_seconds":{"type":"integer"}},"required":["ttl_seconds"],"type":"object"},"models.Skill":{"properties":{"content":{"type":"string"},"content_hash":{"type":"string"},"created_at":{"type":"string"},"description":{"type":"string"},"name":{"type":"string"},"resources":{"additionalProperties":{"type":"string"},"type":"object"},"updated_at":{"type":"string"}},"type":"object"},"models.UsageRecord":{"properties":{"duration_seconds":{"type":"integer"},"ended_at":{"type":"string"},"reason":{"type":"string"},"started_at":{"type":"string"},"tier":{"type":"string"},"vm_id":{"type":"string"}},"type":"object"},"models.UsageSummary":{"properties":{"by_tier":{"additionalProperties":{"type":"integer"},"type":"object"},"period_end":{"type":"string"},"period_start":{"type":"string"},"total_seconds":{"type":"integer"},"vm_count":{"type":"integer"}},"type":"object"}},"securitySchemes":{"BearerAuth":{"description":"STS access token. Obtain via POST https://sts.hexelstudio.com/token with X-API-Key header.","in":"header","name":"Authorization","type":"apiKey"}}},"info":{"contact":{},"description":"On-demand Agent VM platform — pre-warmed execution environments for AI agents with skills registry, code interpreter, and real-time SSE streaming.","title":"Hexel Compute API","version":"1.0.0"},"openapi":"3.0.1","paths":{"/compute/v1/access/clients":{"get":{"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/iamclient.OAuthClient"},"type":"array"}}},"description":"OK"}},"security":[{"BearerAuth":[]}],"summary":"List access clients","tags":["access"]},"post":{"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Client name","required":true,"x-originalParamName":"request"},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/iamclient.OAuthClientResponse"}}},"description":"Created"}},"security":[{"BearerAuth":[]}],"summary":"Create access client","tags":["access"]}},"/compute/v1/access/clients/{client_id}":{"delete":{"parameters":[{"description":"Client ID","in":"path","name":"client_id","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"No Content"}},"security":[{"BearerAuth":[]}],"summary":"Revoke access client","tags":["access"]}},"/compute/v1/agents/{agent_id}/deploy":{"post":{"description":"Creates a new deployment from a registered agent. Returns a deployment_id to use for all subsequent operations.","parameters":[{"description":"Registry Agent ID","in":"path","name":"agent_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Deploy options","x-originalParamName":"request"},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.Agent"}}},"description":"OK"}},"security":[{"BearerAuth":[]}],"summary":"Deploy an agent from the registry","tags":["agents"]}},"/compute/v1/deployments":{"get":{"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/models.Agent"},"type":"array"}}},"description":"OK"}},"security":[{"BearerAuth":[]}],"summary":"List all deployments","tags":["deployments"]}},"/compute/v1/deployments/{deployment_id}":{"delete":{"parameters":[{"description":"Deployment ID","in":"path","name":"deployment_id","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"No Content"}},"security":[{"BearerAuth":[]}],"summary":"Delete a deployment","tags":["deployments"]},"get":{"parameters":[{"description":"Deployment ID","in":"path","name":"deployment_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.Agent"}}},"description":"OK"}},"security":[{"BearerAuth":[]}],"summary":"Get deployment by ID","tags":["deployments"]}},"/compute/v1/deployments/{deployment_id}/redeploy":{"post":{"parameters":[{"description":"Deployment ID","in":"path","name":"deployment_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.Agent"}}},"description":"OK"}},"security":[{"BearerAuth":[]}],"summary":"Redeploy (stop + start)","tags":["deployments"]}},"/compute/v1/deployments/{deployment_id}/stop":{"post":{"parameters":[{"description":"Deployment ID","in":"path","name":"deployment_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.Agent"}}},"description":"OK"}},"security":[{"BearerAuth":[]}],"summary":"Stop a deployment","tags":["deployments"]}},"/compute/v1/pool/config":{"get":{"description":"Returns the current pool configuration parameters","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.PoolConfig"}}},"description":"OK"}},"security":[{"BearerAuth":[]}],"summary":"Get pool configuration","tags":["pool"]},"put":{"description":"Updates the pool configuration parameters","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.PoolConfig"}}},"description":"Pool configuration","required":true,"x-originalParamName":"request"},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.PoolConfig"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorResponse"}}},"description":"Bad Request"}},"security":[{"BearerAuth":[]}],"summary":"Update pool configuration","tags":["pool"]}},"/compute/v1/pool/status":{"get":{"description":"Returns current pool statistics including warm, allocated, and total counts","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.PoolStatus"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"BearerAuth":[]}],"summary":"Get VM pool status","tags":["pool"]}},"/compute/v1/skills":{"get":{"description":"Returns all registered skill definitions","operationId":"listSkills","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/models.Skill"},"type":"array"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"BearerAuth":[]}],"summary":"List all skills","tags":["skills"]},"post":{"description":"Registers a new skill definition with content hashing","operationId":"createSkill","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.CreateSkillRequest"}}},"description":"Skill definition","required":true,"x-originalParamName":"request"},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.Skill"}}},"description":"Created"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"BearerAuth":[]}],"summary":"Create a new skill","tags":["skills"]}},"/compute/v1/skills/{name}":{"delete":{"description":"Removes a skill definition by name","operationId":"deleteSkill","parameters":[{"description":"Skill name","in":"path","name":"name","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"No Content"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"BearerAuth":[]}],"summary":"Delete a skill","tags":["skills"]},"get":{"description":"Returns a single skill definition by name","operationId":"getSkill","parameters":[{"description":"Skill name","in":"path","name":"name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.Skill"}}},"description":"OK"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorResponse"}}},"description":"Not Found"}},"security":[{"BearerAuth":[]}],"summary":"Get skill by name","tags":["skills"]},"put":{"description":"Updates an existing skill definition and recomputes content hash","operationId":"updateSkill","parameters":[{"description":"Skill name","in":"path","name":"name","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.CreateSkillRequest"}}},"description":"Updated skill definition","required":true,"x-originalParamName":"request"},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.Skill"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorResponse"}}},"description":"Bad Request"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"BearerAuth":[]}],"summary":"Update a skill","tags":["skills"]}},"/compute/v1/usage":{"get":{"description":"Returns VM usage records for the caller's org, optionally filtered by date range and tier","operationId":"listUsage","parameters":[{"description":"Workspace ID","in":"header","name":"X-Workspace-Id","required":true,"schema":{"type":"string"}},{"description":"Environment ID","in":"header","name":"X-Environment-Id","required":true,"schema":{"type":"string"}},{"description":"Start date (YYYY-MM-DD), default 30 days ago","in":"query","name":"from","schema":{"type":"string"}},{"description":"End date (YYYY-MM-DD), default today","in":"query","name":"to","schema":{"type":"string"}},{"description":"Filter by tier","in":"query","name":"tier","schema":{"type":"string"}},{"description":"Max records (default 100)","in":"query","name":"limit","schema":{"type":"integer"}},{"description":"Offset for pagination","in":"query","name":"offset","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/models.UsageRecord"},"type":"array"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"BearerAuth":[]}],"summary":"List VM usage records","tags":["usage"]}},"/compute/v1/usage/summary":{"get":{"description":"Returns aggregated VM-seconds consumed by tier for the current calendar month","operationId":"getUsageSummary","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.UsageSummary"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"BearerAuth":[]}],"summary":"Get usage summary for current billing period","tags":["usage"]}},"/compute/v1/vms":{"get":{"description":"Returns VMs scoped to the caller's org","operationId":"listVMs","parameters":[{"description":"Filter by state","in":"query","name":"state","schema":{"type":"string"}},{"description":"Filter by tier","in":"query","name":"tier","schema":{"type":"string"}},{"description":"Limit results","in":"query","name":"limit","schema":{"type":"integer"}},{"description":"Offset results","in":"query","name":"offset","schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/models.AgentVM"},"type":"array"}}},"description":"OK"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorResponse"}}},"description":"Internal Server Error"}},"security":[{"BearerAuth":[]}],"summary":"List Agent VMs","tags":["vms"]}},"/compute/v1/vms/allocate":{"post":{"description":"Allocates a VM from the pool or creates a new one for the requesting org","operationId":"allocateVM","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.AllocateRequest"}}},"description":"Allocation parameters","required":true,"x-originalParamName":"request"},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.AllocateResponse"}}},"description":"Created"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorResponse"}}},"description":"Bad Request"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorResponse"}}},"description":"No VMs available, retry shortly"}},"security":[{"BearerAuth":[]}],"summary":"Allocate a new Agent VM","tags":["vms"]}},"/compute/v1/vms/{id}":{"delete":{"operationId":"deleteVM","parameters":[{"description":"VM ID (UUID)","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"No Content"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorResponse"}}},"description":"Not Found"}},"security":[{"BearerAuth":[]}],"summary":"Delete Agent VM","tags":["vms"]},"get":{"operationId":"getVM","parameters":[{"description":"VM ID (UUID)","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.AgentVM"}}},"description":"OK"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorResponse"}}},"description":"Not Found"}},"security":[{"BearerAuth":[]}],"summary":"Get Agent VM by ID","tags":["vms"]}},"/compute/v1/vms/{id}/endpoint":{"get":{"operationId":"getVMEndpoint","parameters":[{"description":"VM ID (UUID)","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"additionalProperties":{"type":"string"},"type":"object"}}},"description":"OK"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorResponse"}}},"description":"Not Found"}},"security":[{"BearerAuth":[]}],"summary":"Get Agent VM endpoint","tags":["vms"]}},"/compute/v1/vms/{id}/execute":{"post":{"description":"Runs code or shell commands in an allocated sandbox VM","parameters":[{"description":"VM ID","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}},"summary":"Execute code in VM","tags":["vms"]}},"/compute/v1/vms/{id}/r/{path}":{"delete":{"description":"Forwards any request to the runtime inside the VM. Token is injected automatically.","parameters":[{"description":"VM ID (UUID)","in":"path","name":"id","required":true,"schema":{"type":"string"}},{"description":"path e.g. v1/agents/execute","in":"path","name":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorResponse"}}},"description":"Not Found"},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorResponse"}}},"description":"Bad Gateway"}},"security":[{"BearerAuth":[]}],"summary":"Forward request to VM","tags":["vms"]},"get":{"description":"Forwards any request to the runtime inside the VM. Token is injected automatically.","parameters":[{"description":"VM ID (UUID)","in":"path","name":"id","required":true,"schema":{"type":"string"}},{"description":"path e.g. v1/agents/execute","in":"path","name":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorResponse"}}},"description":"Not Found"},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorResponse"}}},"description":"Bad Gateway"}},"security":[{"BearerAuth":[]}],"summary":"Forward request to VM","tags":["vms"]},"post":{"description":"Forwards any request to the runtime inside the VM. Token is injected automatically.","parameters":[{"description":"VM ID (UUID)","in":"path","name":"id","required":true,"schema":{"type":"string"}},{"description":"path e.g. v1/agents/execute","in":"path","name":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorResponse"}}},"description":"Not Found"},"502":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorResponse"}}},"description":"Bad Gateway"}},"security":[{"BearerAuth":[]}],"summary":"Forward request to VM","tags":["vms"]}},"/compute/v1/vms/{id}/release":{"post":{"operationId":"releaseVM","parameters":[{"description":"VM ID (UUID)","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ReleaseRequest"}}},"description":"Release options","required":true,"x-originalParamName":"request"},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.AgentVM"}}},"description":"OK"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorResponse"}}},"description":"Not Found"}},"security":[{"BearerAuth":[]}],"summary":"Release Agent VM","tags":["vms"]}},"/compute/v1/vms/{id}/renew":{"post":{"operationId":"renewVM","parameters":[{"description":"VM ID (UUID)","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.RenewRequest"}}},"description":"Renew parameters","required":true,"x-originalParamName":"request"},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.AgentVM"}}},"description":"OK"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/models.ErrorResponse"}}},"description":"Not Found"}},"security":[{"BearerAuth":[]}],"summary":"Renew Agent VM TTL","tags":["vms"]}},"/internal/agents/{id}/manifest":{"patch":{"description":"Called by agentd sidecar to report agent capabilities and endpoints","parameters":[{"description":"Agent/VM ID","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Manifest","required":true,"x-originalParamName":"body"},"responses":{"204":{"description":"No Content"}},"summary":"Update manifest","tags":["internal"]}},"/internal/vms/{id}/manifest":{"patch":{"description":"Called by agentd sidecar to report agent capabilities and endpoints","parameters":[{"description":"Agent/VM ID","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Manifest","required":true,"x-originalParamName":"body"},"responses":{"204":{"description":"No Content"}},"summary":"Update manifest","tags":["internal"]}}},"servers":[{"url":"https://api.hexelstudio.com/"}]}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/** Token management — API key and client_credentials auth flows. */
|
|
2
|
+
|
|
3
|
+
interface AuthConfig {
|
|
4
|
+
apiKey?: string;
|
|
5
|
+
clientId?: string;
|
|
6
|
+
clientSecret?: string;
|
|
7
|
+
stsUrl: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export class AuthManager {
|
|
11
|
+
private accessToken: string | null = null;
|
|
12
|
+
private expiresAt = 0;
|
|
13
|
+
private config: AuthConfig;
|
|
14
|
+
|
|
15
|
+
constructor(config: AuthConfig) {
|
|
16
|
+
if (!config.apiKey && !(config.clientId && config.clientSecret)) {
|
|
17
|
+
throw new Error("Provide apiKey or (clientId + clientSecret)");
|
|
18
|
+
}
|
|
19
|
+
this.config = config;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async getToken(): Promise<string> {
|
|
23
|
+
if (this.accessToken && Date.now() / 1000 < this.expiresAt - 30) {
|
|
24
|
+
return this.accessToken;
|
|
25
|
+
}
|
|
26
|
+
await this.refresh();
|
|
27
|
+
return this.accessToken!;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async refresh(): Promise<void> {
|
|
31
|
+
const url = `${this.config.stsUrl}/token`;
|
|
32
|
+
let resp: Response;
|
|
33
|
+
|
|
34
|
+
if (this.config.apiKey) {
|
|
35
|
+
resp = await fetch(url, {
|
|
36
|
+
method: "POST",
|
|
37
|
+
headers: { "X-API-Key": this.config.apiKey },
|
|
38
|
+
});
|
|
39
|
+
} else {
|
|
40
|
+
resp = await fetch(url, {
|
|
41
|
+
method: "POST",
|
|
42
|
+
headers: { "Content-Type": "application/json" },
|
|
43
|
+
body: JSON.stringify({
|
|
44
|
+
grant_type: "client_credentials",
|
|
45
|
+
client_id: this.config.clientId,
|
|
46
|
+
client_secret: this.config.clientSecret,
|
|
47
|
+
}),
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (!resp.ok) throw new Error(`STS token exchange failed: ${resp.status}`);
|
|
52
|
+
const data: any = await resp.json();
|
|
53
|
+
this.accessToken = data.access_token;
|
|
54
|
+
this.expiresAt = Date.now() / 1000 + (data.expires_in || 900);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/** Main Hexel client. */
|
|
2
|
+
|
|
3
|
+
import { AuthManager } from "./auth";
|
|
4
|
+
import { HttpClient } from "./http";
|
|
5
|
+
import { ComputeClient } from "../compute";
|
|
6
|
+
|
|
7
|
+
export interface HexelConfig {
|
|
8
|
+
apiKey?: string;
|
|
9
|
+
clientId?: string;
|
|
10
|
+
clientSecret?: string;
|
|
11
|
+
baseUrl?: string;
|
|
12
|
+
stsUrl?: string;
|
|
13
|
+
timeout?: number;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export class Hexel {
|
|
17
|
+
readonly compute: ComputeClient;
|
|
18
|
+
|
|
19
|
+
constructor(config: HexelConfig) {
|
|
20
|
+
const auth = new AuthManager({
|
|
21
|
+
apiKey: config.apiKey,
|
|
22
|
+
clientId: config.clientId,
|
|
23
|
+
clientSecret: config.clientSecret,
|
|
24
|
+
stsUrl: config.stsUrl || "https://sts.hexelstudio.com",
|
|
25
|
+
});
|
|
26
|
+
const http = new HttpClient(
|
|
27
|
+
config.baseUrl || "https://compute.hexelstudio.com",
|
|
28
|
+
auth,
|
|
29
|
+
config.timeout || 30000
|
|
30
|
+
);
|
|
31
|
+
this.compute = new ComputeClient(http);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/** HTTP request pipeline — retries, auth refresh, backoff. */
|
|
2
|
+
|
|
3
|
+
import { AuthManager } from "./auth";
|
|
4
|
+
|
|
5
|
+
const RETRY_STATUS = new Set([429, 500, 502, 503]);
|
|
6
|
+
const MAX_RETRIES = 3;
|
|
7
|
+
|
|
8
|
+
export class HttpClient {
|
|
9
|
+
constructor(
|
|
10
|
+
private baseUrl: string,
|
|
11
|
+
private auth: AuthManager,
|
|
12
|
+
private timeout: number = 30000
|
|
13
|
+
) {
|
|
14
|
+
this.baseUrl = baseUrl.replace(/\/$/, "");
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async request(method: string, path: string, data?: unknown): Promise<unknown> {
|
|
18
|
+
const url = `${this.baseUrl}${path}`;
|
|
19
|
+
|
|
20
|
+
for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
|
|
21
|
+
const token = await this.auth.getToken();
|
|
22
|
+
const headers: Record<string, string> = {
|
|
23
|
+
Authorization: `Bearer ${token}`,
|
|
24
|
+
"Content-Type": "application/json",
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const init: RequestInit = { method, headers };
|
|
28
|
+
if (data && method !== "GET") {
|
|
29
|
+
init.body = JSON.stringify(data);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const resp = await fetch(url, init);
|
|
33
|
+
|
|
34
|
+
if (resp.status === 401 && attempt === 0) {
|
|
35
|
+
await this.auth.refresh();
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
if (RETRY_STATUS.has(resp.status) && attempt < MAX_RETRIES) {
|
|
39
|
+
await new Promise((r) => setTimeout(r, 500 * 2 ** attempt));
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (!resp.ok) {
|
|
43
|
+
const body = await resp.text().catch(() => "");
|
|
44
|
+
throw new Error(`${method} ${path} failed: ${resp.status} ${body}`);
|
|
45
|
+
}
|
|
46
|
+
const text = await resp.text();
|
|
47
|
+
try {
|
|
48
|
+
return JSON.parse(text);
|
|
49
|
+
} catch {
|
|
50
|
+
return text;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
throw new Error(`${method} ${path} failed after ${MAX_RETRIES} retries`);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
get(path: string) { return this.request("GET", path); }
|
|
57
|
+
post(path: string, data?: unknown) { return this.request("POST", path, data); }
|
|
58
|
+
put(path: string, data?: unknown) { return this.request("PUT", path, data); }
|
|
59
|
+
delete(path: string) { return this.request("DELETE", path); }
|
|
60
|
+
patch(path: string, data?: unknown) { return this.request("PATCH", path, data); }
|
|
61
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// Generated by hexel-sdk-generator. Do not edit manually.
|
|
2
|
+
import { HttpClient } from "../_internal/http";
|
|
3
|
+
|
|
4
|
+
export class AgentClient {
|
|
5
|
+
constructor(private http: HttpClient) {}
|
|
6
|
+
|
|
7
|
+
/** Register a new agent in the catalog */
|
|
8
|
+
async register(data: Record<string, unknown>): Promise<unknown> {
|
|
9
|
+
const resp = await this.http.post("/registry/v1/agents", data);
|
|
10
|
+
return resp;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** List agents with optional filters */
|
|
14
|
+
async list(): Promise<unknown> {
|
|
15
|
+
const resp = await this.http.get("/registry/v1/agents");
|
|
16
|
+
return resp;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Get agent by ID */
|
|
20
|
+
async get(id: string): Promise<unknown> {
|
|
21
|
+
const resp = await this.http.get("/registry/v1/agents/{id}".replace("{id}", id));
|
|
22
|
+
return resp;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Update agent fields */
|
|
26
|
+
async update(id: string, data: Record<string, unknown>): Promise<unknown> {
|
|
27
|
+
const resp = await this.http.put("/registry/v1/agents/{id}".replace("{id}", id), data);
|
|
28
|
+
return resp;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Delete agent by ID */
|
|
32
|
+
async delete(id: string): Promise<void> {
|
|
33
|
+
const resp = await this.http.delete("/registry/v1/agents/{id}".replace("{id}", id));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Find agents matching given capabilities */
|
|
37
|
+
async search(): Promise<unknown> {
|
|
38
|
+
const resp = await this.http.get("/registry/v1/agents/search");
|
|
39
|
+
return resp;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Generated by hexel-sdk-generator. Do not edit manually.
|
|
2
|
+
import { HttpClient } from "../_internal/http";
|
|
3
|
+
import { SandboxClient } from "./sandbox";
|
|
4
|
+
import { AgentClient } from "./agent";
|
|
5
|
+
import { InstanceClient } from "./instance";
|
|
6
|
+
|
|
7
|
+
export class ComputeClient {
|
|
8
|
+
readonly sandbox: SandboxClient;
|
|
9
|
+
readonly agent: AgentClient;
|
|
10
|
+
readonly instance: InstanceClient;
|
|
11
|
+
|
|
12
|
+
constructor(http: HttpClient) {
|
|
13
|
+
this.sandbox = new SandboxClient(http);
|
|
14
|
+
this.agent = new AgentClient(http);
|
|
15
|
+
this.instance = new InstanceClient(http);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export { SandboxClient, AgentClient, InstanceClient };
|
|
20
|
+
export * from "./types";
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// Generated by hexel-sdk-generator. Do not edit manually.
|
|
2
|
+
import { HttpClient } from "../_internal/http";
|
|
3
|
+
|
|
4
|
+
export class InstanceClient {
|
|
5
|
+
constructor(private http: HttpClient) {}
|
|
6
|
+
|
|
7
|
+
/** Creates a new deployment from a registered agent. Returns a deployment_id to use for all subsequent operations. */
|
|
8
|
+
async deploy(agentId: string): Promise<unknown> {
|
|
9
|
+
const resp = await this.http.post("/compute/v1/agents/{agent_id}/deploy".replace("{agent_id}", agentId));
|
|
10
|
+
return resp;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** List all deployments */
|
|
14
|
+
async list(): Promise<unknown> {
|
|
15
|
+
const resp = await this.http.get("/compute/v1/deployments");
|
|
16
|
+
return resp;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Get deployment by ID */
|
|
20
|
+
async get(deploymentId: string): Promise<unknown> {
|
|
21
|
+
const resp = await this.http.get("/compute/v1/deployments/{deployment_id}".replace("{deployment_id}", deploymentId));
|
|
22
|
+
return resp;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Delete a deployment */
|
|
26
|
+
async delete(deploymentId: string): Promise<void> {
|
|
27
|
+
const resp = await this.http.delete("/compute/v1/deployments/{deployment_id}".replace("{deployment_id}", deploymentId));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Stop a deployment */
|
|
31
|
+
async stop(deploymentId: string): Promise<unknown> {
|
|
32
|
+
const resp = await this.http.post("/compute/v1/deployments/{deployment_id}/stop".replace("{deployment_id}", deploymentId));
|
|
33
|
+
return resp;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Redeploy (stop + start) */
|
|
37
|
+
async redeploy(deploymentId: string): Promise<unknown> {
|
|
38
|
+
const resp = await this.http.post("/compute/v1/deployments/{deployment_id}/redeploy".replace("{deployment_id}", deploymentId));
|
|
39
|
+
return resp;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// Generated by hexel-sdk-generator. Do not edit manually.
|
|
2
|
+
import { HttpClient } from "../_internal/http";
|
|
3
|
+
|
|
4
|
+
export class SandboxClient {
|
|
5
|
+
constructor(private http: HttpClient) {}
|
|
6
|
+
|
|
7
|
+
/** Allocates a VM from the pool or creates a new one for the requesting org */
|
|
8
|
+
async create(data: Record<string, unknown>): Promise<unknown> {
|
|
9
|
+
const resp = await this.http.post("/compute/v1/vms/allocate", data);
|
|
10
|
+
return resp;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** Returns VMs scoped to the caller's org */
|
|
14
|
+
async list(): Promise<unknown> {
|
|
15
|
+
const resp = await this.http.get("/compute/v1/vms");
|
|
16
|
+
return resp;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Get Agent VM by ID */
|
|
20
|
+
async get(id: string): Promise<unknown> {
|
|
21
|
+
const resp = await this.http.get("/compute/v1/vms/{id}".replace("{id}", id));
|
|
22
|
+
return resp;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Delete Agent VM */
|
|
26
|
+
async delete(id: string): Promise<void> {
|
|
27
|
+
const resp = await this.http.delete("/compute/v1/vms/{id}".replace("{id}", id));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Release Agent VM */
|
|
31
|
+
async release(id: string, data: Record<string, unknown>): Promise<unknown> {
|
|
32
|
+
const resp = await this.http.post("/compute/v1/vms/{id}/release".replace("{id}", id), data);
|
|
33
|
+
return resp;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Renew Agent VM TTL */
|
|
37
|
+
async renew(id: string, data: Record<string, unknown>): Promise<unknown> {
|
|
38
|
+
const resp = await this.http.post("/compute/v1/vms/{id}/renew".replace("{id}", id), data);
|
|
39
|
+
return resp;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Runs code or shell commands in an allocated sandbox VM */
|
|
43
|
+
async execute(id: string): Promise<void> {
|
|
44
|
+
const resp = await this.http.post("/compute/v1/vms/{id}/execute".replace("{id}", id));
|
|
45
|
+
}
|
|
46
|
+
}
|