@leanandmean/coding-agent 0.74.1-scramjet.6 → 0.74.1-scramjet.8

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.
@@ -582,6 +582,14 @@ export class AgentSession {
582
582
  const tools = [];
583
583
  const validToolNames = [];
584
584
  for (const name of toolNames) {
585
+ // SCRAMJET-DIVERGENCE: harness-only tools are never placed in the provider-visible tool
586
+ // set, even when explicitly requested (#244). This is the single choke point for
587
+ // `agent.state.tools`, so filtering here structurally guarantees a harness-only tool can
588
+ // never masquerade as a model-callable one — while it stays resolvable in `_toolRegistry`
589
+ // for `invokeHarnessTool`.
590
+ if (this._toolDefinitions.get(name)?.definition.activation === "harness-only") {
591
+ continue;
592
+ }
585
593
  const tool = this._toolRegistry.get(name);
586
594
  if (tool) {
587
595
  tools.push(tool);
@@ -592,6 +600,26 @@ export class AgentSession {
592
600
  // Rebuild base system prompt with new tool set
593
601
  this._rebuildSystemPrompt(validToolNames);
594
602
  }
603
+ // SCRAMJET-DIVERGENCE: harness-tool invocation (#244).
604
+ /**
605
+ * Execute a registered tool as a harness-originated call (not requested by the model).
606
+ *
607
+ * Resolves the wrapped tool from the full registry — including `"harness-only"` tools that are
608
+ * never provider-visible — so its `execute` still receives the extension context and its
609
+ * `tool_call`/`tool_result` hooks still fire. Delegates to {@link Agent.runHarnessTool}, which
610
+ * runs the call through the real prepare/execute/finalize pipeline: identical live
611
+ * `tool_execution_*`/message events, persisted session entries, and extension hooks, but no
612
+ * run/turn framing. The idle-vs-mid-run branch lives in `runHarnessTool` (keyed on the agent's
613
+ * active run, which tracks `isStreaming`): idle calls execute immediately, mid-run calls queue
614
+ * and drain before the next intra-run LLM call.
615
+ */
616
+ async invokeHarnessTool(name, args, options) {
617
+ const tool = this._toolRegistry.get(name);
618
+ if (!tool) {
619
+ throw new Error(`Cannot invoke harness tool "${name}": no tool with that name is registered.`);
620
+ }
621
+ await this.agent.runHarnessTool(tool, args, options);
622
+ }
595
623
  /** Whether compaction or branch summarization is currently running */
596
624
  get isCompacting() {
597
625
  return (this._autoCompactionAbortController !== undefined ||
@@ -1773,6 +1801,8 @@ export class AgentSession {
1773
1801
  getActiveTools: () => this.getActiveToolNames(),
1774
1802
  getAllTools: () => this.getAllTools(),
1775
1803
  setActiveTools: (toolNames) => this.setActiveToolsByName(toolNames),
1804
+ // SCRAMJET-DIVERGENCE: harness-tool invocation (#244).
1805
+ invokeHarnessTool: (name, args, options) => this.invokeHarnessTool(name, args, options),
1776
1806
  refreshTools: () => this._refreshToolRegistry(),
1777
1807
  getCommands,
1778
1808
  setModel: async (model) => {