@trustloopguard/sdk 0.0.1

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.
Files changed (242) hide show
  1. package/dist/client.d.ts +98 -0
  2. package/dist/client.js +198 -0
  3. package/dist/errors.d.ts +46 -0
  4. package/dist/errors.js +187 -0
  5. package/dist/generated/AgentAuthority.d.ts +4 -0
  6. package/dist/generated/AgentAuthority.js +2 -0
  7. package/dist/generated/AgentListResponse.d.ts +4 -0
  8. package/dist/generated/AgentListResponse.js +1 -0
  9. package/dist/generated/AgentProfile.d.ts +29 -0
  10. package/dist/generated/AgentProfile.js +1 -0
  11. package/dist/generated/AgentScope.d.ts +4 -0
  12. package/dist/generated/AgentScope.js +2 -0
  13. package/dist/generated/AgentTone.d.ts +4 -0
  14. package/dist/generated/AgentTone.js +2 -0
  15. package/dist/generated/ApiError.d.ts +25 -0
  16. package/dist/generated/ApiError.js +1 -0
  17. package/dist/generated/ApiErrorCode.d.ts +6 -0
  18. package/dist/generated/ApiErrorCode.js +2 -0
  19. package/dist/generated/ApiKeyBatchRevokeRequest.d.ts +3 -0
  20. package/dist/generated/ApiKeyBatchRevokeRequest.js +2 -0
  21. package/dist/generated/ApiKeyBatchRevokeResponse.d.ts +4 -0
  22. package/dist/generated/ApiKeyBatchRevokeResponse.js +1 -0
  23. package/dist/generated/ApiKeyListResponse.d.ts +4 -0
  24. package/dist/generated/ApiKeyListResponse.js +1 -0
  25. package/dist/generated/AuthRequest.d.ts +15 -0
  26. package/dist/generated/AuthRequest.js +2 -0
  27. package/dist/generated/AuthResponse.d.ts +16 -0
  28. package/dist/generated/AuthResponse.js +2 -0
  29. package/dist/generated/ChangePasswordRequest.d.ts +15 -0
  30. package/dist/generated/ChangePasswordRequest.js +2 -0
  31. package/dist/generated/Channel.d.ts +8 -0
  32. package/dist/generated/Channel.js +2 -0
  33. package/dist/generated/CheckRequest.d.ts +21 -0
  34. package/dist/generated/CheckRequest.js +1 -0
  35. package/dist/generated/CreateApiKeyRequest.d.ts +3 -0
  36. package/dist/generated/CreateApiKeyRequest.js +2 -0
  37. package/dist/generated/CreateApiKeyResponse.d.ts +8 -0
  38. package/dist/generated/CreateApiKeyResponse.js +1 -0
  39. package/dist/generated/CreateInviteRequest.d.ts +8 -0
  40. package/dist/generated/CreateInviteRequest.js +1 -0
  41. package/dist/generated/CreateInviteResponse.d.ts +18 -0
  42. package/dist/generated/CreateInviteResponse.js +1 -0
  43. package/dist/generated/CreateKnowledgeSourceRequest.d.ts +9 -0
  44. package/dist/generated/CreateKnowledgeSourceRequest.js +1 -0
  45. package/dist/generated/CreateRunEventRequest.d.ts +13 -0
  46. package/dist/generated/CreateRunEventRequest.js +1 -0
  47. package/dist/generated/CreateRunRequest.d.ts +9 -0
  48. package/dist/generated/CreateRunRequest.js +1 -0
  49. package/dist/generated/CreateWorkspaceRequest.d.ts +7 -0
  50. package/dist/generated/CreateWorkspaceRequest.js +2 -0
  51. package/dist/generated/DashboardApiKey.d.ts +15 -0
  52. package/dist/generated/DashboardApiKey.js +2 -0
  53. package/dist/generated/DashboardKnowledgeSourceKind.d.ts +1 -0
  54. package/dist/generated/DashboardKnowledgeSourceKind.js +2 -0
  55. package/dist/generated/Decision.d.ts +17 -0
  56. package/dist/generated/Decision.js +1 -0
  57. package/dist/generated/GuardrailGenerateResponse.d.ts +11 -0
  58. package/dist/generated/GuardrailGenerateResponse.js +1 -0
  59. package/dist/generated/GuardrailListResponse.d.ts +7 -0
  60. package/dist/generated/GuardrailListResponse.js +1 -0
  61. package/dist/generated/InviteListResponse.d.ts +4 -0
  62. package/dist/generated/InviteListResponse.js +1 -0
  63. package/dist/generated/InviteStatus.d.ts +4 -0
  64. package/dist/generated/InviteStatus.js +2 -0
  65. package/dist/generated/KnowledgeFileInput.d.ts +5 -0
  66. package/dist/generated/KnowledgeFileInput.js +2 -0
  67. package/dist/generated/KnowledgeFileMetadata.d.ts +6 -0
  68. package/dist/generated/KnowledgeFileMetadata.js +2 -0
  69. package/dist/generated/KnowledgeSource.d.ts +7 -0
  70. package/dist/generated/KnowledgeSource.js +1 -0
  71. package/dist/generated/KnowledgeSourceDocument.d.ts +22 -0
  72. package/dist/generated/KnowledgeSourceDocument.js +1 -0
  73. package/dist/generated/KnowledgeSourceFileResponse.d.ts +6 -0
  74. package/dist/generated/KnowledgeSourceFileResponse.js +2 -0
  75. package/dist/generated/KnowledgeSourceKind.d.ts +1 -0
  76. package/dist/generated/KnowledgeSourceKind.js +2 -0
  77. package/dist/generated/KnowledgeSourceListResponse.d.ts +4 -0
  78. package/dist/generated/KnowledgeSourceListResponse.js +1 -0
  79. package/dist/generated/KnowledgeSourceStatus.d.ts +1 -0
  80. package/dist/generated/KnowledgeSourceStatus.js +2 -0
  81. package/dist/generated/MemberListResponse.d.ts +4 -0
  82. package/dist/generated/MemberListResponse.js +1 -0
  83. package/dist/generated/MyWorkspace.d.ts +12 -0
  84. package/dist/generated/MyWorkspace.js +1 -0
  85. package/dist/generated/MyWorkspacesResponse.d.ts +4 -0
  86. package/dist/generated/MyWorkspacesResponse.js +1 -0
  87. package/dist/generated/PolicyAction.d.ts +4 -0
  88. package/dist/generated/PolicyAction.js +2 -0
  89. package/dist/generated/PolicyBatchSetEnabledRequest.d.ts +4 -0
  90. package/dist/generated/PolicyBatchSetEnabledRequest.js +2 -0
  91. package/dist/generated/PolicyBatchSetEnabledResponse.d.ts +4 -0
  92. package/dist/generated/PolicyBatchSetEnabledResponse.js +1 -0
  93. package/dist/generated/PolicyDocument.d.ts +8 -0
  94. package/dist/generated/PolicyDocument.js +1 -0
  95. package/dist/generated/PolicyDraft.d.ts +17 -0
  96. package/dist/generated/PolicyDraft.js +1 -0
  97. package/dist/generated/PolicyDraftRequest.d.ts +6 -0
  98. package/dist/generated/PolicyDraftRequest.js +2 -0
  99. package/dist/generated/PolicyDraftResponse.d.ts +4 -0
  100. package/dist/generated/PolicyDraftResponse.js +1 -0
  101. package/dist/generated/PolicyListResponse.d.ts +4 -0
  102. package/dist/generated/PolicyListResponse.js +1 -0
  103. package/dist/generated/PolicyMatchType.d.ts +5 -0
  104. package/dist/generated/PolicyMatchType.js +2 -0
  105. package/dist/generated/PolicySetEnabledRequest.d.ts +3 -0
  106. package/dist/generated/PolicySetEnabledRequest.js +2 -0
  107. package/dist/generated/PolicySummary.d.ts +9 -0
  108. package/dist/generated/PolicySummary.js +1 -0
  109. package/dist/generated/PolicyValidateResponse.d.ts +6 -0
  110. package/dist/generated/PolicyValidateResponse.js +1 -0
  111. package/dist/generated/PolicyValidationIssue.d.ts +4 -0
  112. package/dist/generated/PolicyValidationIssue.js +2 -0
  113. package/dist/generated/RunDetail.d.ts +8 -0
  114. package/dist/generated/RunDetail.js +1 -0
  115. package/dist/generated/RunEventKind.d.ts +1 -0
  116. package/dist/generated/RunEventKind.js +2 -0
  117. package/dist/generated/RunEventListResponse.d.ts +4 -0
  118. package/dist/generated/RunEventListResponse.js +1 -0
  119. package/dist/generated/RunEventSummary.d.ts +20 -0
  120. package/dist/generated/RunEventSummary.js +1 -0
  121. package/dist/generated/RunKind.d.ts +1 -0
  122. package/dist/generated/RunKind.js +2 -0
  123. package/dist/generated/RunListResponse.d.ts +4 -0
  124. package/dist/generated/RunListResponse.js +1 -0
  125. package/dist/generated/RunStatus.d.ts +1 -0
  126. package/dist/generated/RunStatus.js +2 -0
  127. package/dist/generated/RunSummary.d.ts +32 -0
  128. package/dist/generated/RunSummary.js +1 -0
  129. package/dist/generated/Severity.d.ts +1 -0
  130. package/dist/generated/Severity.js +2 -0
  131. package/dist/generated/Tier.d.ts +4 -0
  132. package/dist/generated/Tier.js +2 -0
  133. package/dist/generated/TierResult.d.ts +12 -0
  134. package/dist/generated/TierResult.js +1 -0
  135. package/dist/generated/TierStatus.d.ts +4 -0
  136. package/dist/generated/TierStatus.js +2 -0
  137. package/dist/generated/TraceListResponse.d.ts +4 -0
  138. package/dist/generated/TraceListResponse.js +1 -0
  139. package/dist/generated/TraceSummary.d.ts +13 -0
  140. package/dist/generated/TraceSummary.js +2 -0
  141. package/dist/generated/TriggeredPolicy.d.ts +6 -0
  142. package/dist/generated/TriggeredPolicy.js +1 -0
  143. package/dist/generated/UpdateRunRequest.d.ts +10 -0
  144. package/dist/generated/UpdateRunRequest.js +1 -0
  145. package/dist/generated/Verdict.d.ts +4 -0
  146. package/dist/generated/Verdict.js +2 -0
  147. package/dist/generated/WorkspaceInvite.d.ts +20 -0
  148. package/dist/generated/WorkspaceInvite.js +1 -0
  149. package/dist/generated/WorkspaceMember.d.ts +13 -0
  150. package/dist/generated/WorkspaceMember.js +1 -0
  151. package/dist/generated/WorkspaceRole.d.ts +5 -0
  152. package/dist/generated/WorkspaceRole.js +2 -0
  153. package/dist/generated/WorkspaceSettings.d.ts +11 -0
  154. package/dist/generated/WorkspaceSettings.js +2 -0
  155. package/dist/guard.d.ts +193 -0
  156. package/dist/guard.js +211 -0
  157. package/dist/index.d.ts +64 -0
  158. package/dist/index.js +64 -0
  159. package/dist/retry.d.ts +18 -0
  160. package/dist/retry.js +48 -0
  161. package/package.json +39 -0
  162. package/src/client.ts +453 -0
  163. package/src/errors.ts +202 -0
  164. package/src/generated/AgentAuthority.ts +3 -0
  165. package/src/generated/AgentListResponse.ts +4 -0
  166. package/src/generated/AgentProfile.ts +23 -0
  167. package/src/generated/AgentScope.ts +3 -0
  168. package/src/generated/AgentTone.ts +3 -0
  169. package/src/generated/ApiError.ts +24 -0
  170. package/src/generated/ApiErrorCode.ts +8 -0
  171. package/src/generated/ApiKeyBatchRevokeRequest.ts +3 -0
  172. package/src/generated/ApiKeyBatchRevokeResponse.ts +4 -0
  173. package/src/generated/ApiKeyListResponse.ts +4 -0
  174. package/src/generated/AuthRequest.ts +16 -0
  175. package/src/generated/AuthResponse.ts +15 -0
  176. package/src/generated/ChangePasswordRequest.ts +15 -0
  177. package/src/generated/Channel.ts +10 -0
  178. package/src/generated/CheckRequest.ts +11 -0
  179. package/src/generated/CreateApiKeyRequest.ts +3 -0
  180. package/src/generated/CreateApiKeyResponse.ts +8 -0
  181. package/src/generated/CreateInviteRequest.ts +7 -0
  182. package/src/generated/CreateInviteResponse.ts +14 -0
  183. package/src/generated/CreateKnowledgeSourceRequest.ts +5 -0
  184. package/src/generated/CreateRunEventRequest.ts +8 -0
  185. package/src/generated/CreateRunRequest.ts +5 -0
  186. package/src/generated/CreateWorkspaceRequest.ts +7 -0
  187. package/src/generated/DashboardApiKey.ts +11 -0
  188. package/src/generated/DashboardKnowledgeSourceKind.ts +3 -0
  189. package/src/generated/Decision.ts +12 -0
  190. package/src/generated/GuardrailGenerateResponse.ts +11 -0
  191. package/src/generated/GuardrailListResponse.ts +7 -0
  192. package/src/generated/InviteListResponse.ts +4 -0
  193. package/src/generated/InviteStatus.ts +6 -0
  194. package/src/generated/KnowledgeFileInput.ts +3 -0
  195. package/src/generated/KnowledgeFileMetadata.ts +3 -0
  196. package/src/generated/KnowledgeSource.ts +4 -0
  197. package/src/generated/KnowledgeSourceDocument.ts +17 -0
  198. package/src/generated/KnowledgeSourceFileResponse.ts +3 -0
  199. package/src/generated/KnowledgeSourceKind.ts +3 -0
  200. package/src/generated/KnowledgeSourceListResponse.ts +4 -0
  201. package/src/generated/KnowledgeSourceStatus.ts +3 -0
  202. package/src/generated/MemberListResponse.ts +4 -0
  203. package/src/generated/MyWorkspace.ts +8 -0
  204. package/src/generated/MyWorkspacesResponse.ts +4 -0
  205. package/src/generated/PolicyAction.ts +6 -0
  206. package/src/generated/PolicyBatchSetEnabledRequest.ts +3 -0
  207. package/src/generated/PolicyBatchSetEnabledResponse.ts +4 -0
  208. package/src/generated/PolicyDocument.ts +4 -0
  209. package/src/generated/PolicyDraft.ts +11 -0
  210. package/src/generated/PolicyDraftRequest.ts +6 -0
  211. package/src/generated/PolicyDraftResponse.ts +4 -0
  212. package/src/generated/PolicyListResponse.ts +4 -0
  213. package/src/generated/PolicyMatchType.ts +7 -0
  214. package/src/generated/PolicySetEnabledRequest.ts +3 -0
  215. package/src/generated/PolicySummary.ts +4 -0
  216. package/src/generated/PolicyValidateResponse.ts +4 -0
  217. package/src/generated/PolicyValidationIssue.ts +3 -0
  218. package/src/generated/README.md +1 -0
  219. package/src/generated/RunDetail.ts +6 -0
  220. package/src/generated/RunEventKind.ts +3 -0
  221. package/src/generated/RunEventListResponse.ts +4 -0
  222. package/src/generated/RunEventSummary.ts +12 -0
  223. package/src/generated/RunKind.ts +3 -0
  224. package/src/generated/RunListResponse.ts +4 -0
  225. package/src/generated/RunStatus.ts +3 -0
  226. package/src/generated/RunSummary.ts +21 -0
  227. package/src/generated/Severity.ts +3 -0
  228. package/src/generated/Tier.ts +6 -0
  229. package/src/generated/TierResult.ts +9 -0
  230. package/src/generated/TierStatus.ts +6 -0
  231. package/src/generated/TraceListResponse.ts +4 -0
  232. package/src/generated/TraceSummary.ts +7 -0
  233. package/src/generated/TriggeredPolicy.ts +4 -0
  234. package/src/generated/UpdateRunRequest.ts +9 -0
  235. package/src/generated/Verdict.ts +6 -0
  236. package/src/generated/WorkspaceInvite.ts +14 -0
  237. package/src/generated/WorkspaceMember.ts +11 -0
  238. package/src/generated/WorkspaceRole.ts +7 -0
  239. package/src/generated/WorkspaceSettings.ts +7 -0
  240. package/src/guard.ts +492 -0
  241. package/src/index.ts +97 -0
  242. package/src/retry.ts +67 -0
