@agentforge-io/sdk-server 4.0.18

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.
@@ -0,0 +1,72 @@
1
+ import { AgentsResource } from './resources/agents';
2
+ import { ChatResource } from './resources/chat';
3
+ import { ConnectorsResource } from './resources/connectors';
4
+ import { SecretsResource } from './resources/secrets';
5
+ import { ToolsResource } from './resources/tools';
6
+ export interface AgentForgeClientOptions {
7
+ /** Platform base URL — e.g. http://localhost:3032 in dev. */
8
+ baseURL: string;
9
+ /** ChatToken scoped to a specific agent. */
10
+ chatToken?: string;
11
+ /** ak_live_... API key scoped to the tenant. */
12
+ apiKey?: string;
13
+ /** Override fetch (for testing or custom transports). */
14
+ fetch?: typeof fetch;
15
+ /** Default request timeout in ms. Applied to every HTTP call unless
16
+ * overridden per-call (e.g. streaming calls disable it entirely). */
17
+ timeoutMs?: number;
18
+ }
19
+ export interface RequestOptions {
20
+ /** Force ak_live_ auth even when the client also has a chatToken. Required
21
+ * for tenant-admin surfaces that reject ChatToken auth outright. */
22
+ forceApiKey?: boolean;
23
+ /** Extra headers merged in AFTER the resolved auth header — e.g. the HMAC
24
+ * signature headers a tool-callback response needs alongside its normal
25
+ * ChatToken auth. */
26
+ headers?: Record<string, string>;
27
+ /** Pre-serialized body sent as-is (no JSON.stringify). Needed when the
28
+ * caller already hashed/signed this EXACT string and re-serializing the
29
+ * same object could (in principle) produce a different byte sequence. */
30
+ rawBody?: string;
31
+ /** ms before the request aborts. `null` disables the timeout entirely —
32
+ * used for chat streaming, where a tool-calling turn can legitimately
33
+ * run long. Defaults to the client's `timeoutMs`. */
34
+ timeoutMs?: number | null;
35
+ }
36
+ export declare class AgentForgeClient {
37
+ readonly baseURL: string;
38
+ private readonly chatToken?;
39
+ private readonly apiKey?;
40
+ private readonly fetchImpl;
41
+ private readonly timeoutMs;
42
+ readonly agents: AgentsResource;
43
+ readonly chat: ChatResource;
44
+ readonly connectors: ConnectorsResource;
45
+ readonly secrets: SecretsResource;
46
+ readonly tools: ToolsResource;
47
+ constructor(opts: AgentForgeClientOptions);
48
+ authHeaders(): Record<string, string>;
49
+ getApiKey(): string | undefined;
50
+ getChatToken(): string | undefined;
51
+ /** Como `getApiKey()`, pero tira si el cliente no fue construido con una
52
+ * ak_live_ — usado por resources cuya superficie SIEMPRE requiere apiKey
53
+ * (tenant-admin), regardless de si también hay chatToken. */
54
+ requireApiKey(): string;
55
+ private resolveAuthHeaders;
56
+ /**
57
+ * Primitiva de bajo nivel: hace el fetch, mapea status codes a errores
58
+ * tipados, y devuelve la `Response` cruda SIN parsear el body — así sirve
59
+ * tanto para el helper JSON (`request`) como para streaming (`requestStream`)
60
+ * y para respuestas 204 sin body (`tools.respondToCallback`).
61
+ */
62
+ requestRaw(method: string, path: string, opts?: RequestOptions): Promise<Response>;
63
+ request<T>(method: string, path: string, body?: unknown, opts?: RequestOptions): Promise<T>;
64
+ /** Como `request()`, pero fuerza auth ak_live_ — para superficies
65
+ * tenant-admin (connector-resources, connectors/oauth/*-for-tenant) que
66
+ * rechazan ChatToken aunque el cliente tenga uno configurado también. */
67
+ requestWithApiKey<T>(method: string, path: string, body?: unknown): Promise<T>;
68
+ /** Abre un stream SSE. Sin timeout (`timeoutMs: null`) — una llamada con
69
+ * varias rondas de tool-calling puede tardar más que el default de 30s.
70
+ * El caller consume `res.body` como ReadableStream<Uint8Array>. */
71
+ requestStream(method: string, path: string, body?: unknown): Promise<Response>;
72
+ }
package/dist/client.js ADDED
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AgentForgeClient = void 0;
4
+ // AgentForgeClient — punto de entrada del SDK.
5
+ //
6
+ // Uso:
7
+ // const af = new AgentForgeClient({
8
+ // baseURL: 'http://localhost:3032',
9
+ // chatToken: process.env.AGENTFORGE_CHAT_TOKEN,
10
+ // });
11
+ // const agent = await af.agents.me();
12
+ //
13
+ // Auth: la app cliente elige UNO de dos modos:
14
+ // - `chatToken`: scoped a un agent específico (recomendado para apps
15
+ // que consumen UN agent del tenant). Header X-Chat-Token.
16
+ // - `apiKey`: ak_live_... scoped al tenant (futuro v2).
17
+ //
18
+ // Si ambos están presentes, chatToken gana (es el más específico) — EXCEPTO
19
+ // en superficies tenant-admin (connectors resource picker, OAuth
20
+ // authorize-for-tenant) que el server rechaza explícitamente si el caller
21
+ // solo tiene ChatToken. Esas pasan `{ forceApiKey: true }` a `request()`.
22
+ const errors_1 = require("./errors");
23
+ const agents_1 = require("./resources/agents");
24
+ const chat_1 = require("./resources/chat");
25
+ const connectors_1 = require("./resources/connectors");
26
+ const secrets_1 = require("./resources/secrets");
27
+ const tools_1 = require("./resources/tools");
28
+ class AgentForgeClient {
29
+ constructor(opts) {
30
+ if (!opts.baseURL) {
31
+ throw new Error('AgentForgeClient: baseURL is required');
32
+ }
33
+ if (!opts.chatToken && !opts.apiKey) {
34
+ throw new Error('AgentForgeClient: either chatToken or apiKey is required');
35
+ }
36
+ this.baseURL = opts.baseURL.replace(/\/$/, '');
37
+ this.chatToken = opts.chatToken;
38
+ this.apiKey = opts.apiKey;
39
+ this.fetchImpl = opts.fetch ?? fetch;
40
+ this.timeoutMs = opts.timeoutMs ?? 30000;
41
+ this.agents = new agents_1.AgentsResource(this);
42
+ this.chat = new chat_1.ChatResource(this);
43
+ this.connectors = new connectors_1.ConnectorsResource(this);
44
+ this.secrets = new secrets_1.SecretsResource(this);
45
+ this.tools = new tools_1.ToolsResource(this);
46
+ }
47
+ // Auth headers derivados del modo. ChatToken gana si ambos están presentes.
48
+ authHeaders() {
49
+ if (this.chatToken)
50
+ return { 'X-Chat-Token': this.chatToken };
51
+ if (this.apiKey)
52
+ return { Authorization: `Bearer ${this.apiKey}` };
53
+ return {};
54
+ }
55
+ // Expone el modo auth para que resources puedan tomar decisiones (ej. chat
56
+ // proxy necesita la ak_live_ explícita en x-api-key — no ChatToken).
57
+ getApiKey() {
58
+ return this.apiKey;
59
+ }
60
+ getChatToken() {
61
+ return this.chatToken;
62
+ }
63
+ /** Como `getApiKey()`, pero tira si el cliente no fue construido con una
64
+ * ak_live_ — usado por resources cuya superficie SIEMPRE requiere apiKey
65
+ * (tenant-admin), regardless de si también hay chatToken. */
66
+ requireApiKey() {
67
+ if (!this.apiKey) {
68
+ throw new Error('AgentForgeClient: this call requires an ak_live_ apiKey (tenant-wide), ' +
69
+ 'but the client was constructed without one.');
70
+ }
71
+ return this.apiKey;
72
+ }
73
+ resolveAuthHeaders(opts) {
74
+ if (opts?.forceApiKey)
75
+ return { Authorization: `Bearer ${this.requireApiKey()}` };
76
+ return this.authHeaders();
77
+ }
78
+ /**
79
+ * Primitiva de bajo nivel: hace el fetch, mapea status codes a errores
80
+ * tipados, y devuelve la `Response` cruda SIN parsear el body — así sirve
81
+ * tanto para el helper JSON (`request`) como para streaming (`requestStream`)
82
+ * y para respuestas 204 sin body (`tools.respondToCallback`).
83
+ */
84
+ async requestRaw(method, path, opts) {
85
+ const url = `${this.baseURL}${path.startsWith('/') ? path : '/' + path}`;
86
+ const controller = new AbortController();
87
+ const timeoutMs = opts?.timeoutMs === null ? undefined : (opts?.timeoutMs ?? this.timeoutMs);
88
+ const timeout = timeoutMs !== undefined ? setTimeout(() => controller.abort(), timeoutMs) : undefined;
89
+ let res;
90
+ try {
91
+ res = await this.fetchImpl(url, {
92
+ method,
93
+ headers: {
94
+ ...(opts?.rawBody !== undefined ? { 'content-type': 'application/json' } : {}),
95
+ accept: 'application/json',
96
+ ...this.resolveAuthHeaders(opts),
97
+ ...(opts?.headers ?? {}),
98
+ },
99
+ body: opts?.rawBody,
100
+ signal: controller.signal,
101
+ });
102
+ }
103
+ catch (err) {
104
+ const e = err;
105
+ throw new errors_1.AgentForgeNetworkError(`Network call ${method} ${path} failed: ${e.message}`, e);
106
+ }
107
+ finally {
108
+ if (timeout)
109
+ clearTimeout(timeout);
110
+ }
111
+ if (res.status === 401 || res.status === 403) {
112
+ const bodyText = await res.text();
113
+ throw new errors_1.AgentForgeAuthError(res.status, `${method} ${path} → ${res.status}`, bodyText);
114
+ }
115
+ if (res.status === 404) {
116
+ const bodyText = await res.text();
117
+ throw new errors_1.AgentForgeNotFoundError(`${method} ${path} → 404`, bodyText);
118
+ }
119
+ if (!res.ok) {
120
+ const bodyText = await res.text();
121
+ throw new errors_1.AgentForgeError(res.status, `${method} ${path} → ${res.status}`, bodyText);
122
+ }
123
+ return res;
124
+ }
125
+ // Request tipado. Maneja 4xx con errores específicos, 5xx genérico, network como AgentForgeNetworkError.
126
+ async request(method, path, body, opts) {
127
+ const res = await this.requestRaw(method, path, {
128
+ ...opts,
129
+ rawBody: body === undefined ? undefined : JSON.stringify(body),
130
+ });
131
+ // Algunos endpoints (POST sin body de respuesta) pueden ser 204.
132
+ if (res.status === 204)
133
+ return undefined;
134
+ return (await res.json());
135
+ }
136
+ /** Como `request()`, pero fuerza auth ak_live_ — para superficies
137
+ * tenant-admin (connector-resources, connectors/oauth/*-for-tenant) que
138
+ * rechazan ChatToken aunque el cliente tenga uno configurado también. */
139
+ async requestWithApiKey(method, path, body) {
140
+ return this.request(method, path, body, { forceApiKey: true });
141
+ }
142
+ /** Abre un stream SSE. Sin timeout (`timeoutMs: null`) — una llamada con
143
+ * varias rondas de tool-calling puede tardar más que el default de 30s.
144
+ * El caller consume `res.body` como ReadableStream<Uint8Array>. */
145
+ async requestStream(method, path, body) {
146
+ return this.requestRaw(method, path, {
147
+ rawBody: body === undefined ? undefined : JSON.stringify(body),
148
+ headers: { accept: 'text/event-stream' },
149
+ timeoutMs: null,
150
+ });
151
+ }
152
+ }
153
+ exports.AgentForgeClient = AgentForgeClient;
@@ -0,0 +1,15 @@
1
+ export declare class AgentForgeError extends Error {
2
+ readonly status: number;
3
+ readonly body?: string;
4
+ constructor(status: number, message: string, body?: string);
5
+ }
6
+ export declare class AgentForgeAuthError extends AgentForgeError {
7
+ constructor(status: 401 | 403, message: string, body?: string);
8
+ }
9
+ export declare class AgentForgeNotFoundError extends AgentForgeError {
10
+ constructor(message: string, body?: string);
11
+ }
12
+ export declare class AgentForgeNetworkError extends Error {
13
+ readonly cause: Error;
14
+ constructor(message: string, cause: Error);
15
+ }
package/dist/errors.js ADDED
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ // Errores tipados que el SDK lanza. Las apps cliente pueden hacer
3
+ // `instanceof AgentForgeAuthError` para distinguir 401/403 de otros fallos.
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.AgentForgeNetworkError = exports.AgentForgeNotFoundError = exports.AgentForgeAuthError = exports.AgentForgeError = void 0;
6
+ class AgentForgeError extends Error {
7
+ constructor(status, message, body) {
8
+ super(message);
9
+ this.name = 'AgentForgeError';
10
+ this.status = status;
11
+ this.body = body;
12
+ }
13
+ }
14
+ exports.AgentForgeError = AgentForgeError;
15
+ class AgentForgeAuthError extends AgentForgeError {
16
+ constructor(status, message, body) {
17
+ super(status, message, body);
18
+ this.name = 'AgentForgeAuthError';
19
+ }
20
+ }
21
+ exports.AgentForgeAuthError = AgentForgeAuthError;
22
+ class AgentForgeNotFoundError extends AgentForgeError {
23
+ constructor(message, body) {
24
+ super(404, message, body);
25
+ this.name = 'AgentForgeNotFoundError';
26
+ }
27
+ }
28
+ exports.AgentForgeNotFoundError = AgentForgeNotFoundError;
29
+ class AgentForgeNetworkError extends Error {
30
+ constructor(message, cause) {
31
+ super(message);
32
+ this.name = 'AgentForgeNetworkError';
33
+ this.cause = cause;
34
+ }
35
+ }
36
+ exports.AgentForgeNetworkError = AgentForgeNetworkError;
@@ -0,0 +1,13 @@
1
+ export { AgentForgeClient } from './client';
2
+ export type { AgentForgeClientOptions, RequestOptions } from './client';
3
+ export { AgentForgeError, AgentForgeAuthError, AgentForgeNotFoundError, AgentForgeNetworkError, } from './errors';
4
+ export { TOOL_CALLBACK_HEADERS, ToolCallbackSignatureError, signToolCallbackPayload, verifyToolCallbackSignature, } from './webhooks';
5
+ export type { AgentMe, AgentSummary, ApprovalCopyBundle, ChatStreamChunk, ChatStreamEvent, ChatTokenRecord, ConnectorDefaultsResult, ConnectorDefaultsSource, ConnectorResourceItem, ConnectorStatus, ConnectorToolInfo, ConversationHistory, ConversationStatus, CreateAgentInput, CreateClickupTaskInput, CreateClickupTaskResult, ExternalToolSummary, IssueChatTokenInput, ListAgentsResult, ListConnectorResourcesResult, McpServerConfig, MessageRecord, MessageRole, RegisterToolInput, RegisterToolsInput, RegisterToolsResult, ToolCallbackPayload, ToolCallRecord, ToolPermission, ToolPermissionMode, TokenUsage, TenantSecretEntry, UpdateAgentInput, } from './types';
6
+ export { AgentsResource } from './resources/agents';
7
+ export { ChatResource } from './resources/chat';
8
+ export type { AnthropicClientOptions, StreamMessageInput } from './resources/chat';
9
+ export { ConnectorsResource } from './resources/connectors';
10
+ export type { InboxChannelView } from './resources/connectors';
11
+ export { SecretsResource } from './resources/secrets';
12
+ export { ToolsResource } from './resources/tools';
13
+ export type { RespondToCallbackInput, VerifyCallbackInput } from './resources/tools';
package/dist/index.js ADDED
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ // AgentForge server-side SDK — public exports.
3
+ //
4
+ // Uso típico (ScrappyDoc en M8):
5
+ // import {
6
+ // AgentForgeClient,
7
+ // AgentForgeAuthError,
8
+ // type AgentMe,
9
+ // } from '@agentforge-io/sdk-server';
10
+ //
11
+ // const af = new AgentForgeClient({
12
+ // baseURL: process.env.AGENTFORGE_API_URL!,
13
+ // chatToken: process.env.AGENTFORGE_CHAT_TOKEN,
14
+ // apiKey: process.env.AGENTFORGE_API_KEY,
15
+ // });
16
+ //
17
+ // const agent = await af.agents.me();
18
+ // await af.agents.registerTools({ tools: [...] });
19
+ // const anthropic = await af.chat.createAnthropicClient();
20
+ //
21
+ // // Chat agent-aware con tool-calling + connectors:
22
+ // for await (const ev of af.chat.streamMessage({ content: 'hola' })) { ... }
23
+ //
24
+ // // Picker de recursos de connectors (ak_live_ tenant-wide):
25
+ // const { items } = await af.connectors.listConnected();
26
+ //
27
+ // // Tool 'remote': verificar callback entrante + responder resultado.
28
+ // const payload = af.tools.verifyCallback({ rawBody, signatureHeader, secretPlaintext });
29
+ // await af.tools.respondToCallback({ resultUrl: payload.resultUrl, tenantId: payload.tenantId, secret, result });
30
+ Object.defineProperty(exports, "__esModule", { value: true });
31
+ exports.ToolsResource = exports.SecretsResource = exports.ConnectorsResource = exports.ChatResource = exports.AgentsResource = exports.verifyToolCallbackSignature = exports.signToolCallbackPayload = exports.ToolCallbackSignatureError = exports.TOOL_CALLBACK_HEADERS = exports.AgentForgeNetworkError = exports.AgentForgeNotFoundError = exports.AgentForgeAuthError = exports.AgentForgeError = exports.AgentForgeClient = void 0;
32
+ var client_1 = require("./client");
33
+ Object.defineProperty(exports, "AgentForgeClient", { enumerable: true, get: function () { return client_1.AgentForgeClient; } });
34
+ var errors_1 = require("./errors");
35
+ Object.defineProperty(exports, "AgentForgeError", { enumerable: true, get: function () { return errors_1.AgentForgeError; } });
36
+ Object.defineProperty(exports, "AgentForgeAuthError", { enumerable: true, get: function () { return errors_1.AgentForgeAuthError; } });
37
+ Object.defineProperty(exports, "AgentForgeNotFoundError", { enumerable: true, get: function () { return errors_1.AgentForgeNotFoundError; } });
38
+ Object.defineProperty(exports, "AgentForgeNetworkError", { enumerable: true, get: function () { return errors_1.AgentForgeNetworkError; } });
39
+ var webhooks_1 = require("./webhooks");
40
+ Object.defineProperty(exports, "TOOL_CALLBACK_HEADERS", { enumerable: true, get: function () { return webhooks_1.TOOL_CALLBACK_HEADERS; } });
41
+ Object.defineProperty(exports, "ToolCallbackSignatureError", { enumerable: true, get: function () { return webhooks_1.ToolCallbackSignatureError; } });
42
+ Object.defineProperty(exports, "signToolCallbackPayload", { enumerable: true, get: function () { return webhooks_1.signToolCallbackPayload; } });
43
+ Object.defineProperty(exports, "verifyToolCallbackSignature", { enumerable: true, get: function () { return webhooks_1.verifyToolCallbackSignature; } });
44
+ var agents_1 = require("./resources/agents");
45
+ Object.defineProperty(exports, "AgentsResource", { enumerable: true, get: function () { return agents_1.AgentsResource; } });
46
+ var chat_1 = require("./resources/chat");
47
+ Object.defineProperty(exports, "ChatResource", { enumerable: true, get: function () { return chat_1.ChatResource; } });
48
+ var connectors_1 = require("./resources/connectors");
49
+ Object.defineProperty(exports, "ConnectorsResource", { enumerable: true, get: function () { return connectors_1.ConnectorsResource; } });
50
+ var secrets_1 = require("./resources/secrets");
51
+ Object.defineProperty(exports, "SecretsResource", { enumerable: true, get: function () { return secrets_1.SecretsResource; } });
52
+ var tools_1 = require("./resources/tools");
53
+ Object.defineProperty(exports, "ToolsResource", { enumerable: true, get: function () { return tools_1.ToolsResource; } });
@@ -0,0 +1,88 @@
1
+ import type { AgentForgeClient } from '../client';
2
+ import type { AgentMe, AgentSummary, ChatTokenRecord, CreateAgentInput, IssueChatTokenInput, ListAgentsResult, RegisterToolsInput, RegisterToolsResult, UpdateAgentInput } from '../types';
3
+ export declare class AgentsResource {
4
+ private readonly client;
5
+ constructor(client: AgentForgeClient);
6
+ /**
7
+ * Devuelve la configuración del agente al que está scoped el ChatToken/key.
8
+ *
9
+ * Para ChatToken: el agent al que fue emitido.
10
+ * Para ak_live_ agent-scoped: el agent_id de la api key.
11
+ * Para ak_live_ tenant-wide: 403 (no aplica a /agents/me).
12
+ *
13
+ * @example
14
+ * const agent = await af.agents.me();
15
+ * const prompt = agent.systemPrompt;
16
+ */
17
+ me(): Promise<AgentMe>;
18
+ /**
19
+ * Declara el set completo de tools custom para el agente.
20
+ *
21
+ * Política **last-writer-wins**: las tools del set anterior que no estén
22
+ * en el nuevo set quedan inactive (preservadas para auditoría). Para
23
+ * "borrar todas" pasa `{ tools: [] }`.
24
+ *
25
+ * El platform NO ejecuta estas tools — la app cliente las corre in-process.
26
+ * El platform solo persiste la declaración para visibilidad y auditoría.
27
+ *
28
+ * @example
29
+ * await af.agents.registerTools({
30
+ * tools: [{
31
+ * name: 'lookup_sop',
32
+ * description: 'Busca en SOPs aprobados',
33
+ * inputSchema: { type: 'object', properties: { ... }, required: [...] },
34
+ * }],
35
+ * });
36
+ */
37
+ registerTools(input: RegisterToolsInput): Promise<RegisterToolsResult>;
38
+ /**
39
+ * Lista los agents del tenant del ak_live_.
40
+ *
41
+ * @example
42
+ * const { items, total } = await af.agents.list({ limit: 100 });
43
+ */
44
+ list(opts?: {
45
+ limit?: number;
46
+ }): Promise<ListAgentsResult>;
47
+ /**
48
+ * Crea un agent en el tenant del ak_live_.
49
+ *
50
+ * `slug` debe ser único por tenant (el server responde 409 si choca).
51
+ */
52
+ create(input: CreateAgentInput): Promise<AgentSummary>;
53
+ /**
54
+ * Devuelve un agent por id. 404 si no existe o no pertenece al tenant.
55
+ */
56
+ get(agentId: string): Promise<AgentSummary>;
57
+ /**
58
+ * Actualización parcial. Solo los campos definidos en `patch` se modifican.
59
+ */
60
+ update(agentId: string, patch: UpdateAgentInput): Promise<AgentSummary>;
61
+ /**
62
+ * Emite un ChatToken nuevo para `agentId`. El token recién emitido es la
63
+ * credencial que el widget chat (o el SDK del cliente) usa como
64
+ * `X-Chat-Token` para hablar con la plataforma.
65
+ *
66
+ * `allowedOrigins` vacío = acepta cualquier Origin. En producción siempre
67
+ * pasa la lista explícita de dominios donde se embebe el widget.
68
+ *
69
+ * @example
70
+ * const t = await af.agents.issueChatToken('agent_123', {
71
+ * name: 'Production homepage',
72
+ * allowedOrigins: ['https://app.example.com'],
73
+ * });
74
+ * // t.token → guardar como ChatToken del widget.
75
+ */
76
+ issueChatToken(agentId: string, input?: IssueChatTokenInput): Promise<ChatTokenRecord>;
77
+ /**
78
+ * Lista todos los ChatTokens activos del agent.
79
+ */
80
+ listChatTokens(agentId: string): Promise<{
81
+ items: ChatTokenRecord[];
82
+ }>;
83
+ /**
84
+ * Desactiva un ChatToken por su valor opaco. El widget que lo tenga
85
+ * cacheado empezará a recibir 401 en el siguiente request.
86
+ */
87
+ revokeChatToken(agentId: string, token: string): Promise<void>;
88
+ }
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ // agents resource — wrappers sobre los endpoints /api/v1/agents*.
3
+ //
4
+ // Dos superficies coexisten:
5
+ // - "self" (`me()`, `registerTools()`): auth con ChatToken o ak_live_
6
+ // agent-scoped. El SDK resuelve el agent del token y solo expone esa
7
+ // identidad. Usado por apps que ya saben qué agent representan.
8
+ // - "admin" (`list()`, `create()`, `update()`, `get()`, `issueChatToken()`):
9
+ // auth con ak_live_ tenant-wide. Permite a apps server-side gestionar
10
+ // todos los agents del tenant. Aquí ChatToken NO funciona — el endpoint
11
+ // responde 401/403 si el cliente solo tiene ChatToken.
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.AgentsResource = void 0;
14
+ class AgentsResource {
15
+ constructor(client) {
16
+ this.client = client;
17
+ }
18
+ /**
19
+ * Devuelve la configuración del agente al que está scoped el ChatToken/key.
20
+ *
21
+ * Para ChatToken: el agent al que fue emitido.
22
+ * Para ak_live_ agent-scoped: el agent_id de la api key.
23
+ * Para ak_live_ tenant-wide: 403 (no aplica a /agents/me).
24
+ *
25
+ * @example
26
+ * const agent = await af.agents.me();
27
+ * const prompt = agent.systemPrompt;
28
+ */
29
+ async me() {
30
+ return this.client.request('GET', '/api/v1/agents/me');
31
+ }
32
+ /**
33
+ * Declara el set completo de tools custom para el agente.
34
+ *
35
+ * Política **last-writer-wins**: las tools del set anterior que no estén
36
+ * en el nuevo set quedan inactive (preservadas para auditoría). Para
37
+ * "borrar todas" pasa `{ tools: [] }`.
38
+ *
39
+ * El platform NO ejecuta estas tools — la app cliente las corre in-process.
40
+ * El platform solo persiste la declaración para visibilidad y auditoría.
41
+ *
42
+ * @example
43
+ * await af.agents.registerTools({
44
+ * tools: [{
45
+ * name: 'lookup_sop',
46
+ * description: 'Busca en SOPs aprobados',
47
+ * inputSchema: { type: 'object', properties: { ... }, required: [...] },
48
+ * }],
49
+ * });
50
+ */
51
+ async registerTools(input) {
52
+ return this.client.request('POST', '/api/v1/agents/me/tools', input);
53
+ }
54
+ // ────────────────────────────────────────────────────────────────────────
55
+ // Admin (requiere ak_live_ tenant-wide).
56
+ // ────────────────────────────────────────────────────────────────────────
57
+ /**
58
+ * Lista los agents del tenant del ak_live_.
59
+ *
60
+ * @example
61
+ * const { items, total } = await af.agents.list({ limit: 100 });
62
+ */
63
+ async list(opts) {
64
+ const qs = opts?.limit !== undefined ? `?limit=${encodeURIComponent(opts.limit)}` : '';
65
+ return this.client.request('GET', `/api/v1/agents${qs}`);
66
+ }
67
+ /**
68
+ * Crea un agent en el tenant del ak_live_.
69
+ *
70
+ * `slug` debe ser único por tenant (el server responde 409 si choca).
71
+ */
72
+ async create(input) {
73
+ return this.client.request('POST', '/api/v1/agents', input);
74
+ }
75
+ /**
76
+ * Devuelve un agent por id. 404 si no existe o no pertenece al tenant.
77
+ */
78
+ async get(agentId) {
79
+ return this.client.request('GET', `/api/v1/agents/${encodeURIComponent(agentId)}`);
80
+ }
81
+ /**
82
+ * Actualización parcial. Solo los campos definidos en `patch` se modifican.
83
+ */
84
+ async update(agentId, patch) {
85
+ return this.client.request('PATCH', `/api/v1/agents/${encodeURIComponent(agentId)}`, patch);
86
+ }
87
+ /**
88
+ * Emite un ChatToken nuevo para `agentId`. El token recién emitido es la
89
+ * credencial que el widget chat (o el SDK del cliente) usa como
90
+ * `X-Chat-Token` para hablar con la plataforma.
91
+ *
92
+ * `allowedOrigins` vacío = acepta cualquier Origin. En producción siempre
93
+ * pasa la lista explícita de dominios donde se embebe el widget.
94
+ *
95
+ * @example
96
+ * const t = await af.agents.issueChatToken('agent_123', {
97
+ * name: 'Production homepage',
98
+ * allowedOrigins: ['https://app.example.com'],
99
+ * });
100
+ * // t.token → guardar como ChatToken del widget.
101
+ */
102
+ async issueChatToken(agentId, input) {
103
+ return this.client.request('POST', `/api/v1/agents/${encodeURIComponent(agentId)}/chat-tokens`, input ?? {});
104
+ }
105
+ /**
106
+ * Lista todos los ChatTokens activos del agent.
107
+ */
108
+ async listChatTokens(agentId) {
109
+ return this.client.request('GET', `/api/v1/agents/${encodeURIComponent(agentId)}/chat-tokens`);
110
+ }
111
+ /**
112
+ * Desactiva un ChatToken por su valor opaco. El widget que lo tenga
113
+ * cacheado empezará a recibir 401 en el siguiente request.
114
+ */
115
+ async revokeChatToken(agentId, token) {
116
+ await this.client.request('DELETE', `/api/v1/agents/${encodeURIComponent(agentId)}/chat-tokens/${encodeURIComponent(token)}`);
117
+ }
118
+ }
119
+ exports.AgentsResource = AgentsResource;
@@ -0,0 +1,55 @@
1
+ import type { AgentForgeClient } from '../client';
2
+ import type { ChatStreamEvent, ConversationHistory } from '../types';
3
+ export interface AnthropicClientOptions {
4
+ /** Override de la versión Anthropic. Default: '2023-06-01'. */
5
+ anthropicVersion?: string;
6
+ }
7
+ export interface StreamMessageInput {
8
+ content: string;
9
+ /** Si se omite, el server crea una conversación nueva. */
10
+ conversationId?: string;
11
+ }
12
+ export declare class ChatResource {
13
+ private readonly client;
14
+ constructor(client: AgentForgeClient);
15
+ /**
16
+ * Devuelve una instancia de `Anthropic` (de @anthropic-ai/sdk) preconfigurada
17
+ * para hablar contra el proxy del platform.
18
+ *
19
+ * **Pre-req:** la app cliente tiene `@anthropic-ai/sdk` como dep regular y
20
+ * el `AgentForgeClient` se construyó con `apiKey` (ak_live_) además del
21
+ * chatToken.
22
+ *
23
+ * @example
24
+ * const anthropic = await af.chat.createAnthropicClient();
25
+ * const msg = await anthropic.messages.create({ ... });
26
+ */
27
+ createAnthropicClient(opts?: AnthropicClientOptions): Promise<any>;
28
+ /**
29
+ * Chat streaming AGENT-AWARE — `POST /api/v1/chat/messages/stream`. Auth:
30
+ * ChatToken (scoped al agent). Resuelve connectors del tenant + tools
31
+ * 'remote' registradas del agent automáticamente; el caller solo manda
32
+ * `content`.
33
+ *
34
+ * Yieldea `ChatStreamEvent` tipados en vez de frames SSE crudos — ver
35
+ * el tipo para el detalle de cada `kind`.
36
+ *
37
+ * @example
38
+ * let conversationId: string | undefined;
39
+ * for await (const ev of af.chat.streamMessage({ content: 'hola' })) {
40
+ * if (ev.kind === 'conversation') conversationId = ev.conversationId;
41
+ * else if (ev.kind === 'chunk' && ev.chunk.type === 'text_delta') {
42
+ * process.stdout.write(ev.chunk.delta);
43
+ * }
44
+ * }
45
+ */
46
+ streamMessage(input: StreamMessageInput): AsyncGenerator<ChatStreamEvent>;
47
+ /**
48
+ * Historial completo de una conversación — `GET
49
+ * /api/v1/chat/conversations/:id/messages`. Útil para "resumir" un chat
50
+ * tras un refresh de página cuando el `conversationId` se guardó (ej. en
51
+ * la URL). Tira `AgentForgeNotFoundError` si la conversación no existe o
52
+ * no pertenece al ChatToken que llama.
53
+ */
54
+ getHistory(conversationId: string): Promise<ConversationHistory>;
55
+ }