quantum-ai-sdk 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chat.js +21 -0
- package/dist/index.d.ts +3 -0
- package/dist/missions.d.ts +280 -0
- package/dist/missions.js +278 -0
- package/dist/security.d.ts +158 -0
- package/dist/security.js +135 -0
- package/dist/types.d.ts +33 -1
- package/dist/vision.d.ts +130 -0
- package/dist/vision.js +124 -0
- package/package.json +1 -1
package/dist/chat.js
CHANGED
|
@@ -92,12 +92,33 @@ export async function* chatStream(client, req, signal) {
|
|
|
92
92
|
event.delta = raw.delta;
|
|
93
93
|
break;
|
|
94
94
|
case "tool_use":
|
|
95
|
+
// Legacy atomic event — kept for back-compat with backends
|
|
96
|
+
// that haven't yet shipped the triplet (v0.6+).
|
|
95
97
|
event.tool_use = {
|
|
96
98
|
id: String(raw.id ?? ""),
|
|
97
99
|
name: String(raw.name ?? ""),
|
|
98
100
|
input: raw.input ?? {},
|
|
99
101
|
};
|
|
100
102
|
break;
|
|
103
|
+
case "tool_use_start":
|
|
104
|
+
event.tool_use_start = {
|
|
105
|
+
id: String(raw.id ?? ""),
|
|
106
|
+
name: String(raw.name ?? ""),
|
|
107
|
+
};
|
|
108
|
+
break;
|
|
109
|
+
case "tool_use_input_delta":
|
|
110
|
+
event.tool_use_input_delta = {
|
|
111
|
+
id: String(raw.id ?? ""),
|
|
112
|
+
partial_json: String(raw.partial_json ?? ""),
|
|
113
|
+
};
|
|
114
|
+
break;
|
|
115
|
+
case "tool_use_complete":
|
|
116
|
+
event.tool_use_complete = {
|
|
117
|
+
id: String(raw.id ?? ""),
|
|
118
|
+
name: String(raw.name ?? ""),
|
|
119
|
+
input: raw.input ?? {},
|
|
120
|
+
};
|
|
121
|
+
break;
|
|
101
122
|
case "usage":
|
|
102
123
|
event.usage = {
|
|
103
124
|
input_tokens: raw.input_tokens ?? 0,
|
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,9 @@ export type { RealtimeConfig, RealtimeEvent, RealtimeSession } from "./realtime.
|
|
|
6
6
|
export { contact } from "./contact.js";
|
|
7
7
|
export type { BillingRequest, BillingEntry, BillingResponse } from "./compute-billing.js";
|
|
8
8
|
export type { ClientOptions, ResponseMeta, ChatRequest, ChatMessage, ChatTool, ContentBlock, ChatUsage, ChatResponse, StreamEvent, StreamDelta, StreamToolUse, SessionChatRequest, SessionChatResponse, SessionToolResult, ContextConfig, ContextMetadata, AgentRequest, AgentWorkerConfig, AgentEvent, MissionRequest, MissionWorkerConfig, MissionEvent, ImageRequest, ImageResponse, GeneratedImage, ImageEditRequest, ImageEditResponse, TTSRequest, TTSResponse, STTRequest, STTResponse, MusicRequest, MusicClip, MusicResponse, SoundEffectRequest, SoundEffectResponse, DialogueRequest, DialogueResponse, DialogueVoice, SpeechToSpeechRequest, SpeechToSpeechResponse, IsolateVoiceRequest, IsolateVoiceResponse, RemixVoiceRequest, RemixVoiceResponse, DubRequest, DubResponse, AlignRequest, AlignResponse, AlignedWord, VoiceDesignRequest, VoiceDesignResponse, VoicePreview, StarfishTTSRequest, StarfishTTSResponse, VideoRequest, VideoResponse, GeneratedVideo, VideoStudioRequest, VideoTranslateRequest, PhotoAvatarRequest, DigitalTwinRequest, AsyncJobResponse, AvatarsResponse, HeyGenAvatar, HeyGenTemplatesResponse, HeyGenTemplate, HeyGenVoicesResponse, HeyGenVoice, EmbedRequest, EmbedResponse, DocumentRequest, DocumentResponse, ChunkDocumentRequest, ChunkDocumentResponse, DocumentChunk, ProcessDocumentRequest, ProcessDocumentResponse, RAGSearchRequest, RAGSearchResponse, RAGResult, RAGCorpus, SurrealRAGSearchRequest, SurrealRAGSearchResponse, SurrealRAGResult, SurrealRAGProvidersResponse, SurrealRAGProviderInfo, ModelInfo, PricingInfo, BalanceResponse, UsageEntry, UsageResponse, UsageQuery, UsageSummaryMonth, UsageSummaryResponse, PricingEntry, AccountPricingResponse, JobCreateRequest, JobCreateResponse, JobStatusResponse, JobListResponse, JobStreamEvent, JobListItem, CreateKeyRequest, CreateKeyResponse, KeyDetails, ListKeysResponse, ComputeTemplate, TemplatesResponse, ProvisionRequest, ProvisionResponse, ComputeInstanceInfo, InstancesResponse, InstanceDetailInfo, InstanceResponse, SSHKeyRequest, DeleteResponse, VoiceInfo, VoicesResponse, CloneVoiceRequest, CloneVoiceResponse, ContactRequest, BatchJobInput, BatchSubmitRequest, BatchSubmitResponse, BatchJsonlResponse, BatchJobInfo, BatchJobsResponse, CreditPack, CreditPacksResponse, CreditPurchaseRequest, CreditPurchaseResponse, CreditBalanceResponse, CreditTier, CreditTiersResponse, DevProgramApplyRequest, DevProgramApplyResponse, AuthUser, AuthResponse, AuthAppleRequest, WebSearchRequest, WebSearchResponse, WebSearchResult, NewsResult, VideoSearchResult, LLMContextRequest, LLMContextResponse, ContentChunk, ContextSource, SearchAnswerRequest, SearchAnswerResponse, SearchAnswerChoice, SearchCitation, StatusResponse, Citation, CollectionsListResponse, CollectionDocumentsResponse, CollectionSearchResponse, CreateCollectionRequest, DeleteCollectionResponse, ModelsResponse, RagCorporaResponse, Infobox, Discussion, TextToSpeechRequest, TextToSpeechResponse, SpeechToTextRequest, SpeechToTextResponse, ContactResponse, ContextChunk, ContextOptions, HeyGenAvatarsResponse, JobAcceptedResponse, JobListEntry, PostProcess, RealtimeSessionResponse, SearchMessage, SearchOptions, ScrapeTarget, ScrapeRequest, ScrapeResponse, ScreenshotURL, ScreenshotRequest, ScreenshotResult, ScreenshotResponse, } from "./types.js";
|
|
9
|
+
export type { VisionRequest, VisionContext, VisionResponse, DetectedObject, QualityAssessment, RelevanceCheck, OcrResult, TextOverlay, } from "./vision.js";
|
|
10
|
+
export type { MissionCreateRequest, MissionChatRequest, MissionPlanUpdate, MissionConfirmStructure, MissionApproveRequest, MissionImportRequest, MissionCreateResponse, MissionDetail, MissionTask, MissionListResponse, MissionChatResponse, MissionChatUsage, MissionCheckpoint, MissionCheckpointsResponse, MissionStatusResponse, } from "./missions.js";
|
|
11
|
+
export type { SecurityScanUrlRequest, SecurityScanHtmlRequest, SecurityReportRequest, SecurityScanResponse, SecurityAssessment, SecurityFinding, SecurityCheckResponse, SecurityBlocklistResponse, SecurityBlocklistEntry, SecurityReportResponse, } from "./security.js";
|
|
9
12
|
export { DEFAULT_BASE_URL, TICKS_PER_USD } from "./types.js";
|
|
10
13
|
import type { ChatMessage } from "./types.js";
|
|
11
14
|
/** Create a user message. */
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
import type { QuantumClient } from "./client.js";
|
|
2
|
+
/** Worker configuration within a mission. */
|
|
3
|
+
export interface MissionWorkerConfig {
|
|
4
|
+
/** Model to use for this worker. */
|
|
5
|
+
model: string;
|
|
6
|
+
/** Cost tier: "cheap", "mid", "expensive". */
|
|
7
|
+
tier: string;
|
|
8
|
+
/** Worker description / capabilities. */
|
|
9
|
+
description?: string;
|
|
10
|
+
}
|
|
11
|
+
/** Request body for creating a mission. */
|
|
12
|
+
export interface MissionCreateRequest {
|
|
13
|
+
/** High-level task description. */
|
|
14
|
+
goal: string;
|
|
15
|
+
/** Strategy: "wave" (default), "dag", "mapreduce", "refinement", "branch". */
|
|
16
|
+
strategy?: string;
|
|
17
|
+
/** Conductor model (default: claude-sonnet-4-6). */
|
|
18
|
+
conductorModel?: string;
|
|
19
|
+
/** Worker team configuration (keyed by worker name). */
|
|
20
|
+
workers?: Record<string, MissionWorkerConfig>;
|
|
21
|
+
/** Maximum orchestration steps (default: 25). */
|
|
22
|
+
maxSteps?: number;
|
|
23
|
+
/** Custom system prompt for the conductor. */
|
|
24
|
+
systemPrompt?: string;
|
|
25
|
+
/** Existing session ID for context continuity. */
|
|
26
|
+
sessionId?: string;
|
|
27
|
+
}
|
|
28
|
+
/** Request body for chatting with a mission's architect. */
|
|
29
|
+
export interface MissionChatRequest {
|
|
30
|
+
/** Message to send to the architect. */
|
|
31
|
+
message: string;
|
|
32
|
+
/** Enable streaming (not yet supported). */
|
|
33
|
+
stream?: boolean;
|
|
34
|
+
}
|
|
35
|
+
/** Request body for updating a mission plan. */
|
|
36
|
+
export interface MissionPlanUpdate {
|
|
37
|
+
/** Updated task list. */
|
|
38
|
+
tasks?: Record<string, unknown>[];
|
|
39
|
+
/** Updated worker configuration. */
|
|
40
|
+
workers?: Record<string, MissionWorkerConfig>;
|
|
41
|
+
/** Additional system prompt. */
|
|
42
|
+
systemPrompt?: string;
|
|
43
|
+
/** Updated max steps. */
|
|
44
|
+
maxSteps?: number;
|
|
45
|
+
/** Additional context to inject. */
|
|
46
|
+
context?: string;
|
|
47
|
+
}
|
|
48
|
+
/** Request body for confirming/rejecting a mission structure. */
|
|
49
|
+
export interface MissionConfirmStructure {
|
|
50
|
+
/** Whether the structure is approved. */
|
|
51
|
+
confirmed: boolean;
|
|
52
|
+
/** Rejection reason or modification notes. */
|
|
53
|
+
feedback?: string;
|
|
54
|
+
}
|
|
55
|
+
/** Request body for approving a completed mission. */
|
|
56
|
+
export interface MissionApproveRequest {
|
|
57
|
+
/** Git commit SHA associated with the mission output. */
|
|
58
|
+
commitSha?: string;
|
|
59
|
+
/** Approval comment. */
|
|
60
|
+
comment?: string;
|
|
61
|
+
}
|
|
62
|
+
/** Request body for importing a plan as a new mission. */
|
|
63
|
+
export interface MissionImportRequest {
|
|
64
|
+
/** Mission goal. */
|
|
65
|
+
goal: string;
|
|
66
|
+
/** Strategy. */
|
|
67
|
+
strategy?: string;
|
|
68
|
+
/** Conductor model. */
|
|
69
|
+
conductorModel?: string;
|
|
70
|
+
/** Worker configuration. */
|
|
71
|
+
workers?: Record<string, MissionWorkerConfig>;
|
|
72
|
+
/** Pre-defined tasks. */
|
|
73
|
+
tasks: Record<string, unknown>[];
|
|
74
|
+
/** System prompt. */
|
|
75
|
+
systemPrompt?: string;
|
|
76
|
+
/** Maximum steps. */
|
|
77
|
+
maxSteps?: number;
|
|
78
|
+
/** Auto-execute after import. */
|
|
79
|
+
autoExecute?: boolean;
|
|
80
|
+
}
|
|
81
|
+
/** Response from mission creation. */
|
|
82
|
+
export interface MissionCreateResponse {
|
|
83
|
+
/** Mission identifier. */
|
|
84
|
+
missionId: string;
|
|
85
|
+
/** Initial status. */
|
|
86
|
+
status: string;
|
|
87
|
+
/** Session ID for conversation context. */
|
|
88
|
+
sessionId?: string;
|
|
89
|
+
/** Conductor model used. */
|
|
90
|
+
conductorModel?: string;
|
|
91
|
+
/** Strategy used. */
|
|
92
|
+
strategy?: string;
|
|
93
|
+
/** Worker configuration. */
|
|
94
|
+
workers?: Record<string, MissionWorkerConfig>;
|
|
95
|
+
/** Creation timestamp. */
|
|
96
|
+
createdAt?: string;
|
|
97
|
+
/** Request identifier. */
|
|
98
|
+
requestId?: string;
|
|
99
|
+
}
|
|
100
|
+
/** A task within a mission. */
|
|
101
|
+
export interface MissionTask {
|
|
102
|
+
/** Task identifier. */
|
|
103
|
+
id?: string;
|
|
104
|
+
/** Task name. */
|
|
105
|
+
name?: string;
|
|
106
|
+
/** Task description. */
|
|
107
|
+
description?: string;
|
|
108
|
+
/** Assigned worker name. */
|
|
109
|
+
worker?: string;
|
|
110
|
+
/** Model used. */
|
|
111
|
+
model?: string;
|
|
112
|
+
/** Task status. */
|
|
113
|
+
status?: string;
|
|
114
|
+
/** Task result. */
|
|
115
|
+
result?: string;
|
|
116
|
+
/** Error message if failed. */
|
|
117
|
+
error?: string;
|
|
118
|
+
/** Step number. */
|
|
119
|
+
step: number;
|
|
120
|
+
/** Input tokens used. */
|
|
121
|
+
tokensIn: number;
|
|
122
|
+
/** Output tokens used. */
|
|
123
|
+
tokensOut: number;
|
|
124
|
+
}
|
|
125
|
+
/** Mission detail (from GET /missions/{id}). */
|
|
126
|
+
export interface MissionDetail {
|
|
127
|
+
/** Mission identifier. */
|
|
128
|
+
id?: string;
|
|
129
|
+
/** User who created the mission. */
|
|
130
|
+
userId?: string;
|
|
131
|
+
/** Mission goal. */
|
|
132
|
+
goal?: string;
|
|
133
|
+
/** Strategy. */
|
|
134
|
+
strategy?: string;
|
|
135
|
+
/** Conductor model. */
|
|
136
|
+
conductorModel?: string;
|
|
137
|
+
/** Current status. */
|
|
138
|
+
status?: string;
|
|
139
|
+
/** Creation timestamp. */
|
|
140
|
+
createdAt?: string;
|
|
141
|
+
/** Start timestamp. */
|
|
142
|
+
startedAt?: string;
|
|
143
|
+
/** Completion timestamp. */
|
|
144
|
+
completedAt?: string;
|
|
145
|
+
/** Error message if failed. */
|
|
146
|
+
error?: string;
|
|
147
|
+
/** Total cost in ticks. */
|
|
148
|
+
costTicks: number;
|
|
149
|
+
/** Number of steps executed. */
|
|
150
|
+
totalSteps: number;
|
|
151
|
+
/** Session ID. */
|
|
152
|
+
sessionId?: string;
|
|
153
|
+
/** Final result text. */
|
|
154
|
+
result?: string;
|
|
155
|
+
/** Tasks within the mission. */
|
|
156
|
+
tasks: MissionTask[];
|
|
157
|
+
/** Whether the mission was approved. */
|
|
158
|
+
approved: boolean;
|
|
159
|
+
/** Commit SHA (if approved). */
|
|
160
|
+
commitSha?: string;
|
|
161
|
+
}
|
|
162
|
+
/** Response from listing missions. */
|
|
163
|
+
export interface MissionListResponse {
|
|
164
|
+
/** List of missions. */
|
|
165
|
+
missions: MissionDetail[];
|
|
166
|
+
}
|
|
167
|
+
/** Token usage for a mission chat response. */
|
|
168
|
+
export interface MissionChatUsage {
|
|
169
|
+
inputTokens: number;
|
|
170
|
+
outputTokens: number;
|
|
171
|
+
}
|
|
172
|
+
/** Response from chatting with the architect. */
|
|
173
|
+
export interface MissionChatResponse {
|
|
174
|
+
/** Mission identifier. */
|
|
175
|
+
missionId?: string;
|
|
176
|
+
/** Architect's response content. */
|
|
177
|
+
content?: string;
|
|
178
|
+
/** Model used. */
|
|
179
|
+
model?: string;
|
|
180
|
+
/** Cost in ticks. */
|
|
181
|
+
costTicks: number;
|
|
182
|
+
/** Token usage. */
|
|
183
|
+
usage?: MissionChatUsage;
|
|
184
|
+
}
|
|
185
|
+
/** A git checkpoint within a mission. */
|
|
186
|
+
export interface MissionCheckpoint {
|
|
187
|
+
/** Checkpoint identifier. */
|
|
188
|
+
id?: string;
|
|
189
|
+
/** Commit SHA. */
|
|
190
|
+
commitSha?: string;
|
|
191
|
+
/** Checkpoint message. */
|
|
192
|
+
message?: string;
|
|
193
|
+
/** Creation timestamp. */
|
|
194
|
+
createdAt?: string;
|
|
195
|
+
}
|
|
196
|
+
/** Response from listing checkpoints. */
|
|
197
|
+
export interface MissionCheckpointsResponse {
|
|
198
|
+
missionId?: string;
|
|
199
|
+
checkpoints: MissionCheckpoint[];
|
|
200
|
+
}
|
|
201
|
+
/** Generic status response for mission operations. */
|
|
202
|
+
export interface MissionStatusResponse {
|
|
203
|
+
missionId?: string;
|
|
204
|
+
status?: string;
|
|
205
|
+
confirmed?: boolean;
|
|
206
|
+
approved?: boolean;
|
|
207
|
+
deleted?: boolean;
|
|
208
|
+
updated?: boolean;
|
|
209
|
+
commitSha?: string;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Create and execute a mission asynchronously.
|
|
213
|
+
* @internal
|
|
214
|
+
*/
|
|
215
|
+
export declare function missionCreate(client: QuantumClient, req: MissionCreateRequest): Promise<MissionCreateResponse>;
|
|
216
|
+
/**
|
|
217
|
+
* List missions for the authenticated user.
|
|
218
|
+
* @internal
|
|
219
|
+
*/
|
|
220
|
+
export declare function missionList(client: QuantumClient, status?: string): Promise<MissionListResponse>;
|
|
221
|
+
/**
|
|
222
|
+
* Get mission details including tasks.
|
|
223
|
+
* @internal
|
|
224
|
+
*/
|
|
225
|
+
export declare function missionGet(client: QuantumClient, missionId: string): Promise<MissionDetail>;
|
|
226
|
+
/**
|
|
227
|
+
* Delete a mission.
|
|
228
|
+
* @internal
|
|
229
|
+
*/
|
|
230
|
+
export declare function missionDelete(client: QuantumClient, missionId: string): Promise<MissionStatusResponse>;
|
|
231
|
+
/**
|
|
232
|
+
* Cancel a running mission.
|
|
233
|
+
* @internal
|
|
234
|
+
*/
|
|
235
|
+
export declare function missionCancel(client: QuantumClient, missionId: string): Promise<MissionStatusResponse>;
|
|
236
|
+
/**
|
|
237
|
+
* Pause a running mission.
|
|
238
|
+
* @internal
|
|
239
|
+
*/
|
|
240
|
+
export declare function missionPause(client: QuantumClient, missionId: string): Promise<MissionStatusResponse>;
|
|
241
|
+
/**
|
|
242
|
+
* Resume a paused mission.
|
|
243
|
+
* @internal
|
|
244
|
+
*/
|
|
245
|
+
export declare function missionResume(client: QuantumClient, missionId: string): Promise<MissionStatusResponse>;
|
|
246
|
+
/**
|
|
247
|
+
* Chat with the mission's architect.
|
|
248
|
+
* @internal
|
|
249
|
+
*/
|
|
250
|
+
export declare function missionChat(client: QuantumClient, missionId: string, req: MissionChatRequest): Promise<MissionChatResponse>;
|
|
251
|
+
/**
|
|
252
|
+
* Retry a failed task.
|
|
253
|
+
* @internal
|
|
254
|
+
*/
|
|
255
|
+
export declare function missionRetryTask(client: QuantumClient, missionId: string, taskId: string): Promise<MissionStatusResponse>;
|
|
256
|
+
/**
|
|
257
|
+
* Approve a completed mission.
|
|
258
|
+
* @internal
|
|
259
|
+
*/
|
|
260
|
+
export declare function missionApprove(client: QuantumClient, missionId: string, req: MissionApproveRequest): Promise<MissionStatusResponse>;
|
|
261
|
+
/**
|
|
262
|
+
* Update the mission plan.
|
|
263
|
+
* @internal
|
|
264
|
+
*/
|
|
265
|
+
export declare function missionUpdatePlan(client: QuantumClient, missionId: string, req: MissionPlanUpdate): Promise<MissionStatusResponse>;
|
|
266
|
+
/**
|
|
267
|
+
* Confirm or reject the proposed execution structure.
|
|
268
|
+
* @internal
|
|
269
|
+
*/
|
|
270
|
+
export declare function missionConfirmStructure(client: QuantumClient, missionId: string, req: MissionConfirmStructure): Promise<MissionStatusResponse>;
|
|
271
|
+
/**
|
|
272
|
+
* List git checkpoints for a mission.
|
|
273
|
+
* @internal
|
|
274
|
+
*/
|
|
275
|
+
export declare function missionCheckpoints(client: QuantumClient, missionId: string): Promise<MissionCheckpointsResponse>;
|
|
276
|
+
/**
|
|
277
|
+
* Import an existing plan as a new mission.
|
|
278
|
+
* @internal
|
|
279
|
+
*/
|
|
280
|
+
export declare function missionImport(client: QuantumClient, req: MissionImportRequest): Promise<MissionCreateResponse>;
|
package/dist/missions.js
ADDED
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
// ── Wire format helpers ──────────────────────────────────────────
|
|
2
|
+
/** @internal */
|
|
3
|
+
function createReqToWire(req) {
|
|
4
|
+
const out = { goal: req.goal };
|
|
5
|
+
if (req.strategy !== undefined)
|
|
6
|
+
out.strategy = req.strategy;
|
|
7
|
+
if (req.conductorModel !== undefined)
|
|
8
|
+
out.conductor_model = req.conductorModel;
|
|
9
|
+
if (req.workers !== undefined)
|
|
10
|
+
out.workers = req.workers;
|
|
11
|
+
if (req.maxSteps !== undefined)
|
|
12
|
+
out.max_steps = req.maxSteps;
|
|
13
|
+
if (req.systemPrompt !== undefined)
|
|
14
|
+
out.system_prompt = req.systemPrompt;
|
|
15
|
+
if (req.sessionId !== undefined)
|
|
16
|
+
out.session_id = req.sessionId;
|
|
17
|
+
return out;
|
|
18
|
+
}
|
|
19
|
+
/** @internal */
|
|
20
|
+
function chatReqToWire(req) {
|
|
21
|
+
const out = { message: req.message };
|
|
22
|
+
if (req.stream !== undefined)
|
|
23
|
+
out.stream = req.stream;
|
|
24
|
+
return out;
|
|
25
|
+
}
|
|
26
|
+
/** @internal */
|
|
27
|
+
function planUpdateToWire(req) {
|
|
28
|
+
const out = {};
|
|
29
|
+
if (req.tasks !== undefined)
|
|
30
|
+
out.tasks = req.tasks;
|
|
31
|
+
if (req.workers !== undefined)
|
|
32
|
+
out.workers = req.workers;
|
|
33
|
+
if (req.systemPrompt !== undefined)
|
|
34
|
+
out.system_prompt = req.systemPrompt;
|
|
35
|
+
if (req.maxSteps !== undefined)
|
|
36
|
+
out.max_steps = req.maxSteps;
|
|
37
|
+
if (req.context !== undefined)
|
|
38
|
+
out.context = req.context;
|
|
39
|
+
return out;
|
|
40
|
+
}
|
|
41
|
+
/** @internal */
|
|
42
|
+
function approveReqToWire(req) {
|
|
43
|
+
const out = {};
|
|
44
|
+
if (req.commitSha !== undefined)
|
|
45
|
+
out.commit_sha = req.commitSha;
|
|
46
|
+
if (req.comment !== undefined)
|
|
47
|
+
out.comment = req.comment;
|
|
48
|
+
return out;
|
|
49
|
+
}
|
|
50
|
+
/** @internal */
|
|
51
|
+
function importReqToWire(req) {
|
|
52
|
+
const out = { goal: req.goal, tasks: req.tasks };
|
|
53
|
+
if (req.strategy !== undefined)
|
|
54
|
+
out.strategy = req.strategy;
|
|
55
|
+
if (req.conductorModel !== undefined)
|
|
56
|
+
out.conductor_model = req.conductorModel;
|
|
57
|
+
if (req.workers !== undefined)
|
|
58
|
+
out.workers = req.workers;
|
|
59
|
+
if (req.systemPrompt !== undefined)
|
|
60
|
+
out.system_prompt = req.systemPrompt;
|
|
61
|
+
if (req.maxSteps !== undefined)
|
|
62
|
+
out.max_steps = req.maxSteps;
|
|
63
|
+
if (req.autoExecute !== undefined)
|
|
64
|
+
out.auto_execute = req.autoExecute;
|
|
65
|
+
return out;
|
|
66
|
+
}
|
|
67
|
+
/** @internal */
|
|
68
|
+
function taskFromWire(raw) {
|
|
69
|
+
return {
|
|
70
|
+
id: raw.id,
|
|
71
|
+
name: raw.name,
|
|
72
|
+
description: raw.description,
|
|
73
|
+
worker: raw.worker,
|
|
74
|
+
model: raw.model,
|
|
75
|
+
status: raw.status,
|
|
76
|
+
result: raw.result,
|
|
77
|
+
error: raw.error,
|
|
78
|
+
step: raw.step ?? 0,
|
|
79
|
+
tokensIn: raw.tokens_in ?? 0,
|
|
80
|
+
tokensOut: raw.tokens_out ?? 0,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/** @internal */
|
|
84
|
+
function detailFromWire(raw) {
|
|
85
|
+
const tasks = (raw.tasks ?? []).map(taskFromWire);
|
|
86
|
+
return {
|
|
87
|
+
id: raw.id,
|
|
88
|
+
userId: raw.user_id,
|
|
89
|
+
goal: raw.goal,
|
|
90
|
+
strategy: raw.strategy,
|
|
91
|
+
conductorModel: raw.conductor_model,
|
|
92
|
+
status: raw.status,
|
|
93
|
+
createdAt: raw.created_at,
|
|
94
|
+
startedAt: raw.started_at,
|
|
95
|
+
completedAt: raw.completed_at,
|
|
96
|
+
error: raw.error,
|
|
97
|
+
costTicks: raw.cost_ticks ?? 0,
|
|
98
|
+
totalSteps: raw.total_steps ?? 0,
|
|
99
|
+
sessionId: raw.session_id,
|
|
100
|
+
result: raw.result,
|
|
101
|
+
tasks,
|
|
102
|
+
approved: raw.approved ?? false,
|
|
103
|
+
commitSha: raw.commit_sha,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
/** @internal */
|
|
107
|
+
function createRespFromWire(raw) {
|
|
108
|
+
return {
|
|
109
|
+
missionId: raw.mission_id ?? "",
|
|
110
|
+
status: raw.status ?? "",
|
|
111
|
+
sessionId: raw.session_id,
|
|
112
|
+
conductorModel: raw.conductor_model,
|
|
113
|
+
strategy: raw.strategy,
|
|
114
|
+
workers: raw.workers,
|
|
115
|
+
createdAt: raw.created_at,
|
|
116
|
+
requestId: raw.request_id,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
/** @internal */
|
|
120
|
+
function chatRespFromWire(raw) {
|
|
121
|
+
let usage;
|
|
122
|
+
if (raw.usage) {
|
|
123
|
+
const u = raw.usage;
|
|
124
|
+
usage = {
|
|
125
|
+
inputTokens: u.input_tokens ?? 0,
|
|
126
|
+
outputTokens: u.output_tokens ?? 0,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
return {
|
|
130
|
+
missionId: raw.mission_id,
|
|
131
|
+
content: raw.content,
|
|
132
|
+
model: raw.model,
|
|
133
|
+
costTicks: raw.cost_ticks ?? 0,
|
|
134
|
+
usage,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
/** @internal */
|
|
138
|
+
function statusRespFromWire(raw) {
|
|
139
|
+
return {
|
|
140
|
+
missionId: raw.mission_id,
|
|
141
|
+
status: raw.status,
|
|
142
|
+
confirmed: raw.confirmed,
|
|
143
|
+
approved: raw.approved,
|
|
144
|
+
deleted: raw.deleted,
|
|
145
|
+
updated: raw.updated,
|
|
146
|
+
commitSha: raw.commit_sha,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
/** @internal */
|
|
150
|
+
function checkpointFromWire(raw) {
|
|
151
|
+
return {
|
|
152
|
+
id: raw.id,
|
|
153
|
+
commitSha: raw.commit_sha,
|
|
154
|
+
message: raw.message,
|
|
155
|
+
createdAt: raw.created_at,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
// ── Client methods ───────────────────────────────────────────────
|
|
159
|
+
/**
|
|
160
|
+
* Create and execute a mission asynchronously.
|
|
161
|
+
* @internal
|
|
162
|
+
*/
|
|
163
|
+
export async function missionCreate(client, req) {
|
|
164
|
+
const { data } = await client._doJSON("POST", "/qai/v1/missions/create", createReqToWire(req));
|
|
165
|
+
return createRespFromWire(data);
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* List missions for the authenticated user.
|
|
169
|
+
* @internal
|
|
170
|
+
*/
|
|
171
|
+
export async function missionList(client, status) {
|
|
172
|
+
const path = status
|
|
173
|
+
? `/qai/v1/missions/list?status=${encodeURIComponent(status)}`
|
|
174
|
+
: "/qai/v1/missions/list";
|
|
175
|
+
const { data } = await client._doJSON("GET", path, undefined);
|
|
176
|
+
const missions = (data.missions ?? []).map(detailFromWire);
|
|
177
|
+
return { missions };
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Get mission details including tasks.
|
|
181
|
+
* @internal
|
|
182
|
+
*/
|
|
183
|
+
export async function missionGet(client, missionId) {
|
|
184
|
+
const { data } = await client._doJSON("GET", `/qai/v1/missions/${encodeURIComponent(missionId)}`, undefined);
|
|
185
|
+
return detailFromWire(data);
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Delete a mission.
|
|
189
|
+
* @internal
|
|
190
|
+
*/
|
|
191
|
+
export async function missionDelete(client, missionId) {
|
|
192
|
+
const { data } = await client._doJSON("DELETE", `/qai/v1/missions/${encodeURIComponent(missionId)}`, undefined);
|
|
193
|
+
return statusRespFromWire(data);
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Cancel a running mission.
|
|
197
|
+
* @internal
|
|
198
|
+
*/
|
|
199
|
+
export async function missionCancel(client, missionId) {
|
|
200
|
+
const { data } = await client._doJSON("POST", `/qai/v1/missions/${encodeURIComponent(missionId)}/cancel`, undefined);
|
|
201
|
+
return statusRespFromWire(data);
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Pause a running mission.
|
|
205
|
+
* @internal
|
|
206
|
+
*/
|
|
207
|
+
export async function missionPause(client, missionId) {
|
|
208
|
+
const { data } = await client._doJSON("POST", `/qai/v1/missions/${encodeURIComponent(missionId)}/pause`, undefined);
|
|
209
|
+
return statusRespFromWire(data);
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Resume a paused mission.
|
|
213
|
+
* @internal
|
|
214
|
+
*/
|
|
215
|
+
export async function missionResume(client, missionId) {
|
|
216
|
+
const { data } = await client._doJSON("POST", `/qai/v1/missions/${encodeURIComponent(missionId)}/resume`, undefined);
|
|
217
|
+
return statusRespFromWire(data);
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Chat with the mission's architect.
|
|
221
|
+
* @internal
|
|
222
|
+
*/
|
|
223
|
+
export async function missionChat(client, missionId, req) {
|
|
224
|
+
const { data } = await client._doJSON("POST", `/qai/v1/missions/${encodeURIComponent(missionId)}/chat`, chatReqToWire(req));
|
|
225
|
+
return chatRespFromWire(data);
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Retry a failed task.
|
|
229
|
+
* @internal
|
|
230
|
+
*/
|
|
231
|
+
export async function missionRetryTask(client, missionId, taskId) {
|
|
232
|
+
const { data } = await client._doJSON("POST", `/qai/v1/missions/${encodeURIComponent(missionId)}/retry/${encodeURIComponent(taskId)}`, undefined);
|
|
233
|
+
return statusRespFromWire(data);
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Approve a completed mission.
|
|
237
|
+
* @internal
|
|
238
|
+
*/
|
|
239
|
+
export async function missionApprove(client, missionId, req) {
|
|
240
|
+
const { data } = await client._doJSON("POST", `/qai/v1/missions/${encodeURIComponent(missionId)}/approve`, approveReqToWire(req));
|
|
241
|
+
return statusRespFromWire(data);
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Update the mission plan.
|
|
245
|
+
* @internal
|
|
246
|
+
*/
|
|
247
|
+
export async function missionUpdatePlan(client, missionId, req) {
|
|
248
|
+
const { data } = await client._doJSON("PUT", `/qai/v1/missions/${encodeURIComponent(missionId)}/plan`, planUpdateToWire(req));
|
|
249
|
+
return statusRespFromWire(data);
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Confirm or reject the proposed execution structure.
|
|
253
|
+
* @internal
|
|
254
|
+
*/
|
|
255
|
+
export async function missionConfirmStructure(client, missionId, req) {
|
|
256
|
+
const { data } = await client._doJSON("POST", `/qai/v1/missions/${encodeURIComponent(missionId)}/confirm-structure`, req);
|
|
257
|
+
return statusRespFromWire(data);
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* List git checkpoints for a mission.
|
|
261
|
+
* @internal
|
|
262
|
+
*/
|
|
263
|
+
export async function missionCheckpoints(client, missionId) {
|
|
264
|
+
const { data } = await client._doJSON("GET", `/qai/v1/missions/${encodeURIComponent(missionId)}/checkpoints`, undefined);
|
|
265
|
+
const checkpoints = (data.checkpoints ?? []).map(checkpointFromWire);
|
|
266
|
+
return {
|
|
267
|
+
missionId: data.mission_id,
|
|
268
|
+
checkpoints,
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Import an existing plan as a new mission.
|
|
273
|
+
* @internal
|
|
274
|
+
*/
|
|
275
|
+
export async function missionImport(client, req) {
|
|
276
|
+
const { data } = await client._doJSON("POST", "/qai/v1/missions/import", importReqToWire(req));
|
|
277
|
+
return createRespFromWire(data);
|
|
278
|
+
}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import type { QuantumClient } from "./client.js";
|
|
2
|
+
/** Request body for scanning a URL for prompt injection. */
|
|
3
|
+
export interface SecurityScanUrlRequest {
|
|
4
|
+
/** URL to scan. */
|
|
5
|
+
url: string;
|
|
6
|
+
}
|
|
7
|
+
/** Request body for scanning raw HTML content. */
|
|
8
|
+
export interface SecurityScanHtmlRequest {
|
|
9
|
+
/** Raw HTML to scan. */
|
|
10
|
+
html: string;
|
|
11
|
+
/** Rendered visible text (for structural analysis). */
|
|
12
|
+
visibleText?: string;
|
|
13
|
+
/** Source URL (for context). */
|
|
14
|
+
url?: string;
|
|
15
|
+
}
|
|
16
|
+
/** Request body for reporting a suspicious URL. */
|
|
17
|
+
export interface SecurityReportRequest {
|
|
18
|
+
/** URL to report. */
|
|
19
|
+
url: string;
|
|
20
|
+
/** Description of the suspected threat. */
|
|
21
|
+
description?: string;
|
|
22
|
+
/** Category of the suspected threat. */
|
|
23
|
+
category?: string;
|
|
24
|
+
}
|
|
25
|
+
/** A single detected injection pattern. */
|
|
26
|
+
export interface SecurityFinding {
|
|
27
|
+
/** Category: "instruction_override", "role_impersonation", "data_exfiltration", etc. */
|
|
28
|
+
category: string;
|
|
29
|
+
/** Pattern that matched. */
|
|
30
|
+
pattern: string;
|
|
31
|
+
/** Offending content (truncated). */
|
|
32
|
+
content: string;
|
|
33
|
+
/** Location in the page. */
|
|
34
|
+
location: string;
|
|
35
|
+
/** Threat level for this finding. */
|
|
36
|
+
threat: string;
|
|
37
|
+
/** Detection confidence (0.0 - 1.0). */
|
|
38
|
+
confidence: number;
|
|
39
|
+
/** Human-readable description. */
|
|
40
|
+
description: string;
|
|
41
|
+
}
|
|
42
|
+
/** Threat assessment for a scanned page. */
|
|
43
|
+
export interface SecurityAssessment {
|
|
44
|
+
/** Source URL. */
|
|
45
|
+
url: string;
|
|
46
|
+
/** Overall threat level: "none", "low", "medium", "high", "critical". */
|
|
47
|
+
threatLevel: string;
|
|
48
|
+
/** Numeric threat score (0.0 - 100.0). */
|
|
49
|
+
threatScore: number;
|
|
50
|
+
/** Individual findings. */
|
|
51
|
+
findings: SecurityFinding[];
|
|
52
|
+
/** Length of hidden text content detected. */
|
|
53
|
+
hiddenTextLength: number;
|
|
54
|
+
/** Length of visible text content. */
|
|
55
|
+
visibleTextLength: number;
|
|
56
|
+
/** Ratio of hidden to total content. */
|
|
57
|
+
hiddenRatio: number;
|
|
58
|
+
/** Human-readable summary. */
|
|
59
|
+
summary: string;
|
|
60
|
+
}
|
|
61
|
+
/** Response from a security scan. */
|
|
62
|
+
export interface SecurityScanResponse {
|
|
63
|
+
/** Full threat assessment. */
|
|
64
|
+
assessment: SecurityAssessment;
|
|
65
|
+
/** Request identifier. */
|
|
66
|
+
requestId: string;
|
|
67
|
+
}
|
|
68
|
+
/** Response from checking a URL against the registry. */
|
|
69
|
+
export interface SecurityCheckResponse {
|
|
70
|
+
/** URL that was checked. */
|
|
71
|
+
url: string;
|
|
72
|
+
/** Whether the URL is blocked. */
|
|
73
|
+
blocked: boolean;
|
|
74
|
+
/** Threat level (if blocked). */
|
|
75
|
+
threatLevel?: string;
|
|
76
|
+
/** Threat score (if blocked). */
|
|
77
|
+
threatScore?: number;
|
|
78
|
+
/** Detection categories (if blocked). */
|
|
79
|
+
categories?: string[];
|
|
80
|
+
/** First seen timestamp. */
|
|
81
|
+
firstSeen?: string;
|
|
82
|
+
/** Last seen timestamp. */
|
|
83
|
+
lastSeen?: string;
|
|
84
|
+
/** Number of reports. */
|
|
85
|
+
reportCount?: number;
|
|
86
|
+
/** Registry status: "confirmed", "suspected". */
|
|
87
|
+
status?: string;
|
|
88
|
+
/** Human-readable message. */
|
|
89
|
+
message?: string;
|
|
90
|
+
}
|
|
91
|
+
/** A single blocklist entry. */
|
|
92
|
+
export interface SecurityBlocklistEntry {
|
|
93
|
+
/** Entry identifier. */
|
|
94
|
+
id?: string;
|
|
95
|
+
/** Blocked URL. */
|
|
96
|
+
url: string;
|
|
97
|
+
/** Registry status. */
|
|
98
|
+
status: string;
|
|
99
|
+
/** Threat level. */
|
|
100
|
+
threatLevel: string;
|
|
101
|
+
/** Threat score. */
|
|
102
|
+
threatScore: number;
|
|
103
|
+
/** Detection categories. */
|
|
104
|
+
categories: string[];
|
|
105
|
+
/** Number of findings. */
|
|
106
|
+
findingsCount: number;
|
|
107
|
+
/** Hidden content ratio. */
|
|
108
|
+
hiddenRatio: number;
|
|
109
|
+
/** First seen timestamp. */
|
|
110
|
+
firstSeen?: string;
|
|
111
|
+
/** Summary. */
|
|
112
|
+
summary: string;
|
|
113
|
+
}
|
|
114
|
+
/** Response from the blocklist feed. */
|
|
115
|
+
export interface SecurityBlocklistResponse {
|
|
116
|
+
/** Blocklist entries. */
|
|
117
|
+
entries: SecurityBlocklistEntry[];
|
|
118
|
+
/** Total count. */
|
|
119
|
+
count: number;
|
|
120
|
+
/** Filter status used. */
|
|
121
|
+
status: string;
|
|
122
|
+
}
|
|
123
|
+
/** Response from reporting a URL. */
|
|
124
|
+
export interface SecurityReportResponse {
|
|
125
|
+
/** URL that was reported. */
|
|
126
|
+
url: string;
|
|
127
|
+
/** Report status: "existing" or "suspected". */
|
|
128
|
+
status: string;
|
|
129
|
+
/** Message. */
|
|
130
|
+
message: string;
|
|
131
|
+
/** Threat level (if already in registry). */
|
|
132
|
+
threatLevel?: string;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Scan a URL for prompt injection attacks.
|
|
136
|
+
* @internal
|
|
137
|
+
*/
|
|
138
|
+
export declare function securityScanUrl(client: QuantumClient, url: string): Promise<SecurityScanResponse>;
|
|
139
|
+
/**
|
|
140
|
+
* Scan raw HTML content for prompt injection.
|
|
141
|
+
* @internal
|
|
142
|
+
*/
|
|
143
|
+
export declare function securityScanHtml(client: QuantumClient, req: SecurityScanHtmlRequest): Promise<SecurityScanResponse>;
|
|
144
|
+
/**
|
|
145
|
+
* Check a URL against the injection registry.
|
|
146
|
+
* @internal
|
|
147
|
+
*/
|
|
148
|
+
export declare function securityCheck(client: QuantumClient, url: string): Promise<SecurityCheckResponse>;
|
|
149
|
+
/**
|
|
150
|
+
* Get the injection blocklist feed.
|
|
151
|
+
* @internal
|
|
152
|
+
*/
|
|
153
|
+
export declare function securityBlocklist(client: QuantumClient, status?: string): Promise<SecurityBlocklistResponse>;
|
|
154
|
+
/**
|
|
155
|
+
* Report a suspicious URL.
|
|
156
|
+
* @internal
|
|
157
|
+
*/
|
|
158
|
+
export declare function securityReport(client: QuantumClient, req: SecurityReportRequest): Promise<SecurityReportResponse>;
|
package/dist/security.js
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
// ── Wire format helpers ──────────────────────────────────────────
|
|
2
|
+
/** @internal */
|
|
3
|
+
function scanHtmlToWire(req) {
|
|
4
|
+
const out = { html: req.html };
|
|
5
|
+
if (req.visibleText !== undefined)
|
|
6
|
+
out.visible_text = req.visibleText;
|
|
7
|
+
if (req.url !== undefined)
|
|
8
|
+
out.url = req.url;
|
|
9
|
+
return out;
|
|
10
|
+
}
|
|
11
|
+
/** @internal */
|
|
12
|
+
function findingFromWire(raw) {
|
|
13
|
+
return {
|
|
14
|
+
category: raw.category ?? "",
|
|
15
|
+
pattern: raw.pattern ?? "",
|
|
16
|
+
content: raw.content ?? "",
|
|
17
|
+
location: raw.location ?? "",
|
|
18
|
+
threat: raw.threat ?? "",
|
|
19
|
+
confidence: raw.confidence ?? 0,
|
|
20
|
+
description: raw.description ?? "",
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/** @internal */
|
|
24
|
+
function assessmentFromWire(raw) {
|
|
25
|
+
const findings = (raw.findings ?? []).map(findingFromWire);
|
|
26
|
+
return {
|
|
27
|
+
url: raw.url ?? "",
|
|
28
|
+
threatLevel: raw.threat_level ?? "",
|
|
29
|
+
threatScore: raw.threat_score ?? 0,
|
|
30
|
+
findings,
|
|
31
|
+
hiddenTextLength: raw.hidden_text_length ?? 0,
|
|
32
|
+
visibleTextLength: raw.visible_text_length ?? 0,
|
|
33
|
+
hiddenRatio: raw.hidden_ratio ?? 0,
|
|
34
|
+
summary: raw.summary ?? "",
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/** @internal */
|
|
38
|
+
function scanRespFromWire(raw) {
|
|
39
|
+
return {
|
|
40
|
+
assessment: assessmentFromWire(raw.assessment ?? {}),
|
|
41
|
+
requestId: raw.request_id ?? "",
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/** @internal */
|
|
45
|
+
function checkRespFromWire(raw) {
|
|
46
|
+
return {
|
|
47
|
+
url: raw.url ?? "",
|
|
48
|
+
blocked: raw.blocked ?? false,
|
|
49
|
+
threatLevel: raw.threat_level,
|
|
50
|
+
threatScore: raw.threat_score,
|
|
51
|
+
categories: raw.categories,
|
|
52
|
+
firstSeen: raw.first_seen,
|
|
53
|
+
lastSeen: raw.last_seen,
|
|
54
|
+
reportCount: raw.report_count,
|
|
55
|
+
status: raw.status,
|
|
56
|
+
message: raw.message,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/** @internal */
|
|
60
|
+
function blocklistEntryFromWire(raw) {
|
|
61
|
+
return {
|
|
62
|
+
id: raw.id,
|
|
63
|
+
url: raw.url ?? "",
|
|
64
|
+
status: raw.status ?? "",
|
|
65
|
+
threatLevel: raw.threat_level ?? "",
|
|
66
|
+
threatScore: raw.threat_score ?? 0,
|
|
67
|
+
categories: raw.categories ?? [],
|
|
68
|
+
findingsCount: raw.findings_count ?? 0,
|
|
69
|
+
hiddenRatio: raw.hidden_ratio ?? 0,
|
|
70
|
+
firstSeen: raw.first_seen,
|
|
71
|
+
summary: raw.summary ?? "",
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
/** @internal */
|
|
75
|
+
function blocklistRespFromWire(raw) {
|
|
76
|
+
const entries = (raw.entries ?? []).map(blocklistEntryFromWire);
|
|
77
|
+
return {
|
|
78
|
+
entries,
|
|
79
|
+
count: raw.count ?? 0,
|
|
80
|
+
status: raw.status ?? "",
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/** @internal */
|
|
84
|
+
function reportRespFromWire(raw) {
|
|
85
|
+
return {
|
|
86
|
+
url: raw.url ?? "",
|
|
87
|
+
status: raw.status ?? "",
|
|
88
|
+
message: raw.message ?? "",
|
|
89
|
+
threatLevel: raw.threat_level,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
// ── Client methods ───────────────────────────────────────────────
|
|
93
|
+
/**
|
|
94
|
+
* Scan a URL for prompt injection attacks.
|
|
95
|
+
* @internal
|
|
96
|
+
*/
|
|
97
|
+
export async function securityScanUrl(client, url) {
|
|
98
|
+
const { data } = await client._doJSON("POST", "/qai/v1/security/scan-url", { url });
|
|
99
|
+
return scanRespFromWire(data);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Scan raw HTML content for prompt injection.
|
|
103
|
+
* @internal
|
|
104
|
+
*/
|
|
105
|
+
export async function securityScanHtml(client, req) {
|
|
106
|
+
const { data } = await client._doJSON("POST", "/qai/v1/security/scan-html", scanHtmlToWire(req));
|
|
107
|
+
return scanRespFromWire(data);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Check a URL against the injection registry.
|
|
111
|
+
* @internal
|
|
112
|
+
*/
|
|
113
|
+
export async function securityCheck(client, url) {
|
|
114
|
+
const { data } = await client._doJSON("GET", `/qai/v1/security/check?url=${encodeURIComponent(url)}`, undefined);
|
|
115
|
+
return checkRespFromWire(data);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Get the injection blocklist feed.
|
|
119
|
+
* @internal
|
|
120
|
+
*/
|
|
121
|
+
export async function securityBlocklist(client, status) {
|
|
122
|
+
const path = status
|
|
123
|
+
? `/qai/v1/security/blocklist?status=${encodeURIComponent(status)}`
|
|
124
|
+
: "/qai/v1/security/blocklist";
|
|
125
|
+
const { data } = await client._doJSON("GET", path, undefined);
|
|
126
|
+
return blocklistRespFromWire(data);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Report a suspicious URL.
|
|
130
|
+
* @internal
|
|
131
|
+
*/
|
|
132
|
+
export async function securityReport(client, req) {
|
|
133
|
+
const { data } = await client._doJSON("POST", "/qai/v1/security/report", req);
|
|
134
|
+
return reportRespFromWire(data);
|
|
135
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -84,12 +84,39 @@ export interface StreamToolUse {
|
|
|
84
84
|
name: string;
|
|
85
85
|
input: Record<string, unknown>;
|
|
86
86
|
}
|
|
87
|
+
/** New since v0.6: tool-use streaming triplet. */
|
|
88
|
+
export interface StreamToolUseStart {
|
|
89
|
+
id: string;
|
|
90
|
+
name: string;
|
|
91
|
+
}
|
|
92
|
+
export interface StreamToolUseInputDelta {
|
|
93
|
+
id: string;
|
|
94
|
+
/** Raw JSON fragment — may not parse on its own; accumulate until tool_use_complete. */
|
|
95
|
+
partial_json: string;
|
|
96
|
+
}
|
|
97
|
+
export interface StreamToolUseComplete {
|
|
98
|
+
id: string;
|
|
99
|
+
name: string;
|
|
100
|
+
/** Server-accumulated, fully-parsed tool arguments. */
|
|
101
|
+
input: Record<string, unknown>;
|
|
102
|
+
}
|
|
87
103
|
export interface StreamEvent {
|
|
88
104
|
type: string;
|
|
89
|
-
/** Event type (e.g. "content_delta", "thinking_delta", "
|
|
105
|
+
/** Event type (e.g. "content_delta", "thinking_delta", "tool_use_start",
|
|
106
|
+
* "tool_use_input_delta", "tool_use_complete", "tool_use" (legacy),
|
|
107
|
+
* "usage", "error", "done"). */
|
|
90
108
|
event_type?: string;
|
|
91
109
|
delta?: StreamDelta;
|
|
110
|
+
/** Populated for the legacy atomic "tool_use" event. New code should
|
|
111
|
+
* prefer the triplet (tool_use_start / tool_use_input_delta /
|
|
112
|
+
* tool_use_complete). */
|
|
92
113
|
tool_use?: StreamToolUse;
|
|
114
|
+
/** Populated for "tool_use_start" events. */
|
|
115
|
+
tool_use_start?: StreamToolUseStart;
|
|
116
|
+
/** Populated for "tool_use_input_delta" events. */
|
|
117
|
+
tool_use_input_delta?: StreamToolUseInputDelta;
|
|
118
|
+
/** Populated for "tool_use_complete" events. */
|
|
119
|
+
tool_use_complete?: StreamToolUseComplete;
|
|
93
120
|
usage?: ChatUsage;
|
|
94
121
|
error?: string;
|
|
95
122
|
done?: boolean;
|
|
@@ -99,6 +126,11 @@ export interface RawStreamEvent {
|
|
|
99
126
|
type?: string;
|
|
100
127
|
delta?: StreamDelta;
|
|
101
128
|
tool_use?: StreamToolUse;
|
|
129
|
+
/** Fields shared by the triplet — flattened in the wire format. */
|
|
130
|
+
id?: string;
|
|
131
|
+
name?: string;
|
|
132
|
+
input?: Record<string, unknown>;
|
|
133
|
+
partial_json?: string;
|
|
102
134
|
usage?: ChatUsage;
|
|
103
135
|
message?: string;
|
|
104
136
|
input_tokens?: number;
|
package/dist/vision.d.ts
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import type { QuantumClient } from "./client.js";
|
|
2
|
+
/** Domain context for relevance analysis. */
|
|
3
|
+
export interface VisionContext {
|
|
4
|
+
/** Installation type (e.g. "solar", "heat_pump", "ev_charger"). */
|
|
5
|
+
installationType?: string;
|
|
6
|
+
/** Phase (e.g. "pre_install", "installation", "post_install"). */
|
|
7
|
+
phase?: string;
|
|
8
|
+
/** Expected items for relevance checking. */
|
|
9
|
+
expectedItems?: string[];
|
|
10
|
+
}
|
|
11
|
+
/** Request body for vision analysis endpoints. */
|
|
12
|
+
export interface VisionRequest {
|
|
13
|
+
/** Base64-encoded image (with or without data: prefix). */
|
|
14
|
+
imageBase64?: string;
|
|
15
|
+
/** Image URL (fetched by the model provider). */
|
|
16
|
+
imageUrl?: string;
|
|
17
|
+
/** Model to use. Default: gemini-2.5-flash. */
|
|
18
|
+
model?: string;
|
|
19
|
+
/** Analysis profile: "combined" (default), "scene", "objects", "ocr", "quality". */
|
|
20
|
+
profile?: string;
|
|
21
|
+
/** Domain context for relevance checking. */
|
|
22
|
+
context?: VisionContext;
|
|
23
|
+
}
|
|
24
|
+
/** A detected object with bounding box. */
|
|
25
|
+
export interface DetectedObject {
|
|
26
|
+
/** Object label. */
|
|
27
|
+
label: string;
|
|
28
|
+
/** Detection confidence (0.0 - 1.0). */
|
|
29
|
+
confidence: number;
|
|
30
|
+
/** Bounding box: [y_min, x_min, y_max, x_max] normalised to 0-1000. */
|
|
31
|
+
boundingBox: [number, number, number, number];
|
|
32
|
+
}
|
|
33
|
+
/** Image quality assessment. */
|
|
34
|
+
export interface QualityAssessment {
|
|
35
|
+
/** Overall rating: "good", "acceptable", "poor". */
|
|
36
|
+
overall: string;
|
|
37
|
+
/** Quality score (0.0 - 1.0). */
|
|
38
|
+
score: number;
|
|
39
|
+
/** Blur level: "none", "slight", "significant". */
|
|
40
|
+
blur: string;
|
|
41
|
+
/** Lighting: "well_lit", "dim", "dark". */
|
|
42
|
+
darkness: string;
|
|
43
|
+
/** Resolution: "high", "adequate", "low". */
|
|
44
|
+
resolution: string;
|
|
45
|
+
/** Exposure: "correct", "over", "under". */
|
|
46
|
+
exposure: string;
|
|
47
|
+
/** Specific issues found. */
|
|
48
|
+
issues: string[];
|
|
49
|
+
}
|
|
50
|
+
/** Relevance check against expected content. */
|
|
51
|
+
export interface RelevanceCheck {
|
|
52
|
+
/** Whether the image is relevant to the context. */
|
|
53
|
+
relevant: boolean;
|
|
54
|
+
/** Relevance score (0.0 - 1.0). */
|
|
55
|
+
score: number;
|
|
56
|
+
/** Items expected based on context. */
|
|
57
|
+
expectedItems: string[];
|
|
58
|
+
/** Items actually found in the image. */
|
|
59
|
+
foundItems: string[];
|
|
60
|
+
/** Expected but not found. */
|
|
61
|
+
missingItems: string[];
|
|
62
|
+
/** Found but not expected. */
|
|
63
|
+
unexpectedItems: string[];
|
|
64
|
+
/** Additional notes. */
|
|
65
|
+
notes?: string;
|
|
66
|
+
}
|
|
67
|
+
/** A detected text region in the image. */
|
|
68
|
+
export interface TextOverlay {
|
|
69
|
+
/** Extracted text content. */
|
|
70
|
+
text: string;
|
|
71
|
+
/** Bounding box: [y_min, x_min, y_max, x_max] normalised to 0-1000. */
|
|
72
|
+
boundingBox?: [number, number, number, number];
|
|
73
|
+
/** Overlay type: "gps", "timestamp", "address", "label", "other". */
|
|
74
|
+
type?: string;
|
|
75
|
+
}
|
|
76
|
+
/** OCR / text extraction result. */
|
|
77
|
+
export interface OcrResult {
|
|
78
|
+
/** All extracted text concatenated. */
|
|
79
|
+
text?: string;
|
|
80
|
+
/** Extracted metadata (GPS, timestamp, address, etc.). */
|
|
81
|
+
metadata: Record<string, string>;
|
|
82
|
+
/** Individual text overlays with positions. */
|
|
83
|
+
overlays: TextOverlay[];
|
|
84
|
+
}
|
|
85
|
+
/** Full vision analysis response. */
|
|
86
|
+
export interface VisionResponse {
|
|
87
|
+
/** Scene description. */
|
|
88
|
+
caption?: string;
|
|
89
|
+
/** Suggested tags (lowercase_snake_case). */
|
|
90
|
+
tags: string[];
|
|
91
|
+
/** Detected objects with bounding boxes. */
|
|
92
|
+
objects: DetectedObject[];
|
|
93
|
+
/** Image quality assessment. */
|
|
94
|
+
quality?: QualityAssessment;
|
|
95
|
+
/** Relevance check against context. */
|
|
96
|
+
relevance?: RelevanceCheck;
|
|
97
|
+
/** Extracted text and overlay metadata. */
|
|
98
|
+
ocr?: OcrResult;
|
|
99
|
+
/** Model used. */
|
|
100
|
+
model: string;
|
|
101
|
+
/** Cost in ticks. */
|
|
102
|
+
costTicks: number;
|
|
103
|
+
/** Request identifier. */
|
|
104
|
+
requestId: string;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Full combined vision analysis (scene + objects + quality + OCR + relevance).
|
|
108
|
+
* @internal
|
|
109
|
+
*/
|
|
110
|
+
export declare function visionAnalyze(client: QuantumClient, req: VisionRequest): Promise<VisionResponse>;
|
|
111
|
+
/**
|
|
112
|
+
* Object detection with bounding boxes.
|
|
113
|
+
* @internal
|
|
114
|
+
*/
|
|
115
|
+
export declare function visionDetect(client: QuantumClient, req: VisionRequest): Promise<VisionResponse>;
|
|
116
|
+
/**
|
|
117
|
+
* Scene description and tags.
|
|
118
|
+
* @internal
|
|
119
|
+
*/
|
|
120
|
+
export declare function visionDescribe(client: QuantumClient, req: VisionRequest): Promise<VisionResponse>;
|
|
121
|
+
/**
|
|
122
|
+
* Text extraction and overlay metadata (OCR).
|
|
123
|
+
* @internal
|
|
124
|
+
*/
|
|
125
|
+
export declare function visionOcr(client: QuantumClient, req: VisionRequest): Promise<VisionResponse>;
|
|
126
|
+
/**
|
|
127
|
+
* Image quality assessment.
|
|
128
|
+
* @internal
|
|
129
|
+
*/
|
|
130
|
+
export declare function visionQuality(client: QuantumClient, req: VisionRequest): Promise<VisionResponse>;
|
package/dist/vision.js
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
// ── Wire format (snake_case JSON) ────────────────────────────────
|
|
2
|
+
/** @internal Convert camelCase request to snake_case wire format. */
|
|
3
|
+
function toWire(req) {
|
|
4
|
+
const out = {};
|
|
5
|
+
if (req.imageBase64 !== undefined)
|
|
6
|
+
out.image_base64 = req.imageBase64;
|
|
7
|
+
if (req.imageUrl !== undefined)
|
|
8
|
+
out.image_url = req.imageUrl;
|
|
9
|
+
if (req.model !== undefined)
|
|
10
|
+
out.model = req.model;
|
|
11
|
+
if (req.profile !== undefined)
|
|
12
|
+
out.profile = req.profile;
|
|
13
|
+
if (req.context) {
|
|
14
|
+
const ctx = {};
|
|
15
|
+
if (req.context.installationType !== undefined)
|
|
16
|
+
ctx.installation_type = req.context.installationType;
|
|
17
|
+
if (req.context.phase !== undefined)
|
|
18
|
+
ctx.phase = req.context.phase;
|
|
19
|
+
if (req.context.expectedItems !== undefined)
|
|
20
|
+
ctx.expected_items = req.context.expectedItems;
|
|
21
|
+
out.context = ctx;
|
|
22
|
+
}
|
|
23
|
+
return out;
|
|
24
|
+
}
|
|
25
|
+
/** @internal Convert snake_case wire response to camelCase. */
|
|
26
|
+
function fromWire(raw) {
|
|
27
|
+
const objects = (raw.objects ?? []).map((o) => ({
|
|
28
|
+
label: o.label ?? "",
|
|
29
|
+
confidence: o.confidence ?? 0,
|
|
30
|
+
boundingBox: o.bounding_box ?? [0, 0, 0, 0],
|
|
31
|
+
}));
|
|
32
|
+
let quality;
|
|
33
|
+
if (raw.quality) {
|
|
34
|
+
const q = raw.quality;
|
|
35
|
+
quality = {
|
|
36
|
+
overall: q.overall ?? "",
|
|
37
|
+
score: q.score ?? 0,
|
|
38
|
+
blur: q.blur ?? "",
|
|
39
|
+
darkness: q.darkness ?? "",
|
|
40
|
+
resolution: q.resolution ?? "",
|
|
41
|
+
exposure: q.exposure ?? "",
|
|
42
|
+
issues: q.issues ?? [],
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
let relevance;
|
|
46
|
+
if (raw.relevance) {
|
|
47
|
+
const r = raw.relevance;
|
|
48
|
+
relevance = {
|
|
49
|
+
relevant: r.relevant ?? false,
|
|
50
|
+
score: r.score ?? 0,
|
|
51
|
+
expectedItems: r.expected_items ?? [],
|
|
52
|
+
foundItems: r.found_items ?? [],
|
|
53
|
+
missingItems: r.missing_items ?? [],
|
|
54
|
+
unexpectedItems: r.unexpected_items ?? [],
|
|
55
|
+
notes: r.notes,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
let ocr;
|
|
59
|
+
if (raw.ocr) {
|
|
60
|
+
const o = raw.ocr;
|
|
61
|
+
const overlays = (o.overlays ?? []).map((ov) => ({
|
|
62
|
+
text: ov.text ?? "",
|
|
63
|
+
boundingBox: ov.bounding_box,
|
|
64
|
+
type: ov.type,
|
|
65
|
+
}));
|
|
66
|
+
ocr = {
|
|
67
|
+
text: o.text,
|
|
68
|
+
metadata: o.metadata ?? {},
|
|
69
|
+
overlays,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
caption: raw.caption,
|
|
74
|
+
tags: raw.tags ?? [],
|
|
75
|
+
objects,
|
|
76
|
+
quality,
|
|
77
|
+
relevance,
|
|
78
|
+
ocr,
|
|
79
|
+
model: raw.model ?? "",
|
|
80
|
+
costTicks: raw.cost_ticks ?? 0,
|
|
81
|
+
requestId: raw.request_id ?? "",
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
// ── Client methods ───────────────────────────────────────────────
|
|
85
|
+
/**
|
|
86
|
+
* Full combined vision analysis (scene + objects + quality + OCR + relevance).
|
|
87
|
+
* @internal
|
|
88
|
+
*/
|
|
89
|
+
export async function visionAnalyze(client, req) {
|
|
90
|
+
const { data } = await client._doJSON("POST", "/qai/v1/vision/analyze", toWire(req));
|
|
91
|
+
return fromWire(data);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Object detection with bounding boxes.
|
|
95
|
+
* @internal
|
|
96
|
+
*/
|
|
97
|
+
export async function visionDetect(client, req) {
|
|
98
|
+
const { data } = await client._doJSON("POST", "/qai/v1/vision/detect", toWire(req));
|
|
99
|
+
return fromWire(data);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Scene description and tags.
|
|
103
|
+
* @internal
|
|
104
|
+
*/
|
|
105
|
+
export async function visionDescribe(client, req) {
|
|
106
|
+
const { data } = await client._doJSON("POST", "/qai/v1/vision/describe", toWire(req));
|
|
107
|
+
return fromWire(data);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Text extraction and overlay metadata (OCR).
|
|
111
|
+
* @internal
|
|
112
|
+
*/
|
|
113
|
+
export async function visionOcr(client, req) {
|
|
114
|
+
const { data } = await client._doJSON("POST", "/qai/v1/vision/ocr", toWire(req));
|
|
115
|
+
return fromWire(data);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Image quality assessment.
|
|
119
|
+
* @internal
|
|
120
|
+
*/
|
|
121
|
+
export async function visionQuality(client, req) {
|
|
122
|
+
const { data } = await client._doJSON("POST", "/qai/v1/vision/quality", toWire(req));
|
|
123
|
+
return fromWire(data);
|
|
124
|
+
}
|