@m6d/cortex-cli 0.11.0 → 0.12.1
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/package.json +1 -1
- package/src/contracts/charts/chart-spec.ts +11 -1
- package/src/contracts/graph/clients/embed.ts +18 -1
- package/src/contracts/graph/index.ts +1 -1
- package/src/contracts/markdown/index.ts +11 -3
- package/src/contracts/runtime/api.ts +7 -0
- package/src/contracts/runtime/grammar.ts +8 -1
- package/src/contracts/wire/index.ts +11 -0
- package/src/scaffold/files.ts +1 -1
package/package.json
CHANGED
|
@@ -168,6 +168,7 @@ const OTHER_IMAGE_FUNCTION_GLOBAL = new RegExp(
|
|
|
168
168
|
"gi",
|
|
169
169
|
);
|
|
170
170
|
const CSS_ESCAPE = /\\([0-9a-f]{1,6})\s?|\\(.)/gi;
|
|
171
|
+
const IMPORT_RULE = /@import[^;]*;?/gi;
|
|
171
172
|
|
|
172
173
|
/** Style text with its CSS escapes decoded, so a url() hidden behind one reads as itself. */
|
|
173
174
|
function decodeCssEscapes(text: string) {
|
|
@@ -197,9 +198,18 @@ export function externalResourceIn(value: string) {
|
|
|
197
198
|
return false;
|
|
198
199
|
}
|
|
199
200
|
|
|
200
|
-
/**
|
|
201
|
+
/**
|
|
202
|
+
* Style text with every resource-loading function neutralized: CSS escapes
|
|
203
|
+
* decoded first, url() kept only to fragments. A backslash left after the one
|
|
204
|
+
* decode would be a second escape layer the browser decodes again, and an
|
|
205
|
+
* @import may name its target as a bare string, so both are dropped. Each
|
|
206
|
+
* leaves a space behind, so the text around a removal cannot join into a
|
|
207
|
+
* new one.
|
|
208
|
+
*/
|
|
201
209
|
export function scrubStyleText(text: string) {
|
|
202
210
|
return decodeCssEscapes(text)
|
|
211
|
+
.replaceAll("\\", " ")
|
|
212
|
+
.replace(IMPORT_RULE, " ")
|
|
203
213
|
.replace(OTHER_IMAGE_FUNCTION_GLOBAL, "none")
|
|
204
214
|
.replace(URL_FUNCTION, (match, argument: string) =>
|
|
205
215
|
urlTarget(argument).startsWith("#") ? match : "none",
|
|
@@ -17,10 +17,17 @@ export type EmbeddingProviderConfig = {
|
|
|
17
17
|
/** Turns a batch of strings into their vectors, in the order given. */
|
|
18
18
|
export type EmbedFn = (values: string[]) => Promise<number[][]>;
|
|
19
19
|
|
|
20
|
+
/**
|
|
21
|
+
* The most inputs one embeddings request carries. Text Embeddings Inference
|
|
22
|
+
* refuses more than 32 by default; providers that allow larger batches just
|
|
23
|
+
* take more requests.
|
|
24
|
+
*/
|
|
25
|
+
export const EMBEDDING_MAX_BATCH_SIZE = 32;
|
|
26
|
+
|
|
20
27
|
export function createEmbedder(config: EmbeddingProviderConfig) {
|
|
21
28
|
const url = `${config.baseURL.replace(/\/+$/, "")}/embeddings`;
|
|
22
29
|
|
|
23
|
-
|
|
30
|
+
async function embedBatch(values: string[]) {
|
|
24
31
|
const response = await fetch(url, {
|
|
25
32
|
method: "POST",
|
|
26
33
|
headers: {
|
|
@@ -41,5 +48,15 @@ export function createEmbedder(config: EmbeddingProviderConfig) {
|
|
|
41
48
|
return [...body.data]
|
|
42
49
|
.sort((left, right) => left.index - right.index)
|
|
43
50
|
.map((entry) => entry.embedding);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return async function embed(values: string[]) {
|
|
54
|
+
const embeddings: number[][] = [];
|
|
55
|
+
for (let index = 0; index < values.length; index += EMBEDDING_MAX_BATCH_SIZE) {
|
|
56
|
+
embeddings.push(
|
|
57
|
+
...(await embedBatch(values.slice(index, index + EMBEDDING_MAX_BATCH_SIZE))),
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
return embeddings;
|
|
44
61
|
};
|
|
45
62
|
}
|
|
@@ -27,4 +27,4 @@ export type { Neo4jConfig, Neo4jClient, Neo4jRow } from "./clients/neo4j";
|
|
|
27
27
|
export { createNeo4jClient, Neo4jQueryError } from "./clients/neo4j";
|
|
28
28
|
|
|
29
29
|
export type { EmbedFn, EmbeddingProviderConfig } from "./clients/embed";
|
|
30
|
-
export { createEmbedder } from "./clients/embed";
|
|
30
|
+
export { createEmbedder, EMBEDDING_MAX_BATCH_SIZE } from "./clients/embed";
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* CommonMark fence tracking shared by the prompt rich-text pipeline
|
|
3
|
-
* widget's streamed-message segmenter.
|
|
2
|
+
* CommonMark fence tracking shared by the prompt rich-text pipeline, the
|
|
3
|
+
* widget's streamed-message segmenter, and the server's report stand-ins.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
/** A fence delimiter of three or more backticks or tildes, indented at most three spaces, and the rest of its line. */
|
|
7
|
+
const FENCE_LINE = /^ {0,3}(`{3,}|~{3,})(.*)$/;
|
|
8
|
+
|
|
6
9
|
/**
|
|
7
10
|
* Line-by-line fence state, following CommonMark's fence rules: a fence line
|
|
8
11
|
* is indented at most three spaces; an opening backtick fence's info string
|
|
@@ -14,7 +17,7 @@
|
|
|
14
17
|
export function fenceTracker() {
|
|
15
18
|
let fence: { marker: string; length: number } | null = null;
|
|
16
19
|
return (line: string) => {
|
|
17
|
-
const match =
|
|
20
|
+
const match = FENCE_LINE.exec(line);
|
|
18
21
|
const delimiter = match?.[1];
|
|
19
22
|
const rest = match?.[2] ?? "";
|
|
20
23
|
if (delimiter) {
|
|
@@ -37,3 +40,8 @@ export function fenceTracker() {
|
|
|
37
40
|
return fence ? "inside" : "outside";
|
|
38
41
|
};
|
|
39
42
|
}
|
|
43
|
+
|
|
44
|
+
/** An opening fence line's language: the info string's first word, "" when there is none. */
|
|
45
|
+
export function fenceLanguage(line: string) {
|
|
46
|
+
return FENCE_LINE.exec(line)?.[2]?.trim().split(/\s+/)[0] ?? "";
|
|
47
|
+
}
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
IDENTIFIER_PATTERN,
|
|
8
8
|
localeSchema,
|
|
9
9
|
localizedTextSchema,
|
|
10
|
+
mediaFormSchema,
|
|
10
11
|
mentionedToolSchema,
|
|
11
12
|
slugSchema,
|
|
12
13
|
suggestionsSchema,
|
|
@@ -196,6 +197,12 @@ export const runtimeAgentConfigSchema = z.object({
|
|
|
196
197
|
* attachments stay downloadable and deletable.
|
|
197
198
|
*/
|
|
198
199
|
attachmentsEnabled: z.boolean(),
|
|
200
|
+
/**
|
|
201
|
+
* The media forms the agent may draw, which its prompt then describes.
|
|
202
|
+
* Operational like `attachmentsEnabled`: toggling applies without
|
|
203
|
+
* republishing.
|
|
204
|
+
*/
|
|
205
|
+
media: z.array(mediaFormSchema),
|
|
199
206
|
metaTools: z.object({
|
|
200
207
|
searchKnowledge: z.boolean(),
|
|
201
208
|
searchTools: z.boolean(),
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
LOCALES,
|
|
4
|
+
MEDIA_FORMS,
|
|
5
|
+
TOOL_SURFACES,
|
|
6
|
+
type Greeting,
|
|
7
|
+
type Suggestions,
|
|
8
|
+
} from "../wire/index";
|
|
3
9
|
|
|
4
10
|
/*
|
|
5
11
|
* The grammar both sides of the runtime API share: identifier patterns, the
|
|
@@ -23,6 +29,7 @@ export const slugSchema = z.string().regex(SLUG_PATTERN).max(64);
|
|
|
23
29
|
|
|
24
30
|
export const localeSchema = z.enum(LOCALES);
|
|
25
31
|
export const toolSurfaceSchema = z.enum(TOOL_SURFACES);
|
|
32
|
+
export const mediaFormSchema = z.enum(MEDIA_FORMS);
|
|
26
33
|
export const catalogVersionSchema = z.string().regex(/^[0-9a-f]{16}$/);
|
|
27
34
|
export const sha256HexSchema = z.string().regex(/^[0-9a-f]{64}$/);
|
|
28
35
|
|
|
@@ -20,6 +20,17 @@ export type ToolSurface = (typeof TOOL_SURFACES)[number];
|
|
|
20
20
|
export const MESSAGE_ROLES = ["system", "user", "assistant", "trigger"] as const;
|
|
21
21
|
export type MessageRole = (typeof MESSAGE_ROLES)[number];
|
|
22
22
|
|
|
23
|
+
/** The fenced blocks an agent may draw in its replies instead of text. */
|
|
24
|
+
export const MEDIA_FORMS = ["mermaid", "vega-lite", "map", "report"] as const;
|
|
25
|
+
export type MediaForm = (typeof MEDIA_FORMS)[number];
|
|
26
|
+
|
|
27
|
+
/** The forms an agent draws unless its config says otherwise: reports are large, so they are opt-in. */
|
|
28
|
+
export const DEFAULT_MEDIA_FORMS = [
|
|
29
|
+
"mermaid",
|
|
30
|
+
"vega-lite",
|
|
31
|
+
"map",
|
|
32
|
+
] as const satisfies readonly MediaForm[];
|
|
33
|
+
|
|
23
34
|
export const ATTACHMENT_MIME_TYPES = [
|
|
24
35
|
"image/png",
|
|
25
36
|
"image/jpeg",
|
package/src/scaffold/files.ts
CHANGED
|
@@ -27,7 +27,7 @@ export type Database = "postgres" | "mssql";
|
|
|
27
27
|
// sync (scripts/sync-package-versions.ts) restamps it and files.test.ts holds
|
|
28
28
|
// them to that.
|
|
29
29
|
export const DEPENDENCIES = {
|
|
30
|
-
"@m6d/cortex-server": "~0.
|
|
30
|
+
"@m6d/cortex-server": "~0.12.1",
|
|
31
31
|
"@tanstack/ai": "^0.55.0",
|
|
32
32
|
"@tanstack/ai-openai": "^0.22.8",
|
|
33
33
|
hono: "^4.12.3",
|