@agentforge-io/sdk-server 4.5.2 → 4.6.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/dist/client.d.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  import { AgentsResource } from './resources/agents';
2
+ import { AnalyticsResource } from './resources/analytics';
2
3
  import { AppsResource } from './resources/apps';
3
4
  import { ChatResource } from './resources/chat';
4
5
  import { ConnectorsResource } from './resources/connectors';
6
+ import { InboxResource } from './resources/inbox';
5
7
  import { ProvisioningResource } from './resources/provisioning';
6
8
  import { SecretsResource } from './resources/secrets';
7
9
  import { ToolsResource } from './resources/tools';
@@ -58,9 +60,11 @@ export declare class AgentForgeClient {
58
60
  private readonly fetchImpl;
59
61
  private readonly timeoutMs;
60
62
  readonly agents: AgentsResource;
63
+ readonly analytics: AnalyticsResource;
61
64
  readonly apps: AppsResource;
62
65
  readonly chat: ChatResource;
63
66
  readonly connectors: ConnectorsResource;
67
+ readonly inbox: InboxResource;
64
68
  readonly provisioning: ProvisioningResource;
65
69
  readonly secrets: SecretsResource;
66
70
  readonly tools: ToolsResource;
package/dist/client.js CHANGED
@@ -21,9 +21,11 @@ exports.AgentForgeClient = void 0;
21
21
  // solo tiene ChatToken. Esas pasan `{ forceApiKey: true }` a `request()`.
22
22
  const errors_1 = require("./errors");
23
23
  const agents_1 = require("./resources/agents");
24
+ const analytics_1 = require("./resources/analytics");
24
25
  const apps_1 = require("./resources/apps");
25
26
  const chat_1 = require("./resources/chat");
26
27
  const connectors_1 = require("./resources/connectors");
28
+ const inbox_1 = require("./resources/inbox");
27
29
  const provisioning_1 = require("./resources/provisioning");
28
30
  const secrets_1 = require("./resources/secrets");
29
31
  const tools_1 = require("./resources/tools");
@@ -47,9 +49,11 @@ class AgentForgeClient {
47
49
  this.fetchImpl = opts.fetch ?? fetch;
48
50
  this.timeoutMs = opts.timeoutMs ?? 30000;
49
51
  this.agents = new agents_1.AgentsResource(this);
52
+ this.analytics = new analytics_1.AnalyticsResource(this);
50
53
  this.apps = new apps_1.AppsResource(this);
51
54
  this.chat = new chat_1.ChatResource(this);
52
55
  this.connectors = new connectors_1.ConnectorsResource(this);
56
+ this.inbox = new inbox_1.InboxResource(this);
53
57
  this.provisioning = new provisioning_1.ProvisioningResource(this);
54
58
  this.secrets = new secrets_1.SecretsResource(this);
55
59
  this.tools = new tools_1.ToolsResource(this);
package/dist/index.d.ts CHANGED
@@ -4,11 +4,15 @@ export { AgentForgeError, AgentForgeAuthError, AgentForgeNotFoundError, AgentFor
4
4
  export { TOOL_CALLBACK_HEADERS, ToolCallbackSignatureError, signToolCallbackPayload, verifyToolCallbackSignature, } from './webhooks';
5
5
  export type { AgentMe, AgentSummary, AppUserConnectorStatus, ApprovalCopyBundle, ChannelContext, ChatStreamChunk, ChatStreamEvent, ChatTokenRecord, ConnectorDefaultsResult, ConnectorDefaultsSource, ConnectorResourceItem, ConnectorStatus, ConnectorToolInfo, ConversationHistory, ConversationStatus, CreateAgentInput, CreateClickupTaskInput, CreateClickupTaskResult, ExternalToolSummary, IssueChatTokenInput, ListAgentsResult, ListConnectorResourcesResult, McpServerConfig, MessageRecord, MessageRole, PublicAppBranding, AppSelf, AppSelfConnector, AppSelfConnectors, RegisterToolInput, RegisterToolsInput, RegisterToolsResult, ToolCallbackPayload, ToolCallRecord, ToolPermission, ToolPermissionMode, TokenUsage, TenantSecretEntry, UpdateAgentInput, } from './types';
6
6
  export { AgentsResource } from './resources/agents';
7
+ export { AnalyticsResource } from './resources/analytics';
8
+ export type { AgentAttentionLogRow, SupportAnalyticsQuery, SupportKpiResponse, SupportKpiTotals, } from './resources/analytics';
7
9
  export { AppsResource } from './resources/apps';
8
10
  export { ChatResource } from './resources/chat';
9
11
  export type { AnthropicClientOptions, StreamMessageInput } from './resources/chat';
10
12
  export { ConnectorsResource } from './resources/connectors';
11
13
  export type { InboxChannelView } from './resources/connectors';
14
+ export { InboxResource } from './resources/inbox';
15
+ export type { InboxMessageView, InboxThreadCustomerProfileView, InboxThreadMode, InboxThreadView, } from './resources/inbox';
12
16
  export { ProvisioningResource } from './resources/provisioning';
13
17
  export type { ProvisionedTenant, ProvisionedApp, } from './resources/provisioning';
14
18
  export { SecretsResource } from './resources/secrets';
package/dist/index.js CHANGED
@@ -28,7 +28,7 @@
28
28
  // const payload = af.tools.verifyCallback({ rawBody, signatureHeader, secretPlaintext });
29
29
  // await af.tools.respondToCallback({ resultUrl: payload.resultUrl, tenantId: payload.tenantId, secret, result });
30
30
  Object.defineProperty(exports, "__esModule", { value: true });
31
- exports.ToolsResource = exports.SecretsResource = exports.ProvisioningResource = exports.ConnectorsResource = exports.ChatResource = exports.AppsResource = exports.AgentsResource = exports.verifyToolCallbackSignature = exports.signToolCallbackPayload = exports.ToolCallbackSignatureError = exports.TOOL_CALLBACK_HEADERS = exports.AgentForgeNetworkError = exports.AgentForgeNotFoundError = exports.AgentForgeAuthError = exports.AgentForgeError = exports.AgentForgeClient = void 0;
31
+ exports.ToolsResource = exports.SecretsResource = exports.ProvisioningResource = exports.InboxResource = exports.ConnectorsResource = exports.ChatResource = exports.AppsResource = exports.AnalyticsResource = 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
32
  var client_1 = require("./client");
33
33
  Object.defineProperty(exports, "AgentForgeClient", { enumerable: true, get: function () { return client_1.AgentForgeClient; } });
34
34
  var errors_1 = require("./errors");
@@ -43,12 +43,16 @@ Object.defineProperty(exports, "signToolCallbackPayload", { enumerable: true, ge
43
43
  Object.defineProperty(exports, "verifyToolCallbackSignature", { enumerable: true, get: function () { return webhooks_1.verifyToolCallbackSignature; } });
44
44
  var agents_1 = require("./resources/agents");
45
45
  Object.defineProperty(exports, "AgentsResource", { enumerable: true, get: function () { return agents_1.AgentsResource; } });
46
+ var analytics_1 = require("./resources/analytics");
47
+ Object.defineProperty(exports, "AnalyticsResource", { enumerable: true, get: function () { return analytics_1.AnalyticsResource; } });
46
48
  var apps_1 = require("./resources/apps");
47
49
  Object.defineProperty(exports, "AppsResource", { enumerable: true, get: function () { return apps_1.AppsResource; } });
48
50
  var chat_1 = require("./resources/chat");
49
51
  Object.defineProperty(exports, "ChatResource", { enumerable: true, get: function () { return chat_1.ChatResource; } });
50
52
  var connectors_1 = require("./resources/connectors");
51
53
  Object.defineProperty(exports, "ConnectorsResource", { enumerable: true, get: function () { return connectors_1.ConnectorsResource; } });
54
+ var inbox_1 = require("./resources/inbox");
55
+ Object.defineProperty(exports, "InboxResource", { enumerable: true, get: function () { return inbox_1.InboxResource; } });
52
56
  var provisioning_1 = require("./resources/provisioning");
53
57
  Object.defineProperty(exports, "ProvisioningResource", { enumerable: true, get: function () { return provisioning_1.ProvisioningResource; } });
54
58
  var secrets_1 = require("./resources/secrets");
@@ -0,0 +1,72 @@
1
+ import type { AgentForgeClient } from '../client';
2
+ export interface SupportKpiTotals {
3
+ receivedCount: number;
4
+ aiResponsesCount: number;
5
+ humanMessagesCount: number;
6
+ escalationsCount: number;
7
+ aiResolvedCount: number;
8
+ humanHandledCount: number;
9
+ assignmentsCount: number;
10
+ avgResolutionMs: number | null;
11
+ avgFrtMs: number | null;
12
+ avgTimeToAssignMs: number | null;
13
+ }
14
+ export interface SupportKpiResponse {
15
+ tenantId: string;
16
+ from: string;
17
+ to: string;
18
+ totals: SupportKpiTotals;
19
+ byDimension: Array<SupportKpiTotals & {
20
+ dimensionType: 'agent' | 'operator';
21
+ dimensionKey: string;
22
+ }>;
23
+ }
24
+ export interface AgentAttentionLogRow {
25
+ dimensionType: 'agent' | 'operator';
26
+ dimensionKey: string;
27
+ metricDate: string;
28
+ receivedCount: number;
29
+ aiResponsesCount: number;
30
+ humanMessagesCount: number;
31
+ escalationsCount: number;
32
+ aiResolvedCount: number;
33
+ humanHandledCount: number;
34
+ assignmentsCount: number;
35
+ avgResolutionMs: number | null;
36
+ avgFrtMs: number | null;
37
+ avgTimeToAssignMs: number | null;
38
+ }
39
+ export interface SupportAnalyticsQuery {
40
+ /** ISO date string. Required. */
41
+ from: string;
42
+ /** ISO date string. Required. */
43
+ to: string;
44
+ /** Narrow to one agent's rows (`byDimension`/`items` filtered to
45
+ * `dimensionType: 'agent', dimensionKey: agentId`). */
46
+ agentId?: string;
47
+ /** Narrow to one operator's rows. */
48
+ operatorUserId?: string;
49
+ }
50
+ export declare class AnalyticsResource {
51
+ private readonly client;
52
+ constructor(client: AgentForgeClient);
53
+ /**
54
+ * `GET /apps/me/support-kpis` — totals + per-agent/operator breakdown for
55
+ * the calling App's tenant, over `[from, to]`.
56
+ *
57
+ * @example
58
+ * const kpis = await af.analytics.getSupportKpis({
59
+ * from: '2026-08-01T00:00:00.000Z',
60
+ * to: '2026-08-13T00:00:00.000Z',
61
+ * });
62
+ */
63
+ getSupportKpis(query: SupportAnalyticsQuery): Promise<SupportKpiResponse>;
64
+ /**
65
+ * `GET /apps/me/support-attention-log` — daily per-agent/operator rows
66
+ * over `[from, to]`. Same query params as `getSupportKpis`.
67
+ */
68
+ getAgentAttentionLog(query: SupportAnalyticsQuery): Promise<{
69
+ items: AgentAttentionLogRow[];
70
+ }>;
71
+ private toQueryString;
72
+ }
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ // analytics resource (AGF-SD-3b, AGF-SUPPORT-DESK epic) — wraps
3
+ // `AppSupportAnalyticsController` (`GET /apps/me/support-kpis`,
4
+ // `GET /apps/me/support-attention-log`) on the platform: pre-aggregated
5
+ // support KPIs (received/AI-responses/escalations/resolution-time/etc.)
6
+ // for the calling App's tenant, tenant-wide with optional agent/operator
7
+ // narrowing.
8
+ //
9
+ // Auth: `AppSupportAnalyticsController` accepts BOTH `sk_live_` (appSecret)
10
+ // and `ak_live_` (apiKey) via `ApiKeyGuard`. This resource uses plain
11
+ // `this.client.request()` (NOT `requestWithApiKey()` — that helper
12
+ // hardcodes `ak_live_`-only via `forceApiKey: true` and throws early on an
13
+ // appSecret-only client; see `connectors.ts`'s file header for the same
14
+ // gotcha on the App-user scope methods there), so `authHeaders()` can pick
15
+ // either credential for the `Authorization: Bearer` header. `tenantId` is
16
+ // NEVER a param here (SDD §4.5) — the server resolves it exclusively from
17
+ // the credential.
18
+ //
19
+ // `from`/`to` are REQUIRED on both methods — the platform rejects a
20
+ // missing/malformed/inverted/too-wide range with 400 (no implicit default
21
+ // window). This wrapper does no validation of its own; it forwards
22
+ // whatever `Date` the caller passes as an ISO string and lets the server
23
+ // be the single source of truth for what's a valid range.
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ exports.AnalyticsResource = void 0;
26
+ class AnalyticsResource {
27
+ constructor(client) {
28
+ this.client = client;
29
+ }
30
+ /**
31
+ * `GET /apps/me/support-kpis` — totals + per-agent/operator breakdown for
32
+ * the calling App's tenant, over `[from, to]`.
33
+ *
34
+ * @example
35
+ * const kpis = await af.analytics.getSupportKpis({
36
+ * from: '2026-08-01T00:00:00.000Z',
37
+ * to: '2026-08-13T00:00:00.000Z',
38
+ * });
39
+ */
40
+ async getSupportKpis(query) {
41
+ return this.client.request('GET', `/apps/me/support-kpis${this.toQueryString(query)}`);
42
+ }
43
+ /**
44
+ * `GET /apps/me/support-attention-log` — daily per-agent/operator rows
45
+ * over `[from, to]`. Same query params as `getSupportKpis`.
46
+ */
47
+ async getAgentAttentionLog(query) {
48
+ return this.client.request('GET', `/apps/me/support-attention-log${this.toQueryString(query)}`);
49
+ }
50
+ toQueryString(query) {
51
+ const params = new URLSearchParams({ from: query.from, to: query.to });
52
+ if (query.agentId)
53
+ params.set('agentId', query.agentId);
54
+ if (query.operatorUserId)
55
+ params.set('operatorUserId', query.operatorUserId);
56
+ return `?${params.toString()}`;
57
+ }
58
+ }
59
+ exports.AnalyticsResource = AnalyticsResource;
@@ -0,0 +1,113 @@
1
+ import type { AgentForgeClient } from '../client';
2
+ export declare class InboxResource {
3
+ private readonly client;
4
+ constructor(client: AgentForgeClient);
5
+ /**
6
+ * `GET /connectors/inbox/agents/:agentId/inbox/threads` — threads for this
7
+ * agent's support inbox. Optional `channelId` narrows to one channel.
8
+ *
9
+ * @example
10
+ * const { items } = await af.inbox.listThreads(agentId);
11
+ */
12
+ listThreads(agentId: string, opts?: {
13
+ channelId?: string;
14
+ }): Promise<{
15
+ items: InboxThreadView[];
16
+ }>;
17
+ /**
18
+ * `GET /connectors/inbox/agents/:agentId/inbox/threads/:threadId` — a
19
+ * single thread.
20
+ */
21
+ getThread(agentId: string, threadId: string): Promise<InboxThreadView>;
22
+ /**
23
+ * `GET /connectors/inbox/agents/:agentId/inbox/threads/:threadId/messages`
24
+ * — full message history for a thread.
25
+ */
26
+ listMessages(agentId: string, threadId: string): Promise<{
27
+ items: InboxMessageView[];
28
+ }>;
29
+ /**
30
+ * `POST .../threads/:threadId/messages` — send a message as the operator.
31
+ * `pauseAgent` defaults `true` server-side (pass `false` to reply without
32
+ * taking the thread away from the agent). `operatorId` is the App's own
33
+ * opaque identifier for the acting human rep — see file header.
34
+ *
35
+ * @example
36
+ * await af.inbox.sendOperatorMessage(agentId, threadId, {
37
+ * text: 'Un momento, reviso tu caso.',
38
+ * operatorId: 'scrappydoc-rep-42',
39
+ * });
40
+ */
41
+ sendOperatorMessage(agentId: string, threadId: string, input: {
42
+ text: string;
43
+ pauseAgent?: boolean;
44
+ operatorId?: string;
45
+ }): Promise<void>;
46
+ /**
47
+ * `POST .../threads/:threadId/assign` — claim a thread for an operator.
48
+ * `operatorId` is required (the server rejects a missing one with 401).
49
+ */
50
+ assignThread(agentId: string, threadId: string, input: {
51
+ operatorId: string;
52
+ }): Promise<void>;
53
+ /**
54
+ * `DELETE .../threads/:threadId/assign` — release a thread claim
55
+ * (handback). `operatorId`, when given, must match the current assignee
56
+ * server-side.
57
+ */
58
+ handback(agentId: string, threadId: string, opts?: {
59
+ operatorId?: string;
60
+ }): Promise<void>;
61
+ /**
62
+ * `POST .../threads/:threadId/mode` — switch a thread between agent/human
63
+ * mode.
64
+ */
65
+ setThreadMode(agentId: string, threadId: string, mode: InboxThreadMode): Promise<void>;
66
+ /**
67
+ * `POST .../threads/:threadId/close` — close a human-mode thread.
68
+ */
69
+ closeThread(agentId: string, threadId: string, opts?: {
70
+ notes?: string;
71
+ operatorId?: string;
72
+ }): Promise<void>;
73
+ }
74
+ export type InboxThreadMode = 'agent' | 'human';
75
+ export interface InboxThreadCustomerProfileView {
76
+ id: string;
77
+ displayName?: string;
78
+ username?: string;
79
+ avatarUrl?: string;
80
+ providerId?: string;
81
+ tags?: string[];
82
+ notes?: string;
83
+ }
84
+ export interface InboxThreadView {
85
+ id: string;
86
+ channelId: string;
87
+ externalId: string;
88
+ displayName?: string;
89
+ mode: InboxThreadMode;
90
+ unreadCount: number;
91
+ lastMessageAt?: string;
92
+ lastMessagePreview?: string;
93
+ assignedHumanUserId?: string;
94
+ closedAt?: string;
95
+ closeNotes?: string;
96
+ closedByUserId?: string;
97
+ customerProfileId?: string;
98
+ customerProfile?: InboxThreadCustomerProfileView;
99
+ createdAt: string;
100
+ updatedAt: string;
101
+ }
102
+ export interface InboxMessageView {
103
+ id: string;
104
+ threadId: string;
105
+ direction: 'inbound' | 'outbound';
106
+ source: 'customer' | 'agent' | 'operator';
107
+ type: 'text' | 'image' | 'video' | 'audio' | 'document' | 'sticker' | 'location' | 'unsupported';
108
+ body: string;
109
+ externalMessageId?: string;
110
+ payload?: Record<string, unknown>;
111
+ sentAt: string;
112
+ recordedAt: string;
113
+ }
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+ // inbox resource (AGF-SD-1, AGF-SUPPORT-DESK epic) — wraps
3
+ // `AppInboxController` (`connectors/inbox/agents/:agentId/inbox/*`) on the
4
+ // platform: list/read/reply/assign/handback/mode/close for an agent's
5
+ // support inbox threads, authenticated as an App (`sk_live_`) or an
6
+ // agent-scoped `ak_live_` — never a human dashboard session.
7
+ //
8
+ // Auth: `AppInboxController` accepts BOTH `sk_live_` (appSecret) and
9
+ // `ak_live_` (apiKey) via `ApiKeyGuard` — unlike the tenant-admin-only
10
+ // surfaces `ConnectorsResource` wraps with `requestWithApiKey()` (which
11
+ // hardcodes `ak_live_` and throws early on an appSecret-only client, see
12
+ // that file's header), inbox operator routes are meant to be called by an
13
+ // App itself. So this resource uses plain `this.client.request()`, whose
14
+ // `authHeaders()` picks `apiKey` OR `appSecret` for the `Authorization:
15
+ // Bearer` header (chatToken, if present instead, is rejected server-side
16
+ // with 401 since the route requires `auth.isApiKey`). Every method takes
17
+ // `agentId` explicitly (unlike `af.agents.me()`) because the platform
18
+ // route itself is per-agent and validates ownership server-side
19
+ // (`assertOwnedAgent` — 404, not 403, on a foreign agent).
20
+ //
21
+ // Tenant isolation (SDD §4.5): `tenantId` is NEVER a param here — the
22
+ // server resolves it exclusively from the `ak_live_`/`sk_live_` credential.
23
+ //
24
+ // Operator identity: the platform has no concept of an App's own
25
+ // human-support-rep identity. `operatorId` (optional on most write methods)
26
+ // is an opaque string the calling App mints for its own end of the
27
+ // conversation — passed through verbatim as the platform's `actingUserId`/
28
+ // `userId`. See `AppInboxController`'s file header on the platform for the
29
+ // full rationale.
30
+ //
31
+ // NOT covered here (left for a future extension — see file bottom for
32
+ // what's deliberately excluded and why):
33
+ // - `af.inbox.channels.get`/`update` — no App-scoped single-channel-read
34
+ // or update route exists on the platform today (`ApiKeyInboxController`
35
+ // only has list/create/delete). `list`/`create`/`destroy` already live
36
+ // on `af.connectors.*` (see `connectors.ts`) — not duplicated here.
37
+ // - operator online/offline status (`PUT teams/:teamId/operator/status`)
38
+ // — lives on `OperatorStatusController`, gated by the GLOBAL
39
+ // `JwtAuthGuard` (human dashboard session), not `ApiKeyGuard`. No
40
+ // `@Public()`, not reachable with `sk_live_`/`ak_live_` at all.
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.InboxResource = void 0;
43
+ class InboxResource {
44
+ constructor(client) {
45
+ this.client = client;
46
+ }
47
+ /**
48
+ * `GET /connectors/inbox/agents/:agentId/inbox/threads` — threads for this
49
+ * agent's support inbox. Optional `channelId` narrows to one channel.
50
+ *
51
+ * @example
52
+ * const { items } = await af.inbox.listThreads(agentId);
53
+ */
54
+ async listThreads(agentId, opts) {
55
+ const qs = opts?.channelId
56
+ ? `?channelId=${encodeURIComponent(opts.channelId)}`
57
+ : '';
58
+ return this.client.request('GET', `/connectors/inbox/agents/${encodeURIComponent(agentId)}/inbox/threads${qs}`);
59
+ }
60
+ /**
61
+ * `GET /connectors/inbox/agents/:agentId/inbox/threads/:threadId` — a
62
+ * single thread.
63
+ */
64
+ async getThread(agentId, threadId) {
65
+ return this.client.request('GET', `/connectors/inbox/agents/${encodeURIComponent(agentId)}/inbox/threads/${encodeURIComponent(threadId)}`);
66
+ }
67
+ /**
68
+ * `GET /connectors/inbox/agents/:agentId/inbox/threads/:threadId/messages`
69
+ * — full message history for a thread.
70
+ */
71
+ async listMessages(agentId, threadId) {
72
+ return this.client.request('GET', `/connectors/inbox/agents/${encodeURIComponent(agentId)}/inbox/threads/${encodeURIComponent(threadId)}/messages`);
73
+ }
74
+ /**
75
+ * `POST .../threads/:threadId/messages` — send a message as the operator.
76
+ * `pauseAgent` defaults `true` server-side (pass `false` to reply without
77
+ * taking the thread away from the agent). `operatorId` is the App's own
78
+ * opaque identifier for the acting human rep — see file header.
79
+ *
80
+ * @example
81
+ * await af.inbox.sendOperatorMessage(agentId, threadId, {
82
+ * text: 'Un momento, reviso tu caso.',
83
+ * operatorId: 'scrappydoc-rep-42',
84
+ * });
85
+ */
86
+ async sendOperatorMessage(agentId, threadId, input) {
87
+ await this.client.request('POST', `/connectors/inbox/agents/${encodeURIComponent(agentId)}/inbox/threads/${encodeURIComponent(threadId)}/messages`, input);
88
+ }
89
+ /**
90
+ * `POST .../threads/:threadId/assign` — claim a thread for an operator.
91
+ * `operatorId` is required (the server rejects a missing one with 401).
92
+ */
93
+ async assignThread(agentId, threadId, input) {
94
+ await this.client.request('POST', `/connectors/inbox/agents/${encodeURIComponent(agentId)}/inbox/threads/${encodeURIComponent(threadId)}/assign`, input);
95
+ }
96
+ /**
97
+ * `DELETE .../threads/:threadId/assign` — release a thread claim
98
+ * (handback). `operatorId`, when given, must match the current assignee
99
+ * server-side.
100
+ */
101
+ async handback(agentId, threadId, opts) {
102
+ await this.client.request('DELETE', `/connectors/inbox/agents/${encodeURIComponent(agentId)}/inbox/threads/${encodeURIComponent(threadId)}/assign`, opts);
103
+ }
104
+ /**
105
+ * `POST .../threads/:threadId/mode` — switch a thread between agent/human
106
+ * mode.
107
+ */
108
+ async setThreadMode(agentId, threadId, mode) {
109
+ await this.client.request('POST', `/connectors/inbox/agents/${encodeURIComponent(agentId)}/inbox/threads/${encodeURIComponent(threadId)}/mode`, { mode });
110
+ }
111
+ /**
112
+ * `POST .../threads/:threadId/close` — close a human-mode thread.
113
+ */
114
+ async closeThread(agentId, threadId, opts) {
115
+ await this.client.request('POST', `/connectors/inbox/agents/${encodeURIComponent(agentId)}/inbox/threads/${encodeURIComponent(threadId)}/close`, opts);
116
+ }
117
+ }
118
+ exports.InboxResource = InboxResource;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentforge-io/sdk-server",
3
- "version": "4.5.2",
3
+ "version": "4.6.0",
4
4
  "description": "Server-side SDK for backend apps integrating with AgentForge platform. Auth via ChatToken or ak_live_ API key.",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",