@absolutejs/ai 0.2.7 → 0.2.9
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 +12 -0
- package/changelog.json +38 -0
- package/dist/ai/index.js +8 -1
- package/dist/ai/index.js.map +3 -3
- package/dist/ai/models/index.js +344 -28
- package/dist/ai/models/index.js.map +7 -6
- package/dist/ai/providers/anthropic.js +8 -1
- package/dist/ai/providers/anthropic.js.map +3 -3
- package/dist/ai/providers/gemini.js +8 -1
- package/dist/ai/providers/gemini.js.map +3 -3
- package/dist/ai/providers/openai.js +8 -1
- package/dist/ai/providers/openai.js.map +3 -3
- package/dist/ai/providers/openaiCompatible.js +8 -1
- package/dist/ai/providers/openaiCompatible.js.map +3 -3
- package/dist/ai/providers/openaiResponses.js +8 -1
- package/dist/ai/providers/openaiResponses.js.map +3 -3
- package/dist/ai/providers/openrouter.js +8 -1
- package/dist/ai/providers/openrouter.js.map +3 -3
- package/dist/ai/research.js.map +2 -2
- package/dist/src/ai/models/catalog.d.ts +2 -1
- package/dist/src/ai/models/directory.d.ts +58 -0
- package/dist/src/ai/models/index.d.ts +1 -0
- package/dist/src/ai/models/reasoning.d.ts +2 -1
- package/package.json +1 -1
package/dist/ai/research.js.map
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/ai/research.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import {\n boundedQueries,\n evidenceText,\n sourceSupportsQuote,\n type SearchProvider,\n type SearchResult,\n type SearchSource,\n} from \"@absolutejs/search\";\nexport type ResearchFinding = {\n claim: string;\n sourceId: string;\n quote: string;\n eventDate?: string;\n};\nexport type ResearchEvidence = {\n status: \"grounded\" | \"partial\" | \"empty\" | \"unavailable\";\n text: string;\n findings: ResearchFinding[];\n sources: SearchSource[];\n searches: SearchResult[];\n limitations: string[];\n generatedAt: string;\n};\nexport type ResearchSynthesis = {\n findings: ResearchFinding[];\n limitations?: string[];\n};\n/** Retrieval and synthesis are separate injected capabilities. No hosted search is enabled here. */\nexport const researchWithEvidence = async (input: {\n query: string;\n queries?: string[];\n provider: SearchProvider;\n signal?: AbortSignal;\n maxQueries?: number;\n maxTokens?: number;\n freshness?: string;\n /** Required literal entity phrases; defaults to quoted phrases in the question. */\n requiredPhrases?: string[];\n synthesize: (\n evidence: string,\n signal?: AbortSignal,\n ) => Promise<ResearchSynthesis>;\n}): Promise<ResearchEvidence> => {\n const requested = input.queries ?? boundedQueries(input.query);\n const maxQueries = input.maxQueries ?? 2;\n if (!Number.isInteger(maxQueries) || maxQueries < 1)\n throw new Error(\"Research requires a positive query budget\");\n const searches: SearchResult[] = [];\n const limitations: string[] = [];\n const generatedAt = new Date().toISOString();\n if (requested.length > maxQueries)\n limitations.push(\n \"Query budget reached; some requested research was not performed\",\n );\n for (const query of requested.slice(0, maxQueries)) {\n input.signal?.throwIfAborted();\n searches.push(\n await input.provider.search({\n query,\n mode: \"context\",\n signal: input.signal,\n maxTokens: input.maxTokens ?? 4096,\n freshness: input.freshness,\n }),\n );\n }\n input.signal?.throwIfAborted();\n const byUrl = new Map<string, SearchSource>();\n for (const search of searches) {\n limitations.push(...search.limitations);\n for (const source of search.sources) {\n const previous = byUrl.get(source.url);\n byUrl.set(\n source.url,\n previous\n ? {\n ...previous,\n excerpts: [\n ...new Set([...previous.excerpts, ...source.excerpts]),\n ],\n }\n : source,\n );\n }\n }\n const normalize = (value:string)
|
|
5
|
+
"import {\n boundedQueries,\n evidenceText,\n sourceSupportsQuote,\n type SearchProvider,\n type SearchResult,\n type SearchSource,\n} from \"@absolutejs/search\";\nexport type ResearchFinding = {\n claim: string;\n sourceId: string;\n quote: string;\n eventDate?: string;\n};\nexport type ResearchEvidence = {\n status: \"grounded\" | \"partial\" | \"empty\" | \"unavailable\";\n text: string;\n findings: ResearchFinding[];\n sources: SearchSource[];\n searches: SearchResult[];\n limitations: string[];\n generatedAt: string;\n};\nexport type ResearchSynthesis = {\n findings: ResearchFinding[];\n limitations?: string[];\n};\n/** Retrieval and synthesis are separate injected capabilities. No hosted search is enabled here. */\nexport const researchWithEvidence = async (input: {\n query: string;\n queries?: string[];\n provider: SearchProvider;\n signal?: AbortSignal;\n maxQueries?: number;\n maxTokens?: number;\n freshness?: string;\n /** Required literal entity phrases; defaults to quoted phrases in the question. */\n requiredPhrases?: string[];\n synthesize: (\n evidence: string,\n signal?: AbortSignal,\n ) => Promise<ResearchSynthesis>;\n}): Promise<ResearchEvidence> => {\n const requested = input.queries ?? boundedQueries(input.query);\n const maxQueries = input.maxQueries ?? 2;\n if (!Number.isInteger(maxQueries) || maxQueries < 1)\n throw new Error(\"Research requires a positive query budget\");\n const searches: SearchResult[] = [];\n const limitations: string[] = [];\n const generatedAt = new Date().toISOString();\n if (requested.length > maxQueries)\n limitations.push(\n \"Query budget reached; some requested research was not performed\",\n );\n for (const query of requested.slice(0, maxQueries)) {\n input.signal?.throwIfAborted();\n searches.push(\n await input.provider.search({\n query,\n mode: \"context\",\n signal: input.signal,\n maxTokens: input.maxTokens ?? 4096,\n freshness: input.freshness,\n }),\n );\n }\n input.signal?.throwIfAborted();\n const byUrl = new Map<string, SearchSource>();\n for (const search of searches) {\n limitations.push(...search.limitations);\n for (const source of search.sources) {\n const previous = byUrl.get(source.url);\n byUrl.set(\n source.url,\n previous\n ? {\n ...previous,\n excerpts: [\n ...new Set([...previous.excerpts, ...source.excerpts]),\n ],\n }\n : source,\n );\n }\n }\n const normalize = (value: string) =>\n value.normalize(\"NFKC\").toLowerCase().replace(/\\s+/gu, \" \").trim();\n const requiredPhrases =\n input.requiredPhrases ??\n [...input.query.matchAll(/\"([^\"\\n]+)\"/gu)].map((match) => match[1]!);\n const sources = [...byUrl.values()].filter((source) =>\n requiredPhrases.every((phrase) =>\n normalize(`${source.title} ${source.excerpts.join(\" \")}`).includes(\n normalize(phrase),\n ),\n ),\n );\n if (sources.length < byUrl.size)\n limitations.push(\n \"Sources that did not establish the required literal entity were excluded; similarly named entities are not substitutes.\",\n );\n const complete =\n searches.length > 0 &&\n searches.every(\n (search) => search.status === \"ok\" || search.status === \"empty\",\n ) &&\n requested.length <= maxQueries;\n const base = { searches, sources, limitations, generatedAt };\n if (!sources.length)\n return {\n ...base,\n status: complete ? \"empty\" : \"unavailable\",\n text: \"\",\n findings: [],\n };\n input.signal?.throwIfAborted();\n const synthesis = await input.synthesize(evidenceText(sources), input.signal);\n const findings = synthesis.findings.filter((finding) => {\n const source = sources.find((source) => source.id === finding.sourceId);\n return (\n typeof finding.claim === \"string\" &&\n Boolean(finding.claim.trim()) &&\n typeof finding.quote === \"string\" &&\n source &&\n sourceSupportsQuote(source, finding.quote)\n );\n });\n if (findings.length !== synthesis.findings.length)\n limitations.push(\n \"Unsupported source references or quotations were excluded\",\n );\n limitations.push(...(synthesis.limitations ?? []));\n const text = findings\n .map(\n (finding) =>\n `${finding.claim}\\nEvidence: ${finding.quote}\\nSource: ${sources.find((source) => source.id === finding.sourceId)!.url}`,\n )\n .join(\"\\n\\n\");\n // Quotation/source checks establish provenance, not semantic entailment. Host review remains necessary.\n return {\n ...base,\n status:\n complete && findings.length > 0 && !limitations.length\n ? \"grounded\"\n : \"partial\",\n text,\n findings,\n };\n};\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": ";;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA4BO,IAAM,uBAAuB,OAAO,UAcV;AAAA,EAC/B,MAAM,YAAY,MAAM,WAAW,eAAe,MAAM,KAAK;AAAA,EAC7D,MAAM,aAAa,MAAM,cAAc;AAAA,EACvC,IAAI,CAAC,OAAO,UAAU,UAAU,KAAK,aAAa;AAAA,IAChD,MAAM,IAAI,MAAM,2CAA2C;AAAA,EAC7D,MAAM,WAA2B,CAAC;AAAA,EAClC,MAAM,cAAwB,CAAC;AAAA,EAC/B,MAAM,cAAc,IAAI,KAAK,EAAE,YAAY;AAAA,EAC3C,IAAI,UAAU,SAAS;AAAA,IACrB,YAAY,KACV,iEACF;AAAA,EACF,WAAW,SAAS,UAAU,MAAM,GAAG,UAAU,GAAG;AAAA,IAClD,MAAM,QAAQ,eAAe;AAAA,IAC7B,SAAS,KACP,MAAM,MAAM,SAAS,OAAO;AAAA,MAC1B;AAAA,MACA,MAAM;AAAA,MACN,QAAQ,MAAM;AAAA,MACd,WAAW,MAAM,aAAa;AAAA,MAC9B,WAAW,MAAM;AAAA,IACnB,CAAC,CACH;AAAA,EACF;AAAA,EACA,MAAM,QAAQ,eAAe;AAAA,EAC7B,MAAM,QAAQ,IAAI;AAAA,EAClB,WAAW,UAAU,UAAU;AAAA,IAC7B,YAAY,KAAK,GAAG,OAAO,WAAW;AAAA,IACtC,WAAW,UAAU,OAAO,SAAS;AAAA,MACnC,MAAM,WAAW,MAAM,IAAI,OAAO,GAAG;AAAA,MACrC,MAAM,IACJ,OAAO,KACP,WACI;AAAA,WACK;AAAA,QACH,UAAU;AAAA,UACR,GAAG,IAAI,IAAI,CAAC,GAAG,SAAS,UAAU,GAAG,OAAO,QAAQ,CAAC;AAAA,QACvD;AAAA,MACF,IACA,MACN;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,YAAY,CAAC,
|
|
7
|
+
"mappings": "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",
|
|
8
8
|
"debugId": "0CBE93DA058E304664756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ModelMetadata } from "./index";
|
|
2
|
-
/** Reviewed provider support, independent of application feature availability.
|
|
2
|
+
/** Reviewed provider support, independent of application feature availability.
|
|
3
|
+
* Anthropic entries come from the Models API (`max_input_tokens`, `capabilities`). */
|
|
3
4
|
export declare const MODEL_METADATA: Readonly<Record<string, ModelMetadata>>;
|
|
4
5
|
export declare const getModelMetadata: (provider: string, id: string) => ModelMetadata | undefined;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { modelCapabilities } from "./index";
|
|
2
|
+
/** Display names for the providers the directory covers. */
|
|
3
|
+
export declare const MODEL_PROVIDERS: Readonly<Record<string, string>>;
|
|
4
|
+
export type ModelTier = "frontier" | "balanced" | "fast";
|
|
5
|
+
export type ModelDirectoryEntry = {
|
|
6
|
+
provider: string;
|
|
7
|
+
/** The exact model ID sent to the provider. */
|
|
8
|
+
id: string;
|
|
9
|
+
name: string;
|
|
10
|
+
/** One short, plain sentence for pickers. */
|
|
11
|
+
description: string;
|
|
12
|
+
/** The provider's current frontier model; at most one per provider. */
|
|
13
|
+
featured?: boolean;
|
|
14
|
+
/** Relative capability within the provider's current line, for recommendations. */
|
|
15
|
+
tier?: ModelTier;
|
|
16
|
+
/** Superseded by a newer model in the same line; hide by default. */
|
|
17
|
+
legacy?: boolean;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Human-facing model directory for pickers, newest first within each provider.
|
|
21
|
+
* Capabilities and context windows come from MODEL_METADATA, not from here.
|
|
22
|
+
* Anthropic entries were checked against the Models API on 2026-09-25.
|
|
23
|
+
*/
|
|
24
|
+
export declare const MODEL_DIRECTORY: readonly ModelDirectoryEntry[];
|
|
25
|
+
export declare const modelKey: (model: {
|
|
26
|
+
provider: string;
|
|
27
|
+
id: string;
|
|
28
|
+
}) => string;
|
|
29
|
+
export type ListedModel = ModelDirectoryEntry & {
|
|
30
|
+
key: string;
|
|
31
|
+
providerName: string;
|
|
32
|
+
capabilities: ReturnType<typeof modelCapabilities>;
|
|
33
|
+
contextWindow: number | null;
|
|
34
|
+
reasoningEfforts: readonly string[];
|
|
35
|
+
};
|
|
36
|
+
/** Directory entries joined with reviewed metadata, ready for a picker. */
|
|
37
|
+
export declare const listModels: (options?: {
|
|
38
|
+
providers?: readonly string[];
|
|
39
|
+
includeLegacy?: boolean;
|
|
40
|
+
}) => ListedModel[];
|
|
41
|
+
export declare const findModel: (provider: string, id: string) => ModelDirectoryEntry | undefined;
|
|
42
|
+
/** Chooses a tier from the request text: quick edits and simple questions are
|
|
43
|
+
* fast, deep analysis or very long requests are frontier, everything else is
|
|
44
|
+
* balanced. `depth: "deep"` forces frontier. Adapted from AbsoluteJS PAAS. */
|
|
45
|
+
export declare const recommendTier: (input: {
|
|
46
|
+
message: string;
|
|
47
|
+
depth?: "auto" | "deep";
|
|
48
|
+
}) => ModelTier;
|
|
49
|
+
/** Picks a current model for a request from the first listed provider that
|
|
50
|
+
* has one at the recommended tier. Providers are in preference order and
|
|
51
|
+
* should only include ones the application can call. */
|
|
52
|
+
export declare const recommendModel: (input: {
|
|
53
|
+
message: string;
|
|
54
|
+
providers: readonly string[];
|
|
55
|
+
depth?: "auto" | "deep";
|
|
56
|
+
}) => (ModelDirectoryEntry & {
|
|
57
|
+
tier: ModelTier;
|
|
58
|
+
}) | undefined;
|
|
@@ -30,3 +30,4 @@ export type ModelCapability = keyof typeof MODEL_CAPABILITY_DESCRIPTIONS;
|
|
|
30
30
|
export declare const modelCapabilities: (metadata?: ModelMetadata) => ModelCapability[];
|
|
31
31
|
export { MODEL_METADATA, getModelMetadata } from "./catalog";
|
|
32
32
|
export { MODEL_REASONING, REASONING_EFFORTS, getModelReasoning, isReasoningSelection, supportsReasoningSelection, reasoningSelectionLabel, type ModelReasoning, type ReasoningSelection, } from "./reasoning";
|
|
33
|
+
export { MODEL_DIRECTORY, MODEL_PROVIDERS, findModel, listModels, modelKey, recommendModel, recommendTier, type ListedModel, type ModelDirectoryEntry, type ModelTier, } from "./directory";
|
|
@@ -8,7 +8,8 @@ export type ModelReasoning = {
|
|
|
8
8
|
source: string;
|
|
9
9
|
};
|
|
10
10
|
export declare const isReasoningSelection: (value: unknown) => value is ReasoningSelection;
|
|
11
|
-
/** Exact reviewed IDs; unknown models expose only the provider default. Reviewed 2026-09-20
|
|
11
|
+
/** Exact reviewed IDs; unknown models expose only the provider default. Reviewed 2026-09-20;
|
|
12
|
+
* Anthropic effort levels re-checked against the Models API 2026-09-25. */
|
|
12
13
|
export declare const MODEL_REASONING: Readonly<Record<string, ModelReasoning>>;
|
|
13
14
|
export declare const getModelReasoning: (provider: string, model: string) => ModelReasoning | undefined;
|
|
14
15
|
export declare const supportsReasoningSelection: (provider: string, model: string, selection: ReasoningSelection) => boolean;
|