Files
sentryagent-idp/sdk/src/services/agents.ts
SentryAgent.ai Developer aa5167835e feat: Phase 1 P1 — Dockerfile, AGNTCY alignment docs, Node.js SDK
Three remaining Phase 1 P1 deliverables:

1. Dockerfile — multi-stage build (builder + production), node:18-alpine,
   non-root USER node, .dockerignore excluding secrets and dev artifacts

2. AGNTCY alignment docs (docs/agntcy/) — README and alignment.md mapping
   all 6 AGNTCY domains to AgentIdP features with Phase 2/3 pending items noted

3. Node.js SDK (@sentryagent/idp-sdk) — TypeScript strict, zero any, native
   fetch (Node 18+), TokenManager with 60s auto-refresh, service clients for
   all 14 endpoints (agents, credentials, tokens, audit), AgentIdPError typed
   error hierarchy, full README

All three changes tracked under openspec/changes/ with tasks marked complete.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 14:46:53 +00:00

91 lines
2.3 KiB
TypeScript

import { request } from '../request.js';
import type {
Agent,
RegisterAgentRequest,
UpdateAgentRequest,
ListAgentsParams,
PaginatedAgents,
} from '../types.js';
/**
* Client for the Agent Registry service.
* Covers all agent CRUD operations: register, list, get, update, decommission.
*/
export class AgentRegistryClient {
constructor(
private readonly baseUrl: string,
private readonly getToken: () => Promise<string>,
) {}
/**
* Register a new AI agent.
* Returns the created agent record including its agentId and agentSecret.
*/
async registerAgent(params: RegisterAgentRequest): Promise<Agent> {
const token = await this.getToken();
return request<Agent>(this.baseUrl, {
method: 'POST',
path: '/api/v1/agents',
token,
body: params,
});
}
/**
* List all registered agents with optional filters and pagination.
*/
async listAgents(params: ListAgentsParams = {}): Promise<PaginatedAgents> {
const token = await this.getToken();
return request<PaginatedAgents>(this.baseUrl, {
method: 'GET',
path: '/api/v1/agents',
token,
query: {
status: params.status,
agentType: params.agentType,
page: params.page,
limit: params.limit,
},
});
}
/**
* Get a single agent by its agentId.
*/
async getAgent(agentId: string): Promise<Agent> {
const token = await this.getToken();
return request<Agent>(this.baseUrl, {
method: 'GET',
path: `/api/v1/agents/${agentId}`,
token,
});
}
/**
* Update mutable fields on an existing agent (name, description, capabilities, metadata).
* Returns the updated agent record.
*/
async updateAgent(agentId: string, params: UpdateAgentRequest): Promise<Agent> {
const token = await this.getToken();
return request<Agent>(this.baseUrl, {
method: 'PATCH',
path: `/api/v1/agents/${agentId}`,
token,
body: params,
});
}
/**
* Decommission an agent. This is irreversible — the agent can no longer
* authenticate or obtain tokens after decommission.
*/
async decommissionAgent(agentId: string): Promise<void> {
const token = await this.getToken();
return request<void>(this.baseUrl, {
method: 'DELETE',
path: `/api/v1/agents/${agentId}`,
token,
});
}
}