@agentforge-io/sdk-server 4.5.3 → 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 +4 -0
- package/dist/client.js +4 -0
- package/dist/index.d.ts +6 -2
- package/dist/index.js +5 -1
- package/dist/resources/analytics.d.ts +72 -0
- package/dist/resources/analytics.js +59 -0
- package/dist/resources/apps.d.ts +1 -18
- package/dist/resources/apps.js +0 -19
- package/dist/resources/inbox.d.ts +113 -0
- package/dist/resources/inbox.js +118 -0
- package/dist/resources/provisioning.d.ts +0 -31
- package/dist/resources/provisioning.js +0 -25
- package/dist/types.d.ts +0 -10
- package/package.json +1 -1
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
|
@@ -2,15 +2,19 @@ export { AgentForgeClient } from './client';
|
|
|
2
2
|
export type { AgentForgeClientOptions, RequestOptions } from './client';
|
|
3
3
|
export { AgentForgeError, AgentForgeAuthError, AgentForgeNotFoundError, AgentForgeNetworkError, } from './errors';
|
|
4
4
|
export { TOOL_CALLBACK_HEADERS, ToolCallbackSignatureError, signToolCallbackPayload, verifyToolCallbackSignature, } from './webhooks';
|
|
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,
|
|
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
|
-
export type { ProvisionedTenant, ProvisionedApp,
|
|
17
|
+
export type { ProvisionedTenant, ProvisionedApp, } from './resources/provisioning';
|
|
14
18
|
export { SecretsResource } from './resources/secrets';
|
|
15
19
|
export { ToolsResource } from './resources/tools';
|
|
16
20
|
export type { RespondToCallbackInput, VerifyCallbackInput } from './resources/tools';
|
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;
|
package/dist/resources/apps.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AgentForgeClient } from '../client';
|
|
2
|
-
import type { PublicAppBranding, AppSelf, AppSelfConnectors
|
|
2
|
+
import type { PublicAppBranding, AppSelf, AppSelfConnectors } from '../types';
|
|
3
3
|
export declare class AppsResource {
|
|
4
4
|
private readonly client;
|
|
5
5
|
constructor(client: AgentForgeClient);
|
|
@@ -41,22 +41,5 @@ export declare class AppsResource {
|
|
|
41
41
|
* by the App at runtime.
|
|
42
42
|
*/
|
|
43
43
|
list: () => Promise<AppSelfConnectors>;
|
|
44
|
-
/**
|
|
45
|
-
* `GET /apps/me/connector-tools` (AGF-CTG-1) — flat tool-name catalog
|
|
46
|
-
* contributed by the connectors ENABLED for the App this client
|
|
47
|
-
* authenticated AS. App-level granularity ONLY: this is NOT narrowed
|
|
48
|
-
* per-end-user — that narrowing already happens downstream at runtime
|
|
49
|
-
* via `toolsForAppUser ∩ agent.tools[]`.
|
|
50
|
-
*
|
|
51
|
-
* Intended for a consumer bootstrap to DERIVE its connector-tool
|
|
52
|
-
* whitelist from the App's actually-enabled connectors instead of
|
|
53
|
-
* hardcoding tool names by hand — the top-level `toolNames` is the
|
|
54
|
-
* flat, de-duplicated union across every enabled connector.
|
|
55
|
-
*
|
|
56
|
-
* @example
|
|
57
|
-
* const { toolNames } = await af.apps.connectors.tools();
|
|
58
|
-
* const allowed = new Set(toolNames);
|
|
59
|
-
*/
|
|
60
|
-
tools: () => Promise<AppSelfConnectorToolsResponse>;
|
|
61
44
|
};
|
|
62
45
|
}
|
package/dist/resources/apps.js
CHANGED
|
@@ -35,25 +35,6 @@ class AppsResource {
|
|
|
35
35
|
list: async () => {
|
|
36
36
|
return this.client.request('GET', '/apps/me/connectors');
|
|
37
37
|
},
|
|
38
|
-
/**
|
|
39
|
-
* `GET /apps/me/connector-tools` (AGF-CTG-1) — flat tool-name catalog
|
|
40
|
-
* contributed by the connectors ENABLED for the App this client
|
|
41
|
-
* authenticated AS. App-level granularity ONLY: this is NOT narrowed
|
|
42
|
-
* per-end-user — that narrowing already happens downstream at runtime
|
|
43
|
-
* via `toolsForAppUser ∩ agent.tools[]`.
|
|
44
|
-
*
|
|
45
|
-
* Intended for a consumer bootstrap to DERIVE its connector-tool
|
|
46
|
-
* whitelist from the App's actually-enabled connectors instead of
|
|
47
|
-
* hardcoding tool names by hand — the top-level `toolNames` is the
|
|
48
|
-
* flat, de-duplicated union across every enabled connector.
|
|
49
|
-
*
|
|
50
|
-
* @example
|
|
51
|
-
* const { toolNames } = await af.apps.connectors.tools();
|
|
52
|
-
* const allowed = new Set(toolNames);
|
|
53
|
-
*/
|
|
54
|
-
tools: async () => {
|
|
55
|
-
return this.client.request('GET', '/apps/me/connector-tools');
|
|
56
|
-
},
|
|
57
38
|
};
|
|
58
39
|
}
|
|
59
40
|
/**
|
|
@@ -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;
|
|
@@ -11,14 +11,6 @@ export interface ProvisionedApp {
|
|
|
11
11
|
publicKey: string;
|
|
12
12
|
appSecret: string;
|
|
13
13
|
}
|
|
14
|
-
/** `POST /platform/host-teams` result — a team-orchestrator's identity
|
|
15
|
-
* (AGF-SD-6a). No secret to reveal here (unlike `tenant()`/`app()`) — a
|
|
16
|
-
* team has no credential of its own, it's addressed through the
|
|
17
|
-
* tenant's `ak_live_` / App's `sk_live_`. */
|
|
18
|
-
export interface ProvisionedTeam {
|
|
19
|
-
teamId: string;
|
|
20
|
-
orchestratorAgentId: string;
|
|
21
|
-
}
|
|
22
14
|
export declare class ProvisioningResource {
|
|
23
15
|
private readonly client;
|
|
24
16
|
constructor(client: AgentForgeClient);
|
|
@@ -57,27 +49,4 @@ export declare class ProvisioningResource {
|
|
|
57
49
|
hostApp: string;
|
|
58
50
|
hostRef?: string;
|
|
59
51
|
}): Promise<ProvisionedApp>;
|
|
60
|
-
/**
|
|
61
|
-
* `POST /platform/host-teams` (AGF-SD-6a) — find-or-create a
|
|
62
|
-
* team-orchestrator for an EXISTING tenant on behalf of a trusted host
|
|
63
|
-
* app. Idempotent by `(tenantId, hostRef)`: a re-provision returns the
|
|
64
|
-
* SAME `teamId`/`orchestratorAgentId`, never a duplicate orchestrator.
|
|
65
|
-
*
|
|
66
|
-
* @param input.tenantId the tenant the team belongs to (host provisions
|
|
67
|
-
* it first via `tenant()`)
|
|
68
|
-
* @param input.hostApp short host id (e.g. "scrappydoc") — recorded
|
|
69
|
-
* for parity with `tenant()`/`app()`, not part of
|
|
70
|
-
* the idempotency key here (a team already lives
|
|
71
|
-
* under one tenant, so `(tenantId, hostRef)`
|
|
72
|
-
* alone is unambiguous)
|
|
73
|
-
* @param input.hostRef host reference (e.g. the workspaceId) — the
|
|
74
|
-
* idempotency key together with `tenantId`
|
|
75
|
-
* @param input.name display name, only used on first provision
|
|
76
|
-
*/
|
|
77
|
-
team(input: {
|
|
78
|
-
tenantId: string;
|
|
79
|
-
hostApp: string;
|
|
80
|
-
hostRef: string;
|
|
81
|
-
name?: string;
|
|
82
|
-
}): Promise<ProvisionedTeam>;
|
|
83
52
|
}
|
|
@@ -51,30 +51,5 @@ class ProvisioningResource {
|
|
|
51
51
|
async app(input) {
|
|
52
52
|
return this.client.request('POST', '/platform/host-apps', { tenantId: input.tenantId, hostApp: input.hostApp, hostRef: input.hostRef }, { headers: this.headers() });
|
|
53
53
|
}
|
|
54
|
-
/**
|
|
55
|
-
* `POST /platform/host-teams` (AGF-SD-6a) — find-or-create a
|
|
56
|
-
* team-orchestrator for an EXISTING tenant on behalf of a trusted host
|
|
57
|
-
* app. Idempotent by `(tenantId, hostRef)`: a re-provision returns the
|
|
58
|
-
* SAME `teamId`/`orchestratorAgentId`, never a duplicate orchestrator.
|
|
59
|
-
*
|
|
60
|
-
* @param input.tenantId the tenant the team belongs to (host provisions
|
|
61
|
-
* it first via `tenant()`)
|
|
62
|
-
* @param input.hostApp short host id (e.g. "scrappydoc") — recorded
|
|
63
|
-
* for parity with `tenant()`/`app()`, not part of
|
|
64
|
-
* the idempotency key here (a team already lives
|
|
65
|
-
* under one tenant, so `(tenantId, hostRef)`
|
|
66
|
-
* alone is unambiguous)
|
|
67
|
-
* @param input.hostRef host reference (e.g. the workspaceId) — the
|
|
68
|
-
* idempotency key together with `tenantId`
|
|
69
|
-
* @param input.name display name, only used on first provision
|
|
70
|
-
*/
|
|
71
|
-
async team(input) {
|
|
72
|
-
return this.client.request('POST', '/platform/host-teams', {
|
|
73
|
-
tenantId: input.tenantId,
|
|
74
|
-
hostApp: input.hostApp,
|
|
75
|
-
hostRef: input.hostRef,
|
|
76
|
-
name: input.name,
|
|
77
|
-
}, { headers: this.headers() });
|
|
78
|
-
}
|
|
79
54
|
}
|
|
80
55
|
exports.ProvisioningResource = ProvisioningResource;
|
package/dist/types.d.ts
CHANGED
|
@@ -84,16 +84,6 @@ export interface AppSelfConnectors {
|
|
|
84
84
|
mode: 'whitelist' | 'legacy';
|
|
85
85
|
connectors: AppSelfConnector[];
|
|
86
86
|
}
|
|
87
|
-
export interface AppSelfConnectorTools {
|
|
88
|
-
connectorId: string;
|
|
89
|
-
toolNames: string[];
|
|
90
|
-
}
|
|
91
|
-
export interface AppSelfConnectorToolsResponse {
|
|
92
|
-
connectors: AppSelfConnectorTools[];
|
|
93
|
-
/** Flat, de-duplicated union of every `toolNames` entry above — this is
|
|
94
|
-
* what a whitelist consumer actually wants. */
|
|
95
|
-
toolNames: string[];
|
|
96
|
-
}
|
|
97
87
|
export interface RegisterToolInput {
|
|
98
88
|
name: string;
|
|
99
89
|
description: string;
|
package/package.json
CHANGED