llmist 17.6.0 → 18.1.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.d.cts CHANGED
@@ -1015,6 +1015,13 @@ interface CreateGadgetConfig<TSchema extends ZodType> {
1015
1015
  * See `AbstractGadget.stickyResult` for the full contract.
1016
1016
  */
1017
1017
  stickyResult?: boolean;
1018
+ /**
1019
+ * If true, the consuming agent loop should treat this gadget as a per-
1020
+ * iteration barrier — when it appears in a tool batch, no sibling gadgets
1021
+ * in the same batch execute. See `AbstractGadget.iterationBarrier` for the
1022
+ * full contract (enforcement is consumer-side; this flag is declarative).
1023
+ */
1024
+ iterationBarrier?: boolean;
1018
1025
  }
1019
1026
  /**
1020
1027
  * Creates a gadget from a function (simpler than class-based approach).
@@ -1235,6 +1242,7 @@ declare function Gadget<TSchema extends ZodType>(config: GadgetConfig<TSchema>):
1235
1242
  */
1236
1243
  execute(params: Record<string, unknown>, ctx?: ExecutionContext): GadgetExecuteReturn | Promise<GadgetExecuteReturn>;
1237
1244
  stickyResult?: boolean;
1245
+ iterationBarrier?: boolean;
1238
1246
  throwIfAborted(ctx?: ExecutionContext): void;
1239
1247
  onAbort(ctx: ExecutionContext | undefined, cleanup: () => void | Promise<void>): void;
1240
1248
  createLinkedAbortController(ctx?: ExecutionContext): AbortController;
