@agentforge-io/sdk-server 4.0.19 → 4.0.20
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 +37 -0
- package/dist/resources/apps.js +72 -0
- package/dist/types.d.ts +6 -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, 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,37 @@
|
|
|
1
|
+
import type { AgentForgeClient } from '../client';
|
|
2
|
+
import type { PublicAppBranding } 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
|
+
* Metadata of the App this client authenticated AS (via `sk_live_` in
|
|
24
|
+
* `appSecret`). NOT YET AVAILABLE — the `sk_live_` guard resolves the App
|
|
25
|
+
* server-side, but no "self" endpoint returns it. Throws until the backend
|
|
26
|
+
* half of §6 lands, so callers get a clear signal instead of a 404.
|
|
27
|
+
*/
|
|
28
|
+
me(): Promise<never>;
|
|
29
|
+
readonly connectors: {
|
|
30
|
+
/**
|
|
31
|
+
* Connectors enabled for the authenticated App. NOT YET AVAILABLE — same
|
|
32
|
+
* reason as `me()`: needs a `sk_live_`-authenticated self endpoint that
|
|
33
|
+
* doesn't exist yet.
|
|
34
|
+
*/
|
|
35
|
+
list: () => Promise<never>;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
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`). These need
|
|
15
|
+
// server-side "self" endpoints that DON'T EXIST YET (the guard resolves
|
|
16
|
+
// the App from `sk_live_`, but no controller returns it) — they throw a
|
|
17
|
+
// clear NotImplemented until the backend half lands, rather than silently
|
|
18
|
+
// hitting a 404. See the §6 note in the task ledger.
|
|
19
|
+
//
|
|
20
|
+
// Auth: `publicMetadata` is unauthenticated (the endpoint is `@Public()`), so
|
|
21
|
+
// it works even on a client constructed with only a `baseURL`-less-secret
|
|
22
|
+
// path is N/A here — we call the raw endpoint directly. `me()`/`connectors`
|
|
23
|
+
// will use the `sk_live_` (`appSecret`) auth once their endpoints exist.
|
|
24
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
+
exports.AppsResource = void 0;
|
|
26
|
+
class AppsResource {
|
|
27
|
+
constructor(client) {
|
|
28
|
+
this.client = client;
|
|
29
|
+
this.connectors = {
|
|
30
|
+
/**
|
|
31
|
+
* Connectors enabled for the authenticated App. NOT YET AVAILABLE — same
|
|
32
|
+
* reason as `me()`: needs a `sk_live_`-authenticated self endpoint that
|
|
33
|
+
* doesn't exist yet.
|
|
34
|
+
*/
|
|
35
|
+
list: async () => {
|
|
36
|
+
throw new Error('AppsResource.connectors.list() is not available yet — needs a ' +
|
|
37
|
+
"sk_live_-authenticated self endpoint (GET /apps/me/connectors) that hasn't " +
|
|
38
|
+
'been implemented. See AGF-070 §6.');
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* `GET /apps/public/:publicKey` — UNAUTHENTICATED branding for a published
|
|
44
|
+
* App, looked up by its public key (`pk_live_...`). Returns only
|
|
45
|
+
* name/description/logo/cover — never any secret material or status.
|
|
46
|
+
*
|
|
47
|
+
* Resolves ONLY for a published, non-revoked App addressed by its
|
|
48
|
+
* `pk_live_` key; every other case (unknown key, `pk_test_`, draft,
|
|
49
|
+
* revoked, malformed) maps to a single opaque **404** →
|
|
50
|
+
* `AgentForgeNotFoundError`, so a caller cannot distinguish "doesn't
|
|
51
|
+
* exist" from "exists but not published".
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* const app = await af.apps.publicMetadata('pk_live_abc…');
|
|
55
|
+
* renderHeader(app.name, app.logoUrl);
|
|
56
|
+
*/
|
|
57
|
+
async publicMetadata(publicKey) {
|
|
58
|
+
return this.client.request('GET', `/apps/public/${encodeURIComponent(publicKey)}`);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Metadata of the App this client authenticated AS (via `sk_live_` in
|
|
62
|
+
* `appSecret`). NOT YET AVAILABLE — the `sk_live_` guard resolves the App
|
|
63
|
+
* server-side, but no "self" endpoint returns it. Throws until the backend
|
|
64
|
+
* half of §6 lands, so callers get a clear signal instead of a 404.
|
|
65
|
+
*/
|
|
66
|
+
async me() {
|
|
67
|
+
throw new Error('AppsResource.me() is not available yet — the server-side self endpoint ' +
|
|
68
|
+
"(GET /apps/me, authenticated by sk_live_) hasn't been implemented. " +
|
|
69
|
+
'Use publicMetadata(publicKey) for branding by public key in the meantime.');
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
exports.AppsResource = AppsResource;
|
package/dist/types.d.ts
CHANGED
|
@@ -42,6 +42,12 @@ 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
|
+
}
|
|
45
51
|
export interface RegisterToolInput {
|
|
46
52
|
name: string;
|
|
47
53
|
description: string;
|
package/package.json
CHANGED