la-machina-engine 0.16.0 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -3986,6 +3986,29 @@ var RunContext = class {
3986
3986
  });
3987
3987
  this.episodes?.logTurn(this.turnCount, "user", text2);
3988
3988
  }
3989
+ /**
3990
+ * Plan 051 — seed a prior chat turn into the run's message stack
3991
+ * before the current task. Writes a normal `user` / `assistant`
3992
+ * transcript entry so resume + inspect + compaction see the same
3993
+ * conversation the model saw, but intentionally:
3994
+ * - does NOT increment `turnCount` (a turn is a model response
3995
+ * this run produced, not historical context)
3996
+ * - does NOT log to `episodes` (avoid cross-run memory noise)
3997
+ *
3998
+ * Caller is responsible for validating role + content shape; this
3999
+ * helper just persists what it's given.
4000
+ */
4001
+ async seedInitialMessage(role, text2) {
4002
+ const content = [{ type: "text", text: text2 }];
4003
+ this.messages.push({ role, content });
4004
+ await this.writeEntry({
4005
+ type: role,
4006
+ uuid: this.nextUuid(),
4007
+ parentUuid: this.lastUuid,
4008
+ ts: this.now(),
4009
+ message: { role, content }
4010
+ });
4011
+ }
3989
4012
  async addAssistantMessage(content) {
3990
4013
  this.messages.push({ role: "assistant", content });
3991
4014
  await this.writeEntry({
@@ -8440,6 +8463,9 @@ ${lessons}`);
8440
8463
  sections.push(options.base);
8441
8464
  }
8442
8465
  }
8466
+ if (options.platformAppend !== void 0 && options.platformAppend.length > 0) {
8467
+ sections.push(options.platformAppend);
8468
+ }
8443
8469
  return sections.join("\n\n");
8444
8470
  }
8445
8471
  async function collectSkills(storage, skillsDir) {
@@ -10876,6 +10902,24 @@ function scrubRunOptions(opts) {
10876
10902
  }
10877
10903
  if (opts.compaction !== void 0) out.compaction = opts.compaction;
10878
10904
  if (opts.context !== void 0) out.context = { ...opts.context };
10905
+ if (opts.initialMessages !== void 0 && Array.isArray(opts.initialMessages)) {
10906
+ const roles = [];
10907
+ let totalChars = 0;
10908
+ for (const m of opts.initialMessages) {
10909
+ if (m === null || typeof m !== "object") continue;
10910
+ const role = m.role;
10911
+ const content = m.content;
10912
+ if (role !== "user" && role !== "assistant") continue;
10913
+ if (typeof content !== "string") continue;
10914
+ roles.push(role);
10915
+ totalChars += content.length;
10916
+ }
10917
+ out.initialMessages = {
10918
+ count: roles.length,
10919
+ roles,
10920
+ totalChars
10921
+ };
10922
+ }
10879
10923
  return out;
10880
10924
  }
10881
10925
  function serializeOutputSchema(schema) {
@@ -10951,6 +10995,14 @@ function rebuildMessagesFromEntries(entries) {
10951
10995
  return messages;
10952
10996
  }
10953
10997
 
10998
+ // src/engine/types.ts
10999
+ init_cjs_shims();
11000
+ var INITIAL_MESSAGES_LIMITS = {
11001
+ maxMessages: 100,
11002
+ maxTotalChars: 32e3,
11003
+ maxCharsPerMessage: 8e3
11004
+ };
11005
+
10954
11006
  // src/engine/response.ts
10955
11007
  init_cjs_shims();
10956
11008
  function toResponse(result, extra) {
@@ -11351,6 +11403,7 @@ var Engine = class {
11351
11403
  let systemPrompt = await buildSystemPrompt({
11352
11404
  ...coordinatorBase !== void 0 ? { base: coordinatorBase } : {},
11353
11405
  ...options.systemPromptBase !== void 0 ? { staticBase: options.systemPromptBase } : {},
11406
+ ...options.systemPromptAppend !== void 0 && options.systemPromptAppend.length > 0 ? { platformAppend: options.systemPromptAppend } : {},
11354
11407
  memory,
11355
11408
  storage,
11356
11409
  // When an override was supplied, skip the legacy disk-scan path.
@@ -11452,6 +11505,23 @@ var Engine = class {
11452
11505
  const runTimeout = this.startRunTimeout();
11453
11506
  try {
11454
11507
  await writer.setStatus("running");
11508
+ if (options.initialMessages !== void 0) {
11509
+ const validation = validateInitialMessages(options.initialMessages);
11510
+ if (!validation.ok) {
11511
+ await writer.setStatus("failed");
11512
+ return {
11513
+ runId,
11514
+ status: "failed",
11515
+ data: null,
11516
+ meta: { nodeId: options.nodeId, durationMs: Date.now() - startTime },
11517
+ errors: [{ code: "ERR_INVALID_INITIAL_MESSAGES", message: validation.message }],
11518
+ timestamp: Date.now()
11519
+ };
11520
+ }
11521
+ for (const m of validation.messages) {
11522
+ await ctx.seedInitialMessage(m.role, m.content);
11523
+ }
11524
+ }
11455
11525
  await dispatchHooks(this.config.hooks.preRun, {
11456
11526
  runId,
11457
11527
  nodeId: options.nodeId,
@@ -11555,6 +11625,7 @@ var Engine = class {
11555
11625
  let systemPrompt = await buildSystemPrompt({
11556
11626
  ...coordinatorBase !== void 0 ? { base: coordinatorBase } : {},
11557
11627
  ...options.systemPromptBase !== void 0 ? { staticBase: options.systemPromptBase } : {},
11628
+ ...options.systemPromptAppend !== void 0 && options.systemPromptAppend.length > 0 ? { platformAppend: options.systemPromptAppend } : {},
11558
11629
  memory,
11559
11630
  storage,
11560
11631
  // When an override was supplied, skip the legacy disk-scan path.
@@ -12957,6 +13028,60 @@ function buildToolRegistry(options) {
12957
13028
  }
12958
13029
  return registry;
12959
13030
  }
13031
+ function validateInitialMessages(raw) {
13032
+ if (!Array.isArray(raw)) {
13033
+ return { ok: false, message: "initialMessages must be an array" };
13034
+ }
13035
+ const { maxMessages, maxTotalChars, maxCharsPerMessage } = INITIAL_MESSAGES_LIMITS;
13036
+ if (raw.length > maxMessages) {
13037
+ return {
13038
+ ok: false,
13039
+ message: `initialMessages exceeds max of ${String(maxMessages)} messages (got ${String(raw.length)})`
13040
+ };
13041
+ }
13042
+ const out = [];
13043
+ let totalChars = 0;
13044
+ for (let i = 0; i < raw.length; i++) {
13045
+ const m = raw[i];
13046
+ if (m === null || typeof m !== "object") {
13047
+ return { ok: false, message: `initialMessages[${String(i)}] must be an object` };
13048
+ }
13049
+ if (m.role !== "user" && m.role !== "assistant") {
13050
+ return {
13051
+ ok: false,
13052
+ message: `initialMessages[${String(i)}].role must be 'user' or 'assistant'`
13053
+ };
13054
+ }
13055
+ if (typeof m.content !== "string") {
13056
+ return {
13057
+ ok: false,
13058
+ message: `initialMessages[${String(i)}].content must be a string`
13059
+ };
13060
+ }
13061
+ const trimmed = m.content.trim();
13062
+ if (trimmed.length === 0) {
13063
+ return {
13064
+ ok: false,
13065
+ message: `initialMessages[${String(i)}].content must not be empty`
13066
+ };
13067
+ }
13068
+ if (trimmed.length > maxCharsPerMessage) {
13069
+ return {
13070
+ ok: false,
13071
+ message: `initialMessages[${String(i)}].content exceeds ${String(maxCharsPerMessage)} chars`
13072
+ };
13073
+ }
13074
+ totalChars += trimmed.length;
13075
+ if (totalChars > maxTotalChars) {
13076
+ return {
13077
+ ok: false,
13078
+ message: `initialMessages total content exceeds ${String(maxTotalChars)} chars`
13079
+ };
13080
+ }
13081
+ out.push({ role: m.role, content: trimmed });
13082
+ }
13083
+ return { ok: true, messages: out };
13084
+ }
12960
13085
 
12961
13086
  // src/index.ts
12962
13087
  init_contract();