@@ -4162,6 +4170,27 @@ declare abstract class AbstractGadget {
4162
4170
  * Has no effect on agents that don't enable compaction.
4163
4171
  */
4164
4172
  stickyResult?: boolean;
4173
+ /**
4174
+ * Hints to the consuming agent loop that when this gadget appears in an
4175
+ * LLM iteration's tool batch, no other gadget in the same batch should
4176
+ * execute. Sibling tool calls in the same iteration are expected to be
4177
+ * skipped (not executed) with a synthetic result; the next LLM iteration
4178
+ * gets only this gadget's output back, and must re-plan from there.
4179
+ *
4180
+ * llmist exposes this as declarative metadata only — enforcement is the
4181
+ * consuming agent loop's responsibility (the loop already owns the
4182
+ * stream-event consumption and the `beforeGadgetExecution` controller, so
4183
+ * it can buffer per-iteration calls, decide barrier-status at
4184
+ * `llm_response_end`, and skip non-barrier siblings via the standard
4185
+ * skip-with-synthetic-result mechanism). See `LoadSkill` for the canonical
4186
+ * use case: the agent loop should freeze sibling tool execution so the
4187
+ * LLM sees only the loaded skill body before issuing dependent work.
4188
+ *
4189
+ * Orthogonal to `stickyResult` (which affects compaction) and `exclusive`
4190
+ * (which queues the marked gadget alone, AFTER others — opposite of this
4191
+ * flag's "freeze the others" semantic).
4192
+ */
4193
+ iterationBarrier?: boolean;
4165
4194
  /**
4166
4195
  * Execute the gadget with the given parameters.
4167
4196
  * Can be synchronous or asynchronous.
@@ -10550,8 +10579,8 @@ declare function resolveInstructions(instructions: string, options?: {
10550
10579
  * LoadSkill meta-gadget — bridges the skill system into the gadget execution pipeline.
10551
10580
  *
10552
10581
  * When skills are registered with an agent, this gadget is auto-created and added
10553
- * to the gadget registry. The LLM can invoke it like any other gadget, and the
10554
- * skill's instructions are returned as the gadget result.
10582
+ * to the gadget registry. The LLM invokes it with an array of skill names; each
10583
+ * skill's resolved instructions are composed into a single multi-section result.
10555
10584
  *
10556
10585
  * This approach requires zero changes to the stream processor or agent loop.
10557
10586
  *
@@ -10563,8 +10592,16 @@ declare const LOAD_SKILL_GADGET_NAME = "LoadSkill";
10563
10592
  /**
10564
10593
  * Create the LoadSkill meta-gadget from a skill registry.
10565
10594
  *
10566
- * The gadget description includes a summary of all available skills,
10567
- * so the LLM knows what skills exist and when to load them.
10595
+ * The gadget's tool description includes a summary of all available skills, so
10596
+ * the LLM knows what skills exist and when to load them. Setting
10597
+ * `iterationBarrier: true` and `stickyResult: true` are the two declarative
10598
+ * flags every LoadSkill should carry:
10599
+ *
10600
+ * - `iterationBarrier`: tells the consuming agent loop to skip every sibling
10601
+ * tool call in the same iteration's batch. The next LLM iteration sees
10602
+ * only the loaded skill bodies and re-plans from there.
10603
+ * - `stickyResult`: tells the compaction layer to preserve the result past
10604
+ * truncation, so the agent doesn't re-load the same skill ten turns later.
10568
10605
  */
10569
10606
  declare function createLoadSkillGadget(registry: SkillRegistry): AbstractGadget;
10570
10607
 
package/dist/index.d.ts CHANGED
@@ -1015,6 +1015,13 @@ interface CreateGadgetConfig<TSchema extends ZodType> {
1015
1015
  * See `AbstractGadget.stickyResult` for the full contract.
1016
1016
  */
1017
1017
  stickyResult?: boolean;
1018
+ /**
1019
+ * If true, the consuming agent loop should treat this gadget as a per-
1020
+ * iteration barrier — when it appears in a tool batch, no sibling gadgets
1021
+ * in the same batch execute. See `AbstractGadget.iterationBarrier` for the
1022
+ * full contract (enforcement is consumer-side; this flag is declarative).
1023
+ */
1024
+ iterationBarrier?: boolean;
1018
1025
  }
1019
1026
  /**
1020
1027
  * Creates a gadget from a function (simpler than class-based approach).
@@ -1235,6 +1242,7 @@ declare function Gadget<TSchema extends ZodType>(config: GadgetConfig<TSchema>):
1235
1242
  */
1236
1243
  execute(params: Record<string, unknown>, ctx?: ExecutionContext): GadgetExecuteReturn | Promise<GadgetExecuteReturn>;
1237
1244
  stickyResult?: boolean;
1245
+ iterationBarrier?: boolean;
1238
1246
  throwIfAborted(ctx?: ExecutionContext): void;
1239
1247
  onAbort(ctx: ExecutionContext | undefined, cleanup: () => void | Promise<void>): void;
1240
1248
  createLinkedAbortController(ctx?: ExecutionContext): AbortController;
@@ -4162,6 +4170,27 @@ declare abstract class AbstractGadget {
4162
4170
  * Has no effect on agents that don't enable compaction.
4163
4171
  */
4164
4172
  stickyResult?: boolean;
4173
+ /**
4174
+ * Hints to the consuming agent loop that when this gadget appears in an
4175
+ * LLM iteration's tool batch, no other gadget in the same batch should
4176
+ * execute. Sibling tool calls in the same iteration are expected to be
4177
+ * skipped (not executed) with a synthetic result; the next LLM iteration
4178
+ * gets only this gadget's output back, and must re-plan from there.
4179
+ *
4180
+ * llmist exposes this as declarative metadata only — enforcement is the
4181
+ * consuming agent loop's responsibility (the loop already owns the
4182
+ * stream-event consumption and the `beforeGadgetExecution` controller, so
4183
+ * it can buffer per-iteration calls, decide barrier-status at
4184
+ * `llm_response_end`, and skip non-barrier siblings via the standard
4185
+ * skip-with-synthetic-result mechanism). See `LoadSkill` for the canonical
4186
+ * use case: the agent loop should freeze sibling tool execution so the
4187
+ * LLM sees only the loaded skill body before issuing dependent work.
4188
+ *
4189
+ * Orthogonal to `stickyResult` (which affects compaction) and `exclusive`
4190
+ * (which queues the marked gadget alone, AFTER others — opposite of this
4191
+ * flag's "freeze the others" semantic).
4192
+ */
4193
+ iterationBarrier?: boolean;
4165
4194
  /**
4166
4195
  * Execute the gadget with the given parameters.
4167
4196
  * Can be synchronous or asynchronous.
@@ -10550,8 +10579,8 @@ declare function resolveInstructions(instructions: string, options?: {
10550
10579
  * LoadSkill meta-gadget — bridges the skill system into the gadget execution pipeline.
10551
10580
  *
10552
10581
  * When skills are registered with an agent, this gadget is auto-created and added
10553
- * to the gadget registry. The LLM can invoke it like any other gadget, and the
10554
- * skill's instructions are returned as the gadget result.
10582
+ * to the gadget registry. The LLM invokes it with an array of skill names; each
10583
+ * skill's resolved instructions are composed into a single multi-section result.
10555
10584
  *
10556
10585
  * This approach requires zero changes to the stream processor or agent loop.
10557
10586
  *
@@ -10563,8 +10592,16 @@ declare const LOAD_SKILL_GADGET_NAME = "LoadSkill";
10563
10592
  /**
10564
10593
  * Create the LoadSkill meta-gadget from a skill registry.
10565
10594
  *
10566
- * The gadget description includes a summary of all available skills,
10567
- * so the LLM knows what skills exist and when to load them.
10595
+ * The gadget's tool description includes a summary of all available skills, so
10596
+ * the LLM knows what skills exist and when to load them. Setting
10597
+ * `iterationBarrier: true` and `stickyResult: true` are the two declarative
10598
+ * flags every LoadSkill should carry:
10599
+ *
10600
+ * - `iterationBarrier`: tells the consuming agent loop to skip every sibling
10601
+ * tool call in the same iteration's batch. The next LLM iteration sees
10602
+ * only the loaded skill bodies and re-plans from there.
10603
+ * - `stickyResult`: tells the compaction layer to preserve the result past
10604
+ * truncation, so the agent doesn't re-load the same skill ten turns later.
10568
10605
  */
10569
10606
  declare function createLoadSkillGadget(registry: SkillRegistry): AbstractGadget;
10570
10607
 
package/dist/index.js CHANGED
@@ -81,7 +81,7 @@ import {
81
81
  toBase64,
82
82
  validateGadgetSchema,
83
83
  withErrorHandling
84
- } from "./chunk-EXFIXEGW.js";
84
+ } from "./chunk-DNB4DPM4.js";
85
85
 
86
86
  // src/core/execution-tree-aggregator.ts
87
87
  var ExecutionTreeAggregator;
@@ -4125,37 +4125,70 @@ var init_activation = __esm({
4125
4125
 
4126
4126
  // src/skills/load-skill-gadget.ts
4127
4127
  import { z as z2 } from "zod";
4128
+ function composeSkillSections(sections) {
4129
+ return sections.map(({ name, body }) => `==== ${name} ====
4130
+ ${body}`).join("\n\n");
4131
+ }
4128
4132
  function createLoadSkillGadget(registry) {
4129
4133
  const summaries = registry.getMetadataSummaries();
4130
4134
  const skillNames = registry.getModelInvocable().map((s) => s.name);
4131
4135
  const description = [
4132
- "Load a skill's specialized instructions into context for a task.",
4136
+ "Load one or more skill bodies into context. Pass `skills` as a JSON",
4137
+ "array of skill-name strings \u2014 NOT a string of a JSON-encoded array.",
4138
+ 'Right: `{"skills": ["alpha"]}` or `{"skills": ["alpha", "beta"]}`.',
4139
+ 'Wrong: `{"skills": "[\\"alpha\\"]"}` (the value is a string, not an array).',
4140
+ "**This gadget is an iteration barrier \u2014 no other gadgets in the same",
4141
+ "tool batch will execute, so load every skill you know you'll need in",
4142
+ "one shot.** The loaded bodies are sticky and survive context compaction.",
4143
+ "",
4133
4144
  "Available skills:",
4134
4145
  summaries
4135
4146
  ].join("\n");
4147
+ const examples = [];
4148
+ if (skillNames.length >= 1) {
4149
+ examples.push({
4150
+ params: { skills: [skillNames[0]] },
4151
+ comment: "Single-skill call \u2014 `skills` is still an array of length 1."
4152
+ });
4153
+ }
4154
+ if (skillNames.length >= 2) {
4155
+ examples.push({
4156
+ params: { skills: [skillNames[0], skillNames[1]] },
4157
+ comment: "Multi-skill call \u2014 load several skills in one shot to avoid round-trips."
4158
+ });
4159
+ }
4136
4160
  return createGadget({
4137
4161
  name: LOAD_SKILL_GADGET_NAME,
4138
4162
  description,
4139
4163
  schema: z2.object({
4140
- skill: z2.enum(skillNames).describe("Name of the skill to load"),
4141
- arguments: z2.string().optional().describe("Arguments for the skill (e.g., a filename, issue number, or search query)")
4164
+ skills: z2.array(z2.enum(skillNames)).min(1).describe(
4165
+ "One or more skill names to load in this single call. Prefer loading everything you know you'll need at once \u2014 this gadget is an iteration barrier, so sibling tool calls in the same batch will not execute."
4166
+ ),
4167
+ arguments: z2.string().optional().describe(
4168
+ "Optional argument string substituted into each skill's $ARGUMENTS placeholders. Applies to every skill in the batch. To pass different arguments to different skills, issue separate LoadSkill calls."
4169
+ )
4142
4170
  }),
4143
- // LoadSkill exists specifically so the agent can keep a skill body in
4144
- // context for the rest of the task — marking its results sticky lets the
4145
- // compaction layer preserve them past truncation. Without this the agent
4146
- // gets the skill body once, compaction drops it, and the next iteration
4147
- // falls back to stale training knowledge of whatever the skill covered.
4148
4171
  stickyResult: true,
4149
- execute: async ({ skill: skillName, arguments: args }) => {
4150
- const skill = registry.get(skillName);
4151
- if (!skill) {
4152
- return `Unknown skill: "${skillName}". Available skills: ${skillNames.join(", ")}`;
4153
- }
4154
- const activation = await skill.activate({
4155
- arguments: args,
4156
- cwd: process.cwd()
4157
- });
4158
- return activation.resolvedInstructions;
4172
+ iterationBarrier: true,
4173
+ examples,
4174
+ execute: async ({ skills: skillNamesArg, arguments: args }) => {
4175
+ const sections = [];
4176
+ for (const skillName of skillNamesArg) {
4177
+ const skill = registry.get(skillName);
4178
+ if (!skill) {
4179
+ sections.push({
4180
+ name: skillName,
4181
+ body: `Unknown skill: "${skillName}". Available skills: ${skillNames.join(", ")}`
4182
+ });
4183
+ continue;
4184
+ }
4185
+ const activation = await skill.activate({
4186
+ arguments: args,
4187
+ cwd: process.cwd()
4188
+ });
4189
+ sections.push({ name: skillName, body: activation.resolvedInstructions });
4190
+ }
4191
+ return composeSkillSections(sections);
4159
4192
  }
4160
4193
  });
4161
4194
  }
@@ -15722,7 +15755,7 @@ var init_agent = __esm({
15722
15755
  }
15723
15756
  const unsubscribeBridge = bridgeTreeToHooks(this.tree, this.hooks, this.logger);
15724
15757
  if (this.mcpSpecs.length > 0) {
15725
- const { setupMcpServers } = await import("./runtime-LKTAP7X6.js");
15758
+ const { setupMcpServers } = await import("./runtime-KB7US2FQ.js");
15726
15759
  this.mcpLifecycle = await setupMcpServers({
15727
15760
  specs: this.mcpSpecs,
15728
15761
  registry: this.registry,