Fresh history cut from cynarAI/evoo antigravity-handoff/project-timeline (Voice First + project timeline). Brand docs/titles as evOo; keep @rakazo/* packages as tech debt. Excludes node_modules, caches, secrets, voice blobs.
59 lines
1.6 KiB
TypeScript
59 lines
1.6 KiB
TypeScript
import type {
|
|
AdapterContext,
|
|
WebFetchRequest,
|
|
WebFetchResult,
|
|
WebProvider,
|
|
WebSearchHit,
|
|
WebSearchRequest,
|
|
} from "@rakazo/adapter-kit";
|
|
|
|
/** In-memory web provider for offline tests. Never hits the network. */
|
|
export class FakeWebProvider implements WebProvider {
|
|
searchHits: WebSearchHit[] = [];
|
|
fetchResult: WebFetchResult = {
|
|
url: "https://example.test/page",
|
|
title: "Example",
|
|
text: "Hello from fake web",
|
|
truncated: false,
|
|
};
|
|
lastSearch?: WebSearchRequest;
|
|
lastFetch?: WebFetchRequest;
|
|
searchError?: Error;
|
|
fetchError?: Error;
|
|
|
|
describe() {
|
|
return {
|
|
id: "fake",
|
|
contractVersion: "1",
|
|
adapterVersion: "0.1.0",
|
|
capabilities: {
|
|
search: true,
|
|
fetch: true,
|
|
keyless: true,
|
|
native: false,
|
|
readability: true,
|
|
},
|
|
};
|
|
}
|
|
|
|
async search(request: WebSearchRequest, _context: AdapterContext): Promise<WebSearchHit[]> {
|
|
this.lastSearch = request;
|
|
if (this.searchError) throw this.searchError;
|
|
const limit = request.maxResults ?? this.searchHits.length;
|
|
return this.searchHits.slice(0, limit);
|
|
}
|
|
|
|
async fetch(request: WebFetchRequest, _context: AdapterContext): Promise<WebFetchResult> {
|
|
this.lastFetch = request;
|
|
if (this.fetchError) throw this.fetchError;
|
|
const maxChars = request.maxChars ?? this.fetchResult.text.length;
|
|
const truncated = this.fetchResult.text.length > maxChars;
|
|
return {
|
|
...this.fetchResult,
|
|
url: request.url || this.fetchResult.url,
|
|
text: truncated ? this.fetchResult.text.slice(0, maxChars) : this.fetchResult.text,
|
|
truncated: truncated || this.fetchResult.truncated,
|
|
};
|
|
}
|
|
}
|