@lloyal-labs/ui 0.1.0-alpha.6
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/LICENSE +107 -0
- package/dist/assets.d.ts +18 -0
- package/dist/assets.d.ts.map +1 -0
- package/dist/assets.js +83 -0
- package/dist/assets.js.map +1 -0
- package/dist/fold.d.ts +194 -0
- package/dist/fold.d.ts.map +1 -0
- package/dist/fold.js +295 -0
- package/dist/fold.js.map +1 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/lightbox.d.ts +21 -0
- package/dist/lightbox.d.ts.map +1 -0
- package/dist/lightbox.js +43 -0
- package/dist/lightbox.js.map +1 -0
- package/dist/markdown.d.ts +14 -0
- package/dist/markdown.d.ts.map +1 -0
- package/dist/markdown.js +34 -0
- package/dist/markdown.js.map +1 -0
- package/dist/provider.d.ts +43 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +172 -0
- package/dist/provider.js.map +1 -0
- package/package.json +57 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# Functional Source License, Version 1.1, Apache 2.0 Future License
|
|
2
|
+
|
|
3
|
+
## Abbreviation
|
|
4
|
+
|
|
5
|
+
FSL-1.1-Apache-2.0
|
|
6
|
+
|
|
7
|
+
## Notice
|
|
8
|
+
|
|
9
|
+
Copyright 2026 Lloyal Labs
|
|
10
|
+
|
|
11
|
+
## Terms and Conditions
|
|
12
|
+
|
|
13
|
+
### Licensor ("We")
|
|
14
|
+
|
|
15
|
+
The party offering the Software under these Terms and Conditions.
|
|
16
|
+
|
|
17
|
+
### The Software
|
|
18
|
+
|
|
19
|
+
The "Software" is each version of the software that we make available under
|
|
20
|
+
these Terms and Conditions, as indicated by our inclusion of these Terms and
|
|
21
|
+
Conditions with the Software.
|
|
22
|
+
|
|
23
|
+
### License Grant
|
|
24
|
+
|
|
25
|
+
Subject to your compliance with this License Grant and the Patents,
|
|
26
|
+
Redistribution and Trademark clauses below, we hereby grant you the right to
|
|
27
|
+
use, copy, modify, create derivative works, publish, and distribute the
|
|
28
|
+
Software for any Permitted Purpose identified below.
|
|
29
|
+
|
|
30
|
+
### Permitted Purpose
|
|
31
|
+
|
|
32
|
+
A "Permitted Purpose" is any purpose other than a Competing Use. A
|
|
33
|
+
"Competing Use" means making the Software available to others in a
|
|
34
|
+
commercial product or service that:
|
|
35
|
+
|
|
36
|
+
1. substitutes for the Software;
|
|
37
|
+
|
|
38
|
+
2. substitutes for any other product or service we offer using the Software
|
|
39
|
+
that exists as of the date we make the Software available; or
|
|
40
|
+
|
|
41
|
+
3. offers the same or substantially similar functionality as the Software.
|
|
42
|
+
|
|
43
|
+
Permitted Purposes specifically include using the Software:
|
|
44
|
+
|
|
45
|
+
1. for your internal use and access;
|
|
46
|
+
|
|
47
|
+
2. for non-commercial education;
|
|
48
|
+
|
|
49
|
+
3. for non-commercial research; and
|
|
50
|
+
|
|
51
|
+
4. in connection with professional services that you provide to a Licensee
|
|
52
|
+
using the Software in accordance with these Terms and Conditions.
|
|
53
|
+
|
|
54
|
+
### Patents
|
|
55
|
+
|
|
56
|
+
To the extent your use for a Permitted Purpose would necessarily infringe our
|
|
57
|
+
patents, the license grant above includes a license under our patents. If you
|
|
58
|
+
make a claim against any party that the Software infringes or contributes to
|
|
59
|
+
the infringement of any patent, then your patent license to the Software ends
|
|
60
|
+
immediately.
|
|
61
|
+
|
|
62
|
+
### Redistribution
|
|
63
|
+
|
|
64
|
+
The Terms and Conditions apply to all copies, modifications and derivatives
|
|
65
|
+
of the Software.
|
|
66
|
+
|
|
67
|
+
If you redistribute any copies, modifications or derivatives of the Software,
|
|
68
|
+
you must include a copy of or a link to these Terms and Conditions and not
|
|
69
|
+
remove any copyright notices provided in or with the Software.
|
|
70
|
+
|
|
71
|
+
### Disclaimer
|
|
72
|
+
|
|
73
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTIES OF ANY KIND,
|
|
74
|
+
INCLUDING WITHOUT LIMITATION WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE,
|
|
75
|
+
MERCHANTABILITY, TITLE OR NON-INFRINGEMENT.
|
|
76
|
+
|
|
77
|
+
IN NO EVENT WILL WE HAVE ANY LIABILITY TO YOU ARISING OUT OF OR RELATED TO
|
|
78
|
+
THE SOFTWARE, INCLUDING INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
|
|
79
|
+
DAMAGES, EVEN IF WE HAVE BEEN INFORMED OF THEIR POSSIBILITY IN ADVANCE.
|
|
80
|
+
|
|
81
|
+
### Trademarks
|
|
82
|
+
|
|
83
|
+
Except for displaying the License Details and identifying us as the origin of
|
|
84
|
+
the Software, you have no right under these Terms and Conditions to use our
|
|
85
|
+
trademarks, trade names, service marks or product names.
|
|
86
|
+
|
|
87
|
+
## Grant of Future License
|
|
88
|
+
|
|
89
|
+
We hereby irrevocably grant you an additional license to use the Software
|
|
90
|
+
under the Apache License, Version 2.0 that is effective on the second
|
|
91
|
+
anniversary of the date we make the Software available. On or after that
|
|
92
|
+
date, you may use the Software under the Apache License, Version 2.0, in
|
|
93
|
+
which case the following will apply:
|
|
94
|
+
|
|
95
|
+
Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
|
96
|
+
use this file except in compliance with the License.
|
|
97
|
+
|
|
98
|
+
You may obtain a copy of the License at
|
|
99
|
+
|
|
100
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
101
|
+
|
|
102
|
+
Unless required by applicable law or agreed to in writing, software
|
|
103
|
+
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
104
|
+
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
105
|
+
|
|
106
|
+
See the License for the specific language governing permissions and
|
|
107
|
+
limitations under the License.
|
package/dist/assets.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { DocumentMeta } from '@lloyal-labs/media';
|
|
2
|
+
export type Asset = {
|
|
3
|
+
kind: 'image';
|
|
4
|
+
} | {
|
|
5
|
+
kind: 'document';
|
|
6
|
+
meta: DocumentMeta; /** The ingest retained the original file. */
|
|
7
|
+
source: boolean;
|
|
8
|
+
};
|
|
9
|
+
export declare function resolveAsset(origin: string, digest: string): Promise<Asset>;
|
|
10
|
+
/** The kinds of the given roots, filled in as the content plane answers. */
|
|
11
|
+
export declare function useAssets(digests: readonly string[]): Record<string, Asset>;
|
|
12
|
+
/** "1, 2, 3, 7" with runs of three or more folded: "1–3, 7". */
|
|
13
|
+
export declare function pageList(pages: readonly number[]): string;
|
|
14
|
+
/** What of a document reached the model, page by page: which pages had no text
|
|
15
|
+
* to extract (scanned), which were extracted as text, and — when the thread
|
|
16
|
+
* holds their renders — which pages the model looked at. */
|
|
17
|
+
export declare function pageFacts(meta: DocumentMeta, viewedRenders?: ReadonlySet<string>): string[];
|
|
18
|
+
//# sourceMappingURL=assets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../src/assets.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGvD,MAAM,MAAM,KAAK,GACb;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,YAAY,CAAC,CAAC,6CAA6C;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,CAAC;AAI5G,wBAAsB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAcjF;AAED,4EAA4E;AAC5E,wBAAgB,SAAS,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAoB3E;AAED,gEAAgE;AAChE,wBAAgB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CASzD;AAED;;6DAE6D;AAC7D,wBAAgB,SAAS,CAAC,IAAI,EAAE,YAAY,EAAE,aAAa,GAAE,WAAW,CAAC,MAAM,CAAa,GAAG,MAAM,EAAE,CAatG"}
|
package/dist/assets.js
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a root IS, learned from its manifest through the content plane: a
|
|
3
|
+
* picture, or a document with its sidecar. One resolution per digest for the
|
|
4
|
+
* page's lifetime — content is immutable under its address, so an answer never
|
|
5
|
+
* goes stale. A root whose manifest cannot be read is shown as an image, so
|
|
6
|
+
* the failure is visible (a broken picture) rather than silent.
|
|
7
|
+
*
|
|
8
|
+
* @category UI
|
|
9
|
+
*/
|
|
10
|
+
import { useEffect, useState } from 'react';
|
|
11
|
+
import { asDocumentMeta, configUrl, DOCUMENT_CONFIG_TYPE, manifestUrl } from '@lloyal-labs/media';
|
|
12
|
+
import { useContentOrigin } from './provider.js';
|
|
13
|
+
const resolved = new Map();
|
|
14
|
+
export async function resolveAsset(origin, digest) {
|
|
15
|
+
try {
|
|
16
|
+
const manifest = (await (await fetch(manifestUrl(origin, digest))).json());
|
|
17
|
+
if (manifest.config?.mediaType !== DOCUMENT_CONFIG_TYPE)
|
|
18
|
+
return { kind: 'image' };
|
|
19
|
+
const meta = asDocumentMeta(await (await fetch(configUrl(origin, digest))).json());
|
|
20
|
+
if (!meta)
|
|
21
|
+
return { kind: 'image' };
|
|
22
|
+
const source = (manifest.layers ?? []).some((l) => l.annotations?.['ai.lloyal.role'] === 'source');
|
|
23
|
+
return { kind: 'document', meta, source };
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return { kind: 'image' };
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/** The kinds of the given roots, filled in as the content plane answers. */
|
|
30
|
+
export function useAssets(digests) {
|
|
31
|
+
const origin = useContentOrigin();
|
|
32
|
+
const [assets, setAssets] = useState({});
|
|
33
|
+
const key = digests.join(' ');
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
if (origin === null)
|
|
36
|
+
return;
|
|
37
|
+
let live = true;
|
|
38
|
+
for (const digest of key ? key.split(' ') : []) {
|
|
39
|
+
let p = resolved.get(digest);
|
|
40
|
+
if (!p) {
|
|
41
|
+
p = resolveAsset(origin, digest);
|
|
42
|
+
resolved.set(digest, p);
|
|
43
|
+
}
|
|
44
|
+
void p.then((asset) => {
|
|
45
|
+
if (live)
|
|
46
|
+
setAssets((prev) => (prev[digest] ? prev : { ...prev, [digest]: asset }));
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
return () => { live = false; };
|
|
50
|
+
}, [origin, key]);
|
|
51
|
+
return assets;
|
|
52
|
+
}
|
|
53
|
+
/** "1, 2, 3, 7" with runs of three or more folded: "1–3, 7". */
|
|
54
|
+
export function pageList(pages) {
|
|
55
|
+
const out = [];
|
|
56
|
+
for (let i = 0; i < pages.length;) {
|
|
57
|
+
let j = i;
|
|
58
|
+
while (j + 1 < pages.length && pages[j + 1] === pages[j] + 1)
|
|
59
|
+
j++;
|
|
60
|
+
out.push(j - i >= 2 ? `${pages[i]}–${pages[j]}` : pages.slice(i, j + 1).join(', '));
|
|
61
|
+
i = j + 1;
|
|
62
|
+
}
|
|
63
|
+
return out.join(', ');
|
|
64
|
+
}
|
|
65
|
+
/** What of a document reached the model, page by page: which pages had no text
|
|
66
|
+
* to extract (scanned), which were extracted as text, and — when the thread
|
|
67
|
+
* holds their renders — which pages the model looked at. */
|
|
68
|
+
export function pageFacts(meta, viewedRenders = new Set()) {
|
|
69
|
+
const scanned = meta.pages.filter((p) => p.chars === 0).map((p) => p.page);
|
|
70
|
+
const viewed = meta.pages.filter((p) => p.render && viewedRenders.has(p.render.digest)).map((p) => p.page);
|
|
71
|
+
const n = meta.pageCount;
|
|
72
|
+
const lines = [
|
|
73
|
+
scanned.length === 0
|
|
74
|
+
? `Extracted as text: all ${n} page${n === 1 ? '' : 's'}`
|
|
75
|
+
: scanned.length === n
|
|
76
|
+
? `Scanned (image only): all ${n} page${n === 1 ? '' : 's'}`
|
|
77
|
+
: `Scanned: ${pageList(scanned)} · extracted as text: the rest`,
|
|
78
|
+
];
|
|
79
|
+
if (viewed.length > 0)
|
|
80
|
+
lines.push(`Viewed as images: ${pageList(viewed)}`);
|
|
81
|
+
return lines;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=assets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assets.js","sourceRoot":"","sources":["../src/assets.ts"],"names":[],"mappings":"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"}
|
package/dist/fold.d.ts
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The generic agent fold: one agent's life on a view, folded from the bus
|
|
3
|
+
* events every pool emits. Framework-free — the Ink view, the desktop shell's
|
|
4
|
+
* own fold and the browser page all fold the same records — and it knows no
|
|
5
|
+
* product: which spawns get a timeline, and what an agent's task is called,
|
|
6
|
+
* are the application's decisions, handed in at `agent:spawn`.
|
|
7
|
+
*
|
|
8
|
+
* What it owns: the per-agent record ({@link AgentRuntime}), the `<think>`
|
|
9
|
+
* boundary machine (a live think block advances until the marker, then closes
|
|
10
|
+
* and seeds the content buffer with the tail), the timeline items — think,
|
|
11
|
+
* tool call, tool result, report — with their summaries, retry state, and the
|
|
12
|
+
* terminal transitions (`return`/`recovered` → done, `failed`, and the
|
|
13
|
+
* stall-break `done` that precedes a forced recovery).
|
|
14
|
+
*
|
|
15
|
+
* @packageDocumentation
|
|
16
|
+
* @category UI
|
|
17
|
+
*/
|
|
18
|
+
/** One cited source, extracted CONSUMER-side from a tool result (the Ability
|
|
19
|
+
* Protocol prescribes no result schema). Web tools populate url/title/snippet;
|
|
20
|
+
* image and icon arrive when an ability emits them; a corpus ability fills
|
|
21
|
+
* whatever subset applies. */
|
|
22
|
+
export interface SourceMeta {
|
|
23
|
+
url?: string;
|
|
24
|
+
title?: string;
|
|
25
|
+
snippet?: string;
|
|
26
|
+
image?: string;
|
|
27
|
+
icon?: string;
|
|
28
|
+
/** Display host, derived from url when present. */
|
|
29
|
+
host?: string;
|
|
30
|
+
}
|
|
31
|
+
/** Per-agent chronological stream item — a renderer lays one component per
|
|
32
|
+
* kind. `live: true` on a think item means its body is currently streaming. */
|
|
33
|
+
export type TimelineItem = {
|
|
34
|
+
kind: 'think';
|
|
35
|
+
id: number;
|
|
36
|
+
title: string;
|
|
37
|
+
body: string;
|
|
38
|
+
live: boolean;
|
|
39
|
+
openedAt: number;
|
|
40
|
+
closedAt: number | null;
|
|
41
|
+
} | {
|
|
42
|
+
kind: 'tool_call';
|
|
43
|
+
id: number;
|
|
44
|
+
tool: string;
|
|
45
|
+
argsSummary: string;
|
|
46
|
+
} | {
|
|
47
|
+
kind: 'tool_result';
|
|
48
|
+
id: number;
|
|
49
|
+
tool: string;
|
|
50
|
+
/** The tool_call id this result pairs with, for a renderer that indents results under their call. */
|
|
51
|
+
callId: number | null;
|
|
52
|
+
byteLength: number;
|
|
53
|
+
preview: string | null;
|
|
54
|
+
hosts: string[];
|
|
55
|
+
resultCount: number | null;
|
|
56
|
+
/** Per-source citation metadata parsed from the tool's free-form result. */
|
|
57
|
+
sources?: SourceMeta[];
|
|
58
|
+
} | {
|
|
59
|
+
kind: 'report';
|
|
60
|
+
id: number;
|
|
61
|
+
body: string;
|
|
62
|
+
tokenCount: number;
|
|
63
|
+
};
|
|
64
|
+
export interface AgentRuntime {
|
|
65
|
+
id: number;
|
|
66
|
+
/** "A0", "A1", … in spawn order within the roster. */
|
|
67
|
+
label: string;
|
|
68
|
+
phase: 'idle' | 'thinking' | 'content' | 'tool' | 'done' | 'failed';
|
|
69
|
+
tokenCount: number;
|
|
70
|
+
toolCallCount: number;
|
|
71
|
+
/** Wall-clock spawn time (ms). */
|
|
72
|
+
startedAt: number;
|
|
73
|
+
/** Wall-clock completion time (ms), set when the agent reaches `done` or `failed`. */
|
|
74
|
+
endedAt: number | null;
|
|
75
|
+
/** The application's index for this agent's task. Null means the agent is tracked but keeps no timeline. */
|
|
76
|
+
taskIndex: number | null;
|
|
77
|
+
taskDescription: string | null;
|
|
78
|
+
/** A dependency hint for a chained task ("builds on Task 1"). */
|
|
79
|
+
dependencyHint: string | null;
|
|
80
|
+
/** Id of the currently-live think item in `timeline`, or null. */
|
|
81
|
+
currentThinkId: number | null;
|
|
82
|
+
/** Id of the most recent tool_call, paired with its tool_result when one lands. */
|
|
83
|
+
pendingToolCallId: number | null;
|
|
84
|
+
/** A parked tool call: the provider was rate-limited and the pool re-executes after the delay. */
|
|
85
|
+
retry: {
|
|
86
|
+
tool: string;
|
|
87
|
+
retryAt: number;
|
|
88
|
+
attempt: number;
|
|
89
|
+
} | null;
|
|
90
|
+
/** Live post-`</think>` token buffer: the model writing its tool-call JSON, or a forced recovery's prose. */
|
|
91
|
+
contentBuffer: string;
|
|
92
|
+
/** True while the agent is being force-recovered: `agent:done` fired without a report and the pool
|
|
93
|
+
* streams a forced one; produce tokens go to `contentBuffer`, not a think block. */
|
|
94
|
+
recovering: boolean;
|
|
95
|
+
/** Set when the agent ended without a result: the terminal failure's reason. */
|
|
96
|
+
failReason: string | null;
|
|
97
|
+
timeline: TimelineItem[];
|
|
98
|
+
}
|
|
99
|
+
/** What a roster holds beside its agents: the counters that keep timeline ids and labels stable. */
|
|
100
|
+
export interface AgentRoster {
|
|
101
|
+
agents: Map<number, AgentRuntime>;
|
|
102
|
+
nextTimelineId: number;
|
|
103
|
+
nextLabelIdx: number;
|
|
104
|
+
}
|
|
105
|
+
export declare const emptyRoster: () => AgentRoster;
|
|
106
|
+
/** The bus events the fold reads, structurally — the agents package's own
|
|
107
|
+
* vocabulary, versioned beside it; every field the fold touches is guarded. */
|
|
108
|
+
export type AgentEvent = {
|
|
109
|
+
type: 'agent:spawn';
|
|
110
|
+
agentId: number;
|
|
111
|
+
parentAgentId?: number;
|
|
112
|
+
key?: string;
|
|
113
|
+
after?: number[];
|
|
114
|
+
} | {
|
|
115
|
+
type: 'agent:produce';
|
|
116
|
+
agentId: number;
|
|
117
|
+
text: string;
|
|
118
|
+
tokenCount: number;
|
|
119
|
+
} | {
|
|
120
|
+
type: 'agent:tool_call';
|
|
121
|
+
agentId: number;
|
|
122
|
+
tool: string;
|
|
123
|
+
args: string;
|
|
124
|
+
} | {
|
|
125
|
+
type: 'agent:tool_retry';
|
|
126
|
+
agentId: number;
|
|
127
|
+
tool: string;
|
|
128
|
+
retryAfterMs: number;
|
|
129
|
+
attempt: number;
|
|
130
|
+
} | {
|
|
131
|
+
type: 'agent:tool_result';
|
|
132
|
+
agentId: number;
|
|
133
|
+
tool: string;
|
|
134
|
+
result: string;
|
|
135
|
+
} | {
|
|
136
|
+
type: 'agent:return';
|
|
137
|
+
agentId: number;
|
|
138
|
+
result: string;
|
|
139
|
+
} | {
|
|
140
|
+
type: 'agent:recovered';
|
|
141
|
+
agentId: number;
|
|
142
|
+
result: string;
|
|
143
|
+
} | {
|
|
144
|
+
type: 'agent:failed';
|
|
145
|
+
agentId: number;
|
|
146
|
+
reason: string;
|
|
147
|
+
} | {
|
|
148
|
+
type: 'agent:done';
|
|
149
|
+
agentId: number;
|
|
150
|
+
};
|
|
151
|
+
/** What the application decides at a spawn: the agent's task, or nothing (tracked, no timeline). */
|
|
152
|
+
export interface SpawnDecision {
|
|
153
|
+
taskIndex: number | null;
|
|
154
|
+
taskDescription?: string | null;
|
|
155
|
+
dependencyHint?: string | null;
|
|
156
|
+
}
|
|
157
|
+
export interface FoldAgentsOptions {
|
|
158
|
+
/** The application's decision at `agent:spawn`. Default: every agent is tracked with no timeline. */
|
|
159
|
+
spawn?: (ev: Extract<AgentEvent, {
|
|
160
|
+
type: 'agent:spawn';
|
|
161
|
+
}>) => SpawnDecision;
|
|
162
|
+
/** The tool whose call ends the turn. Its call is not a timeline row: the report streamed live and
|
|
163
|
+
* `agent:return` files it. */
|
|
164
|
+
terminal?: string;
|
|
165
|
+
/** The clock, for tests. */
|
|
166
|
+
now?: () => number;
|
|
167
|
+
}
|
|
168
|
+
/** Live report markdown from a raw Hermes terminal-tool buffer
|
|
169
|
+
* (`…<parameter=result>\n<markdown>\n</parameter>…`). Null until the open
|
|
170
|
+
* marker arrives, so a half-written tool call never flashes as prose. A forced
|
|
171
|
+
* recovery streams raw prose with no envelope — callers branch on `recovering` first. */
|
|
172
|
+
export declare function extractStreamingReport(buffer: string): string | null;
|
|
173
|
+
/** First meaningful line of a think-block body, cleaned up for a title. */
|
|
174
|
+
export declare function extractTitle(body: string): string;
|
|
175
|
+
export declare function hostOf(url: string): string;
|
|
176
|
+
/** A one-line summary of a tool call's arguments: the query, pattern, url or filename it named. */
|
|
177
|
+
export declare function formatArgSummary(_tool: string, rawArgs: string): string;
|
|
178
|
+
export interface ResultSummary {
|
|
179
|
+
summary: string;
|
|
180
|
+
hosts: string[];
|
|
181
|
+
resultCount: number | null;
|
|
182
|
+
preview: string | null;
|
|
183
|
+
sources?: SourceMeta[];
|
|
184
|
+
}
|
|
185
|
+
/** A per-tool summary of a result, parsed from the stock abilities' result
|
|
186
|
+
* shapes (web search and fetch, corpus search, grep and read); anything else
|
|
187
|
+
* falls back to the URLs it carries, else its size. */
|
|
188
|
+
export declare function summarizeResult(tool: string, raw: string): ResultSummary;
|
|
189
|
+
/**
|
|
190
|
+
* Fold one agent event into the roster. Returns the same roster when the event
|
|
191
|
+
* changed nothing. An event for an unknown agent is dropped.
|
|
192
|
+
*/
|
|
193
|
+
export declare function foldAgents(r: AgentRoster, ev: AgentEvent, opts?: FoldAgentsOptions): AgentRoster;
|
|
194
|
+
//# sourceMappingURL=fold.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fold.d.ts","sourceRoot":"","sources":["../src/fold.ts"],"names":[],"mappings":"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"}
|
package/dist/fold.js
ADDED
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The generic agent fold: one agent's life on a view, folded from the bus
|
|
3
|
+
* events every pool emits. Framework-free — the Ink view, the desktop shell's
|
|
4
|
+
* own fold and the browser page all fold the same records — and it knows no
|
|
5
|
+
* product: which spawns get a timeline, and what an agent's task is called,
|
|
6
|
+
* are the application's decisions, handed in at `agent:spawn`.
|
|
7
|
+
*
|
|
8
|
+
* What it owns: the per-agent record ({@link AgentRuntime}), the `<think>`
|
|
9
|
+
* boundary machine (a live think block advances until the marker, then closes
|
|
10
|
+
* and seeds the content buffer with the tail), the timeline items — think,
|
|
11
|
+
* tool call, tool result, report — with their summaries, retry state, and the
|
|
12
|
+
* terminal transitions (`return`/`recovered` → done, `failed`, and the
|
|
13
|
+
* stall-break `done` that precedes a forced recovery).
|
|
14
|
+
*
|
|
15
|
+
* @packageDocumentation
|
|
16
|
+
* @category UI
|
|
17
|
+
*/
|
|
18
|
+
export const emptyRoster = () => ({ agents: new Map(), nextTimelineId: 0, nextLabelIdx: 0 });
|
|
19
|
+
/** Live report markdown from a raw Hermes terminal-tool buffer
|
|
20
|
+
* (`…<parameter=result>\n<markdown>\n</parameter>…`). Null until the open
|
|
21
|
+
* marker arrives, so a half-written tool call never flashes as prose. A forced
|
|
22
|
+
* recovery streams raw prose with no envelope — callers branch on `recovering` first. */
|
|
23
|
+
export function extractStreamingReport(buffer) {
|
|
24
|
+
const OPEN = '<parameter=result>';
|
|
25
|
+
const i = buffer.indexOf(OPEN);
|
|
26
|
+
if (i === -1)
|
|
27
|
+
return null;
|
|
28
|
+
let body = buffer.slice(i + OPEN.length);
|
|
29
|
+
const c = body.indexOf('</parameter>');
|
|
30
|
+
if (c !== -1)
|
|
31
|
+
body = body.slice(0, c);
|
|
32
|
+
return body.replace(/^\n/, '');
|
|
33
|
+
}
|
|
34
|
+
const THINK_CLOSE = '</think>';
|
|
35
|
+
/** First meaningful line of a think-block body, cleaned up for a title. */
|
|
36
|
+
export function extractTitle(body) {
|
|
37
|
+
const text = body.replace(/^\s*\n/, '').replace(/\*\*/g, '').replace(/^#+\s*/, '').trim();
|
|
38
|
+
if (!text)
|
|
39
|
+
return 'Thinking…';
|
|
40
|
+
const firstLine = text.split('\n')[0].trim();
|
|
41
|
+
return firstLine.length > 72 ? firstLine.slice(0, 72).trimEnd() + '…' : firstLine;
|
|
42
|
+
}
|
|
43
|
+
export function hostOf(url) {
|
|
44
|
+
try {
|
|
45
|
+
return new URL(url).hostname.replace(/^www\./, '');
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return url;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/** A one-line summary of a tool call's arguments: the query, pattern, url or filename it named. */
|
|
52
|
+
export function formatArgSummary(_tool, rawArgs) {
|
|
53
|
+
let parsed;
|
|
54
|
+
try {
|
|
55
|
+
parsed = JSON.parse(rawArgs);
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
parsed = {};
|
|
59
|
+
}
|
|
60
|
+
const q = typeof parsed.query === 'string' ? parsed.query
|
|
61
|
+
: typeof parsed.pattern === 'string' ? parsed.pattern
|
|
62
|
+
: typeof parsed.url === 'string' ? parsed.url
|
|
63
|
+
: typeof parsed.filename === 'string' ? parsed.filename
|
|
64
|
+
: '';
|
|
65
|
+
return q ? `"${q.length > 48 ? q.slice(0, 48) + '…' : q}"` : '';
|
|
66
|
+
}
|
|
67
|
+
/** A per-tool summary of a result, parsed from the stock abilities' result
|
|
68
|
+
* shapes (web search and fetch, corpus search, grep and read); anything else
|
|
69
|
+
* falls back to the URLs it carries, else its size. */
|
|
70
|
+
export function summarizeResult(tool, raw) {
|
|
71
|
+
try {
|
|
72
|
+
const parsed = JSON.parse(raw);
|
|
73
|
+
if (tool === 'web_search' && Array.isArray(parsed)) {
|
|
74
|
+
const items = parsed;
|
|
75
|
+
const hosts = Array.from(new Set(items.map((i) => (i.url ? hostOf(i.url) : '')).filter(Boolean))).slice(0, 3);
|
|
76
|
+
const sources = items
|
|
77
|
+
.filter((i) => i.url || i.title)
|
|
78
|
+
.slice(0, 8)
|
|
79
|
+
.map((i) => ({ url: i.url, title: i.title, snippet: i.snippet, image: i.image, icon: i.icon, host: i.url ? hostOf(i.url) : undefined }));
|
|
80
|
+
return { summary: `${items.length} results`, hosts, resultCount: items.length, preview: items[0]?.title ?? null, sources: sources.length ? sources : undefined };
|
|
81
|
+
}
|
|
82
|
+
if (tool === 'search' && typeof parsed === 'object' && parsed !== null && Array.isArray(parsed.hits)) {
|
|
83
|
+
const hits = parsed.hits;
|
|
84
|
+
const sources = hits.slice(0, 8).map((h) => ({ title: h.heading || h.file, host: h.file })).filter((s) => s.title || s.host);
|
|
85
|
+
return { summary: `${hits.length} results`, hosts: [], resultCount: hits.length, preview: hits[0]?.heading ?? hits[0]?.file ?? null, sources: sources.length ? sources : undefined };
|
|
86
|
+
}
|
|
87
|
+
if (tool === 'grep' && typeof parsed === 'object' && parsed !== null) {
|
|
88
|
+
const r = parsed;
|
|
89
|
+
const matches = r.matches ?? [];
|
|
90
|
+
const sources = matches.slice(0, 8)
|
|
91
|
+
.map((m) => ({ title: m.file, host: m.line != null ? `line ${m.line}` : undefined, snippet: m.text }))
|
|
92
|
+
.filter((s) => s.title);
|
|
93
|
+
return { summary: `${r.totalMatches ?? 0} matches`, hosts: [], resultCount: r.totalMatches ?? null, preview: matches[0]?.file ?? null, sources: sources.length ? sources : undefined };
|
|
94
|
+
}
|
|
95
|
+
if (tool === 'read_file' && typeof parsed === 'object' && parsed !== null) {
|
|
96
|
+
const r = parsed;
|
|
97
|
+
if (r.error)
|
|
98
|
+
return { summary: r.error, hosts: [], resultCount: null, preview: null };
|
|
99
|
+
const sources = r.file ? [{ title: r.file }] : [];
|
|
100
|
+
return { summary: `${raw.length}b`, hosts: [], resultCount: null, preview: r.file ?? null, sources: sources.length ? sources : undefined };
|
|
101
|
+
}
|
|
102
|
+
if ((tool === 'fetch_page' || tool === 'web_fetch') && typeof parsed === 'object' && parsed !== null) {
|
|
103
|
+
const r = parsed;
|
|
104
|
+
if (r.error)
|
|
105
|
+
return { summary: r.error, hosts: [], resultCount: null, preview: null };
|
|
106
|
+
const hosts = r.url ? [hostOf(r.url)] : [];
|
|
107
|
+
const sources = r.url || r.title
|
|
108
|
+
? [{ url: r.url, title: r.title, snippet: r.excerpt, image: r.image, icon: r.icon, host: r.url ? hostOf(r.url) : undefined }]
|
|
109
|
+
: undefined;
|
|
110
|
+
return { summary: `${raw.length}b`, hosts, resultCount: null, preview: r.title ?? null, sources };
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
/* fall through to the URL scan */
|
|
115
|
+
}
|
|
116
|
+
const urls = Array.from(raw.matchAll(/https?:\/\/[^\s\])>"]+/g)).map((m) => m[0]);
|
|
117
|
+
if (urls.length > 0) {
|
|
118
|
+
return { summary: `${urls.length} links`, hosts: Array.from(new Set(urls.map(hostOf))).slice(0, 3), resultCount: urls.length, preview: null };
|
|
119
|
+
}
|
|
120
|
+
return { summary: `${raw.length}b`, hosts: [], resultCount: null, preview: null };
|
|
121
|
+
}
|
|
122
|
+
// ── immutable helpers over the roster ──────────────────────────────
|
|
123
|
+
function replaceAgent(r, id, patch) {
|
|
124
|
+
const existing = r.agents.get(id);
|
|
125
|
+
if (!existing)
|
|
126
|
+
return r;
|
|
127
|
+
const agents = new Map(r.agents);
|
|
128
|
+
agents.set(id, patch(existing));
|
|
129
|
+
return { ...r, agents };
|
|
130
|
+
}
|
|
131
|
+
function createAgent(r, id, now, patch) {
|
|
132
|
+
if (r.agents.has(id))
|
|
133
|
+
return r;
|
|
134
|
+
const base = {
|
|
135
|
+
id, label: `A${r.nextLabelIdx}`, phase: 'idle', startedAt: now, endedAt: null, tokenCount: 0, toolCallCount: 0,
|
|
136
|
+
taskIndex: null, taskDescription: null, dependencyHint: null, currentThinkId: null, pendingToolCallId: null,
|
|
137
|
+
retry: null, contentBuffer: '', recovering: false, failReason: null, timeline: [],
|
|
138
|
+
...patch,
|
|
139
|
+
};
|
|
140
|
+
const agents = new Map(r.agents);
|
|
141
|
+
agents.set(id, base);
|
|
142
|
+
return { ...r, agents, nextLabelIdx: r.nextLabelIdx + 1 };
|
|
143
|
+
}
|
|
144
|
+
const pushTimeline = (a, item) => ({ ...a, timeline: [...a.timeline, item] });
|
|
145
|
+
const updateTimeline = (a, id, update) => ({ ...a, timeline: a.timeline.map((it) => (it.id === id ? update(it) : it)) });
|
|
146
|
+
/** Open a new live think block on this agent. */
|
|
147
|
+
function openThink(r, agentId, now) {
|
|
148
|
+
const id = r.nextTimelineId;
|
|
149
|
+
const next = replaceAgent(r, agentId, (a) => pushTimeline({ ...a, currentThinkId: id, phase: 'thinking' }, { kind: 'think', id, title: 'Thinking…', body: '', live: true, openedAt: now, closedAt: null }));
|
|
150
|
+
return { ...next, nextTimelineId: r.nextTimelineId + 1 };
|
|
151
|
+
}
|
|
152
|
+
/** Close the agent's live think block with `finalBody`. */
|
|
153
|
+
function closeThink(r, agentId, finalBody, now) {
|
|
154
|
+
const agent = r.agents.get(agentId);
|
|
155
|
+
if (!agent || agent.currentThinkId === null)
|
|
156
|
+
return r;
|
|
157
|
+
const thinkId = agent.currentThinkId;
|
|
158
|
+
const title = extractTitle(finalBody);
|
|
159
|
+
return replaceAgent(r, agentId, (a) => updateTimeline({ ...a, currentThinkId: null, phase: 'content' }, thinkId, (it) => it.kind === 'think' ? { ...it, body: finalBody, title, live: false, closedAt: now } : it));
|
|
160
|
+
}
|
|
161
|
+
/** Close any live think block, keeping whatever body it holds — the recovery and tool-call paths may reach here without a `</think>`. */
|
|
162
|
+
function closeLiveThink(r, agentId, now) {
|
|
163
|
+
const agent = r.agents.get(agentId);
|
|
164
|
+
if (!agent || agent.currentThinkId === null)
|
|
165
|
+
return r;
|
|
166
|
+
const item = agent.timeline.find((it) => it.id === agent.currentThinkId);
|
|
167
|
+
return closeThink(r, agentId, item && item.kind === 'think' ? item.body : '', now);
|
|
168
|
+
}
|
|
169
|
+
/** Advance the live think block: append until `</think>`, then close on the marker and seed the content buffer with the tail. */
|
|
170
|
+
function advanceThink(r, agentId, text, tokenCount, now) {
|
|
171
|
+
const agent = r.agents.get(agentId);
|
|
172
|
+
if (!agent || agent.currentThinkId === null)
|
|
173
|
+
return r;
|
|
174
|
+
const thinkId = agent.currentThinkId;
|
|
175
|
+
const item = agent.timeline.find((it) => it.id === thinkId);
|
|
176
|
+
if (!item || item.kind !== 'think')
|
|
177
|
+
return r;
|
|
178
|
+
const combined = item.body + text;
|
|
179
|
+
const markerIdx = combined.indexOf(THINK_CLOSE);
|
|
180
|
+
if (markerIdx === -1) {
|
|
181
|
+
return replaceAgent(r, agentId, (a) => updateTimeline({ ...a, tokenCount }, thinkId, (it) => (it.kind === 'think' ? { ...it, body: combined } : it)));
|
|
182
|
+
}
|
|
183
|
+
const finalBody = combined.slice(0, markerIdx);
|
|
184
|
+
const tail = combined.slice(markerIdx + THINK_CLOSE.length);
|
|
185
|
+
return replaceAgent(closeThink(r, agentId, finalBody, now), agentId, (a) => ({ ...a, tokenCount, contentBuffer: tail }));
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Fold one agent event into the roster. Returns the same roster when the event
|
|
189
|
+
* changed nothing. An event for an unknown agent is dropped.
|
|
190
|
+
*/
|
|
191
|
+
export function foldAgents(r, ev, opts = {}) {
|
|
192
|
+
const now = (opts.now ?? Date.now)();
|
|
193
|
+
switch (ev.type) {
|
|
194
|
+
case 'agent:spawn': {
|
|
195
|
+
const decision = opts.spawn?.(ev) ?? { taskIndex: null };
|
|
196
|
+
const next = createAgent(r, ev.agentId, now, {
|
|
197
|
+
phase: decision.taskIndex !== null ? 'thinking' : 'idle',
|
|
198
|
+
taskIndex: decision.taskIndex,
|
|
199
|
+
taskDescription: decision.taskDescription ?? null,
|
|
200
|
+
dependencyHint: decision.dependencyHint ?? null,
|
|
201
|
+
});
|
|
202
|
+
return decision.taskIndex !== null ? openThink(next, ev.agentId, now) : next;
|
|
203
|
+
}
|
|
204
|
+
case 'agent:produce': {
|
|
205
|
+
const agent = r.agents.get(ev.agentId);
|
|
206
|
+
if (!agent)
|
|
207
|
+
return r;
|
|
208
|
+
if (agent.taskIndex === null)
|
|
209
|
+
return replaceAgent(r, ev.agentId, (a) => ({ ...a, tokenCount: ev.tokenCount }));
|
|
210
|
+
// Content-phase tokens (post-</think>, pre-tool_call): the model writing its tool-call JSON — the
|
|
211
|
+
// terminal tool's body lives inside it, so it streams into the buffer a renderer can read live.
|
|
212
|
+
if (agent.phase === 'content' || agent.recovering) {
|
|
213
|
+
return replaceAgent(r, ev.agentId, (a) => ({ ...a, tokenCount: ev.tokenCount, contentBuffer: a.contentBuffer + ev.text }));
|
|
214
|
+
}
|
|
215
|
+
let working = r;
|
|
216
|
+
if (agent.phase !== 'thinking' || agent.currentThinkId === null) {
|
|
217
|
+
if (agent.phase === 'tool' || agent.phase === 'idle')
|
|
218
|
+
working = openThink(working, ev.agentId, now);
|
|
219
|
+
else
|
|
220
|
+
return replaceAgent(working, ev.agentId, (a) => ({ ...a, tokenCount: ev.tokenCount })); // done or failed: count only
|
|
221
|
+
}
|
|
222
|
+
return advanceThink(working, ev.agentId, ev.text, ev.tokenCount, now);
|
|
223
|
+
}
|
|
224
|
+
case 'agent:tool_call': {
|
|
225
|
+
const agent = r.agents.get(ev.agentId);
|
|
226
|
+
if (!agent)
|
|
227
|
+
return r;
|
|
228
|
+
const working = closeLiveThink(r, ev.agentId, now);
|
|
229
|
+
if (agent.taskIndex === null) {
|
|
230
|
+
return replaceAgent(working, ev.agentId, (a) => ({ ...a, phase: 'tool', toolCallCount: a.toolCallCount + 1 }));
|
|
231
|
+
}
|
|
232
|
+
// The terminal tool fires at the stop token, but its report already streamed as content: no timeline row,
|
|
233
|
+
// the buffer clears, and `agent:return` files the report next.
|
|
234
|
+
const acting = working.agents.get(ev.agentId);
|
|
235
|
+
const wasReporting = ev.tool === opts.terminal || (acting?.contentBuffer.includes('<parameter=result>') ?? false);
|
|
236
|
+
if (wasReporting) {
|
|
237
|
+
return replaceAgent(working, ev.agentId, (a) => ({ ...a, phase: 'tool', toolCallCount: a.toolCallCount + 1, contentBuffer: '' }));
|
|
238
|
+
}
|
|
239
|
+
const id = working.nextTimelineId;
|
|
240
|
+
const next = replaceAgent(working, ev.agentId, (a) => pushTimeline({ ...a, phase: 'tool', toolCallCount: a.toolCallCount + 1, pendingToolCallId: id, contentBuffer: '' }, { kind: 'tool_call', id, tool: ev.tool, argsSummary: formatArgSummary(ev.tool, ev.args) }));
|
|
241
|
+
return { ...next, nextTimelineId: working.nextTimelineId + 1 };
|
|
242
|
+
}
|
|
243
|
+
case 'agent:tool_retry': {
|
|
244
|
+
if (!r.agents.has(ev.agentId))
|
|
245
|
+
return r;
|
|
246
|
+
return replaceAgent(r, ev.agentId, (a) => ({ ...a, retry: { tool: ev.tool, retryAt: now + ev.retryAfterMs, attempt: ev.attempt } }));
|
|
247
|
+
}
|
|
248
|
+
case 'agent:tool_result': {
|
|
249
|
+
const agent = r.agents.get(ev.agentId);
|
|
250
|
+
if (!agent)
|
|
251
|
+
return r;
|
|
252
|
+
if (agent.taskIndex === null)
|
|
253
|
+
return replaceAgent(r, ev.agentId, (a) => ({ ...a, phase: 'idle', retry: null }));
|
|
254
|
+
const summary = summarizeResult(ev.tool, ev.result);
|
|
255
|
+
const id = r.nextTimelineId;
|
|
256
|
+
const next = replaceAgent(r, ev.agentId, (a) => pushTimeline({ ...a, phase: 'idle', pendingToolCallId: null, retry: null }, {
|
|
257
|
+
kind: 'tool_result', id, tool: ev.tool, callId: agent.pendingToolCallId, byteLength: ev.result.length,
|
|
258
|
+
preview: summary.preview, hosts: Array.from(new Set(summary.hosts)), resultCount: summary.resultCount, sources: summary.sources,
|
|
259
|
+
}));
|
|
260
|
+
return { ...next, nextTimelineId: r.nextTimelineId + 1 };
|
|
261
|
+
}
|
|
262
|
+
case 'agent:return':
|
|
263
|
+
case 'agent:recovered': {
|
|
264
|
+
const agent = r.agents.get(ev.agentId);
|
|
265
|
+
if (!agent)
|
|
266
|
+
return r;
|
|
267
|
+
const working = closeLiveThink(r, ev.agentId, now);
|
|
268
|
+
if (agent.taskIndex === null) {
|
|
269
|
+
return replaceAgent(working, ev.agentId, (a) => ({ ...a, phase: 'done', endedAt: now, contentBuffer: '', recovering: false }));
|
|
270
|
+
}
|
|
271
|
+
const id = working.nextTimelineId;
|
|
272
|
+
const next = replaceAgent(working, ev.agentId, (a) => pushTimeline({ ...a, phase: 'done', endedAt: now, contentBuffer: '', recovering: false }, { kind: 'report', id, body: ev.result, tokenCount: a.tokenCount }));
|
|
273
|
+
return { ...next, nextTimelineId: working.nextTimelineId + 1 };
|
|
274
|
+
}
|
|
275
|
+
case 'agent:failed': {
|
|
276
|
+
const agent = r.agents.get(ev.agentId);
|
|
277
|
+
if (!agent || agent.phase === 'done' || agent.phase === 'failed')
|
|
278
|
+
return r;
|
|
279
|
+
const working = closeLiveThink(r, ev.agentId, now);
|
|
280
|
+
return replaceAgent(working, ev.agentId, (a) => ({ ...a, phase: 'failed', endedAt: now, contentBuffer: '', recovering: false, failReason: ev.reason }));
|
|
281
|
+
}
|
|
282
|
+
case 'agent:done': {
|
|
283
|
+
// Not `done` yet: in the stall-break path this precedes the forced recovery's produce stream and
|
|
284
|
+
// `agent:recovered`. Close any live think, step back to idle, and route what follows into the buffer.
|
|
285
|
+
const agent = r.agents.get(ev.agentId);
|
|
286
|
+
if (!agent || agent.phase === 'done' || agent.phase === 'failed')
|
|
287
|
+
return r; // terminal either way
|
|
288
|
+
const working = closeLiveThink(r, ev.agentId, now);
|
|
289
|
+
return replaceAgent(working, ev.agentId, (a) => ({ ...a, phase: 'idle', contentBuffer: '', recovering: true }));
|
|
290
|
+
}
|
|
291
|
+
default:
|
|
292
|
+
return r;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
//# sourceMappingURL=fold.js.map
|
package/dist/fold.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fold.js","sourceRoot":"","sources":["../src/fold.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@lloyal-labs/ui` — the view side of a harness, for React.
|
|
3
|
+
*
|
|
4
|
+
* The provider connects a bridge's projection once; the hooks read the fold,
|
|
5
|
+
* the wire's status, the command sink and the content plane's origin. The
|
|
6
|
+
* primitives are the pieces every harness view rebuilt: markdown with math,
|
|
7
|
+
* the one enlarged view of an asset, and what a root is. The generic agent
|
|
8
|
+
* fold is framework-free and lives at `@lloyal-labs/ui/fold`, so a fold that
|
|
9
|
+
* runs where React does not (a terminal, a desktop shell's own process) takes
|
|
10
|
+
* that entry alone.
|
|
11
|
+
*
|
|
12
|
+
* Browser-safe: nothing here imports a Node module.
|
|
13
|
+
*
|
|
14
|
+
* @packageDocumentation
|
|
15
|
+
* @category UI
|
|
16
|
+
*/
|
|
17
|
+
export { HarnessProvider, projectionFor, useHarness, useProjection, useSend, useConnection, useAvailability, useRecover, useContentOrigin } from './provider.js';
|
|
18
|
+
export type { Harness } from './provider.js';
|
|
19
|
+
export { Markdown, admitAttachmentUrls } from './markdown.js';
|
|
20
|
+
export type { MarkdownComponents } from './markdown.js';
|
|
21
|
+
export { Lightbox } from './lightbox.js';
|
|
22
|
+
export type { LightboxProps } from './lightbox.js';
|
|
23
|
+
export { resolveAsset, useAssets, pageFacts, pageList } from './assets.js';
|
|
24
|
+
export type { Asset } from './assets.js';
|
|
25
|
+
export * from './fold.js';
|
|
26
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa,EAAE,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjK,YAAY,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAC9D,YAAY,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC3E,YAAY,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,cAAc,WAAW,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@lloyal-labs/ui` — the view side of a harness, for React.
|
|
3
|
+
*
|
|
4
|
+
* The provider connects a bridge's projection once; the hooks read the fold,
|
|
5
|
+
* the wire's status, the command sink and the content plane's origin. The
|
|
6
|
+
* primitives are the pieces every harness view rebuilt: markdown with math,
|
|
7
|
+
* the one enlarged view of an asset, and what a root is. The generic agent
|
|
8
|
+
* fold is framework-free and lives at `@lloyal-labs/ui/fold`, so a fold that
|
|
9
|
+
* runs where React does not (a terminal, a desktop shell's own process) takes
|
|
10
|
+
* that entry alone.
|
|
11
|
+
*
|
|
12
|
+
* Browser-safe: nothing here imports a Node module.
|
|
13
|
+
*
|
|
14
|
+
* @packageDocumentation
|
|
15
|
+
* @category UI
|
|
16
|
+
*/
|
|
17
|
+
export { HarnessProvider, projectionFor, useHarness, useProjection, useSend, useConnection, useAvailability, useRecover, useContentOrigin } from './provider.js';
|
|
18
|
+
export { Markdown, admitAttachmentUrls } from './markdown.js';
|
|
19
|
+
export { Lightbox } from './lightbox.js';
|
|
20
|
+
export { resolveAsset, useAssets, pageFacts, pageList } from './assets.js';
|
|
21
|
+
export * from './fold.js';
|
|
22
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa,EAAE,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjK,OAAO,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAE9D,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE3E,cAAc,WAAW,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { CSSProperties, ReactElement } from 'react';
|
|
2
|
+
export interface LightboxProps {
|
|
3
|
+
/** The root of a single image to show — a photo, a page render. */
|
|
4
|
+
digest?: string;
|
|
5
|
+
/** Or a PDF to open in the browser's own viewer: the URL the content plane serves the original at. */
|
|
6
|
+
pdf?: string;
|
|
7
|
+
/** The representation's true pixel size, when the caller read it off the loaded element. */
|
|
8
|
+
dims?: string;
|
|
9
|
+
/** What is being shown, when it is not simply "the attached image". */
|
|
10
|
+
label?: string;
|
|
11
|
+
onClose: () => void;
|
|
12
|
+
/** The caller's register: the scrim, the image and the caption. */
|
|
13
|
+
styles?: {
|
|
14
|
+
scrim?: CSSProperties;
|
|
15
|
+
full?: CSSProperties;
|
|
16
|
+
pdf?: CSSProperties;
|
|
17
|
+
caption?: CSSProperties;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export declare function Lightbox({ digest, pdf, dims, label, onClose, styles }: LightboxProps): ReactElement | null;
|
|
21
|
+
//# sourceMappingURL=lightbox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lightbox.d.ts","sourceRoot":"","sources":["../src/lightbox.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAMzD,MAAM,WAAW,aAAa;IAC5B,mEAAmE;IACnE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sGAAsG;IACtG,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,4FAA4F;IAC5F,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,mEAAmE;IACnE,MAAM,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,aAAa,CAAC;QAAC,IAAI,CAAC,EAAE,aAAa,CAAC;QAAC,GAAG,CAAC,EAAE,aAAa,CAAC;QAAC,OAAO,CAAC,EAAE,aAAa,CAAA;KAAE,CAAC;CACxG;AAYD,wBAAgB,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,MAAW,EAAE,EAAE,aAAa,GAAG,YAAY,GAAG,IAAI,CA6B/G"}
|
package/dist/lightbox.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* The full-size view of one asset: a single image by its root, or a PDF in
|
|
4
|
+
* the browser's own viewer. One enlarged view for a whole app — the figure
|
|
5
|
+
* strip, a run bar's marker and a cited page in the prose all open this one,
|
|
6
|
+
* so there is one that cannot drift. Escape and a click on the scrim close it.
|
|
7
|
+
*
|
|
8
|
+
* @category UI
|
|
9
|
+
*/
|
|
10
|
+
import { useEffect } from 'react';
|
|
11
|
+
import { representationUrl } from '@lloyal-labs/media';
|
|
12
|
+
import { useContentOrigin } from './provider.js';
|
|
13
|
+
const short = (digest) => digest.replace(/^sha256:/, '').slice(0, 10);
|
|
14
|
+
const S = {
|
|
15
|
+
scrim: {
|
|
16
|
+
position: 'fixed', inset: 0, zIndex: 50, cursor: 'zoom-out', background: 'rgba(20,20,22,.82)',
|
|
17
|
+
display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 12, padding: 32,
|
|
18
|
+
},
|
|
19
|
+
full: { maxWidth: '100%', maxHeight: 'calc(100vh - 110px)', objectFit: 'contain', borderRadius: 12, background: '#fff' },
|
|
20
|
+
pdf: { width: 'min(1100px, 94vw)', height: 'calc(100vh - 110px)', border: 0, borderRadius: 12, background: '#fff' },
|
|
21
|
+
caption: { font: '12px system-ui, sans-serif', color: '#D8D8D2', margin: 0 },
|
|
22
|
+
};
|
|
23
|
+
export function Lightbox({ digest, pdf, dims, label, onClose, styles = {} }) {
|
|
24
|
+
const origin = useContentOrigin();
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
const onKey = (e) => {
|
|
27
|
+
if (e.key === 'Escape')
|
|
28
|
+
onClose();
|
|
29
|
+
};
|
|
30
|
+
window.addEventListener('keydown', onKey);
|
|
31
|
+
return () => window.removeEventListener('keydown', onKey);
|
|
32
|
+
}, [onClose]);
|
|
33
|
+
if (origin === null)
|
|
34
|
+
return null;
|
|
35
|
+
const s = { ...S, ...styles };
|
|
36
|
+
if (pdf !== undefined) {
|
|
37
|
+
return (_jsxs("div", { style: s.scrim, role: "dialog", "aria-modal": "true", "aria-label": label ?? 'Attached document', onClick: onClose, children: [_jsx("iframe", { src: pdf, title: label ?? 'Attached document', style: s.pdf, onClick: (e) => e.stopPropagation() }), _jsxs("p", { style: s.caption, children: [label ?? 'the attached document', " \u00B7 the file as attached"] })] }));
|
|
38
|
+
}
|
|
39
|
+
if (digest === undefined)
|
|
40
|
+
return null;
|
|
41
|
+
return (_jsxs("div", { style: s.scrim, role: "dialog", "aria-modal": "true", "aria-label": label ?? 'Attached image, full size', onClick: onClose, children: [_jsx("img", { src: representationUrl(origin, digest), alt: label ?? 'Attached image, as the model received it', style: s.full }), _jsxs("p", { style: s.caption, children: [label ?? 'what the model saw', dims ? ` · ${dims}` : '', " \u00B7 ", short(digest)] })] }));
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=lightbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lightbox.js","sourceRoot":"","sources":["../src/lightbox.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { CSSProperties } from 'react';
|
|
2
|
+
import type { Components } from 'react-markdown';
|
|
3
|
+
import 'katex/dist/katex.min.css';
|
|
4
|
+
export type { Components as MarkdownComponents } from 'react-markdown';
|
|
5
|
+
/** The content plane's scheme is admitted; every other unknown scheme is stripped, as react-markdown does. */
|
|
6
|
+
export declare const admitAttachmentUrls: (url: string) => string;
|
|
7
|
+
/** Memoized on its props: a settled block keeps its parse while a sibling streams. */
|
|
8
|
+
export declare const Markdown: import("react").NamedExoticComponent<{
|
|
9
|
+
markdown: string;
|
|
10
|
+
/** The caller's renderers — links with citation chips, headings with anchors, the prose's own type. */
|
|
11
|
+
components?: Components;
|
|
12
|
+
style?: CSSProperties;
|
|
13
|
+
}>;
|
|
14
|
+
//# sourceMappingURL=markdown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../src/markdown.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,aAAa,EAAgB,MAAM,OAAO,CAAC;AAEzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAIjD,OAAO,0BAA0B,CAAC;AAElC,YAAY,EAAE,UAAU,IAAI,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAUvE,8GAA8G;AAC9G,eAAO,MAAM,mBAAmB,GAAI,KAAK,MAAM,KAAG,MACgB,CAAC;AAEnE,sFAAsF;AACtF,eAAO,MAAM,QAAQ;cACT,MAAM;IAChB,uGAAuG;iBAC1F,UAAU;YACf,aAAa;EAerB,CAAC"}
|
package/dist/markdown.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Markdown in a harness view: GitHub-flavoured, with math set by KaTeX, links
|
|
4
|
+
* left to the caller's renderers, and the content plane's own scheme admitted
|
|
5
|
+
* through the URL transform so a cited page (`attachment://…/page/n`) reaches
|
|
6
|
+
* the caller's link component instead of being stripped as unknown.
|
|
7
|
+
*
|
|
8
|
+
* Math takes the document's own face where that is safe: inline runs inherit
|
|
9
|
+
* the surrounding font, while stacked constructs (fractions, radicals,
|
|
10
|
+
* accents, sized operators and delimiters) keep KaTeX's fonts — its metrics
|
|
11
|
+
* position them, and an inherited face's taller numerals crash into the bar.
|
|
12
|
+
*
|
|
13
|
+
* @category UI
|
|
14
|
+
*/
|
|
15
|
+
import { memo } from 'react';
|
|
16
|
+
import ReactMarkdown, { defaultUrlTransform } from 'react-markdown';
|
|
17
|
+
import remarkGfm from 'remark-gfm';
|
|
18
|
+
import remarkMath from 'remark-math';
|
|
19
|
+
import rehypeKatex from 'rehype-katex';
|
|
20
|
+
import 'katex/dist/katex.min.css';
|
|
21
|
+
const MATH = `
|
|
22
|
+
.katex { font-size: 1em !important; }
|
|
23
|
+
.katex, .katex *:not(.delimsizing, .op-symbol) { font-family: inherit !important; }
|
|
24
|
+
.katex :is(.mfrac, .sqrt, .root, .accent) * {
|
|
25
|
+
font-family: KaTeX_Main, "Times New Roman", serif !important;
|
|
26
|
+
}
|
|
27
|
+
`;
|
|
28
|
+
/** The content plane's scheme is admitted; every other unknown scheme is stripped, as react-markdown does. */
|
|
29
|
+
export const admitAttachmentUrls = (url) => url.startsWith('attachment://') ? url : defaultUrlTransform(url);
|
|
30
|
+
/** Memoized on its props: a settled block keeps its parse while a sibling streams. */
|
|
31
|
+
export const Markdown = memo(function Markdown({ markdown, components, style }) {
|
|
32
|
+
return (_jsxs("div", { style: style, children: [_jsx("style", { children: MATH }), _jsx(ReactMarkdown, { remarkPlugins: [remarkGfm, remarkMath], rehypePlugins: [[rehypeKatex, { throwOnError: false }]], urlTransform: admitAttachmentUrls, components: components, children: markdown })] }));
|
|
33
|
+
});
|
|
34
|
+
//# sourceMappingURL=markdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.js","sourceRoot":"","sources":["../src/markdown.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAE7B,OAAO,aAAa,EAAE,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAEpE,OAAO,SAAS,MAAM,YAAY,CAAC;AACnC,OAAO,UAAU,MAAM,aAAa,CAAC;AACrC,OAAO,WAAW,MAAM,cAAc,CAAC;AACvC,OAAO,0BAA0B,CAAC;AAIlC,MAAM,IAAI,GAAG;;;;;;CAMZ,CAAC;AAEF,8GAA8G;AAC9G,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,GAAW,EAAU,EAAE,CACzD,GAAG,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;AAEnE,sFAAsF;AACtF,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,QAAQ,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,EAK3E;IACC,OAAO,CACL,eAAK,KAAK,EAAE,KAAK,aACf,0BAAQ,IAAI,GAAS,EACrB,KAAC,aAAa,IACZ,aAAa,EAAE,CAAC,SAAS,EAAE,UAAU,CAAC,EACtC,aAAa,EAAE,CAAC,CAAC,WAAW,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAC,EACvD,YAAY,EAAE,mBAAmB,EACjC,UAAU,EAAE,UAAU,YAErB,QAAQ,GACK,IACZ,CACP,CAAC;AACJ,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { ReactElement, ReactNode } from 'react';
|
|
2
|
+
import type { Availability, Bridge, Projection, WireStatus } from '@lloyal-labs/binding';
|
|
3
|
+
export interface Harness<E, C, S extends object> {
|
|
4
|
+
bridge: Bridge<E, C, S>;
|
|
5
|
+
projection: Projection<S>;
|
|
6
|
+
}
|
|
7
|
+
/** The one projection over a bridge — the provider's, shared with a consumer outside React (a history adapter). */
|
|
8
|
+
export declare function projectionFor<E, C, S extends object>(bridge: Bridge<E, C, S>, initialState: S, reduce: (state: S, ev: E) => S): Projection<S>;
|
|
9
|
+
export declare function HarnessProvider<E, C, S extends object>({ bridge, initialState, reduce, children }: {
|
|
10
|
+
bridge: Bridge<E, C, S>;
|
|
11
|
+
initialState: S;
|
|
12
|
+
reduce: (state: S, ev: E) => S;
|
|
13
|
+
children: ReactNode;
|
|
14
|
+
}): ReactElement;
|
|
15
|
+
/** The provider's bridge and projection, for a consumer outside the hooks (a history adapter). */
|
|
16
|
+
export declare function useHarness<E = unknown, C = unknown, S extends object = object>(): Harness<E, C, S>;
|
|
17
|
+
/** Read a derivation of the folded state, memoized per fold. */
|
|
18
|
+
export declare function useProjection<S extends object, T>(select: (state: S) => T): T;
|
|
19
|
+
/** Dispatch a command to the harness. */
|
|
20
|
+
export declare function useSend<C>(): (command: C) => void;
|
|
21
|
+
/** The wire's status. A bridge without `onStatus` (in-process) reads 'connected' forever. */
|
|
22
|
+
export declare function useConnection(): WireStatus;
|
|
23
|
+
/**
|
|
24
|
+
* Whether this harness can take work, and if not, why — the question a view actually asks.
|
|
25
|
+
*
|
|
26
|
+
* Derived from the transport's status and the host's session phase, because neither answers it
|
|
27
|
+
* alone: a queued reader's socket is healthy, and an ended session is followed by a close that
|
|
28
|
+
* reads as a network failure. Prefer this to {@link useConnection}, which is the transport fact
|
|
29
|
+
* on its own.
|
|
30
|
+
*/
|
|
31
|
+
export declare function useAvailability(): Availability;
|
|
32
|
+
/**
|
|
33
|
+
* Ask the placement for a working harness — or null where this bridge cannot provide one.
|
|
34
|
+
*
|
|
35
|
+
* A view knows WHEN recovery is wanted and never what it costs: a browser opens a new connection
|
|
36
|
+
* because a served host cannot re-admit an existing one; a desktop shell starts a new engine while
|
|
37
|
+
* its renderer's IPC link stays up throughout. Same button, different price, and the view pays
|
|
38
|
+
* neither.
|
|
39
|
+
*/
|
|
40
|
+
export declare function useRecover(): (() => void) | null;
|
|
41
|
+
/** The content plane's origin, or null on a bridge without one. */
|
|
42
|
+
export declare function useContentOrigin(): string | null;
|
|
43
|
+
//# sourceMappingURL=provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.tsx"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAErD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAgB,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvG,MAAM,WAAW,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,MAAM;IAC7C,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACxB,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;CAC3B;AASD,mHAAmH;AACnH,wBAAgB,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAO7I;AAED,wBAAgB,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,MAAM,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE;IAClG,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACxB,YAAY,EAAE,CAAC,CAAC;IAChB,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;IAC/B,QAAQ,EAAE,SAAS,CAAC;CACrB,GAAG,YAAY,CAGf;AAED,kGAAkG;AAClG,wBAAgB,UAAU,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM,KAAK,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAIlG;AAID,gEAAgE;AAChE,wBAAgB,aAAa,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAc7E;AAED,yCAAyC;AACzC,wBAAgB,OAAO,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,KAAK,IAAI,CAGjD;AAqCD,6FAA6F;AAC7F,wBAAgB,aAAa,IAAI,UAAU,CAI1C;AA4CD;;;;;;;GAOG;AACH,wBAAgB,eAAe,IAAI,YAAY,CAI9C;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAGhD;AAED,mEAAmE;AACnE,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,IAAI,CAGhD"}
|
package/dist/provider.js
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The projection, in React: a provider that connects a bridge once, and hooks
|
|
3
|
+
* that read the fold, the wire's status, the command sink and the content
|
|
4
|
+
* plane's origin. One projection per provider; a remount under the same bridge
|
|
5
|
+
* reattaches to the running fold, it never re-subscribes or resets.
|
|
6
|
+
*
|
|
7
|
+
* `useProjection(select)` memoizes per fold: the state is immutable between
|
|
8
|
+
* events, so a named selector returns the SAME reference until the next fold —
|
|
9
|
+
* what `useSyncExternalStore` needs. The contract: a selector with a stable
|
|
10
|
+
* identity may build objects; an inline selector must return a primitive.
|
|
11
|
+
*
|
|
12
|
+
* The folded state must be an OBJECT, and a new one on every event. Both halves
|
|
13
|
+
* are load-bearing and neither is a style preference: the memo is a `WeakMap`
|
|
14
|
+
* keyed by the snapshot, so a scalar or `null` state is not a legal key at all,
|
|
15
|
+
* and a state mutated in place keeps its identity and so keeps returning the
|
|
16
|
+
* selection cached against the previous fold. `S extends object` states the
|
|
17
|
+
* first half to the compiler. The second is a discipline the type system cannot
|
|
18
|
+
* carry, which is why it is written here.
|
|
19
|
+
*
|
|
20
|
+
* @category UI
|
|
21
|
+
*/
|
|
22
|
+
import { createContext, createElement, useContext, useMemo, useSyncExternalStore } from 'react';
|
|
23
|
+
import { connectProjection, availabilityOf } from '@lloyal-labs/binding';
|
|
24
|
+
// `object`, not `unknown`, is what the erased context can say now that `S` is
|
|
25
|
+
// constrained — the hooks below cast back out of it exactly as before.
|
|
26
|
+
const HarnessContext = createContext(null);
|
|
27
|
+
/** One projection per bridge, for the life of the page: a React remount under the same bridge reattaches. */
|
|
28
|
+
const projections = new WeakMap();
|
|
29
|
+
/** The one projection over a bridge — the provider's, shared with a consumer outside React (a history adapter). */
|
|
30
|
+
export function projectionFor(bridge, initialState, reduce) {
|
|
31
|
+
let projection = projections.get(bridge);
|
|
32
|
+
if (!projection) {
|
|
33
|
+
projection = connectProjection(bridge, initialState, reduce);
|
|
34
|
+
projections.set(bridge, projection);
|
|
35
|
+
}
|
|
36
|
+
return projection;
|
|
37
|
+
}
|
|
38
|
+
export function HarnessProvider({ bridge, initialState, reduce, children }) {
|
|
39
|
+
const value = useMemo(() => ({ bridge, projection: projectionFor(bridge, initialState, reduce) }), [bridge]);
|
|
40
|
+
return createElement(HarnessContext.Provider, { value: value }, children);
|
|
41
|
+
}
|
|
42
|
+
/** The provider's bridge and projection, for a consumer outside the hooks (a history adapter). */
|
|
43
|
+
export function useHarness() {
|
|
44
|
+
const h = useContext(HarnessContext);
|
|
45
|
+
if (!h)
|
|
46
|
+
throw new Error('useHarness: no HarnessProvider above this component');
|
|
47
|
+
return h;
|
|
48
|
+
}
|
|
49
|
+
const derived = new WeakMap();
|
|
50
|
+
/** Read a derivation of the folded state, memoized per fold. */
|
|
51
|
+
export function useProjection(select) {
|
|
52
|
+
const { projection } = useHarness();
|
|
53
|
+
const read = () => {
|
|
54
|
+
const state = projection.getSnapshot();
|
|
55
|
+
let memo = derived.get(state);
|
|
56
|
+
if (!memo) {
|
|
57
|
+
memo = new Map();
|
|
58
|
+
derived.set(state, memo);
|
|
59
|
+
}
|
|
60
|
+
const key = select;
|
|
61
|
+
if (!memo.has(key))
|
|
62
|
+
memo.set(key, select(state));
|
|
63
|
+
return memo.get(key);
|
|
64
|
+
};
|
|
65
|
+
return useSyncExternalStore(projection.subscribe, read, read);
|
|
66
|
+
}
|
|
67
|
+
/** Dispatch a command to the harness. */
|
|
68
|
+
export function useSend() {
|
|
69
|
+
const { bridge } = useHarness();
|
|
70
|
+
return bridge.send;
|
|
71
|
+
}
|
|
72
|
+
/** One status per bridge, for the life of the page. React reads `getSnapshot`
|
|
73
|
+
* during render, so the status it reads must outlive the render that reads it:
|
|
74
|
+
* the bridge is told once, here, and every renderer of it shares that one
|
|
75
|
+
* answer. A bridge without `onStatus` (in-process) never leaves 'connected'. */
|
|
76
|
+
const statuses = new WeakMap();
|
|
77
|
+
function statusFor(bridge) {
|
|
78
|
+
let store = statuses.get(bridge);
|
|
79
|
+
if (!store) {
|
|
80
|
+
let status = 'connected';
|
|
81
|
+
const listeners = new Set();
|
|
82
|
+
bridge.onStatus?.((next) => {
|
|
83
|
+
status = next;
|
|
84
|
+
for (const notify of listeners)
|
|
85
|
+
notify();
|
|
86
|
+
});
|
|
87
|
+
store = {
|
|
88
|
+
subscribe(notify) {
|
|
89
|
+
listeners.add(notify);
|
|
90
|
+
return () => { listeners.delete(notify); };
|
|
91
|
+
},
|
|
92
|
+
getSnapshot: () => status,
|
|
93
|
+
};
|
|
94
|
+
statuses.set(bridge, store);
|
|
95
|
+
}
|
|
96
|
+
return store;
|
|
97
|
+
}
|
|
98
|
+
/** The status a server render reads: no wire has been asked yet. */
|
|
99
|
+
const connected = () => 'connected';
|
|
100
|
+
/** The wire's status. A bridge without `onStatus` (in-process) reads 'connected' forever. */
|
|
101
|
+
export function useConnection() {
|
|
102
|
+
const { bridge } = useHarness();
|
|
103
|
+
const wire = statusFor(bridge);
|
|
104
|
+
return useSyncExternalStore(wire.subscribe, wire.getSnapshot, connected);
|
|
105
|
+
}
|
|
106
|
+
/** One derivation per bridge, for the life of the page — the same reason the status has one. */
|
|
107
|
+
const availabilities = new WeakMap();
|
|
108
|
+
function availabilityFor(bridge) {
|
|
109
|
+
let store = availabilities.get(bridge);
|
|
110
|
+
if (!store) {
|
|
111
|
+
// A bridge with no droppable link is up, and one with no session plane has a single implicit
|
|
112
|
+
// session that is live: nothing queues it and nothing reaps it, so "waiting" and "ended" are not
|
|
113
|
+
// states it can be in. This is the ONE place a placement difference is stated; the derivation
|
|
114
|
+
// itself knows no placements.
|
|
115
|
+
let wire = 'connected';
|
|
116
|
+
let session = bridge.onSession ? null : { phase: 'live' };
|
|
117
|
+
let value = availabilityOf(session, wire);
|
|
118
|
+
const listeners = new Set();
|
|
119
|
+
const settle = () => {
|
|
120
|
+
const next = availabilityOf(session, wire);
|
|
121
|
+
if (next === value)
|
|
122
|
+
return;
|
|
123
|
+
value = next;
|
|
124
|
+
for (const notify of listeners)
|
|
125
|
+
notify();
|
|
126
|
+
};
|
|
127
|
+
bridge.onStatus?.((next) => { wire = next; settle(); });
|
|
128
|
+
bridge.onSession?.((next) => { session = next; settle(); });
|
|
129
|
+
store = {
|
|
130
|
+
subscribe(notify) {
|
|
131
|
+
listeners.add(notify);
|
|
132
|
+
return () => { listeners.delete(notify); };
|
|
133
|
+
},
|
|
134
|
+
getSnapshot: () => value,
|
|
135
|
+
};
|
|
136
|
+
availabilities.set(bridge, store);
|
|
137
|
+
}
|
|
138
|
+
return store;
|
|
139
|
+
}
|
|
140
|
+
/** What a server render reads: nothing has been asked of either plane yet. */
|
|
141
|
+
const starting = () => 'connecting';
|
|
142
|
+
/**
|
|
143
|
+
* Whether this harness can take work, and if not, why — the question a view actually asks.
|
|
144
|
+
*
|
|
145
|
+
* Derived from the transport's status and the host's session phase, because neither answers it
|
|
146
|
+
* alone: a queued reader's socket is healthy, and an ended session is followed by a close that
|
|
147
|
+
* reads as a network failure. Prefer this to {@link useConnection}, which is the transport fact
|
|
148
|
+
* on its own.
|
|
149
|
+
*/
|
|
150
|
+
export function useAvailability() {
|
|
151
|
+
const { bridge } = useHarness();
|
|
152
|
+
const store = availabilityFor(bridge);
|
|
153
|
+
return useSyncExternalStore(store.subscribe, store.getSnapshot, starting);
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Ask the placement for a working harness — or null where this bridge cannot provide one.
|
|
157
|
+
*
|
|
158
|
+
* A view knows WHEN recovery is wanted and never what it costs: a browser opens a new connection
|
|
159
|
+
* because a served host cannot re-admit an existing one; a desktop shell starts a new engine while
|
|
160
|
+
* its renderer's IPC link stays up throughout. Same button, different price, and the view pays
|
|
161
|
+
* neither.
|
|
162
|
+
*/
|
|
163
|
+
export function useRecover() {
|
|
164
|
+
const { bridge } = useHarness();
|
|
165
|
+
return useMemo(() => (bridge.recover ? () => bridge.recover() : null), [bridge]);
|
|
166
|
+
}
|
|
167
|
+
/** The content plane's origin, or null on a bridge without one. */
|
|
168
|
+
export function useContentOrigin() {
|
|
169
|
+
const { bridge } = useHarness();
|
|
170
|
+
return bridge.contentOrigin?.() ?? null;
|
|
171
|
+
}
|
|
172
|
+
//# sourceMappingURL=provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.tsx"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lloyal-labs/ui",
|
|
3
|
+
"version": "0.1.0-alpha.6",
|
|
4
|
+
"description": "The view side of a harness: the projection provider and hooks over a bridge, the generic agent fold, and the prose and figure primitives",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"default": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./fold": {
|
|
14
|
+
"types": "./dist/fold.d.ts",
|
|
15
|
+
"default": "./dist/fold.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"publishConfig": {
|
|
19
|
+
"access": "public"
|
|
20
|
+
},
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+https://github.com/lloyal-ai/hdk.git",
|
|
24
|
+
"directory": "packages/ui"
|
|
25
|
+
},
|
|
26
|
+
"homepage": "https://github.com/lloyal-ai/hdk/tree/main/packages/ui#readme",
|
|
27
|
+
"bugs": {
|
|
28
|
+
"url": "https://github.com/lloyal-ai/hdk/issues"
|
|
29
|
+
},
|
|
30
|
+
"keywords": [
|
|
31
|
+
"ui",
|
|
32
|
+
"react",
|
|
33
|
+
"harness",
|
|
34
|
+
"projection",
|
|
35
|
+
"markdown"
|
|
36
|
+
],
|
|
37
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
38
|
+
"files": [
|
|
39
|
+
"dist/",
|
|
40
|
+
"LICENSE"
|
|
41
|
+
],
|
|
42
|
+
"scripts": {
|
|
43
|
+
"build": "tsc -p tsconfig.json"
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"@lloyal-labs/binding": "0.2.0-alpha.6",
|
|
47
|
+
"@lloyal-labs/media": "0.2.0-alpha.6",
|
|
48
|
+
"katex": "^0.16.22",
|
|
49
|
+
"react-markdown": "^10.1.0",
|
|
50
|
+
"rehype-katex": "^7.0.1",
|
|
51
|
+
"remark-gfm": "^4.0.1",
|
|
52
|
+
"remark-math": "^6.0.0"
|
|
53
|
+
},
|
|
54
|
+
"peerDependencies": {
|
|
55
|
+
"react": "^18.3.0 || ^19.0.0"
|
|
56
|
+
}
|
|
57
|
+
}
|