@jigs.design/server 0.1.1 → 0.1.2
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 +13 -13
- package/dist/chat.d.ts +1 -1
- package/dist/chat.js +26 -26
- package/dist/compile.js +5 -5
- package/dist/confirm.js +1 -1
- package/dist/errors.d.ts +4 -4
- package/dist/errors.js +8 -8
- package/dist/index.d.ts +5 -5
- package/dist/index.js +3 -3
- package/dist/node.d.ts +2 -2
- package/dist/node.js +4 -4
- package/dist/pragma.js +3 -3
- package/dist/server.d.ts +4 -4
- package/dist/server.js +23 -23
- package/dist/session.js +2 -2
- package/dist/types.d.ts +10 -10
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
# @jigs.design/server
|
|
2
2
|
|
|
3
|
-
`
|
|
3
|
+
`createJigsServer` turns a host into one fetch handler. That handler streams checked programs, runs queries and mutations, and serves the sandbox frame. You give it a `run` function per procedure, a `context` for each request, and a `model` function that calls your LLM.
|
|
4
4
|
|
|
5
5
|
Import it from server code only.
|
|
6
6
|
|
|
7
7
|
```ts
|
|
8
|
-
import {
|
|
8
|
+
import { createJigsServer, JigsError } from "@jigs.design/server";
|
|
9
9
|
import { aiSdkModel } from "@jigs.design/ai-sdk";
|
|
10
10
|
import { host } from "./host";
|
|
11
11
|
|
|
12
|
-
export const
|
|
12
|
+
export const jigs = createJigsServer({
|
|
13
13
|
host,
|
|
14
14
|
context: async (request) => ({ userId: await userIdFrom(request) }),
|
|
15
15
|
run: {
|
|
@@ -17,7 +17,7 @@ export const pickle = createPickleServer({
|
|
|
17
17
|
db.listOrders(ctx.userId, input.status, { signal }),
|
|
18
18
|
archiveOrder: async (input, { ctx }) => {
|
|
19
19
|
if (!(await db.archiveOrder(ctx.userId, input.id))) {
|
|
20
|
-
throw new
|
|
20
|
+
throw new JigsError("NOT_FOUND", "That order is gone.");
|
|
21
21
|
}
|
|
22
22
|
},
|
|
23
23
|
},
|
|
@@ -25,22 +25,22 @@ export const pickle = createPickleServer({
|
|
|
25
25
|
instructions: "You are Acme's order assistant. Today is 2026-10-18.",
|
|
26
26
|
});
|
|
27
27
|
|
|
28
|
-
// Mount it as GET, POST and OPTIONS on one route, e.g. /api/
|
|
29
|
-
export const handler =
|
|
28
|
+
// Mount it as GET, POST and OPTIONS on one route, e.g. /api/jigs.
|
|
29
|
+
export const handler = jigs.handler;
|
|
30
30
|
```
|
|
31
31
|
|
|
32
32
|
The server renders the prompt from the host, calls the model, checks each streamed prefix and compiles it to a program. `instructions`, such as who the assistant is and today's date, reach every prompt: document-mode sessions, chat and repairs. When the checker finds errors, it runs repair rounds. A call carries its procedure's `kind`, and the server refuses one that does not match the host. A follow-up turn may answer with SEARCH/REPLACE edits instead of a whole document.
|
|
33
33
|
|
|
34
|
-
Specs need not come from the model. `
|
|
34
|
+
Specs need not come from the model. `jigs.spec(name)` returns a spec your product ships in `specs`, compiled once at startup. `jigs.compile(source)` checks and compiles one a user saved.
|
|
35
35
|
|
|
36
36
|
## Exports
|
|
37
37
|
|
|
38
38
|
| Export | What it is |
|
|
39
39
|
| -------------------------- | ----------------------------------------------------------------------------------- |
|
|
40
|
-
| `
|
|
40
|
+
| `createJigsServer` | The server: `handler`, `spec`, `compile`, `chat`, and the functions `handler` wraps |
|
|
41
41
|
| `defineRun` | Types `run` functions outside a server, to share them between two servers |
|
|
42
|
-
| `
|
|
43
|
-
| `
|
|
42
|
+
| `JigsError` | Throw from `context` or `run` with a code the browser can read |
|
|
43
|
+
| `JigsCompileError` | What a strict `jigs.compile` rejects with, carrying the `diagnostics` |
|
|
44
44
|
| `chatBlockText` | Writes a chat block back as a fenced block, for the model's history |
|
|
45
45
|
| `@jigs.design/server/node` | `nodeHandler`, for Node's `http` and Express |
|
|
46
46
|
|
|
@@ -48,13 +48,13 @@ It re-exports the shared types from `@jigs.design/runtime`.
|
|
|
48
48
|
|
|
49
49
|
## Source
|
|
50
50
|
|
|
51
|
-
- `src/server.ts`: `
|
|
51
|
+
- `src/server.ts`: `createJigsServer` and the request routing.
|
|
52
52
|
- `src/session.ts`: one turn: prompt, model, checking, repair and edits.
|
|
53
53
|
- `src/compile.ts`: compiling a document against the host's catalog and recipes.
|
|
54
54
|
- `src/inputs.ts`, `src/literal.ts`: literal procedure inputs checked against their schemas.
|
|
55
|
-
- `src/chat.ts`: chat mode, where a Markdown reply carries fenced `
|
|
55
|
+
- `src/chat.ts`: chat mode, where a Markdown reply carries fenced `jigs` blocks.
|
|
56
56
|
- `src/invalidation.ts`: which queries a mutation refreshes.
|
|
57
|
-
- `src/pragma.ts`: the `{@
|
|
57
|
+
- `src/pragma.ts`: the `{@jigs 0 catalog=3}` version line.
|
|
58
58
|
- `src/node.ts`: the Node adapter.
|
|
59
59
|
- `src/errors.ts`, `src/types.ts`: errors and the public types.
|
|
60
60
|
|
package/dist/chat.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import "@jigs.design/compiler";
|
|
|
5
5
|
import { ChatBlock, Diagnostic, Program } from "@jigs.design/runtime";
|
|
6
6
|
//#region src/chat.d.ts
|
|
7
7
|
/**
|
|
8
|
-
* A block as the model wrote it, for the model's history: a fenced `
|
|
8
|
+
* A block as the model wrote it, for the model's history: a fenced `jigs`
|
|
9
9
|
* block with its id, and its source without the pragma line.
|
|
10
10
|
*/
|
|
11
11
|
export declare function chatBlockText(block: ChatBlockSource): string;
|
package/dist/chat.js
CHANGED
|
@@ -17,13 +17,13 @@ const MAX_BLOCKS = 8;
|
|
|
17
17
|
*/
|
|
18
18
|
const MAX_BLOCK_REPAIRS = 3;
|
|
19
19
|
/**
|
|
20
|
-
* Lines after unfenced
|
|
20
|
+
* Lines after unfenced Jigs that wait to see whether more Jigs follows
|
|
21
21
|
* (a heading or a blank line inside a document), before they show as prose.
|
|
22
22
|
*/
|
|
23
23
|
const MAX_HELD_LINES = 6;
|
|
24
24
|
/**
|
|
25
25
|
* Tags Markdown and HTML also use, so a prose line may start with one, as in
|
|
26
|
-
* "<code>npm i</code> installs it." Such a line is
|
|
26
|
+
* "<code>npm i</code> installs it." Such a line is Jigs only when it is all
|
|
27
27
|
* markup, ending in a tag.
|
|
28
28
|
*/
|
|
29
29
|
const PROSE_TAGS = /* @__PURE__ */ new Set([
|
|
@@ -51,12 +51,12 @@ const PROSE_TAGS = /* @__PURE__ */ new Set([
|
|
|
51
51
|
"table",
|
|
52
52
|
"u"
|
|
53
53
|
]);
|
|
54
|
-
/** A line that opens a
|
|
55
|
-
const
|
|
56
|
-
/** A line that closes a
|
|
54
|
+
/** A line that opens a jig block: ```jigs, then an optional id. */
|
|
55
|
+
const JIGS_OPEN = /^( {0,3})`{3}[ \t]*jigs(?:[ \t]+([^`]*?))?[ \t]*$/i;
|
|
56
|
+
/** A line that closes a jig block. */
|
|
57
57
|
const BLOCK_CLOSE = /^ {0,3}`{3,}[ \t]*$/;
|
|
58
58
|
/**
|
|
59
|
-
* A fence with text after it, inside a block.
|
|
59
|
+
* A fence with text after it, inside a block. Jigs never holds a fence, so
|
|
60
60
|
* the model closed the block and ran its prose onto the same line.
|
|
61
61
|
*/
|
|
62
62
|
const BLOCK_CLOSE_RUN_ON = /^ {0,3}`{3,}(.+)$/;
|
|
@@ -83,21 +83,21 @@ const FENCE_OPEN = /^ {0,3}(`{3,}|~{3,})(.*)$/;
|
|
|
83
83
|
const MAYBE_FENCE = /^ {0,3}(?:`{0,2}|~{0,2})$/;
|
|
84
84
|
/** A partial line that is a fence line, whose end decides what it opens. */
|
|
85
85
|
const FENCE_START = /^ {0,3}(?:`{3}|~{3})/;
|
|
86
|
-
const AUTO_ID = /^
|
|
86
|
+
const AUTO_ID = /^jigs-(\d+)$/;
|
|
87
87
|
const VALID_ID = /^[a-z][a-z0-9-]*$/;
|
|
88
88
|
/**
|
|
89
|
-
* A block as the model wrote it, for the model's history: a fenced `
|
|
89
|
+
* A block as the model wrote it, for the model's history: a fenced `jigs`
|
|
90
90
|
* block with its id, and its source without the pragma line.
|
|
91
91
|
*/
|
|
92
92
|
function chatBlockText(block) {
|
|
93
93
|
const body = splitPragma(block.source).body.replace(/\n+$/, "");
|
|
94
|
-
return `\`\`\`
|
|
94
|
+
return `\`\`\`jigs ${block.id}\n${body}\n\`\`\``;
|
|
95
95
|
}
|
|
96
96
|
/** The block's id from the fence's info string, made kebab-case. */
|
|
97
97
|
function slug(info) {
|
|
98
98
|
const joined = info.toLowerCase().split(/[^a-z0-9]+/).filter((word) => word !== "").join("-");
|
|
99
99
|
if (joined === "") return "";
|
|
100
|
-
return /^[a-z]/.test(joined) ? joined : `
|
|
100
|
+
return /^[a-z]/.test(joined) ? joined : `jigs-${joined}`;
|
|
101
101
|
}
|
|
102
102
|
/** Whether `line` closes a code fence opened with `fence`. */
|
|
103
103
|
function closesFence(line, fence) {
|
|
@@ -126,7 +126,7 @@ function depthChange(line) {
|
|
|
126
126
|
return trimmed.endsWith("/>") || trimmed.includes(`</${name}>`) ? 0 : 1;
|
|
127
127
|
}
|
|
128
128
|
/**
|
|
129
|
-
* Splits a chat reply into prose and
|
|
129
|
+
* Splits a chat reply into prose and jig blocks as it streams. Pure and
|
|
130
130
|
* synchronous: `push` takes any slice of the reply and returns what it
|
|
131
131
|
* completed. Prose comes out as soon as a partial line can no longer be a
|
|
132
132
|
* fence; a block compiles at each committed line and is sent again whenever
|
|
@@ -169,15 +169,15 @@ function createReplyParser(deps, history) {
|
|
|
169
169
|
/** Whether the current prose line is already known to be text. */
|
|
170
170
|
let lineIsText = false;
|
|
171
171
|
let out = [];
|
|
172
|
-
/** Whether a complete prose line is
|
|
172
|
+
/** Whether a complete prose line is Jigs the model forgot to fence. */
|
|
173
173
|
const strayLine = (value) => {
|
|
174
174
|
if (BODY_LINE.test(value)) return true;
|
|
175
175
|
const name = TAG_LINE.exec(value)?.[1] ?? "";
|
|
176
176
|
if (!deps.tags.has(name)) return false;
|
|
177
177
|
return !PROSE_TAGS.has(name) || value.trimEnd().endsWith(">");
|
|
178
178
|
};
|
|
179
|
-
/** Whether a line keeps unfenced
|
|
180
|
-
const
|
|
179
|
+
/** Whether a line keeps unfenced Jigs going: a stray line or a closing tag. */
|
|
180
|
+
const jigsLine = (value) => value.trim() !== "" && (strayLine(value) || /^\s*<\//.test(value));
|
|
181
181
|
/** Whether a partial prose line may still become a stray line. */
|
|
182
182
|
const mayBeStray = (partial) => {
|
|
183
183
|
const trimmed = partial.trimStart();
|
|
@@ -249,7 +249,7 @@ function createReplyParser(deps, history) {
|
|
|
249
249
|
};
|
|
250
250
|
const open = (info, indent, implicit = false) => {
|
|
251
251
|
const named = slug(info ?? "");
|
|
252
|
-
const id = named === "" ? `
|
|
252
|
+
const id = named === "" ? `jigs-${++autoId}` : named;
|
|
253
253
|
const version = (versions.get(id) ?? 0) + 1;
|
|
254
254
|
versions.set(id, version);
|
|
255
255
|
opened++;
|
|
@@ -319,7 +319,7 @@ function createReplyParser(deps, history) {
|
|
|
319
319
|
if (block.over) {
|
|
320
320
|
settle(block, blockOf(block, "", empty, "done", {
|
|
321
321
|
code: "RATE_LIMITED",
|
|
322
|
-
message: `A reply shows at most ${MAX_BLOCKS}
|
|
322
|
+
message: `A reply shows at most ${MAX_BLOCKS} jigs, so this one was left out.`
|
|
323
323
|
}));
|
|
324
324
|
return;
|
|
325
325
|
}
|
|
@@ -332,7 +332,7 @@ function createReplyParser(deps, history) {
|
|
|
332
332
|
if (base === void 0) {
|
|
333
333
|
settle(block, blockOf(block, "", empty, "done", {
|
|
334
334
|
code: "NOT_FOUND",
|
|
335
|
-
message: `There is no earlier
|
|
335
|
+
message: `There is no earlier jig "${block.id}" to change.`
|
|
336
336
|
}), {
|
|
337
337
|
applied: false,
|
|
338
338
|
blocks: parsed.length
|
|
@@ -391,7 +391,7 @@ function createReplyParser(deps, history) {
|
|
|
391
391
|
if (mode.kind === "block") {
|
|
392
392
|
const { block } = mode;
|
|
393
393
|
if (block.implicit) {
|
|
394
|
-
if (block.depth > 0 ||
|
|
394
|
+
if (block.depth > 0 || jigsLine(value)) {
|
|
395
395
|
block.lines.push(...block.waiting);
|
|
396
396
|
block.waiting = [];
|
|
397
397
|
block.depth = Math.max(0, block.depth + depthChange(value));
|
|
@@ -414,7 +414,7 @@ function createReplyParser(deps, history) {
|
|
|
414
414
|
const runOn = BLOCK_CLOSE_RUN_ON.exec(value);
|
|
415
415
|
if (runOn !== null) {
|
|
416
416
|
close(block);
|
|
417
|
-
line(
|
|
417
|
+
line(JIGS_OPEN.test(value) ? value : (runOn[1] ?? "").trimStart());
|
|
418
418
|
return;
|
|
419
419
|
}
|
|
420
420
|
let cut = 0;
|
|
@@ -432,9 +432,9 @@ function createReplyParser(deps, history) {
|
|
|
432
432
|
text(`${raw}\n`);
|
|
433
433
|
return;
|
|
434
434
|
}
|
|
435
|
-
const
|
|
436
|
-
if (
|
|
437
|
-
open(
|
|
435
|
+
const jigs = JIGS_OPEN.exec(value);
|
|
436
|
+
if (jigs !== null) {
|
|
437
|
+
open(jigs[2], jigs[1]?.length ?? 0);
|
|
438
438
|
return;
|
|
439
439
|
}
|
|
440
440
|
if (TOOL_MARKUP.test(value)) return;
|
|
@@ -452,7 +452,7 @@ function createReplyParser(deps, history) {
|
|
|
452
452
|
};
|
|
453
453
|
/**
|
|
454
454
|
* Closes a block; for one with no fence, the lines still waiting after
|
|
455
|
-
* its
|
|
455
|
+
* its Jigs lines are prose again.
|
|
456
456
|
*/
|
|
457
457
|
function finishImplicit(block) {
|
|
458
458
|
const waiting = block.waiting;
|
|
@@ -515,12 +515,12 @@ function createReplyParser(deps, history) {
|
|
|
515
515
|
if (!block.implicit) {
|
|
516
516
|
if (last !== "") line(last);
|
|
517
517
|
closeOpen();
|
|
518
|
-
} else if (last !== "" && (block.depth > 0 ||
|
|
518
|
+
} else if (last !== "" && (block.depth > 0 || jigsLine(last))) {
|
|
519
519
|
line(last);
|
|
520
520
|
closeOpen();
|
|
521
521
|
} else {
|
|
522
522
|
finishImplicit(block);
|
|
523
|
-
if (
|
|
523
|
+
if (JIGS_OPEN.exec(last) === null) text(last);
|
|
524
524
|
}
|
|
525
525
|
} else if (lineIsText) lineIsText = false;
|
|
526
526
|
else if (held !== "") {
|
|
@@ -529,7 +529,7 @@ function createReplyParser(deps, history) {
|
|
|
529
529
|
if (mode.kind !== "code" && strayLine(last)) {
|
|
530
530
|
line(last);
|
|
531
531
|
closeOpen();
|
|
532
|
-
} else if (mode.kind === "code" ||
|
|
532
|
+
} else if (mode.kind === "code" || JIGS_OPEN.exec(last) === null) text(last);
|
|
533
533
|
}
|
|
534
534
|
const events = out;
|
|
535
535
|
out = [];
|
package/dist/compile.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { designChecks } from "./design.js";
|
|
2
|
-
import {
|
|
2
|
+
import { JigsCompileError, fatalDiagnostics } from "./errors.js";
|
|
3
3
|
import { inputDiagnostics } from "./inputs.js";
|
|
4
4
|
import { outputDiagnostics } from "./outputs.js";
|
|
5
|
-
import { columnAt,
|
|
5
|
+
import { columnAt, compileJigs, compileLibrary, lineAt } from "@jigs.design/compiler";
|
|
6
6
|
import { componentSchema } from "@jigs.design/host";
|
|
7
7
|
import { PROGRAM_FORMAT } from "@jigs.design/runtime";
|
|
8
8
|
//#region src/compile.ts
|
|
@@ -129,7 +129,7 @@ function tagsIn(source) {
|
|
|
129
129
|
* or calls a procedure the host does not have, so a bad recipe stops the
|
|
130
130
|
* server at startup instead of reaching the model. Throws too when a
|
|
131
131
|
* situation's example has a diagnostic worse than info, so the prompt never
|
|
132
|
-
* shows the model
|
|
132
|
+
* shows the model Jigs the checker refuses.
|
|
133
133
|
*/
|
|
134
134
|
function createChecker(host) {
|
|
135
135
|
const catalog = compileCatalog(host.components);
|
|
@@ -167,7 +167,7 @@ function createChecker(host) {
|
|
|
167
167
|
};
|
|
168
168
|
};
|
|
169
169
|
const compile = (body) => {
|
|
170
|
-
const result =
|
|
170
|
+
const result = compileJigs(body, {
|
|
171
171
|
catalog,
|
|
172
172
|
library
|
|
173
173
|
});
|
|
@@ -213,7 +213,7 @@ function createChecker(host) {
|
|
|
213
213
|
for (const entry of host.situations) {
|
|
214
214
|
if (entry.example === void 0) continue;
|
|
215
215
|
const fatal = fatalDiagnostics(compile(entry.example).diagnostics);
|
|
216
|
-
if (fatal.length > 0) throw new
|
|
216
|
+
if (fatal.length > 0) throw new JigsCompileError(`Situation "${entry.name}" example`, fatal);
|
|
217
217
|
}
|
|
218
218
|
return { compile };
|
|
219
219
|
}
|
package/dist/confirm.js
CHANGED
|
@@ -68,7 +68,7 @@ function createConfirmer(secret, store, now) {
|
|
|
68
68
|
name: "HMAC"
|
|
69
69
|
}, false, ["sign", "verify"]);
|
|
70
70
|
const signed = (binding, expiresAt, id) => encoder.encode(JSON.stringify([
|
|
71
|
-
"
|
|
71
|
+
"jigs-confirm-1",
|
|
72
72
|
binding.name,
|
|
73
73
|
binding.subject,
|
|
74
74
|
expiresAt,
|
package/dist/errors.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { Diagnostic,
|
|
1
|
+
import { Diagnostic, JigsErrorCode, JigsErrorData } from "@jigs.design/runtime";
|
|
2
2
|
//#region src/errors.d.ts
|
|
3
3
|
/** Codes a product may throw from `context` or `run`. */
|
|
4
|
-
export type ThrownCode = Exclude<
|
|
4
|
+
export type ThrownCode = Exclude<JigsErrorCode, "DECLINED" | "NETWORK" | "UNAVAILABLE" | "UNKNOWN_PROCEDURE">;
|
|
5
5
|
declare const BRAND: unique symbol;
|
|
6
6
|
/** An error whose code and message reach the browser. */
|
|
7
|
-
export declare class
|
|
7
|
+
export declare class JigsError extends Error {
|
|
8
8
|
readonly [BRAND] = true;
|
|
9
9
|
readonly code: ThrownCode;
|
|
10
10
|
constructor(code: ThrownCode, message: string);
|
|
@@ -14,7 +14,7 @@ export declare class PickleError extends Error {
|
|
|
14
14
|
* startup. `diagnostics` holds the error and warning diagnostics; the message
|
|
15
15
|
* lists them with their lines.
|
|
16
16
|
*/
|
|
17
|
-
export declare class
|
|
17
|
+
export declare class JigsCompileError extends Error {
|
|
18
18
|
readonly diagnostics: ReadonlyArray<Diagnostic>;
|
|
19
19
|
constructor(subject: string, diagnostics: ReadonlyArray<Diagnostic>);
|
|
20
20
|
}
|
package/dist/errors.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
//#region src/errors.ts
|
|
2
|
-
const BRAND = Symbol.for("@jigs.design/server.
|
|
2
|
+
const BRAND = Symbol.for("@jigs.design/server.JigsError");
|
|
3
3
|
/** An error whose code and message reach the browser. */
|
|
4
|
-
var
|
|
4
|
+
var JigsError = class extends Error {
|
|
5
5
|
[BRAND] = true;
|
|
6
6
|
code;
|
|
7
7
|
constructor(code, message) {
|
|
8
8
|
super(message);
|
|
9
9
|
this.code = code;
|
|
10
|
-
this.name = "
|
|
10
|
+
this.name = "JigsError";
|
|
11
11
|
}
|
|
12
12
|
};
|
|
13
|
-
function
|
|
13
|
+
function isJigsError(cause) {
|
|
14
14
|
return typeof cause === "object" && cause !== null && BRAND in cause;
|
|
15
15
|
}
|
|
16
16
|
/** Diagnostics that make a stored spec or a strict compile fail. */
|
|
@@ -22,13 +22,13 @@ function fatalDiagnostics(diagnostics) {
|
|
|
22
22
|
* startup. `diagnostics` holds the error and warning diagnostics; the message
|
|
23
23
|
* lists them with their lines.
|
|
24
24
|
*/
|
|
25
|
-
var
|
|
25
|
+
var JigsCompileError = class extends Error {
|
|
26
26
|
diagnostics;
|
|
27
27
|
constructor(subject, diagnostics) {
|
|
28
28
|
const lines = diagnostics.map((diagnostic) => `line ${diagnostic.span.line}: ${diagnostic.message}`);
|
|
29
29
|
super(`${subject} failed to compile:\n${lines.join("\n")}`);
|
|
30
30
|
this.diagnostics = diagnostics;
|
|
31
|
-
this.name = "
|
|
31
|
+
this.name = "JigsCompileError";
|
|
32
32
|
}
|
|
33
33
|
};
|
|
34
34
|
const STATUS = {
|
|
@@ -48,7 +48,7 @@ function statusOf(code) {
|
|
|
48
48
|
return STATUS[code];
|
|
49
49
|
}
|
|
50
50
|
const INTERNAL_MESSAGE = "Something went wrong.";
|
|
51
|
-
/** The browser's view of a thrown value: a `
|
|
51
|
+
/** The browser's view of a thrown value: a `JigsError` keeps its message, anything else does not. */
|
|
52
52
|
function errorData(error) {
|
|
53
53
|
return error === null ? {
|
|
54
54
|
code: "INTERNAL",
|
|
@@ -59,4 +59,4 @@ function errorData(error) {
|
|
|
59
59
|
};
|
|
60
60
|
}
|
|
61
61
|
//#endregion
|
|
62
|
-
export { INTERNAL_MESSAGE,
|
|
62
|
+
export { INTERNAL_MESSAGE, JigsCompileError, JigsError, errorData, fatalDiagnostics, isJigsError, statusOf };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Advice, DesignCheckCode, Placement } from "./design.js";
|
|
2
2
|
import { ConfirmationStore, memoryConfirmations } from "./confirm.js";
|
|
3
|
-
import { CallContext, CallOutcome, CallReport, CallReportOutcome, CallRequest, ChatBlockResult, ChatBlockSource, ChatEvent, ChatOptions, ChatTurn, CompileOptions, ContextFunction, EditFailureReason, ErrorInfo,
|
|
3
|
+
import { CallContext, CallOutcome, CallReport, CallReportOutcome, CallRequest, ChatBlockResult, ChatBlockSource, ChatEvent, ChatOptions, ChatTurn, CompileOptions, ContextFunction, EditFailureReason, ErrorInfo, JigsServer, JigsServerOptions, ModelFunction, ModelRequest, ModelRequestKind, PolicyCall, RequiresAction, RunFunctions, SessionRequest, Turn, TurnEdits, TurnRewrite, TurnRound, Usage } from "./types.js";
|
|
4
4
|
import { chatBlockText } from "./chat.js";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import { JigsCompileError, JigsError, ThrownCode } from "./errors.js";
|
|
6
|
+
import { createJigsServer, defineRun } from "./server.js";
|
|
7
7
|
import { addUsage } from "./usage.js";
|
|
8
8
|
import { PromptMode } from "@jigs.design/prompt";
|
|
9
|
-
import { ChatBlock, ChatBlockStatus, Diagnostic,
|
|
10
|
-
export { type Advice, type CallContext, type CallOutcome, type CallReport, type CallReportOutcome, type CallRequest, type ChatBlock, type ChatBlockResult, type ChatBlockSource, type ChatBlockStatus, type ChatEvent, type ChatOptions, type ChatTurn, type CompileOptions, type ConfirmationStore, type ContextFunction, type DesignCheckCode, type Diagnostic, type EditFailureReason, type ErrorInfo,
|
|
9
|
+
import { ChatBlock, ChatBlockStatus, Diagnostic, JigsErrorCode, JigsErrorData, Message, Program, SessionEvent, Span } from "@jigs.design/runtime";
|
|
10
|
+
export { type Advice, type CallContext, type CallOutcome, type CallReport, type CallReportOutcome, type CallRequest, type ChatBlock, type ChatBlockResult, type ChatBlockSource, type ChatBlockStatus, type ChatEvent, type ChatOptions, type ChatTurn, type CompileOptions, type ConfirmationStore, type ContextFunction, type DesignCheckCode, type Diagnostic, type EditFailureReason, type ErrorInfo, JigsCompileError, JigsError, type JigsErrorCode, type JigsErrorData, type JigsServer, type JigsServerOptions, type Message, type ModelFunction, type ModelRequest, type ModelRequestKind, type Placement, type PolicyCall, type Program, type PromptMode, type RequiresAction, type RunFunctions, type SessionEvent, type SessionRequest, type Span, type ThrownCode, type Turn, type TurnEdits, type TurnRewrite, type TurnRound, type Usage, addUsage, chatBlockText, createJigsServer, defineRun, memoryConfirmations };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { JigsCompileError, JigsError } from "./errors.js";
|
|
2
2
|
import { addUsage } from "./usage.js";
|
|
3
3
|
import { chatBlockText } from "./chat.js";
|
|
4
4
|
import { memoryConfirmations } from "./confirm.js";
|
|
5
|
-
import {
|
|
6
|
-
export {
|
|
5
|
+
import { createJigsServer, defineRun } from "./server.js";
|
|
6
|
+
export { JigsCompileError, JigsError, addUsage, chatBlockText, createJigsServer, defineRun, memoryConfirmations };
|
package/dist/node.d.ts
CHANGED
|
@@ -10,10 +10,10 @@ interface HandlerOwner {
|
|
|
10
10
|
maxBodyBytes: number;
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
13
|
-
* Mounts `
|
|
13
|
+
* Mounts `jigs.handler` on Express or plain Node. It builds a standard
|
|
14
14
|
* `Request`, so `context` is the same function on every platform, and aborts
|
|
15
15
|
* the request's signal when the connection closes early.
|
|
16
16
|
*/
|
|
17
|
-
export declare function nodeHandler(
|
|
17
|
+
export declare function nodeHandler(jigs: HandlerOwner): (request: NodeRequest, response: ServerResponse) => void;
|
|
18
18
|
//#endregion
|
|
19
19
|
export {};
|
package/dist/node.js
CHANGED
|
@@ -40,11 +40,11 @@ function toHeaders(request) {
|
|
|
40
40
|
return headers;
|
|
41
41
|
}
|
|
42
42
|
/**
|
|
43
|
-
* Mounts `
|
|
43
|
+
* Mounts `jigs.handler` on Express or plain Node. It builds a standard
|
|
44
44
|
* `Request`, so `context` is the same function on every platform, and aborts
|
|
45
45
|
* the request's signal when the connection closes early.
|
|
46
46
|
*/
|
|
47
|
-
function nodeHandler(
|
|
47
|
+
function nodeHandler(jigs) {
|
|
48
48
|
return (request, response) => {
|
|
49
49
|
const abort = new AbortController();
|
|
50
50
|
response.on("close", () => {
|
|
@@ -54,14 +54,14 @@ function nodeHandler(pickle) {
|
|
|
54
54
|
try {
|
|
55
55
|
const encrypted = "encrypted" in request.socket;
|
|
56
56
|
const url = new URL(request.originalUrl ?? request.url ?? "/", `${encrypted ? "https" : "http"}://${request.headers.host ?? "localhost"}`);
|
|
57
|
-
const body = await readBody(request,
|
|
57
|
+
const body = await readBody(request, jigs.maxBodyBytes);
|
|
58
58
|
const init = {
|
|
59
59
|
headers: toHeaders(request),
|
|
60
60
|
method: request.method ?? "GET",
|
|
61
61
|
signal: abort.signal
|
|
62
62
|
};
|
|
63
63
|
if (body !== null) init.body = body;
|
|
64
|
-
const reply = await
|
|
64
|
+
const reply = await jigs.handler(new Request(url, init));
|
|
65
65
|
response.statusCode = reply.status;
|
|
66
66
|
reply.headers.forEach((value, name) => {
|
|
67
67
|
response.setHeader(name, value);
|
package/dist/pragma.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const PRAGMA = /^\{@
|
|
2
|
-
/** Splits a leading `{@
|
|
1
|
+
const PRAGMA = /^\{@jigs\s+(\d+)(?:\s+catalog=(\d+))?\}[ \t]*(?:\r?\n|$)/;
|
|
2
|
+
/** Splits a leading `{@jigs 0 catalog=1}` line from the body. */
|
|
3
3
|
function splitPragma(source) {
|
|
4
4
|
const match = PRAGMA.exec(source);
|
|
5
5
|
if (match === null) return {
|
|
@@ -39,7 +39,7 @@ function versionDiagnostics(versions, catalogVersion) {
|
|
|
39
39
|
}
|
|
40
40
|
/** The pragma line `withPragma` puts above a body, with its line break. */
|
|
41
41
|
function pragmaLine(catalogVersion) {
|
|
42
|
-
return `{@
|
|
42
|
+
return `{@jigs 0 catalog=${catalogVersion}}\n`;
|
|
43
43
|
}
|
|
44
44
|
/** `body` with a pragma naming the versions it was checked against. */
|
|
45
45
|
function withPragma(body, catalogVersion) {
|
package/dist/server.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { ContextFunction,
|
|
1
|
+
import { ContextFunction, JigsServer, JigsServerOptions, RunFunctions } from "./types.js";
|
|
2
2
|
import { Catalog, Procedures } from "@jigs.design/host";
|
|
3
3
|
//#region src/server.d.ts
|
|
4
4
|
/**
|
|
5
|
-
* Types a `context` and `run` pair outside `
|
|
5
|
+
* Types a `context` and `run` pair outside `createJigsServer`, so two
|
|
6
6
|
* servers (one per platform) can share them. `TContext` comes from `context`
|
|
7
|
-
* alone, as in `
|
|
7
|
+
* alone, as in `createJigsServer`.
|
|
8
8
|
*/
|
|
9
9
|
export declare function defineRun<const TProcedures extends Procedures, TContext = any>(procedures: TProcedures, handlers: {
|
|
10
10
|
context: ContextFunction<TContext>;
|
|
@@ -13,5 +13,5 @@ export declare function defineRun<const TProcedures extends Procedures, TContext
|
|
|
13
13
|
context: ContextFunction<TContext>;
|
|
14
14
|
run: RunFunctions<TProcedures, TContext>;
|
|
15
15
|
};
|
|
16
|
-
export declare function
|
|
16
|
+
export declare function createJigsServer<const TProcedures extends Procedures, const TCatalog extends Catalog, TContext = any, TOptions = undefined, const TSpecName extends string = never>(options: JigsServerOptions<TProcedures, TCatalog, TContext, TOptions, TSpecName>): JigsServer<TContext, TSpecName>;
|
|
17
17
|
//#endregion
|
package/dist/server.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { INTERNAL_MESSAGE,
|
|
1
|
+
import { INTERNAL_MESSAGE, JigsCompileError, JigsError, errorData, fatalDiagnostics, isJigsError, statusOf } from "./errors.js";
|
|
2
2
|
import { checkMarkdownElements, createChecker } from "./compile.js";
|
|
3
3
|
import { belowPrefix, splitPragma, versionDiagnostics } from "./pragma.js";
|
|
4
4
|
import { MAX_CONTENT, messagesSchema, runSession } from "./session.js";
|
|
@@ -11,7 +11,7 @@ import { PROGRAM_FORMAT } from "@jigs.design/runtime";
|
|
|
11
11
|
import { z } from "zod";
|
|
12
12
|
import { frameDocument, frameSecurityPolicy } from "@jigs.design/runtime/frame";
|
|
13
13
|
//#region src/server.ts
|
|
14
|
-
const VERSION_HEADER = "
|
|
14
|
+
const VERSION_HEADER = "jigs-version";
|
|
15
15
|
const DEFAULT_MAX_BODY_BYTES = 1e6;
|
|
16
16
|
const HEARTBEAT_MS = 15e3;
|
|
17
17
|
/** A small document whose compiled code changes when the compiler's output does. */
|
|
@@ -96,12 +96,12 @@ const TOKEN_REFUSALS = {
|
|
|
96
96
|
function confirmerFor(options) {
|
|
97
97
|
if (options.secret === void 0) {
|
|
98
98
|
const confirming = Object.entries(options.host.procedures).find(([, procedure]) => procedure.kind === "mutation" && procedure.policy === "confirm");
|
|
99
|
-
if (confirming !== void 0) throw new Error(`
|
|
100
|
-
if (options.confirmSubject !== void 0) throw new Error("
|
|
99
|
+
if (confirming !== void 0) throw new Error(`createJigsServer needs a secret and confirmSubject: "${confirming[0]}" asks for confirmation, and its tokens are signed with the secret`);
|
|
100
|
+
if (options.confirmSubject !== void 0) throw new Error("createJigsServer has confirmSubject but no secret");
|
|
101
101
|
return null;
|
|
102
102
|
}
|
|
103
|
-
if (options.secret.length < 32) throw new Error(`
|
|
104
|
-
if (options.confirmSubject === void 0) throw new Error("
|
|
103
|
+
if (options.secret.length < 32) throw new Error(`createJigsServer's secret must be at least 32 characters`);
|
|
104
|
+
if (options.confirmSubject === void 0) throw new Error("createJigsServer has a secret but no confirmSubject: a confirmation token must be bound to who it was issued to");
|
|
105
105
|
const now = options.now ?? Date.now;
|
|
106
106
|
return createConfirmer(options.secret, options.confirmations ?? memoryConfirmations(now), now);
|
|
107
107
|
}
|
|
@@ -140,7 +140,7 @@ function hostFingerprint(host) {
|
|
|
140
140
|
});
|
|
141
141
|
}
|
|
142
142
|
/**
|
|
143
|
-
* What `
|
|
143
|
+
* What `jigs.chat` reads from the route besides the request. `blocks` and
|
|
144
144
|
* `prompt` come from the browser, so they are checked like a session's
|
|
145
145
|
* messages.
|
|
146
146
|
*/
|
|
@@ -177,17 +177,17 @@ function issuesText(error) {
|
|
|
177
177
|
return error.issues.slice(0, 3).map((issue) => issue.path.length === 0 ? issue.message : `${issue.path.join(".")}: ${issue.message}`).join("; ");
|
|
178
178
|
}
|
|
179
179
|
/**
|
|
180
|
-
* Types a `context` and `run` pair outside `
|
|
180
|
+
* Types a `context` and `run` pair outside `createJigsServer`, so two
|
|
181
181
|
* servers (one per platform) can share them. `TContext` comes from `context`
|
|
182
|
-
* alone, as in `
|
|
182
|
+
* alone, as in `createJigsServer`.
|
|
183
183
|
*/
|
|
184
184
|
function defineRun(procedures, handlers) {
|
|
185
185
|
return handlers;
|
|
186
186
|
}
|
|
187
|
-
function
|
|
187
|
+
function createJigsServer(options) {
|
|
188
188
|
const { host } = options;
|
|
189
189
|
checkMarkdownElements(host.components);
|
|
190
|
-
for (const [name, procedure] of Object.entries(host.procedures)) if (procedure.kind !== "action" && !Object.hasOwn(options.run, name)) throw new Error(`
|
|
190
|
+
for (const [name, procedure] of Object.entries(host.procedures)) if (procedure.kind !== "action" && !Object.hasOwn(options.run, name)) throw new Error(`createJigsServer has no run function for "${name}"`);
|
|
191
191
|
const confirmer = confirmerFor(options);
|
|
192
192
|
const checker = createChecker(host);
|
|
193
193
|
const promptOptions = (mode) => options.instructions === void 0 ? { mode } : {
|
|
@@ -198,7 +198,7 @@ function createPickleServer(options) {
|
|
|
198
198
|
const chatParts = systemPromptParts(host, promptOptions("chat"));
|
|
199
199
|
const system = `${documentParts.stable}\n\n${documentParts.variable}`;
|
|
200
200
|
const chatSystem = `${chatParts.stable}\n\n${chatParts.variable}`;
|
|
201
|
-
/** Tags that mark unfenced
|
|
201
|
+
/** Tags that mark unfenced Jigs in a chat reply. */
|
|
202
202
|
const chatTags = /* @__PURE__ */ new Set([...host.components.components.map((component) => component.name), ...host.recipes.map((entry) => entry.name)]);
|
|
203
203
|
const maxRepairs = options.maxRepairs ?? 1;
|
|
204
204
|
const programIntervalMs = options.programIntervalMs ?? 250;
|
|
@@ -256,7 +256,7 @@ function createPickleServer(options) {
|
|
|
256
256
|
});
|
|
257
257
|
return denial(name);
|
|
258
258
|
};
|
|
259
|
-
if (confirmer === null || options.confirmSubject === void 0) return refuse(/* @__PURE__ */ new Error(`The policy for "${name}" is "confirm", but
|
|
259
|
+
if (confirmer === null || options.confirmSubject === void 0) return refuse(/* @__PURE__ */ new Error(`The policy for "${name}" is "confirm", but createJigsServer has no secret and confirmSubject to sign a confirmation`));
|
|
260
260
|
let binding;
|
|
261
261
|
try {
|
|
262
262
|
binding = {
|
|
@@ -333,7 +333,7 @@ function createPickleServer(options) {
|
|
|
333
333
|
try {
|
|
334
334
|
result = await run(input, context);
|
|
335
335
|
} catch (error) {
|
|
336
|
-
if (
|
|
336
|
+
if (isJigsError(error)) return { error: errorData(error) };
|
|
337
337
|
onError(error, {
|
|
338
338
|
name: request.name,
|
|
339
339
|
type: "call"
|
|
@@ -458,14 +458,14 @@ function createPickleServer(options) {
|
|
|
458
458
|
const compileStrict = (subject, source, placement) => {
|
|
459
459
|
const compiled = compileStored(source, placement);
|
|
460
460
|
const fatal = fatalDiagnostics(compiled.diagnostics);
|
|
461
|
-
if (fatal.length > 0) throw new
|
|
461
|
+
if (fatal.length > 0) throw new JigsCompileError(subject, fatal);
|
|
462
462
|
return compiled;
|
|
463
463
|
};
|
|
464
464
|
const specs = /* @__PURE__ */ new Map();
|
|
465
465
|
for (const [name, source] of Object.entries(options.specs ?? {})) specs.set(name, compileStrict(`Spec "${name}"`, source).program);
|
|
466
466
|
const spec = (name) => {
|
|
467
467
|
const program = specs.get(name);
|
|
468
|
-
if (program === void 0) throw new Error(`
|
|
468
|
+
if (program === void 0) throw new Error(`createJigsServer has no spec named "${name}"`);
|
|
469
469
|
return program;
|
|
470
470
|
};
|
|
471
471
|
const compile = async (source, compileOptions) => compileOptions?.strict === false ? compileStored(source, compileOptions.placement) : compileStrict("The source", source, compileOptions?.placement);
|
|
@@ -502,26 +502,26 @@ function createPickleServer(options) {
|
|
|
502
502
|
};
|
|
503
503
|
const chat = async (request, chatOptions) => {
|
|
504
504
|
const refused = refusal(request);
|
|
505
|
-
if (refused !== null) throw new
|
|
505
|
+
if (refused !== null) throw new JigsError(refused.code, refused.message);
|
|
506
506
|
let ctx;
|
|
507
507
|
try {
|
|
508
508
|
ctx = await options.context(request);
|
|
509
509
|
} catch (error) {
|
|
510
|
-
if (
|
|
510
|
+
if (isJigsError(error)) throw error;
|
|
511
511
|
onError(error, { type: "chat" });
|
|
512
|
-
throw new
|
|
512
|
+
throw new JigsError("INTERNAL", INTERNAL_MESSAGE);
|
|
513
513
|
}
|
|
514
514
|
const input = parseBounded(() => chatInputSchema.safeParse({
|
|
515
515
|
blocks: chatOptions?.blocks,
|
|
516
516
|
prompt: chatOptions?.prompt
|
|
517
517
|
}));
|
|
518
|
-
if (!input.success) throw new
|
|
518
|
+
if (!input.success) throw new JigsError("BAD_INPUT", input.message);
|
|
519
519
|
let turnOptions;
|
|
520
520
|
if (options.options === void 0) turnOptions = void 0;
|
|
521
521
|
else {
|
|
522
522
|
const schema = options.options;
|
|
523
523
|
const parsed = parseBounded(() => schema.safeParse(chatOptions?.options ?? {}));
|
|
524
|
-
if (!parsed.success) throw new
|
|
524
|
+
if (!parsed.success) throw new JigsError("BAD_INPUT", `options: ${parsed.message}`);
|
|
525
525
|
turnOptions = parsed.data;
|
|
526
526
|
}
|
|
527
527
|
const turnCall = {
|
|
@@ -623,7 +623,7 @@ function createPickleServer(options) {
|
|
|
623
623
|
try {
|
|
624
624
|
return { ctx: await options.context(request) };
|
|
625
625
|
} catch (error) {
|
|
626
|
-
if (
|
|
626
|
+
if (isJigsError(error)) return { error: errorData(error) };
|
|
627
627
|
onError(error, { type });
|
|
628
628
|
return { error: {
|
|
629
629
|
code: "INTERNAL",
|
|
@@ -783,4 +783,4 @@ function createPickleServer(options) {
|
|
|
783
783
|
};
|
|
784
784
|
}
|
|
785
785
|
//#endregion
|
|
786
|
-
export {
|
|
786
|
+
export { createJigsServer, defineRun };
|
package/dist/session.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { errorData,
|
|
1
|
+
import { errorData, isJigsError } from "./errors.js";
|
|
2
2
|
import { belowPrefix, pragmaLine, splitPragma, versionDiagnostics, withPragma } from "./pragma.js";
|
|
3
3
|
import { reorderDeclarations } from "./rewrite.js";
|
|
4
4
|
import { addUsage } from "./usage.js";
|
|
@@ -313,7 +313,7 @@ async function* runSession(deps, messages, options, call) {
|
|
|
313
313
|
return;
|
|
314
314
|
}
|
|
315
315
|
} catch (error) {
|
|
316
|
-
if (
|
|
316
|
+
if (isJigsError(error)) yield {
|
|
317
317
|
error: errorData(error),
|
|
318
318
|
type: "error"
|
|
319
319
|
};
|
package/dist/types.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { ConfirmationStore } from "./confirm.js";
|
|
|
3
3
|
import { EditFailureReason } from "@jigs.design/compiler";
|
|
4
4
|
import { PromptMode } from "@jigs.design/prompt";
|
|
5
5
|
import { ActionDefinition, CallPolicy, Catalog, Host, InputOf, MutationDefinition, OutputOf, ProcedureDefinition, Procedures } from "@jigs.design/host";
|
|
6
|
-
import { ChatBlock, ChatBlockStatus, Diagnostic, Invalidation,
|
|
6
|
+
import { ChatBlock, ChatBlockStatus, Diagnostic, Invalidation, JigsErrorData, Message, Program, SessionEvent } from "@jigs.design/runtime";
|
|
7
7
|
import { z } from "zod";
|
|
8
8
|
//#region src/types.d.ts
|
|
9
9
|
/**
|
|
@@ -175,7 +175,7 @@ export interface CallReport<TContext> {
|
|
|
175
175
|
/** From the call's arrival to its outcome, in milliseconds. */
|
|
176
176
|
durationMs: number;
|
|
177
177
|
/** What the browser received, when `outcome` is not "success". */
|
|
178
|
-
error?:
|
|
178
|
+
error?: JigsErrorData;
|
|
179
179
|
/**
|
|
180
180
|
* The parsed input, or the input as the browser sent it when the call
|
|
181
181
|
* failed before its input parsed.
|
|
@@ -200,7 +200,7 @@ export interface ErrorInfo {
|
|
|
200
200
|
* `TContext` is inferred from `context`; `run` only reads it (`NoInfer`), so
|
|
201
201
|
* a mistake in one `run` function is reported at that function.
|
|
202
202
|
*/
|
|
203
|
-
export interface
|
|
203
|
+
export interface JigsServerOptions<TProcedures extends Procedures, TCatalog extends Catalog, TContext, TOptions, TSpecName extends string = never> {
|
|
204
204
|
/** Origins whose views may call this server and embed its frame. */
|
|
205
205
|
allowedOrigins?: ReadonlyArray<string>;
|
|
206
206
|
/**
|
|
@@ -286,7 +286,7 @@ export interface CompileOptions {
|
|
|
286
286
|
*/
|
|
287
287
|
placement?: Placement;
|
|
288
288
|
/**
|
|
289
|
-
* Throw a `
|
|
289
|
+
* Throw a `JigsCompileError` when the source has an error or warning
|
|
290
290
|
* diagnostic. Default true; pass false to get the program and the
|
|
291
291
|
* diagnostics instead, as a session turn does.
|
|
292
292
|
*/
|
|
@@ -300,7 +300,7 @@ export type CallOutcome = {
|
|
|
300
300
|
data: unknown;
|
|
301
301
|
invalidate?: ReadonlyArray<Invalidation>;
|
|
302
302
|
} | {
|
|
303
|
-
error:
|
|
303
|
+
error: JigsErrorData;
|
|
304
304
|
} | {
|
|
305
305
|
requiresAction: RequiresAction;
|
|
306
306
|
};
|
|
@@ -364,8 +364,8 @@ export interface ChatBlockResult {
|
|
|
364
364
|
* reply's limit (`RATE_LIMITED`), or an edit or repair that failed
|
|
365
365
|
* (`INTERNAL`). The same error the block carries.
|
|
366
366
|
*/
|
|
367
|
-
error?:
|
|
368
|
-
/** False for
|
|
367
|
+
error?: JigsErrorData;
|
|
368
|
+
/** False for Jigs the model wrote without a fence. */
|
|
369
369
|
fenced: boolean;
|
|
370
370
|
id: string;
|
|
371
371
|
key: string;
|
|
@@ -437,13 +437,13 @@ export interface ChatTurn {
|
|
|
437
437
|
/** The start of `system` that is the same on every turn, as on `ModelRequest`. */
|
|
438
438
|
systemPrefix: string;
|
|
439
439
|
}
|
|
440
|
-
export interface
|
|
440
|
+
export interface JigsServer<TContext, TSpecName extends string = never> {
|
|
441
441
|
call: (request: CallRequest, context: CallContext<TContext>) => Promise<CallOutcome>;
|
|
442
442
|
/**
|
|
443
443
|
* Starts a chat reply for `request`. It refuses the request as `handler`
|
|
444
444
|
* would (an `Origin` that may not call this server, or a body that is not
|
|
445
445
|
* JSON), then runs `context` and parses `blocks` and `options`. Each
|
|
446
|
-
* failure rejects with a `
|
|
446
|
+
* failure rejects with a `JigsError`. See `ChatTurn`.
|
|
447
447
|
*/
|
|
448
448
|
chat: (request: Request, options?: ChatOptions) => Promise<ChatTurn>;
|
|
449
449
|
/** Checks and compiles a source with no model. Strict unless told otherwise. */
|
|
@@ -461,7 +461,7 @@ export interface PickleServer<TContext, TSpecName extends string = never> {
|
|
|
461
461
|
/**
|
|
462
462
|
* The system prompt for this host. "document" (default) is what sessions
|
|
463
463
|
* use: every reply is one UI. "chat" is Markdown with UIs in fenced
|
|
464
|
-
* `
|
|
464
|
+
* `jigs` blocks.
|
|
465
465
|
*/
|
|
466
466
|
prompt: (mode?: PromptMode) => string;
|
|
467
467
|
/**
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jigs.design/server",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "createJigsServer: checks and streams programs, runs procedures, and serves the sandbox frame.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
|
-
"url": "git+https://github.com/yoamomonstruos/
|
|
8
|
+
"url": "git+https://github.com/yoamomonstruos/jigs.git",
|
|
9
9
|
"directory": "packages/server"
|
|
10
10
|
},
|
|
11
11
|
"type": "module",
|
|
@@ -29,10 +29,10 @@
|
|
|
29
29
|
"access": "public"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@jigs.design/
|
|
33
|
-
"@jigs.design/
|
|
34
|
-
"@jigs.design/
|
|
35
|
-
"@jigs.design/
|
|
32
|
+
"@jigs.design/host": "0.1.2",
|
|
33
|
+
"@jigs.design/prompt": "0.1.2",
|
|
34
|
+
"@jigs.design/compiler": "0.1.2",
|
|
35
|
+
"@jigs.design/runtime": "0.1.2"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"zod": "^4.0.0"
|