@firststep-studio/sdk 0.1.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/README.md ADDED
@@ -0,0 +1,40 @@
1
+ # @firststep-studio/sdk
2
+
3
+ SDK for building protocol handlers that integrate with FirstStep Studio.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @firststep-studio/sdk
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```typescript
14
+ import { createServer } from '@firststep-studio/sdk/server';
15
+ import type { ProtocolHandler } from '@firststep-studio/sdk';
16
+
17
+ const handler: ProtocolHandler = {
18
+ async handleMessage(request, context) {
19
+ return {
20
+ message: `Echo: ${request.message}`,
21
+ sessionId: request.sessionId || `session-${Date.now()}`,
22
+ agentId: 'main',
23
+ sessionStatus: 'active',
24
+ };
25
+ },
26
+ getCapabilities() {
27
+ return { streaming: false, formQuestions: false, knowledgeActions: false, integrations: false };
28
+ },
29
+ };
30
+
31
+ createServer(handler, {
32
+ token: process.env.FIRSTSTEP_TOKEN || '',
33
+ port: 4001,
34
+ skipSignatureVerification: !process.env.FIRSTSTEP_TOKEN,
35
+ }).start();
36
+ ```
37
+
38
+ ## LLM Reference
39
+
40
+ See `llms.txt` for full API specification.
@@ -0,0 +1,299 @@
1
+ import { C as ChatMessage } from './types-Bm98aHcd.mjs';
2
+ export { A as AnalyticsContext, r as ChatbotInfo, s as ClassifierConfig, D as DeploymentInfo, F as FormData, z as FormFieldDefinition, B as FormFieldType, t as FormFieldValue, y as FormSchema, H as HandlerInfo, q as Helpline, p as HelplineResult, o as HelplineSearchOptions, I as IntegrationContext, n as IntegrationResult, w as InteractionEvent, x as InteractionEventType, K as KnowledgeContext, m as KnowledgeResult, L as LoggerContext, i as ProtocolCapabilities, j as ProtocolContext, g as ProtocolError, e as ProtocolFieldValidation, b as ProtocolForm, c as ProtocolFormField, d as ProtocolFormOption, h as ProtocolHandler, E as ProtocolRegistration, P as ProtocolRequest, a as ProtocolResponse, f as ProtocolStreamChunk, R as RoutingDecision, u as RoutingLog, k as SessionContext, v as SessionMetadata, l as SessionState, S as SessionStatus } from './types-Bm98aHcd.mjs';
3
+
4
+ /**
5
+ * UCP (Universal Classification Protocol) Types
6
+ *
7
+ * Standard protocol for communicating with classifier services.
8
+ * Any classifier implementing UCP can be used with FirstStep SDK.
9
+ */
10
+ /**
11
+ * UCP Message format for classification
12
+ */
13
+ interface UCPMessage {
14
+ /** Unique message ID */
15
+ id: string;
16
+ /** Message role */
17
+ role: 'user' | 'assistant';
18
+ /** Message content */
19
+ content: string;
20
+ /** Unix timestamp (ms) */
21
+ timestamp: number;
22
+ /** Optional metadata */
23
+ metadata?: Record<string, unknown>;
24
+ }
25
+ /**
26
+ * UCP Classification Request
27
+ */
28
+ interface UCPClassifyRequest {
29
+ /** Messages to classify */
30
+ messages: UCPMessage[];
31
+ }
32
+ /**
33
+ * UCP Classification Response
34
+ */
35
+ interface UCPClassifyResponse {
36
+ /** Classification category */
37
+ category: string;
38
+ /** Classification level */
39
+ level: string;
40
+ /** Classification score (0-100) */
41
+ score: number;
42
+ /** Rationale for classification */
43
+ rationale: string;
44
+ /** Additional metadata */
45
+ metadata?: {
46
+ executionTime?: number;
47
+ timestamp?: number;
48
+ [key: string]: unknown;
49
+ };
50
+ /** All category results (for multi-category classifiers) */
51
+ allCategoryResults?: Array<{
52
+ category: string;
53
+ level: string;
54
+ score: number;
55
+ }>;
56
+ }
57
+ /**
58
+ * UCP Error Response
59
+ */
60
+ interface UCPErrorResponse {
61
+ error: {
62
+ code: string;
63
+ message: string;
64
+ details?: unknown;
65
+ };
66
+ }
67
+ /**
68
+ * UCP Classifier Info Response
69
+ */
70
+ interface UCPInfoResponse {
71
+ /** Classifier name */
72
+ name: string;
73
+ /** Classifier version */
74
+ version: string;
75
+ /** Classifier description */
76
+ description: string;
77
+ /** Provider info */
78
+ provider: {
79
+ name: string;
80
+ website?: string;
81
+ contact?: string;
82
+ };
83
+ /** Classifier capabilities */
84
+ capabilities: {
85
+ maxConversationTurns: number;
86
+ averageLatency: number;
87
+ supportsBatch?: boolean;
88
+ };
89
+ /** Pricing info */
90
+ pricing?: {
91
+ tier: string;
92
+ pricePerRequest?: number;
93
+ currency?: string;
94
+ };
95
+ }
96
+ /**
97
+ * UCP Client configuration
98
+ */
99
+ interface UCPClientConfig {
100
+ /** Base URL of the UCP endpoint (e.g., "https://api.example.com/ucp/v1") */
101
+ baseUrl: string;
102
+ /** Classifier ID */
103
+ classifierId: string;
104
+ /** API key for authentication (optional) */
105
+ apiKey?: string;
106
+ /** Request timeout in ms (default: 30000) */
107
+ timeout?: number;
108
+ /** Custom headers */
109
+ headers?: Record<string, string>;
110
+ }
111
+ /**
112
+ * Simplified configuration using just a URL
113
+ * URL format: {baseUrl}/classifiers/{classifierId}
114
+ */
115
+ interface UCPEndpointConfig {
116
+ /** Full endpoint URL */
117
+ endpoint: string;
118
+ /** API key for authentication (optional) */
119
+ apiKey?: string;
120
+ /** Request timeout in ms (default: 30000) */
121
+ timeout?: number;
122
+ }
123
+ /**
124
+ * Classification result for SDK consumers
125
+ * Normalized from UCP response
126
+ */
127
+ interface ClassificationResult {
128
+ /** Classifier ID or endpoint */
129
+ classifierId: string;
130
+ /** Classification category */
131
+ category: string;
132
+ /** Classification level */
133
+ level: string;
134
+ /** Classification score (normalized to 0-1) */
135
+ confidence: number;
136
+ /** Rationale/reasoning */
137
+ reasoning?: string;
138
+ /** Raw UCP response */
139
+ raw?: UCPClassifyResponse;
140
+ }
141
+
142
+ /**
143
+ * UCP (Universal Classification Protocol) Client
144
+ *
145
+ * Client for communicating with UCP-compliant classifier endpoints.
146
+ * Supports both full configuration and simple endpoint URL.
147
+ *
148
+ * @example
149
+ * ```typescript
150
+ * // Simple usage with endpoint URL
151
+ * const client = UCPClient.fromEndpoint('https://api.example.com/ucp/v1/classifiers/abc123');
152
+ *
153
+ * // With API key
154
+ * const client = UCPClient.fromEndpoint(
155
+ * 'https://api.example.com/ucp/v1/classifiers/abc123',
156
+ * { apiKey: 'your-api-key' }
157
+ * );
158
+ *
159
+ * // Classify messages
160
+ * const result = await client.classify(messages);
161
+ * ```
162
+ */
163
+
164
+ /**
165
+ * UCP Client for classifier communication
166
+ */
167
+ declare class UCPClient {
168
+ private baseUrl;
169
+ private classifierId;
170
+ private apiKey?;
171
+ private timeout;
172
+ private headers;
173
+ constructor(config: UCPClientConfig);
174
+ /**
175
+ * Create client from a full endpoint URL
176
+ *
177
+ * URL format: {baseUrl}/classifiers/{classifierId}
178
+ * Example: https://api.example.com/ucp/v1/classifiers/abc123
179
+ */
180
+ static fromEndpoint(endpoint: string, options?: {
181
+ apiKey?: string;
182
+ timeout?: number;
183
+ }): UCPClient;
184
+ /**
185
+ * Get the classify endpoint URL
186
+ */
187
+ get classifyUrl(): string;
188
+ /**
189
+ * Get the info endpoint URL
190
+ */
191
+ get infoUrl(): string;
192
+ /**
193
+ * Classify messages using UCP protocol
194
+ */
195
+ classify(messages: UCPMessage[]): Promise<ClassificationResult>;
196
+ /**
197
+ * Classify ChatMessage array (convenience method)
198
+ * Converts ChatMessage to UCPMessage format
199
+ */
200
+ classifyChat(messages: ChatMessage[]): Promise<ClassificationResult>;
201
+ /**
202
+ * Get classifier info
203
+ */
204
+ getInfo(): Promise<UCPInfoResponse>;
205
+ /**
206
+ * Check if the classifier endpoint is reachable
207
+ */
208
+ healthCheck(): Promise<boolean>;
209
+ /**
210
+ * Internal fetch helper with error handling
211
+ */
212
+ private fetch;
213
+ }
214
+ /**
215
+ * UCP-specific error class
216
+ */
217
+ declare class UCPError extends Error {
218
+ code: string;
219
+ details?: unknown | undefined;
220
+ constructor(code: string, message: string, details?: unknown | undefined);
221
+ }
222
+ /**
223
+ * Create a UCP client from an endpoint URL
224
+ */
225
+ declare function createUCPClient(endpoint: string, options?: {
226
+ apiKey?: string;
227
+ timeout?: number;
228
+ }): UCPClient;
229
+ /**
230
+ * Classify messages using a UCP endpoint
231
+ * One-shot function for simple usage
232
+ */
233
+ declare function classifyWithUCP(endpoint: string, messages: ChatMessage[], options?: {
234
+ apiKey?: string;
235
+ timeout?: number;
236
+ }): Promise<ClassificationResult>;
237
+
238
+ /**
239
+ * Verify an HMAC-SHA256 request signature.
240
+ *
241
+ * The handler server can use this to verify that incoming webhook
242
+ * requests were signed by the FirstStep platform using the shared token.
243
+ *
244
+ * @param token - The API token (FIRSTSTEP_TOKEN)
245
+ * @param payload - The raw request body string
246
+ * @param signature - The signature from the X-FirstStep-Signature header
247
+ * @returns true if the signature is valid
248
+ *
249
+ * @example
250
+ * ```typescript
251
+ * import { verifyRequestSignature } from '@firststep-studio/sdk';
252
+ *
253
+ * app.post('/webhook', (req, res) => {
254
+ * const signature = req.headers['x-firststep-signature'] as string;
255
+ * if (!verifyRequestSignature(process.env.FIRSTSTEP_TOKEN!, req.body, signature)) {
256
+ * return res.status(401).send('Invalid signature');
257
+ * }
258
+ * // Process the request...
259
+ * });
260
+ * ```
261
+ */
262
+ declare function verifyRequestSignature(token: string, payload: string, signature: string): boolean;
263
+ /**
264
+ * Create an HMAC-SHA256 signature for a payload.
265
+ *
266
+ * Used by the platform to sign outgoing requests to handler servers.
267
+ *
268
+ * @param token - The API token
269
+ * @param payload - The request body string to sign
270
+ * @returns The hex-encoded HMAC signature
271
+ */
272
+ declare function createRequestSignature(token: string, payload: string): string;
273
+ /**
274
+ * Create an Authorization header value for API requests.
275
+ *
276
+ * @param token - The API token (fst_xxx)
277
+ * @returns The header value, e.g. "Bearer fst_xxx"
278
+ *
279
+ * @example
280
+ * ```typescript
281
+ * import { createAuthHeader } from '@firststep-studio/sdk';
282
+ *
283
+ * const response = await fetch('https://api.firststep.ai/api/projects', {
284
+ * headers: {
285
+ * 'Authorization': createAuthHeader(process.env.FIRSTSTEP_TOKEN!),
286
+ * },
287
+ * });
288
+ * ```
289
+ */
290
+ declare function createAuthHeader(token: string): string;
291
+ /**
292
+ * Validate that a token has the correct format (fst_ prefix + 40 hex chars).
293
+ *
294
+ * @param token - The token string to validate
295
+ * @returns true if the token matches the expected format
296
+ */
297
+ declare function isValidToken(token: string): boolean;
298
+
299
+ export { ChatMessage, type ClassificationResult, type UCPClassifyRequest, type UCPClassifyResponse, UCPClient, type UCPClientConfig, type UCPEndpointConfig, UCPError, type UCPErrorResponse, type UCPInfoResponse, type UCPMessage, classifyWithUCP, createAuthHeader, createRequestSignature, createUCPClient, isValidToken, verifyRequestSignature };
@@ -0,0 +1,299 @@
1
+ import { C as ChatMessage } from './types-Bm98aHcd.js';
2
+ export { A as AnalyticsContext, r as ChatbotInfo, s as ClassifierConfig, D as DeploymentInfo, F as FormData, z as FormFieldDefinition, B as FormFieldType, t as FormFieldValue, y as FormSchema, H as HandlerInfo, q as Helpline, p as HelplineResult, o as HelplineSearchOptions, I as IntegrationContext, n as IntegrationResult, w as InteractionEvent, x as InteractionEventType, K as KnowledgeContext, m as KnowledgeResult, L as LoggerContext, i as ProtocolCapabilities, j as ProtocolContext, g as ProtocolError, e as ProtocolFieldValidation, b as ProtocolForm, c as ProtocolFormField, d as ProtocolFormOption, h as ProtocolHandler, E as ProtocolRegistration, P as ProtocolRequest, a as ProtocolResponse, f as ProtocolStreamChunk, R as RoutingDecision, u as RoutingLog, k as SessionContext, v as SessionMetadata, l as SessionState, S as SessionStatus } from './types-Bm98aHcd.js';
3
+
4
+ /**
5
+ * UCP (Universal Classification Protocol) Types
6
+ *
7
+ * Standard protocol for communicating with classifier services.
8
+ * Any classifier implementing UCP can be used with FirstStep SDK.
9
+ */
10
+ /**
11
+ * UCP Message format for classification
12
+ */
13
+ interface UCPMessage {
14
+ /** Unique message ID */
15
+ id: string;
16
+ /** Message role */
17
+ role: 'user' | 'assistant';
18
+ /** Message content */
19
+ content: string;
20
+ /** Unix timestamp (ms) */
21
+ timestamp: number;
22
+ /** Optional metadata */
23
+ metadata?: Record<string, unknown>;
24
+ }
25
+ /**
26
+ * UCP Classification Request
27
+ */
28
+ interface UCPClassifyRequest {
29
+ /** Messages to classify */
30
+ messages: UCPMessage[];
31
+ }
32
+ /**
33
+ * UCP Classification Response
34
+ */
35
+ interface UCPClassifyResponse {
36
+ /** Classification category */
37
+ category: string;
38
+ /** Classification level */
39
+ level: string;
40
+ /** Classification score (0-100) */
41
+ score: number;
42
+ /** Rationale for classification */
43
+ rationale: string;
44
+ /** Additional metadata */
45
+ metadata?: {
46
+ executionTime?: number;
47
+ timestamp?: number;
48
+ [key: string]: unknown;
49
+ };
50
+ /** All category results (for multi-category classifiers) */
51
+ allCategoryResults?: Array<{
52
+ category: string;
53
+ level: string;
54
+ score: number;
55
+ }>;
56
+ }
57
+ /**
58
+ * UCP Error Response
59
+ */
60
+ interface UCPErrorResponse {
61
+ error: {
62
+ code: string;
63
+ message: string;
64
+ details?: unknown;
65
+ };
66
+ }
67
+ /**
68
+ * UCP Classifier Info Response
69
+ */
70
+ interface UCPInfoResponse {
71
+ /** Classifier name */
72
+ name: string;
73
+ /** Classifier version */
74
+ version: string;
75
+ /** Classifier description */
76
+ description: string;
77
+ /** Provider info */
78
+ provider: {
79
+ name: string;
80
+ website?: string;
81
+ contact?: string;
82
+ };
83
+ /** Classifier capabilities */
84
+ capabilities: {
85
+ maxConversationTurns: number;
86
+ averageLatency: number;
87
+ supportsBatch?: boolean;
88
+ };
89
+ /** Pricing info */
90
+ pricing?: {
91
+ tier: string;
92
+ pricePerRequest?: number;
93
+ currency?: string;
94
+ };
95
+ }
96
+ /**
97
+ * UCP Client configuration
98
+ */
99
+ interface UCPClientConfig {
100
+ /** Base URL of the UCP endpoint (e.g., "https://api.example.com/ucp/v1") */
101
+ baseUrl: string;
102
+ /** Classifier ID */
103
+ classifierId: string;
104
+ /** API key for authentication (optional) */
105
+ apiKey?: string;
106
+ /** Request timeout in ms (default: 30000) */
107
+ timeout?: number;
108
+ /** Custom headers */
109
+ headers?: Record<string, string>;
110
+ }
111
+ /**
112
+ * Simplified configuration using just a URL
113
+ * URL format: {baseUrl}/classifiers/{classifierId}
114
+ */
115
+ interface UCPEndpointConfig {
116
+ /** Full endpoint URL */
117
+ endpoint: string;
118
+ /** API key for authentication (optional) */
119
+ apiKey?: string;
120
+ /** Request timeout in ms (default: 30000) */
121
+ timeout?: number;
122
+ }
123
+ /**
124
+ * Classification result for SDK consumers
125
+ * Normalized from UCP response
126
+ */
127
+ interface ClassificationResult {
128
+ /** Classifier ID or endpoint */
129
+ classifierId: string;
130
+ /** Classification category */
131
+ category: string;
132
+ /** Classification level */
133
+ level: string;
134
+ /** Classification score (normalized to 0-1) */
135
+ confidence: number;
136
+ /** Rationale/reasoning */
137
+ reasoning?: string;
138
+ /** Raw UCP response */
139
+ raw?: UCPClassifyResponse;
140
+ }
141
+
142
+ /**
143
+ * UCP (Universal Classification Protocol) Client
144
+ *
145
+ * Client for communicating with UCP-compliant classifier endpoints.
146
+ * Supports both full configuration and simple endpoint URL.
147
+ *
148
+ * @example
149
+ * ```typescript
150
+ * // Simple usage with endpoint URL
151
+ * const client = UCPClient.fromEndpoint('https://api.example.com/ucp/v1/classifiers/abc123');
152
+ *
153
+ * // With API key
154
+ * const client = UCPClient.fromEndpoint(
155
+ * 'https://api.example.com/ucp/v1/classifiers/abc123',
156
+ * { apiKey: 'your-api-key' }
157
+ * );
158
+ *
159
+ * // Classify messages
160
+ * const result = await client.classify(messages);
161
+ * ```
162
+ */
163
+
164
+ /**
165
+ * UCP Client for classifier communication
166
+ */
167
+ declare class UCPClient {
168
+ private baseUrl;
169
+ private classifierId;
170
+ private apiKey?;
171
+ private timeout;
172
+ private headers;
173
+ constructor(config: UCPClientConfig);
174
+ /**
175
+ * Create client from a full endpoint URL
176
+ *
177
+ * URL format: {baseUrl}/classifiers/{classifierId}
178
+ * Example: https://api.example.com/ucp/v1/classifiers/abc123
179
+ */
180
+ static fromEndpoint(endpoint: string, options?: {
181
+ apiKey?: string;
182
+ timeout?: number;
183
+ }): UCPClient;
184
+ /**
185
+ * Get the classify endpoint URL
186
+ */
187
+ get classifyUrl(): string;
188
+ /**
189
+ * Get the info endpoint URL
190
+ */
191
+ get infoUrl(): string;
192
+ /**
193
+ * Classify messages using UCP protocol
194
+ */
195
+ classify(messages: UCPMessage[]): Promise<ClassificationResult>;
196
+ /**
197
+ * Classify ChatMessage array (convenience method)
198
+ * Converts ChatMessage to UCPMessage format
199
+ */
200
+ classifyChat(messages: ChatMessage[]): Promise<ClassificationResult>;
201
+ /**
202
+ * Get classifier info
203
+ */
204
+ getInfo(): Promise<UCPInfoResponse>;
205
+ /**
206
+ * Check if the classifier endpoint is reachable
207
+ */
208
+ healthCheck(): Promise<boolean>;
209
+ /**
210
+ * Internal fetch helper with error handling
211
+ */
212
+ private fetch;
213
+ }
214
+ /**
215
+ * UCP-specific error class
216
+ */
217
+ declare class UCPError extends Error {
218
+ code: string;
219
+ details?: unknown | undefined;
220
+ constructor(code: string, message: string, details?: unknown | undefined);
221
+ }
222
+ /**
223
+ * Create a UCP client from an endpoint URL
224
+ */
225
+ declare function createUCPClient(endpoint: string, options?: {
226
+ apiKey?: string;
227
+ timeout?: number;
228
+ }): UCPClient;
229
+ /**
230
+ * Classify messages using a UCP endpoint
231
+ * One-shot function for simple usage
232
+ */
233
+ declare function classifyWithUCP(endpoint: string, messages: ChatMessage[], options?: {
234
+ apiKey?: string;
235
+ timeout?: number;
236
+ }): Promise<ClassificationResult>;
237
+
238
+ /**
239
+ * Verify an HMAC-SHA256 request signature.
240
+ *
241
+ * The handler server can use this to verify that incoming webhook
242
+ * requests were signed by the FirstStep platform using the shared token.
243
+ *
244
+ * @param token - The API token (FIRSTSTEP_TOKEN)
245
+ * @param payload - The raw request body string
246
+ * @param signature - The signature from the X-FirstStep-Signature header
247
+ * @returns true if the signature is valid
248
+ *
249
+ * @example
250
+ * ```typescript
251
+ * import { verifyRequestSignature } from '@firststep-studio/sdk';
252
+ *
253
+ * app.post('/webhook', (req, res) => {
254
+ * const signature = req.headers['x-firststep-signature'] as string;
255
+ * if (!verifyRequestSignature(process.env.FIRSTSTEP_TOKEN!, req.body, signature)) {
256
+ * return res.status(401).send('Invalid signature');
257
+ * }
258
+ * // Process the request...
259
+ * });
260
+ * ```
261
+ */
262
+ declare function verifyRequestSignature(token: string, payload: string, signature: string): boolean;
263
+ /**
264
+ * Create an HMAC-SHA256 signature for a payload.
265
+ *
266
+ * Used by the platform to sign outgoing requests to handler servers.
267
+ *
268
+ * @param token - The API token
269
+ * @param payload - The request body string to sign
270
+ * @returns The hex-encoded HMAC signature
271
+ */
272
+ declare function createRequestSignature(token: string, payload: string): string;
273
+ /**
274
+ * Create an Authorization header value for API requests.
275
+ *
276
+ * @param token - The API token (fst_xxx)
277
+ * @returns The header value, e.g. "Bearer fst_xxx"
278
+ *
279
+ * @example
280
+ * ```typescript
281
+ * import { createAuthHeader } from '@firststep-studio/sdk';
282
+ *
283
+ * const response = await fetch('https://api.firststep.ai/api/projects', {
284
+ * headers: {
285
+ * 'Authorization': createAuthHeader(process.env.FIRSTSTEP_TOKEN!),
286
+ * },
287
+ * });
288
+ * ```
289
+ */
290
+ declare function createAuthHeader(token: string): string;
291
+ /**
292
+ * Validate that a token has the correct format (fst_ prefix + 40 hex chars).
293
+ *
294
+ * @param token - The token string to validate
295
+ * @returns true if the token matches the expected format
296
+ */
297
+ declare function isValidToken(token: string): boolean;
298
+
299
+ export { ChatMessage, type ClassificationResult, type UCPClassifyRequest, type UCPClassifyResponse, UCPClient, type UCPClientConfig, type UCPEndpointConfig, UCPError, type UCPErrorResponse, type UCPInfoResponse, type UCPMessage, classifyWithUCP, createAuthHeader, createRequestSignature, createUCPClient, isValidToken, verifyRequestSignature };