@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.
- package/dist/client.d.ts +98 -0
- package/dist/client.js +198 -0
- package/dist/errors.d.ts +46 -0
- package/dist/errors.js +187 -0
- package/dist/generated/AgentAuthority.d.ts +4 -0
- package/dist/generated/AgentAuthority.js +2 -0
- package/dist/generated/AgentListResponse.d.ts +4 -0
- package/dist/generated/AgentListResponse.js +1 -0
- package/dist/generated/AgentProfile.d.ts +29 -0
- package/dist/generated/AgentProfile.js +1 -0
- package/dist/generated/AgentScope.d.ts +4 -0
- package/dist/generated/AgentScope.js +2 -0
- package/dist/generated/AgentTone.d.ts +4 -0
- package/dist/generated/AgentTone.js +2 -0
- package/dist/generated/ApiError.d.ts +25 -0
- package/dist/generated/ApiError.js +1 -0
- package/dist/generated/ApiErrorCode.d.ts +6 -0
- package/dist/generated/ApiErrorCode.js +2 -0
- package/dist/generated/ApiKeyBatchRevokeRequest.d.ts +3 -0
- package/dist/generated/ApiKeyBatchRevokeRequest.js +2 -0
- package/dist/generated/ApiKeyBatchRevokeResponse.d.ts +4 -0
- package/dist/generated/ApiKeyBatchRevokeResponse.js +1 -0
- package/dist/generated/ApiKeyListResponse.d.ts +4 -0
- package/dist/generated/ApiKeyListResponse.js +1 -0
- package/dist/generated/AuthRequest.d.ts +15 -0
- package/dist/generated/AuthRequest.js +2 -0
- package/dist/generated/AuthResponse.d.ts +16 -0
- package/dist/generated/AuthResponse.js +2 -0
- package/dist/generated/ChangePasswordRequest.d.ts +15 -0
- package/dist/generated/ChangePasswordRequest.js +2 -0
- package/dist/generated/Channel.d.ts +8 -0
- package/dist/generated/Channel.js +2 -0
- package/dist/generated/CheckRequest.d.ts +21 -0
- package/dist/generated/CheckRequest.js +1 -0
- package/dist/generated/CreateApiKeyRequest.d.ts +3 -0
- package/dist/generated/CreateApiKeyRequest.js +2 -0
- package/dist/generated/CreateApiKeyResponse.d.ts +8 -0
- package/dist/generated/CreateApiKeyResponse.js +1 -0
- package/dist/generated/CreateInviteRequest.d.ts +8 -0
- package/dist/generated/CreateInviteRequest.js +1 -0
- package/dist/generated/CreateInviteResponse.d.ts +18 -0
- package/dist/generated/CreateInviteResponse.js +1 -0
- package/dist/generated/CreateKnowledgeSourceRequest.d.ts +9 -0
- package/dist/generated/CreateKnowledgeSourceRequest.js +1 -0
- package/dist/generated/CreateRunEventRequest.d.ts +13 -0
- package/dist/generated/CreateRunEventRequest.js +1 -0
- package/dist/generated/CreateRunRequest.d.ts +9 -0
- package/dist/generated/CreateRunRequest.js +1 -0
- package/dist/generated/CreateWorkspaceRequest.d.ts +7 -0
- package/dist/generated/CreateWorkspaceRequest.js +2 -0
- package/dist/generated/DashboardApiKey.d.ts +15 -0
- package/dist/generated/DashboardApiKey.js +2 -0
- package/dist/generated/DashboardKnowledgeSourceKind.d.ts +1 -0
- package/dist/generated/DashboardKnowledgeSourceKind.js +2 -0
- package/dist/generated/Decision.d.ts +17 -0
- package/dist/generated/Decision.js +1 -0
- package/dist/generated/GuardrailGenerateResponse.d.ts +11 -0
- package/dist/generated/GuardrailGenerateResponse.js +1 -0
- package/dist/generated/GuardrailListResponse.d.ts +7 -0
- package/dist/generated/GuardrailListResponse.js +1 -0
- package/dist/generated/InviteListResponse.d.ts +4 -0
- package/dist/generated/InviteListResponse.js +1 -0
- package/dist/generated/InviteStatus.d.ts +4 -0
- package/dist/generated/InviteStatus.js +2 -0
- package/dist/generated/KnowledgeFileInput.d.ts +5 -0
- package/dist/generated/KnowledgeFileInput.js +2 -0
- package/dist/generated/KnowledgeFileMetadata.d.ts +6 -0
- package/dist/generated/KnowledgeFileMetadata.js +2 -0
- package/dist/generated/KnowledgeSource.d.ts +7 -0
- package/dist/generated/KnowledgeSource.js +1 -0
- package/dist/generated/KnowledgeSourceDocument.d.ts +22 -0
- package/dist/generated/KnowledgeSourceDocument.js +1 -0
- package/dist/generated/KnowledgeSourceFileResponse.d.ts +6 -0
- package/dist/generated/KnowledgeSourceFileResponse.js +2 -0
- package/dist/generated/KnowledgeSourceKind.d.ts +1 -0
- package/dist/generated/KnowledgeSourceKind.js +2 -0
- package/dist/generated/KnowledgeSourceListResponse.d.ts +4 -0
- package/dist/generated/KnowledgeSourceListResponse.js +1 -0
- package/dist/generated/KnowledgeSourceStatus.d.ts +1 -0
- package/dist/generated/KnowledgeSourceStatus.js +2 -0
- package/dist/generated/MemberListResponse.d.ts +4 -0
- package/dist/generated/MemberListResponse.js +1 -0
- package/dist/generated/MyWorkspace.d.ts +12 -0
- package/dist/generated/MyWorkspace.js +1 -0
- package/dist/generated/MyWorkspacesResponse.d.ts +4 -0
- package/dist/generated/MyWorkspacesResponse.js +1 -0
- package/dist/generated/PolicyAction.d.ts +4 -0
- package/dist/generated/PolicyAction.js +2 -0
- package/dist/generated/PolicyBatchSetEnabledRequest.d.ts +4 -0
- package/dist/generated/PolicyBatchSetEnabledRequest.js +2 -0
- package/dist/generated/PolicyBatchSetEnabledResponse.d.ts +4 -0
- package/dist/generated/PolicyBatchSetEnabledResponse.js +1 -0
- package/dist/generated/PolicyDocument.d.ts +8 -0
- package/dist/generated/PolicyDocument.js +1 -0
- package/dist/generated/PolicyDraft.d.ts +17 -0
- package/dist/generated/PolicyDraft.js +1 -0
- package/dist/generated/PolicyDraftRequest.d.ts +6 -0
- package/dist/generated/PolicyDraftRequest.js +2 -0
- package/dist/generated/PolicyDraftResponse.d.ts +4 -0
- package/dist/generated/PolicyDraftResponse.js +1 -0
- package/dist/generated/PolicyListResponse.d.ts +4 -0
- package/dist/generated/PolicyListResponse.js +1 -0
- package/dist/generated/PolicyMatchType.d.ts +5 -0
- package/dist/generated/PolicyMatchType.js +2 -0
- package/dist/generated/PolicySetEnabledRequest.d.ts +3 -0
- package/dist/generated/PolicySetEnabledRequest.js +2 -0
- package/dist/generated/PolicySummary.d.ts +9 -0
- package/dist/generated/PolicySummary.js +1 -0
- package/dist/generated/PolicyValidateResponse.d.ts +6 -0
- package/dist/generated/PolicyValidateResponse.js +1 -0
- package/dist/generated/PolicyValidationIssue.d.ts +4 -0
- package/dist/generated/PolicyValidationIssue.js +2 -0
- package/dist/generated/RunDetail.d.ts +8 -0
- package/dist/generated/RunDetail.js +1 -0
- package/dist/generated/RunEventKind.d.ts +1 -0
- package/dist/generated/RunEventKind.js +2 -0
- package/dist/generated/RunEventListResponse.d.ts +4 -0
- package/dist/generated/RunEventListResponse.js +1 -0
- package/dist/generated/RunEventSummary.d.ts +20 -0
- package/dist/generated/RunEventSummary.js +1 -0
- package/dist/generated/RunKind.d.ts +1 -0
- package/dist/generated/RunKind.js +2 -0
- package/dist/generated/RunListResponse.d.ts +4 -0
- package/dist/generated/RunListResponse.js +1 -0
- package/dist/generated/RunStatus.d.ts +1 -0
- package/dist/generated/RunStatus.js +2 -0
- package/dist/generated/RunSummary.d.ts +32 -0
- package/dist/generated/RunSummary.js +1 -0
- package/dist/generated/Severity.d.ts +1 -0
- package/dist/generated/Severity.js +2 -0
- package/dist/generated/Tier.d.ts +4 -0
- package/dist/generated/Tier.js +2 -0
- package/dist/generated/TierResult.d.ts +12 -0
- package/dist/generated/TierResult.js +1 -0
- package/dist/generated/TierStatus.d.ts +4 -0
- package/dist/generated/TierStatus.js +2 -0
- package/dist/generated/TraceListResponse.d.ts +4 -0
- package/dist/generated/TraceListResponse.js +1 -0
- package/dist/generated/TraceSummary.d.ts +13 -0
- package/dist/generated/TraceSummary.js +2 -0
- package/dist/generated/TriggeredPolicy.d.ts +6 -0
- package/dist/generated/TriggeredPolicy.js +1 -0
- package/dist/generated/UpdateRunRequest.d.ts +10 -0
- package/dist/generated/UpdateRunRequest.js +1 -0
- package/dist/generated/Verdict.d.ts +4 -0
- package/dist/generated/Verdict.js +2 -0
- package/dist/generated/WorkspaceInvite.d.ts +20 -0
- package/dist/generated/WorkspaceInvite.js +1 -0
- package/dist/generated/WorkspaceMember.d.ts +13 -0
- package/dist/generated/WorkspaceMember.js +1 -0
- package/dist/generated/WorkspaceRole.d.ts +5 -0
- package/dist/generated/WorkspaceRole.js +2 -0
- package/dist/generated/WorkspaceSettings.d.ts +11 -0
- package/dist/generated/WorkspaceSettings.js +2 -0
- package/dist/guard.d.ts +193 -0
- package/dist/guard.js +211 -0
- package/dist/index.d.ts +64 -0
- package/dist/index.js +64 -0
- package/dist/retry.d.ts +18 -0
- package/dist/retry.js +48 -0
- package/package.json +39 -0
- package/src/client.ts +453 -0
- package/src/errors.ts +202 -0
- package/src/generated/AgentAuthority.ts +3 -0
- package/src/generated/AgentListResponse.ts +4 -0
- package/src/generated/AgentProfile.ts +23 -0
- package/src/generated/AgentScope.ts +3 -0
- package/src/generated/AgentTone.ts +3 -0
- package/src/generated/ApiError.ts +24 -0
- package/src/generated/ApiErrorCode.ts +8 -0
- package/src/generated/ApiKeyBatchRevokeRequest.ts +3 -0
- package/src/generated/ApiKeyBatchRevokeResponse.ts +4 -0
- package/src/generated/ApiKeyListResponse.ts +4 -0
- package/src/generated/AuthRequest.ts +16 -0
- package/src/generated/AuthResponse.ts +15 -0
- package/src/generated/ChangePasswordRequest.ts +15 -0
- package/src/generated/Channel.ts +10 -0
- package/src/generated/CheckRequest.ts +11 -0
- package/src/generated/CreateApiKeyRequest.ts +3 -0
- package/src/generated/CreateApiKeyResponse.ts +8 -0
- package/src/generated/CreateInviteRequest.ts +7 -0
- package/src/generated/CreateInviteResponse.ts +14 -0
- package/src/generated/CreateKnowledgeSourceRequest.ts +5 -0
- package/src/generated/CreateRunEventRequest.ts +8 -0
- package/src/generated/CreateRunRequest.ts +5 -0
- package/src/generated/CreateWorkspaceRequest.ts +7 -0
- package/src/generated/DashboardApiKey.ts +11 -0
- package/src/generated/DashboardKnowledgeSourceKind.ts +3 -0
- package/src/generated/Decision.ts +12 -0
- package/src/generated/GuardrailGenerateResponse.ts +11 -0
- package/src/generated/GuardrailListResponse.ts +7 -0
- package/src/generated/InviteListResponse.ts +4 -0
- package/src/generated/InviteStatus.ts +6 -0
- package/src/generated/KnowledgeFileInput.ts +3 -0
- package/src/generated/KnowledgeFileMetadata.ts +3 -0
- package/src/generated/KnowledgeSource.ts +4 -0
- package/src/generated/KnowledgeSourceDocument.ts +17 -0
- package/src/generated/KnowledgeSourceFileResponse.ts +3 -0
- package/src/generated/KnowledgeSourceKind.ts +3 -0
- package/src/generated/KnowledgeSourceListResponse.ts +4 -0
- package/src/generated/KnowledgeSourceStatus.ts +3 -0
- package/src/generated/MemberListResponse.ts +4 -0
- package/src/generated/MyWorkspace.ts +8 -0
- package/src/generated/MyWorkspacesResponse.ts +4 -0
- package/src/generated/PolicyAction.ts +6 -0
- package/src/generated/PolicyBatchSetEnabledRequest.ts +3 -0
- package/src/generated/PolicyBatchSetEnabledResponse.ts +4 -0
- package/src/generated/PolicyDocument.ts +4 -0
- package/src/generated/PolicyDraft.ts +11 -0
- package/src/generated/PolicyDraftRequest.ts +6 -0
- package/src/generated/PolicyDraftResponse.ts +4 -0
- package/src/generated/PolicyListResponse.ts +4 -0
- package/src/generated/PolicyMatchType.ts +7 -0
- package/src/generated/PolicySetEnabledRequest.ts +3 -0
- package/src/generated/PolicySummary.ts +4 -0
- package/src/generated/PolicyValidateResponse.ts +4 -0
- package/src/generated/PolicyValidationIssue.ts +3 -0
- package/src/generated/README.md +1 -0
- package/src/generated/RunDetail.ts +6 -0
- package/src/generated/RunEventKind.ts +3 -0
- package/src/generated/RunEventListResponse.ts +4 -0
- package/src/generated/RunEventSummary.ts +12 -0
- package/src/generated/RunKind.ts +3 -0
- package/src/generated/RunListResponse.ts +4 -0
- package/src/generated/RunStatus.ts +3 -0
- package/src/generated/RunSummary.ts +21 -0
- package/src/generated/Severity.ts +3 -0
- package/src/generated/Tier.ts +6 -0
- package/src/generated/TierResult.ts +9 -0
- package/src/generated/TierStatus.ts +6 -0
- package/src/generated/TraceListResponse.ts +4 -0
- package/src/generated/TraceSummary.ts +7 -0
- package/src/generated/TriggeredPolicy.ts +4 -0
- package/src/generated/UpdateRunRequest.ts +9 -0
- package/src/generated/Verdict.ts +6 -0
- package/src/generated/WorkspaceInvite.ts +14 -0
- package/src/generated/WorkspaceMember.ts +11 -0
- package/src/generated/WorkspaceRole.ts +7 -0
- package/src/generated/WorkspaceSettings.ts +7 -0
- package/src/guard.ts +492 -0
- package/src/index.ts +97 -0
- package/src/retry.ts +67 -0
package/src/client.ts
ADDED
|
@@ -0,0 +1,453 @@
|
|
|
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
|
+
|
|
7
|
+
import type { CheckRequest } from './generated/CheckRequest';
|
|
8
|
+
import type { Decision } from './generated/Decision';
|
|
9
|
+
import type { AgentListResponse } from './generated/AgentListResponse';
|
|
10
|
+
import type { AgentProfile } from './generated/AgentProfile';
|
|
11
|
+
import type { ApiKeyBatchRevokeResponse } from './generated/ApiKeyBatchRevokeResponse';
|
|
12
|
+
import type { GuardrailGenerateResponse } from './generated/GuardrailGenerateResponse';
|
|
13
|
+
import type { GuardrailListResponse } from './generated/GuardrailListResponse';
|
|
14
|
+
import type { PolicyDocument } from './generated/PolicyDocument';
|
|
15
|
+
import type { PolicyBatchSetEnabledResponse } from './generated/PolicyBatchSetEnabledResponse';
|
|
16
|
+
import type { PolicyDraftResponse } from './generated/PolicyDraftResponse';
|
|
17
|
+
import type { PolicyListResponse } from './generated/PolicyListResponse';
|
|
18
|
+
import type { PolicyValidateResponse } from './generated/PolicyValidateResponse';
|
|
19
|
+
import type { CreateRunEventRequest } from './generated/CreateRunEventRequest';
|
|
20
|
+
import type { CreateRunRequest } from './generated/CreateRunRequest';
|
|
21
|
+
import type { RunDetail } from './generated/RunDetail';
|
|
22
|
+
import type { RunEventListResponse } from './generated/RunEventListResponse';
|
|
23
|
+
import type { RunEventSummary } from './generated/RunEventSummary';
|
|
24
|
+
import type { RunListResponse } from './generated/RunListResponse';
|
|
25
|
+
import type { RunStatus } from './generated/RunStatus';
|
|
26
|
+
import type { RunSummary } from './generated/RunSummary';
|
|
27
|
+
import type { TraceListResponse } from './generated/TraceListResponse';
|
|
28
|
+
import type { UpdateRunRequest } from './generated/UpdateRunRequest';
|
|
29
|
+
import { Decode, SdkError, Transport, fromResponse, parseRetryAfter } from './errors';
|
|
30
|
+
import { DEFAULT_RETRY, type RetryConfig, nextDelay } from './retry';
|
|
31
|
+
|
|
32
|
+
export interface ClientOptions {
|
|
33
|
+
baseUrl: string;
|
|
34
|
+
apiKey?: string;
|
|
35
|
+
fetchImpl?: typeof fetch;
|
|
36
|
+
retry?: RetryConfig;
|
|
37
|
+
/**
|
|
38
|
+
* Hook invoked once per retry decision. Useful for surfacing retry
|
|
39
|
+
* activity in logs / OpenTelemetry without forcing a logger
|
|
40
|
+
* dependency on the SDK.
|
|
41
|
+
*/
|
|
42
|
+
onRetry?: (info: { attempt: number; delayS: number; error: SdkError }) => void;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export class Client {
|
|
46
|
+
private readonly baseUrl: string;
|
|
47
|
+
private readonly apiKey: string | undefined;
|
|
48
|
+
private readonly fetchImpl: typeof fetch;
|
|
49
|
+
private readonly retry: RetryConfig;
|
|
50
|
+
private readonly onRetry: ClientOptions['onRetry'];
|
|
51
|
+
|
|
52
|
+
constructor(opts: ClientOptions) {
|
|
53
|
+
this.baseUrl = opts.baseUrl.replace(/\/$/, '');
|
|
54
|
+
this.apiKey = opts.apiKey;
|
|
55
|
+
this.fetchImpl = opts.fetchImpl ?? globalThis.fetch.bind(globalThis);
|
|
56
|
+
this.retry = opts.retry ?? DEFAULT_RETRY;
|
|
57
|
+
this.onRetry = opts.onRetry;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async check(req: CheckRequest, signal?: AbortSignal): Promise<Decision> {
|
|
61
|
+
return this.withRetry(
|
|
62
|
+
(signal) =>
|
|
63
|
+
this.sendJson<Decision>(
|
|
64
|
+
'/v1/check',
|
|
65
|
+
{
|
|
66
|
+
method: 'POST',
|
|
67
|
+
body: JSON.stringify(req),
|
|
68
|
+
},
|
|
69
|
+
signal,
|
|
70
|
+
),
|
|
71
|
+
signal,
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async startRun(
|
|
76
|
+
req: Omit<CreateRunRequest, 'metadata'> & { metadata?: Record<string, unknown> },
|
|
77
|
+
signal?: AbortSignal,
|
|
78
|
+
): Promise<RunSummary> {
|
|
79
|
+
return this.withRetry(
|
|
80
|
+
(signal) =>
|
|
81
|
+
this.sendJson<RunSummary>(
|
|
82
|
+
'/v1/runs',
|
|
83
|
+
{
|
|
84
|
+
method: 'POST',
|
|
85
|
+
body: JSON.stringify({ metadata: {}, ...req }),
|
|
86
|
+
},
|
|
87
|
+
signal,
|
|
88
|
+
),
|
|
89
|
+
signal,
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async listRuns(signal?: AbortSignal): Promise<RunListResponse> {
|
|
94
|
+
return this.withRetry(
|
|
95
|
+
(signal) => this.sendJson<RunListResponse>('/v1/runs', { method: 'GET' }, signal),
|
|
96
|
+
signal,
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
async getRun(runId: string, signal?: AbortSignal): Promise<RunDetail> {
|
|
101
|
+
return this.withRetry(
|
|
102
|
+
(signal) =>
|
|
103
|
+
this.sendJson<RunDetail>(
|
|
104
|
+
`/v1/runs/${encodeURIComponent(runId)}`,
|
|
105
|
+
{ method: 'GET' },
|
|
106
|
+
signal,
|
|
107
|
+
),
|
|
108
|
+
signal,
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
async updateRun(
|
|
113
|
+
runId: string,
|
|
114
|
+
req: UpdateRunRequest,
|
|
115
|
+
signal?: AbortSignal,
|
|
116
|
+
): Promise<RunSummary> {
|
|
117
|
+
return this.withRetry(
|
|
118
|
+
(signal) =>
|
|
119
|
+
this.sendJson<RunSummary>(
|
|
120
|
+
`/v1/runs/${encodeURIComponent(runId)}`,
|
|
121
|
+
{
|
|
122
|
+
method: 'PATCH',
|
|
123
|
+
body: JSON.stringify(req),
|
|
124
|
+
},
|
|
125
|
+
signal,
|
|
126
|
+
),
|
|
127
|
+
signal,
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
async finishRun(
|
|
132
|
+
runId: string,
|
|
133
|
+
status: Extract<RunStatus, 'completed' | 'failed' | 'canceled'> = 'completed',
|
|
134
|
+
signal?: AbortSignal,
|
|
135
|
+
): Promise<RunSummary> {
|
|
136
|
+
return this.updateRun(runId, { status }, signal);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
async createRunEvent(
|
|
140
|
+
runId: string,
|
|
141
|
+
req: Omit<CreateRunEventRequest, 'metadata'> & { metadata?: Record<string, unknown> },
|
|
142
|
+
signal?: AbortSignal,
|
|
143
|
+
): Promise<RunEventSummary> {
|
|
144
|
+
return this.withRetry(
|
|
145
|
+
(signal) =>
|
|
146
|
+
this.sendJson<RunEventSummary>(
|
|
147
|
+
`/v1/runs/${encodeURIComponent(runId)}/events`,
|
|
148
|
+
{
|
|
149
|
+
method: 'POST',
|
|
150
|
+
body: JSON.stringify({ metadata: {}, ...req }),
|
|
151
|
+
},
|
|
152
|
+
signal,
|
|
153
|
+
),
|
|
154
|
+
signal,
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
async listRunEvents(runId: string, signal?: AbortSignal): Promise<RunEventListResponse> {
|
|
159
|
+
return this.withRetry(
|
|
160
|
+
(signal) =>
|
|
161
|
+
this.sendJson<RunEventListResponse>(
|
|
162
|
+
`/v1/runs/${encodeURIComponent(runId)}/events`,
|
|
163
|
+
{ method: 'GET' },
|
|
164
|
+
signal,
|
|
165
|
+
),
|
|
166
|
+
signal,
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
async listRunTraces(runId: string, signal?: AbortSignal): Promise<TraceListResponse> {
|
|
171
|
+
return this.withRetry(
|
|
172
|
+
(signal) =>
|
|
173
|
+
this.sendJson<TraceListResponse>(
|
|
174
|
+
`/v1/runs/${encodeURIComponent(runId)}/traces`,
|
|
175
|
+
{ method: 'GET' },
|
|
176
|
+
signal,
|
|
177
|
+
),
|
|
178
|
+
signal,
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
async validatePolicy(source: string, signal?: AbortSignal): Promise<PolicyValidateResponse> {
|
|
183
|
+
return this.withRetry(
|
|
184
|
+
(signal) =>
|
|
185
|
+
this.sendText<PolicyValidateResponse>(
|
|
186
|
+
'/v1/policies/validate',
|
|
187
|
+
'POST',
|
|
188
|
+
source,
|
|
189
|
+
'application/yaml',
|
|
190
|
+
signal,
|
|
191
|
+
),
|
|
192
|
+
signal,
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
async listPolicies(signal?: AbortSignal): Promise<PolicyListResponse> {
|
|
197
|
+
return this.withRetry(
|
|
198
|
+
(signal) => this.sendJson<PolicyListResponse>('/v1/policies', { method: 'GET' }, signal),
|
|
199
|
+
signal,
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
async listAgents(signal?: AbortSignal): Promise<AgentListResponse> {
|
|
204
|
+
return this.withRetry(
|
|
205
|
+
(signal) => this.sendJson<AgentListResponse>('/v1/agents', { method: 'GET' }, signal),
|
|
206
|
+
signal,
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
async upsertAgent(profile: AgentProfile, signal?: AbortSignal): Promise<AgentProfile> {
|
|
211
|
+
return this.withRetry(
|
|
212
|
+
(signal) =>
|
|
213
|
+
this.sendJson<AgentProfile>(
|
|
214
|
+
'/v1/agents',
|
|
215
|
+
{
|
|
216
|
+
method: 'POST',
|
|
217
|
+
body: JSON.stringify(profile),
|
|
218
|
+
},
|
|
219
|
+
signal,
|
|
220
|
+
),
|
|
221
|
+
signal,
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
async getPolicy(policyId: string, signal?: AbortSignal): Promise<PolicyDocument> {
|
|
226
|
+
return this.withRetry(
|
|
227
|
+
(signal) =>
|
|
228
|
+
this.sendJson<PolicyDocument>(
|
|
229
|
+
`/v1/policies/${encodeURIComponent(policyId)}`,
|
|
230
|
+
{ method: 'GET' },
|
|
231
|
+
signal,
|
|
232
|
+
),
|
|
233
|
+
signal,
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
async upsertPolicy(source: string, signal?: AbortSignal): Promise<PolicyDocument> {
|
|
238
|
+
return this.withRetry(
|
|
239
|
+
(signal) =>
|
|
240
|
+
this.sendText<PolicyDocument>('/v1/policies', 'POST', source, 'application/yaml', signal),
|
|
241
|
+
signal,
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
async setPolicyEnabled(
|
|
246
|
+
policyId: string,
|
|
247
|
+
enabled: boolean,
|
|
248
|
+
signal?: AbortSignal,
|
|
249
|
+
): Promise<PolicyDocument> {
|
|
250
|
+
return this.withRetry(
|
|
251
|
+
(signal) =>
|
|
252
|
+
this.sendJson<PolicyDocument>(
|
|
253
|
+
`/v1/policies/${encodeURIComponent(policyId)}/enabled`,
|
|
254
|
+
{
|
|
255
|
+
method: 'PATCH',
|
|
256
|
+
body: JSON.stringify({ enabled }),
|
|
257
|
+
},
|
|
258
|
+
signal,
|
|
259
|
+
),
|
|
260
|
+
signal,
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
async batchSetPolicyEnabled(
|
|
265
|
+
policyIds: string[],
|
|
266
|
+
enabled: boolean,
|
|
267
|
+
signal?: AbortSignal,
|
|
268
|
+
): Promise<PolicyBatchSetEnabledResponse> {
|
|
269
|
+
return this.withRetry(
|
|
270
|
+
(signal) =>
|
|
271
|
+
this.sendJson<PolicyBatchSetEnabledResponse>(
|
|
272
|
+
'/v1/policies/batch/enabled',
|
|
273
|
+
{
|
|
274
|
+
method: 'PATCH',
|
|
275
|
+
body: JSON.stringify({ ids: policyIds, enabled }),
|
|
276
|
+
},
|
|
277
|
+
signal,
|
|
278
|
+
),
|
|
279
|
+
signal,
|
|
280
|
+
);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* LLM-draft a policy skeleton from a natural-language prompt. The
|
|
285
|
+
* server holds the provider key; the response is a strict, typed
|
|
286
|
+
* `PolicyDraftResponse`. Returns a 503-mapped `Unavailable` error when
|
|
287
|
+
* the deployment has no LLM configured.
|
|
288
|
+
*/
|
|
289
|
+
async draftPolicy(prompt: string, signal?: AbortSignal): Promise<PolicyDraftResponse> {
|
|
290
|
+
return this.withRetry(
|
|
291
|
+
(signal) =>
|
|
292
|
+
this.sendJson<PolicyDraftResponse>(
|
|
293
|
+
'/v1/policies/draft',
|
|
294
|
+
{
|
|
295
|
+
method: 'POST',
|
|
296
|
+
body: JSON.stringify({ prompt }),
|
|
297
|
+
},
|
|
298
|
+
signal,
|
|
299
|
+
),
|
|
300
|
+
signal,
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Derive a guardrail policy set from the agent's stored `system_prompt`,
|
|
306
|
+
* auto-persist each draft with `enabled=false`, and return what was
|
|
307
|
+
* saved. The caller must have previously registered the agent (with a
|
|
308
|
+
* non-empty `system_prompt`) via `POST /v1/agents`.
|
|
309
|
+
*
|
|
310
|
+
* Errors:
|
|
311
|
+
* - `NotFound` (404) — agent is not registered.
|
|
312
|
+
* - `Unprocessable` (422) — agent has no `system_prompt`.
|
|
313
|
+
* - `Unavailable` (503) — the deployment has no LLM configured.
|
|
314
|
+
*/
|
|
315
|
+
async generateGuardrails(
|
|
316
|
+
agentId: string,
|
|
317
|
+
signal?: AbortSignal,
|
|
318
|
+
): Promise<GuardrailGenerateResponse> {
|
|
319
|
+
return this.withRetry(
|
|
320
|
+
(signal) =>
|
|
321
|
+
this.sendJson<GuardrailGenerateResponse>(
|
|
322
|
+
`/v1/agents/${encodeURIComponent(agentId)}/guardrails/generate`,
|
|
323
|
+
{ method: 'POST' },
|
|
324
|
+
signal,
|
|
325
|
+
),
|
|
326
|
+
signal,
|
|
327
|
+
);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* List policies owned by an agent. Empty when the agent has none or
|
|
332
|
+
* doesn't exist — existence is the caller's concern.
|
|
333
|
+
*/
|
|
334
|
+
async listGuardrails(agentId: string, signal?: AbortSignal): Promise<GuardrailListResponse> {
|
|
335
|
+
return this.withRetry(
|
|
336
|
+
(signal) =>
|
|
337
|
+
this.sendJson<GuardrailListResponse>(
|
|
338
|
+
`/v1/agents/${encodeURIComponent(agentId)}/guardrails`,
|
|
339
|
+
{ method: 'GET' },
|
|
340
|
+
signal,
|
|
341
|
+
),
|
|
342
|
+
signal,
|
|
343
|
+
);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
async deletePolicy(policyId: string, signal?: AbortSignal): Promise<void> {
|
|
347
|
+
return this.withRetry(
|
|
348
|
+
(signal) =>
|
|
349
|
+
this.sendJson<void>(
|
|
350
|
+
`/v1/policies/${encodeURIComponent(policyId)}`,
|
|
351
|
+
{ method: 'DELETE' },
|
|
352
|
+
signal,
|
|
353
|
+
),
|
|
354
|
+
signal,
|
|
355
|
+
);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
async batchRevokeApiKeys(
|
|
359
|
+
apiKeyIds: string[],
|
|
360
|
+
signal?: AbortSignal,
|
|
361
|
+
): Promise<ApiKeyBatchRevokeResponse> {
|
|
362
|
+
return this.withRetry(
|
|
363
|
+
(signal) =>
|
|
364
|
+
this.sendJson<ApiKeyBatchRevokeResponse>(
|
|
365
|
+
'/v1/api-keys/batch/revoke',
|
|
366
|
+
{
|
|
367
|
+
method: 'PATCH',
|
|
368
|
+
body: JSON.stringify({ ids: apiKeyIds }),
|
|
369
|
+
},
|
|
370
|
+
signal,
|
|
371
|
+
),
|
|
372
|
+
signal,
|
|
373
|
+
);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
private async withRetry<T>(
|
|
377
|
+
send: (signal?: AbortSignal) => Promise<T>,
|
|
378
|
+
signal?: AbortSignal,
|
|
379
|
+
): Promise<T> {
|
|
380
|
+
const start = performance.now();
|
|
381
|
+
let attempt = 0;
|
|
382
|
+
while (true) {
|
|
383
|
+
attempt += 1;
|
|
384
|
+
try {
|
|
385
|
+
return await send(signal);
|
|
386
|
+
} catch (e) {
|
|
387
|
+
if (!(e instanceof SdkError)) throw e;
|
|
388
|
+
const elapsedS = (performance.now() - start) / 1000;
|
|
389
|
+
const delay = nextDelay(this.retry, attempt, elapsedS, e, Math.random());
|
|
390
|
+
if (delay === undefined) throw e;
|
|
391
|
+
this.onRetry?.({ attempt, delayS: delay, error: e });
|
|
392
|
+
await new Promise((resolve) => setTimeout(resolve, delay * 1000));
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
private async sendText<T>(
|
|
398
|
+
path: string,
|
|
399
|
+
method: string,
|
|
400
|
+
body: string,
|
|
401
|
+
contentType: string,
|
|
402
|
+
signal?: AbortSignal,
|
|
403
|
+
): Promise<T> {
|
|
404
|
+
return this.sendJson<T>(
|
|
405
|
+
path,
|
|
406
|
+
{
|
|
407
|
+
method,
|
|
408
|
+
headers: { 'content-type': contentType },
|
|
409
|
+
body,
|
|
410
|
+
},
|
|
411
|
+
signal,
|
|
412
|
+
);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
private async sendJson<T>(path: string, init: RequestInit, signal?: AbortSignal): Promise<T> {
|
|
416
|
+
const headers: Record<string, string> = {
|
|
417
|
+
'content-type': 'application/json',
|
|
418
|
+
...((init.headers as Record<string, string> | undefined) ?? {}),
|
|
419
|
+
};
|
|
420
|
+
if (this.apiKey !== undefined) {
|
|
421
|
+
headers['authorization'] = `Bearer ${this.apiKey}`;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
const requestInit: RequestInit = {
|
|
425
|
+
...init,
|
|
426
|
+
headers,
|
|
427
|
+
};
|
|
428
|
+
if (signal !== undefined) {
|
|
429
|
+
requestInit.signal = signal;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
let res: Response;
|
|
433
|
+
try {
|
|
434
|
+
res = await this.fetchImpl(`${this.baseUrl}${path}`, requestInit);
|
|
435
|
+
} catch (e) {
|
|
436
|
+
throw new Transport(e instanceof Error ? e.message : String(e));
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
if (res.status === 204) return undefined as T;
|
|
440
|
+
|
|
441
|
+
if (res.ok) {
|
|
442
|
+
try {
|
|
443
|
+
return (await res.json()) as T;
|
|
444
|
+
} catch (e) {
|
|
445
|
+
throw new Decode(`failed to parse response: ${String(e)}`);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
const retryAfter = parseRetryAfter(res.headers.get('retry-after'));
|
|
450
|
+
const body = await res.text().catch(() => '');
|
|
451
|
+
throw fromResponse(res.status, body, retryAfter);
|
|
452
|
+
}
|
|
453
|
+
}
|
package/src/errors.ts
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
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
|
+
|
|
22
|
+
import type { ApiError } from './generated/ApiError';
|
|
23
|
+
import type { ApiErrorCode } from './generated/ApiErrorCode';
|
|
24
|
+
|
|
25
|
+
const STATUS_TO_CODE: Record<number, ApiErrorCode> = {
|
|
26
|
+
400: 'invalid',
|
|
27
|
+
401: 'unauthorized',
|
|
28
|
+
403: 'forbidden',
|
|
29
|
+
404: 'not_found',
|
|
30
|
+
410: 'gone',
|
|
31
|
+
422: 'unprocessable',
|
|
32
|
+
429: 'rate_limited',
|
|
33
|
+
500: 'internal',
|
|
34
|
+
501: 'internal',
|
|
35
|
+
502: 'unavailable',
|
|
36
|
+
503: 'unavailable',
|
|
37
|
+
504: 'unavailable',
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const DEFAULT_RETRIABLE: ReadonlySet<ApiErrorCode> = new Set<ApiErrorCode>([
|
|
41
|
+
'rate_limited',
|
|
42
|
+
'unavailable',
|
|
43
|
+
]);
|
|
44
|
+
|
|
45
|
+
export function codeFromHttpStatus(status: number): ApiErrorCode {
|
|
46
|
+
if (status in STATUS_TO_CODE) {
|
|
47
|
+
return STATUS_TO_CODE[status]!;
|
|
48
|
+
}
|
|
49
|
+
if (status >= 500 && status < 600) return 'internal';
|
|
50
|
+
return 'invalid';
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function synthesizeApiError(status: number, body: string): ApiError {
|
|
54
|
+
const code = codeFromHttpStatus(status);
|
|
55
|
+
return {
|
|
56
|
+
code,
|
|
57
|
+
message: body || `server returned status ${status}`,
|
|
58
|
+
retriable: DEFAULT_RETRIABLE.has(code),
|
|
59
|
+
details: null,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export class SdkError extends Error {
|
|
64
|
+
readonly error: ApiError;
|
|
65
|
+
constructor(error: ApiError) {
|
|
66
|
+
super(`${error.code}: ${error.message}`);
|
|
67
|
+
this.name = 'SdkError';
|
|
68
|
+
this.error = error;
|
|
69
|
+
// Preserve prototype chain for `instanceof` to work after transpile.
|
|
70
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
71
|
+
}
|
|
72
|
+
get code(): ApiErrorCode {
|
|
73
|
+
return this.error.code;
|
|
74
|
+
}
|
|
75
|
+
isRetriable(): boolean {
|
|
76
|
+
return this.error.retriable;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// One subclass per ApiErrorCode. The classes carry no extra behavior
|
|
81
|
+
// beyond their name — they exist so callers can use `instanceof` and
|
|
82
|
+
// stack traces are labeled. RateLimited is the one exception: it carries
|
|
83
|
+
// the parsed Retry-After value.
|
|
84
|
+
|
|
85
|
+
export class Invalid extends SdkError {
|
|
86
|
+
constructor(error: ApiError) {
|
|
87
|
+
super(error);
|
|
88
|
+
this.name = 'Invalid';
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
export class Unauthorized extends SdkError {
|
|
92
|
+
constructor(error: ApiError) {
|
|
93
|
+
super(error);
|
|
94
|
+
this.name = 'Unauthorized';
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
export class Forbidden extends SdkError {
|
|
98
|
+
constructor(error: ApiError) {
|
|
99
|
+
super(error);
|
|
100
|
+
this.name = 'Forbidden';
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
export class NotFound extends SdkError {
|
|
104
|
+
constructor(error: ApiError) {
|
|
105
|
+
super(error);
|
|
106
|
+
this.name = 'NotFound';
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
export class Gone extends SdkError {
|
|
110
|
+
constructor(error: ApiError) {
|
|
111
|
+
super(error);
|
|
112
|
+
this.name = 'Gone';
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
export class Unprocessable extends SdkError {
|
|
116
|
+
constructor(error: ApiError) {
|
|
117
|
+
super(error);
|
|
118
|
+
this.name = 'Unprocessable';
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
export class RateLimited extends SdkError {
|
|
122
|
+
readonly retryAfter: number | undefined;
|
|
123
|
+
constructor(error: ApiError, retryAfter?: number) {
|
|
124
|
+
super(error);
|
|
125
|
+
this.name = 'RateLimited';
|
|
126
|
+
this.retryAfter = retryAfter;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
export class Internal extends SdkError {
|
|
130
|
+
constructor(error: ApiError) {
|
|
131
|
+
super(error);
|
|
132
|
+
this.name = 'Internal';
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
export class Unavailable extends SdkError {
|
|
136
|
+
constructor(error: ApiError) {
|
|
137
|
+
super(error);
|
|
138
|
+
this.name = 'Unavailable';
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
export class Transport extends SdkError {
|
|
142
|
+
constructor(message: string) {
|
|
143
|
+
super({ code: 'unavailable', message, retriable: true, details: null });
|
|
144
|
+
this.name = 'Transport';
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
export class Decode extends SdkError {
|
|
148
|
+
constructor(message: string) {
|
|
149
|
+
super({ code: 'internal', message, retriable: false, details: null });
|
|
150
|
+
this.name = 'Decode';
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const CODE_TO_CLASS: Record<ApiErrorCode, new (e: ApiError) => SdkError> = {
|
|
155
|
+
invalid: Invalid,
|
|
156
|
+
unauthorized: Unauthorized,
|
|
157
|
+
forbidden: Forbidden,
|
|
158
|
+
not_found: NotFound,
|
|
159
|
+
gone: Gone,
|
|
160
|
+
unprocessable: Unprocessable,
|
|
161
|
+
rate_limited: RateLimited,
|
|
162
|
+
internal: Internal,
|
|
163
|
+
unavailable: Unavailable,
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
function isApiError(value: unknown): value is ApiError {
|
|
167
|
+
if (typeof value !== 'object' || value === null) return false;
|
|
168
|
+
const v = value as Partial<ApiError>;
|
|
169
|
+
return (
|
|
170
|
+
typeof v.code === 'string' &&
|
|
171
|
+
typeof v.message === 'string' &&
|
|
172
|
+
typeof v.retriable === 'boolean' &&
|
|
173
|
+
v.code in CODE_TO_CLASS
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export function fromResponse(
|
|
178
|
+
status: number,
|
|
179
|
+
body: string,
|
|
180
|
+
retryAfter?: number,
|
|
181
|
+
): SdkError {
|
|
182
|
+
let apiErr: ApiError;
|
|
183
|
+
try {
|
|
184
|
+
const parsed: unknown = JSON.parse(body);
|
|
185
|
+
apiErr = isApiError(parsed) ? parsed : synthesizeApiError(status, body);
|
|
186
|
+
} catch {
|
|
187
|
+
apiErr = synthesizeApiError(status, body);
|
|
188
|
+
}
|
|
189
|
+
if (apiErr.code === 'rate_limited') {
|
|
190
|
+
return new RateLimited(apiErr, retryAfter);
|
|
191
|
+
}
|
|
192
|
+
const Cls = CODE_TO_CLASS[apiErr.code];
|
|
193
|
+
return new Cls(apiErr);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export function parseRetryAfter(header: string | null | undefined): number | undefined {
|
|
197
|
+
if (header === null || header === undefined) return undefined;
|
|
198
|
+
const trimmed = header.trim();
|
|
199
|
+
const n = Number(trimmed);
|
|
200
|
+
if (!Number.isFinite(n)) return undefined;
|
|
201
|
+
return n;
|
|
202
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
|
2
|
+
import type { AgentAuthority } from "./AgentAuthority";
|
|
3
|
+
import type { AgentScope } from "./AgentScope";
|
|
4
|
+
import type { AgentTone } from "./AgentTone";
|
|
5
|
+
import type { KnowledgeSource } from "./KnowledgeSource";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* What an agent is, what it may claim, and how it should sound.
|
|
9
|
+
*
|
|
10
|
+
* Authored as YAML by the customer (see `policies/agents/*.yaml`), parsed
|
|
11
|
+
* by `tl-policy::load_agent_str`, persisted in Postgres, cached in process,
|
|
12
|
+
* and consulted by Tier 2 (out-of-scope embedding lookup) and Tier 3
|
|
13
|
+
* (LLM judge ground truth).
|
|
14
|
+
*/
|
|
15
|
+
export type AgentProfile = { agent_id: string, display_name: string, scope: AgentScope, authority: AgentAuthority, tone: AgentTone, knowledge_sources: Array<KnowledgeSource>, escalation_triggers: Array<string>,
|
|
16
|
+
/**
|
|
17
|
+
* Raw system prompt the customer ships to their LLM. Source of truth
|
|
18
|
+
* for auto-generating guardrails: `POST /v1/agents/{id}/guardrails:generate`
|
|
19
|
+
* reads this and asks an LLM to derive a policy set tailored to it.
|
|
20
|
+
* Optional at the type level so existing profiles keep deserializing;
|
|
21
|
+
* the generate endpoint enforces presence at call time.
|
|
22
|
+
*/
|
|
23
|
+
system_prompt?: string, };
|