@north-light/crouter 0.3.160 → 0.3.162
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/api/client.d.ts +3 -1
- package/dist/api/client.js +6 -0
- package/dist/api/dto/modelauth.d.ts +32 -0
- package/dist/api/dto/modelauth.js +2 -1
- package/dist/api/routes.d.ts +1 -0
- package/dist/api/routes.js +1 -0
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/provider-rotation.test.ts +55 -395
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +204 -419
- package/dist/clients/attach/__tests__/markdown-headings.test.js +8 -0
- package/dist/clients/attach/render/glyph-codepoints.d.ts +3 -0
- package/dist/clients/attach/render/glyph-codepoints.js +42 -0
- package/dist/clients/attach/render/markdown-headings.js +15 -4
- package/dist/clients/attach/viewer.js +558 -558
- package/dist/core/__tests__/broker-launch-candidates.test.js +13 -3
- package/dist/core/__tests__/broker-sdk-wiring.test.js +53 -25
- package/dist/core/__tests__/full/broker-provider-retry.test.js +6 -122
- package/dist/core/__tests__/model-pin-durability.test.js +7 -5
- package/dist/core/__tests__/model-routes.test.d.ts +1 -0
- package/dist/core/__tests__/model-routes.test.js +41 -0
- package/dist/core/__tests__/review-model-floor.test.js +2 -2
- package/dist/core/auth-file.d.ts +3 -2
- package/dist/core/auth-file.js +5 -3
- package/dist/core/canvas/labels.d.ts +5 -3
- package/dist/core/canvas/labels.js +7 -4
- package/dist/core/canvas/types.d.ts +6 -1
- package/dist/core/config.d.ts +3 -1
- package/dist/core/config.js +88 -2
- package/dist/core/model-routes.d.ts +37 -0
- package/dist/core/model-routes.js +140 -0
- package/dist/core/runtime/broker.d.ts +0 -4
- package/dist/core/runtime/broker.js +116 -372
- package/dist/core/runtime/launch.d.ts +9 -11
- package/dist/core/runtime/launch.js +15 -21
- package/dist/core/runtime/managed-provider-cooling.d.ts +0 -14
- package/dist/core/runtime/managed-provider-cooling.js +0 -19
- package/dist/core/runtime/model-swap.js +7 -1
- package/dist/core/runtime/naming.js +21 -14
- package/dist/core/runtime/promote.js +1 -0
- package/dist/core/subscription-state.d.ts +12 -36
- package/dist/core/subscription-state.js +19 -203
- package/dist/daemon/api/__tests__/full/api-server.test.js +9 -6
- package/dist/daemon/api/__tests__/full/b10-attach-modelauth.test.js +123 -1
- package/dist/daemon/api/handlers/modelauth.js +51 -2
- package/dist/daemon/api/handlers/nodes.js +2 -0
- package/dist/types.d.ts +17 -0
- package/dist/web-client/assets/{index-B76ZKfT_.js → index-NIuSCOHM.js} +1 -1
- package/dist/web-client/index.html +1 -1
- package/dist/web-client/sw.js +1 -1
- package/package.json +8 -8
- package/runtime.lock.json +161 -161
|
@@ -25,3 +25,11 @@ test('copies message blocks for terminal-only decoration', () => {
|
|
|
25
25
|
assert.match(rendered.content[0].text, /^\x1b\[[^m]+mDetail/);
|
|
26
26
|
assert.equal(rendered.content[1], source.content[1], 'non-Markdown blocks preserve identity');
|
|
27
27
|
});
|
|
28
|
+
test('expands private-use codepoint references to glyphs, and only those', () => {
|
|
29
|
+
const source = { content: [{ type: 'text', text: 'icons: U+F188 U+F0001 — not U+0041 or U+241C, nor MU+FFFF' }] };
|
|
30
|
+
const rendered = styleAttachMessageMarkdown(source);
|
|
31
|
+
const text = rendered.content[0].text;
|
|
32
|
+
assert.match(text, new RegExp(`icons: ${String.fromCodePoint(0xf188)} ${String.fromCodePoint(0xf0001)}`), 'PUA references become their glyphs');
|
|
33
|
+
assert.match(text, /not U\+0041 or U\+241C/, 'ordinary codepoint references stay as text');
|
|
34
|
+
assert.match(text, /MU\+FFFF/, 'a reference glued to a word is not a reference');
|
|
35
|
+
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// glyph-codepoints.ts — render `U+XXXX` as the glyph it names, for the private-
|
|
2
|
+
// use areas only.
|
|
3
|
+
//
|
|
4
|
+
// Nerd Font icons live in the Unicode private-use areas, and PUA codepoints are
|
|
5
|
+
// effectively absent from model tokenizer vocabularies: an agent cannot type one
|
|
6
|
+
// into its reply (the character never becomes tokens, so it is simply missing
|
|
7
|
+
// from the message) and cannot even perceive one in a prompt. Agents CAN name a
|
|
8
|
+
// codepoint accurately, so the viewer closes the gap at the other end — an agent
|
|
9
|
+
// writes `U+F188` and the reader sees the bug glyph.
|
|
10
|
+
//
|
|
11
|
+
// Scoped to the private-use areas on purpose. Those are exactly the codepoints
|
|
12
|
+
// an agent cannot write literally, so expanding them adds an ability rather than
|
|
13
|
+
// taking one away; every other codepoint reference (`U+0041`, `U+241C`) is left
|
|
14
|
+
// as text, because a message discussing Unicode wants the hex on screen and
|
|
15
|
+
// could have contained the character itself if it meant the character.
|
|
16
|
+
/** `U+` followed by 4-6 hex digits, not glued to a surrounding word. Case
|
|
17
|
+
* insensitive on both the prefix and the digits. */
|
|
18
|
+
const CODEPOINT = /\bU\+([0-9A-Fa-f]{4,6})\b/g;
|
|
19
|
+
/** Private-use areas: the BMP block plus planes 15 and 16. Nerd Fonts use the
|
|
20
|
+
* BMP block and, since v3, the supplementary block above U+F0000. */
|
|
21
|
+
function isPrivateUse(cp) {
|
|
22
|
+
return ((cp >= 0xe000 && cp <= 0xf8ff) ||
|
|
23
|
+
(cp >= 0xf0000 && cp <= 0xffffd) ||
|
|
24
|
+
(cp >= 0x100000 && cp <= 0x10fffd));
|
|
25
|
+
}
|
|
26
|
+
/** Replace every private-use `U+XXXX` reference in `text` with the character it
|
|
27
|
+
* names. Non-PUA references and malformed digits pass through untouched. */
|
|
28
|
+
export function expandGlyphCodepoints(text) {
|
|
29
|
+
if (!text.includes('U+') && !text.includes('u+'))
|
|
30
|
+
return text;
|
|
31
|
+
return text.replace(CODEPOINT, (match, hex) => {
|
|
32
|
+
const cp = Number.parseInt(hex, 16);
|
|
33
|
+
if (!isPrivateUse(cp))
|
|
34
|
+
return match;
|
|
35
|
+
try {
|
|
36
|
+
return String.fromCodePoint(cp);
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return match;
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
@@ -7,6 +7,12 @@
|
|
|
7
7
|
// owns parsing, wrapping, inline formatting, and H1/H2's established styling.
|
|
8
8
|
// This stays attach-local — persisted messages and copied text remain ordinary
|
|
9
9
|
// Markdown without terminal escape sequences.
|
|
10
|
+
//
|
|
11
|
+
// The same per-block copy carries the viewer's other source-text transform:
|
|
12
|
+
// private-use `U+XXXX` references become their glyphs (see glyph-codepoints.ts),
|
|
13
|
+
// so an agent that cannot type a Nerd Font character can still put one on
|
|
14
|
+
// screen.
|
|
15
|
+
import { expandGlyphCodepoints } from './glyph-codepoints.js';
|
|
10
16
|
const ATX_HEADING = /^(\s{0,3})(#{3,6})(?:[ \t]+|$)(.*?)([ \t]+#+[ \t]*)?$/;
|
|
11
17
|
const FENCE_OPEN = /^\s{0,3}(`{3,}|~{3,})/;
|
|
12
18
|
// A constant-lightness ramp from warm yellow to cool blue, with saturation
|
|
@@ -49,6 +55,11 @@ export function styleAttachMarkdownHeadings(markdown) {
|
|
|
49
55
|
return `${indent}${headingColor(hashes.length)(body)}`;
|
|
50
56
|
}).join('\n');
|
|
51
57
|
}
|
|
58
|
+
/** Every source-text transform the viewer applies to a Markdown-bearing block,
|
|
59
|
+
* in one place: heading hierarchy, then glyph expansion. */
|
|
60
|
+
function renderableText(markdown) {
|
|
61
|
+
return expandGlyphCodepoints(styleAttachMarkdownHeadings(markdown));
|
|
62
|
+
}
|
|
52
63
|
/** Copy a pi message for terminal rendering and decorate only Markdown-bearing
|
|
53
64
|
* text/thinking blocks. The broker's source event is never mutated. */
|
|
54
65
|
export function styleAttachMessageMarkdown(message) {
|
|
@@ -56,7 +67,7 @@ export function styleAttachMessageMarkdown(message) {
|
|
|
56
67
|
return message;
|
|
57
68
|
const candidate = message;
|
|
58
69
|
if (typeof candidate.content === 'string') {
|
|
59
|
-
return { ...candidate, content:
|
|
70
|
+
return { ...candidate, content: renderableText(candidate.content) };
|
|
60
71
|
}
|
|
61
72
|
if (!Array.isArray(candidate.content))
|
|
62
73
|
return message;
|
|
@@ -67,10 +78,10 @@ export function styleAttachMessageMarkdown(message) {
|
|
|
67
78
|
return part;
|
|
68
79
|
const block = part;
|
|
69
80
|
if (block.type === 'text' && typeof block.text === 'string') {
|
|
70
|
-
return { ...block, text:
|
|
81
|
+
return { ...block, text: renderableText(block.text) };
|
|
71
82
|
}
|
|
72
83
|
if (block.type === 'thinking' && typeof block.thinking === 'string') {
|
|
73
|
-
return { ...block, thinking:
|
|
84
|
+
return { ...block, thinking: renderableText(block.thinking) };
|
|
74
85
|
}
|
|
75
86
|
return part;
|
|
76
87
|
}),
|
|
@@ -78,5 +89,5 @@ export function styleAttachMessageMarkdown(message) {
|
|
|
78
89
|
}
|
|
79
90
|
/** Copy an expanded pi summary without changing its persisted source. */
|
|
80
91
|
export function styleAttachSummaryMarkdown(message) {
|
|
81
|
-
return { ...message, summary:
|
|
92
|
+
return { ...message, summary: renderableText(message.summary) };
|
|
82
93
|
}
|