isorite 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/README.md +2 -5
- package/dist/core.js +91 -7
- package/dist/main.js +163 -179
- package/docs/setup-for-agents.md +11 -36
- package/docs/setup.md +20 -61
- package/docs/terminal.md +28 -80
- package/package.json +1 -1
- package/web/_app/immutable/assets/0.BXPxx6Q0.css +1 -0
- package/web/_app/immutable/assets/{5.DbDKXCoO.css → 5.rBvyRuST.css} +1 -1
- package/web/_app/immutable/assets/{7.ljiu9bn5.css → 7.C00vyVPo.css} +1 -1
- package/web/_app/immutable/assets/Drawing.Q7J9MyIo.css +1 -0
- package/web/_app/immutable/assets/{NoteList.F579Zvj_.css → NoteList.E6jC-AtZ.css} +1 -1
- package/web/_app/immutable/assets/Timeline.LsRXYIBv.css +1 -0
- package/web/_app/immutable/assets/ground.hxi5N5fC.css +1 -0
- package/web/_app/immutable/chunks/{DGmSCGD3.js → 4kgFUGOH.js} +1 -1
- package/web/_app/immutable/chunks/8SS1q0nk.js +7 -0
- package/web/_app/immutable/chunks/{CfL6O_ia.js → BK6pLgdi.js} +1 -1
- package/web/_app/immutable/chunks/{DuLysVkb.js → Bk_JinGf.js} +1 -1
- package/web/_app/immutable/chunks/CFEI5lV9.js +1 -0
- package/web/_app/immutable/chunks/{BgT6ZdzK.js → CiMp12cC.js} +1 -1
- package/web/_app/immutable/chunks/{mLFVM17H.js → D4YEq54N.js} +1 -1
- package/web/_app/immutable/chunks/{CMeq8te_.js → DDCg82xL.js} +1 -1
- package/web/_app/immutable/chunks/DThNJvmp.js +1 -0
- package/web/_app/immutable/chunks/{DNjLZcwq.js → D_jbSWJl.js} +1 -1
- package/web/_app/immutable/chunks/DbeMVOH4.js +1 -0
- package/web/_app/immutable/chunks/{CODXTnUW.js → DsQj0LyB.js} +4 -4
- package/web/_app/immutable/chunks/{DktGnzDy.js → Uo6irDQW.js} +80 -79
- package/web/_app/immutable/chunks/{DaulBP5z.js → jTXVas70.js} +1 -1
- package/web/_app/immutable/entry/app.CvK8zypr.js +2 -0
- package/web/_app/immutable/entry/start.Dcgm6sQd.js +1 -0
- package/web/_app/immutable/nodes/0.0TdRBEoR.js +26 -0
- package/web/_app/immutable/nodes/{1.C-RxYNx3.js → 1.Dchqgt4j.js} +1 -1
- package/web/_app/immutable/nodes/2.C0CMUdSu.js +1 -0
- package/web/_app/immutable/nodes/3.MjtWDMWd.js +1 -0
- package/web/_app/immutable/nodes/4.hhS0SQta.js +2 -0
- package/web/_app/immutable/nodes/5.C33_cw2J.js +9 -0
- package/web/_app/immutable/nodes/6.owNfwwRl.js +1 -0
- package/web/_app/immutable/nodes/7.BpxHVHoY.js +1 -0
- package/web/_app/version.json +1 -1
- package/web/index.html +20 -19
- package/web/_app/immutable/assets/0.DcsDj0O1.css +0 -1
- package/web/_app/immutable/assets/Timeline.KTc3LKuK.css +0 -1
- package/web/_app/immutable/assets/drawn.CHbcoujQ.css +0 -1
- package/web/_app/immutable/chunks/BYSDTLqw.js +0 -1
- package/web/_app/immutable/chunks/DDVefAkE.js +0 -7
- package/web/_app/immutable/chunks/Db_gdTNI.js +0 -1
- package/web/_app/immutable/chunks/F7HCRtmu.js +0 -1
- package/web/_app/immutable/chunks/wxBqjpRy.js +0 -1
- package/web/_app/immutable/entry/app.wp4GfiBT.js +0 -2
- package/web/_app/immutable/entry/start.PPXyd7_0.js +0 -1
- package/web/_app/immutable/nodes/0.JerS9yOA.js +0 -26
- package/web/_app/immutable/nodes/2.Bbkruoyi.js +0 -1
- package/web/_app/immutable/nodes/3.BkpGKa9k.js +0 -1
- package/web/_app/immutable/nodes/4.Bj25nsxG.js +0 -2
- package/web/_app/immutable/nodes/5.D9sfzyBX.js +0 -9
- package/web/_app/immutable/nodes/6.Di1re0aR.js +0 -1
- package/web/_app/immutable/nodes/7.MWEn-qPC.js +0 -1
package/dist/main.js
CHANGED
|
@@ -346,7 +346,7 @@ var init_data = __esmMin((() => {
|
|
|
346
346
|
//#region packages/kit/src/context.gen.ts
|
|
347
347
|
var REFERENCE, RECIPES;
|
|
348
348
|
var init_context_gen = __esmMin((() => {
|
|
349
|
-
REFERENCE = "# The kit (isorite kit 1)\n\nAn artifact is one HTML file: markup, perhaps a script, and a manifest in its `<head>`. isorite gives it the kit
|
|
349
|
+
REFERENCE = "# The kit (isorite kit 1)\n\nAn artifact is one HTML file: markup, perhaps a script, and a manifest in its `<head>`. isorite gives it the kit: the look (every colour, font and corner), the elements below, and `window.iso`. Write what it shows and does, never how it looks: no colour, font family or border-radius of your own.\n\n## The file\n\n```html\n<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<title>Title</title>\n<meta name=\"description\" content=\"One sentence: what it shows, and what can be done with it.\">\n<meta name=\"isorite:kit\" content=\"1\">\n<meta name=\"isorite:uses\" content=\"runs.csv other.csv\">\n<style>/* layout only, if needed */</style>\n</head>\n<body>\n<iso-page>\n <header><h1>Title</h1><p>The question it answers, in a sentence or two.</p></header>\n <iso-grid>\n <iso-panel class=\"wide\"><h2>Name <span>a short reading</span></h2> … </iso-panel>\n <iso-panel><h2>…</h2> … </iso-panel>\n </iso-grid>\n</iso-page>\n</body>\n</html>\n```\n\n`write_artifact` fills in the title, description and manifest from its arguments, so they are always right.\n\n## Layout\n\n- `<iso-grid>`: panels in two columns (`style=\"--cols: 3\"` for three); `<iso-panel class=\"wide\">` spans the row.\n- `<iso-panel>`: its first child is `<h2>`; a `<span>` in the `h2` is a soft aside. A `<p>` in a panel is a caption: what the panel shows, in a sentence.\n- `<iso-row>`: controls side by side. `<iso-stats>`: big numbers side by side.\n\n## Data, with no script\n\nEvery element with `data=\"file.csv\"` reads it itself. Several files are one table: `data=\"euler.csv leapfrog.csv\"` adds a column `file` (`euler`, `leapfrog`) to compare them with `by=\"file\"`. `where=\"integrator=leapfrog\"` keeps some rows; `where=\"t<=$t\"` compares with a control's value. `abs(col)` is a column's size.\n\n- `<iso-chart data=\"f.csv\" x=\"t\" y=\"energy\" by=\"body\">`: a chart.\n - `type`: `line` (default), `dot`, `bar`, `area`, `step`.\n - `y` may name several columns: `y=\"kinetic potential total\"`, each its own line.\n - `by`: a column whose values are the series.\n - `x-scale`, `y-scale`: `linear` or `log`, or `$name` to follow a control (`y-scale=\"$scale\"`).\n - `x-label`, `y-label`: the axis with its unit (`\"time (s)\"`). `height` in pixels (260).\n - `at=\"t\"`: follows the control `t`. A rule where x is its value; or, when the data has a column `t` and x is another column (a path in x and y over time), a dot on each series at the row whose `t` is nearest it.\n- `<iso-table data=\"f.csv\" columns=\"a b c\" limit=\"50\">`: the rows.\n- `<iso-stat data=\"f.csv\" column=\"err\" of=\"max\" label=\"worst error\" tone=\"gold\">`: one number. `of`: `min`, `max`, `mean`, `sum`, `count`, `first`, `last`. Tones: `gold`, `blue`, `green`, `rose`. Without `data`, set it from a script: `el.value = 0.0023`.\n- `<iso-chart3d data=\"f.csv\" x=\"x\" y=\"y\" z=\"z\" by=\"body\" at=\"t\">`: points or paths in 3D, turned by dragging.\n- `<iso-model src=\"part.glb\">`: a 3D model (glTF, GLB, STL, OBJ), turned by dragging. List it in isorite:uses.\n\n## Text and maths\n\n- A `<p>` in a panel is its caption. Maths is written as in a note: `$E = \\tfrac12 m v^2$` inline, `$$…$$` on a line of its own; the kit sets it. `<iso-math>\\frac{a}{b}</iso-math>` is a formula alone.\n- Never name the theme's colours in text (\"the lattice line\"): a chart's legend says which series is which.\n\n## Controls\n\nEach writes its value to `iso.state[name]`; elements that name it (`at=\"t\"`, `$t`) follow it.\n\n- `<iso-slider name=\"dt\" label=\"time step\" min=\"0.001\" max=\"0.05\" step=\"0.001\" value=\"0.01\" digits=\"3\">`\n- `<iso-select name=\"scale\" label=\"scale\" options=\"linear log\">`: one of several.\n- `<iso-toggle name=\"softened\" label=\"softened\" value=\"true\">`: on or off.\n- `<iso-play name=\"t\" min=\"0\" max=\"12\" speed=\"1.5\">`: plays `iso.state.t` from min to max, and pauses.\n- `<iso-note href=\"physics/softening\">softening</iso-note>`: opens a note in isorite.\n\n## Script, when markup isn't enough\n\nFor a simulation or anything computed. Put it at the end of the body.\n\n- `const rows = await iso.data(\"f.csv\")`: the rows as objects, numbers as numbers.\n- `iso.state.name`, `iso.watch((name) => …)`: the shared state; `watch` runs after any change.\n- `iso.loop((dt, t) => …)`: runs every frame (dt in seconds), paused when hidden. Returns a stop function.\n- `<iso-canvas height=\"320\" id=\"sim\">` and `document.getElementById(\"sim\").draw = (ctx, w, h, t) => { … }`: draw on a canvas sized to its panel; call `.redraw()` after a change. `t` is the theme: `t.text`, `t.soft`, `t.faint`, `t.line`, `t.lattice` (blue), `t.growth` (gold), `t.malachite` (green), `t.rose`, `t.series[i]`, `t.ui` (the font).\n- A chart of what the script computes: `chart.rows = [{ t: 0, energy: -1.3 }, …]` on an `<iso-chart>` with no `data`.\n- `iso.format(x)`: a number to read (3 figures, 2.3×10⁻³). `iso.tokens()`: the theme, as `t` above.\n- In CSS: `var(--text)`, `var(--text-soft)`, `var(--text-faint)`, `var(--line)`, `var(--lattice)`, `var(--growth)`, `var(--malachite)`, `var(--rose)`, `var(--font-ui)`, `var(--font-text)`.\n\n## Rules (write_artifact checks them, and refuses a file that breaks one)\n\n1. Every file read (`data=\"…\"`, `src=\"…\"`, `iso.data(\"…\")`) is in `uses`, and exists: call `read_data` first.\n2. Every column named is in its file, spelt as `read_data` gives it.\n3. No colour, font family or border-radius of its own: no `#hex`, `rgb(…)`, `white`, `Arial`. Use the tokens.\n4. No network: no `http…` address, no `<script src>`, no `fetch`. The kit is given; everything else is in the file.\n5. Under 200 kB: data stays in data files.\n6. No text that tells how to use it (\"drag to rotate\", \"click here\"): a label says what a thing is.\n\n## What good is\n\nEvery panel answers a question about the data, with a caption saying what to see. Numbers are read out. Axes say what they measure, with units. Controls change what is drawn at once. Nothing is decoration.\n";
|
|
350
350
|
RECIPES = {
|
|
351
351
|
"dashboard": {
|
|
352
352
|
"about": "a dashboard of one data file: numbers, charts and a table, in markup only",
|
|
@@ -1570,6 +1570,79 @@ var init_source = __esmMin((() => {
|
|
|
1570
1570
|
};
|
|
1571
1571
|
}));
|
|
1572
1572
|
//#endregion
|
|
1573
|
+
//#region packages/core/src/unwrap.ts
|
|
1574
|
+
function unwrap(text) {
|
|
1575
|
+
const lines = text.split("\n"), out = [];
|
|
1576
|
+
let i = 0, fence = "", maths = false;
|
|
1577
|
+
/** What the last line written may be continued by: prose, a quoted line, or nothing. */
|
|
1578
|
+
let open = "";
|
|
1579
|
+
if (lines[0] === "---") {
|
|
1580
|
+
const end = lines.indexOf("---", 1);
|
|
1581
|
+
if (end > 0) {
|
|
1582
|
+
out.push(...lines.slice(0, end + 1));
|
|
1583
|
+
i = end + 1;
|
|
1584
|
+
}
|
|
1585
|
+
}
|
|
1586
|
+
for (; i < lines.length; i++) {
|
|
1587
|
+
const l = lines[i], t = l.trim();
|
|
1588
|
+
if (fence) {
|
|
1589
|
+
out.push(l);
|
|
1590
|
+
if (t.startsWith(fence)) fence = "";
|
|
1591
|
+
continue;
|
|
1592
|
+
}
|
|
1593
|
+
if (maths) {
|
|
1594
|
+
out.push(l);
|
|
1595
|
+
if (t.endsWith("$$")) maths = false;
|
|
1596
|
+
continue;
|
|
1597
|
+
}
|
|
1598
|
+
if (t.startsWith("```") || t.startsWith("~~~")) {
|
|
1599
|
+
fence = t.slice(0, 3);
|
|
1600
|
+
out.push(l);
|
|
1601
|
+
open = "";
|
|
1602
|
+
continue;
|
|
1603
|
+
}
|
|
1604
|
+
if (t.startsWith("$$") && !t.slice(2).includes("$$")) {
|
|
1605
|
+
maths = true;
|
|
1606
|
+
out.push(l);
|
|
1607
|
+
open = "";
|
|
1608
|
+
continue;
|
|
1609
|
+
}
|
|
1610
|
+
if (!t) {
|
|
1611
|
+
out.push(l);
|
|
1612
|
+
open = "";
|
|
1613
|
+
continue;
|
|
1614
|
+
}
|
|
1615
|
+
const hard = /( {2}|\\)$/.test(out.at(-1) ?? "");
|
|
1616
|
+
if (APART.test(l)) {
|
|
1617
|
+
if (open === "quote" && QUOTED.test(l) && !/^\s*>\s*([-*+]|\d+[.)]|#)/.test(l) && !hard) {
|
|
1618
|
+
out[out.length - 1] += " " + l.replace(/^\s*>\s?/, "").trim();
|
|
1619
|
+
continue;
|
|
1620
|
+
}
|
|
1621
|
+
out.push(l);
|
|
1622
|
+
open = QUOTED.test(l) ? "quote" : "";
|
|
1623
|
+
continue;
|
|
1624
|
+
}
|
|
1625
|
+
if (ITEM.test(l)) {
|
|
1626
|
+
out.push(l);
|
|
1627
|
+
open = "prose";
|
|
1628
|
+
continue;
|
|
1629
|
+
}
|
|
1630
|
+
if (open === "prose" && !hard) {
|
|
1631
|
+
out[out.length - 1] += " " + t;
|
|
1632
|
+
continue;
|
|
1633
|
+
}
|
|
1634
|
+
out.push(l);
|
|
1635
|
+
open = open === "" && /^( {4}|\t)/.test(l) ? "" : "prose";
|
|
1636
|
+
}
|
|
1637
|
+
return out.join("\n");
|
|
1638
|
+
}
|
|
1639
|
+
var ITEM, APART, QUOTED;
|
|
1640
|
+
var init_unwrap = __esmMin((() => {
|
|
1641
|
+
ITEM = /^\s*([-*+]|\d+[.)])\s+/;
|
|
1642
|
+
APART = /^\s*(#{1,6}\s|\||<|```|~~~|\$\$|>|---\s*$|\*\*\*\s*$|___\s*$|\[[^\]]+\]:\s)/;
|
|
1643
|
+
QUOTED = /^\s*>\s?\S/;
|
|
1644
|
+
}));
|
|
1645
|
+
//#endregion
|
|
1573
1646
|
//#region packages/core/src/search.ts
|
|
1574
1647
|
function stem(token) {
|
|
1575
1648
|
for (const suffix of ["ness", "ing"]) if (token.endsWith(suffix) && token.length - suffix.length >= 4) return token.slice(0, -suffix.length);
|
|
@@ -2093,16 +2166,21 @@ function written$1(note, p, region) {
|
|
|
2093
2166
|
lines.splice(at, 0, ...blank(at - 1) ? [] : [""], ...ins, ...blank(at) ? [] : [""]);
|
|
2094
2167
|
return lines.join("\n");
|
|
2095
2168
|
}
|
|
2096
|
-
/** The journal as the timeline shows it. Your own edits in a row within a session are one moment
|
|
2097
|
-
* one moment whose `what` says how it ended. Revisions are not
|
|
2169
|
+
/** The journal as the timeline shows it. Your own edits in a row within a session are one moment, until ten minutes
|
|
2170
|
+
* pass with none (LAYER_IDLE_MS); a proposal is one moment whose `what` says how it ended. Revisions are not
|
|
2171
|
+
* moments. */
|
|
2098
2172
|
function moments(entries) {
|
|
2099
2173
|
const out = [], offered = /* @__PURE__ */ new Map(), asked = /* @__PURE__ */ new Map();
|
|
2174
|
+
/** Lines a change put in and took out: a note's first entry, all of its text. */
|
|
2175
|
+
const size = (c) => c.why === "start" || !c.hunks.length && c.before === null ? [(c.text ?? "").split("\n").length, 0] : [c.hunks.reduce((n, h) => n + h.ins.length, 0), c.hunks.reduce((n, h) => n + h.del.length, 0)];
|
|
2100
2176
|
for (const e of entries) {
|
|
2101
2177
|
const base = {
|
|
2102
2178
|
ids: [e.id],
|
|
2103
2179
|
at: e.at,
|
|
2104
2180
|
session: e.session,
|
|
2105
|
-
who: e.who
|
|
2181
|
+
who: e.who,
|
|
2182
|
+
added: 0,
|
|
2183
|
+
removed: 0
|
|
2106
2184
|
};
|
|
2107
2185
|
if (e.kind === "proposal") {
|
|
2108
2186
|
const m = {
|
|
@@ -2121,22 +2199,29 @@ function moments(entries) {
|
|
|
2121
2199
|
}
|
|
2122
2200
|
} else if (e.kind === "change") {
|
|
2123
2201
|
const m = e.proposal ? offered.get(e.proposal) : void 0;
|
|
2202
|
+
const [added, removed] = size(e);
|
|
2124
2203
|
if (e.why === "keep" && m) {
|
|
2125
2204
|
m.what = "kept";
|
|
2126
2205
|
m.ids.push(e.id);
|
|
2127
2206
|
m.at = e.at;
|
|
2207
|
+
m.added += added;
|
|
2208
|
+
m.removed += removed;
|
|
2128
2209
|
continue;
|
|
2129
2210
|
}
|
|
2130
2211
|
const last = out[out.length - 1];
|
|
2131
|
-
if (e.why === "edit" && last && last.what === "edited" && last.who === e.who && last.session === e.session) {
|
|
2212
|
+
if (e.why === "edit" && last && last.what === "edited" && last.who === e.who && last.session === e.session && Date.parse(e.at) - Date.parse(last.at) <= 6e5) {
|
|
2132
2213
|
last.ids.push(e.id);
|
|
2133
2214
|
last.at = e.at;
|
|
2215
|
+
last.added += added;
|
|
2216
|
+
last.removed += removed;
|
|
2134
2217
|
continue;
|
|
2135
2218
|
}
|
|
2136
2219
|
const what = e.why === "start" ? e.who === "external" ? "found" : "wrote" : e.why === "edit" ? "edited" : e.why === "restore" ? "restored" : e.why === "keep" ? "kept" : e.why === "move" ? "moved" : "changed elsewhere";
|
|
2137
2220
|
out.push({
|
|
2138
2221
|
...base,
|
|
2139
2222
|
what,
|
|
2223
|
+
added,
|
|
2224
|
+
removed,
|
|
2140
2225
|
...e.asked ? { asked: e.asked } : {}
|
|
2141
2226
|
});
|
|
2142
2227
|
}
|
|
@@ -2330,6 +2415,7 @@ var init_src$1 = __esmMin((() => {
|
|
|
2330
2415
|
init_frontmatter();
|
|
2331
2416
|
init_source();
|
|
2332
2417
|
init_markdown();
|
|
2418
|
+
init_unwrap();
|
|
2333
2419
|
init_text();
|
|
2334
2420
|
init_search();
|
|
2335
2421
|
init_record();
|
|
@@ -3053,7 +3139,7 @@ function parseRewrite(reply, count) {
|
|
|
3053
3139
|
/** A passage's new text, set between the same neighbours as the old: it keeps the old one's space and line
|
|
3054
3140
|
* breaks at either end, whatever the model put round what it wrote. An empty one takes the passage out. */
|
|
3055
3141
|
function fitted(old, text) {
|
|
3056
|
-
const core = text.trim();
|
|
3142
|
+
const core = unwrap(text.trim());
|
|
3057
3143
|
if (!core) return "";
|
|
3058
3144
|
return /^\s*/.exec(old)[0] + core + /\s*$/.exec(old)[0];
|
|
3059
3145
|
}
|
|
@@ -3112,7 +3198,7 @@ function replyText(reply) {
|
|
|
3112
3198
|
let text = reply.replaceAll(HERE, "").replace(/^\s*\n/, "").trimEnd();
|
|
3113
3199
|
const fenced = /^```(?:markdown|md)?\n([\s\S]*)\n```$/.exec(text.trim());
|
|
3114
3200
|
if (fenced) text = fenced[1];
|
|
3115
|
-
return text.trim();
|
|
3201
|
+
return unwrap(text.trim());
|
|
3116
3202
|
}
|
|
3117
3203
|
var HERE, WHO$1, INSERT, OPEN, CLOSE, SAY_OPEN, SAY_CLOSE, REWRITE, NOTE, FORMAT, FORMAT_RULES, LOOKUP, estimate, CONVERSATION_BUDGET, NOTE_BUDGET, OLD_EXCHANGE, NO_LOOKUP, looked, LINKED_BUDGET;
|
|
3118
3204
|
var init_iso = __esmMin((() => {
|
|
@@ -3207,6 +3293,8 @@ something at one place in the note they have open.`;
|
|
|
3207
3293
|
- A picture is shown as . You can't see it: what
|
|
3208
3294
|
you know of it is the words in the brackets. Keep a picture's line as it is
|
|
3209
3295
|
when you rewrite around it, and never make up a picture's path.
|
|
3296
|
+
- A paragraph or a list item is one line, however long: do not break lines at
|
|
3297
|
+
a width. The editor wraps them to the pane.
|
|
3210
3298
|
- Ordinary Markdown otherwise. No HTML.`;
|
|
3211
3299
|
FORMAT_RULES = FORMAT;
|
|
3212
3300
|
LOOKUP = (rounds, meaning) => `# Looking things up
|
|
@@ -3524,38 +3612,6 @@ var init_lookup = __esmMin((() => {
|
|
|
3524
3612
|
};
|
|
3525
3613
|
}));
|
|
3526
3614
|
//#endregion
|
|
3527
|
-
//#region packages/engine/src/understand.ts
|
|
3528
|
-
/** The two parts of an Understanding note's file. A file in another shape is read as all scratchpad. */
|
|
3529
|
-
function parseUnderstanding(text) {
|
|
3530
|
-
if (!text) return {
|
|
3531
|
-
reading: "",
|
|
3532
|
-
scratchpad: ""
|
|
3533
|
-
};
|
|
3534
|
-
const body = text.replace(/^---\n[\s\S]*?\n---\n/, "");
|
|
3535
|
-
const r = body.indexOf(READING$1), p = body.indexOf(PAD);
|
|
3536
|
-
if (r < 0 && p < 0) return {
|
|
3537
|
-
reading: "",
|
|
3538
|
-
scratchpad: body.trim()
|
|
3539
|
-
};
|
|
3540
|
-
return {
|
|
3541
|
-
reading: r < 0 ? "" : body.slice(r + 16, p > r ? p : void 0).trim(),
|
|
3542
|
-
scratchpad: p < 0 ? "" : body.slice(p + 13, r > p ? r : void 0).trim()
|
|
3543
|
-
};
|
|
3544
|
-
}
|
|
3545
|
-
/** An Understanding note's file, from its parts. */
|
|
3546
|
-
function understandingText(note, title, parts) {
|
|
3547
|
-
return `---\ntype: Understanding\ntitle: ${JSON.stringify(`Understanding · ${title}`)}\nof: ${note}\n---\n\n${READING$1}\n\n${parts.reading.trim()}\n\n${PAD}\n\n${parts.scratchpad.trim()}\n`;
|
|
3548
|
-
}
|
|
3549
|
-
var UNDERSTANDING_PREFIX, UNDERSTANDING_DIR, isUnderstandingId, understandingId, READING$1, PAD;
|
|
3550
|
-
var init_understand = __esmMin((() => {
|
|
3551
|
-
UNDERSTANDING_PREFIX = "@understanding/";
|
|
3552
|
-
UNDERSTANDING_DIR = "understanding";
|
|
3553
|
-
isUnderstandingId = (id) => id.startsWith(UNDERSTANDING_PREFIX);
|
|
3554
|
-
understandingId = (note) => UNDERSTANDING_PREFIX + note;
|
|
3555
|
-
READING$1 = "## Iso's reading";
|
|
3556
|
-
PAD = "## Scratchpad";
|
|
3557
|
-
}));
|
|
3558
|
-
//#endregion
|
|
3559
3615
|
//#region packages/engine/src/hand.ts
|
|
3560
3616
|
/** The lines about the working set in a conversation's file, in order. Turns' own lines are passed over. */
|
|
3561
3617
|
function readHand(text) {
|
|
@@ -3676,6 +3732,7 @@ function readTurns(text) {
|
|
|
3676
3732
|
turns.set(t.id, {
|
|
3677
3733
|
...t,
|
|
3678
3734
|
mode: MODES.includes(t.mode) ? t.mode : "ask",
|
|
3735
|
+
given: (t.given ?? []).filter((g) => GIVEN.includes(g.kind)),
|
|
3679
3736
|
items: [],
|
|
3680
3737
|
state: "running"
|
|
3681
3738
|
});
|
|
@@ -3684,7 +3741,7 @@ function readTurns(text) {
|
|
|
3684
3741
|
const t = turns.get(line.turn);
|
|
3685
3742
|
if (!t) continue;
|
|
3686
3743
|
if (line.kind === "item") {
|
|
3687
|
-
if (ITEMS.includes(line.item.kind)) t.items.push(line.item);
|
|
3744
|
+
if (ITEMS.includes(line.item.kind) && !(line.item.kind === "change" && line.item.note.startsWith("@understanding/"))) t.items.push(line.item);
|
|
3688
3745
|
} else if (line.kind === "answer") {
|
|
3689
3746
|
for (const i of t.items) if (i.kind === "permission" && i.id === line.permission) i.answer = line.decision;
|
|
3690
3747
|
} else if (line.kind === "taken") {
|
|
@@ -3701,9 +3758,9 @@ function readTurns(text) {
|
|
|
3701
3758
|
state: "stopped"
|
|
3702
3759
|
} : t).sort((a, b) => a.id < b.id ? -1 : 1);
|
|
3703
3760
|
}
|
|
3704
|
-
/** A turn's own tools: its mode's
|
|
3705
|
-
function turnTools(mode
|
|
3706
|
-
return
|
|
3761
|
+
/** A turn's own tools: its mode's. */
|
|
3762
|
+
function turnTools(mode) {
|
|
3763
|
+
return MODE_TOOLS[mode];
|
|
3707
3764
|
}
|
|
3708
3765
|
function sentText(s) {
|
|
3709
3766
|
if (s.kind === "note") {
|
|
@@ -3712,15 +3769,14 @@ function sentText(s) {
|
|
|
3712
3769
|
}
|
|
3713
3770
|
if (s.kind === "passage") return `## A passage they chose in ${s.title} (/${s.id}.md)\n\n${s.text.split("\n").map((l) => `> ${l}`).join("\n")}`;
|
|
3714
3771
|
if (s.kind === "read") return `## ${s.title} (/${s.id}.md)${s.sections === "whole" ? "" : `, ${s.sections.length === 1 ? "the section" : "the sections"} ${s.sections.map((x) => `"${x}"`).join(", ")}`}\n\n${s.text}`;
|
|
3715
|
-
|
|
3716
|
-
return `## Their understanding of ${s.title} (/${s.id}.md)\n\nYour reading so far: ${s.reading || "none yet."}`;
|
|
3772
|
+
return `## The folder ${s.id || "at the top of the base"}: its notes\n\n${s.notes.map((n) => `- ${n.title} (/${n.id}.md)${n.description ? `: ${n.description}` : ""}`).join("\n") || "(empty)"}`;
|
|
3717
3773
|
}
|
|
3718
3774
|
/** An earlier turn as it is sent: in the shape `conversation()` shortens. */
|
|
3719
3775
|
function turnExchange(t) {
|
|
3720
3776
|
const text = t.items.filter((i) => i.kind === "text").map((i) => i.text).join("\n\n").trim();
|
|
3721
3777
|
const changed = t.items.flatMap((i) => i.kind === "change" ? [`${i.why === "create" ? "made" : i.why === "delete" ? "deleted" : i.why === "move" ? "moved" : "changed"} ${i.title} (/${i.note}.md)`] : []);
|
|
3722
3778
|
const asked = t.items.flatMap((i) => i.kind === "question" ? [`You asked them: ${i.title}${i.made ? ` (/${i.made}.md)` : ""}.`] : i.kind === "offer" ? [`You offered them a passage for /${i.note}.md, which they ${i.taken ? "inserted" : "have not inserted"}.`] : []);
|
|
3723
|
-
const gave = t.given.
|
|
3779
|
+
const gave = t.given.map((g) => g.kind === "passage" ? `a passage of /${g.id}.md` : `/${g.id}${g.kind === "note" ? ".md" : "/"}`);
|
|
3724
3780
|
return {
|
|
3725
3781
|
id: t.id,
|
|
3726
3782
|
note: "",
|
|
@@ -3729,7 +3785,6 @@ function turnExchange(t) {
|
|
|
3729
3785
|
}
|
|
3730
3786
|
/** The messages for a turn, and what they hold, part by part. */
|
|
3731
3787
|
function turnMessages(a) {
|
|
3732
|
-
const understood = a.sent.filter((s) => s.kind === "understanding");
|
|
3733
3788
|
const checking = a.sent.some((s) => s.kind === "note" && s.of === "problem");
|
|
3734
3789
|
const system = [
|
|
3735
3790
|
WHO,
|
|
@@ -3740,20 +3795,18 @@ function turnMessages(a) {
|
|
|
3740
3795
|
...a.mode === "write" ? [ARTIFACTS] : [],
|
|
3741
3796
|
ASKING(a.mode === "write"),
|
|
3742
3797
|
...checking ? [CHECKING] : [],
|
|
3743
|
-
...understood.length ? [UNDERSTANDING] : [],
|
|
3744
3798
|
FORMAT_RULES,
|
|
3745
3799
|
LOOKING(a.mode === "write" ? Math.max(ROUNDS[a.tier], 6) : ROUNDS[a.tier], a.meaning, a.lookup)
|
|
3746
3800
|
].join("\n\n");
|
|
3747
3801
|
const briefed = a.briefings?.length ? `# Earlier in this conversation, summed up\n\n${a.briefings.join("\n\n---\n\n")}` : "";
|
|
3748
3802
|
const talk = a.earlier.map((t) => turnExchange(t).text).join("\n\n---\n\n");
|
|
3749
3803
|
const earlier = [briefed, talk ? `# Earlier in this conversation\n\n${talk}` : ""].filter(Boolean).join("\n\n");
|
|
3750
|
-
const given = a.sent.filter((s) => s.kind !== "
|
|
3804
|
+
const given = a.sent.filter((s) => s.kind !== "read"), reads = a.sent.filter((s) => s.kind === "read");
|
|
3751
3805
|
const gave = given.length ? `# What they gave you\n\n${given.map(sentText).join("\n\n")}` : "";
|
|
3752
3806
|
const held = reads.length ? `# Notes you read earlier in this conversation\n\n${reads.map(sentText).join("\n\n")}` : "";
|
|
3753
3807
|
const aside = a.aside?.length ? `# Read earlier, set aside\n\n${a.aside.map((n) => `- ${n.title} (/${n.id}.md)`).join("\n")}` : "";
|
|
3754
3808
|
const agents = a.agents?.trim() ? `# Their instructions for this knowledge base (AGENTS.md)\n\n${a.agents.trim()}` : "";
|
|
3755
3809
|
const lent = a.lookup && a.lent?.length ? `# Other knowledge bases lent to you\n\nYou may read these with the same look-up tools, giving their base; you change notes only in this one. Look in them where what is asked may be there: how the person works, their tools, what was settled before.\n\n${a.lent.map((l) => `- ${l.name}: ${l.about}`).join("\n")}` : "";
|
|
3756
|
-
const known = understood.length ? `# Their understanding, as you have recorded it\n\n${understood.map(sentText).join("\n\n")}` : "";
|
|
3757
3810
|
const broken = a.broken?.length ? `# Code links that no longer resolve\n\nSince you were last told, these links in their notes point to files no longer in their repository. Mention it only where it bears on what they ask.\n\n${a.broken.map((b) => `- in ${b.title} (/${b.id}.md): ${b.href}`).join("\n")}` : "";
|
|
3758
3811
|
const request = `# What they ask now\n\n${a.asked}`;
|
|
3759
3812
|
return {
|
|
@@ -3769,7 +3822,6 @@ function turnMessages(a) {
|
|
|
3769
3822
|
agents,
|
|
3770
3823
|
lent,
|
|
3771
3824
|
earlier,
|
|
3772
|
-
known,
|
|
3773
3825
|
gave,
|
|
3774
3826
|
held,
|
|
3775
3827
|
aside,
|
|
@@ -3781,7 +3833,7 @@ function turnMessages(a) {
|
|
|
3781
3833
|
{
|
|
3782
3834
|
name: "instructions and tools",
|
|
3783
3835
|
detail: `${a.mode} mode${checking ? ", checking" : ""}${a.lookup ? "" : ", no look-ups"}`,
|
|
3784
|
-
tokens: estimate(system) + estimate(lent) + (a.lookup ? 500 : 0) + turnTools(a.mode
|
|
3836
|
+
tokens: estimate(system) + estimate(lent) + (a.lookup ? 500 : 0) + turnTools(a.mode).length * 120
|
|
3785
3837
|
},
|
|
3786
3838
|
{
|
|
3787
3839
|
name: "earlier in this conversation",
|
|
@@ -3803,11 +3855,6 @@ function turnMessages(a) {
|
|
|
3803
3855
|
detail: `${reads.length} in hand${a.aside?.length ? `, ${a.aside.length} set aside` : ""}`,
|
|
3804
3856
|
tokens: estimate(held) + estimate(aside)
|
|
3805
3857
|
}] : [],
|
|
3806
|
-
...understood.length ? [{
|
|
3807
|
-
name: "your understanding",
|
|
3808
|
-
detail: `${understood.length} ${understood.length === 1 ? "note" : "notes"}`,
|
|
3809
|
-
tokens: estimate(known)
|
|
3810
|
-
}] : [],
|
|
3811
3858
|
...broken ? [{
|
|
3812
3859
|
name: "code links broken",
|
|
3813
3860
|
detail: `${a.broken.length}`,
|
|
@@ -3821,7 +3868,7 @@ function turnMessages(a) {
|
|
|
3821
3868
|
]
|
|
3822
3869
|
};
|
|
3823
3870
|
}
|
|
3824
|
-
var MODES, ITEMS, CONVERSATIONS_DIR, conversationPath, WHO, ISORITE, PRACTICE, LEARNING, ASK, WRITE,
|
|
3871
|
+
var MODES, GIVEN, ITEMS, CONVERSATIONS_DIR, conversationPath, WHO, ISORITE, PRACTICE, LEARNING, ASK, WRITE, ARTIFACTS, ASKING, CHECKING, MODE_RULES, LOOKING, COMPACT$1, str, fn, POINT_TO_NOTE, EDIT_NOTE$1, WRITE_NOTE$1, MOVE_NOTE, DELETE_NOTE, ASK_QUESTION, READ_DATA, ARTIFACT_RECIPE, WRITE_ARTIFACT, READ_ARTIFACT, OFFER_TEXT, MODE_TOOLS;
|
|
3825
3872
|
var init_turn = __esmMin((() => {
|
|
3826
3873
|
init_iso();
|
|
3827
3874
|
init_loop();
|
|
@@ -3830,6 +3877,11 @@ var init_turn = __esmMin((() => {
|
|
|
3830
3877
|
"write",
|
|
3831
3878
|
"build"
|
|
3832
3879
|
];
|
|
3880
|
+
GIVEN = [
|
|
3881
|
+
"note",
|
|
3882
|
+
"folder",
|
|
3883
|
+
"passage"
|
|
3884
|
+
];
|
|
3833
3885
|
ITEMS = [
|
|
3834
3886
|
"text",
|
|
3835
3887
|
"look",
|
|
@@ -3900,6 +3952,9 @@ It follows from [surprise](/basics/surprise.md "requires"), but how?
|
|
|
3900
3952
|
stop. Explain once they have answered. When they ask for a fact, a check or
|
|
3901
3953
|
a change, just answer.
|
|
3902
3954
|
- Prefer a question back, or a problem to try, to a summary.
|
|
3955
|
+
- Where they stand shows in their notes: what they wrote, their open questions,
|
|
3956
|
+
the problems they have solved and not. Where you find it stops, offer it to
|
|
3957
|
+
them as a question to keep (ask_question) or a problem to try.
|
|
3903
3958
|
- Check a solution; never solve it for them.`;
|
|
3904
3959
|
ASK = `# Ask mode: what you may do
|
|
3905
3960
|
|
|
@@ -3913,6 +3968,9 @@ note, no folder.
|
|
|
3913
3968
|
the notes you used, so they can open them. Where the base does not hold what
|
|
3914
3969
|
is asked, answer from what you know of the subject, exactly, and say that
|
|
3915
3970
|
their notes do not cover it.
|
|
3971
|
+
- Cite in the sentence: the phrase that rests on a note is the link to it,
|
|
3972
|
+
with its kind. No numbered references and no list of sources at the end;
|
|
3973
|
+
the notes you read are shown under your reply.
|
|
3916
3974
|
- When one of their notes would help them and they may not know it, point it
|
|
3917
3975
|
out with point_to_note. Use it sparingly: one or two notes.
|
|
3918
3976
|
- Never invent a note, a link or a quotation.`;
|
|
@@ -3930,24 +3988,12 @@ change marked as yours, and can undo it.
|
|
|
3930
3988
|
- A new note (write_note) is written as one of theirs: frontmatter with type
|
|
3931
3989
|
and title, their notation, their level, plain words, linked to the notes it
|
|
3932
3990
|
rests on.
|
|
3991
|
+
- Write each paragraph and each list item on one line. Do not break lines at a
|
|
3992
|
+
width: the editor wraps them to the pane.
|
|
3933
3993
|
- Moving or deleting a note is asked of them before it happens. Do it only
|
|
3934
3994
|
when they asked for it.
|
|
3935
3995
|
- When you are done, say in a sentence or two what you changed and why. Do not
|
|
3936
3996
|
repeat the text you wrote: they see it in the note.
|
|
3937
|
-
- Never invent a note, a link or a quotation.`;
|
|
3938
|
-
UNDERSTANDING = `# Their understanding
|
|
3939
|
-
|
|
3940
|
-
Below, for each note in hand, is your reading of their understanding of it so
|
|
3941
|
-
far, from its Understanding note.
|
|
3942
|
-
|
|
3943
|
-
- Start from where they are: do not explain what they have shown they know; go
|
|
3944
|
-
to what they have not yet shown, and ask about that first.
|
|
3945
|
-
- At the end of a conversation about a note, or when your reading of them has
|
|
3946
|
-
changed, rewrite your reading with write_understanding: a few plain
|
|
3947
|
-
sentences on what they can do with the note and what they have not yet
|
|
3948
|
-
shown. It is theirs to read. Rest each sentence on evidence they can open,
|
|
3949
|
-
linked: what they wrote in a note, a question of theirs open or resolved,
|
|
3950
|
-
a problem solved or not. Say nothing the evidence does not show.
|
|
3951
3997
|
- Never invent a note, a link or a quotation.`;
|
|
3952
3998
|
ARTIFACTS = `# Artifacts
|
|
3953
3999
|
|
|
@@ -4086,13 +4132,6 @@ was not said.`;
|
|
|
4086
4132
|
}
|
|
4087
4133
|
}, ["id", "to"]);
|
|
4088
4134
|
DELETE_NOTE = fn("delete_note", "Delete a note. They are asked first. Its history stays.", { id: str }, ["id"]);
|
|
4089
|
-
WRITE_UNDERSTANDING = fn("write_understanding", "Rewrite your reading of their understanding of one note: a few plain sentences on what they can do with it and what they have not yet shown, each resting on evidence linked as [their words](/id.md), [a question](/id.md) or [a problem](/id.md). Replaces the reading you had.", {
|
|
4090
|
-
id: {
|
|
4091
|
-
...str,
|
|
4092
|
-
description: "The note's id."
|
|
4093
|
-
},
|
|
4094
|
-
reading: str
|
|
4095
|
-
}, ["id", "reading"]);
|
|
4096
4135
|
ASK_QUESTION = fn("ask_question", "Ask them a question back, kept as an open question in their base, about one or more of their notes.", {
|
|
4097
4136
|
title: {
|
|
4098
4137
|
...str,
|
|
@@ -4438,7 +4477,6 @@ var init_engine = __esmMin((() => {
|
|
|
4438
4477
|
init_iso();
|
|
4439
4478
|
init_loop();
|
|
4440
4479
|
init_lookup();
|
|
4441
|
-
init_understand();
|
|
4442
4480
|
init_hand();
|
|
4443
4481
|
init_turn();
|
|
4444
4482
|
init_meaning();
|
|
@@ -4451,7 +4489,7 @@ var init_engine = __esmMin((() => {
|
|
|
4451
4489
|
DRAFT_PREFIX = "@draft/";
|
|
4452
4490
|
DRAFT_DIR = "drafts";
|
|
4453
4491
|
isDraftId = (id) => id.startsWith(DRAFT_PREFIX);
|
|
4454
|
-
bare = (id) => isDraftId(id) ? id.slice(7) :
|
|
4492
|
+
bare = (id) => isDraftId(id) ? id.slice(7) : id;
|
|
4455
4493
|
inBase = (id) => !id.startsWith("@");
|
|
4456
4494
|
BAD_PART = /^\.|[\0\\:*?"<>|]|^\s|\s$/;
|
|
4457
4495
|
TURN_ID = /^[0-9A-HJKMNP-TV-Z]{26}$/;
|
|
@@ -5192,16 +5230,19 @@ var init_engine = __esmMin((() => {
|
|
|
5192
5230
|
};
|
|
5193
5231
|
});
|
|
5194
5232
|
}
|
|
5195
|
-
/** Where a note's file is: drafts
|
|
5233
|
+
/** Where a note's file is: drafts are among isorite's own files. */
|
|
5196
5234
|
where(id) {
|
|
5197
5235
|
if (inBase(id) && citeKind(id) === "artifact") return {
|
|
5198
5236
|
files: this.opts.notes,
|
|
5199
5237
|
path: checkNoteId(id)
|
|
5200
5238
|
};
|
|
5201
|
-
if (!inBase(id))
|
|
5202
|
-
|
|
5203
|
-
|
|
5204
|
-
|
|
5239
|
+
if (!inBase(id)) {
|
|
5240
|
+
if (!isDraftId(id)) throw new EngineError(`there is no note ${id}`);
|
|
5241
|
+
return {
|
|
5242
|
+
files: this.opts.own,
|
|
5243
|
+
path: `${DRAFT_DIR}/${checkNoteId(bare(id))}.md`
|
|
5244
|
+
};
|
|
5245
|
+
}
|
|
5205
5246
|
return {
|
|
5206
5247
|
files: this.opts.notes,
|
|
5207
5248
|
path: `${checkNoteId(id)}.md`
|
|
@@ -5950,6 +5991,32 @@ var init_engine = __esmMin((() => {
|
|
|
5950
5991
|
} : t)
|
|
5951
5992
|
};
|
|
5952
5993
|
}
|
|
5994
|
+
async conversations() {
|
|
5995
|
+
const study = this.opts.own;
|
|
5996
|
+
const names = await study.list(CONVERSATIONS_DIR).catch(() => []);
|
|
5997
|
+
const all = [];
|
|
5998
|
+
for (const f of names) {
|
|
5999
|
+
const id = f.name.slice(0, -6);
|
|
6000
|
+
if (f.dir || !f.name.endsWith(".jsonl") || !TURN_ID.test(id)) continue;
|
|
6001
|
+
const turns = readTurns(await study.read(conversationPath(id)) ?? "");
|
|
6002
|
+
if (!turns.length) continue;
|
|
6003
|
+
const notes = /* @__PURE__ */ new Set();
|
|
6004
|
+
for (const t of turns) {
|
|
6005
|
+
for (const g of t.given) if (g.kind !== "folder") notes.add(g.id);
|
|
6006
|
+
for (const i of t.items) if (i.kind === "look" && i.step.opened && !i.step.away) notes.add(i.step.opened);
|
|
6007
|
+
else if (i.kind === "point" || i.kind === "change" && i.why !== "delete") notes.add(i.kind === "change" && i.to ? i.to : i.note);
|
|
6008
|
+
}
|
|
6009
|
+
all.push({
|
|
6010
|
+
id,
|
|
6011
|
+
at: turns[0].at,
|
|
6012
|
+
last: turns.at(-1).at,
|
|
6013
|
+
asked: turns[0].asked,
|
|
6014
|
+
turns: turns.length,
|
|
6015
|
+
notes: notes.size
|
|
6016
|
+
});
|
|
6017
|
+
}
|
|
6018
|
+
return all.sort((a, b) => a.last < b.last ? 1 : a.last > b.last ? -1 : 0);
|
|
6019
|
+
}
|
|
5953
6020
|
/** What was given, checked: notes and passages of the base, and its folders. */
|
|
5954
6021
|
given(raw) {
|
|
5955
6022
|
if (!Array.isArray(raw) || raw.length > 40) throw new EngineError("give Iso between none and forty notes, folders and passages");
|
|
@@ -5967,10 +6034,6 @@ var init_engine = __esmMin((() => {
|
|
|
5967
6034
|
kind: "note",
|
|
5968
6035
|
id
|
|
5969
6036
|
};
|
|
5970
|
-
if (g?.kind === "understanding") return {
|
|
5971
|
-
kind: "understanding",
|
|
5972
|
-
id
|
|
5973
|
-
};
|
|
5974
6037
|
if (g?.kind === "passage" && typeof g.text === "string" && g.text.trim() && g.text.length <= 2e4) return {
|
|
5975
6038
|
kind: "passage",
|
|
5976
6039
|
id,
|
|
@@ -6006,16 +6069,6 @@ var init_engine = __esmMin((() => {
|
|
|
6006
6069
|
}
|
|
6007
6070
|
const c = this.bundle.concepts.get(g.id);
|
|
6008
6071
|
if (!c) continue;
|
|
6009
|
-
if (g.kind === "understanding") {
|
|
6010
|
-
const u = await this.understanding(g.id);
|
|
6011
|
-
out.push({
|
|
6012
|
-
kind: "understanding",
|
|
6013
|
-
id: g.id,
|
|
6014
|
-
title: c.title,
|
|
6015
|
-
reading: u.reading
|
|
6016
|
-
});
|
|
6017
|
-
continue;
|
|
6018
|
-
}
|
|
6019
6072
|
if (g.kind === "passage") out.push({
|
|
6020
6073
|
kind: "passage",
|
|
6021
6074
|
id: g.id,
|
|
@@ -6146,7 +6199,7 @@ var init_engine = __esmMin((() => {
|
|
|
6146
6199
|
group: "notes",
|
|
6147
6200
|
kind: g.kind,
|
|
6148
6201
|
title: g.kind === "folder" ? g.id || "the top of the base" : title(g.id),
|
|
6149
|
-
detail: g.kind === "passage" ? "a passage" : g.kind === "folder" ? `${s.kind === "folder" ? s.notes.length : 0} notes listed` :
|
|
6202
|
+
detail: g.kind === "passage" ? "a passage" : g.kind === "folder" ? `${s.kind === "folder" ? s.notes.length : 0} notes listed` : "",
|
|
6150
6203
|
tokens: scaled(estimate(sentText(s))),
|
|
6151
6204
|
on: !w.off.has(k),
|
|
6152
6205
|
by: "you",
|
|
@@ -6436,7 +6489,7 @@ var init_engine = __esmMin((() => {
|
|
|
6436
6489
|
const big = [...w.built.parts].sort((a, b) => b.tokens - a.tokens)[0], k = (n) => `${Math.round(n / 1e3)}k`;
|
|
6437
6490
|
throw new EngineError(`This turn would be sent about ${k(size())} tokens, more than the ${k(limit)} the model takes. The largest part is ${big.name} (${k(w.scaled(big.tokens))}): switch parts off in the Context view.`, 413);
|
|
6438
6491
|
}
|
|
6439
|
-
const sent = [...w.sent, ...w.reads], own = turnTools(mode
|
|
6492
|
+
const sent = [...w.sent, ...w.reads], own = turnTools(mode);
|
|
6440
6493
|
const inHand = new Map(w.reads.flatMap((r) => r.kind === "read" ? [[r.id, r.sections]] : []));
|
|
6441
6494
|
for (const g of w.givenOn) if (g.kind === "note") inHand.set(g.id, "whole");
|
|
6442
6495
|
const { messages } = turnMessages({
|
|
@@ -6724,7 +6777,7 @@ var init_engine = __esmMin((() => {
|
|
|
6724
6777
|
if (name === "edit_note") {
|
|
6725
6778
|
const id = noteId(this.bundle, args.id);
|
|
6726
6779
|
if (!id) return `There is no note ${String(args.id ?? "")}. Search for it by its words.`;
|
|
6727
|
-
const old = String(args.old ?? ""), next = String(args.new ?? "");
|
|
6780
|
+
const old = String(args.old ?? ""), next = unwrap(String(args.new ?? ""));
|
|
6728
6781
|
if (!old) return "Give the passage as it is now, in old.";
|
|
6729
6782
|
const now = await this.readNote(id);
|
|
6730
6783
|
const at = now.text.indexOf(old), again = at < 0 ? -1 : now.text.indexOf(old, at + 1);
|
|
@@ -6745,7 +6798,7 @@ var init_engine = __esmMin((() => {
|
|
|
6745
6798
|
if (name === "write_note") {
|
|
6746
6799
|
const id = this.newNoteId(args.id);
|
|
6747
6800
|
if (!id) return `${String(args.id ?? "")} is not a note's id in their base: give folder/name, lower case with hyphens.`;
|
|
6748
|
-
let text = String(args.text ?? "");
|
|
6801
|
+
let text = unwrap(String(args.text ?? ""));
|
|
6749
6802
|
if (!text.trim()) return "Give the note's whole text.";
|
|
6750
6803
|
if (!/^---\n/.test(text)) text = `---\ntype: Concept\ntitle: ${JSON.stringify(/^#\s+(.+)$/m.exec(text)?.[1]?.trim() ?? id.split("/").at(-1).replace(/-/g, " "))}\n---\n\n${text.replace(/^#\s+.+\n+/, "")}`;
|
|
6751
6804
|
const was = this.bundle.concepts.has(id) ? await this.readNote(id) : null;
|
|
@@ -6851,28 +6904,6 @@ var init_engine = __esmMin((() => {
|
|
|
6851
6904
|
});
|
|
6852
6905
|
return `It is offered to them for ${agents ? "their AGENTS.md" : title(id)}.`;
|
|
6853
6906
|
}
|
|
6854
|
-
if (name === "write_understanding") {
|
|
6855
|
-
const id = noteId(this.bundle, args.id);
|
|
6856
|
-
if (!id) return `There is no note ${String(args.id ?? "")}.`;
|
|
6857
|
-
const reading = String(args.reading ?? "").trim();
|
|
6858
|
-
if (!reading) return "Give your reading.";
|
|
6859
|
-
const uid = understandingId(id), was = await this.readNote(uid).catch(() => null);
|
|
6860
|
-
const text = understandingText(id, title(id), {
|
|
6861
|
-
...parseUnderstanding(was?.text ?? null),
|
|
6862
|
-
reading
|
|
6863
|
-
});
|
|
6864
|
-
const saved = await this.one(() => this.put(uid, text, was?.version ?? null, "edit", {}, t.who));
|
|
6865
|
-
if (saved.entry) await t.item({
|
|
6866
|
-
kind: "change",
|
|
6867
|
-
note: uid,
|
|
6868
|
-
entry: saved.entry,
|
|
6869
|
-
why: was ? "edit" : "create",
|
|
6870
|
-
title: `Understanding · ${title(id)}`,
|
|
6871
|
-
added: 0,
|
|
6872
|
-
removed: 0
|
|
6873
|
-
});
|
|
6874
|
-
return `Your reading of ${title(id)} is written.`;
|
|
6875
|
-
}
|
|
6876
6907
|
if (name === "read_data") {
|
|
6877
6908
|
const path = filePathOf(args.path);
|
|
6878
6909
|
if (!path) return `${String(args.path ?? "")} is not a file's path in their base.`;
|
|
@@ -6968,29 +6999,6 @@ var init_engine = __esmMin((() => {
|
|
|
6968
6999
|
];
|
|
6969
7000
|
return `${was === null ? "Written" : "Written anew"}: ${path}. ${run ? "It was run, with every control touched" : "It couldn't be run here (no browser), so only its rules were checked"}${problems.length ? `, and:\n${problems.map((p) => `- ${p}`).join("\n")}\nFix these and call write_artifact again with the whole file.` : run ? ", with no error." : "."}`;
|
|
6970
7001
|
}
|
|
6971
|
-
/** A note's Understanding note (M10): Iso's reading and your scratchpad. */
|
|
6972
|
-
async understanding(note) {
|
|
6973
|
-
if (!inBase(checkNoteId(note))) throw new EngineError("only a note of the base has an Understanding note");
|
|
6974
|
-
const uid = understandingId(note);
|
|
6975
|
-
const source = await this.readNote(uid).catch(() => null);
|
|
6976
|
-
return {
|
|
6977
|
-
note,
|
|
6978
|
-
...parseUnderstanding(source?.text ?? null),
|
|
6979
|
-
version: source?.version ?? null
|
|
6980
|
-
};
|
|
6981
|
-
}
|
|
6982
|
-
/** Your scratchpad in a note's Understanding note: yours alone; Iso does not write it. `base` as for saveNote, or
|
|
6983
|
-
* null when there is no Understanding note yet. */
|
|
6984
|
-
async saveScratchpad(note, scratchpad, base) {
|
|
6985
|
-
if (!inBase(checkNoteId(note))) throw new EngineError("only a note of the base has an Understanding note");
|
|
6986
|
-
const uid = understandingId(note), was = await this.readNote(uid).catch(() => null);
|
|
6987
|
-
const title = this.bundle.concepts.get(note)?.title ?? note;
|
|
6988
|
-
await this.one(() => this.put(uid, understandingText(note, title, {
|
|
6989
|
-
...parseUnderstanding(was?.text ?? null),
|
|
6990
|
-
scratchpad
|
|
6991
|
-
}), base));
|
|
6992
|
-
return this.understanding(note);
|
|
6993
|
-
}
|
|
6994
7002
|
/** A question asked in a turn, made a question note: in the folder of the first note it is about, named by its
|
|
6995
7003
|
* title. */
|
|
6996
7004
|
async makeQuestion(q, who, asked) {
|
|
@@ -7426,7 +7434,6 @@ var init_src = __esmMin((() => {
|
|
|
7426
7434
|
init_iso();
|
|
7427
7435
|
init_meaning();
|
|
7428
7436
|
init_agent();
|
|
7429
|
-
init_understand();
|
|
7430
7437
|
init_turn();
|
|
7431
7438
|
}));
|
|
7432
7439
|
//#endregion
|
|
@@ -8609,7 +8616,7 @@ function toTurns(messages, { live = /* @__PURE__ */ new Map(), ours = /* @__PURE
|
|
|
8609
8616
|
/** What is asked from a page, with what was given in the Iso pane's context: notes and folders by name, for the
|
|
8610
8617
|
* agent to read with isorite's tools, and passages as they are. */
|
|
8611
8618
|
function given(asked, parts, title) {
|
|
8612
|
-
const notes = parts.filter((p) => p.kind === "note"
|
|
8619
|
+
const notes = parts.filter((p) => p.kind === "note").map((p) => `- ${title(p.id)} (${p.id})`);
|
|
8613
8620
|
const folders = parts.filter((p) => p.kind === "folder").map((p) => `- the folder ${p.id}`);
|
|
8614
8621
|
const passages = parts.flatMap((p) => p.kind === "passage" ? [`From ${title(p.id)} (${p.id}):\n${p.text.split("\n").map((l) => "> " + l).join("\n")}`] : []);
|
|
8615
8622
|
const out = [asked.trim()];
|
|
@@ -8933,10 +8940,6 @@ const Given = z.discriminatedUnion("kind", [
|
|
|
8933
8940
|
kind: z.literal("passage"),
|
|
8934
8941
|
id: z.string().max(400),
|
|
8935
8942
|
text: z.string().max(2e4)
|
|
8936
|
-
}).strict(),
|
|
8937
|
-
z.object({
|
|
8938
|
-
kind: z.literal("understanding"),
|
|
8939
|
-
id: z.string().max(400)
|
|
8940
8943
|
}).strict()
|
|
8941
8944
|
]);
|
|
8942
8945
|
const Mode = z.enum([
|
|
@@ -9154,11 +9157,6 @@ function createApp({ api, token, loopback, web, allowHosts = [], notes, terminal
|
|
|
9154
9157
|
});
|
|
9155
9158
|
post("/api/iso/ask", Ask, (_c, b) => api.ask(b));
|
|
9156
9159
|
post("/api/iso/converse", TurnAsk, (_c, b) => api.converse(b));
|
|
9157
|
-
app.get("/api/understanding", (c) => answer(c, () => api.understanding(id(c))));
|
|
9158
|
-
post("/api/understanding/scratchpad", z.object({
|
|
9159
|
-
scratchpad: z.string().max(2e5),
|
|
9160
|
-
base: z.string().max(64).nullable()
|
|
9161
|
-
}).strict(), (c, b) => api.saveScratchpad(id(c), b.scratchpad, b.base));
|
|
9162
9160
|
post("/api/iso/take", z.object({
|
|
9163
9161
|
conversation: z.string().max(64),
|
|
9164
9162
|
turn: z.string().max(64),
|
|
@@ -9189,6 +9187,7 @@ function createApp({ api, token, loopback, web, allowHosts = [], notes, terminal
|
|
|
9189
9187
|
"reject"
|
|
9190
9188
|
])
|
|
9191
9189
|
}).strict(), (_c, b) => api.answer(b.turn, b.permission, b.decision));
|
|
9190
|
+
app.get("/api/conversations", (c) => answer(c, () => api.conversations()));
|
|
9192
9191
|
app.get("/api/conversation", (c) => answer(c, async () => await api.conversation(c.req.query("id") || void 0) ?? {
|
|
9193
9192
|
id: "",
|
|
9194
9193
|
turns: []
|
|
@@ -9779,7 +9778,7 @@ var Setup = class {
|
|
|
9779
9778
|
};
|
|
9780
9779
|
//#endregion
|
|
9781
9780
|
//#region packages/server/src/version.ts
|
|
9782
|
-
const VERSION = "0.
|
|
9781
|
+
const VERSION = "0.12.0";
|
|
9783
9782
|
//#endregion
|
|
9784
9783
|
//#region packages/server/src/git.ts
|
|
9785
9784
|
/** The top of the repository `folder` is in, or null: the nearest folder holding `.git`, a directory or, in a
|
|
@@ -11869,7 +11868,7 @@ const ISO_QUESTIONS = {
|
|
|
11869
11868
|
about: [TRIANGLE]
|
|
11870
11869
|
}
|
|
11871
11870
|
};
|
|
11872
|
-
/** Iso's
|
|
11871
|
+
/** Iso's answer to where you stand on Gauss–Bonnet, each sentence resting on what you can open. */
|
|
11873
11872
|
const READING = `You can state it and use it: the [examples](/${BONNET}.md) are yours, and you [solved the torus](/${TORUS}.md). [The proof sketch](/${BONNET}.md) is still mine, untouched: you have not yet said it in your own words. [Where compactness is used](/${COMPACT}.md) is open, and so is [the triangle](/${TRIANGLE}.md), whose solution leans on a step not yet shown.`;
|
|
11874
11873
|
const anchor = (text) => ({
|
|
11875
11874
|
text,
|
|
@@ -12118,7 +12117,6 @@ async function buildGeometry(sources, code, now = Date.now()) {
|
|
|
12118
12117
|
await write(CYLINDER, final(CYLINDER));
|
|
12119
12118
|
await engine.setDone(CYLINDER, true, (await engine.readNote(CYLINDER)).version);
|
|
12120
12119
|
});
|
|
12121
|
-
on(1, 55, async () => engine.saveScratchpad(BONNET, "Compact: I think it is only that the triangulation is finite. Check against the Möbius band, which is compact and still fails, so orientation must be a separate matter.", null));
|
|
12122
12120
|
on(0, -40, async () => {
|
|
12123
12121
|
replies.push({
|
|
12124
12122
|
calls: [{
|
|
@@ -12134,34 +12132,20 @@ async function buildGeometry(sources, code, now = Date.now()) {
|
|
|
12134
12132
|
usd: .0071
|
|
12135
12133
|
}
|
|
12136
12134
|
}, {
|
|
12137
|
-
|
|
12138
|
-
name: "write_understanding",
|
|
12139
|
-
arguments: {
|
|
12140
|
-
id: BONNET,
|
|
12141
|
-
reading: READING
|
|
12142
|
-
}
|
|
12143
|
-
}],
|
|
12135
|
+
text: READING,
|
|
12144
12136
|
usage: {
|
|
12145
12137
|
in: 7200,
|
|
12146
12138
|
out: 150,
|
|
12147
12139
|
cached: 4200,
|
|
12148
12140
|
usd: .0103
|
|
12149
12141
|
}
|
|
12150
|
-
}, {
|
|
12151
|
-
text: "I have written my reading of you on Gauss–Bonnet.",
|
|
12152
|
-
usage: {
|
|
12153
|
-
in: 7500,
|
|
12154
|
-
out: 20,
|
|
12155
|
-
cached: 7e3,
|
|
12156
|
-
usd: .0037
|
|
12157
|
-
}
|
|
12158
12142
|
});
|
|
12159
12143
|
const { turn: id } = await engine.converse({
|
|
12160
12144
|
mode: "ask",
|
|
12161
12145
|
asked: "where do I stand on Gauss–Bonnet?",
|
|
12162
12146
|
tier: "mid",
|
|
12163
12147
|
given: [{
|
|
12164
|
-
kind: "
|
|
12148
|
+
kind: "note",
|
|
12165
12149
|
id: BONNET
|
|
12166
12150
|
}]
|
|
12167
12151
|
});
|