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.
Files changed (51) hide show
  1. package/DOCS.md +8 -4
  2. package/ERRORS.md +5 -2
  3. package/dist/{component-BpMVZYOa.cjs → component-CMFoCHyu.cjs} +3 -3
  4. package/dist/{component-C27qu6Zv.js → component-DncqP4fB.js} +3 -3
  5. package/dist/context.d.ts +1 -1
  6. package/dist/{custom-client-BDkgBR2w.js → custom-client-C-WXvLD9.js} +37 -13
  7. package/dist/{custom-client-MytucGI-.cjs → custom-client-Cgt9_0r1.cjs} +37 -13
  8. package/dist/errors/catalog.d.ts +7 -0
  9. package/dist/{errors-IhnTKUp7.cjs → errors-C6ppQUZX.cjs} +22 -0
  10. package/dist/{errors-H4JJFH3S.js → errors-Crk5P8jo.js} +17 -1
  11. package/dist/errors.d.ts +6 -0
  12. package/dist/{execute-BYI_U5sR.js → execute-CiYvPs5Q.js} +196 -78
  13. package/dist/{execute-DLas4V2n.cjs → execute-DTTfacsi.cjs} +196 -78
  14. package/dist/{exit-BUgJ5qi5.cjs → exit-BOtKWPuT.cjs} +2 -2
  15. package/dist/{exit-CPNk3vbz.js → exit-DMPwCSba.js} +2 -2
  16. package/dist/index.cjs +18 -17
  17. package/dist/index.d.ts +1 -1
  18. package/dist/index.js +18 -18
  19. package/dist/index.workerd.js +252 -79
  20. package/dist/inspection.d.ts +2 -0
  21. package/dist/{native-Bm6L9zOb.cjs → native-0bq5ATZM.cjs} +3 -3
  22. package/dist/{native-DvTH9vFe.js → native-n_718Z-T.js} +3 -3
  23. package/dist/{quickjs-variant-DJwYDSsb.cjs → quickjs-variant-21IO97PF.cjs} +15 -8
  24. package/dist/{quickjs-variant-DlPi9-Sx.js → quickjs-variant-CtuGagsb.js} +10 -9
  25. package/dist/runtime/chat-completion.test.d.ts +1 -0
  26. package/dist/runtime/chat-last-speaker.test.d.ts +1 -0
  27. package/dist/runtime/empty-completion.test.d.ts +1 -0
  28. package/dist/runtime/execution-report.d.ts +3 -0
  29. package/dist/runtime/forced-inspection.d.ts +13 -0
  30. package/dist/runtime/forced-inspection.test.d.ts +1 -0
  31. package/dist/runtime/javascript-api.d.ts +3 -0
  32. package/dist/runtime/think-signal.test.d.ts +1 -0
  33. package/dist/runtime/tool-wrapper.d.ts +4 -2
  34. package/dist/runtime/types.d.ts +8 -0
  35. package/dist/{schema-DBkjo0b7.cjs → schema-CXlnbb3n.cjs} +1 -1
  36. package/dist/{schema-Aer_W7Al.js → schema-GE4ISPCR.js} +1 -1
  37. package/dist/session/messages.d.ts +2 -0
  38. package/dist/session/serialization.d.ts +2 -0
  39. package/dist/session/session.d.ts +4 -0
  40. package/dist/session/speaker.test.d.ts +1 -0
  41. package/dist/{tool--gK91eez.js → tool-DstssiAs.js} +4 -4
  42. package/dist/{tool-Da_F-N-5.cjs → tool-_wK9hQOb.cjs} +4 -4
  43. package/dist/{truncate-BSoH2-nY.js → truncate-BEKbdo3t.js} +1 -1
  44. package/dist/{truncate-nV3Mxr6-.cjs → truncate-uomAMGPs.cjs} +1 -1
  45. package/dist/types.d.ts +6 -0
  46. package/dist/{typings-C1ihexWE.cjs → typings-BA_XxAcY.cjs} +1 -1
  47. package/dist/{typings-D9_aC8aq.js → typings-BEVDvtuk.js} +1 -1
  48. package/dist/vm/types.d.ts +2 -0
  49. package/dist/{vm-8jxt8PTK.js → vm-C7SfutHn.js} +28 -3
  50. package/dist/{vm-XuVPuW3Y.cjs → vm-gmekHc0i.cjs} +28 -2
  51. package/package.json +1 -1
