@cdot65/prisma-airs-cli 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (234) hide show
  1. package/README.md +42 -0
  2. package/dist/airs/management.d.ts +58 -0
  3. package/dist/airs/management.d.ts.map +1 -0
  4. package/dist/airs/management.js +287 -0
  5. package/dist/airs/management.js.map +1 -0
  6. package/dist/airs/modelsecurity.d.ts +74 -0
  7. package/dist/airs/modelsecurity.d.ts.map +1 -0
  8. package/dist/airs/modelsecurity.js +337 -0
  9. package/dist/airs/modelsecurity.js.map +1 -0
  10. package/dist/airs/promptsets.d.ts +50 -0
  11. package/dist/airs/promptsets.d.ts.map +1 -0
  12. package/dist/airs/promptsets.js +133 -0
  13. package/dist/airs/promptsets.js.map +1 -0
  14. package/dist/airs/redteam.d.ts +45 -0
  15. package/dist/airs/redteam.d.ts.map +1 -0
  16. package/dist/airs/redteam.js +219 -0
  17. package/dist/airs/redteam.js.map +1 -0
  18. package/dist/airs/runtime.d.ts +27 -0
  19. package/dist/airs/runtime.d.ts.map +1 -0
  20. package/dist/airs/runtime.js +158 -0
  21. package/dist/airs/runtime.js.map +1 -0
  22. package/dist/airs/scanner.d.ts +22 -0
  23. package/dist/airs/scanner.d.ts.map +1 -0
  24. package/dist/airs/scanner.js +62 -0
  25. package/dist/airs/scanner.js.map +1 -0
  26. package/dist/airs/types.d.ts +683 -0
  27. package/dist/airs/types.d.ts.map +1 -0
  28. package/dist/airs/types.js +6 -0
  29. package/dist/airs/types.js.map +1 -0
  30. package/dist/audit/evaluator.d.ts +17 -0
  31. package/dist/audit/evaluator.d.ts.map +1 -0
  32. package/dist/audit/evaluator.js +82 -0
  33. package/dist/audit/evaluator.js.map +1 -0
  34. package/dist/audit/report.d.ts +38 -0
  35. package/dist/audit/report.d.ts.map +1 -0
  36. package/dist/audit/report.js +141 -0
  37. package/dist/audit/report.js.map +1 -0
  38. package/dist/audit/runner.d.ts +18 -0
  39. package/dist/audit/runner.d.ts.map +1 -0
  40. package/dist/audit/runner.js +60 -0
  41. package/dist/audit/runner.js.map +1 -0
  42. package/dist/audit/types.d.ts +53 -0
  43. package/dist/audit/types.d.ts.map +1 -0
  44. package/dist/audit/types.js +5 -0
  45. package/dist/audit/types.js.map +1 -0
  46. package/dist/cli/bulk-scan-state.d.ts +15 -0
  47. package/dist/cli/bulk-scan-state.d.ts.map +1 -0
  48. package/dist/cli/bulk-scan-state.js +20 -0
  49. package/dist/cli/bulk-scan-state.js.map +1 -0
  50. package/dist/cli/commands/audit.d.ts +4 -0
  51. package/dist/cli/commands/audit.d.ts.map +1 -0
  52. package/dist/cli/commands/audit.js +113 -0
  53. package/dist/cli/commands/audit.js.map +1 -0
  54. package/dist/cli/commands/generate.d.ts +4 -0
  55. package/dist/cli/commands/generate.d.ts.map +1 -0
  56. package/dist/cli/commands/generate.js +231 -0
  57. package/dist/cli/commands/generate.js.map +1 -0
  58. package/dist/cli/commands/list.d.ts +4 -0
  59. package/dist/cli/commands/list.d.ts.map +1 -0
  60. package/dist/cli/commands/list.js +23 -0
  61. package/dist/cli/commands/list.js.map +1 -0
  62. package/dist/cli/commands/modelsecurity.d.ts +4 -0
  63. package/dist/cli/commands/modelsecurity.d.ts.map +1 -0
  64. package/dist/cli/commands/modelsecurity.js +499 -0
  65. package/dist/cli/commands/modelsecurity.js.map +1 -0
  66. package/dist/cli/commands/redteam.d.ts +4 -0
  67. package/dist/cli/commands/redteam.d.ts.map +1 -0
  68. package/dist/cli/commands/redteam.js +630 -0
  69. package/dist/cli/commands/redteam.js.map +1 -0
  70. package/dist/cli/commands/report.d.ts +4 -0
  71. package/dist/cli/commands/report.d.ts.map +1 -0
  72. package/dist/cli/commands/report.js +116 -0
  73. package/dist/cli/commands/report.js.map +1 -0
  74. package/dist/cli/commands/resume.d.ts +4 -0
  75. package/dist/cli/commands/resume.d.ts.map +1 -0
  76. package/dist/cli/commands/resume.js +138 -0
  77. package/dist/cli/commands/resume.js.map +1 -0
  78. package/dist/cli/commands/runtime.d.ts +3 -0
  79. package/dist/cli/commands/runtime.d.ts.map +1 -0
  80. package/dist/cli/commands/runtime.js +582 -0
  81. package/dist/cli/commands/runtime.js.map +1 -0
  82. package/dist/cli/index.d.ts +3 -0
  83. package/dist/cli/index.d.ts.map +1 -0
  84. package/dist/cli/index.js +46 -0
  85. package/dist/cli/index.js.map +1 -0
  86. package/dist/cli/parse-input.d.ts +9 -0
  87. package/dist/cli/parse-input.d.ts.map +1 -0
  88. package/dist/cli/parse-input.js +109 -0
  89. package/dist/cli/parse-input.js.map +1 -0
  90. package/dist/cli/prompts.d.ts +9 -0
  91. package/dist/cli/prompts.d.ts.map +1 -0
  92. package/dist/cli/prompts.js +90 -0
  93. package/dist/cli/prompts.js.map +1 -0
  94. package/dist/cli/renderer/audit.d.ts +8 -0
  95. package/dist/cli/renderer/audit.d.ts.map +1 -0
  96. package/dist/cli/renderer/audit.js +44 -0
  97. package/dist/cli/renderer/audit.js.map +1 -0
  98. package/dist/cli/renderer/common.d.ts +3 -0
  99. package/dist/cli/renderer/common.d.ts.map +1 -0
  100. package/dist/cli/renderer/common.js +6 -0
  101. package/dist/cli/renderer/common.js.map +1 -0
  102. package/dist/cli/renderer/generate.d.ts +29 -0
  103. package/dist/cli/renderer/generate.d.ts.map +1 -0
  104. package/dist/cli/renderer/generate.js +132 -0
  105. package/dist/cli/renderer/generate.js.map +1 -0
  106. package/dist/cli/renderer/index.d.ts +7 -0
  107. package/dist/cli/renderer/index.d.ts.map +1 -0
  108. package/dist/cli/renderer/index.js +7 -0
  109. package/dist/cli/renderer/index.js.map +1 -0
  110. package/dist/cli/renderer/modelsecurity.d.ts +34 -0
  111. package/dist/cli/renderer/modelsecurity.d.ts.map +1 -0
  112. package/dist/cli/renderer/modelsecurity.js +285 -0
  113. package/dist/cli/renderer/modelsecurity.js.map +1 -0
  114. package/dist/cli/renderer/redteam.d.ts +152 -0
  115. package/dist/cli/renderer/redteam.d.ts.map +1 -0
  116. package/dist/cli/renderer/redteam.js +294 -0
  117. package/dist/cli/renderer/redteam.js.map +1 -0
  118. package/dist/cli/renderer/runtime.d.ts +87 -0
  119. package/dist/cli/renderer/runtime.d.ts.map +1 -0
  120. package/dist/cli/renderer/runtime.js +230 -0
  121. package/dist/cli/renderer/runtime.js.map +1 -0
  122. package/dist/config/loader.d.ts +3 -0
  123. package/dist/config/loader.d.ts.map +1 -0
  124. package/dist/config/loader.js +65 -0
  125. package/dist/config/loader.js.map +1 -0
  126. package/dist/config/schema.d.ts +78 -0
  127. package/dist/config/schema.d.ts.map +1 -0
  128. package/dist/config/schema.js +44 -0
  129. package/dist/config/schema.js.map +1 -0
  130. package/dist/core/constraints.d.ts +18 -0
  131. package/dist/core/constraints.d.ts.map +1 -0
  132. package/dist/core/constraints.js +75 -0
  133. package/dist/core/constraints.js.map +1 -0
  134. package/dist/core/loop.d.ts +54 -0
  135. package/dist/core/loop.d.ts.map +1 -0
  136. package/dist/core/loop.js +462 -0
  137. package/dist/core/loop.js.map +1 -0
  138. package/dist/core/metrics.d.ts +13 -0
  139. package/dist/core/metrics.d.ts.map +1 -0
  140. package/dist/core/metrics.js +73 -0
  141. package/dist/core/metrics.js.map +1 -0
  142. package/dist/core/types.d.ts +175 -0
  143. package/dist/core/types.d.ts.map +1 -0
  144. package/dist/core/types.js +5 -0
  145. package/dist/core/types.js.map +1 -0
  146. package/dist/index.d.ts +35 -0
  147. package/dist/index.d.ts.map +1 -0
  148. package/dist/index.js +49 -0
  149. package/dist/index.js.map +1 -0
  150. package/dist/llm/prompts/analyze-results.d.ts +3 -0
  151. package/dist/llm/prompts/analyze-results.d.ts.map +1 -0
  152. package/dist/llm/prompts/analyze-results.js +52 -0
  153. package/dist/llm/prompts/analyze-results.js.map +1 -0
  154. package/dist/llm/prompts/generate-companion.d.ts +3 -0
  155. package/dist/llm/prompts/generate-companion.d.ts.map +1 -0
  156. package/dist/llm/prompts/generate-companion.js +42 -0
  157. package/dist/llm/prompts/generate-companion.js.map +1 -0
  158. package/dist/llm/prompts/generate-tests.d.ts +3 -0
  159. package/dist/llm/prompts/generate-tests.d.ts.map +1 -0
  160. package/dist/llm/prompts/generate-tests.js +46 -0
  161. package/dist/llm/prompts/generate-tests.js.map +1 -0
  162. package/dist/llm/prompts/generate-topic.d.ts +4 -0
  163. package/dist/llm/prompts/generate-topic.d.ts.map +1 -0
  164. package/dist/llm/prompts/generate-topic.js +41 -0
  165. package/dist/llm/prompts/generate-topic.js.map +1 -0
  166. package/dist/llm/prompts/improve-topic.d.ts +3 -0
  167. package/dist/llm/prompts/improve-topic.d.ts.map +1 -0
  168. package/dist/llm/prompts/improve-topic.js +77 -0
  169. package/dist/llm/prompts/improve-topic.js.map +1 -0
  170. package/dist/llm/prompts/simplify-topic.d.ts +3 -0
  171. package/dist/llm/prompts/simplify-topic.d.ts.map +1 -0
  172. package/dist/llm/prompts/simplify-topic.js +50 -0
  173. package/dist/llm/prompts/simplify-topic.js.map +1 -0
  174. package/dist/llm/provider.d.ts +21 -0
  175. package/dist/llm/provider.d.ts.map +1 -0
  176. package/dist/llm/provider.js +76 -0
  177. package/dist/llm/provider.js.map +1 -0
  178. package/dist/llm/schemas.d.ts +97 -0
  179. package/dist/llm/schemas.d.ts.map +1 -0
  180. package/dist/llm/schemas.js +24 -0
  181. package/dist/llm/schemas.js.map +1 -0
  182. package/dist/llm/service.d.ts +30 -0
  183. package/dist/llm/service.d.ts.map +1 -0
  184. package/dist/llm/service.js +273 -0
  185. package/dist/llm/service.js.map +1 -0
  186. package/dist/memory/diff.d.ts +4 -0
  187. package/dist/memory/diff.d.ts.map +1 -0
  188. package/dist/memory/diff.js +24 -0
  189. package/dist/memory/diff.js.map +1 -0
  190. package/dist/memory/extractor.d.ts +15 -0
  191. package/dist/memory/extractor.d.ts.map +1 -0
  192. package/dist/memory/extractor.js +133 -0
  193. package/dist/memory/extractor.js.map +1 -0
  194. package/dist/memory/injector.d.ts +22 -0
  195. package/dist/memory/injector.d.ts.map +1 -0
  196. package/dist/memory/injector.js +90 -0
  197. package/dist/memory/injector.js.map +1 -0
  198. package/dist/memory/prompts/extract-learnings.d.ts +3 -0
  199. package/dist/memory/prompts/extract-learnings.d.ts.map +1 -0
  200. package/dist/memory/prompts/extract-learnings.js +40 -0
  201. package/dist/memory/prompts/extract-learnings.js.map +1 -0
  202. package/dist/memory/schemas.d.ts +63 -0
  203. package/dist/memory/schemas.d.ts.map +1 -0
  204. package/dist/memory/schemas.js +13 -0
  205. package/dist/memory/schemas.js.map +1 -0
  206. package/dist/memory/store.d.ts +28 -0
  207. package/dist/memory/store.d.ts.map +1 -0
  208. package/dist/memory/store.js +103 -0
  209. package/dist/memory/store.js.map +1 -0
  210. package/dist/memory/types.d.ts +55 -0
  211. package/dist/memory/types.d.ts.map +1 -0
  212. package/dist/memory/types.js +6 -0
  213. package/dist/memory/types.js.map +1 -0
  214. package/dist/persistence/store.d.ts +21 -0
  215. package/dist/persistence/store.d.ts.map +1 -0
  216. package/dist/persistence/store.js +77 -0
  217. package/dist/persistence/store.js.map +1 -0
  218. package/dist/persistence/types.d.ts +23 -0
  219. package/dist/persistence/types.d.ts.map +1 -0
  220. package/dist/persistence/types.js +2 -0
  221. package/dist/persistence/types.js.map +1 -0
  222. package/dist/report/html.d.ts +6 -0
  223. package/dist/report/html.d.ts.map +1 -0
  224. package/dist/report/html.js +200 -0
  225. package/dist/report/html.js.map +1 -0
  226. package/dist/report/json.d.ts +11 -0
  227. package/dist/report/json.d.ts.map +1 -0
  228. package/dist/report/json.js +74 -0
  229. package/dist/report/json.js.map +1 -0
  230. package/dist/report/types.d.ts +58 -0
  231. package/dist/report/types.d.ts.map +1 -0
  232. package/dist/report/types.js +5 -0
  233. package/dist/report/types.js.map +1 -0
  234. package/package.json +67 -0
