llmz 1.0.1 → 1.0.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/DOCS.md +8 -4
- package/ERRORS.md +5 -2
- package/dist/{component-BpMVZYOa.cjs → component-CMFoCHyu.cjs} +3 -3
- package/dist/{component-C27qu6Zv.js → component-DncqP4fB.js} +3 -3
- package/dist/context.d.ts +1 -1
- package/dist/{custom-client-BDkgBR2w.js → custom-client-C-WXvLD9.js} +37 -13
- package/dist/{custom-client-MytucGI-.cjs → custom-client-Cgt9_0r1.cjs} +37 -13
- package/dist/errors/catalog.d.ts +7 -0
- package/dist/{errors-IhnTKUp7.cjs → errors-C6ppQUZX.cjs} +22 -0
- package/dist/{errors-H4JJFH3S.js → errors-Crk5P8jo.js} +17 -1
- package/dist/errors.d.ts +6 -0
- package/dist/{execute-BYI_U5sR.js → execute-CiYvPs5Q.js} +196 -78
- package/dist/{execute-DLas4V2n.cjs → execute-DTTfacsi.cjs} +196 -78
- package/dist/{exit-BUgJ5qi5.cjs → exit-BOtKWPuT.cjs} +2 -2
- package/dist/{exit-CPNk3vbz.js → exit-DMPwCSba.js} +2 -2
- package/dist/index.cjs +18 -17
- package/dist/index.d.ts +1 -1
- package/dist/index.js +18 -18
- package/dist/index.workerd.js +252 -79
- package/dist/inspection.d.ts +2 -0
- package/dist/{native-Bm6L9zOb.cjs → native-0bq5ATZM.cjs} +3 -3
- package/dist/{native-DvTH9vFe.js → native-n_718Z-T.js} +3 -3
- package/dist/{quickjs-variant-DJwYDSsb.cjs → quickjs-variant-21IO97PF.cjs} +15 -8
- package/dist/{quickjs-variant-DlPi9-Sx.js → quickjs-variant-CtuGagsb.js} +10 -9
- package/dist/runtime/chat-completion.test.d.ts +1 -0
- package/dist/runtime/chat-last-speaker.test.d.ts +1 -0
- package/dist/runtime/empty-completion.test.d.ts +1 -0
- package/dist/runtime/execution-report.d.ts +3 -0
- package/dist/runtime/forced-inspection.d.ts +13 -0
- package/dist/runtime/forced-inspection.test.d.ts +1 -0
- package/dist/runtime/javascript-api.d.ts +3 -0
- package/dist/runtime/think-signal.test.d.ts +1 -0
- package/dist/runtime/tool-wrapper.d.ts +4 -2
- package/dist/runtime/types.d.ts +8 -0
- package/dist/{schema-DBkjo0b7.cjs → schema-CXlnbb3n.cjs} +1 -1
- package/dist/{schema-Aer_W7Al.js → schema-GE4ISPCR.js} +1 -1
- package/dist/session/messages.d.ts +2 -0
- package/dist/session/serialization.d.ts +2 -0
- package/dist/session/session.d.ts +4 -0
- package/dist/session/speaker.test.d.ts +1 -0
- package/dist/{tool--gK91eez.js → tool-DstssiAs.js} +4 -4
- package/dist/{tool-Da_F-N-5.cjs → tool-_wK9hQOb.cjs} +4 -4
- package/dist/{truncate-BSoH2-nY.js → truncate-BEKbdo3t.js} +1 -1
- package/dist/{truncate-nV3Mxr6-.cjs → truncate-uomAMGPs.cjs} +1 -1
- package/dist/types.d.ts +6 -0
- package/dist/{typings-C1ihexWE.cjs → typings-BA_XxAcY.cjs} +1 -1
- package/dist/{typings-D9_aC8aq.js → typings-BEVDvtuk.js} +1 -1
- package/dist/vm/types.d.ts +2 -0
- package/dist/{vm-8jxt8PTK.js → vm-C7SfutHn.js} +28 -3
- package/dist/{vm-XuVPuW3Y.cjs → vm-gmekHc0i.cjs} +28 -2
- package/package.json +1 -1
package/DOCS.md
CHANGED
|
@@ -138,10 +138,12 @@ console.log(restored.status) // pending
|
|
|
138
138
|
|
|
139
139
|
Restoration checks format versions, chronology, identities, call/result pairing, exact result encodings, and memory capacity. Unknown versions are rejected. Conversation/provider fields must be acyclic JSON data; encode binary values explicitly. This is conversation and memory persistence, not a paused JavaScript stack.
|
|
140
140
|
|
|
141
|
-
After a failed execution, the session retains the active input batch and any completed effects/results. Executing it again continues that turn. Newly appended messages remain queued. Applications should inspect failures before retrying operations that produce external effects.
|
|
141
|
+
After a failed execution, the session retains the active input batch and any completed effects/results. Executing it again continues that turn. Newly appended messages remain queued. A successful retry can therefore leave `session.status === "pending"`; call `execute()` again to process that next batch. Its user messages reset the chat response guard when the next turn starts. Applications should inspect failures before retrying operations that produce external effects.
|
|
142
142
|
|
|
143
143
|
`result.toJSON()` is a compact outcome summary. `result.diagnostics()` exports run diagnostics. Neither replaces `session.toJSON()`.
|
|
144
144
|
|
|
145
|
+
Chat requires the assistant to be the last participant who spoke before `exit("listen")` can complete. Successfully delivered text and components count across iterations, executions, and saved sessions. A new user message requires a new response; events, tool results, failed deliveries, and whitespace-only content do not change the last speaker. An empty or whitespace-only model response with `stopReason: "stop"` and no tool calls follows the same listen flow and guard. Silent completion raises a recoverable `MissingChatResponseError` before `onExit`, preserving tool results for the next attempt. Set `options: { requireChatResponse: false }` for intentionally silent handling. Custom task exits and worker mode are unaffected. Older session snapshots without delivery tracking restore with an unknown last speaker and require a response by default.
|
|
146
|
+
|
|
145
147
|
## Tools and exits
|
|
146
148
|
|
|
147
149
|
A `Tool` has a name, async handler, optional description, input/output schemas, aliases, metadata, and retry callback. Its original input schema validates and normalizes arguments before the handler runs. Its output schema describes likely returned data for TypeScript and the model: results are never validated, normalized, stripped, or rejected against that schema. Dynamic tools, objects, exits, instructions, and model configuration can be supplied as getters evaluated for each iteration.
|
|
@@ -177,7 +179,9 @@ Model-facing schemas describe accepted input shapes, not arbitrary JavaScript be
|
|
|
177
179
|
|
|
178
180
|
Use `result.is(done)` to narrow the result and its output type. `result.isError()` exposes an execution failure. Without custom exits, workers receive `DefaultExit`. An explicit empty `exits` array supplies no completion exits. Chat adds `ListenExit`; an accepted plain assistant answer can complete the chat turn.
|
|
179
181
|
|
|
180
|
-
Tools return business data. Generated code sends rich messages through registered `chat.<component>(props)` methods. A `ThinkSignal`
|
|
182
|
+
Tools return business data. Generated code sends rich messages through registered `chat.<component>(props)` methods. A tool may throw or return `new ThinkSignal(reason, context)` to require inspection of a successful result. JavaScript receives `context` as the tool return value: assignments, subsequent calls, and awaited parallel tools continue normally. At the end of that iteration, inspection takes precedence over an attempted exit or a later recoverable error; exit hooks do not run. The next model turn receives every signaling tool's name, source line, reason, and result together inside `<forced_inspection>`, and is instructed to reuse those results rather than repeat successful calls. Explicit `inspect()` output is also preserved. Tool-result display budgets and `truncate()` policies still apply. Only the business tool handler may produce a `ThinkSignal`; tool hooks must return their documented input/output overrides. Forced inspection uses the output accepted by `onAfterTool`. If that hook rejects or cancels, the rejected result is withheld from guest memory and inspection.
|
|
183
|
+
|
|
184
|
+
Forced inspection delays completion, not business actions: code after a signaling tool still runs, including other tools and chat component deliveries. It is not an authorization barrier. Cancellation and critical failures still stop execution completely. `ThinkSignal` is not durable pause/resume.
|
|
181
185
|
|
|
182
186
|
## Components
|
|
183
187
|
|
|
@@ -208,7 +212,7 @@ The model calls `chat.cards(...)`. `render` parses props once and captures an im
|
|
|
208
212
|
|
|
209
213
|
`response.onDelta` receives previews. Its normal event has `delta`, accumulated `content`, `id`, and `iterationId`. A restart event has `restart: true`, an iteration ID, attempt number, models, and reason. Retract the prior preview before displaying replacement text.
|
|
210
214
|
|
|
211
|
-
`response.handler` receives the accepted complete text and its message metadata. Components use their own handlers. Without handlers, native text is still retained in session history
|
|
215
|
+
`response.handler` receives the accepted complete text and its message metadata. Components use their own handlers. Without handlers, native text is still retained in session history, but does not count as delivered speech for `requireChatResponse`.
|
|
212
216
|
|
|
213
217
|
Complete JavaScript calls can execute while streaming continues. If a stream fails after dispatch, the runtime retains completed effects and reports the interruption; it does not replay the program on another model. `options.midStreamFallback` enables restarts before dispatch and requires a preview consumer capable of handling retractions. Normal preview callback failures are ignored; failed retractions stop generation. A final delivery failure can fail execution.
|
|
214
218
|
|
|
@@ -283,7 +287,7 @@ const getEvidence = new Tool({
|
|
|
283
287
|
|
|
284
288
|
Inventories and diagnostic previews keep their own small budgets even if a value carries a larger inspection override. Truncation markers are included in the final measured output. Unicode boundaries, cyclic structures, throwing formatters, and accessor properties are handled without changing retained data.
|
|
285
289
|
|
|
286
|
-
Standalone text is displayed directly. Strings nested in objects or arrays use JSON quoting so source indentation, line endings, and literal escapes remain distinct from the preview's formatting.
|
|
290
|
+
Both `return inspect(value)` and forced ThinkSignal inspection use the native inspector. Standalone text is displayed directly, preserving whitespace, code, and literal tags within its preview budget. Report sections add no XML entity escaping or CDATA. Strings nested in objects or arrays use JSON quoting so source indentation, line endings, and literal escapes remain distinct from the preview's formatting.
|
|
287
291
|
|
|
288
292
|
`onInspect` customizes previews by purpose and identity. Return `undefined` for the default formatter. The hook receives an isolated read-only snapshot; custom text is still bounded. A formatter failure falls back to default inspection.
|
|
289
293
|
|
package/ERRORS.md
CHANGED
|
@@ -58,6 +58,7 @@ A **critical** failure stops the execution without another model call. Critical
|
|
|
58
58
|
| `INVALID_COMPONENT_INPUT` | `ComponentInputError` | Recoverable. `componentName`, `issues`, `expectedInput`. No message was sent. |
|
|
59
59
|
| `INVALID_NATIVE_CALL` | `NativeProtocolError` | Recoverable. Malformed native call, invalid JavaScript envelope, or multiple calls in one response. The rejected batch did not execute. |
|
|
60
60
|
| `HOST_OPERATION_FAILED` | `HostOperationError` | Recoverable. Unawaited tool or operation after JavaScript completion. Started work is joined; feedback distinguishes its effects. |
|
|
61
|
+
| `MISSING_CHAT_RESPONSE` | `MissingChatResponseError` | Recoverable. Chat tried to complete through `listen` while the assistant was not the last participant to speak; disabled by `options.requireChatResponse: false`. |
|
|
61
62
|
| `DELIVERY_FAILED` | `DeliveryError` | Recoverable. Text/component handler failed. Earlier acknowledged sends remain delivered; later queued sends are skipped. Inspect `cause`. |
|
|
62
63
|
| `HOOK_FAILED` | `HookError` | Recoverable. A hook rejected an operation; original `cause` is retained. |
|
|
63
64
|
| `INVALID_MEMORY_VALUE` | `MemoryValueError` | Recoverable. Unsupported/cyclic memory or inspection value. Failed captures also appear in `iteration.errors` and the memory report. |
|
|
@@ -89,10 +90,12 @@ Validation errors include a path/message list and the expected argument shape as
|
|
|
89
90
|
|
|
90
91
|
[`src/runtime/error-recovery.test.ts`](./src/runtime/error-recovery.test.ts) runs scripted, mocked LLM responses through the real runtime and both VM drivers. Its `.toMatchInlineSnapshot()` assertions show the tool-result feedback actually present in the next model request, including the expected input types. Memory and iteration-budget footers are excluded from the catalogue snapshot so the failure feedback is easy to review. Critical-error tests in [`src/runtime/errors.test.ts`](./src/runtime/errors.test.ts) assert that no additional provider call or business action occurs.
|
|
91
92
|
|
|
92
|
-
Recovery feedback uses XML-style sections: `<error>` contains the specific error code and readable message, `<stack_trace>` shows source-mapped guest code with line numbers and carets, and `<recovery>` explains how to continue. Tool calls, sent messages, memory changes, and inspection results each have their own section.
|
|
93
|
+
Recovery feedback uses XML-style sections: `<error>` contains the specific error code and readable message, `<stack_trace>` shows source-mapped guest code with line numbers and carets, and `<recovery>` explains how to continue. Tool calls, sent messages, memory changes, and inspection results each have their own section. Section tags are readable separators, not a strict XML document. Content is shown verbatim without entity escaping or CDATA, so code examples, entity literals, and retrieval tags stay unchanged. Validation messages preserve line breaks and the expected TypeScript shape.
|
|
93
94
|
|
|
94
95
|
Source traces are bounded previews around the failure sites, including failures near the end of long programs. The complete annotated source remains available as `CodeExecutionError.stacktrace`. Node and QuickJS may report different column precision; the inline snapshots cover each. Compiler errors show the invalid source. Host failures outside guest execution retain their original `cause` for consumers; the model is not shown a misleading guest stack or internal host paths.
|
|
95
96
|
|
|
96
|
-
A `ThinkSignal`
|
|
97
|
+
A tool's thrown or returned `ThinkSignal` counts as successful execution, with its `context` returned to JavaScript. Multiple signals are collected while code continues. At settlement, they force inspection before any exit hook can run, even when later code raises a recoverable error. The `<forced_inspection>` section groups each tool's name, original call-site line (when available), reason, and result. It explicitly describes this as equivalent to `inspect()` and tells the model not to repeat those calls. Actual downstream failures remain in `iteration.errors` and the report's error sections; cancellation and critical errors still stop execution.
|
|
98
|
+
|
|
99
|
+
`think_signal` traces include the responsible tool name, tool-call ID, source line, reason, context, and optional metadata. Results are captured after output hooks and before guest mutations, and displayed through the normal inspection hooks and token budgets.
|
|
97
100
|
|
|
98
101
|
`toJSON()` and `result.diagnostics()` retain codes, messages, criticality, and nested error diagnostics. They are plain data: JSON does not retain the shared symbol brand or Error prototypes, so class guards intentionally do not accept parsed diagnostic JSON. The VM restores typed errors internally before exposing them on iterations.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const require_utils = require("./utils-CTlsXvdj.cjs");
|
|
2
|
-
const require_errors = require("./errors-
|
|
3
|
-
const require_schema = require("./schema-
|
|
4
|
-
const require_typings = require("./typings-
|
|
2
|
+
const require_errors = require("./errors-C6ppQUZX.cjs");
|
|
3
|
+
const require_schema = require("./schema-CXlnbb3n.cjs");
|
|
4
|
+
const require_typings = require("./typings-BA_XxAcY.cjs");
|
|
5
5
|
let _bpinternal_zui = require("@bpinternal/zui");
|
|
6
6
|
//#region ../../node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/_baseCreate.js
|
|
7
7
|
/** Built-in value references. */
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { A as keys, B as baseAssignValue, C as getAllKeysIn, D as Stack, E as getSymbols, F as isBuffer, G as isObjectLike, H as isObject, K as Symbol, L as isPrototype, N as nodeUtil, O as getPrototype, P as baseUnary, T as getSymbolsIn, U as isArray, Y as __exportAll, b as Uint8Array, k as keysIn, q as root, w as getAllKeys, x as _getTag_default, z as assignValue } from "./utils-BOFzb8Ok.js";
|
|
2
|
-
import {
|
|
3
|
-
import { n as parseSchemaSync, r as schemaInput } from "./schema-
|
|
4
|
-
import { n as schemaToTypeScript } from "./typings-
|
|
2
|
+
import { P as ReservedIdentifierError, d as ComponentInputError, y as InvalidComponentError } from "./errors-Crk5P8jo.js";
|
|
3
|
+
import { n as parseSchemaSync, r as schemaInput } from "./schema-GE4ISPCR.js";
|
|
4
|
+
import { n as schemaToTypeScript } from "./typings-BEVDvtuk.js";
|
|
5
5
|
import { z } from "@bpinternal/zui";
|
|
6
6
|
//#region ../../node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/_baseCreate.js
|
|
7
7
|
/** Built-in value references. */
|
package/dist/context.d.ts
CHANGED
|
@@ -93,7 +93,7 @@ export declare namespace IterationStatuses {
|
|
|
93
93
|
/** The value returned by the executed code (or the context provided by a ThinkSignal). */
|
|
94
94
|
variables: unknown;
|
|
95
95
|
metadata?: Record<string, unknown>;
|
|
96
|
-
/** A
|
|
96
|
+
/** A legacy VM control-flow signal paused execution. Tool ThinkSignals now use forced inspection. */
|
|
97
97
|
interrupted?: boolean;
|
|
98
98
|
};
|
|
99
99
|
};
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { a as getTokenizer } from "./utils-BOFzb8Ok.js";
|
|
2
|
-
import { C as InvalidMessageError, F as
|
|
3
|
-
import { i as createComponentRegistry, n as assertValidComponent } from "./component-
|
|
4
|
-
import { t as Tool } from "./tool
|
|
5
|
-
import { t as Exit } from "./exit-
|
|
6
|
-
import { t as DEFAULT_TOOL_RESULT_MAX_TOKENS } from "./truncate-
|
|
7
|
-
import { a as cloneMemoryValue, c as freezeMemoryValue, f as createInspector, i as renderMemory, l as RESERVED_RUNTIME_NAMES, o as decodeMemoryValue, r as Memory, s as encodeMemoryValue } from "./quickjs-variant-
|
|
8
|
-
import { o as resolveResponse, t as getNativeSystemMessage } from "./native-
|
|
2
|
+
import { C as InvalidMessageError, F as SessionStateError, I as TokenOverflowError, O as LoopExceededError, P as ReservedIdentifierError, T as InvalidSessionError, U as isLLMzError, _ as InternalError, b as InvalidConfigurationError, i as describeError, l as CognitiveError, p as ExecutionAbortedError, t as Signals, u as CompactionError, x as InvalidEventError } from "./errors-Crk5P8jo.js";
|
|
3
|
+
import { i as createComponentRegistry, n as assertValidComponent } from "./component-DncqP4fB.js";
|
|
4
|
+
import { t as Tool } from "./tool-DstssiAs.js";
|
|
5
|
+
import { t as Exit } from "./exit-DMPwCSba.js";
|
|
6
|
+
import { t as DEFAULT_TOOL_RESULT_MAX_TOKENS } from "./truncate-BEKbdo3t.js";
|
|
7
|
+
import { a as cloneMemoryValue, c as freezeMemoryValue, f as createInspector, i as renderMemory, l as RESERVED_RUNTIME_NAMES, o as decodeMemoryValue, r as Memory, s as encodeMemoryValue } from "./quickjs-variant-CtuGagsb.js";
|
|
8
|
+
import { o as resolveResponse, t as getNativeSystemMessage } from "./native-n_718Z-T.js";
|
|
9
9
|
import { z } from "@bpinternal/zui";
|
|
10
10
|
import { ulid } from "ulid";
|
|
11
11
|
import { Cognitive } from "@botpress/cognitive";
|
|
@@ -325,6 +325,14 @@ function normalizeMessage(message) {
|
|
|
325
325
|
validateInputMessage(normalized);
|
|
326
326
|
return normalized;
|
|
327
327
|
}
|
|
328
|
+
/** Only actual participant content counts as speech, including image/audio-only messages. */
|
|
329
|
+
function inputSpeaker(message) {
|
|
330
|
+
var _message$content;
|
|
331
|
+
return (Array.isArray(message.content) ? message.content.some((part) => {
|
|
332
|
+
var _part$text;
|
|
333
|
+
return part.type !== "text" || Boolean((_part$text = part.text) === null || _part$text === void 0 ? void 0 : _part$text.trim());
|
|
334
|
+
}) : Boolean((_message$content = message.content) === null || _message$content === void 0 ? void 0 : _message$content.trim())) && (message.role === "user" || message.role === "assistant") ? message.role : null;
|
|
335
|
+
}
|
|
328
336
|
function createAssistantMessage(response) {
|
|
329
337
|
var _response$toolCalls;
|
|
330
338
|
if (response.assistantMessage) return asSessionMessage(response.assistantMessage);
|
|
@@ -493,6 +501,7 @@ function validateRestoredHistory(state) {
|
|
|
493
501
|
if (!Array.isArray(state.groups) || !Array.isArray(state.pendingInputs)) throw new InvalidSessionError("Session history and queued inputs must be arrays.");
|
|
494
502
|
if (!Number.isSafeInteger(state.turn) || state.turn < 0 || !Number.isSafeInteger(state.iteration) || state.iteration < 0) throw new InvalidSessionError("Session turn and iteration counters must be non-negative safe integers");
|
|
495
503
|
if (typeof state.activeTurn !== "boolean" || state.activeTurn && (!state.turn || !state.turnId)) throw new InvalidSessionError("Session processing state must identify an active turn.");
|
|
504
|
+
if (state.lastSpeaker !== void 0 && state.lastSpeaker !== null && !["user", "assistant"].includes(state.lastSpeaker)) throw new InvalidSessionError("Session last speaker must be user, assistant, or null.");
|
|
496
505
|
const groupIds = /* @__PURE__ */ new Set();
|
|
497
506
|
const callIds = /* @__PURE__ */ new Set();
|
|
498
507
|
let previousIteration = 0;
|
|
@@ -593,6 +602,7 @@ var Session = class Session {
|
|
|
593
602
|
#pendingInputs = [];
|
|
594
603
|
#activeTurn = false;
|
|
595
604
|
#locked = false;
|
|
605
|
+
#lastSpeaker = null;
|
|
596
606
|
constructor(options = {}) {
|
|
597
607
|
this.id = `session_${ulid()}`;
|
|
598
608
|
this.memory = new Memory({
|
|
@@ -617,6 +627,15 @@ var Session = class Session {
|
|
|
617
627
|
get transcript() {
|
|
618
628
|
return structuredClone([...this.#allGroups().flatMap((group) => group.source ? [group.source] : group.messages), ...this.#pendingInputs.map((input) => input.source ?? input.message)]);
|
|
619
629
|
}
|
|
630
|
+
/** Last participant who spoke in the active history. Events and queued inputs do not count. */
|
|
631
|
+
get lastSpeaker() {
|
|
632
|
+
return this.#lastSpeaker;
|
|
633
|
+
}
|
|
634
|
+
/** Record acknowledged text or component delivery, never generation alone. */
|
|
635
|
+
recordAssistantDelivery(iterationId) {
|
|
636
|
+
this.#getActiveIteration(iterationId);
|
|
637
|
+
this.#lastSpeaker = "assistant";
|
|
638
|
+
}
|
|
620
639
|
get pendingMessages() {
|
|
621
640
|
return structuredClone(this.#pendingInputs.map((input) => input.message));
|
|
622
641
|
}
|
|
@@ -705,12 +724,15 @@ var Session = class Session {
|
|
|
705
724
|
this.#turn++;
|
|
706
725
|
this.#turnId = `turn_${ulid()}`;
|
|
707
726
|
this.#activeTurn = true;
|
|
708
|
-
for (const input of this.#pendingInputs)
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
727
|
+
for (const input of this.#pendingInputs) {
|
|
728
|
+
if (!input.source) this.#lastSpeaker = inputSpeaker(input.message) ?? this.#lastSpeaker;
|
|
729
|
+
this.#groups.push({
|
|
730
|
+
id: input.id,
|
|
731
|
+
turn: this.#turn,
|
|
732
|
+
messages: [input.message],
|
|
733
|
+
...input.source ? { source: input.source } : {}
|
|
734
|
+
});
|
|
735
|
+
}
|
|
714
736
|
this.#pendingInputs = [];
|
|
715
737
|
}
|
|
716
738
|
/** Mark the active input batch complete without consuming newly queued input. */
|
|
@@ -1033,6 +1055,7 @@ var Session = class Session {
|
|
|
1033
1055
|
groups: this.#groups.map(serializeGroup),
|
|
1034
1056
|
memory: this.memory.serialize(),
|
|
1035
1057
|
pendingInputs: structuredClone(this.#pendingInputs),
|
|
1058
|
+
lastSpeaker: this.#lastSpeaker,
|
|
1036
1059
|
activeTurn: this.#activeTurn,
|
|
1037
1060
|
latestResultId: this.#latestResultId,
|
|
1038
1061
|
compaction
|
|
@@ -1051,6 +1074,7 @@ var Session = class Session {
|
|
|
1051
1074
|
session.#groups = state.groups.map(restoreGroup);
|
|
1052
1075
|
session.#pendingInputs = structuredClone(state.pendingInputs);
|
|
1053
1076
|
session.#activeTurn = state.activeTurn;
|
|
1077
|
+
session.#lastSpeaker = state.lastSpeaker ?? null;
|
|
1054
1078
|
session.#latestResultId = state.latestResultId;
|
|
1055
1079
|
Object.defineProperty(session, "memory", {
|
|
1056
1080
|
value: Memory.restore(state.memory, () => session.#resultBytes()),
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
const require_utils = require("./utils-CTlsXvdj.cjs");
|
|
2
|
-
const require_errors = require("./errors-
|
|
3
|
-
const require_component = require("./component-
|
|
4
|
-
const require_tool = require("./tool-
|
|
5
|
-
const require_exit = require("./exit-
|
|
6
|
-
const require_truncate = require("./truncate-
|
|
7
|
-
const require_quickjs_variant = require("./quickjs-variant-
|
|
8
|
-
const require_native = require("./native-
|
|
2
|
+
const require_errors = require("./errors-C6ppQUZX.cjs");
|
|
3
|
+
const require_component = require("./component-CMFoCHyu.cjs");
|
|
4
|
+
const require_tool = require("./tool-_wK9hQOb.cjs");
|
|
5
|
+
const require_exit = require("./exit-BOtKWPuT.cjs");
|
|
6
|
+
const require_truncate = require("./truncate-uomAMGPs.cjs");
|
|
7
|
+
const require_quickjs_variant = require("./quickjs-variant-21IO97PF.cjs");
|
|
8
|
+
const require_native = require("./native-0bq5ATZM.cjs");
|
|
9
9
|
let _bpinternal_zui = require("@bpinternal/zui");
|
|
10
10
|
let ulid = require("ulid");
|
|
11
11
|
let _botpress_cognitive = require("@botpress/cognitive");
|
|
@@ -325,6 +325,14 @@ function normalizeMessage(message) {
|
|
|
325
325
|
validateInputMessage(normalized);
|
|
326
326
|
return normalized;
|
|
327
327
|
}
|
|
328
|
+
/** Only actual participant content counts as speech, including image/audio-only messages. */
|
|
329
|
+
function inputSpeaker(message) {
|
|
330
|
+
var _message$content;
|
|
331
|
+
return (Array.isArray(message.content) ? message.content.some((part) => {
|
|
332
|
+
var _part$text;
|
|
333
|
+
return part.type !== "text" || Boolean((_part$text = part.text) === null || _part$text === void 0 ? void 0 : _part$text.trim());
|
|
334
|
+
}) : Boolean((_message$content = message.content) === null || _message$content === void 0 ? void 0 : _message$content.trim())) && (message.role === "user" || message.role === "assistant") ? message.role : null;
|
|
335
|
+
}
|
|
328
336
|
function createAssistantMessage(response) {
|
|
329
337
|
var _response$toolCalls;
|
|
330
338
|
if (response.assistantMessage) return asSessionMessage(response.assistantMessage);
|
|
@@ -493,6 +501,7 @@ function validateRestoredHistory(state) {
|
|
|
493
501
|
if (!Array.isArray(state.groups) || !Array.isArray(state.pendingInputs)) throw new require_errors.InvalidSessionError("Session history and queued inputs must be arrays.");
|
|
494
502
|
if (!Number.isSafeInteger(state.turn) || state.turn < 0 || !Number.isSafeInteger(state.iteration) || state.iteration < 0) throw new require_errors.InvalidSessionError("Session turn and iteration counters must be non-negative safe integers");
|
|
495
503
|
if (typeof state.activeTurn !== "boolean" || state.activeTurn && (!state.turn || !state.turnId)) throw new require_errors.InvalidSessionError("Session processing state must identify an active turn.");
|
|
504
|
+
if (state.lastSpeaker !== void 0 && state.lastSpeaker !== null && !["user", "assistant"].includes(state.lastSpeaker)) throw new require_errors.InvalidSessionError("Session last speaker must be user, assistant, or null.");
|
|
496
505
|
const groupIds = /* @__PURE__ */ new Set();
|
|
497
506
|
const callIds = /* @__PURE__ */ new Set();
|
|
498
507
|
let previousIteration = 0;
|
|
@@ -593,6 +602,7 @@ var Session = class Session {
|
|
|
593
602
|
#pendingInputs = [];
|
|
594
603
|
#activeTurn = false;
|
|
595
604
|
#locked = false;
|
|
605
|
+
#lastSpeaker = null;
|
|
596
606
|
constructor(options = {}) {
|
|
597
607
|
this.id = `session_${(0, ulid.ulid)()}`;
|
|
598
608
|
this.memory = new require_quickjs_variant.Memory({
|
|
@@ -617,6 +627,15 @@ var Session = class Session {
|
|
|
617
627
|
get transcript() {
|
|
618
628
|
return structuredClone([...this.#allGroups().flatMap((group) => group.source ? [group.source] : group.messages), ...this.#pendingInputs.map((input) => input.source ?? input.message)]);
|
|
619
629
|
}
|
|
630
|
+
/** Last participant who spoke in the active history. Events and queued inputs do not count. */
|
|
631
|
+
get lastSpeaker() {
|
|
632
|
+
return this.#lastSpeaker;
|
|
633
|
+
}
|
|
634
|
+
/** Record acknowledged text or component delivery, never generation alone. */
|
|
635
|
+
recordAssistantDelivery(iterationId) {
|
|
636
|
+
this.#getActiveIteration(iterationId);
|
|
637
|
+
this.#lastSpeaker = "assistant";
|
|
638
|
+
}
|
|
620
639
|
get pendingMessages() {
|
|
621
640
|
return structuredClone(this.#pendingInputs.map((input) => input.message));
|
|
622
641
|
}
|
|
@@ -705,12 +724,15 @@ var Session = class Session {
|
|
|
705
724
|
this.#turn++;
|
|
706
725
|
this.#turnId = `turn_${(0, ulid.ulid)()}`;
|
|
707
726
|
this.#activeTurn = true;
|
|
708
|
-
for (const input of this.#pendingInputs)
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
727
|
+
for (const input of this.#pendingInputs) {
|
|
728
|
+
if (!input.source) this.#lastSpeaker = inputSpeaker(input.message) ?? this.#lastSpeaker;
|
|
729
|
+
this.#groups.push({
|
|
730
|
+
id: input.id,
|
|
731
|
+
turn: this.#turn,
|
|
732
|
+
messages: [input.message],
|
|
733
|
+
...input.source ? { source: input.source } : {}
|
|
734
|
+
});
|
|
735
|
+
}
|
|
714
736
|
this.#pendingInputs = [];
|
|
715
737
|
}
|
|
716
738
|
/** Mark the active input batch complete without consuming newly queued input. */
|
|
@@ -1033,6 +1055,7 @@ var Session = class Session {
|
|
|
1033
1055
|
groups: this.#groups.map(serializeGroup),
|
|
1034
1056
|
memory: this.memory.serialize(),
|
|
1035
1057
|
pendingInputs: structuredClone(this.#pendingInputs),
|
|
1058
|
+
lastSpeaker: this.#lastSpeaker,
|
|
1036
1059
|
activeTurn: this.#activeTurn,
|
|
1037
1060
|
latestResultId: this.#latestResultId,
|
|
1038
1061
|
compaction
|
|
@@ -1051,6 +1074,7 @@ var Session = class Session {
|
|
|
1051
1074
|
session.#groups = state.groups.map(restoreGroup);
|
|
1052
1075
|
session.#pendingInputs = structuredClone(state.pendingInputs);
|
|
1053
1076
|
session.#activeTurn = state.activeTurn;
|
|
1077
|
+
session.#lastSpeaker = state.lastSpeaker ?? null;
|
|
1054
1078
|
session.#latestResultId = state.latestResultId;
|
|
1055
1079
|
Object.defineProperty(session, "memory", {
|
|
1056
1080
|
value: require_quickjs_variant.Memory.restore(state.memory, () => session.#resultBytes()),
|
package/dist/errors/catalog.d.ts
CHANGED
|
@@ -211,6 +211,12 @@ export declare class HostOperationError extends LLMzError<'HOST_OPERATION_FAILED
|
|
|
211
211
|
readonly code = "HOST_OPERATION_FAILED";
|
|
212
212
|
constructor(message: string, options?: ErrorOptions);
|
|
213
213
|
}
|
|
214
|
+
/** Chat tried to wait for the user without delivering any message. */
|
|
215
|
+
export declare class MissingChatResponseError extends LLMzError<'MISSING_CHAT_RESPONSE'> {
|
|
216
|
+
static readonly is: (value: unknown) => value is MissingChatResponseError;
|
|
217
|
+
readonly code = "MISSING_CHAT_RESPONSE";
|
|
218
|
+
constructor(message: string, options?: ErrorOptions);
|
|
219
|
+
}
|
|
214
220
|
/** Message delivery failed; external delivery may have partially completed. */
|
|
215
221
|
export declare class DeliveryError extends LLMzError<'DELIVERY_FAILED'> {
|
|
216
222
|
static readonly is: (value: unknown) => value is DeliveryError;
|
|
@@ -268,6 +274,7 @@ export declare const errorClasses: {
|
|
|
268
274
|
NativeProtocolError: typeof NativeProtocolError;
|
|
269
275
|
HostOperationError: typeof HostOperationError;
|
|
270
276
|
DeliveryError: typeof DeliveryError;
|
|
277
|
+
MissingChatResponseError: typeof MissingChatResponseError;
|
|
271
278
|
HookError: typeof HookError;
|
|
272
279
|
ExecutionAbortedError: typeof ExecutionAbortedError;
|
|
273
280
|
InternalError: typeof InternalError;
|
|
@@ -306,6 +306,14 @@ var HostOperationError = class extends LLMzError {
|
|
|
306
306
|
super(message, false, options);
|
|
307
307
|
}
|
|
308
308
|
};
|
|
309
|
+
/** Chat tried to wait for the user without delivering any message. */
|
|
310
|
+
var MissingChatResponseError = class extends LLMzError {
|
|
311
|
+
static is = (value) => isLLMzError(value, "MISSING_CHAT_RESPONSE");
|
|
312
|
+
code = "MISSING_CHAT_RESPONSE";
|
|
313
|
+
constructor(message, options) {
|
|
314
|
+
super(message, false, options);
|
|
315
|
+
}
|
|
316
|
+
};
|
|
309
317
|
/** Message delivery failed; external delivery may have partially completed. */
|
|
310
318
|
var DeliveryError = class extends LLMzError {
|
|
311
319
|
static is = (value) => isLLMzError(value, "DELIVERY_FAILED");
|
|
@@ -371,6 +379,7 @@ const errorClasses$1 = {
|
|
|
371
379
|
NativeProtocolError,
|
|
372
380
|
HostOperationError,
|
|
373
381
|
DeliveryError,
|
|
382
|
+
MissingChatResponseError,
|
|
374
383
|
HookError,
|
|
375
384
|
ExecutionAbortedError,
|
|
376
385
|
InternalError
|
|
@@ -407,6 +416,7 @@ const ERROR_CODES = /* @__PURE__ */ new Set([
|
|
|
407
416
|
"INVALID_NATIVE_CALL",
|
|
408
417
|
"HOST_OPERATION_FAILED",
|
|
409
418
|
"DELIVERY_FAILED",
|
|
419
|
+
"MISSING_CHAT_RESPONSE",
|
|
410
420
|
"HOOK_FAILED",
|
|
411
421
|
"EXECUTION_ABORTED",
|
|
412
422
|
"INTERNAL_ERROR"
|
|
@@ -595,6 +605,12 @@ var VMLoopSignal = class extends VMSignal {
|
|
|
595
605
|
this.message = Signals.serializeError(this);
|
|
596
606
|
}
|
|
597
607
|
};
|
|
608
|
+
/**
|
|
609
|
+
* A successful tool result that requires model inspection before completion.
|
|
610
|
+
* Tools may throw or return this signal. Its context becomes the JavaScript
|
|
611
|
+
* return value; calls and assignments continue, and inspection overrides any
|
|
612
|
+
* attempted exit at iteration settlement. Cancellation and critical errors still stop execution.
|
|
613
|
+
*/
|
|
598
614
|
var ThinkSignal = class extends VMLoopSignal {
|
|
599
615
|
reason;
|
|
600
616
|
context;
|
|
@@ -767,6 +783,12 @@ Object.defineProperty(exports, "MemoryValueError", {
|
|
|
767
783
|
return MemoryValueError;
|
|
768
784
|
}
|
|
769
785
|
});
|
|
786
|
+
Object.defineProperty(exports, "MissingChatResponseError", {
|
|
787
|
+
enumerable: true,
|
|
788
|
+
get: function() {
|
|
789
|
+
return MissingChatResponseError;
|
|
790
|
+
}
|
|
791
|
+
});
|
|
770
792
|
Object.defineProperty(exports, "NativeProtocolError", {
|
|
771
793
|
enumerable: true,
|
|
772
794
|
get: function() {
|
|
@@ -306,6 +306,14 @@ var HostOperationError = class extends LLMzError {
|
|
|
306
306
|
super(message, false, options);
|
|
307
307
|
}
|
|
308
308
|
};
|
|
309
|
+
/** Chat tried to wait for the user without delivering any message. */
|
|
310
|
+
var MissingChatResponseError = class extends LLMzError {
|
|
311
|
+
static is = (value) => isLLMzError(value, "MISSING_CHAT_RESPONSE");
|
|
312
|
+
code = "MISSING_CHAT_RESPONSE";
|
|
313
|
+
constructor(message, options) {
|
|
314
|
+
super(message, false, options);
|
|
315
|
+
}
|
|
316
|
+
};
|
|
309
317
|
/** Message delivery failed; external delivery may have partially completed. */
|
|
310
318
|
var DeliveryError = class extends LLMzError {
|
|
311
319
|
static is = (value) => isLLMzError(value, "DELIVERY_FAILED");
|
|
@@ -371,6 +379,7 @@ const errorClasses$1 = {
|
|
|
371
379
|
NativeProtocolError,
|
|
372
380
|
HostOperationError,
|
|
373
381
|
DeliveryError,
|
|
382
|
+
MissingChatResponseError,
|
|
374
383
|
HookError,
|
|
375
384
|
ExecutionAbortedError,
|
|
376
385
|
InternalError
|
|
@@ -407,6 +416,7 @@ const ERROR_CODES = /* @__PURE__ */ new Set([
|
|
|
407
416
|
"INVALID_NATIVE_CALL",
|
|
408
417
|
"HOST_OPERATION_FAILED",
|
|
409
418
|
"DELIVERY_FAILED",
|
|
419
|
+
"MISSING_CHAT_RESPONSE",
|
|
410
420
|
"HOOK_FAILED",
|
|
411
421
|
"EXECUTION_ABORTED",
|
|
412
422
|
"INTERNAL_ERROR"
|
|
@@ -595,6 +605,12 @@ var VMLoopSignal = class extends VMSignal {
|
|
|
595
605
|
this.message = Signals.serializeError(this);
|
|
596
606
|
}
|
|
597
607
|
};
|
|
608
|
+
/**
|
|
609
|
+
* A successful tool result that requires model inspection before completion.
|
|
610
|
+
* Tools may throw or return this signal. Its context becomes the JavaScript
|
|
611
|
+
* return value; calls and assignments continue, and inspection overrides any
|
|
612
|
+
* attempted exit at iteration settlement. Cancellation and critical errors still stop execution.
|
|
613
|
+
*/
|
|
598
614
|
var ThinkSignal = class extends VMLoopSignal {
|
|
599
615
|
reason;
|
|
600
616
|
context;
|
|
@@ -617,4 +633,4 @@ registerErrorClass("VMSignal", VMSignal);
|
|
|
617
633
|
registerErrorClass("VMLoopSignal", VMLoopSignal);
|
|
618
634
|
registerErrorClass("ThinkSignal", ThinkSignal);
|
|
619
635
|
//#endregion
|
|
620
|
-
export { MemoryValueError as A,
|
|
636
|
+
export { MemoryValueError as A, UnknownExitError as B, InvalidMessageError as C, LLMzError as D, InvalidToolError as E, SessionStateError as F, isCriticalError as H, TokenOverflowError as I, ToolExecutionError as L, NativeProtocolError as M, ObjectPropertyError as N, LoopExceededError as O, ReservedIdentifierError as P, ToolInputError as R, InvalidExitError as S, InvalidSessionError as T, isLLMzError as U, UnknownToolError as V, InternalError as _, cleanStackTrace as a, InvalidConfigurationError as b, CodeFormattingError as c, ComponentInputError as d, DeliveryError as f, HostOperationError as g, HookError as h, describeError as i, MissingChatResponseError as j, MemoryCapacityError as k, CognitiveError as l, ExitInputError as m, ThinkSignal as n, AssignmentError as o, ExecutionAbortedError as p, VMSignal as r, CodeExecutionError as s, Signals as t, CompactionError as u, InvalidCodeError as v, InvalidObjectError as w, InvalidEventError as x, InvalidComponentError as y, UnknownComponentError as z };
|
package/dist/errors.d.ts
CHANGED
|
@@ -39,6 +39,12 @@ export declare class VMLoopSignal extends VMSignal {
|
|
|
39
39
|
static readonly is: (value: unknown) => value is VMLoopSignal;
|
|
40
40
|
constructor(message: string);
|
|
41
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* A successful tool result that requires model inspection before completion.
|
|
44
|
+
* Tools may throw or return this signal. Its context becomes the JavaScript
|
|
45
|
+
* return value; calls and assignments continue, and inspection overrides any
|
|
46
|
+
* attempted exit at iteration settlement. Cancellation and critical errors still stop execution.
|
|
47
|
+
*/
|
|
42
48
|
export declare class ThinkSignal extends VMLoopSignal {
|
|
43
49
|
reason: string;
|
|
44
50
|
context?: any;
|