@kognitivedev/cloud-web-search 0.2.28

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/CHANGELOG.md ADDED
@@ -0,0 +1,13 @@
1
+ # @kognitivedev/cloud-web-search
2
+
3
+ ## 0.2.28
4
+
5
+ ### Patch Changes
6
+
7
+ - add hosted cloud web-search SDK
8
+ - validate REST and SSE payloads at runtime
9
+ - support typed `result.output` parsing via `parseOutput`
10
+ - normalize canonical lifecycle frames and persisted job-event replay streams
11
+
12
+ - Updated dependencies []:
13
+ - @kognitivedev/client-core@0.2.28
package/README.md ADDED
@@ -0,0 +1,186 @@
1
+ # @kognitivedev/cloud-web-search
2
+
3
+ Cloud web-search SDK for Kognitive's hosted `/api/cloud/web-search/*` job APIs.
4
+
5
+ Use it when you want a first-class TypeScript client for:
6
+
7
+ - creating hosted `search` and `research` jobs
8
+ - polling current job state
9
+ - waiting for completion
10
+ - cancelling queued or running jobs
11
+ - subscribing to live progress over SSE
12
+ - validating server payloads before they reach application code
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ bun add @kognitivedev/cloud-web-search
18
+ ```
19
+
20
+ ## Quick Start
21
+
22
+ ```ts
23
+ import { KognitiveCloudWebSearchClient } from "@kognitivedev/cloud-web-search";
24
+
25
+ const webSearch = new KognitiveCloudWebSearchClient({
26
+ baseUrl: process.env.COGNITIVE_API_URL ?? "http://localhost:3001",
27
+ apiKey: process.env.COGNITIVE_API_KEY,
28
+ });
29
+
30
+ const job = await webSearch.jobs.create({
31
+ mode: "research",
32
+ instructions: "Research the latest Bun release updates.",
33
+ responseInstructions: "Return a concise summary.",
34
+ responseSchema: {
35
+ type: "object",
36
+ properties: {
37
+ summary: { type: "string" },
38
+ },
39
+ required: ["summary"],
40
+ },
41
+ parameters: {
42
+ maxPages: 4,
43
+ timeRange: "month",
44
+ },
45
+ });
46
+
47
+ const completed = await webSearch.jobs.waitForCompletion(job.id, {
48
+ parseOutput(value) {
49
+ if (!value || typeof value !== "object" || Array.isArray(value) || typeof value.summary !== "string") {
50
+ throw new Error("Expected { summary: string }");
51
+ }
52
+
53
+ return { summary: value.summary };
54
+ },
55
+ });
56
+
57
+ console.log(completed.result?.output?.summary);
58
+ console.log(completed.result?.sources);
59
+ ```
60
+
61
+ ## API Surface
62
+
63
+ `@kognitivedev/cloud-web-search` centers on hosted job lifecycle methods:
64
+
65
+ - `jobs.list()`
66
+ - `jobs.create()`
67
+ - `jobs.createSearch()`
68
+ - `jobs.createResearch()`
69
+ - `jobs.get()`
70
+ - `jobs.result()`
71
+ - `jobs.cancel()`
72
+ - `jobs.waitForCompletion()`
73
+ - `jobs.stream()`
74
+ - `jobs.subscribe()`
75
+ - `jobs.streamUrl()`
76
+
77
+ All requests use the same project API key model as the backend cloud web-search endpoints.
78
+
79
+ ## Typed Output
80
+
81
+ `jobs.get()`, `jobs.result()`, `jobs.waitForCompletion()`, and `jobs.subscribe()` accept `parseOutput` so you can turn `result.output` from `unknown` into a typed shape at the SDK boundary.
82
+
83
+ ```ts
84
+ const envelope = await webSearch.jobs.result(job.id, {
85
+ parseOutput(value) {
86
+ if (!value || typeof value !== "object" || Array.isArray(value) || typeof value.summary !== "string") {
87
+ throw new Error("Expected { summary: string }");
88
+ }
89
+
90
+ return { summary: value.summary };
91
+ },
92
+ });
93
+
94
+ envelope.result?.output?.summary;
95
+ ```
96
+
97
+ ## Streaming Progress
98
+
99
+ Use `jobs.subscribe()` when you want normalized progress events without manually parsing SSE frames:
100
+
101
+ ```ts
102
+ const stream = await webSearch.jobs.subscribe(job.id);
103
+
104
+ for await (const event of stream) {
105
+ switch (event.type) {
106
+ case "snapshot":
107
+ console.log("job status:", event.job.status);
108
+ break;
109
+ case "progress":
110
+ console.log(`[${event.progress.stage}] ${event.progress.message}`);
111
+ break;
112
+ case "completed":
113
+ console.log("done:", event.result?.text);
114
+ break;
115
+ case "error":
116
+ console.error(event.errorMessage);
117
+ break;
118
+ case "cancelled":
119
+ console.log("job cancelled");
120
+ break;
121
+ case "event":
122
+ console.log("raw job event:", event.event.eventType);
123
+ break;
124
+ case "unknown":
125
+ console.log("unrecognized frame:", event.frame.event);
126
+ break;
127
+ }
128
+ }
129
+ ```
130
+
131
+ The SDK handles both stream shapes the backend can emit:
132
+
133
+ - canonical lifecycle frames such as `job.snapshot`, `job.progress`, and `job.completed`
134
+ - persisted job-event replay frames where the SSE `event:` name is the stored `eventType`
135
+
136
+ The low-level `readSSEStream()` parser is chunk-safe and supports:
137
+
138
+ - multi-line `data:` fields
139
+ - `CRLF`, `LF`, and `CR` line endings
140
+ - SSE comments
141
+ - `id:` and `retry:` fields
142
+ - EOF flush for the final event
143
+
144
+ If you want the raw SSE response instead, use:
145
+
146
+ ```ts
147
+ const response = await webSearch.jobs.stream(job.id);
148
+ ```
149
+
150
+ ## Polling For Completion
151
+
152
+ ```ts
153
+ const { job: finalJob, result } = await webSearch.jobs.waitForCompletion(job.id, {
154
+ intervalMs: 1_000,
155
+ timeoutMs: 120_000,
156
+ });
157
+
158
+ console.log(finalJob.status);
159
+ console.log(result?.text);
160
+ ```
161
+
162
+ `waitForCompletion()` polls `jobs.get()` until the job reaches a terminal state:
163
+
164
+ - returns `{ job, result }` when the job completes successfully
165
+ - throws when the job ends in `error`
166
+ - throws when the job is `cancelled`
167
+
168
+ ## Cancellation
169
+
170
+ ```ts
171
+ await webSearch.jobs.cancel(job.id);
172
+ ```
173
+
174
+ Cancellation is best-effort at the job layer. Completed, failed, or already-cancelled jobs are returned unchanged by the backend.
175
+
176
+ ## Error Model
177
+
178
+ The SDK fails fast on malformed server payloads instead of returning optimistic casts:
179
+
180
+ - `CloudWebSearchValidationError` for invalid REST or stream payloads
181
+ - `CloudWebSearchStreamProtocolError` when the SSE response cannot be consumed as a stream
182
+
183
+ ## Related Packages
184
+
185
+ - `@kognitivedev/web-search` for the in-process workflow/tool package
186
+ - `@kognitivedev/flows` for hosted cloud-flow APIs
@@ -0,0 +1,33 @@
1
+ import { HttpTransport } from "@kognitivedev/client-core";
2
+ import type { CloudWebSearchClientConfig, CloudWebSearchDecodeOptions, CloudWebSearchExecutionParameters, CloudWebSearchJobRecord, CloudWebSearchJobResultEnvelope, CloudWebSearchJobWaitResult, CloudWebSearchResearchJobInput, CloudWebSearchRichEvent, CloudWebSearchSearchJobInput, CloudWebSearchStreamEvent, CloudWebSearchSubscribeOptions, CreateCloudWebSearchJobInput, WaitForCompletionOptions } from "./types";
3
+ export declare function readCloudWebSearchEventStream<TOutput = unknown>(stream: ReadableStream<Uint8Array>, options?: CloudWebSearchDecodeOptions<TOutput>): AsyncGenerator<CloudWebSearchStreamEvent<TOutput>>;
4
+ export declare class KognitiveCloudWebSearchClient {
5
+ private readonly transport;
6
+ readonly jobs: {
7
+ list: <TOutput = unknown>(options?: CloudWebSearchDecodeOptions<TOutput>) => Promise<CloudWebSearchJobRecord<TOutput>[]>;
8
+ create: (input: CreateCloudWebSearchJobInput) => Promise<CloudWebSearchJobRecord<unknown>>;
9
+ createSearch: (input: Omit<CloudWebSearchSearchJobInput, "mode"> | string, parameters?: CloudWebSearchExecutionParameters) => Promise<CloudWebSearchJobRecord<unknown>>;
10
+ createResearch: <TOutput = unknown>(input: Omit<CloudWebSearchResearchJobInput, "mode"> | string, options?: Omit<CloudWebSearchResearchJobInput, "mode" | "instructions">) => Promise<CloudWebSearchJobRecord<TOutput>>;
11
+ get: <TOutput = unknown>(jobId: string, options?: CloudWebSearchDecodeOptions<TOutput>) => Promise<CloudWebSearchJobRecord<TOutput>>;
12
+ result: <TOutput = unknown>(jobId: string, options?: CloudWebSearchDecodeOptions<TOutput>) => Promise<CloudWebSearchJobResultEnvelope<TOutput>>;
13
+ cancel: <TOutput = unknown>(jobId: string, options?: CloudWebSearchDecodeOptions<TOutput>) => Promise<CloudWebSearchJobRecord<TOutput>>;
14
+ stream: (jobId: string, init?: RequestInit) => Promise<Response>;
15
+ subscribe: <TOutput = unknown>(jobId: string, options?: CloudWebSearchSubscribeOptions<TOutput>) => Promise<AsyncGenerator<CloudWebSearchStreamEvent<TOutput>, any, any>>;
16
+ subscribeRich: <TOutput = unknown>(jobId: string, options?: CloudWebSearchSubscribeOptions<TOutput>) => Promise<AsyncGenerator<CloudWebSearchRichEvent<TOutput>, any, any>>;
17
+ streamUrl: (jobId: string) => string;
18
+ waitForCompletion: <TOutput = unknown>(jobId: string, options?: WaitForCompletionOptions<TOutput>) => Promise<CloudWebSearchJobWaitResult<TOutput>>;
19
+ };
20
+ constructor(config: CloudWebSearchClientConfig | HttpTransport);
21
+ getJobEventsStreamUrl(jobId: string): string;
22
+ listJobs<TOutput = unknown>(options?: CloudWebSearchDecodeOptions<TOutput>): Promise<CloudWebSearchJobRecord<TOutput>[]>;
23
+ createJob(input: CreateCloudWebSearchJobInput): Promise<CloudWebSearchJobRecord>;
24
+ createSearchJob(input: Omit<CloudWebSearchSearchJobInput, "mode"> | string, parameters?: CloudWebSearchExecutionParameters): Promise<CloudWebSearchJobRecord>;
25
+ createResearchJob<TOutput = unknown>(input: Omit<CloudWebSearchResearchJobInput, "mode"> | string, options?: Omit<CloudWebSearchResearchJobInput, "mode" | "instructions">): Promise<CloudWebSearchJobRecord<TOutput>>;
26
+ getJob<TOutput = unknown>(jobId: string, options?: CloudWebSearchDecodeOptions<TOutput>): Promise<CloudWebSearchJobRecord<TOutput>>;
27
+ getJobResult<TOutput = unknown>(jobId: string, options?: CloudWebSearchDecodeOptions<TOutput>): Promise<CloudWebSearchJobResultEnvelope<TOutput>>;
28
+ cancelJob<TOutput = unknown>(jobId: string, options?: CloudWebSearchDecodeOptions<TOutput>): Promise<CloudWebSearchJobRecord<TOutput>>;
29
+ streamJob(jobId: string, init?: RequestInit): Promise<Response>;
30
+ subscribeToJob<TOutput = unknown>(jobId: string, options?: CloudWebSearchSubscribeOptions<TOutput>): Promise<AsyncGenerator<CloudWebSearchStreamEvent<TOutput>>>;
31
+ subscribeToRichJob<TOutput = unknown>(jobId: string, options?: CloudWebSearchSubscribeOptions<TOutput>): Promise<AsyncGenerator<CloudWebSearchRichEvent<TOutput>>>;
32
+ waitForCompletion<TOutput = unknown>(jobId: string, options?: WaitForCompletionOptions<TOutput>): Promise<CloudWebSearchJobWaitResult<TOutput>>;
33
+ }