@agentforge-io/sdk-server 4.0.19 → 4.0.21
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 +11 -0
- package/dist/client.js +14 -3
- package/dist/index.d.ts +2 -1
- package/dist/index.js +3 -1
- package/dist/resources/apps.d.ts +45 -0
- package/dist/resources/apps.js +75 -0
- package/dist/types.d.ts +42 -0
- package/package.json +1 -1
package/dist/client.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AgentsResource } from './resources/agents';
|
|
2
|
+
import { AppsResource } from './resources/apps';
|
|
2
3
|
import { ChatResource } from './resources/chat';
|
|
3
4
|
import { ConnectorsResource } from './resources/connectors';
|
|
4
5
|
import { SecretsResource } from './resources/secrets';
|
|
@@ -10,6 +11,13 @@ export interface AgentForgeClientOptions {
|
|
|
10
11
|
chatToken?: string;
|
|
11
12
|
/** ak_live_... API key scoped to the tenant. */
|
|
12
13
|
apiKey?: string;
|
|
14
|
+
/** sk_live_... secret of a platform App (AGF-070). Authenticates AS the
|
|
15
|
+
* App (the guard resolves its `appId` + tenant). Additive alongside
|
|
16
|
+
* `apiKey` — deprecating `apiKey` is deliberately out of scope (SDD §6
|
|
17
|
+
* decision #4). On the wire it uses the same `Authorization: Bearer`
|
|
18
|
+
* header as `apiKey`; the server's ApiKeyGuard accepts both `ak_live_`
|
|
19
|
+
* and `sk_live_` prefixes. */
|
|
20
|
+
appSecret?: string;
|
|
13
21
|
/** Override fetch (for testing or custom transports). */
|
|
14
22
|
fetch?: typeof fetch;
|
|
15
23
|
/** Default request timeout in ms. Applied to every HTTP call unless
|
|
@@ -37,15 +45,18 @@ export declare class AgentForgeClient {
|
|
|
37
45
|
readonly baseURL: string;
|
|
38
46
|
private readonly chatToken?;
|
|
39
47
|
private readonly apiKey?;
|
|
48
|
+
private readonly appSecret?;
|
|
40
49
|
private readonly fetchImpl;
|
|
41
50
|
private readonly timeoutMs;
|
|
42
51
|
readonly agents: AgentsResource;
|
|
52
|
+
readonly apps: AppsResource;
|
|
43
53
|
readonly chat: ChatResource;
|
|
44
54
|
readonly connectors: ConnectorsResource;
|
|
45
55
|
readonly secrets: SecretsResource;
|
|
46
56
|
readonly tools: ToolsResource;
|
|
47
57
|
constructor(opts: AgentForgeClientOptions);
|
|
48
58
|
authHeaders(): Record<string, string>;
|
|
59
|
+
getAppSecret(): string | undefined;
|
|
49
60
|
getApiKey(): string | undefined;
|
|
50
61
|
getChatToken(): string | undefined;
|
|
51
62
|
/** Como `getApiKey()`, pero tira si el cliente no fue construido con una
|
package/dist/client.js
CHANGED
|
@@ -21,6 +21,7 @@ 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 apps_1 = require("./resources/apps");
|
|
24
25
|
const chat_1 = require("./resources/chat");
|
|
25
26
|
const connectors_1 = require("./resources/connectors");
|
|
26
27
|
const secrets_1 = require("./resources/secrets");
|
|
@@ -30,28 +31,38 @@ class AgentForgeClient {
|
|
|
30
31
|
if (!opts.baseURL) {
|
|
31
32
|
throw new Error('AgentForgeClient: baseURL is required');
|
|
32
33
|
}
|
|
33
|
-
if (!opts.chatToken && !opts.apiKey) {
|
|
34
|
-
throw new Error('AgentForgeClient:
|
|
34
|
+
if (!opts.chatToken && !opts.apiKey && !opts.appSecret) {
|
|
35
|
+
throw new Error('AgentForgeClient: one of chatToken, apiKey, or appSecret is required');
|
|
35
36
|
}
|
|
36
37
|
this.baseURL = opts.baseURL.replace(/\/$/, '');
|
|
37
38
|
this.chatToken = opts.chatToken;
|
|
38
39
|
this.apiKey = opts.apiKey;
|
|
40
|
+
this.appSecret = opts.appSecret;
|
|
39
41
|
this.fetchImpl = opts.fetch ?? fetch;
|
|
40
42
|
this.timeoutMs = opts.timeoutMs ?? 30000;
|
|
41
43
|
this.agents = new agents_1.AgentsResource(this);
|
|
44
|
+
this.apps = new apps_1.AppsResource(this);
|
|
42
45
|
this.chat = new chat_1.ChatResource(this);
|
|
43
46
|
this.connectors = new connectors_1.ConnectorsResource(this);
|
|
44
47
|
this.secrets = new secrets_1.SecretsResource(this);
|
|
45
48
|
this.tools = new tools_1.ToolsResource(this);
|
|
46
49
|
}
|
|
47
|
-
// Auth headers derivados del modo. ChatToken gana si ambos están presentes
|
|
50
|
+
// Auth headers derivados del modo. ChatToken gana si ambos están presentes;
|
|
51
|
+
// luego apiKey (ak_live_); luego appSecret (sk_live_) — ambos secrets viajan
|
|
52
|
+
// en el MISMO header `Authorization: Bearer` porque el ApiKeyGuard del server
|
|
53
|
+
// reconoce ambos prefijos.
|
|
48
54
|
authHeaders() {
|
|
49
55
|
if (this.chatToken)
|
|
50
56
|
return { 'X-Chat-Token': this.chatToken };
|
|
51
57
|
if (this.apiKey)
|
|
52
58
|
return { Authorization: `Bearer ${this.apiKey}` };
|
|
59
|
+
if (this.appSecret)
|
|
60
|
+
return { Authorization: `Bearer ${this.appSecret}` };
|
|
53
61
|
return {};
|
|
54
62
|
}
|
|
63
|
+
getAppSecret() {
|
|
64
|
+
return this.appSecret;
|
|
65
|
+
}
|
|
55
66
|
// Expone el modo auth para que resources puedan tomar decisiones (ej. chat
|
|
56
67
|
// proxy necesita la ak_live_ explícita en x-api-key — no ChatToken).
|
|
57
68
|
getApiKey() {
|
package/dist/index.d.ts
CHANGED
|
@@ -2,8 +2,9 @@ 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, 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';
|
|
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, 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 { AppsResource } from './resources/apps';
|
|
7
8
|
export { ChatResource } from './resources/chat';
|
|
8
9
|
export type { AnthropicClientOptions, StreamMessageInput } from './resources/chat';
|
|
9
10
|
export { ConnectorsResource } from './resources/connectors';
|
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.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;
|
|
31
|
+
exports.ToolsResource = exports.SecretsResource = 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;
|
|
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,6 +43,8 @@ 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 apps_1 = require("./resources/apps");
|
|
47
|
+
Object.defineProperty(exports, "AppsResource", { enumerable: true, get: function () { return apps_1.AppsResource; } });
|
|
46
48
|
var chat_1 = require("./resources/chat");
|
|
47
49
|
Object.defineProperty(exports, "ChatResource", { enumerable: true, get: function () { return chat_1.ChatResource; } });
|
|
48
50
|
var connectors_1 = require("./resources/connectors");
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { AgentForgeClient } from '../client';
|
|
2
|
+
import type { PublicAppBranding, AppSelf, AppSelfConnectors } from '../types';
|
|
3
|
+
export declare class AppsResource {
|
|
4
|
+
private readonly client;
|
|
5
|
+
constructor(client: AgentForgeClient);
|
|
6
|
+
/**
|
|
7
|
+
* `GET /apps/public/:publicKey` — UNAUTHENTICATED branding for a published
|
|
8
|
+
* App, looked up by its public key (`pk_live_...`). Returns only
|
|
9
|
+
* name/description/logo/cover — never any secret material or status.
|
|
10
|
+
*
|
|
11
|
+
* Resolves ONLY for a published, non-revoked App addressed by its
|
|
12
|
+
* `pk_live_` key; every other case (unknown key, `pk_test_`, draft,
|
|
13
|
+
* revoked, malformed) maps to a single opaque **404** →
|
|
14
|
+
* `AgentForgeNotFoundError`, so a caller cannot distinguish "doesn't
|
|
15
|
+
* exist" from "exists but not published".
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* const app = await af.apps.publicMetadata('pk_live_abc…');
|
|
19
|
+
* renderHeader(app.name, app.logoUrl);
|
|
20
|
+
*/
|
|
21
|
+
publicMetadata(publicKey: string): Promise<PublicAppBranding>;
|
|
22
|
+
/**
|
|
23
|
+
* `GET /apps/me` — metadata of the App this client authenticated AS (via
|
|
24
|
+
* `sk_live_` in `appSecret`). Returns branding + status + credential
|
|
25
|
+
* prefixes only — never the plaintext secret or its hash.
|
|
26
|
+
*
|
|
27
|
+
* Requires the client to have an `appSecret`. A `pk_test_`/draft App's
|
|
28
|
+
* `sk_live_` is rejected upstream (403 `not_published`); a client with no
|
|
29
|
+
* `appSecret` gets 401.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* const me = await af.apps.me();
|
|
33
|
+
* if (me.status !== 'published') warnAuthorTheirAppIsDraft();
|
|
34
|
+
*/
|
|
35
|
+
me(): Promise<AppSelf>;
|
|
36
|
+
readonly connectors: {
|
|
37
|
+
/**
|
|
38
|
+
* `GET /apps/me/connectors` — connectors resolved for the App this client
|
|
39
|
+
* authenticated AS, with the same whitelist-vs-legacy `mode` the
|
|
40
|
+
* tenant-admin surface returns. Only `enabled` rows are actually usable
|
|
41
|
+
* by the App at runtime.
|
|
42
|
+
*/
|
|
43
|
+
list: () => Promise<AppSelfConnectors>;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// apps resource (AGF-070 §6) — surfaces the platform "App" object to a
|
|
3
|
+
// consuming client (ScrappyDoc, a widget, etc.) so it never has to hand-roll
|
|
4
|
+
// a fetch against `/apps/*` (the SDK-first rule).
|
|
5
|
+
//
|
|
6
|
+
// A platform App bundles a `pk_live_`/`sk_live_` credential pair + branding +
|
|
7
|
+
// a connector whitelist. This resource exposes three reads:
|
|
8
|
+
//
|
|
9
|
+
// - `publicMetadata(publicKey)` — UNAUTHENTICATED branding lookup by
|
|
10
|
+
// `pk_live_...`. Backed by the existing public endpoint
|
|
11
|
+
// `GET /apps/public/:publicKey` (AGF-070f-pk). Used for the
|
|
12
|
+
// frontend/widget case where only the public key is known.
|
|
13
|
+
// - `me()` / `connectors.list()` — self-metadata for the App the client
|
|
14
|
+
// authenticated AS (via `sk_live_` in `appSecret`). Backed by
|
|
15
|
+
// `GET /apps/me` and `GET /apps/me/connectors` (AGF-070 §6 backend).
|
|
16
|
+
// The client's `appSecret` is sent automatically on the
|
|
17
|
+
// `Authorization: Bearer` header, so the server's `ApiKeyGuard` resolves
|
|
18
|
+
// the calling App and returns ONLY that App — no id/tenant param needed.
|
|
19
|
+
//
|
|
20
|
+
// Auth: `publicMetadata` is unauthenticated (the endpoint is `@Public()`).
|
|
21
|
+
// `me()`/`connectors.list()` require the client to have been constructed with
|
|
22
|
+
// `appSecret` (`sk_live_...`); without it the server answers 401.
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
exports.AppsResource = void 0;
|
|
25
|
+
class AppsResource {
|
|
26
|
+
constructor(client) {
|
|
27
|
+
this.client = client;
|
|
28
|
+
this.connectors = {
|
|
29
|
+
/**
|
|
30
|
+
* `GET /apps/me/connectors` — connectors resolved for the App this client
|
|
31
|
+
* authenticated AS, with the same whitelist-vs-legacy `mode` the
|
|
32
|
+
* tenant-admin surface returns. Only `enabled` rows are actually usable
|
|
33
|
+
* by the App at runtime.
|
|
34
|
+
*/
|
|
35
|
+
list: async () => {
|
|
36
|
+
return this.client.request('GET', '/apps/me/connectors');
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* `GET /apps/public/:publicKey` — UNAUTHENTICATED branding for a published
|
|
42
|
+
* App, looked up by its public key (`pk_live_...`). Returns only
|
|
43
|
+
* name/description/logo/cover — never any secret material or status.
|
|
44
|
+
*
|
|
45
|
+
* Resolves ONLY for a published, non-revoked App addressed by its
|
|
46
|
+
* `pk_live_` key; every other case (unknown key, `pk_test_`, draft,
|
|
47
|
+
* revoked, malformed) maps to a single opaque **404** →
|
|
48
|
+
* `AgentForgeNotFoundError`, so a caller cannot distinguish "doesn't
|
|
49
|
+
* exist" from "exists but not published".
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* const app = await af.apps.publicMetadata('pk_live_abc…');
|
|
53
|
+
* renderHeader(app.name, app.logoUrl);
|
|
54
|
+
*/
|
|
55
|
+
async publicMetadata(publicKey) {
|
|
56
|
+
return this.client.request('GET', `/apps/public/${encodeURIComponent(publicKey)}`);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* `GET /apps/me` — metadata of the App this client authenticated AS (via
|
|
60
|
+
* `sk_live_` in `appSecret`). Returns branding + status + credential
|
|
61
|
+
* prefixes only — never the plaintext secret or its hash.
|
|
62
|
+
*
|
|
63
|
+
* Requires the client to have an `appSecret`. A `pk_test_`/draft App's
|
|
64
|
+
* `sk_live_` is rejected upstream (403 `not_published`); a client with no
|
|
65
|
+
* `appSecret` gets 401.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* const me = await af.apps.me();
|
|
69
|
+
* if (me.status !== 'published') warnAuthorTheirAppIsDraft();
|
|
70
|
+
*/
|
|
71
|
+
async me() {
|
|
72
|
+
return this.client.request('GET', '/apps/me');
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
exports.AppsResource = AppsResource;
|
package/dist/types.d.ts
CHANGED
|
@@ -42,6 +42,48 @@ export interface AgentMe {
|
|
|
42
42
|
updatedAt: string | Date;
|
|
43
43
|
externalTools: ExternalToolSummary[];
|
|
44
44
|
}
|
|
45
|
+
export interface PublicAppBranding {
|
|
46
|
+
name: string;
|
|
47
|
+
description: string | null;
|
|
48
|
+
logoUrl: string | null;
|
|
49
|
+
coverUrl: string | null;
|
|
50
|
+
}
|
|
51
|
+
export interface AppSelf {
|
|
52
|
+
id: string;
|
|
53
|
+
name: string;
|
|
54
|
+
description: string | null;
|
|
55
|
+
logoUrl: string | null;
|
|
56
|
+
coverUrl: string | null;
|
|
57
|
+
content: string | null;
|
|
58
|
+
status: 'draft' | 'published';
|
|
59
|
+
publicKey: string;
|
|
60
|
+
apiSecretPrefix: string;
|
|
61
|
+
publicKeyTest: string | null;
|
|
62
|
+
apiSecretTestPrefix: string | null;
|
|
63
|
+
revokedAt: string | null;
|
|
64
|
+
lastUsedAt: string | null;
|
|
65
|
+
createdAt: string;
|
|
66
|
+
updatedAt: string;
|
|
67
|
+
}
|
|
68
|
+
export interface AppSelfConnector {
|
|
69
|
+
connectorId: string;
|
|
70
|
+
name: string;
|
|
71
|
+
iconUrl?: string;
|
|
72
|
+
/** Available to this App via the tenant's connected connectors. */
|
|
73
|
+
available: boolean;
|
|
74
|
+
/** Enabled for this App (whitelist row `enabled`, or `available` when the
|
|
75
|
+
* App has no whitelist rows and falls back to legacy allow-all). */
|
|
76
|
+
enabled: boolean;
|
|
77
|
+
/** The App has a per-tool permission override for this connector. */
|
|
78
|
+
hasOverride: boolean;
|
|
79
|
+
}
|
|
80
|
+
export interface AppSelfConnectors {
|
|
81
|
+
/** `'whitelist'` — the App has >=1 explicit row; only `enabled` counts.
|
|
82
|
+
* `'legacy'` — zero rows, every tenant-connected connector is implicitly
|
|
83
|
+
* available. */
|
|
84
|
+
mode: 'whitelist' | 'legacy';
|
|
85
|
+
connectors: AppSelfConnector[];
|
|
86
|
+
}
|
|
45
87
|
export interface RegisterToolInput {
|
|
46
88
|
name: string;
|
|
47
89
|
description: string;
|
package/package.json
CHANGED