@@ -36,3 +36,5 @@ export type InspectionOptions = {
36
36
  export type Inspector = (value: unknown, options: InspectionOptions) => string;
37
37
  /** The shared boundary for values displayed in prompts, reports, and memory inventories. */
38
38
  export declare function createInspector(onInspect?: OnInspect): Inspector;
39
+ /** Isolate evidence from subsequent guest mutations without invoking getters. */
40
+ export declare function snapshotInspectionValue(value: unknown, copies?: WeakMap<object, unknown>): unknown;
@@ -1,6 +1,6 @@
1
1
  const require_utils = require("./utils-CTlsXvdj.cjs");
2
- const require_errors = require("./errors-IhnTKUp7.cjs");
3
- const require_typings = require("./typings-C1ihexWE.cjs");
2
+ const require_errors = require("./errors-C6ppQUZX.cjs");
3
+ const require_typings = require("./typings-BA_XxAcY.cjs");
4
4
  //#region src/chat/response.ts
5
5
  const presets = {
6
6
  markdown: { instructions: "Write natural Markdown directly in the assistant response. Use paragraphs, lists, links, and code blocks where useful. Do not wrap the entire response in JSON or a Markdown fence." },
@@ -122,7 +122,7 @@ function runtimeRules(props, chat) {
122
122
  }
123
123
  rules.push("Execution may overlap the remaining response stream. The runtime waits for the stream, code, and queued message deliveries before the next response.", "# Memory", "Declare retained variables at top level with const or let. Bare assignment only updates a variable already declared in this program or listed in Memory. Named variables survive transcript compaction; assignment age records when they were set, not when the underlying data was fetched.", "Object properties are immutable snapshots. Replace a writable property completely, such as account.profile = { ...account.profile, age: 42 }; nested edits are forbidden and replacements are schema-validated.", "$return is the latest successful inspection result. $iterations is read-only retained history, newest first: [0] is the last settled iteration and [1] the preceding one. The current execution is not included. Entries without results still occupy indexes; check hasResult. Compaction prunes automatic results. Assign useful data to named variables to retain it independently.", "# Recovery", "Execution reports identify completed actions, inspected values, memory changes, and errors. Reuse preserved variables and completed actions; retry only failed work. Build completion payloads from those values, not by calling successful tools again. An inspection has already run the recorded calls; it is not a dry run.", "An operational error does not by itself finish the task. Inspect the actual error, repair its cause when safe and authorized, then retry. Unchanged retries do not establish that recovery is exhausted. If another response must diagnose the error, return inspect({ errors, completed }) or let the error reach the runtime. Honor task instructions defining terminal failure outcomes.");
124
124
  if (hasExits) rules.push("Use a failure exit only when recovery is unavailable, unsafe, forbidden, its budget is exhausted, or task instructions make the failure terminal. Do not select failure in advance for an unseen error. Do not turn an unexpected exception or rejected Promise.allSettled entry directly into failure completion: first expose it with inspect or let it reach the runtime, then diagnose the actual cause and available recovery tools. Explicit task instructions may define an error as terminal.");
125
- rules.push("A thinking interruption stops the current program and requests another model response. Statements after the interruption have not run; continue with a new program without repeating completed actions.", "Respect tool-attempt limits separately from the model-response budget. An empty successful inspection result is not a failure.");
125
+ rules.push("A tool may request forced inspection through ThinkSignal. The tool succeeded and its context is returned to JavaScript. Other calls and assignments continue normally. At the end of the program, forced inspection takes precedence over completion: review the reported results as an inspect() call, then continue from retained values without repeating successful calls.", "Respect tool-attempt limits separately from the model-response budget. An empty successful inspection result is not a failure.");
126
126
  return rules.join("\n\n");
127
127
  }
128
128
  async function describeRuntimeAPI(props, chat) {
@@ -1,6 +1,6 @@
1
1
  import { Y as __exportAll, i as getMultilineComment } from "./utils-BOFzb8Ok.js";
2
- import { b as InvalidConfigurationError } from "./errors-H4JJFH3S.js";
3
- import { i as formatTypings, t as getTypings } from "./typings-D9_aC8aq.js";
2
+ import { b as InvalidConfigurationError } from "./errors-Crk5P8jo.js";
3
+ import { i as formatTypings, t as getTypings } from "./typings-BEVDvtuk.js";
4
4
  //#region src/chat/response.ts
5
5
  const presets = {
6
6
  markdown: { instructions: "Write natural Markdown directly in the assistant response. Use paragraphs, lists, links, and code blocks where useful. Do not wrap the entire response in JSON or a Markdown fence." },
@@ -122,7 +122,7 @@ function runtimeRules(props, chat) {
122
122
  }
123
123
  rules.push("Execution may overlap the remaining response stream. The runtime waits for the stream, code, and queued message deliveries before the next response.", "# Memory", "Declare retained variables at top level with const or let. Bare assignment only updates a variable already declared in this program or listed in Memory. Named variables survive transcript compaction; assignment age records when they were set, not when the underlying data was fetched.", "Object properties are immutable snapshots. Replace a writable property completely, such as account.profile = { ...account.profile, age: 42 }; nested edits are forbidden and replacements are schema-validated.", "$return is the latest successful inspection result. $iterations is read-only retained history, newest first: [0] is the last settled iteration and [1] the preceding one. The current execution is not included. Entries without results still occupy indexes; check hasResult. Compaction prunes automatic results. Assign useful data to named variables to retain it independently.", "# Recovery", "Execution reports identify completed actions, inspected values, memory changes, and errors. Reuse preserved variables and completed actions; retry only failed work. Build completion payloads from those values, not by calling successful tools again. An inspection has already run the recorded calls; it is not a dry run.", "An operational error does not by itself finish the task. Inspect the actual error, repair its cause when safe and authorized, then retry. Unchanged retries do not establish that recovery is exhausted. If another response must diagnose the error, return inspect({ errors, completed }) or let the error reach the runtime. Honor task instructions defining terminal failure outcomes.");
124
124
  if (hasExits) rules.push("Use a failure exit only when recovery is unavailable, unsafe, forbidden, its budget is exhausted, or task instructions make the failure terminal. Do not select failure in advance for an unseen error. Do not turn an unexpected exception or rejected Promise.allSettled entry directly into failure completion: first expose it with inspect or let it reach the runtime, then diagnose the actual cause and available recovery tools. Explicit task instructions may define an error as terminal.");
125
- rules.push("A thinking interruption stops the current program and requests another model response. Statements after the interruption have not run; continue with a new program without repeating completed actions.", "Respect tool-attempt limits separately from the model-response budget. An empty successful inspection result is not a failure.");
125
+ rules.push("A tool may request forced inspection through ThinkSignal. The tool succeeded and its context is returned to JavaScript. Other calls and assignments continue normally. At the end of the program, forced inspection takes precedence over completion: review the reported results as an inspect() call, then continue from retained values without repeating successful calls.", "Respect tool-attempt limits separately from the model-response budget. An empty successful inspection result is not a failure.");
126
126
  return rules.join("\n\n");
127
127
  }
128
128
  async function describeRuntimeAPI(props, chat) {
@@ -1,8 +1,8 @@
1
1
  const require_utils = require("./utils-CTlsXvdj.cjs");
2
- const require_errors = require("./errors-IhnTKUp7.cjs");
3
- const require_schema = require("./schema-DBkjo0b7.cjs");
4
- const require_truncate = require("./truncate-nV3Mxr6-.cjs");
5
- const require_typings = require("./typings-C1ihexWE.cjs");
2
+ const require_errors = require("./errors-C6ppQUZX.cjs");
3
+ const require_schema = require("./schema-CXlnbb3n.cjs");
4
+ const require_truncate = require("./truncate-uomAMGPs.cjs");
5
+ const require_typings = require("./typings-BA_XxAcY.cjs");
6
6
  //#region src/inspect.ts
7
7
  const SUBTITLE_LN = "--------------";
8
8
  const TRUNCATION_MARKER = "[truncated]";
@@ -401,7 +401,7 @@ function createInspector(onInspect) {
401
401
  if (onInspect) try {
402
402
  const budget = resolveInspectionBudget(value, formatting);
403
403
  const output = onInspect(Object.freeze({
404
- value: snapshot(value),
404
+ value: snapshotInspectionValue(value),
405
405
  purpose: options.purpose,
406
406
  maxTokens: budget.tokens,
407
407
  preserve: budget.preserve,
@@ -413,12 +413,13 @@ function createInspector(onInspect) {
413
413
  return inspect(value, void 0, formatting);
414
414
  };
415
415
  }
416
- function snapshot(value, copies = /* @__PURE__ */ new WeakMap()) {
416
+ /** Isolate evidence from subsequent guest mutations without invoking getters. */
417
+ function snapshotInspectionValue(value, copies = /* @__PURE__ */ new WeakMap()) {
417
418
  if (!value || typeof value !== "object") return typeof value === "function" ? "[Function]" : value;
418
419
  if (copies.has(value)) return copies.get(value);
419
420
  if (require_truncate.isTruncated(value)) {
420
421
  copies.set(value, "[Circular]");
421
- const copy = snapshot(value.value, copies);
422
+ const copy = snapshotInspectionValue(value.value, copies);
422
423
  copies.set(value, copy);
423
424
  return copy;
424
425
  }
@@ -429,7 +430,7 @@ function snapshot(value, copies = /* @__PURE__ */ new WeakMap()) {
429
430
  if (Array.isArray(value) && key === "length") continue;
430
431
  const descriptor = Object.getOwnPropertyDescriptor(value, key);
431
432
  if (descriptor) Object.defineProperty(copy, key, {
432
- value: "value" in descriptor ? snapshot(descriptor.value, copies) : "[Getter]",
433
+ value: "value" in descriptor ? snapshotInspectionValue(descriptor.value, copies) : "[Getter]",
433
434
  enumerable: descriptor.enumerable
434
435
  });
435
436
  }
@@ -1071,3 +1072,9 @@ Object.defineProperty(exports, "resolveInspectionBudget", {
1071
1072
  return resolveInspectionBudget;
1072
1073
  }
1073
1074
  });
1075
+ Object.defineProperty(exports, "snapshotInspectionValue", {
1076
+ enumerable: true,
1077
+ get: function() {
1078
+ return snapshotInspectionValue;
1079
+ }
1080
+ });
@@ -1,8 +1,8 @@
1
1
  import { a as getTokenizer } from "./utils-BOFzb8Ok.js";
2
- import { A as MemoryValueError, N as ReservedIdentifierError, b as InvalidConfigurationError, k as MemoryCapacityError, o as AssignmentError } from "./errors-H4JJFH3S.js";
3
- import { i as toModelSchema } from "./schema-Aer_W7Al.js";
4
- import { n as isTruncated } from "./truncate-BSoH2-nY.js";
5
- import { t as getTypings } from "./typings-D9_aC8aq.js";
2
+ import { A as MemoryValueError, P as ReservedIdentifierError, b as InvalidConfigurationError, k as MemoryCapacityError, o as AssignmentError } from "./errors-Crk5P8jo.js";
3
+ import { i as toModelSchema } from "./schema-GE4ISPCR.js";
4
+ import { n as isTruncated } from "./truncate-BEKbdo3t.js";
5
+ import { t as getTypings } from "./typings-BEVDvtuk.js";
6
6
  //#region src/inspect.ts
7
7
  const SUBTITLE_LN = "--------------";
8
8
  const TRUNCATION_MARKER = "[truncated]";
@@ -401,7 +401,7 @@ function createInspector(onInspect) {
401
401
  if (onInspect) try {
402
402
  const budget = resolveInspectionBudget(value, formatting);
403
403
  const output = onInspect(Object.freeze({
404
- value: snapshot(value),
404
+ value: snapshotInspectionValue(value),
405
405
  purpose: options.purpose,
406
406
  maxTokens: budget.tokens,
407
407
  preserve: budget.preserve,
@@ -413,12 +413,13 @@ function createInspector(onInspect) {
413
413
  return inspect(value, void 0, formatting);
414
414
  };
415
415
  }
416
- function snapshot(value, copies = /* @__PURE__ */ new WeakMap()) {
416
+ /** Isolate evidence from subsequent guest mutations without invoking getters. */
417
+ function snapshotInspectionValue(value, copies = /* @__PURE__ */ new WeakMap()) {
417
418
  if (!value || typeof value !== "object") return typeof value === "function" ? "[Function]" : value;
418
419
  if (copies.has(value)) return copies.get(value);
419
420
  if (isTruncated(value)) {
420
421
  copies.set(value, "[Circular]");
421
- const copy = snapshot(value.value, copies);
422
+ const copy = snapshotInspectionValue(value.value, copies);
422
423
  copies.set(value, copy);
423
424
  return copy;
424
425
  }
@@ -429,7 +430,7 @@ function snapshot(value, copies = /* @__PURE__ */ new WeakMap()) {
429
430
  if (Array.isArray(value) && key === "length") continue;
430
431
  const descriptor = Object.getOwnPropertyDescriptor(value, key);
431
432
  if (descriptor) Object.defineProperty(copy, key, {
432
- value: "value" in descriptor ? snapshot(descriptor.value, copies) : "[Getter]",
433
+ value: "value" in descriptor ? snapshotInspectionValue(descriptor.value, copies) : "[Getter]",
433
434
  enumerable: descriptor.enumerable
434
435
  });
435
436
  }
@@ -981,4 +982,4 @@ const configureQuickJS = (variant) => {
981
982
  };
982
983
  const getQuickJSVariant = () => _activeVariant;
983
984
  //#endregion
984
- export { cloneMemoryValue as a, freezeMemoryValue as c, TERMINATION_BINDING_NAMES as d, createInspector as f, resolveInspectionBudget as h, renderMemory as i, RESERVED_RUNTIME_NAMES as l, limitInspectionOutput as m, getQuickJSVariant as n, decodeMemoryValue as o, inspect as p, Memory as r, encodeMemoryValue as s, configureQuickJS as t, RUNTIME_BINDING_NAMES as u };
985
+ export { cloneMemoryValue as a, freezeMemoryValue as c, TERMINATION_BINDING_NAMES as d, createInspector as f, resolveInspectionBudget as g, limitInspectionOutput as h, renderMemory as i, RESERVED_RUNTIME_NAMES as l, inspect as m, getQuickJSVariant as n, decodeMemoryValue as o, snapshotInspectionValue as p, Memory as r, encodeMemoryValue as s, configureQuickJS as t, RUNTIME_BINDING_NAMES as u };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -2,12 +2,15 @@ import { type InspectionPolicyLookup } from '../inspect.js';
2
2
  import { type InspectionIdentity, type Inspector } from '../inspection.js';
3
3
  import type { MemoryReport } from '../session/memory.js';
4
4
  import { type ExecutionActivity } from './execution-activity.js';
5
+ import { type ForcedInspection } from './forced-inspection.js';
5
6
  export { renderMessageDeliveries } from './execution-activity.js';
6
7
  export type ExecutionOutcome = {
7
8
  type: 'inspect';
8
9
  value: unknown;
9
10
  available: boolean;
10
11
  explicit: boolean;
12
+ forcedInspections?: readonly ForcedInspection[];
13
+ downstreamError?: unknown;
11
14
  } | {
12
15
  type: 'exit';
13
16
  name: string;
@@ -0,0 +1,13 @@
1
+ import { type InspectionPolicyLookup } from '../inspect.js';
2
+ import type { InspectionIdentity, Inspector } from '../inspection.js';
3
+ /** A successful business result that must be shown before this turn may complete. */
4
+ export type ForcedInspection = {
5
+ tool: string;
6
+ toolCallId: string;
7
+ line?: number;
8
+ reason: string;
9
+ value: unknown;
10
+ metadata?: Record<string, unknown>;
11
+ };
12
+ /** Keep attribution and content together, using the same display budgets as inspect(). */
13
+ export declare function renderForcedInspection(inspections: readonly ForcedInspection[], inspector: Inspector, identity: InspectionIdentity, maxTokens: number, policies?: InspectionPolicyLookup): string;
@@ -0,0 +1 @@
1
+ export {};
@@ -2,6 +2,7 @@ import type { ComponentRegistry, RenderedComponent } from '../chat/component.js'
2
2
  import type { Iteration } from '../context.js';
3
3
  import { ThinkSignal } from '../errors.js';
4
4
  import type { Exit } from '../exit.js';
5
+ import type { ForcedInspection } from './forced-inspection.js';
5
6
  /** A child message keeps its identity from preparation through acknowledged delivery. */
6
7
  export type PreparedMessage = {
7
8
  id: string;
@@ -33,6 +34,8 @@ export type JavaScriptApi = {
33
34
  getTerminalOutcome(): TerminalOutcome | undefined;
34
35
  /** The first host interruption closes execution before guest handlers can consume it. */
35
36
  getInterruption(): ThinkSignal | undefined;
37
+ requestInspection(inspection: ForcedInspection): void;
38
+ getForcedInspections(): readonly ForcedInspection[];
36
39
  throwIfTerminated(): void;
37
40
  track<T>(operation: () => Promise<T>): Promise<T>;
38
41
  assertOpen(): void;
@@ -0,0 +1 @@
1
+ export {};
@@ -1,6 +1,7 @@
1
1
  import { Iteration } from '../context.js';
2
2
  import { type Tool } from '../tool.js';
3
- import type { TruncationPolicy } from '../truncate.js';
3
+ import { type TruncationPolicy } from '../truncate.js';
4
+ import type { ForcedInspection } from './forced-inspection.js';
4
5
  import { ExecutionHooks } from './types.js';
5
6
  type ToolWrapperProps = {
6
7
  tool: Tool;
@@ -11,6 +12,7 @@ type ToolWrapperProps = {
11
12
  onTruncation?: (value: unknown, policy: TruncationPolicy) => void;
12
13
  onResult?: (value: unknown) => void;
13
14
  controller: AbortController;
15
+ onThink?: (inspection: ForcedInspection) => void;
14
16
  };
15
- export declare function wrapTool({ tool, object, iteration, beforeHook, afterHook, onTruncation, onResult, controller, }: ToolWrapperProps): (input: any) => Promise<any>;
17
+ export declare function wrapTool({ tool, object, iteration, beforeHook, afterHook, onTruncation, onResult, controller, onThink, }: ToolWrapperProps): (input: any, line?: number) => Promise<any>;
16
18
  export {};
@@ -126,6 +126,14 @@ export type ExecutionHooks = {
126
126
  } | void>;
127
127
  };
128
128
  type Options = Partial<Pick<Context, 'loop' | 'timeout'>> & {
129
+ /**
130
+ * Require the assistant to be the last participant who spoke before the built-in
131
+ * ListenExit can complete. Defaults to true. Successful text and component delivery
132
+ * count across iterations and executions; events and tool results do not.
133
+ * Set false for intentionally silent chat handling. Custom exits and workers
134
+ * are unaffected. Rejection is recoverable within the remaining loop budget.
135
+ */
136
+ requireChatResponse?: boolean;
129
137
  /**
130
138
  * Optional cap on the model's context window, in tokens.
131
139
  * The effective limit is `min(maxTokens, smallest configured model input limit)`.
@@ -1,4 +1,4 @@
1
- const require_errors = require("./errors-IhnTKUp7.cjs");
1
+ const require_errors = require("./errors-C6ppQUZX.cjs");
2
2
  let _bpinternal_zui = require("@bpinternal/zui");
3
3
  //#region src/schema.ts
4
4
  const INPUT_SCHEMA_OPTIONS = {
@@ -1,4 +1,4 @@
1
- import { H as isLLMzError, b as InvalidConfigurationError } from "./errors-H4JJFH3S.js";
1
+ import { U as isLLMzError, b as InvalidConfigurationError } from "./errors-Crk5P8jo.js";
2
2
  import { transforms, z } from "@bpinternal/zui";
3
3
  //#region src/schema.ts
4
4
  const INPUT_SCHEMA_OPTIONS = {
@@ -10,6 +10,8 @@ export type AssistantResponse = {
10
10
  continuation?: unknown;
11
11
  };
12
12
  export declare function normalizeInput(message: SessionInput): SessionMessage;
13
+ /** Only actual participant content counts as speech, including image/audio-only messages. */
14
+ export declare function inputSpeaker(message: SessionMessage): 'user' | 'assistant' | null;
13
15
  export declare function createAssistantMessage(response: AssistantResponse): SessionMessage;
14
16
  export declare function validateInputMessage(message: CognitiveMessage): void;
15
17
  export declare function validateMessageContent(message: CognitiveMessage): void;
@@ -23,6 +23,8 @@ export type SessionState = {
23
23
  memory: SerializedMemory;
24
24
  pendingInputs: PendingInput[];
25
25
  activeTurn: boolean;
26
+ /** Acknowledged conversation speaker, independent of retained/compacted history. Absent in older snapshots. */
27
+ lastSpeaker?: 'user' | 'assistant' | null;
26
28
  latestResultId?: string;
27
29
  compaction?: false | Omit<CompactionOptions, 'summarize'>;
28
30
  };
@@ -45,6 +45,10 @@ export declare class Session {
45
45
  get messages(): SessionMessage[];
46
46
  /** Retained conversation plus queued input, preserving event and summary roles. Returns a detached copy. */
47
47
  get transcript(): SessionInput[];
48
+ /** Last participant who spoke in the active history. Events and queued inputs do not count. */
49
+ get lastSpeaker(): 'user' | 'assistant' | null;
50
+ /** Record acknowledged text or component delivery, never generation alone. */
51
+ recordAssistantDelivery(iterationId: string): void;
48
52
  get pendingMessages(): SessionMessage[];
49
53
  get hasActiveTurn(): boolean;
50
54
  get status(): 'idle' | 'pending' | 'active';
@@ -0,0 +1 @@
1
+ export {};
@@ -1,9 +1,9 @@
1
1
  import { F as isBuffer, I as isArguments, L as isPrototype, M as isTypedArray, R as isArrayLike, U as isArray, Y as __exportAll, c as isValidIdentifier, j as baseKeys, l as isZuiSchema, n as fromJSONSchemaCompat, s as isJsonSchema, x as _getTag_default } from "./utils-BOFzb8Ok.js";
2
- import { E as InvalidToolError, H as isLLMzError, I as ToolExecutionError, L as ToolInputError, V as isCriticalError, r as VMSignal } from "./errors-H4JJFH3S.js";
2
+ import { E as InvalidToolError, H as isCriticalError, L as ToolExecutionError, R as ToolInputError, U as isLLMzError, r as VMSignal } from "./errors-Crk5P8jo.js";
3
3
  import { t as uniq } from "./uniq-DfUeSNaX.js";
4
- import { i as toModelSchema, r as schemaInput, t as parseSchemaAsync } from "./schema-Aer_W7Al.js";
5
- import { i as unwrapTruncated, n as isTruncated } from "./truncate-BSoH2-nY.js";
6
- import { t as getTypings } from "./typings-D9_aC8aq.js";
4
+ import { i as toModelSchema, r as schemaInput, t as parseSchemaAsync } from "./schema-GE4ISPCR.js";
5
+ import { i as unwrapTruncated, n as isTruncated } from "./truncate-BEKbdo3t.js";
6
+ import { t as getTypings } from "./typings-BEVDvtuk.js";
7
7
  import { transforms, z } from "@bpinternal/zui";
8
8
  //#region ../../node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/isEmpty.js
9
9
  /** `Object#toString` result references. */
@@ -1,9 +1,9 @@
1
1
  const require_utils = require("./utils-CTlsXvdj.cjs");
2
- const require_errors = require("./errors-IhnTKUp7.cjs");
2
+ const require_errors = require("./errors-C6ppQUZX.cjs");
3
3
  const require_uniq = require("./uniq-DiXgysNV.cjs");
4
- const require_schema = require("./schema-DBkjo0b7.cjs");
5
- const require_truncate = require("./truncate-nV3Mxr6-.cjs");
6
- const require_typings = require("./typings-C1ihexWE.cjs");
4
+ const require_schema = require("./schema-CXlnbb3n.cjs");
5
+ const require_truncate = require("./truncate-uomAMGPs.cjs");
6
+ const require_typings = require("./typings-BA_XxAcY.cjs");
7
7
  let _bpinternal_zui = require("@bpinternal/zui");
8
8
  //#region ../../node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/isEmpty.js
9
9
  /** `Object#toString` result references. */
@@ -1,4 +1,4 @@
1
- import { b as InvalidConfigurationError } from "./errors-H4JJFH3S.js";
1
+ import { b as InvalidConfigurationError } from "./errors-Crk5P8jo.js";
2
2
  //#region src/truncate.ts
3
3
  const TRUNCATE_SIGNATURE = "llmz.truncate.v1";
4
4
  const DEFAULT_TOOL_RESULT_MAX_TOKENS = 2e3;
@@ -1,4 +1,4 @@
1
- const require_errors = require("./errors-IhnTKUp7.cjs");
1
+ const require_errors = require("./errors-C6ppQUZX.cjs");
2
2
  //#region src/truncate.ts
3
3
  const TRUNCATE_SIGNATURE = "llmz.truncate.v1";
4
4
  const DEFAULT_TOOL_RESULT_MAX_TOKENS = 2e3;
package/dist/types.d.ts CHANGED
@@ -35,6 +35,12 @@ export declare namespace Traces {
35
35
  duration: number;
36
36
  }>;
37
37
  type ThinkSignal = TraceTemplate<'think_signal', {
38
+ tool_name?: string;
39
+ tool_call_id?: string;
40
+ object?: string;
41
+ reason?: string;
42
+ context?: unknown;
43
+ metadata?: Record<string, unknown>;
38
44
  line: number;
39
45
  }>;
40
46
  type PropertyMutation = TraceTemplate<'property', {
@@ -1,5 +1,5 @@
1
1
  const require_utils = require("./utils-CTlsXvdj.cjs");
2
- const require_errors = require("./errors-IhnTKUp7.cjs");
2
+ const require_errors = require("./errors-C6ppQUZX.cjs");
3
3
  let _bpinternal_zui = require("@bpinternal/zui");
4
4
  //#region src/typings-formatter.ts
5
5
  /**
@@ -1,5 +1,5 @@
1
1
  import { Y as __exportAll, d as toPropertyKey, i as getMultilineComment, n as fromJSONSchemaCompat } from "./utils-BOFzb8Ok.js";
2
- import { b as InvalidConfigurationError, c as CodeFormattingError } from "./errors-H4JJFH3S.js";
2
+ import { b as InvalidConfigurationError, c as CodeFormattingError } from "./errors-Crk5P8jo.js";
3
3
  import { transforms, z } from "@bpinternal/zui";
4
4
  //#region src/typings-formatter.ts
5
5
  /**
@@ -5,6 +5,7 @@ import type { Trace, VMExecutionResult } from '../types.js';
5
5
  /** Host-only lifecycle hook; symbols are not copied into the generated program's globals. */
6
6
  export declare const VM_PROGRAM_COMPLETE: unique symbol;
7
7
  export declare const VM_TERMINATION: unique symbol;
8
+ export declare const VM_CALL_SITE: unique symbol;
8
9
  export declare const VM_ON_ERROR: unique symbol;
9
10
  export type VMTermination = {
10
11
  isTerminated(): boolean;
@@ -13,6 +14,7 @@ export type VMTermination = {
13
14
  getSignal?(): VMSignal | undefined;
14
15
  };
15
16
  export type VMContext = Record<string, any> & {
17
+ [VM_CALL_SITE]?: () => number | undefined;
16
18
  [VM_ON_ERROR]?: (error: LLMzFailure) => void;
17
19
  [VM_PROGRAM_COMPLETE]?: () => void;
18
20
  [VM_TERMINATION]?: VMTermination;
@@ -1,6 +1,6 @@
1
1
  import { A as keys, B as baseAssignValue, J as __commonJSMin, V as isFunction, W as isSymbol, h as baseIteratee } from "./utils-BOFzb8Ok.js";
2
- import { B as UnknownToolError, H as isLLMzError, N as ReservedIdentifierError, o as AssignmentError, r as VMSignal, s as CodeExecutionError, t as Signals, v as InvalidCodeError } from "./errors-H4JJFH3S.js";
3
- import { a as cloneMemoryValue, d as TERMINATION_BINDING_NAMES, l as RESERVED_RUNTIME_NAMES, n as getQuickJSVariant, o as decodeMemoryValue, u as RUNTIME_BINDING_NAMES } from "./quickjs-variant-DlPi9-Sx.js";
2
+ import { P as ReservedIdentifierError, U as isLLMzError, V as UnknownToolError, o as AssignmentError, r as VMSignal, s as CodeExecutionError, t as Signals, v as InvalidCodeError } from "./errors-Crk5P8jo.js";
3
+ import { a as cloneMemoryValue, d as TERMINATION_BINDING_NAMES, l as RESERVED_RUNTIME_NAMES, n as getQuickJSVariant, o as decodeMemoryValue, u as RUNTIME_BINDING_NAMES } from "./quickjs-variant-CtuGagsb.js";
4
4
  import MagicString from "magic-string";
5
5
  import { parse } from "acorn";
6
6
  import { newQuickJSWASMModuleFromVariant, shouldInterruptAfterDeadline } from "quickjs-emscripten-core";
@@ -2994,6 +2994,7 @@ function formatError(err, lines, matches, traces, variables, lines_executed, cod
2994
2994
  /** Host-only lifecycle hook; symbols are not copied into the generated program's globals. */
2995
2995
  const VM_PROGRAM_COMPLETE = Symbol("llmz.programComplete");
2996
2996
  const VM_TERMINATION = Symbol("llmz.termination");
2997
+ const VM_CALL_SITE = Symbol("llmz.callSite");
2997
2998
  const VM_ON_ERROR = Symbol("llmz.onError");
2998
2999
  //#endregion
2999
3000
  //#region src/vm/instrument.ts
@@ -3121,6 +3122,16 @@ var NodeDriver = class {
3121
3122
  async execute(ctx) {
3122
3123
  const { transformed, consumer, context, traces, recordTrace, code, lines_executed, variables } = ctx;
3123
3124
  const state = instrumentContext(context, transformed, recordTrace, variables, lines_executed, consumer, findUserCodeStartLine(transformed), ctx.memoryNames);
3125
+ context[VM_CALL_SITE] = () => {
3126
+ var _Error$stack;
3127
+ const frame = (_Error$stack = (/* @__PURE__ */ new Error()).stack) === null || _Error$stack === void 0 ? void 0 : _Error$stack.match(/<anonymous>:(\d+):(\d+)/);
3128
+ if (!frame) return;
3129
+ const position = consumer.originalPositionFor({
3130
+ line: Number(frame[1]) - 1,
3131
+ column: Number(frame[2])
3132
+ });
3133
+ return position.line ? Math.max(1, position.line - 3) : void 0;
3134
+ };
3124
3135
  const AsyncFunction = async function() {}.constructor;
3125
3136
  return finalizeMemoryCapture(await (async () => {
3126
3137
  const descriptors = Object.getOwnPropertyDescriptors(context);
@@ -3273,6 +3284,20 @@ var QuickJSDriver = class {
3273
3284
  const disposeIfNeeded = (handle) => {
3274
3285
  if (handle !== vm.true && handle !== vm.false && handle !== vm.null && handle !== vm.undefined) handle.dispose();
3275
3286
  };
3287
+ context[VM_CALL_SITE] = () => {
3288
+ const stack = vm.evalCode("new Error().stack");
3289
+ if ("error" in stack) {
3290
+ var _stack$error;
3291
+ (_stack$error = stack.error) === null || _stack$error === void 0 || _stack$error.dispose();
3292
+ return;
3293
+ }
3294
+ try {
3295
+ const frame = vm.getString(stack.value).match(/<quickjs>:(\d+)/);
3296
+ return frame ? Math.max(1, Number(frame[1]) - 9 - userCodeStartLine + 1) : void 0;
3297
+ } finally {
3298
+ stack.value.dispose();
3299
+ }
3300
+ };
3276
3301
  const bridgeFunction = (fn, _fnName = "anonymous") => {
3277
3302
  return (...argHandles) => {
3278
3303
  const args = argHandles.map((h) => vm.dump(h));
@@ -3956,4 +3981,4 @@ async function runAsyncFunction(context, code, traces = [], signal = null, timeo
3956
3981
  });
3957
3982
  }
3958
3983
  //#endregion
3959
- export { compile as a, VM_TERMINATION as i, VM_ON_ERROR as n, VM_PROGRAM_COMPLETE as r, runAsyncFunction, withMissingMember as t };
3984
+ export { VM_TERMINATION as a, VM_PROGRAM_COMPLETE as i, VM_CALL_SITE as n, compile as o, VM_ON_ERROR as r, runAsyncFunction, withMissingMember as t };
@@ -1,6 +1,6 @@
1
1
  const require_utils = require("./utils-CTlsXvdj.cjs");
2
- const require_errors = require("./errors-IhnTKUp7.cjs");
3
- const require_quickjs_variant = require("./quickjs-variant-DJwYDSsb.cjs");
2
+ const require_errors = require("./errors-C6ppQUZX.cjs");
3
+ const require_quickjs_variant = require("./quickjs-variant-21IO97PF.cjs");
4
4
  let magic_string = require("magic-string");
5
5
  magic_string = require_utils.__toESM(magic_string, 1);
6
6
  let acorn = require("acorn");
@@ -2995,6 +2995,7 @@ function formatError(err, lines, matches, traces, variables, lines_executed, cod
2995
2995
  /** Host-only lifecycle hook; symbols are not copied into the generated program's globals. */
2996
2996
  const VM_PROGRAM_COMPLETE = Symbol("llmz.programComplete");
2997
2997
  const VM_TERMINATION = Symbol("llmz.termination");
2998
+ const VM_CALL_SITE = Symbol("llmz.callSite");
2998
2999
  const VM_ON_ERROR = Symbol("llmz.onError");
2999
3000
  //#endregion
3000
3001
  //#region src/vm/instrument.ts
@@ -3122,6 +3123,16 @@ var NodeDriver = class {
3122
3123
  async execute(ctx) {
3123
3124
  const { transformed, consumer, context, traces, recordTrace, code, lines_executed, variables } = ctx;
3124
3125
  const state = instrumentContext(context, transformed, recordTrace, variables, lines_executed, consumer, findUserCodeStartLine(transformed), ctx.memoryNames);
3126
+ context[VM_CALL_SITE] = () => {
3127
+ var _Error$stack;
3128
+ const frame = (_Error$stack = (/* @__PURE__ */ new Error()).stack) === null || _Error$stack === void 0 ? void 0 : _Error$stack.match(/<anonymous>:(\d+):(\d+)/);
3129
+ if (!frame) return;
3130
+ const position = consumer.originalPositionFor({
3131
+ line: Number(frame[1]) - 1,
3132
+ column: Number(frame[2])
3133
+ });
3134
+ return position.line ? Math.max(1, position.line - 3) : void 0;
3135
+ };
3125
3136
  const AsyncFunction = async function() {}.constructor;
3126
3137
  return finalizeMemoryCapture(await (async () => {
3127
3138
  const descriptors = Object.getOwnPropertyDescriptors(context);
@@ -3274,6 +3285,20 @@ var QuickJSDriver = class {
3274
3285
  const disposeIfNeeded = (handle) => {
3275
3286
  if (handle !== vm.true && handle !== vm.false && handle !== vm.null && handle !== vm.undefined) handle.dispose();
3276
3287
  };
3288
+ context[VM_CALL_SITE] = () => {
3289
+ const stack = vm.evalCode("new Error().stack");
3290
+ if ("error" in stack) {
3291
+ var _stack$error;
3292
+ (_stack$error = stack.error) === null || _stack$error === void 0 || _stack$error.dispose();
3293
+ return;
3294
+ }
3295
+ try {
3296
+ const frame = vm.getString(stack.value).match(/<quickjs>:(\d+)/);
3297
+ return frame ? Math.max(1, Number(frame[1]) - 9 - userCodeStartLine + 1) : void 0;
3298
+ } finally {
3299
+ stack.value.dispose();
3300
+ }
3301
+ };
3277
3302
  const bridgeFunction = (fn, _fnName = "anonymous") => {
3278
3303
  return (...argHandles) => {
3279
3304
  const args = argHandles.map((h) => vm.dump(h));
@@ -3957,6 +3982,7 @@ async function runAsyncFunction(context, code, traces = [], signal = null, timeo
3957
3982
  });
3958
3983
  }
3959
3984
  //#endregion
3985
+ exports.VM_CALL_SITE = VM_CALL_SITE;
3960
3986
  exports.VM_ON_ERROR = VM_ON_ERROR;
3961
3987
  exports.VM_PROGRAM_COMPLETE = VM_PROGRAM_COMPLETE;
3962
3988
  exports.VM_TERMINATION = VM_TERMINATION;
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "llmz",
3
3
  "type": "module",
4
4
  "description": "LLMz - An LLM-native Typescript VM built on top of Zui",
5
- "version": "1.0.1",
5
+ "version": "1.0.2",
6
6
  "files": [
7
7
  "dist",
8
8
  "DOCS.md",