@jigs.design/server 0.3.0 → 0.3.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/dist/chat.js +6 -2
- package/dist/compile.js +20 -7
- package/dist/core.js +48 -10
- package/dist/inputs.js +16 -1
- package/dist/model-server.js +14 -3
- package/dist/tool-results.js +20 -0
- package/dist/types.d.ts +35 -7
- package/package.json +6 -6
package/dist/chat.js
CHANGED
|
@@ -218,6 +218,7 @@ function createReplyParser(deps, history) {
|
|
|
218
218
|
};
|
|
219
219
|
if (error !== void 0) block.error = error;
|
|
220
220
|
if (compiled.ref !== null) block.ref = compiled.ref;
|
|
221
|
+
if (compiled.toolKeys !== null && compiled.toolKeys !== void 0) block.toolKeys = compiled.toolKeys;
|
|
221
222
|
return block;
|
|
222
223
|
};
|
|
223
224
|
const emit = (block) => {
|
|
@@ -615,15 +616,18 @@ async function* repairBlock(deps, block) {
|
|
|
615
616
|
else if (event.type === "done") {
|
|
616
617
|
const body = splitPragma(event.source).body;
|
|
617
618
|
deps.parser.remember(block.name, body);
|
|
619
|
+
const { toolKeys: _before, ...rest } = block;
|
|
618
620
|
const repaired = {
|
|
619
|
-
...
|
|
621
|
+
...rest,
|
|
620
622
|
diagnostics: event.diagnostics,
|
|
621
623
|
program: program ?? block.program,
|
|
622
624
|
source: event.source,
|
|
623
625
|
status: "done"
|
|
624
626
|
};
|
|
625
|
-
const
|
|
627
|
+
const compiled = deps.session.checker.compile(body);
|
|
628
|
+
const { ref } = compiled;
|
|
626
629
|
if (ref !== null) repaired.ref = ref;
|
|
630
|
+
if (compiled.toolKeys !== null) repaired.toolKeys = compiled.toolKeys;
|
|
627
631
|
if (result !== void 0) {
|
|
628
632
|
result.status = "done";
|
|
629
633
|
if (ref !== null) result.ref = ref;
|
package/dist/compile.js
CHANGED
|
@@ -4,6 +4,7 @@ import { inputDiagnostics } from "./inputs.js";
|
|
|
4
4
|
import { outputDiagnostics } from "./outputs.js";
|
|
5
5
|
import { splitPragma, versionDiagnostics } from "./pragma.js";
|
|
6
6
|
import { compileJigs, compileLibrary, spanIn } from "@jigs.design/compiler";
|
|
7
|
+
import { TOOL_RESULTS } from "@jigs.design/prompt";
|
|
7
8
|
import { componentSchema } from "@jigs.design/host";
|
|
8
9
|
import { PROGRAM_FORMAT } from "@jigs.design/protocol";
|
|
9
10
|
//#region src/compile.ts
|
|
@@ -57,6 +58,17 @@ function compileCatalog(catalog) {
|
|
|
57
58
|
return out;
|
|
58
59
|
}
|
|
59
60
|
const TAG = /<([a-z][A-Za-z0-9]*)/g;
|
|
61
|
+
/** Each procedure kind as a diagnostic names it. */
|
|
62
|
+
const KIND_NAMES = {
|
|
63
|
+
action: "an action",
|
|
64
|
+
data: "provided data",
|
|
65
|
+
mutation: "a mutation",
|
|
66
|
+
query: "a query"
|
|
67
|
+
};
|
|
68
|
+
/** The hook that reads or calls a procedure of `kind`: a provided slot is read like a query. */
|
|
69
|
+
function hookFor(kind) {
|
|
70
|
+
return kind === "query" || kind === "data" ? "useQuery" : "useMutation";
|
|
71
|
+
}
|
|
60
72
|
function procedureDiagnostics(host, source, uses) {
|
|
61
73
|
const diagnostics = [];
|
|
62
74
|
const report = (use, code, message) => {
|
|
@@ -83,11 +95,11 @@ function procedureDiagnostics(host, source, uses) {
|
|
|
83
95
|
}
|
|
84
96
|
const procedure = Object.hasOwn(host.procedures, use.name) ? host.procedures[use.name] : void 0;
|
|
85
97
|
if (procedure === void 0) {
|
|
86
|
-
report(use, "unknown_procedure", `"${use.name}" is not a query, mutation or
|
|
98
|
+
report(use, "unknown_procedure", `"${use.name}" is not a query, mutation, action or provided data on this host; its handle reports UNKNOWN_PROCEDURE`);
|
|
87
99
|
continue;
|
|
88
100
|
}
|
|
89
|
-
const expected = procedure.kind
|
|
90
|
-
if (expected !== use.hook) report(use, "procedure_kind", `\`${use.hook}("${use.name}")\` names ${procedure.kind
|
|
101
|
+
const expected = hookFor(procedure.kind);
|
|
102
|
+
if (expected !== use.hook) report(use, "procedure_kind", `\`${use.hook}("${use.name}")\` names ${KIND_NAMES[procedure.kind]}. Write \`${expected}("${use.name}")\`${expected === "useQuery" ? "" : " and call `mutate` from a handler"}`);
|
|
91
103
|
}
|
|
92
104
|
return diagnostics;
|
|
93
105
|
}
|
|
@@ -96,8 +108,7 @@ function procedureTable(host, uses) {
|
|
|
96
108
|
for (const use of uses) {
|
|
97
109
|
if (use.name === null || use.tanstack) continue;
|
|
98
110
|
const procedure = Object.hasOwn(host.procedures, use.name) ? host.procedures[use.name] : void 0;
|
|
99
|
-
|
|
100
|
-
if (procedure === void 0 || expected !== use.hook) continue;
|
|
111
|
+
if (procedure === void 0 || hookFor(procedure.kind) !== use.hook) continue;
|
|
101
112
|
table.set(use.name, {
|
|
102
113
|
invalidates: procedure.kind === "mutation" ? procedure.invalidates : [],
|
|
103
114
|
kind: procedure.kind
|
|
@@ -260,6 +271,7 @@ function createChecker(host) {
|
|
|
260
271
|
let ref = diagnostics.some((diagnostic) => diagnostic.severity === "error") ? null : refOf(result.program.tree, pages);
|
|
261
272
|
const define = ref === null ? void 0 : fullLibrary.get(ref.name);
|
|
262
273
|
if (ref !== null && (define === void 0 || pagePropsProblem(define, ref.props) !== null)) ref = null;
|
|
274
|
+
const procedures = procedureTable(host, [...own, ...reached.uses]);
|
|
263
275
|
return {
|
|
264
276
|
advise: (placement) => designChecks({
|
|
265
277
|
catalog: host.components,
|
|
@@ -272,10 +284,11 @@ function createChecker(host) {
|
|
|
272
284
|
components: Object.fromEntries(host.components.components.filter((component) => reached.tags.has(component.name)).map((component) => [component.name, componentSchema(component)])),
|
|
273
285
|
format: PROGRAM_FORMAT,
|
|
274
286
|
imageHosts: host.imageHosts,
|
|
275
|
-
procedures
|
|
287
|
+
procedures,
|
|
276
288
|
prose: result.output.constants
|
|
277
289
|
},
|
|
278
|
-
ref
|
|
290
|
+
ref,
|
|
291
|
+
toolKeys: !Object.hasOwn(procedures, TOOL_RESULTS) ? null : reached.uses.some((use) => use.name === TOOL_RESULTS) ? "all" : result.fields[TOOL_RESULTS] ?? []
|
|
279
292
|
};
|
|
280
293
|
};
|
|
281
294
|
const compile = (body) => compileWith(body, tagLibrary, tagFacts);
|
package/dist/core.js
CHANGED
|
@@ -7,6 +7,7 @@ import { confirmMessage, createConfirmer, memoryConfirmations } from "./confirm.
|
|
|
7
7
|
import { processCompileCache, sha256 } from "./compile-cache.js";
|
|
8
8
|
import { eventStream } from "./events.js";
|
|
9
9
|
import { invalidationsOf } from "./invalidation.js";
|
|
10
|
+
import { withToolResults } from "./tool-results.js";
|
|
10
11
|
import { createModelServer } from "./model-server.js";
|
|
11
12
|
import { systemPromptParts } from "@jigs.design/prompt";
|
|
12
13
|
import { isCallPolicy } from "@jigs.design/host";
|
|
@@ -36,6 +37,10 @@ function strictly(subject, compiled) {
|
|
|
36
37
|
function noProps(name, props) {
|
|
37
38
|
if (Object.keys(props).length > 0) throw new JigsError("BAD_INPUT", `"${name}" is a document page, which takes no props`);
|
|
38
39
|
}
|
|
40
|
+
/** An `AbortError`, as `fetch` and other APIs reject with on an aborted signal. */
|
|
41
|
+
function isAbortError(cause) {
|
|
42
|
+
return cause instanceof Error && cause.name === "AbortError";
|
|
43
|
+
}
|
|
39
44
|
/** A call a policy refused. The procedure stays in the prompt. */
|
|
40
45
|
const denial = (name) => ({ error: {
|
|
41
46
|
code: "FORBIDDEN",
|
|
@@ -91,7 +96,7 @@ function hostFingerprint(host) {
|
|
|
91
96
|
kind: procedure.kind,
|
|
92
97
|
name,
|
|
93
98
|
output: procedure.output === void 0 ? null : z.toJSONSchema(procedure.output),
|
|
94
|
-
projection: procedure.kind === "action" || procedure.projection === void 0 ? null : z.toJSONSchema(procedure.projection.schema)
|
|
99
|
+
projection: procedure.kind === "action" || procedure.kind === "data" || procedure.projection === void 0 ? null : z.toJSONSchema(procedure.projection.schema)
|
|
95
100
|
})),
|
|
96
101
|
jigs: host.jigs.map((entry) => [
|
|
97
102
|
entry.name,
|
|
@@ -111,17 +116,26 @@ function defineRun(procedures, handlers) {
|
|
|
111
116
|
return handlers;
|
|
112
117
|
}
|
|
113
118
|
function createJigsServer(options) {
|
|
114
|
-
const
|
|
119
|
+
const tools = options.toolResults === true;
|
|
120
|
+
const host = tools ? withToolResults(options.host) : options.host;
|
|
115
121
|
checkMarkdownElements(host.components);
|
|
116
|
-
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}"`);
|
|
122
|
+
for (const [name, procedure] of Object.entries(host.procedures)) if (procedure.kind !== "action" && procedure.kind !== "data" && !Object.hasOwn(options.run, name)) throw new Error(`createJigsServer has no run function for "${name}"`);
|
|
117
123
|
const confirmer = confirmerFor(options);
|
|
118
124
|
const checker = createChecker(host);
|
|
119
|
-
const promptOptions = (mode) => options.instructions === void 0 ? {
|
|
125
|
+
const promptOptions = (mode) => options.instructions === void 0 ? {
|
|
126
|
+
mode,
|
|
127
|
+
toolResults: tools
|
|
128
|
+
} : {
|
|
120
129
|
instructions: options.instructions,
|
|
121
|
-
mode
|
|
130
|
+
mode,
|
|
131
|
+
toolResults: tools
|
|
122
132
|
};
|
|
123
|
-
const documentParts = systemPromptParts(host,
|
|
133
|
+
const documentParts = systemPromptParts(options.host, {
|
|
134
|
+
...promptOptions("document"),
|
|
135
|
+
toolResults: false
|
|
136
|
+
});
|
|
124
137
|
const chatParts = systemPromptParts(host, promptOptions("chat"));
|
|
138
|
+
const toolParts = tools ? systemPromptParts(host, promptOptions("document")) : null;
|
|
125
139
|
const system = `${documentParts.stable}\n\n${documentParts.variable}`;
|
|
126
140
|
const chatSystem = `${chatParts.stable}\n\n${chatParts.variable}`;
|
|
127
141
|
const allowedOrigins = new Set((options.allowedOrigins ?? []).map((entry) => originOf(entry)));
|
|
@@ -220,7 +234,11 @@ function createJigsServer(options) {
|
|
|
220
234
|
};
|
|
221
235
|
const dispatch = async (request, context, trace) => {
|
|
222
236
|
const procedure = Object.hasOwn(host.procedures, request.name) ? host.procedures[request.name] : void 0;
|
|
223
|
-
const run = procedure?.kind !== "action" && Object.hasOwn(runs, request.name) ? runs[request.name] : void 0;
|
|
237
|
+
const run = procedure?.kind !== "action" && procedure?.kind !== "data" && Object.hasOwn(runs, request.name) ? runs[request.name] : void 0;
|
|
238
|
+
if (procedure?.kind === "data") return { error: {
|
|
239
|
+
code: "BAD_INPUT",
|
|
240
|
+
message: `"${request.name}" is provided data: it is supplied by the page, not fetched`
|
|
241
|
+
} };
|
|
224
242
|
if (procedure === void 0 || procedure.kind !== "action" && run === void 0) return { error: {
|
|
225
243
|
code: "UNKNOWN_PROCEDURE",
|
|
226
244
|
message: `"${request.name}" is not a query, mutation or action on this host`
|
|
@@ -256,6 +274,10 @@ function createJigsServer(options) {
|
|
|
256
274
|
try {
|
|
257
275
|
result = await run(input, context);
|
|
258
276
|
} catch (error) {
|
|
277
|
+
if (context.signal.aborted || isAbortError(error)) {
|
|
278
|
+
trace.aborted = true;
|
|
279
|
+
return { error: errorData(null) };
|
|
280
|
+
}
|
|
259
281
|
if (isJigsError(error)) return { error: errorData(error) };
|
|
260
282
|
onError(error, {
|
|
261
283
|
name: request.name,
|
|
@@ -327,6 +349,7 @@ function createJigsServer(options) {
|
|
|
327
349
|
const call = async (request, context) => {
|
|
328
350
|
const started = performance.now();
|
|
329
351
|
const trace = {
|
|
352
|
+
aborted: false,
|
|
330
353
|
gate: null,
|
|
331
354
|
input: request.input
|
|
332
355
|
};
|
|
@@ -339,7 +362,8 @@ function createJigsServer(options) {
|
|
|
339
362
|
name: request.name,
|
|
340
363
|
outcome: trace.gate ?? "success"
|
|
341
364
|
};
|
|
342
|
-
if (
|
|
365
|
+
if (trace.aborted) report.outcome = "aborted";
|
|
366
|
+
else if ("error" in outcome) {
|
|
343
367
|
report.error = outcome.error;
|
|
344
368
|
report.outcome = trace.gate === "denied" ? "denied" : "error";
|
|
345
369
|
}
|
|
@@ -351,11 +375,13 @@ function createJigsServer(options) {
|
|
|
351
375
|
const stored = splitPragma(source);
|
|
352
376
|
const compiled = checker.compile(stored.body);
|
|
353
377
|
const prefix = source.slice(0, source.length - stored.body.length);
|
|
354
|
-
|
|
378
|
+
const result = {
|
|
355
379
|
advice: belowPrefix(compiled.advise(placement), prefix),
|
|
356
380
|
diagnostics: [...versionDiagnostics(stored.versions, host.components.version), ...belowPrefix(compiled.diagnostics, prefix)],
|
|
357
381
|
program: compiled.program
|
|
358
382
|
};
|
|
383
|
+
if (compiled.toolKeys !== null) result.toolKeys = compiled.toolKeys;
|
|
384
|
+
return result;
|
|
359
385
|
};
|
|
360
386
|
/**
|
|
361
387
|
* `compile` through the process's cache, keyed by what this server
|
|
@@ -671,9 +697,17 @@ function createJigsServer(options) {
|
|
|
671
697
|
onError,
|
|
672
698
|
page: pageRequest
|
|
673
699
|
};
|
|
700
|
+
const data = (name, value) => {
|
|
701
|
+
const slot = Object.hasOwn(host.procedures, name) ? host.procedures[name] : void 0;
|
|
702
|
+
if (slot?.kind !== "data") throw new JigsError("BAD_INPUT", `"${name}" is not provided data on this host`);
|
|
703
|
+
const parsed = slot.output.safeParse(value);
|
|
704
|
+
if (!parsed.success) throw new JigsError("BAD_INPUT", `"${name}": ${issuesText(parsed.error)}`);
|
|
705
|
+
return parsed.data;
|
|
706
|
+
};
|
|
674
707
|
const core = {
|
|
675
708
|
call,
|
|
676
709
|
compile,
|
|
710
|
+
data,
|
|
677
711
|
events,
|
|
678
712
|
frame,
|
|
679
713
|
handler: createHandler({
|
|
@@ -691,7 +725,11 @@ function createJigsServer(options) {
|
|
|
691
725
|
handlerDeps,
|
|
692
726
|
host,
|
|
693
727
|
onError,
|
|
694
|
-
prepareSession
|
|
728
|
+
prepareSession,
|
|
729
|
+
toolPrompt: toolParts === null ? null : {
|
|
730
|
+
system: `${toolParts.stable}\n\n${toolParts.variable}`,
|
|
731
|
+
systemPrefix: toolParts.stable
|
|
732
|
+
}
|
|
695
733
|
}, core, modelOptions)
|
|
696
734
|
};
|
|
697
735
|
return core;
|
package/dist/inputs.js
CHANGED
|
@@ -3,6 +3,11 @@ import { z } from "zod";
|
|
|
3
3
|
//#region src/inputs.ts
|
|
4
4
|
/** A handle declared as `const name = useMutation("procedure")`. */
|
|
5
5
|
const MUTATION_HANDLE = /(?<![\w$.])(?:const|let|var)\s+([A-Za-z_$][\w$]*)\s*=\s*useMutation\(\s*(["'`])([A-Za-z_$][\w$]*)\2\s*\)/g;
|
|
6
|
+
/**
|
|
7
|
+
* What may follow a provided slot's name in `useQuery`: the call's end, or
|
|
8
|
+
* an empty input (`undefined` or `null`) before or without options.
|
|
9
|
+
*/
|
|
10
|
+
const NO_INPUT = /^(?:,\s*)?\)|^,\s*(?:undefined|null)(?![\w$])/;
|
|
6
11
|
const QUERY_CALL = /(?<![\w$.])useQuery\(\s*(["'`])([A-Za-z_$][\w$]*)\1\s*/g;
|
|
7
12
|
/** At most this many problems per call, so one bad literal does not flood the repair. */
|
|
8
13
|
const MAX_PROBLEMS = 3;
|
|
@@ -192,8 +197,18 @@ function inputDiagnostics(host, source) {
|
|
|
192
197
|
for (const match of source.matchAll(QUERY_CALL)) {
|
|
193
198
|
const name = match[2] ?? "";
|
|
194
199
|
const procedure = procedureOf(name);
|
|
195
|
-
if (procedure?.kind !== "query" || procedure.input === void 0) continue;
|
|
196
200
|
const rest = match.index + match[0].length;
|
|
201
|
+
if (procedure?.kind === "data") {
|
|
202
|
+
if (NO_INPUT.test(source.slice(rest))) continue;
|
|
203
|
+
diagnostics.push({
|
|
204
|
+
code: "data_takes_no_input",
|
|
205
|
+
message: `useQuery("${name}") reads provided data, which takes no input. Drop the input; the app provides this data`,
|
|
206
|
+
severity: "error",
|
|
207
|
+
span: { line: lineAt(source, match.index) }
|
|
208
|
+
});
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
if (procedure?.kind !== "query" || procedure.input === void 0) continue;
|
|
197
212
|
const char = source.charAt(rest);
|
|
198
213
|
if (char !== "," && char !== ")") continue;
|
|
199
214
|
const [input] = char === ")" ? [] : readArguments(source, rest + 1);
|
package/dist/model-server.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { INTERNAL_MESSAGE, JigsError, isJigsError } from "./errors.js";
|
|
2
|
+
import { splitPragma } from "./pragma.js";
|
|
2
3
|
import { createHandler, issuesText, parseBounded } from "./handler.js";
|
|
3
4
|
import { MAX_CONTENT, runSession } from "./session.js";
|
|
4
5
|
import { createReplyParser, repairBlock, streamChat } from "./chat.js";
|
|
6
|
+
import { TOOL_RESULTS } from "@jigs.design/prompt";
|
|
5
7
|
import { z } from "zod";
|
|
6
8
|
//#region src/model-server.ts
|
|
7
9
|
/**
|
|
@@ -54,6 +56,14 @@ function createModelServer(internals, core, options) {
|
|
|
54
56
|
system,
|
|
55
57
|
systemPrefix: core.promptPrefix("document")
|
|
56
58
|
};
|
|
59
|
+
const toolPrompt = internals.toolPrompt;
|
|
60
|
+
const toolSessionDeps = toolPrompt === null ? sessionDeps : {
|
|
61
|
+
...sessionDeps,
|
|
62
|
+
system: toolPrompt.system,
|
|
63
|
+
systemPrefix: toolPrompt.systemPrefix
|
|
64
|
+
};
|
|
65
|
+
/** A session's deps: the slot's prompt when its document reads `toolResults`. */
|
|
66
|
+
const depsFor = (turn) => toolPrompt !== null && turn.document !== null && Object.hasOwn(internals.checker.compile(splitPragma(turn.document).body).program.procedures, TOOL_RESULTS) ? toolSessionDeps : sessionDeps;
|
|
57
67
|
const chat = async (request, chatOptions) => {
|
|
58
68
|
const refused = internals.handlerDeps.http.refusal(request);
|
|
59
69
|
if (refused !== null) throw new JigsError(refused.code, refused.message);
|
|
@@ -98,7 +108,7 @@ function createModelServer(internals, core, options) {
|
|
|
98
108
|
parser,
|
|
99
109
|
prompt: input.data.prompt,
|
|
100
110
|
session: {
|
|
101
|
-
...
|
|
111
|
+
...toolSessionDeps,
|
|
102
112
|
kind: "chat-repair",
|
|
103
113
|
maxRepairs: repairRounds
|
|
104
114
|
}
|
|
@@ -122,6 +132,7 @@ function createModelServer(internals, core, options) {
|
|
|
122
132
|
call: core.call,
|
|
123
133
|
chat,
|
|
124
134
|
compile: core.compile,
|
|
135
|
+
data: core.data,
|
|
125
136
|
events: core.events,
|
|
126
137
|
frame: core.frame,
|
|
127
138
|
handler: createHandler({
|
|
@@ -129,7 +140,7 @@ function createModelServer(internals, core, options) {
|
|
|
129
140
|
session: async (body, call) => {
|
|
130
141
|
const prepared = await prepareSession(body, call);
|
|
131
142
|
if ("error" in prepared) return prepared;
|
|
132
|
-
return { turn: (turnCall) => runSession(
|
|
143
|
+
return { turn: (turnCall) => runSession(depsFor(prepared.turn), prepared.turn, prepared.options, turnCall) };
|
|
133
144
|
}
|
|
134
145
|
}),
|
|
135
146
|
maxBodyBytes: core.maxBodyBytes,
|
|
@@ -145,7 +156,7 @@ function createModelServer(internals, core, options) {
|
|
|
145
156
|
};
|
|
146
157
|
return;
|
|
147
158
|
}
|
|
148
|
-
yield* runSession(
|
|
159
|
+
yield* runSession(depsFor(prepared.turn), prepared.turn, prepared.options, context);
|
|
149
160
|
},
|
|
150
161
|
version: core.version
|
|
151
162
|
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { TOOL_RESULTS, toolResultsSlot } from "@jigs.design/prompt";
|
|
2
|
+
//#region src/tool-results.ts
|
|
3
|
+
/**
|
|
4
|
+
* `host` with the `toolResults` slot added, for a server with
|
|
5
|
+
* `toolResults: true`: the checker, the calls and the prompts that list it
|
|
6
|
+
* see one more provided slot. Throws when the host already has a procedure
|
|
7
|
+
* of that name.
|
|
8
|
+
*/
|
|
9
|
+
function withToolResults(host) {
|
|
10
|
+
if (Object.hasOwn(host.procedures, TOOL_RESULTS)) throw new Error(`The host has a procedure named "${TOOL_RESULTS}", which toolResults: true adds; rename it`);
|
|
11
|
+
return {
|
|
12
|
+
...host,
|
|
13
|
+
procedures: {
|
|
14
|
+
...host.procedures,
|
|
15
|
+
[TOOL_RESULTS]: toolResultsSlot
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
//#endregion
|
|
20
|
+
export { withToolResults };
|
package/dist/types.d.ts
CHANGED
|
@@ -2,8 +2,8 @@ import { Advice, DesignCheckCode, Placement } from "./design.js";
|
|
|
2
2
|
import { ConfirmationStore } from "./confirm.js";
|
|
3
3
|
import { EditFailureReason } from "@jigs.design/compiler";
|
|
4
4
|
import { PromptMode } from "@jigs.design/prompt";
|
|
5
|
-
import { ActionDefinition, CallPolicy, Catalog, Host, InputOf, JigDefinition, MutationDefinition, OutputOf, PageName, ProcedureDefinition, Procedures, QueryDefinition } from "@jigs.design/host";
|
|
6
|
-
import { ChatBlock, ChatBlockStatus, Diagnostic, Invalidation, JigsErrorData, Message, PageInvalidation, PageProps, PageRef, Program, SessionEvent } from "@jigs.design/protocol";
|
|
5
|
+
import { ActionDefinition, CallPolicy, Catalog, DataDefinition, Host, InputOf, JigDefinition, MutationDefinition, OutputOf, PageName, ProcedureDefinition, Procedures, QueryDefinition } from "@jigs.design/host";
|
|
6
|
+
import { ChatBlock, ChatBlockStatus, Diagnostic, Invalidation, JigsErrorData, JsonValue, Message, PageInvalidation, PageProps, PageRef, Program, SessionEvent } from "@jigs.design/protocol";
|
|
7
7
|
import { z } from "zod";
|
|
8
8
|
//#region src/types.d.ts
|
|
9
9
|
/**
|
|
@@ -159,9 +159,10 @@ type DeepReadonly<T> = T extends object ? { readonly [K in keyof T]: DeepReadonl
|
|
|
159
159
|
type RunOutput<P extends ProcedureDefinition> = DeepReadonly<OutputOf<P>>;
|
|
160
160
|
/**
|
|
161
161
|
* One function per query and mutation. Actions have none: the page handles
|
|
162
|
-
* them, and the server only checks their input.
|
|
162
|
+
* them, and the server only checks their input. Provided data has none
|
|
163
|
+
* either: the page supplies it.
|
|
163
164
|
*/
|
|
164
|
-
export type RunFunctions<TProcedures extends Procedures, TContext> = { readonly [K in keyof TProcedures as TProcedures[K] extends ActionDefinition ? never : K]: (input: InputOf<TProcedures[K]>, call: CallContext<TContext>) => RunOutput<TProcedures[K]> | Promise<RunOutput<TProcedures[K]>>; };
|
|
165
|
+
export type RunFunctions<TProcedures extends Procedures, TContext> = { readonly [K in keyof TProcedures as TProcedures[K] extends ActionDefinition | DataDefinition ? never : K]: (input: InputOf<TProcedures[K]>, call: CallContext<TContext>) => RunOutput<TProcedures[K]> | Promise<RunOutput<TProcedures[K]>>; };
|
|
165
166
|
export type ContextFunction<TContext> = (request: Request) => TContext | Promise<TContext>;
|
|
166
167
|
/** The names of a host's mutations. */
|
|
167
168
|
type MutationName<TProcedures extends Procedures> = { [K in keyof TProcedures & string]: TProcedures[K] extends MutationDefinition ? K : never; }[keyof TProcedures & string];
|
|
@@ -180,7 +181,7 @@ export type PolicyCall<TProcedures extends Procedures, TContext> = { [K in Mutat
|
|
|
180
181
|
* as "requires-action" when the server asks the page, and once as
|
|
181
182
|
* "confirmed" when it ran with the user's approval.
|
|
182
183
|
*/
|
|
183
|
-
export type CallReportOutcome = "confirmed" | "denied" | "error" | "requires-action" | "success";
|
|
184
|
+
export type CallReportOutcome = "aborted" | "confirmed" | "denied" | "error" | "requires-action" | "success";
|
|
184
185
|
/**
|
|
185
186
|
* One call to a query, mutation or action, or one page request, as
|
|
186
187
|
* `onCall` receives it.
|
|
@@ -189,7 +190,7 @@ export interface CallReport<TContext> {
|
|
|
189
190
|
ctx: TContext;
|
|
190
191
|
/** From the call's arrival to its outcome, in milliseconds. */
|
|
191
192
|
durationMs: number;
|
|
192
|
-
/** What the browser received, when `outcome` is
|
|
193
|
+
/** What the browser received, when `outcome` is "denied" or "error". */
|
|
193
194
|
error?: JigsErrorData;
|
|
194
195
|
/**
|
|
195
196
|
* The parsed input, or the input as the browser sent it when the call
|
|
@@ -205,7 +206,9 @@ export interface CallReport<TContext> {
|
|
|
205
206
|
/**
|
|
206
207
|
* "denied" when a policy or a bad confirmation refused the call, or
|
|
207
208
|
* `pagePolicy` a page; "error" for any other failure, including one
|
|
208
|
-
* `run` threw and a page no list has
|
|
209
|
+
* `run` threw and a page no list has; "aborted" when `run` rejected
|
|
210
|
+
* after the browser abandoned the call (its `signal` aborted), which
|
|
211
|
+
* does not reach `onError`.
|
|
209
212
|
*/
|
|
210
213
|
outcome: CallReportOutcome;
|
|
211
214
|
}
|
|
@@ -388,6 +391,18 @@ export interface JigsServerOptions<TProcedures extends Procedures, TCatalog exte
|
|
|
388
391
|
* "confirm": the server refuses to start without it.
|
|
389
392
|
*/
|
|
390
393
|
secret?: string;
|
|
394
|
+
/**
|
|
395
|
+
* Adds a provided slot, `toolResults`, for a chat whose agent calls
|
|
396
|
+
* tools: the page passes each block the results of the tools called
|
|
397
|
+
* before it, by tool name (`toolData` in `@jigs.design/ai-sdk/client`),
|
|
398
|
+
* and the block reads them with `useQuery("toolResults")` instead of the
|
|
399
|
+
* model copying them into its source. The chat prompt lists the slot and
|
|
400
|
+
* says how to read it, as do chat repairs and a session on a block's
|
|
401
|
+
* source; a plain session's prompt is unchanged. Fixed for the server's
|
|
402
|
+
* life, so the prompt's cached start never changes per turn. A host
|
|
403
|
+
* procedure of that name throws. Default false.
|
|
404
|
+
*/
|
|
405
|
+
toolResults?: boolean;
|
|
391
406
|
}
|
|
392
407
|
/**
|
|
393
408
|
* What `withModel` takes: everything that exists only because a model does.
|
|
@@ -641,7 +656,20 @@ export interface JigsServer<TContext, TPageName extends string = never> {
|
|
|
641
656
|
advice: ReadonlyArray<Advice>;
|
|
642
657
|
diagnostics: ReadonlyArray<Diagnostic>;
|
|
643
658
|
program: Program;
|
|
659
|
+
/**
|
|
660
|
+
* With `toolResults: true`, for a source that reads the slot: the tool
|
|
661
|
+
* names it reads, or `"all"` (`ChatBlock.toolKeys`).
|
|
662
|
+
*/
|
|
663
|
+
toolKeys?: ReadonlyArray<string> | "all";
|
|
644
664
|
}>;
|
|
665
|
+
/**
|
|
666
|
+
* `value` parsed with the schema of provided slot `name`, for a page
|
|
667
|
+
* that wants it checked before it passes it to `JigsView` as `data`.
|
|
668
|
+
* Throws `JigsError("BAD_INPUT")` when it does not match, or when `name`
|
|
669
|
+
* is not provided data on this host. The view does not check it: a value
|
|
670
|
+
* that does not match renders as the program reads it.
|
|
671
|
+
*/
|
|
672
|
+
data: (name: string, value: JsonValue) => JsonValue;
|
|
645
673
|
/**
|
|
646
674
|
* The push stream for `request`, whose `ctx` the caller already has: a
|
|
647
675
|
* foreign `Origin` is `403`, a server without `events` answers `204`, and
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jigs.design/server",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "createJigsServer: checks and streams programs, runs procedures, and serves the sandbox frame.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -29,11 +29,11 @@
|
|
|
29
29
|
"access": "public"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@jigs.design/compiler": "0.3.
|
|
33
|
-
"@jigs.design/prompt": "0.3.
|
|
34
|
-
"@jigs.design/
|
|
35
|
-
"@jigs.design/
|
|
36
|
-
"@jigs.design/
|
|
32
|
+
"@jigs.design/compiler": "0.3.2",
|
|
33
|
+
"@jigs.design/prompt": "0.3.2",
|
|
34
|
+
"@jigs.design/host": "0.3.2",
|
|
35
|
+
"@jigs.design/protocol": "0.3.2",
|
|
36
|
+
"@jigs.design/runtime": "0.3.2"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"zod": "^4.0.0"
|