@@ -0,0 +1,219 @@
1
+ import { RedTeamClient } from '@cdot65/prisma-airs-sdk';
2
+ const TERMINAL_STATUSES = new Set(['COMPLETED', 'PARTIALLY_COMPLETE', 'FAILED', 'ABORTED']);
3
+ /** Normalize an SDK job response into a RedTeamJob. */
4
+ function normalizeJob(raw) {
5
+ const target = raw.target;
6
+ return {
7
+ uuid: raw.uuid,
8
+ name: raw.name,
9
+ status: raw.status,
10
+ jobType: raw.job_type,
11
+ targetId: raw.target_id,
12
+ targetName: target?.name,
13
+ score: raw.score,
14
+ asr: raw.asr,
15
+ total: raw.total,
16
+ completed: raw.completed,
17
+ createdAt: raw.created_at,
18
+ };
19
+ }
20
+ /** Normalize an SDK target response into a RedTeamTargetDetail. */
21
+ function normalizeTargetDetail(raw) {
22
+ return {
23
+ uuid: raw.uuid,
24
+ name: raw.name,
25
+ status: raw.status,
26
+ targetType: raw.target_type,
27
+ active: raw.active,
28
+ connectionParams: raw.connection_params,
29
+ background: raw.background,
30
+ additionalContext: raw.additional_context,
31
+ metadata: raw.metadata,
32
+ };
33
+ }
34
+ /**
35
+ * Wraps the SDK's RedTeamClient to implement RedTeamService.
36
+ * Provides scan creation, status polling, report retrieval, and target/category listing.
37
+ */
38
+ export class SdkRedTeamService {
39
+ client;
40
+ constructor(opts) {
41
+ this.client = new RedTeamClient(opts);
42
+ }
43
+ async listTargets() {
44
+ const response = await this.client.targets.list();
45
+ return response.data.map((t) => ({
46
+ uuid: t.uuid,
47
+ name: t.name,
48
+ status: t.status,
49
+ targetType: t.target_type,
50
+ active: t.active,
51
+ }));
52
+ }
53
+ async getTarget(uuid) {
54
+ const response = await this.client.targets.get(uuid);
55
+ return normalizeTargetDetail(response);
56
+ }
57
+ async createTarget(request, opts) {
58
+ const response = await this.client.targets.create(request, opts);
59
+ return normalizeTargetDetail(response);
60
+ }
61
+ async updateTarget(uuid, request, opts) {
62
+ const response = await this.client.targets.update(uuid, request, opts);
63
+ return normalizeTargetDetail(response);
64
+ }
65
+ async deleteTarget(uuid) {
66
+ await this.client.targets.delete(uuid);
67
+ }
68
+ async probeTarget(request) {
69
+ const response = await this.client.targets.probe(request);
70
+ return response;
71
+ }
72
+ async getTargetProfile(uuid) {
73
+ const response = await this.client.targets.getProfile(uuid);
74
+ return response;
75
+ }
76
+ async updateTargetProfile(uuid, request) {
77
+ const response = await this.client.targets.updateProfile(uuid, request);
78
+ return response;
79
+ }
80
+ async createScan(request) {
81
+ let jobMetadata = {};
82
+ if (request.jobType === 'STATIC' && request.categories) {
83
+ jobMetadata = { categories: request.categories };
84
+ }
85
+ else if (request.jobType === 'CUSTOM' && request.customPromptSets) {
86
+ jobMetadata = {
87
+ custom_prompt_sets: request.customPromptSets,
88
+ };
89
+ }
90
+ const response = await this.client.scans.create({
91
+ name: request.name,
92
+ target: { uuid: request.targetUuid },
93
+ job_type: request.jobType,
94
+ job_metadata: jobMetadata,
95
+ });
96
+ return normalizeJob(response);
97
+ }
98
+ async getScan(jobId) {
99
+ const response = await this.client.scans.get(jobId);
100
+ return normalizeJob(response);
101
+ }
102
+ async listScans(opts) {
103
+ const sdkOpts = {};
104
+ if (opts?.status)
105
+ sdkOpts.status = opts.status;
106
+ if (opts?.jobType)
107
+ sdkOpts.job_type = opts.jobType;
108
+ if (opts?.targetId)
109
+ sdkOpts.target_id = opts.targetId;
110
+ if (opts?.limit)
111
+ sdkOpts.limit = opts.limit;
112
+ const response = await this.client.scans.list(sdkOpts);
113
+ return response.data.map(normalizeJob);
114
+ }
115
+ async abortScan(jobId) {
116
+ await this.client.scans.abort(jobId);
117
+ }
118
+ async getStaticReport(jobId) {
119
+ const raw = (await this.client.reports.getStaticReport(jobId));
120
+ const severityReport = raw.severity_report;
121
+ const stats = (severityReport?.stats ?? []);
122
+ const securityReport = raw.security_report;
123
+ const subCategories = (securityReport?.sub_categories ?? []);
124
+ return {
125
+ score: raw.score,
126
+ asr: raw.asr,
127
+ severityBreakdown: stats.map((s) => ({
128
+ severity: s.severity,
129
+ successful: (s.successful ?? 0),
130
+ failed: (s.failed ?? 0),
131
+ })),
132
+ reportSummary: raw.report_summary,
133
+ categories: subCategories.map((sc) => {
134
+ const successful = (sc.successful ?? 0);
135
+ const failed = (sc.failed ?? 0);
136
+ const total = (sc.total ?? successful + failed);
137
+ return {
138
+ id: sc.id,
139
+ displayName: sc.display_name,
140
+ asr: total > 0 ? (successful / total) * 100 : 0,
141
+ successful,
142
+ failed,
143
+ total,
144
+ };
145
+ }),
146
+ };
147
+ }
148
+ async getCustomReport(jobId) {
149
+ const raw = (await this.client.customAttackReports.getReport(jobId));
150
+ const reports = (raw.custom_attack_reports ?? []);
151
+ return {
152
+ totalPrompts: raw.total_prompts,
153
+ totalAttacks: raw.total_attacks,
154
+ totalThreats: raw.total_threats,
155
+ failedAttacks: raw.failed_attacks,
156
+ score: raw.score,
157
+ asr: raw.asr,
158
+ promptSets: reports.map((r) => ({
159
+ promptSetId: r.prompt_set_id,
160
+ promptSetName: r.prompt_set_name,
161
+ totalPrompts: r.total_prompts,
162
+ totalAttacks: r.total_attacks,
163
+ totalThreats: r.total_threats,
164
+ threatRate: r.threat_rate,
165
+ })),
166
+ };
167
+ }
168
+ async listAttacks(jobId, opts) {
169
+ const response = await this.client.reports.listAttacks(jobId, opts);
170
+ return response.data.map((a) => ({
171
+ id: a.uuid,
172
+ name: a.attack_name,
173
+ severity: a.severity,
174
+ category: a.category,
175
+ subCategory: a.sub_category,
176
+ successful: a.successful,
177
+ }));
178
+ }
179
+ async listCustomAttacks(jobId, opts) {
180
+ const response = await this.client.customAttackReports.listCustomAttacks(jobId, opts);
181
+ return response.data.map((a) => ({
182
+ promptId: a.prompt_id,
183
+ promptText: a.prompt_text,
184
+ goal: a.goal,
185
+ threat: (a.threat ?? false),
186
+ asr: a.asr,
187
+ promptSetName: a.prompt_set_name,
188
+ }));
189
+ }
190
+ async getCategories() {
191
+ const response = (await this.client.scans.getCategories());
192
+ return response.map((c) => ({
193
+ id: c.id,
194
+ displayName: c.display_name,
195
+ description: c.description,
196
+ subCategories: (c.sub_categories ?? []).map((sc) => ({
197
+ id: sc.id,
198
+ displayName: sc.display_name,
199
+ description: sc.description,
200
+ })),
201
+ }));
202
+ }
203
+ async waitForCompletion(jobId, onProgress, intervalMs = 5000) {
204
+ const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
205
+ // eslint-disable-next-line no-constant-condition
206
+ while (true) {
207
+ const job = await this.getScan(jobId);
208
+ onProgress?.(job);
209
+ if (job.status === 'FAILED') {
210
+ throw new Error(`Scan ${jobId} failed`);
211
+ }
212
+ if (TERMINAL_STATUSES.has(job.status)) {
213
+ return job;
214
+ }
215
+ await delay(intervalMs);
216
+ }
217
+ }
218
+ }
219
+ //# sourceMappingURL=redteam.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redteam.js","sourceRoot":"","sources":["../../src/airs/redteam.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { RuntimeScanResult, RuntimeService } from './types.js';
2
+ export interface PollRetryOptions {
3
+ /** Max retries per rate-limit error before giving up. Default: 5. */
4
+ maxRetries?: number;
5
+ /** Base delay in ms for exponential backoff. Default: 10000. */
6
+ baseDelayMs?: number;
7
+ /** Called on each retry with (attempt, delayMs). */
8
+ onRetry?: (attempt: number, delayMs: number) => void;
9
+ }
10
+ export declare class SdkRuntimeService implements RuntimeService {
11
+ private scanner;
12
+ constructor(apiKey: string);
13
+ scanPrompt(profileName: string, prompt: string, response?: string): Promise<RuntimeScanResult>;
14
+ submitBulkScan(profileName: string, prompts: string[], sessionId?: string): Promise<string[]>;
15
+ /**
16
+ * Poll async scan results until all complete or fail.
17
+ *
18
+ * Note: The async query API (`queryByScanIds`) does not return `prompt`,
19
+ * `response`, `triggered`, or `detections` fields. These are set to
20
+ * defaults (`''`, `undefined`, `false`, `{}`) in the returned results.
21
+ * Use `scanPrompt()` (sync API) when these fields are needed.
22
+ */
23
+ pollResults(scanIds: string[], intervalMs?: number, retryOpts?: PollRetryOptions): Promise<RuntimeScanResult[]>;
24
+ private processQueryResults;
25
+ static formatResultsCsv(results: RuntimeScanResult[]): string;
26
+ }
27
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/airs/runtime.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAOpE,MAAM,WAAW,gBAAgB;IAC/B,qEAAqE;IACrE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gEAAgE;IAChE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oDAAoD;IACpD,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACtD;AAUD,qBAAa,iBAAkB,YAAW,cAAc;IACtD,OAAO,CAAC,OAAO,CAA+B;gBAElC,MAAM,EAAE,MAAM;IAKpB,UAAU,CACd,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,iBAAiB,CAAC;IAgCvB,cAAc,CAClB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EAAE,EACjB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,EAAE,CAAC;IAqBpB;;;;;;;OAOG;IACG,WAAW,CACf,OAAO,EAAE,MAAM,EAAE,EACjB,UAAU,SAA2B,EACrC,SAAS,CAAC,EAAE,gBAAgB,GAC3B,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAqD/B,OAAO,CAAC,mBAAmB;IAsC3B,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,EAAE,GAAG,MAAM;CAQ9D"}
@@ -0,0 +1,158 @@
1
+ import { Content, init, Scanner } from '@cdot65/prisma-airs-sdk';
2
+ const BATCH_SIZE = 5;
3
+ const DEFAULT_POLL_INTERVAL_MS = 5000;
4
+ const DEFAULT_MAX_RETRIES = 5;
5
+ const DEFAULT_BASE_DELAY_MS = 10_000;
6
+ function isRateLimitError(err) {
7
+ if (err instanceof Error) {
8
+ const msg = err.message.toLowerCase();
9
+ return msg.includes('rate limit') || msg.includes('rate_limit') || msg.includes('429');
10
+ }
11
+ return false;
12
+ }
13
+ export class SdkRuntimeService {
14
+ scanner;
15
+ constructor(apiKey) {
16
+ init({ apiKey });
17
+ this.scanner = new Scanner();
18
+ }
19
+ async scanPrompt(profileName, prompt, response) {
20
+ const contentOpts = { prompt };
21
+ if (response)
22
+ contentOpts.response = response;
23
+ const content = new Content(contentOpts);
24
+ const res = await this.scanner.syncScan({ profile_name: profileName }, content, undefined);
25
+ const detected = res.prompt_detected ?? {};
26
+ // Runtime scanning aggregates all 6 detection types — intentionally broader than
27
+ // the guardrail loop's topic_violation-only signal. Runtime is a general-purpose
28
+ // firewall check, not topic-specific evaluation.
29
+ const triggered = !!(detected.topic_violation ||
30
+ detected.injection ||
31
+ detected.toxic_content ||
32
+ detected.dlp ||
33
+ detected.url_cats ||
34
+ detected.malicious_code);
35
+ return {
36
+ prompt,
37
+ response,
38
+ scanId: res.scan_id ?? '',
39
+ reportId: res.report_id ?? '',
40
+ action: res.action === 'block' ? 'block' : 'allow',
41
+ category: res.category ?? 'unknown',
42
+ triggered,
43
+ detections: detected,
44
+ };
45
+ }
46
+ async submitBulkScan(profileName, prompts, sessionId) {
47
+ const scanIds = [];
48
+ for (let i = 0; i < prompts.length; i += BATCH_SIZE) {
49
+ const batch = prompts.slice(i, i + BATCH_SIZE);
50
+ const scanObjects = batch.map((prompt, idx) => ({
51
+ req_id: i + idx,
52
+ scan_req: {
53
+ ai_profile: { profile_name: profileName },
54
+ contents: [{ prompt }],
55
+ ...(sessionId ? { session_id: sessionId } : {}),
56
+ },
57
+ }));
58
+ const res = await this.scanner.asyncScan(scanObjects);
59
+ scanIds.push(res.scan_id);
60
+ }
61
+ return scanIds;
62
+ }
63
+ /**
64
+ * Poll async scan results until all complete or fail.
65
+ *
66
+ * Note: The async query API (`queryByScanIds`) does not return `prompt`,
67
+ * `response`, `triggered`, or `detections` fields. These are set to
68
+ * defaults (`''`, `undefined`, `false`, `{}`) in the returned results.
69
+ * Use `scanPrompt()` (sync API) when these fields are needed.
70
+ */
71
+ async pollResults(scanIds, intervalMs = DEFAULT_POLL_INTERVAL_MS, retryOpts) {
72
+ const maxRetries = retryOpts?.maxRetries ?? DEFAULT_MAX_RETRIES;
73
+ const baseDelay = retryOpts?.baseDelayMs ?? DEFAULT_BASE_DELAY_MS;
74
+ const completed = new Map();
75
+ const pending = new Set(scanIds);
76
+ let retryLevel = 0;
77
+ while (pending.size > 0) {
78
+ // Query all pending IDs in batches of 5 per sweep
79
+ const pendingIds = [...pending];
80
+ let sweepCompleted = true;
81
+ for (let b = 0; b < pendingIds.length; b += 5) {
82
+ const batch = pendingIds.slice(b, b + 5);
83
+ let results;
84
+ try {
85
+ results = await this.scanner.queryByScanIds(batch);
86
+ }
87
+ catch (err) {
88
+ if (isRateLimitError(err) && retryLevel < maxRetries) {
89
+ retryLevel++;
90
+ const delayMs = baseDelay * 2 ** (retryLevel - 1);
91
+ retryOpts?.onRetry?.(retryLevel, delayMs);
92
+ await new Promise((resolve) => setTimeout(resolve, delayMs));
93
+ sweepCompleted = false;
94
+ break; // restart sweep from the beginning
95
+ }
96
+ throw err;
97
+ }
98
+ this.processQueryResults(results, completed, pending);
99
+ // Small inter-batch delay to avoid hammering the API
100
+ if (b + 5 < pendingIds.length) {
101
+ const batchDelay = retryLevel > 0 ? baseDelay : Math.min(baseDelay, 1000);
102
+ await new Promise((resolve) => setTimeout(resolve, batchDelay));
103
+ }
104
+ }
105
+ // Only decay retry level after a full sweep with no rate limit errors
106
+ if (sweepCompleted && retryLevel > 0) {
107
+ retryLevel = Math.max(0, retryLevel - 1);
108
+ }
109
+ if (pending.size > 0) {
110
+ const sweepDelay = retryLevel > 0 ? baseDelay * 2 ** retryLevel : intervalMs;
111
+ await new Promise((resolve) => setTimeout(resolve, sweepDelay));
112
+ }
113
+ }
114
+ return scanIds.map((id) => completed.get(id));
115
+ }
116
+ processQueryResults(results, completed, pending) {
117
+ for (const r of results) {
118
+ const id = r.scan_id ?? '';
119
+ const status = r.status ?? '';
120
+ if (status === 'COMPLETED' && r.result) {
121
+ const result = r.result;
122
+ completed.set(id, {
123
+ prompt: '', // not available from async API
124
+ response: undefined, // not available from async API
125
+ scanId: result.scan_id ?? id,
126
+ reportId: result.report_id ?? '',
127
+ action: result.action === 'block' ? 'block' : 'allow',
128
+ category: result.category ?? 'unknown',
129
+ triggered: false, // not available from async API — always false
130
+ detections: {}, // not available from async API
131
+ });
132
+ pending.delete(id);
133
+ }
134
+ else if (status === 'FAILED') {
135
+ completed.set(id, {
136
+ prompt: '', // not available from async API
137
+ response: undefined, // not available from async API
138
+ scanId: id,
139
+ reportId: '',
140
+ action: 'allow', // safe default for failed scans
141
+ category: 'error',
142
+ triggered: false, // not available from async API — always false
143
+ detections: {}, // not available from async API
144
+ });
145
+ pending.delete(id);
146
+ }
147
+ }
148
+ }
149
+ static formatResultsCsv(results) {
150
+ const header = 'prompt,action,category,triggered,scan_id,report_id';
151
+ const rows = results.map((r) => {
152
+ const escaped = r.prompt.replace(/"/g, '""');
153
+ return `"${escaped}","${r.action}","${r.category}","${r.triggered}","${r.scanId}","${r.reportId}"`;
154
+ });
155
+ return [header, ...rows].join('\n');
156
+ }
157
+ }
158
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/airs/runtime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { ScanResult, ScanService } from './types.js';
2
+ /** Scans prompts against AIRS security profiles via the Prisma AIRS SDK. */
3
+ export declare class AirsScanService implements ScanService {
4
+ private scanner;
5
+ constructor(apiKey: string);
6
+ /** Scan a single prompt synchronously and return the normalized result. */
7
+ scan(profileName: string, prompt: string, sessionId?: string): Promise<ScanResult>;
8
+ /** Scan multiple prompts concurrently (default 5) and return results in order. */
9
+ scanBatch(profileName: string, prompts: string[], concurrency?: number, sessionId?: string): Promise<ScanResult[]>;
10
+ }
11
+ /**
12
+ * Debug wrapper that delegates to an inner ScanService and appends
13
+ * each raw response + prompt to a JSONL file for offline inspection.
14
+ */
15
+ export declare class DebugScanService implements ScanService {
16
+ private inner;
17
+ private filePath;
18
+ constructor(inner: ScanService, filePath: string);
19
+ scan(profileName: string, prompt: string, sessionId?: string): Promise<ScanResult>;
20
+ scanBatch(profileName: string, prompts: string[], concurrency?: number, sessionId?: string): Promise<ScanResult[]>;
21
+ }
22
+ //# sourceMappingURL=scanner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../src/airs/scanner.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE1D,4EAA4E;AAC5E,qBAAa,eAAgB,YAAW,WAAW;IACjD,OAAO,CAAC,OAAO,CAA+B;gBAElC,MAAM,EAAE,MAAM;IAK1B,2EAA2E;IACrE,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAuBxF,kFAAkF;IAC5E,SAAS,CACb,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EAAE,EACjB,WAAW,SAAI,EACf,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,UAAU,EAAE,CAAC;CAMzB;AAED;;;GAGG;AACH,qBAAa,gBAAiB,YAAW,WAAW;IAEhD,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,QAAQ;gBADR,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,MAAM;IAGpB,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAalF,SAAS,CACb,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EAAE,EACjB,WAAW,CAAC,EAAE,MAAM,EACpB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,UAAU,EAAE,CAAC;CAMzB"}
@@ -0,0 +1,62 @@
1
+ import * as fs from 'node:fs/promises';
2
+ import { Content, init, Scanner } from '@cdot65/prisma-airs-sdk';
3
+ import pLimit from 'p-limit';
4
+ /** Scans prompts against AIRS security profiles via the Prisma AIRS SDK. */
5
+ export class AirsScanService {
6
+ scanner;
7
+ constructor(apiKey) {
8
+ init({ apiKey });
9
+ this.scanner = new Scanner();
10
+ }
11
+ /** Scan a single prompt synchronously and return the normalized result. */
12
+ async scan(profileName, prompt, sessionId) {
13
+ const content = new Content({ prompt });
14
+ const response = await this.scanner.syncScan({ profile_name: profileName }, content, sessionId ? { sessionId } : undefined);
15
+ const action = response.action === 'block' ? 'block' : 'allow';
16
+ const detected = response.prompt_detected;
17
+ const triggered = detected?.topic_violation === true;
18
+ const category = response.category ?? undefined;
19
+ return {
20
+ scanId: response.scan_id ?? '',
21
+ reportId: response.report_id ?? '',
22
+ action: action,
23
+ triggered,
24
+ category,
25
+ raw: response,
26
+ };
27
+ }
28
+ /** Scan multiple prompts concurrently (default 5) and return results in order. */
29
+ async scanBatch(profileName, prompts, concurrency = 5, sessionId) {
30
+ const limit = pLimit(concurrency);
31
+ return Promise.all(prompts.map((prompt) => limit(() => this.scan(profileName, prompt, sessionId))));
32
+ }
33
+ }
34
+ /**
35
+ * Debug wrapper that delegates to an inner ScanService and appends
36
+ * each raw response + prompt to a JSONL file for offline inspection.
37
+ */
38
+ export class DebugScanService {
39
+ inner;
40
+ filePath;
41
+ constructor(inner, filePath) {
42
+ this.inner = inner;
43
+ this.filePath = filePath;
44
+ }
45
+ async scan(profileName, prompt, sessionId) {
46
+ const result = await this.inner.scan(profileName, prompt, sessionId);
47
+ const entry = JSON.stringify({
48
+ prompt,
49
+ profileName,
50
+ result,
51
+ raw: result.raw,
52
+ timestamp: Date.now(),
53
+ });
54
+ await fs.appendFile(this.filePath, `${entry}\n`);
55
+ return result;
56
+ }
57
+ async scanBatch(profileName, prompts, concurrency, sessionId) {
58
+ const limit = pLimit(concurrency ?? 5);
59
+ return Promise.all(prompts.map((prompt) => limit(() => this.scan(profileName, prompt, sessionId))));
60
+ }
61
+ }
62
+ //# sourceMappingURL=scanner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.js","sourceRoot":"","sources":["../../src/airs/scanner.ts"],"names":[],"mappings":"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"}