@absolutejs/absolute 0.19.0-beta.443 → 0.19.0-beta.445
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/ai/index.js +148 -7
- package/dist/ai/index.js.map +5 -4
- package/dist/ai-client/angular/ai/index.js +24 -0
- package/dist/angular/ai/index.js +25 -1
- package/dist/angular/ai/index.js.map +3 -3
- package/dist/angular/index.js +2 -2
- package/dist/angular/index.js.map +1 -1
- package/dist/angular/server.js +2 -2
- package/dist/angular/server.js.map +1 -1
- package/dist/build.js +2 -2
- package/dist/build.js.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/src/ai/rag/chat.d.ts +8 -8
- package/dist/src/ai/rag/htmxWorkflowRenderers.d.ts +3 -0
- package/dist/src/angular/ai/rag-client.service.d.ts +9 -1
- package/dist/types/ai.d.ts +26 -0
- package/package.json +1 -1
package/dist/ai/index.js
CHANGED
|
@@ -2467,6 +2467,85 @@ var createRAGCollection = (options) => {
|
|
|
2467
2467
|
};
|
|
2468
2468
|
};
|
|
2469
2469
|
|
|
2470
|
+
// src/ai/rag/htmxWorkflowRenderers.ts
|
|
2471
|
+
var escapeHtml2 = (text) => text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
2472
|
+
var renderEmptyState = (kind) => {
|
|
2473
|
+
switch (kind) {
|
|
2474
|
+
case "documents":
|
|
2475
|
+
return '<p class="rag-empty">No documents indexed.</p>';
|
|
2476
|
+
case "searchResults":
|
|
2477
|
+
return '<p class="rag-empty">No matching chunks.</p>';
|
|
2478
|
+
case "chunkPreview":
|
|
2479
|
+
return '<p class="rag-empty">No chunk preview available.</p>';
|
|
2480
|
+
case "status":
|
|
2481
|
+
default:
|
|
2482
|
+
return '<p class="rag-empty">No status available.</p>';
|
|
2483
|
+
}
|
|
2484
|
+
};
|
|
2485
|
+
var renderCapabilityList = (capabilities) => {
|
|
2486
|
+
if (!capabilities) {
|
|
2487
|
+
return "";
|
|
2488
|
+
}
|
|
2489
|
+
const items = [
|
|
2490
|
+
`backend=${capabilities.backend}`,
|
|
2491
|
+
`persistence=${capabilities.persistence}`,
|
|
2492
|
+
`nativeVectorSearch=${capabilities.nativeVectorSearch ? "true" : "false"}`,
|
|
2493
|
+
`serverSideFiltering=${capabilities.serverSideFiltering ? "true" : "false"}`,
|
|
2494
|
+
`streamingIngestStatus=${capabilities.streamingIngestStatus ? "true" : "false"}`
|
|
2495
|
+
];
|
|
2496
|
+
return '<ul class="rag-status-capabilities">' + items.map((item) => `<li>${escapeHtml2(item)}</li>`).join("") + "</ul>";
|
|
2497
|
+
};
|
|
2498
|
+
var defaultStatus = ({
|
|
2499
|
+
status,
|
|
2500
|
+
capabilities
|
|
2501
|
+
}) => {
|
|
2502
|
+
if (!status) {
|
|
2503
|
+
return renderEmptyState("status");
|
|
2504
|
+
}
|
|
2505
|
+
return '<dl class="rag-status">' + `<div><dt>Backend</dt><dd>${escapeHtml2(status.backend)}</dd></div>` + `<div><dt>Vector mode</dt><dd>${escapeHtml2(status.vectorMode)}</dd></div>` + `<div><dt>Embedding dimensions</dt><dd>${status.dimensions ?? "n/a"}</dd></div>` + `<div><dt>Vector acceleration</dt><dd>${status.native?.active ? "active" : "inactive"}</dd></div>` + "</dl>" + renderCapabilityList(capabilities);
|
|
2506
|
+
};
|
|
2507
|
+
var defaultSearchResultItem = (source, index) => '<article class="rag-search-result">' + `<h3>${escapeHtml2(source.title ?? source.chunkId ?? `Result ${index + 1}`)}</h3>` + `<p class="rag-search-source">${escapeHtml2(source.source ?? "unknown source")}</p>` + `<p class="rag-search-score">score ${source.score.toFixed(3)}</p>` + `<p class="rag-search-text">${escapeHtml2(source.text)}</p>` + "</article>";
|
|
2508
|
+
var defaultSearchResults = ({
|
|
2509
|
+
query,
|
|
2510
|
+
results
|
|
2511
|
+
}) => results.length === 0 ? renderEmptyState("searchResults") : '<section class="rag-search-results">' + `<p class="rag-search-summary">${results.length} results for ${escapeHtml2(query)}</p>` + results.map((result, index) => defaultSearchResultItem(result, index)).join("") + "</section>";
|
|
2512
|
+
var defaultDocumentItem = (document, index) => '<article class="rag-document">' + `<h3>${escapeHtml2(document.title || `Document ${index + 1}`)}</h3>` + `<p class="rag-document-id">${escapeHtml2(document.id)}</p>` + `<p class="rag-document-source">${escapeHtml2(document.source)}</p>` + `<p class="rag-document-meta">${escapeHtml2(document.format ?? "text")} \xB7 ${escapeHtml2(document.chunkStrategy ?? "paragraphs")} \xB7 ${document.chunkCount ?? 0} chunks</p>` + "</article>";
|
|
2513
|
+
var defaultDocuments = ({
|
|
2514
|
+
documents
|
|
2515
|
+
}) => documents.length === 0 ? renderEmptyState("documents") : '<section class="rag-documents">' + documents.map((document, index) => defaultDocumentItem(document, index)).join("") + "</section>";
|
|
2516
|
+
var defaultChunkPreview = (input) => '<section class="rag-chunk-preview">' + `<h3>${escapeHtml2(input.document.title)}</h3>` + `<p class="rag-chunk-preview-source">${escapeHtml2(input.document.source)}</p>` + '<article class="rag-chunk-normalized">' + "<h4>Normalized text</h4>" + `<pre>${escapeHtml2(input.normalizedText)}</pre>` + "</article>" + input.chunks.map((chunk) => '<article class="rag-chunk">' + `<h4>${escapeHtml2(chunk.chunkId)}</h4>` + `<p class="rag-chunk-meta">chunk ${chunk.metadata?.chunkIndex ?? 0} of ${chunk.metadata?.chunkCount ?? input.chunks.length}</p>` + `<pre>${escapeHtml2(chunk.text)}</pre>` + "</article>").join("") + "</section>";
|
|
2517
|
+
var defaultMutationResult = (input) => {
|
|
2518
|
+
if (!input.ok) {
|
|
2519
|
+
return `<div class="rag-mutation error">${escapeHtml2(input.error ?? "Request failed")}</div>`;
|
|
2520
|
+
}
|
|
2521
|
+
const details = [];
|
|
2522
|
+
if (input.status) {
|
|
2523
|
+
details.push(input.status);
|
|
2524
|
+
}
|
|
2525
|
+
if (input.inserted) {
|
|
2526
|
+
details.push(`inserted=${input.inserted}`);
|
|
2527
|
+
}
|
|
2528
|
+
if (input.deleted) {
|
|
2529
|
+
details.push(`deleted=${input.deleted}`);
|
|
2530
|
+
}
|
|
2531
|
+
if (typeof input.documents === "number") {
|
|
2532
|
+
details.push(`documents=${input.documents}`);
|
|
2533
|
+
}
|
|
2534
|
+
return `<div class="rag-mutation ok">${escapeHtml2(details.join(" \xB7 ") || "ok")}</div>`;
|
|
2535
|
+
};
|
|
2536
|
+
var defaultError2 = (message) => `<div class="rag-error">${escapeHtml2(message)}</div>`;
|
|
2537
|
+
var resolveRAGWorkflowRenderers = (custom) => ({
|
|
2538
|
+
status: custom?.status ?? defaultStatus,
|
|
2539
|
+
searchResults: custom?.searchResults ?? defaultSearchResults,
|
|
2540
|
+
searchResultItem: custom?.searchResultItem ?? defaultSearchResultItem,
|
|
2541
|
+
documents: custom?.documents ?? defaultDocuments,
|
|
2542
|
+
documentItem: custom?.documentItem ?? defaultDocumentItem,
|
|
2543
|
+
chunkPreview: custom?.chunkPreview ?? defaultChunkPreview,
|
|
2544
|
+
mutationResult: custom?.mutationResult ?? defaultMutationResult,
|
|
2545
|
+
emptyState: custom?.emptyState ?? renderEmptyState,
|
|
2546
|
+
error: custom?.error ?? defaultError2
|
|
2547
|
+
});
|
|
2548
|
+
|
|
2470
2549
|
// src/ai/rag/types.ts
|
|
2471
2550
|
var buildRAGContext = (hits) => {
|
|
2472
2551
|
if (hits.length === 0) {
|
|
@@ -2492,6 +2571,7 @@ var DEFAULT_TOP_K2 = 6;
|
|
|
2492
2571
|
var DEFAULT_PREFIX_LEN = 12;
|
|
2493
2572
|
var DEFAULT_PROVIDER = "anthropic";
|
|
2494
2573
|
var TITLE_MAX_LENGTH2 = 80;
|
|
2574
|
+
var HTML_HEADERS = { "Content-Type": "text/html; charset=utf-8" };
|
|
2495
2575
|
var defaultParseProvider2 = (content) => {
|
|
2496
2576
|
const colonIdx = content.indexOf(":");
|
|
2497
2577
|
const hasPrefix = colonIdx > 0 && colonIdx < DEFAULT_PREFIX_LEN;
|
|
@@ -2502,6 +2582,7 @@ var defaultParseProvider2 = (content) => {
|
|
|
2502
2582
|
};
|
|
2503
2583
|
};
|
|
2504
2584
|
var normalizeScore = (value) => Number.isFinite(value) ? value : 0;
|
|
2585
|
+
var isHTMXRequest = (request) => request.headers.get("HX-Request") === "true";
|
|
2505
2586
|
var buildSources = (results) => results.map((result) => ({
|
|
2506
2587
|
chunkId: result.chunkId,
|
|
2507
2588
|
score: normalizeScore(result.score),
|
|
@@ -2619,6 +2700,11 @@ var ragChat = (config) => {
|
|
|
2619
2700
|
const abortControllers = new Map;
|
|
2620
2701
|
const includeCompleteSources = config.ragCompleteSources === true;
|
|
2621
2702
|
const indexManager = config.indexManager;
|
|
2703
|
+
const workflowRenderers = resolveRAGWorkflowRenderers(typeof config.htmx === "object" ? config.htmx.workflow?.render : undefined);
|
|
2704
|
+
const toHTMXResponse = (html, status) => new Response(html, {
|
|
2705
|
+
headers: HTML_HEADERS,
|
|
2706
|
+
status: typeof status === "number" ? status : 200
|
|
2707
|
+
});
|
|
2622
2708
|
const appendMessage2 = (conversation, message) => {
|
|
2623
2709
|
conversation.messages.push(message);
|
|
2624
2710
|
conversation.lastMessageAt = Date.now();
|
|
@@ -3008,23 +3094,66 @@ var ragChat = (config) => {
|
|
|
3008
3094
|
await handleMessage(ws, msg.content, msg.conversationId, msg.attachments);
|
|
3009
3095
|
}
|
|
3010
3096
|
}
|
|
3011
|
-
}).post(`${path}/search`, async ({ body
|
|
3097
|
+
}).post(`${path}/search`, async ({ body, request, set }) => {
|
|
3098
|
+
const result = await handleSearch(body);
|
|
3099
|
+
if (!result.ok) {
|
|
3100
|
+
set.status = result.error === "Invalid payload" || result.error?.startsWith("Expected payload shape:") ? 400 : 404;
|
|
3101
|
+
}
|
|
3102
|
+
if (config.htmx && isHTMXRequest(request)) {
|
|
3103
|
+
if (!result.ok) {
|
|
3104
|
+
return toHTMXResponse(workflowRenderers.error(result.error ?? "Search failed"), set.status);
|
|
3105
|
+
}
|
|
3106
|
+
const query = body && typeof body === "object" && typeof body.query === "string" ? body.query : "";
|
|
3107
|
+
return toHTMXResponse(workflowRenderers.searchResults({
|
|
3108
|
+
query,
|
|
3109
|
+
results: result.results ?? []
|
|
3110
|
+
}));
|
|
3111
|
+
}
|
|
3112
|
+
return result;
|
|
3113
|
+
}).get(`${path}/status`, ({ request }) => {
|
|
3114
|
+
const result = handleStatus();
|
|
3115
|
+
if (config.htmx && isHTMXRequest(request)) {
|
|
3116
|
+
return toHTMXResponse(workflowRenderers.status({
|
|
3117
|
+
capabilities: result.capabilities,
|
|
3118
|
+
status: result.status
|
|
3119
|
+
}));
|
|
3120
|
+
}
|
|
3121
|
+
return result;
|
|
3122
|
+
}).get(`${path}/documents`, async ({ query, request, set }) => {
|
|
3012
3123
|
const result = await handleDocuments(typeof query?.kind === "string" ? query.kind : undefined);
|
|
3013
3124
|
if (!result.ok) {
|
|
3014
3125
|
set.status = 404;
|
|
3015
3126
|
}
|
|
3127
|
+
if (config.htmx && isHTMXRequest(request)) {
|
|
3128
|
+
if (!result.ok) {
|
|
3129
|
+
return toHTMXResponse(workflowRenderers.error(result.error), set.status);
|
|
3130
|
+
}
|
|
3131
|
+
return toHTMXResponse(workflowRenderers.documents({
|
|
3132
|
+
documents: result.documents
|
|
3133
|
+
}));
|
|
3134
|
+
}
|
|
3016
3135
|
return result;
|
|
3017
|
-
}).post(`${path}/documents`, async ({ body, set }) => {
|
|
3136
|
+
}).post(`${path}/documents`, async ({ body, request, set }) => {
|
|
3018
3137
|
const result = await handleCreateDocument(body);
|
|
3019
3138
|
if (!result.ok) {
|
|
3020
3139
|
set.status = result.error === "Invalid payload" ? 400 : result.error?.includes("not configured") ? 404 : 400;
|
|
3021
3140
|
}
|
|
3141
|
+
if (config.htmx && isHTMXRequest(request)) {
|
|
3142
|
+
const html = result.ok ? workflowRenderers.mutationResult(result) : workflowRenderers.error(result.error ?? "Failed to create document");
|
|
3143
|
+
return toHTMXResponse(html, set.status);
|
|
3144
|
+
}
|
|
3022
3145
|
return result;
|
|
3023
|
-
}).get(`${path}/documents/:id/chunks`, async ({ params, set }) => {
|
|
3146
|
+
}).get(`${path}/documents/:id/chunks`, async ({ params, request, set }) => {
|
|
3024
3147
|
const result = await handleDocumentChunks(typeof params.id === "string" ? params.id.trim() : "");
|
|
3025
3148
|
if (!result.ok) {
|
|
3026
3149
|
set.status = result.error === "document id is required" ? 400 : result.error === "document not found" ? 404 : 404;
|
|
3027
3150
|
}
|
|
3151
|
+
if (config.htmx && isHTMXRequest(request)) {
|
|
3152
|
+
if (!result.ok) {
|
|
3153
|
+
return toHTMXResponse(workflowRenderers.error(result.error), set.status);
|
|
3154
|
+
}
|
|
3155
|
+
return toHTMXResponse(workflowRenderers.chunkPreview(result));
|
|
3156
|
+
}
|
|
3028
3157
|
return result;
|
|
3029
3158
|
}).get(`${path}/backends`, async ({ set }) => {
|
|
3030
3159
|
const result = await handleBackends();
|
|
@@ -3038,23 +3167,35 @@ var ragChat = (config) => {
|
|
|
3038
3167
|
}
|
|
3039
3168
|
await ragStore.clear?.();
|
|
3040
3169
|
return { ok: true };
|
|
3041
|
-
}).delete(`${path}/documents/:id`, async ({ params, set }) => {
|
|
3170
|
+
}).delete(`${path}/documents/:id`, async ({ params, request, set }) => {
|
|
3042
3171
|
const result = await handleDeleteDocument(typeof params.id === "string" ? params.id.trim() : "");
|
|
3043
3172
|
if (!result.ok) {
|
|
3044
3173
|
set.status = result.error === "document id is required" ? 400 : result.error === "document not found" ? 404 : 404;
|
|
3045
3174
|
}
|
|
3175
|
+
if (config.htmx && isHTMXRequest(request)) {
|
|
3176
|
+
const html = result.ok ? workflowRenderers.mutationResult(result) : workflowRenderers.error(result.error ?? "Failed to delete document");
|
|
3177
|
+
return toHTMXResponse(html, set.status);
|
|
3178
|
+
}
|
|
3046
3179
|
return result;
|
|
3047
|
-
}).post(`${path}/reseed`, async ({ set }) => {
|
|
3180
|
+
}).post(`${path}/reseed`, async ({ request, set }) => {
|
|
3048
3181
|
const result = await handleReseed();
|
|
3049
3182
|
if (!result.ok) {
|
|
3050
3183
|
set.status = 404;
|
|
3051
3184
|
}
|
|
3185
|
+
if (config.htmx && isHTMXRequest(request)) {
|
|
3186
|
+
const html = result.ok ? workflowRenderers.mutationResult(result) : workflowRenderers.error(result.error ?? "Failed to reseed index");
|
|
3187
|
+
return toHTMXResponse(html, set.status);
|
|
3188
|
+
}
|
|
3052
3189
|
return result;
|
|
3053
|
-
}).post(`${path}/reset`, async ({ set }) => {
|
|
3190
|
+
}).post(`${path}/reset`, async ({ request, set }) => {
|
|
3054
3191
|
const result = await handleReset();
|
|
3055
3192
|
if (!result.ok) {
|
|
3056
3193
|
set.status = 404;
|
|
3057
3194
|
}
|
|
3195
|
+
if (config.htmx && isHTMXRequest(request)) {
|
|
3196
|
+
const html = result.ok ? workflowRenderers.mutationResult(result) : workflowRenderers.error(result.error ?? "Failed to reset index");
|
|
3197
|
+
return toHTMXResponse(html, set.status);
|
|
3198
|
+
}
|
|
3058
3199
|
return result;
|
|
3059
3200
|
}).get(`${path}/conversations`, () => store.list()).get(`${path}/conversations/:id`, async ({ params }) => {
|
|
3060
3201
|
const conv = await store.get(params.id);
|
|
@@ -4166,5 +4307,5 @@ export {
|
|
|
4166
4307
|
aiChat
|
|
4167
4308
|
};
|
|
4168
4309
|
|
|
4169
|
-
//# debugId=
|
|
4310
|
+
//# debugId=1CB9D35FC2D88FAA64756E2164756E21
|
|
4170
4311
|
//# sourceMappingURL=index.js.map
|