@m6d/cortex-cli 0.11.0 → 0.12.0

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@m6d/cortex-cli",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "description": "Scaffold and operate Cortex servers",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -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
- /** Style text with every resource-loading function neutralized: CSS escapes decoded first, url() kept only to fragments. */
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",
@@ -1,8 +1,11 @@
1
1
  /*
2
- * CommonMark fence tracking shared by the prompt rich-text pipeline and the
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 = /^ {0,3}(`{3,}|~{3,})(.*)$/.exec(line);
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 { LOCALES, TOOL_SURFACES, type Greeting, type Suggestions } from "../wire/index";
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",
@@ -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.11.0",
30
+ "@m6d/cortex-server": "~0.12.0",
31
31
  "@tanstack/ai": "^0.55.0",
32
32
  "@tanstack/ai-openai": "^0.22.8",
33
33
  hono: "^4.12.3",