@@ -0,0 +1,98 @@
1
+ import type { CheckRequest } from './generated/CheckRequest';
2
+ import type { Decision } from './generated/Decision';
3
+ import type { AgentListResponse } from './generated/AgentListResponse';
4
+ import type { AgentProfile } from './generated/AgentProfile';
5
+ import type { ApiKeyBatchRevokeResponse } from './generated/ApiKeyBatchRevokeResponse';
6
+ import type { GuardrailGenerateResponse } from './generated/GuardrailGenerateResponse';
7
+ import type { GuardrailListResponse } from './generated/GuardrailListResponse';
8
+ import type { PolicyDocument } from './generated/PolicyDocument';
9
+ import type { PolicyBatchSetEnabledResponse } from './generated/PolicyBatchSetEnabledResponse';
10
+ import type { PolicyDraftResponse } from './generated/PolicyDraftResponse';
11
+ import type { PolicyListResponse } from './generated/PolicyListResponse';
12
+ import type { PolicyValidateResponse } from './generated/PolicyValidateResponse';
13
+ import type { CreateRunEventRequest } from './generated/CreateRunEventRequest';
14
+ import type { CreateRunRequest } from './generated/CreateRunRequest';
15
+ import type { RunDetail } from './generated/RunDetail';
16
+ import type { RunEventListResponse } from './generated/RunEventListResponse';
17
+ import type { RunEventSummary } from './generated/RunEventSummary';
18
+ import type { RunListResponse } from './generated/RunListResponse';
19
+ import type { RunStatus } from './generated/RunStatus';
20
+ import type { RunSummary } from './generated/RunSummary';
21
+ import type { TraceListResponse } from './generated/TraceListResponse';
22
+ import type { UpdateRunRequest } from './generated/UpdateRunRequest';
23
+ import { SdkError } from './errors';
24
+ import { type RetryConfig } from './retry';
25
+ export interface ClientOptions {
26
+ baseUrl: string;
27
+ apiKey?: string;
28
+ fetchImpl?: typeof fetch;
29
+ retry?: RetryConfig;
30
+ /**
31
+ * Hook invoked once per retry decision. Useful for surfacing retry
32
+ * activity in logs / OpenTelemetry without forcing a logger
33
+ * dependency on the SDK.
34
+ */
35
+ onRetry?: (info: {
36
+ attempt: number;
37
+ delayS: number;
38
+ error: SdkError;
39
+ }) => void;
40
+ }
41
+ export declare class Client {
42
+ private readonly baseUrl;
43
+ private readonly apiKey;
44
+ private readonly fetchImpl;
45
+ private readonly retry;
46
+ private readonly onRetry;
47
+ constructor(opts: ClientOptions);
48
+ check(req: CheckRequest, signal?: AbortSignal): Promise<Decision>;
49
+ startRun(req: Omit<CreateRunRequest, 'metadata'> & {
50
+ metadata?: Record<string, unknown>;
51
+ }, signal?: AbortSignal): Promise<RunSummary>;
52
+ listRuns(signal?: AbortSignal): Promise<RunListResponse>;
53
+ getRun(runId: string, signal?: AbortSignal): Promise<RunDetail>;
54
+ updateRun(runId: string, req: UpdateRunRequest, signal?: AbortSignal): Promise<RunSummary>;
55
+ finishRun(runId: string, status?: Extract<RunStatus, 'completed' | 'failed' | 'canceled'>, signal?: AbortSignal): Promise<RunSummary>;
56
+ createRunEvent(runId: string, req: Omit<CreateRunEventRequest, 'metadata'> & {
57
+ metadata?: Record<string, unknown>;
58
+ }, signal?: AbortSignal): Promise<RunEventSummary>;
59
+ listRunEvents(runId: string, signal?: AbortSignal): Promise<RunEventListResponse>;
60
+ listRunTraces(runId: string, signal?: AbortSignal): Promise<TraceListResponse>;
61
+ validatePolicy(source: string, signal?: AbortSignal): Promise<PolicyValidateResponse>;
62
+ listPolicies(signal?: AbortSignal): Promise<PolicyListResponse>;
63
+ listAgents(signal?: AbortSignal): Promise<AgentListResponse>;
64
+ upsertAgent(profile: AgentProfile, signal?: AbortSignal): Promise<AgentProfile>;
65
+ getPolicy(policyId: string, signal?: AbortSignal): Promise<PolicyDocument>;
66
+ upsertPolicy(source: string, signal?: AbortSignal): Promise<PolicyDocument>;
67
+ setPolicyEnabled(policyId: string, enabled: boolean, signal?: AbortSignal): Promise<PolicyDocument>;
68
+ batchSetPolicyEnabled(policyIds: string[], enabled: boolean, signal?: AbortSignal): Promise<PolicyBatchSetEnabledResponse>;
69
+ /**
70
+ * LLM-draft a policy skeleton from a natural-language prompt. The
71
+ * server holds the provider key; the response is a strict, typed
72
+ * `PolicyDraftResponse`. Returns a 503-mapped `Unavailable` error when
73
+ * the deployment has no LLM configured.
74
+ */
75
+ draftPolicy(prompt: string, signal?: AbortSignal): Promise<PolicyDraftResponse>;
76
+ /**
77
+ * Derive a guardrail policy set from the agent's stored `system_prompt`,
78
+ * auto-persist each draft with `enabled=false`, and return what was
79
+ * saved. The caller must have previously registered the agent (with a
80
+ * non-empty `system_prompt`) via `POST /v1/agents`.
81
+ *
82
+ * Errors:
83
+ * - `NotFound` (404) — agent is not registered.
84
+ * - `Unprocessable` (422) — agent has no `system_prompt`.
85
+ * - `Unavailable` (503) — the deployment has no LLM configured.
86
+ */
87
+ generateGuardrails(agentId: string, signal?: AbortSignal): Promise<GuardrailGenerateResponse>;
88
+ /**
89
+ * List policies owned by an agent. Empty when the agent has none or
90
+ * doesn't exist — existence is the caller's concern.
91
+ */
92
+ listGuardrails(agentId: string, signal?: AbortSignal): Promise<GuardrailListResponse>;
93
+ deletePolicy(policyId: string, signal?: AbortSignal): Promise<void>;
94
+ batchRevokeApiKeys(apiKeyIds: string[], signal?: AbortSignal): Promise<ApiKeyBatchRevokeResponse>;
95
+ private withRetry;
96
+ private sendText;
97
+ private sendJson;
98
+ }
package/dist/client.js ADDED
@@ -0,0 +1,198 @@
1
+ // Thin HTTP client. Mirrors the `Guard.check(draft, ctx)` plugin contract.
2
+ //
3
+ // Retry policy mirrors tl-sdk-rust and the Python SDK — same defaults,
4
+ // same `nextDelay` semantics. Voice callers should pass
5
+ // `{ ...DEFAULT_RETRY, maxAttempts: 1 }` to opt out.
6
+ import { Decode, SdkError, Transport, fromResponse, parseRetryAfter } from './errors';
7
+ import { DEFAULT_RETRY, nextDelay } from './retry';
8
+ export class Client {
9
+ baseUrl;
10
+ apiKey;
11
+ fetchImpl;
12
+ retry;
13
+ onRetry;
14
+ constructor(opts) {
15
+ this.baseUrl = opts.baseUrl.replace(/\/$/, '');
16
+ this.apiKey = opts.apiKey;
17
+ this.fetchImpl = opts.fetchImpl ?? globalThis.fetch.bind(globalThis);
18
+ this.retry = opts.retry ?? DEFAULT_RETRY;
19
+ this.onRetry = opts.onRetry;
20
+ }
21
+ async check(req, signal) {
22
+ return this.withRetry((signal) => this.sendJson('/v1/check', {
23
+ method: 'POST',
24
+ body: JSON.stringify(req),
25
+ }, signal), signal);
26
+ }
27
+ async startRun(req, signal) {
28
+ return this.withRetry((signal) => this.sendJson('/v1/runs', {
29
+ method: 'POST',
30
+ body: JSON.stringify({ metadata: {}, ...req }),
31
+ }, signal), signal);
32
+ }
33
+ async listRuns(signal) {
34
+ return this.withRetry((signal) => this.sendJson('/v1/runs', { method: 'GET' }, signal), signal);
35
+ }
36
+ async getRun(runId, signal) {
37
+ return this.withRetry((signal) => this.sendJson(`/v1/runs/${encodeURIComponent(runId)}`, { method: 'GET' }, signal), signal);
38
+ }
39
+ async updateRun(runId, req, signal) {
40
+ return this.withRetry((signal) => this.sendJson(`/v1/runs/${encodeURIComponent(runId)}`, {
41
+ method: 'PATCH',
42
+ body: JSON.stringify(req),
43
+ }, signal), signal);
44
+ }
45
+ async finishRun(runId, status = 'completed', signal) {
46
+ return this.updateRun(runId, { status }, signal);
47
+ }
48
+ async createRunEvent(runId, req, signal) {
49
+ return this.withRetry((signal) => this.sendJson(`/v1/runs/${encodeURIComponent(runId)}/events`, {
50
+ method: 'POST',
51
+ body: JSON.stringify({ metadata: {}, ...req }),
52
+ }, signal), signal);
53
+ }
54
+ async listRunEvents(runId, signal) {
55
+ return this.withRetry((signal) => this.sendJson(`/v1/runs/${encodeURIComponent(runId)}/events`, { method: 'GET' }, signal), signal);
56
+ }
57
+ async listRunTraces(runId, signal) {
58
+ return this.withRetry((signal) => this.sendJson(`/v1/runs/${encodeURIComponent(runId)}/traces`, { method: 'GET' }, signal), signal);
59
+ }
60
+ async validatePolicy(source, signal) {
61
+ return this.withRetry((signal) => this.sendText('/v1/policies/validate', 'POST', source, 'application/yaml', signal), signal);
62
+ }
63
+ async listPolicies(signal) {
64
+ return this.withRetry((signal) => this.sendJson('/v1/policies', { method: 'GET' }, signal), signal);
65
+ }
66
+ async listAgents(signal) {
67
+ return this.withRetry((signal) => this.sendJson('/v1/agents', { method: 'GET' }, signal), signal);
68
+ }
69
+ async upsertAgent(profile, signal) {
70
+ return this.withRetry((signal) => this.sendJson('/v1/agents', {
71
+ method: 'POST',
72
+ body: JSON.stringify(profile),
73
+ }, signal), signal);
74
+ }
75
+ async getPolicy(policyId, signal) {
76
+ return this.withRetry((signal) => this.sendJson(`/v1/policies/${encodeURIComponent(policyId)}`, { method: 'GET' }, signal), signal);
77
+ }
78
+ async upsertPolicy(source, signal) {
79
+ return this.withRetry((signal) => this.sendText('/v1/policies', 'POST', source, 'application/yaml', signal), signal);
80
+ }
81
+ async setPolicyEnabled(policyId, enabled, signal) {
82
+ return this.withRetry((signal) => this.sendJson(`/v1/policies/${encodeURIComponent(policyId)}/enabled`, {
83
+ method: 'PATCH',
84
+ body: JSON.stringify({ enabled }),
85
+ }, signal), signal);
86
+ }
87
+ async batchSetPolicyEnabled(policyIds, enabled, signal) {
88
+ return this.withRetry((signal) => this.sendJson('/v1/policies/batch/enabled', {
89
+ method: 'PATCH',
90
+ body: JSON.stringify({ ids: policyIds, enabled }),
91
+ }, signal), signal);
92
+ }
93
+ /**
94
+ * LLM-draft a policy skeleton from a natural-language prompt. The
95
+ * server holds the provider key; the response is a strict, typed
96
+ * `PolicyDraftResponse`. Returns a 503-mapped `Unavailable` error when
97
+ * the deployment has no LLM configured.
98
+ */
99
+ async draftPolicy(prompt, signal) {
100
+ return this.withRetry((signal) => this.sendJson('/v1/policies/draft', {
101
+ method: 'POST',
102
+ body: JSON.stringify({ prompt }),
103
+ }, signal), signal);
104
+ }
105
+ /**
106
+ * Derive a guardrail policy set from the agent's stored `system_prompt`,
107
+ * auto-persist each draft with `enabled=false`, and return what was
108
+ * saved. The caller must have previously registered the agent (with a
109
+ * non-empty `system_prompt`) via `POST /v1/agents`.
110
+ *
111
+ * Errors:
112
+ * - `NotFound` (404) — agent is not registered.
113
+ * - `Unprocessable` (422) — agent has no `system_prompt`.
114
+ * - `Unavailable` (503) — the deployment has no LLM configured.
115
+ */
116
+ async generateGuardrails(agentId, signal) {
117
+ return this.withRetry((signal) => this.sendJson(`/v1/agents/${encodeURIComponent(agentId)}/guardrails/generate`, { method: 'POST' }, signal), signal);
118
+ }
119
+ /**
120
+ * List policies owned by an agent. Empty when the agent has none or
121
+ * doesn't exist — existence is the caller's concern.
122
+ */
123
+ async listGuardrails(agentId, signal) {
124
+ return this.withRetry((signal) => this.sendJson(`/v1/agents/${encodeURIComponent(agentId)}/guardrails`, { method: 'GET' }, signal), signal);
125
+ }
126
+ async deletePolicy(policyId, signal) {
127
+ return this.withRetry((signal) => this.sendJson(`/v1/policies/${encodeURIComponent(policyId)}`, { method: 'DELETE' }, signal), signal);
128
+ }
129
+ async batchRevokeApiKeys(apiKeyIds, signal) {
130
+ return this.withRetry((signal) => this.sendJson('/v1/api-keys/batch/revoke', {
131
+ method: 'PATCH',
132
+ body: JSON.stringify({ ids: apiKeyIds }),
133
+ }, signal), signal);
134
+ }
135
+ async withRetry(send, signal) {
136
+ const start = performance.now();
137
+ let attempt = 0;
138
+ while (true) {
139
+ attempt += 1;
140
+ try {
141
+ return await send(signal);
142
+ }
143
+ catch (e) {
144
+ if (!(e instanceof SdkError))
145
+ throw e;
146
+ const elapsedS = (performance.now() - start) / 1000;
147
+ const delay = nextDelay(this.retry, attempt, elapsedS, e, Math.random());
148
+ if (delay === undefined)
149
+ throw e;
150
+ this.onRetry?.({ attempt, delayS: delay, error: e });
151
+ await new Promise((resolve) => setTimeout(resolve, delay * 1000));
152
+ }
153
+ }
154
+ }
155
+ async sendText(path, method, body, contentType, signal) {
156
+ return this.sendJson(path, {
157
+ method,
158
+ headers: { 'content-type': contentType },
159
+ body,
160
+ }, signal);
161
+ }
162
+ async sendJson(path, init, signal) {
163
+ const headers = {
164
+ 'content-type': 'application/json',
165
+ ...(init.headers ?? {}),
166
+ };
167
+ if (this.apiKey !== undefined) {
168
+ headers['authorization'] = `Bearer ${this.apiKey}`;
169
+ }
170
+ const requestInit = {
171
+ ...init,
172
+ headers,
173
+ };
174
+ if (signal !== undefined) {
175
+ requestInit.signal = signal;
176
+ }
177
+ let res;
178
+ try {
179
+ res = await this.fetchImpl(`${this.baseUrl}${path}`, requestInit);
180
+ }
181
+ catch (e) {
182
+ throw new Transport(e instanceof Error ? e.message : String(e));
183
+ }
184
+ if (res.status === 204)
185
+ return undefined;
186
+ if (res.ok) {
187
+ try {
188
+ return (await res.json());
189
+ }
190
+ catch (e) {
191
+ throw new Decode(`failed to parse response: ${String(e)}`);
192
+ }
193
+ }
194
+ const retryAfter = parseRetryAfter(res.headers.get('retry-after'));
195
+ const body = await res.text().catch(() => '');
196
+ throw fromResponse(res.status, body, retryAfter);
197
+ }
198
+ }
@@ -0,0 +1,46 @@
1
+ import type { ApiError } from './generated/ApiError';
2
+ import type { ApiErrorCode } from './generated/ApiErrorCode';
3
+ export declare function codeFromHttpStatus(status: number): ApiErrorCode;
4
+ export declare function synthesizeApiError(status: number, body: string): ApiError;
5
+ export declare class SdkError extends Error {
6
+ readonly error: ApiError;
7
+ constructor(error: ApiError);
8
+ get code(): ApiErrorCode;
9
+ isRetriable(): boolean;
10
+ }
11
+ export declare class Invalid extends SdkError {
12
+ constructor(error: ApiError);
13
+ }
14
+ export declare class Unauthorized extends SdkError {
15
+ constructor(error: ApiError);
16
+ }
17
+ export declare class Forbidden extends SdkError {
18
+ constructor(error: ApiError);
19
+ }
20
+ export declare class NotFound extends SdkError {
21
+ constructor(error: ApiError);
22
+ }
23
+ export declare class Gone extends SdkError {
24
+ constructor(error: ApiError);
25
+ }
26
+ export declare class Unprocessable extends SdkError {
27
+ constructor(error: ApiError);
28
+ }
29
+ export declare class RateLimited extends SdkError {
30
+ readonly retryAfter: number | undefined;
31
+ constructor(error: ApiError, retryAfter?: number);
32
+ }
33
+ export declare class Internal extends SdkError {
34
+ constructor(error: ApiError);
35
+ }
36
+ export declare class Unavailable extends SdkError {
37
+ constructor(error: ApiError);
38
+ }
39
+ export declare class Transport extends SdkError {
40
+ constructor(message: string);
41
+ }
42
+ export declare class Decode extends SdkError {
43
+ constructor(message: string);
44
+ }
45
+ export declare function fromResponse(status: number, body: string, retryAfter?: number): SdkError;
46
+ export declare function parseRetryAfter(header: string | null | undefined): number | undefined;
package/dist/errors.js ADDED
@@ -0,0 +1,187 @@
1
+ // Typed errors for the TrustLoopGuard TypeScript SDK.
2
+ //
3
+ // Mirrors `tl-sdk-rust`'s `SdkError` and the Python SDK's exception
4
+ // hierarchy. Callers branch on `instanceof` (or on `error.code`) instead
5
+ // of inspecting status codes:
6
+ //
7
+ // try {
8
+ // await client.check(req);
9
+ // } catch (e) {
10
+ // if (e instanceof RateLimited) {
11
+ // await sleep((e.retryAfter ?? 1) * 1000);
12
+ // } else if (e instanceof Unauthorized) {
13
+ // refreshToken();
14
+ // }
15
+ // }
16
+ //
17
+ // The status -> code fallback table and retriable-by-default set are kept
18
+ // in lockstep with `tl-core::ApiErrorCode::from_http_status` and the
19
+ // Python `_STATUS_TO_CODE` dict — the parity is asserted by tests in
20
+ // every SDK so they cannot drift silently.
21
+ const STATUS_TO_CODE = {
22
+ 400: 'invalid',
23
+ 401: 'unauthorized',
24
+ 403: 'forbidden',
25
+ 404: 'not_found',
26
+ 410: 'gone',
27
+ 422: 'unprocessable',
28
+ 429: 'rate_limited',
29
+ 500: 'internal',
30
+ 501: 'internal',
31
+ 502: 'unavailable',
32
+ 503: 'unavailable',
33
+ 504: 'unavailable',
34
+ };
35
+ const DEFAULT_RETRIABLE = new Set([
36
+ 'rate_limited',
37
+ 'unavailable',
38
+ ]);
39
+ export function codeFromHttpStatus(status) {
40
+ if (status in STATUS_TO_CODE) {
41
+ return STATUS_TO_CODE[status];
42
+ }
43
+ if (status >= 500 && status < 600)
44
+ return 'internal';
45
+ return 'invalid';
46
+ }
47
+ export function synthesizeApiError(status, body) {
48
+ const code = codeFromHttpStatus(status);
49
+ return {
50
+ code,
51
+ message: body || `server returned status ${status}`,
52
+ retriable: DEFAULT_RETRIABLE.has(code),
53
+ details: null,
54
+ };
55
+ }
56
+ export class SdkError extends Error {
57
+ error;
58
+ constructor(error) {
59
+ super(`${error.code}: ${error.message}`);
60
+ this.name = 'SdkError';
61
+ this.error = error;
62
+ // Preserve prototype chain for `instanceof` to work after transpile.
63
+ Object.setPrototypeOf(this, new.target.prototype);
64
+ }
65
+ get code() {
66
+ return this.error.code;
67
+ }
68
+ isRetriable() {
69
+ return this.error.retriable;
70
+ }
71
+ }
72
+ // One subclass per ApiErrorCode. The classes carry no extra behavior
73
+ // beyond their name — they exist so callers can use `instanceof` and
74
+ // stack traces are labeled. RateLimited is the one exception: it carries
75
+ // the parsed Retry-After value.
76
+ export class Invalid extends SdkError {
77
+ constructor(error) {
78
+ super(error);
79
+ this.name = 'Invalid';
80
+ }
81
+ }
82
+ export class Unauthorized extends SdkError {
83
+ constructor(error) {
84
+ super(error);
85
+ this.name = 'Unauthorized';
86
+ }
87
+ }
88
+ export class Forbidden extends SdkError {
89
+ constructor(error) {
90
+ super(error);
91
+ this.name = 'Forbidden';
92
+ }
93
+ }
94
+ export class NotFound extends SdkError {
95
+ constructor(error) {
96
+ super(error);
97
+ this.name = 'NotFound';
98
+ }
99
+ }
100
+ export class Gone extends SdkError {
101
+ constructor(error) {
102
+ super(error);
103
+ this.name = 'Gone';
104
+ }
105
+ }
106
+ export class Unprocessable extends SdkError {
107
+ constructor(error) {
108
+ super(error);
109
+ this.name = 'Unprocessable';
110
+ }
111
+ }
112
+ export class RateLimited extends SdkError {
113
+ retryAfter;
114
+ constructor(error, retryAfter) {
115
+ super(error);
116
+ this.name = 'RateLimited';
117
+ this.retryAfter = retryAfter;
118
+ }
119
+ }
120
+ export class Internal extends SdkError {
121
+ constructor(error) {
122
+ super(error);
123
+ this.name = 'Internal';
124
+ }
125
+ }
126
+ export class Unavailable extends SdkError {
127
+ constructor(error) {
128
+ super(error);
129
+ this.name = 'Unavailable';
130
+ }
131
+ }
132
+ export class Transport extends SdkError {
133
+ constructor(message) {
134
+ super({ code: 'unavailable', message, retriable: true, details: null });
135
+ this.name = 'Transport';
136
+ }
137
+ }
138
+ export class Decode extends SdkError {
139
+ constructor(message) {
140
+ super({ code: 'internal', message, retriable: false, details: null });
141
+ this.name = 'Decode';
142
+ }
143
+ }
144
+ const CODE_TO_CLASS = {
145
+ invalid: Invalid,
146
+ unauthorized: Unauthorized,
147
+ forbidden: Forbidden,
148
+ not_found: NotFound,
149
+ gone: Gone,
150
+ unprocessable: Unprocessable,
151
+ rate_limited: RateLimited,
152
+ internal: Internal,
153
+ unavailable: Unavailable,
154
+ };
155
+ function isApiError(value) {
156
+ if (typeof value !== 'object' || value === null)
157
+ return false;
158
+ const v = value;
159
+ return (typeof v.code === 'string' &&
160
+ typeof v.message === 'string' &&
161
+ typeof v.retriable === 'boolean' &&
162
+ v.code in CODE_TO_CLASS);
163
+ }
164
+ export function fromResponse(status, body, retryAfter) {
165
+ let apiErr;
166
+ try {
167
+ const parsed = JSON.parse(body);
168
+ apiErr = isApiError(parsed) ? parsed : synthesizeApiError(status, body);
169
+ }
170
+ catch {
171
+ apiErr = synthesizeApiError(status, body);
172
+ }
173
+ if (apiErr.code === 'rate_limited') {
174
+ return new RateLimited(apiErr, retryAfter);
175
+ }
176
+ const Cls = CODE_TO_CLASS[apiErr.code];
177
+ return new Cls(apiErr);
178
+ }
179
+ export function parseRetryAfter(header) {
180
+ if (header === null || header === undefined)
181
+ return undefined;
182
+ const trimmed = header.trim();
183
+ const n = Number(trimmed);
184
+ if (!Number.isFinite(n))
185
+ return undefined;
186
+ return n;
187
+ }
@@ -0,0 +1,4 @@
1
+ export type AgentAuthority = {
2
+ can_promise: Array<string>;
3
+ cannot_promise: Array<string>;
4
+ };
@@ -0,0 +1,2 @@
1
+ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2
+ export {};
@@ -0,0 +1,4 @@
1
+ import type { AgentProfile } from "./AgentProfile";
2
+ export type AgentListResponse = {
3
+ agents: Array<AgentProfile>;
4
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,29 @@
1
+ import type { AgentAuthority } from "./AgentAuthority";
2
+ import type { AgentScope } from "./AgentScope";
3
+ import type { AgentTone } from "./AgentTone";
4
+ import type { KnowledgeSource } from "./KnowledgeSource";
5
+ /**
6
+ * What an agent is, what it may claim, and how it should sound.
7
+ *
8
+ * Authored as YAML by the customer (see `policies/agents/*.yaml`), parsed
9
+ * by `tl-policy::load_agent_str`, persisted in Postgres, cached in process,
10
+ * and consulted by Tier 2 (out-of-scope embedding lookup) and Tier 3
11
+ * (LLM judge ground truth).
12
+ */
13
+ export type AgentProfile = {
14
+ agent_id: string;
15
+ display_name: string;
16
+ scope: AgentScope;
17
+ authority: AgentAuthority;
18
+ tone: AgentTone;
19
+ knowledge_sources: Array<KnowledgeSource>;
20
+ escalation_triggers: Array<string>;
21
+ /**
22
+ * Raw system prompt the customer ships to their LLM. Source of truth
23
+ * for auto-generating guardrails: `POST /v1/agents/{id}/guardrails:generate`
24
+ * reads this and asks an LLM to derive a policy set tailored to it.
25
+ * Optional at the type level so existing profiles keep deserializing;
26
+ * the generate endpoint enforces presence at call time.
27
+ */
28
+ system_prompt?: string;
29
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ export type AgentScope = {
2
+ in_scope: Array<string>;
3
+ out_of_scope: Array<string>;
4
+ };
@@ -0,0 +1,2 @@
1
+ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2
+ export {};
@@ -0,0 +1,4 @@
1
+ export type AgentTone = {
2
+ target: string;
3
+ forbidden: Array<string>;
4
+ };
@@ -0,0 +1,2 @@
1
+ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2
+ export {};
@@ -0,0 +1,25 @@
1
+ import type { ApiErrorCode } from "./ApiErrorCode";
2
+ /**
3
+ * Canonical error envelope returned on non-2xx responses from every
4
+ * TrustLoopGuard endpoint. SDKs deserialize this body to produce typed
5
+ * errors; integrators don't have to inspect status codes by hand.
6
+ *
7
+ * The shape is intentionally minimal — `code` drives SDK-side fan-out,
8
+ * `message` is for logs, `retriable` tells callers whether the same
9
+ * request may be retried, and `details` is opaque so the server can
10
+ * add validation field paths without breaking SDKs.
11
+ */
12
+ export type ApiError = {
13
+ code: ApiErrorCode;
14
+ message: string;
15
+ /**
16
+ * Whether the caller may retry the same request without modification.
17
+ * SDKs honor `Retry-After` when present in addition to this flag.
18
+ */
19
+ retriable: boolean;
20
+ /**
21
+ * Opaque structured details (e.g. validation field path).
22
+ * Defaults to `null`; servers may add fields without breaking SDKs.
23
+ */
24
+ details: Record<string, unknown> | null;
25
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Stable error code dictionary. Add variants here when introducing new
3
+ * failure modes; never repurpose an existing variant — SDK callers may
4
+ * be branching on it.
5
+ */
6
+ export type ApiErrorCode = "invalid" | "unauthorized" | "forbidden" | "not_found" | "gone" | "unprocessable" | "rate_limited" | "internal" | "unavailable";
@@ -0,0 +1,2 @@
1
+ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2
+ export {};
@@ -0,0 +1,3 @@
1
+ export type ApiKeyBatchRevokeRequest = {
2
+ ids: Array<string>;
3
+ };
@@ -0,0 +1,2 @@
1
+ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2
+ export {};
@@ -0,0 +1,4 @@
1
+ import type { DashboardApiKey } from "./DashboardApiKey";
2
+ export type ApiKeyBatchRevokeResponse = {
3
+ api_keys: Array<DashboardApiKey>;
4
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ import type { DashboardApiKey } from "./DashboardApiKey";
2
+ export type ApiKeyListResponse = {
3
+ api_keys: Array<DashboardApiKey>;
4
+ };
@@ -0,0 +1 @@
1
+ export {};