@letsping/sdk 0.3.1 → 0.3.2

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.
@@ -1,5 +1,5 @@
1
- export type Priority = "low" | "medium" | "high" | "critical";
2
- export interface RequestOptions {
1
+ type Priority = "low" | "medium" | "high" | "critical";
2
+ interface RequestOptions {
3
3
  service: string;
4
4
  action: string;
5
5
  payload: Record<string, any>;
@@ -7,7 +7,7 @@ export interface RequestOptions {
7
7
  schema?: Record<string, any>;
8
8
  timeoutMs?: number;
9
9
  }
10
- export interface Decision {
10
+ interface Decision {
11
11
  status: "APPROVED" | "REJECTED" | "APPROVED_WITH_MODIFICATIONS";
12
12
  payload: any;
13
13
  patched_payload?: any;
@@ -18,7 +18,7 @@ export interface Decision {
18
18
  method?: string;
19
19
  };
20
20
  }
21
- export interface EscrowEnvelope {
21
+ interface EscrowEnvelope {
22
22
  id: string;
23
23
  event: string;
24
24
  data: any;
@@ -31,18 +31,18 @@ export interface EscrowEnvelope {
31
31
  ap2_mandate?: any;
32
32
  };
33
33
  }
34
- export declare function verifyEscrow(event: EscrowEnvelope, secret: string): boolean;
35
- export interface AgentCallPayload {
34
+ declare function verifyEscrow(event: EscrowEnvelope, secret: string): boolean;
35
+ interface AgentCallPayload {
36
36
  project_id: string;
37
37
  service: string;
38
38
  action: string;
39
39
  payload: any;
40
40
  }
41
- export declare function signAgentCall(agentId: string, secret: string, call: AgentCallPayload): {
41
+ declare function signAgentCall(agentId: string, secret: string, call: AgentCallPayload): {
42
42
  agent_id: string;
43
43
  agent_signature: string;
44
44
  };
45
- export declare function signIngestBody(agentId: string, secret: string, body: {
45
+ declare function signIngestBody(agentId: string, secret: string, body: {
46
46
  project_id: string;
47
47
  service: string;
48
48
  action: string;
@@ -55,9 +55,9 @@ export declare function signIngestBody(agentId: string, secret: string, body: {
55
55
  agent_id: string;
56
56
  agent_signature: string;
57
57
  };
58
- export declare function verifyAgentSignature(agentId: string, secret: string, call: AgentCallPayload, signature: string): boolean;
58
+ declare function verifyAgentSignature(agentId: string, secret: string, call: AgentCallPayload, signature: string): boolean;
59
59
 
60
- export interface AgentWorkspaceCredentials {
60
+ interface AgentWorkspaceCredentials {
61
61
  project_id: string;
62
62
  api_key: string;
63
63
  ingest_url: string;
@@ -67,25 +67,25 @@ export interface AgentWorkspaceCredentials {
67
67
  org_id?: string;
68
68
  docs_url?: string;
69
69
  }
70
- export declare function createAgentWorkspace(options?: { baseUrl?: string }): Promise<AgentWorkspaceCredentials>;
70
+ declare function createAgentWorkspace(options?: { baseUrl?: string }): Promise<AgentWorkspaceCredentials>;
71
71
 
72
- export interface IngestWithAgentSignatureOptions {
72
+ interface IngestWithAgentSignatureOptions {
73
73
  projectId: string;
74
74
  ingestUrl: string;
75
75
  apiKey: string;
76
76
  }
77
- export interface IngestPayload {
77
+ interface IngestPayload {
78
78
  service: string;
79
79
  action: string;
80
80
  payload: Record<string, any>;
81
81
  }
82
- export declare function ingestWithAgentSignature(
82
+ declare function ingestWithAgentSignature(
83
83
  agentId: string,
84
84
  agentSecret: string,
85
85
  payload: IngestPayload,
86
86
  options: IngestWithAgentSignatureOptions
87
87
  ): Promise<Record<string, any>>;
88
- export declare function chainHandoff(previous: EscrowEnvelope, nextData: {
88
+ declare function chainHandoff(previous: EscrowEnvelope, nextData: {
89
89
  service: string;
90
90
  action: string;
91
91
  payload: any;
@@ -100,20 +100,20 @@ export declare function chainHandoff(previous: EscrowEnvelope, nextData: {
100
100
  handoff_signature: string;
101
101
  };
102
102
  };
103
- export declare const LETSPING_DOCS_BASE: string;
104
- export type LetsPingErrorCode = "LETSPING_401_AUTH" | "LETSPING_402_QUOTA" | "LETSPING_403_FORBIDDEN" | "LETSPING_404_NOT_FOUND" | "LETSPING_429_RATE_LIMIT" | "LETSPING_TIMEOUT" | "LETSPING_NETWORK" | "LETSPING_WEBHOOK_INVALID" | string;
105
- export declare class LetsPingError extends Error {
103
+ declare const LETSPING_DOCS_BASE: string;
104
+ type LetsPingErrorCode = "LETSPING_401_AUTH" | "LETSPING_402_QUOTA" | "LETSPING_403_FORBIDDEN" | "LETSPING_404_NOT_FOUND" | "LETSPING_429_RATE_LIMIT" | "LETSPING_TIMEOUT" | "LETSPING_NETWORK" | "LETSPING_WEBHOOK_INVALID" | string;
105
+ declare class LetsPingError extends Error {
106
106
  status?: number;
107
107
  code?: LetsPingErrorCode;
108
108
  documentationUrl?: string;
109
109
  constructor(message: string, status?: number, code?: LetsPingErrorCode, documentationUrl?: string);
110
110
  }
111
- export interface RetryOptions {
111
+ interface RetryOptions {
112
112
  maxAttempts?: number;
113
113
  initialDelayMs?: number;
114
114
  maxDelayMs?: number;
115
115
  }
116
- export interface RequestStatus {
116
+ interface RequestStatus {
117
117
  id: string;
118
118
  status: "PENDING" | "APPROVED" | "REJECTED";
119
119
  payload?: any;
@@ -121,7 +121,7 @@ export interface RequestStatus {
121
121
  resolved_at?: string | null;
122
122
  actor_id?: string | null;
123
123
  }
124
- export declare class LetsPing {
124
+ declare class LetsPing {
125
125
  constructor(apiKey?: string, options?: {
126
126
  baseUrl?: string;
127
127
  encryptionKey?: string;
@@ -134,3 +134,5 @@ export declare class LetsPing {
134
134
  tool(service: string, action: string, priority?: Priority): (context: string | Record<string, any>) => Promise<string>;
135
135
  webhookHandler(payloadStr: string, signatureHeader: string, webhookSecret: string): Promise<{ id: string; event: string; data: Decision; state_snapshot?: Record<string, any> }>;
136
136
  }
137
+
138
+ export { type AgentCallPayload, type AgentWorkspaceCredentials, type Decision, type EscrowEnvelope, type IngestPayload, type IngestWithAgentSignatureOptions, LETSPING_DOCS_BASE, LetsPing, LetsPingError, type LetsPingErrorCode, type Priority, type RequestOptions, type RequestStatus, type RetryOptions, chainHandoff, createAgentWorkspace, ingestWithAgentSignature, signAgentCall, signIngestBody, verifyAgentSignature, verifyEscrow };
@@ -0,0 +1,227 @@
1
+ export type Priority = "low" | "medium" | "high" | "critical";
2
+ export interface RequestOptions {
3
+ service: string;
4
+ action: string;
5
+ payload: Record<string, any>;
6
+ priority?: Priority;
7
+ schema?: Record<string, any>;
8
+ state_snapshot?: Record<string, any>;
9
+ timeoutMs?: number;
10
+ role?: string;
11
+ /**
12
+ * Optional distributed tracing identifiers. If provided, these will be
13
+ * attached to the request envelope so downstream frameworks can stitch
14
+ * together multi-agent flows.
15
+ */
16
+ trace_id?: string;
17
+ parent_request_id?: string;
18
+ }
19
+ export interface Decision {
20
+ status: "APPROVED" | "REJECTED" | "APPROVED_WITH_MODIFICATIONS";
21
+ payload: any;
22
+ patched_payload?: any;
23
+ diff_summary?: any;
24
+ metadata?: {
25
+ resolved_at: string;
26
+ actor_id: string;
27
+ method?: string;
28
+ };
29
+ }
30
+ /** Status of a request returned by GET /status/:id. Use with defer() + getRequestStatus() for polling without reading the raw HTTP API. */
31
+ export interface RequestStatus {
32
+ id: string;
33
+ status: "PENDING" | "APPROVED" | "REJECTED";
34
+ payload?: any;
35
+ patched_payload?: any;
36
+ resolved_at?: string | null;
37
+ actor_id?: string | null;
38
+ }
39
+ /** Base URL for error documentation. Errors may include a link to a specific anchor. */
40
+ export declare const LETSPING_DOCS_BASE = "https://letsping.co/docs";
41
+ /** Known error codes for programmatic handling and doc links. */
42
+ export type LetsPingErrorCode = "LETSPING_401_AUTH" | "LETSPING_402_QUOTA" | "LETSPING_403_FORBIDDEN" | "LETSPING_404_NOT_FOUND" | "LETSPING_429_RATE_LIMIT" | "LETSPING_TIMEOUT" | "LETSPING_NETWORK" | "LETSPING_WEBHOOK_INVALID" | string;
43
+ export declare class LetsPingError extends Error {
44
+ /** HTTP status when the error came from the API (e.g. 402, 429). */
45
+ readonly status?: number;
46
+ /** Stable code for handling (e.g. LETSPING_402_QUOTA). Use for branching or logging. */
47
+ readonly code?: LetsPingErrorCode;
48
+ /** Link to the relevant doc section. Present when code is set. */
49
+ readonly documentationUrl?: string;
50
+ constructor(message: string, status?: number, code?: LetsPingErrorCode, documentationUrl?: string);
51
+ }
52
+ declare function computeDiff(original: any, patched: any): any;
53
+ export interface EscrowEnvelope {
54
+ id: string;
55
+ event: string;
56
+ data: any;
57
+ escrow?: {
58
+ mode: "none" | "handoff" | "finalized";
59
+ handoff_signature: string | null;
60
+ upstream_agent_id: string | null;
61
+ downstream_agent_id: string | null;
62
+ x402_mandate?: any;
63
+ ap2_mandate?: any;
64
+ };
65
+ }
66
+ export declare function verifyEscrow(event: EscrowEnvelope, secret: string): boolean;
67
+ export interface AgentCallPayload {
68
+ project_id: string;
69
+ service: string;
70
+ action: string;
71
+ payload: any;
72
+ }
73
+ export declare function signAgentCall(agentId: string, secret: string, call: AgentCallPayload): {
74
+ agent_id: string;
75
+ agent_signature: string;
76
+ };
77
+ export declare function signIngestBody(agentId: string, secret: string, body: {
78
+ project_id: string;
79
+ service: string;
80
+ action: string;
81
+ payload: any;
82
+ }): {
83
+ project_id: string;
84
+ service: string;
85
+ action: string;
86
+ payload: any;
87
+ agent_id: string;
88
+ agent_signature: string;
89
+ };
90
+ /** Credentials returned by createAgentWorkspace. Use api_key for Bearer auth and ingestWithAgentSignature for signed ingest. */
91
+ export interface AgentWorkspaceCredentials {
92
+ project_id: string;
93
+ api_key: string;
94
+ ingest_url: string;
95
+ agents_register_url: string;
96
+ agent_id: string;
97
+ agent_secret: string;
98
+ org_id?: string;
99
+ docs_url?: string;
100
+ }
101
+ /**
102
+ * Request a signup token, redeem it to create a workspace, and register one agent. Returns credentials so the agent can call ingestWithAgentSignature.
103
+ * Rate limits apply (see letsping.co/docs). Throws on 4xx/5xx or if self-serve signup is disabled.
104
+ * @param options.baseUrl - App root URL (e.g. https://letsping.co). Defaults to LETSPING_BASE_URL or https://letsping.co.
105
+ */
106
+ export declare function createAgentWorkspace(options?: {
107
+ baseUrl?: string;
108
+ }): Promise<AgentWorkspaceCredentials>;
109
+ /** Options for ingestWithAgentSignature. */
110
+ export interface IngestWithAgentSignatureOptions {
111
+ projectId: string;
112
+ ingestUrl: string;
113
+ apiKey: string;
114
+ }
115
+ /** Ingest payload: service, action, and payload. */
116
+ export interface IngestPayload {
117
+ service: string;
118
+ action: string;
119
+ payload: Record<string, any>;
120
+ }
121
+ /**
122
+ * Build a signed ingest body and POST it to the ingest URL with Bearer apiKey. Returns the JSON response; throws on non-2xx.
123
+ * Use this so the agent quickstart does not require hand-rolled HMAC or curl. See also: signIngestBody.
124
+ */
125
+ export declare function ingestWithAgentSignature(agentId: string, agentSecret: string, payload: IngestPayload, options: IngestWithAgentSignatureOptions): Promise<Record<string, any>>;
126
+ export declare function verifyAgentSignature(agentId: string, secret: string, call: AgentCallPayload, signature: string): boolean;
127
+ export declare function chainHandoff(previous: EscrowEnvelope, nextData: {
128
+ service: string;
129
+ action: string;
130
+ payload: any;
131
+ upstream_agent_id: string;
132
+ downstream_agent_id: string;
133
+ }, secret: string): {
134
+ payload: any;
135
+ escrow: {
136
+ mode: "handoff";
137
+ upstream_agent_id: string;
138
+ downstream_agent_id: string;
139
+ handoff_signature: string;
140
+ };
141
+ };
142
+ /** Optional retry config for ingest and status calls. Disabled when maxAttempts is 1 or omitted. */
143
+ export interface RetryOptions {
144
+ /** Max attempts per request (default 1 = no retry). Try 3 for transient resilience. */
145
+ maxAttempts?: number;
146
+ /** Initial delay in ms before first retry (default 1000). */
147
+ initialDelayMs?: number;
148
+ /** Cap on delay between retries in ms (default 10000). */
149
+ maxDelayMs?: number;
150
+ }
151
+ export declare class LetsPing {
152
+ private readonly apiKey;
153
+ private readonly baseUrl;
154
+ private readonly encryptionKey;
155
+ private readonly retry;
156
+ constructor(apiKey?: string, options?: {
157
+ baseUrl?: string;
158
+ encryptionKey?: string;
159
+ retry?: RetryOptions;
160
+ });
161
+ private _encrypt;
162
+ private _decrypt;
163
+ private _prepareStateUpload;
164
+ /**
165
+ * Send a request and block until a human approves or rejects it (or timeout). Use for HITL steps in your agent.
166
+ * @param options - service, action, payload; optional priority, schema, state_snapshot, timeoutMs, role
167
+ * @returns Decision with status APPROVED | REJECTED | APPROVED_WITH_MODIFICATIONS and payload (or patched_payload)
168
+ * @throws LetsPingError with code/documentationUrl on API or network errors, or LETSPING_TIMEOUT if no decision in time
169
+ * @see https://letsping.co/docs#ask
170
+ */
171
+ ask(options: RequestOptions): Promise<Decision>;
172
+ /**
173
+ * Fetch the current status of a request by id. Use after defer() to poll until status is APPROVED or REJECTED without calling the raw HTTP API.
174
+ * @param id - Request id returned from defer()
175
+ * @returns RequestStatus with status PENDING | APPROVED | REJECTED, payload, resolved_at, actor_id
176
+ * @see https://letsping.co/docs#requests
177
+ */
178
+ getRequestStatus(id: string): Promise<RequestStatus>;
179
+ /**
180
+ * Send a request and return immediately with the request id. Poll with getRequestStatus(id) or waitForDecision(id) until resolved.
181
+ * Use for async flows (e.g. webhook rehydration) where you do not want to block in-process.
182
+ * @param options - service, action, payload; optional priority, schema, state_snapshot, role
183
+ * @returns { id } - use id with getRequestStatus(id) or waitForDecision(id)
184
+ * @see https://letsping.co/docs#defer
185
+ */
186
+ defer(options: RequestOptions): Promise<{
187
+ id: string;
188
+ }>;
189
+ private request;
190
+ private _delay;
191
+ /**
192
+ * Poll for a decision on a request created with defer(). Blocks until status is APPROVED/REJECTED or timeout.
193
+ * @param id - request id from defer()
194
+ * @param options - originalPayload (fallback if payload not in response), timeoutMs (default 24h)
195
+ * @returns Decision same shape as ask()
196
+ * @see https://letsping.co/docs#requests
197
+ */
198
+ waitForDecision(id: string, options?: {
199
+ originalPayload?: Record<string, any>;
200
+ timeoutMs?: number;
201
+ }): Promise<Decision>;
202
+ /**
203
+ * Build a callable tool (e.g. for LangChain) that runs ask(service, action, payload) and returns a result string.
204
+ * @param service - LetsPing service name
205
+ * @param action - action name
206
+ * @param priority - optional priority (default medium)
207
+ * @returns Async function(context) => string; context can be JSON string or object
208
+ * @see https://letsping.co/docs#tool
209
+ */
210
+ tool(service: string, action: string, priority?: Priority): (context: string | Record<string, any>) => Promise<string>;
211
+ /**
212
+ * Validate and parse an incoming LetsPing webhook body. Verifies signature and optionally fetches/decrypts state_snapshot.
213
+ * @param payloadStr - raw request body (e.g. await req.text())
214
+ * @param signatureHeader - x-letsping-signature header
215
+ * @param webhookSecret - secret from dashboard → Settings → Webhooks
216
+ * @returns { id, event, data, state_snapshot } for resuming your workflow
217
+ * @throws LetsPingError with code LETSPING_WEBHOOK_INVALID and documentationUrl on invalid signature or replay
218
+ * @see https://letsping.co/docs#webhooks
219
+ */
220
+ webhookHandler(payloadStr: string, signatureHeader: string, webhookSecret: string): Promise<{
221
+ id: string;
222
+ event: string;
223
+ data: Decision;
224
+ state_snapshot?: Record<string, any>;
225
+ }>;
226
+ }
227
+ export { computeDiff };