Skip to content

feat(runtime): implement turn-scoped tool_search activation #3752

Description

@likun666661

Problem

Maka currently controls provider-visible tools through overlapping mechanisms: economy/full mode, predefined load_tools groups, MAKA_DISABLE_DEFERRED_TOOLS, historical connector aliases, and cross-turn ledger seeding. The model-facing contract is difficult to explain, and low-frequency tool schemas can add substantial context cost before the model needs them.

Discussion #3621 reached agreement on the first implementation slice after working through binding authority, search-space discovery, activation timing, schema visibility, and the tradeoff between automatic activation and a separate confirmation command.

Related tracker: #1382. This issue implements the provider-independent first slice agreed in #3621 rather than the original provider-native-first and cross-turn persistence assumptions in #1382.

Desired outcome

Provide one Maka-owned, provider-independent tool_search contract:

tool_search(query, limit?)
-> bounded top-k matches
-> successful results become active immediately
-> complete schemas become visible on the next provider step
-> activation is monotonic within the current turn
-> activation is cleared when the turn completes

The search ranker selects which bounded schemas become visible. The model selects which visible tool to execute. Runtime binding and execution checks remain authoritative.

Agreed semantics

Authority and visibility

  • The tools actually bound to the current run are the capability ceiling.
  • Search metadata and the initial inventory are derived from those bindings.
  • A tool name in the inventory is discoverable metadata, not callable visibility.
  • A tool is visible for a provider step only when its complete callable definition is present in that request.
  • Search never binds a new executable tool and never escapes boundTools.
  • Tool visibility does not replace permission or execution-time validation.

Initial discovery surface

The model receives a lightweight inventory of deferred tools before searching:

group:
- canonical_tool_name
- canonical_tool_name

The inventory contains group names and canonical tool names only. Direct tools already have complete definitions and are not repeated. Dynamic client tools are grouped by their derived source metadata.

Search contract

Initial interface:

tool_search({query: string,limit?: number,})

The first index should use canonical name and description metadata derived from current bound deferred tools. Exact names may affect ranking but must not change the operation semantics: every successful search uniformly activates the matches it returns.

The ordinary model-facing result stays thin:

{
"activated": ["browser_snapshot", "browser_click"]
}

Complete schemas must not be duplicated in the ordinary tool result. They enter the next request through the normal provider tool projection.

Repeated and parallel searches

  • Successful searches add their matches to the current turn active set.
  • Repeated tools are deduplicated.
  • Parallel search results in one provider step are unioned.
  • The model may continue searching and expanding the active set.
  • There is no turn-wide activation budget or unload operation.
  • Each individual search remains bounded by result count and schema bytes.
  • The binding ceiling is the final upper bound.

Step boundary

A search result cannot rewrite the request in which the search call was emitted.

For a search completed during provider step n:

step n:
tool_search executes and updates future active tools
step n + 1:
matching complete schemas enter the provider request

A parallel hidden-tool call in the same step must still fail the step-start availability guard:

tool_search("browser")
browser_click(...)

The search may affect only the next provider request.

Runtime ownership

The correct owner of mutable activation state is the existing per-send()TurnScope in packages/runtime/src/ai-sdk-backend.ts.

classTurnScope{readonlyactiveTools=newMap<string,MakaTool>()// existing per-turn state}

This matches the current lifecycle:

  • openTurnScope() creates one scope for one send();
  • every provider step and retry in that send shares the scope;
  • overlapping turns on one backend have separate scopes;
  • cleanupAfterTurn() drops the scope on completion, error, or cancellation.

The backend-scoped ToolAvailabilityRuntime must remain immutable with respect to turn state. It may own bound catalog/index/projection logic, but it must not own mutable activeTools.

Request projection computes the current provider-visible names from:

direct tools
union TurnScope.activeTools
union context-required orchestration tools
intersect current boundTools

The execution guard must read the immutable step-start active set, not the live map mutated by a search that is settling in the same step.

No additional public ActivationReceipt or VisibleSnapshot domain type is required. The active map is the state, the thin tool result reports what changed, and the actual provider request is the visibility fact.

Direct baseline

Keep the agreed frequent baseline direct when those tools are present in the current binding:

  • Bash
  • Read
  • ArchiveRead
  • Write
  • Edit
  • Glob
  • Grep
  • WebFetch
  • AskUserQuestion
  • StopBackgroundTask
  • tool_search

Runtime-required tools may still be projected directly when current state requires them. Existing exact hosted-execution profiles and caller-provided boundTools remain hard ceilings.

Implementation work

  1. Add TurnScope.activeTools: Map<string, MakaTool>.
  2. Replace the current economy/group availability policy with direct and searchable bound-tool derivation.
  3. Build a cached search index from canonical bound tool name and description metadata.
  4. Add the synthetic direct tool_search tool with a per-turn activation callback.
  5. Generate the grouped canonical-name inventory from the effective bound deferred surface.
  6. Project direct + active + required tools before every provider request.
  7. Preserve a step-start gating snapshot so same-step search and hidden-tool execution cannot race.
  8. Union and deduplicate successful repeated and parallel searches.
  9. Record search query, ranked names, activated names, schema characters, and subsequent actual calls for evaluation.
  10. Remove the old model-facing availability mechanisms and update documentation.

Likely primary files:

  • packages/runtime/src/ai-sdk-backend.ts
  • packages/runtime/src/tool-availability.ts
  • packages/runtime/src/tool-catalog-derive.ts
  • packages/runtime-host/src/server/interactive-run-composer.ts
  • deferred-tool and execution-composition tests

Migration

Remove from the new model-facing contract:

  • economy/full mode;
  • MAKA_DISABLE_DEFERRED_TOOLS;
  • predefined groups as activation units;
  • load_tools;
  • load_tool;
  • connect_tool_source;
  • cross-turn activation replay and ledger seeding.

Historical RuntimeEvents may remain readable when required for old transcript compatibility, but they must never seed a new turn active set.

Provider-native tool search, if added later, must remain an optimization behind this same Maka-owned contract rather than a second semantic path.

Acceptance criteria

  1. The initial provider request contains the direct baseline and tool_search, but not deferred complete schemas.
  2. The lightweight inventory lists only currently bound deferred canonical names.
  3. Search results can contain only tools in the current binding ceiling.
  4. The ordinary search result contains activated names without complete schemas.
  5. Search completed in step n exposes complete matching schemas in step n + 1, never step n.
  6. Repeated and parallel searches accumulate a deduplicated active set for the current turn.
  7. A same-step hidden-tool call remains rejected even when a parallel search activates it for the next step.
  8. Provider retries preserve the current turn active set without double activation.
  9. Completion, failure, and cancellation do not leak active tools into another turn.
  10. Exact hosted profiles and explicit boundTools cannot be widened by search.
  11. Direct and discovered tools cross the same permission, durable execution, output bounding, and artifact boundaries.
  12. New turns do not restore activation from historical load_tools or alias calls.
  13. Tests cover direct mode, code mode, graph/swarm required tools, dynamic client tools, retry, parallel calls, and turn cleanup.
  14. Telemetry can report exposed-but-unused tool count/schema characters, top-k recall, repeated searches, and time to first successful tool call.

Evaluation

Measure:

  • schemas exposed but never called;
  • schema characters exposed but unused;
  • top-k recall of the tool eventually called;
  • revised or repeated searches;
  • time to the first successful tool call;
  • tasks where the required tool falls outside the per-search activation cap.

If the measurements show material context waste or retrieval misses, evaluate restoring an explicit model confirmation boundary through load_tools. The first slice intentionally starts with uniform search-and-activate semantics.

Explicitly out of scope

  • Skill and SkillSearch discovery;
  • goal-tool redesign;
  • provider prompt-cache semantics;
  • provider-native search as a separate contract;
  • unload semantics;
  • cross-turn discovery persistence;
  • changing ToolRuntime execution authority.

References

AI assistance disclosure: Maka helped inspect the current Runtime lifecycle, synthesize the agreement from Discussion #3621, and draft this implementation issue. I reviewed and approved the final scope.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    , 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
     blocks
    (function() {
    function addCopyButtons() {
    document.querySelectorAll('pre code').forEach(function(codeBlock) {
    if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
    codeBlock.parentElement.setAttribute('data-copy-added', 'true');
    var btn = document.createElement('button');
    btn.textContent = 'Copy';
    btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
    btn.onmouseover = function() { this.style.opacity = '1'; };
    btn.onmouseout = function() { this.style.opacity = '0.7'; };
    btn.onclick = function() {
    navigator.clipboard.writeText(codeBlock.textContent).then(function() {
    btn.textContent = 'Copied!';
    setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
    });
    };
    codeBlock.parentElement.style.position = 'relative';
    codeBlock.parentElement.appendChild(btn);
    });
    }
    addCopyButtons();
    // Re-run on dynamic content
    var observer = new MutationObserver(addCopyButtons);
    observer.observe(document.body, { childList: true, subtree: true });
    })();
    }
    } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
    })();
    (function(){
    try {
    var __m = "github.com";
    var __re = new RegExp('^' + "github\\.com" + '
    feat(runtime): implement turn-scoped tool_search activation · Issue #3752 · apache/maka · GitHub
    Skip to content

    feat(runtime): implement turn-scoped tool_search activation #3752

    Description

    @likun666661

    Problem

    Maka currently controls provider-visible tools through overlapping mechanisms: economy/full mode, predefined load_tools groups, MAKA_DISABLE_DEFERRED_TOOLS, historical connector aliases, and cross-turn ledger seeding. The model-facing contract is difficult to explain, and low-frequency tool schemas can add substantial context cost before the model needs them.

    Discussion #3621 reached agreement on the first implementation slice after working through binding authority, search-space discovery, activation timing, schema visibility, and the tradeoff between automatic activation and a separate confirmation command.

    Related tracker: #1382. This issue implements the provider-independent first slice agreed in #3621 rather than the original provider-native-first and cross-turn persistence assumptions in #1382.

    Desired outcome

    Provide one Maka-owned, provider-independent tool_search contract:

    tool_search(query, limit?)
    -> bounded top-k matches
    -> successful results become active immediately
    -> complete schemas become visible on the next provider step
    -> activation is monotonic within the current turn
    -> activation is cleared when the turn completes
    

    The search ranker selects which bounded schemas become visible. The model selects which visible tool to execute. Runtime binding and execution checks remain authoritative.

    Agreed semantics

    Authority and visibility

    • The tools actually bound to the current run are the capability ceiling.
    • Search metadata and the initial inventory are derived from those bindings.
    • A tool name in the inventory is discoverable metadata, not callable visibility.
    • A tool is visible for a provider step only when its complete callable definition is present in that request.
    • Search never binds a new executable tool and never escapes boundTools.
    • Tool visibility does not replace permission or execution-time validation.

    Initial discovery surface

    The model receives a lightweight inventory of deferred tools before searching:

    group:
    - canonical_tool_name
    - canonical_tool_name
    

    The inventory contains group names and canonical tool names only. Direct tools already have complete definitions and are not repeated. Dynamic client tools are grouped by their derived source metadata.

    Search contract

    Initial interface:

    tool_search({query: string,limit?: number,})

    The first index should use canonical name and description metadata derived from current bound deferred tools. Exact names may affect ranking but must not change the operation semantics: every successful search uniformly activates the matches it returns.

    The ordinary model-facing result stays thin:

    {
    "activated": ["browser_snapshot", "browser_click"]
    }

    Complete schemas must not be duplicated in the ordinary tool result. They enter the next request through the normal provider tool projection.

    Repeated and parallel searches

    • Successful searches add their matches to the current turn active set.
    • Repeated tools are deduplicated.
    • Parallel search results in one provider step are unioned.
    • The model may continue searching and expanding the active set.
    • There is no turn-wide activation budget or unload operation.
    • Each individual search remains bounded by result count and schema bytes.
    • The binding ceiling is the final upper bound.

    Step boundary

    A search result cannot rewrite the request in which the search call was emitted.

    For a search completed during provider step n:

    step n:
    tool_search executes and updates future active tools
    step n + 1:
    matching complete schemas enter the provider request
    

    A parallel hidden-tool call in the same step must still fail the step-start availability guard:

    tool_search("browser")
    browser_click(...)
    

    The search may affect only the next provider request.

    Runtime ownership

    The correct owner of mutable activation state is the existing per-send()TurnScope in packages/runtime/src/ai-sdk-backend.ts.

    classTurnScope{readonlyactiveTools=newMap<string,MakaTool>()// existing per-turn state}

    This matches the current lifecycle:

    • openTurnScope() creates one scope for one send();
    • every provider step and retry in that send shares the scope;
    • overlapping turns on one backend have separate scopes;
    • cleanupAfterTurn() drops the scope on completion, error, or cancellation.

    The backend-scoped ToolAvailabilityRuntime must remain immutable with respect to turn state. It may own bound catalog/index/projection logic, but it must not own mutable activeTools.

    Request projection computes the current provider-visible names from:

    direct tools
    union TurnScope.activeTools
    union context-required orchestration tools
    intersect current boundTools
    

    The execution guard must read the immutable step-start active set, not the live map mutated by a search that is settling in the same step.

    No additional public ActivationReceipt or VisibleSnapshot domain type is required. The active map is the state, the thin tool result reports what changed, and the actual provider request is the visibility fact.

    Direct baseline

    Keep the agreed frequent baseline direct when those tools are present in the current binding:

    • Bash
    • Read
    • ArchiveRead
    • Write
    • Edit
    • Glob
    • Grep
    • WebFetch
    • AskUserQuestion
    • StopBackgroundTask
    • tool_search

    Runtime-required tools may still be projected directly when current state requires them. Existing exact hosted-execution profiles and caller-provided boundTools remain hard ceilings.

    Implementation work

    1. Add TurnScope.activeTools: Map<string, MakaTool>.
    2. Replace the current economy/group availability policy with direct and searchable bound-tool derivation.
    3. Build a cached search index from canonical bound tool name and description metadata.
    4. Add the synthetic direct tool_search tool with a per-turn activation callback.
    5. Generate the grouped canonical-name inventory from the effective bound deferred surface.
    6. Project direct + active + required tools before every provider request.
    7. Preserve a step-start gating snapshot so same-step search and hidden-tool execution cannot race.
    8. Union and deduplicate successful repeated and parallel searches.
    9. Record search query, ranked names, activated names, schema characters, and subsequent actual calls for evaluation.
    10. Remove the old model-facing availability mechanisms and update documentation.

    Likely primary files:

    • packages/runtime/src/ai-sdk-backend.ts
    • packages/runtime/src/tool-availability.ts
    • packages/runtime/src/tool-catalog-derive.ts
    • packages/runtime-host/src/server/interactive-run-composer.ts
    • deferred-tool and execution-composition tests

    Migration

    Remove from the new model-facing contract:

    • economy/full mode;
    • MAKA_DISABLE_DEFERRED_TOOLS;
    • predefined groups as activation units;
    • load_tools;
    • load_tool;
    • connect_tool_source;
    • cross-turn activation replay and ledger seeding.

    Historical RuntimeEvents may remain readable when required for old transcript compatibility, but they must never seed a new turn active set.

    Provider-native tool search, if added later, must remain an optimization behind this same Maka-owned contract rather than a second semantic path.

    Acceptance criteria

    1. The initial provider request contains the direct baseline and tool_search, but not deferred complete schemas.
    2. The lightweight inventory lists only currently bound deferred canonical names.
    3. Search results can contain only tools in the current binding ceiling.
    4. The ordinary search result contains activated names without complete schemas.
    5. Search completed in step n exposes complete matching schemas in step n + 1, never step n.
    6. Repeated and parallel searches accumulate a deduplicated active set for the current turn.
    7. A same-step hidden-tool call remains rejected even when a parallel search activates it for the next step.
    8. Provider retries preserve the current turn active set without double activation.
    9. Completion, failure, and cancellation do not leak active tools into another turn.
    10. Exact hosted profiles and explicit boundTools cannot be widened by search.
    11. Direct and discovered tools cross the same permission, durable execution, output bounding, and artifact boundaries.
    12. New turns do not restore activation from historical load_tools or alias calls.
    13. Tests cover direct mode, code mode, graph/swarm required tools, dynamic client tools, retry, parallel calls, and turn cleanup.
    14. Telemetry can report exposed-but-unused tool count/schema characters, top-k recall, repeated searches, and time to first successful tool call.

    Evaluation

    Measure:

    • schemas exposed but never called;
    • schema characters exposed but unused;
    • top-k recall of the tool eventually called;
    • revised or repeated searches;
    • time to the first successful tool call;
    • tasks where the required tool falls outside the per-search activation cap.

    If the measurements show material context waste or retrieval misses, evaluate restoring an explicit model confirmation boundary through load_tools. The first slice intentionally starts with uniform search-and-activate semantics.

    Explicitly out of scope

    • Skill and SkillSearch discovery;
    • goal-tool redesign;
    • provider prompt-cache semantics;
    • provider-native search as a separate contract;
    • unload semantics;
    • cross-turn discovery persistence;
    • changing ToolRuntime execution authority.

    References

    AI assistance disclosure: Maka helped inspect the current Runtime lifecycle, synthesize the agreement from Discussion #3621, and draft this implementation issue. I reviewed and approved the final scope.

    Metadata

    Metadata

    Assignees

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      , 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' feat(runtime): implement turn-scoped tool_search activation · Issue #3752 · apache/maka · GitHub
      Skip to content

      feat(runtime): implement turn-scoped tool_search activation #3752

      Description

      @likun666661

      Problem

      Maka currently controls provider-visible tools through overlapping mechanisms: economy/full mode, predefined load_tools groups, MAKA_DISABLE_DEFERRED_TOOLS, historical connector aliases, and cross-turn ledger seeding. The model-facing contract is difficult to explain, and low-frequency tool schemas can add substantial context cost before the model needs them.

      Discussion #3621 reached agreement on the first implementation slice after working through binding authority, search-space discovery, activation timing, schema visibility, and the tradeoff between automatic activation and a separate confirmation command.

      Related tracker: #1382. This issue implements the provider-independent first slice agreed in #3621 rather than the original provider-native-first and cross-turn persistence assumptions in #1382.

      Desired outcome

      Provide one Maka-owned, provider-independent tool_search contract:

      tool_search(query, limit?)
      -> bounded top-k matches
      -> successful results become active immediately
      -> complete schemas become visible on the next provider step
      -> activation is monotonic within the current turn
      -> activation is cleared when the turn completes
      

      The search ranker selects which bounded schemas become visible. The model selects which visible tool to execute. Runtime binding and execution checks remain authoritative.

      Agreed semantics

      Authority and visibility

      • The tools actually bound to the current run are the capability ceiling.
      • Search metadata and the initial inventory are derived from those bindings.
      • A tool name in the inventory is discoverable metadata, not callable visibility.
      • A tool is visible for a provider step only when its complete callable definition is present in that request.
      • Search never binds a new executable tool and never escapes boundTools.
      • Tool visibility does not replace permission or execution-time validation.

      Initial discovery surface

      The model receives a lightweight inventory of deferred tools before searching:

      group:
      - canonical_tool_name
      - canonical_tool_name
      

      The inventory contains group names and canonical tool names only. Direct tools already have complete definitions and are not repeated. Dynamic client tools are grouped by their derived source metadata.

      Search contract

      Initial interface:

      tool_search({query: string,limit?: number,})

      The first index should use canonical name and description metadata derived from current bound deferred tools. Exact names may affect ranking but must not change the operation semantics: every successful search uniformly activates the matches it returns.

      The ordinary model-facing result stays thin:

      {
      "activated": ["browser_snapshot", "browser_click"]
      }

      Complete schemas must not be duplicated in the ordinary tool result. They enter the next request through the normal provider tool projection.

      Repeated and parallel searches

      • Successful searches add their matches to the current turn active set.
      • Repeated tools are deduplicated.
      • Parallel search results in one provider step are unioned.
      • The model may continue searching and expanding the active set.
      • There is no turn-wide activation budget or unload operation.
      • Each individual search remains bounded by result count and schema bytes.
      • The binding ceiling is the final upper bound.

      Step boundary

      A search result cannot rewrite the request in which the search call was emitted.

      For a search completed during provider step n:

      step n:
      tool_search executes and updates future active tools
      step n + 1:
      matching complete schemas enter the provider request
      

      A parallel hidden-tool call in the same step must still fail the step-start availability guard:

      tool_search("browser")
      browser_click(...)
      

      The search may affect only the next provider request.

      Runtime ownership

      The correct owner of mutable activation state is the existing per-send()TurnScope in packages/runtime/src/ai-sdk-backend.ts.

      classTurnScope{readonlyactiveTools=newMap<string,MakaTool>()// existing per-turn state}

      This matches the current lifecycle:

      • openTurnScope() creates one scope for one send();
      • every provider step and retry in that send shares the scope;
      • overlapping turns on one backend have separate scopes;
      • cleanupAfterTurn() drops the scope on completion, error, or cancellation.

      The backend-scoped ToolAvailabilityRuntime must remain immutable with respect to turn state. It may own bound catalog/index/projection logic, but it must not own mutable activeTools.

      Request projection computes the current provider-visible names from:

      direct tools
      union TurnScope.activeTools
      union context-required orchestration tools
      intersect current boundTools
      

      The execution guard must read the immutable step-start active set, not the live map mutated by a search that is settling in the same step.

      No additional public ActivationReceipt or VisibleSnapshot domain type is required. The active map is the state, the thin tool result reports what changed, and the actual provider request is the visibility fact.

      Direct baseline

      Keep the agreed frequent baseline direct when those tools are present in the current binding:

      • Bash
      • Read
      • ArchiveRead
      • Write
      • Edit
      • Glob
      • Grep
      • WebFetch
      • AskUserQuestion
      • StopBackgroundTask
      • tool_search

      Runtime-required tools may still be projected directly when current state requires them. Existing exact hosted-execution profiles and caller-provided boundTools remain hard ceilings.

      Implementation work

      1. Add TurnScope.activeTools: Map<string, MakaTool>.
      2. Replace the current economy/group availability policy with direct and searchable bound-tool derivation.
      3. Build a cached search index from canonical bound tool name and description metadata.
      4. Add the synthetic direct tool_search tool with a per-turn activation callback.
      5. Generate the grouped canonical-name inventory from the effective bound deferred surface.
      6. Project direct + active + required tools before every provider request.
      7. Preserve a step-start gating snapshot so same-step search and hidden-tool execution cannot race.
      8. Union and deduplicate successful repeated and parallel searches.
      9. Record search query, ranked names, activated names, schema characters, and subsequent actual calls for evaluation.
      10. Remove the old model-facing availability mechanisms and update documentation.

      Likely primary files:

      • packages/runtime/src/ai-sdk-backend.ts
      • packages/runtime/src/tool-availability.ts
      • packages/runtime/src/tool-catalog-derive.ts
      • packages/runtime-host/src/server/interactive-run-composer.ts
      • deferred-tool and execution-composition tests

      Migration

      Remove from the new model-facing contract:

      • economy/full mode;
      • MAKA_DISABLE_DEFERRED_TOOLS;
      • predefined groups as activation units;
      • load_tools;
      • load_tool;
      • connect_tool_source;
      • cross-turn activation replay and ledger seeding.

      Historical RuntimeEvents may remain readable when required for old transcript compatibility, but they must never seed a new turn active set.

      Provider-native tool search, if added later, must remain an optimization behind this same Maka-owned contract rather than a second semantic path.

      Acceptance criteria

      1. The initial provider request contains the direct baseline and tool_search, but not deferred complete schemas.
      2. The lightweight inventory lists only currently bound deferred canonical names.
      3. Search results can contain only tools in the current binding ceiling.
      4. The ordinary search result contains activated names without complete schemas.
      5. Search completed in step n exposes complete matching schemas in step n + 1, never step n.
      6. Repeated and parallel searches accumulate a deduplicated active set for the current turn.
      7. A same-step hidden-tool call remains rejected even when a parallel search activates it for the next step.
      8. Provider retries preserve the current turn active set without double activation.
      9. Completion, failure, and cancellation do not leak active tools into another turn.
      10. Exact hosted profiles and explicit boundTools cannot be widened by search.
      11. Direct and discovered tools cross the same permission, durable execution, output bounding, and artifact boundaries.
      12. New turns do not restore activation from historical load_tools or alias calls.
      13. Tests cover direct mode, code mode, graph/swarm required tools, dynamic client tools, retry, parallel calls, and turn cleanup.
      14. Telemetry can report exposed-but-unused tool count/schema characters, top-k recall, repeated searches, and time to first successful tool call.

      Evaluation

      Measure:

      • schemas exposed but never called;
      • schema characters exposed but unused;
      • top-k recall of the tool eventually called;
      • revised or repeated searches;
      • time to the first successful tool call;
      • tasks where the required tool falls outside the per-search activation cap.

      If the measurements show material context waste or retrieval misses, evaluate restoring an explicit model confirmation boundary through load_tools. The first slice intentionally starts with uniform search-and-activate semantics.

      Explicitly out of scope

      • Skill and SkillSearch discovery;
      • goal-tool redesign;
      • provider prompt-cache semantics;
      • provider-native search as a separate contract;
      • unload semantics;
      • cross-turn discovery persistence;
      • changing ToolRuntime execution authority.

      References

      AI assistance disclosure: Maka helped inspect the current Runtime lifecycle, synthesize the agreement from Discussion #3621, and draft this implementation issue. I reviewed and approved the final scope.

      Metadata

      Metadata

      Assignees

      Labels

      enhancementNew feature or request

      Type

      No type

      Projects

      No projects

        Milestone

        No milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions

        , 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' feat(runtime): implement turn-scoped tool_search activation · Issue #3752 · apache/maka · GitHub
        Skip to content

        feat(runtime): implement turn-scoped tool_search activation #3752

        Description

        @likun666661

        Problem

        Maka currently controls provider-visible tools through overlapping mechanisms: economy/full mode, predefined load_tools groups, MAKA_DISABLE_DEFERRED_TOOLS, historical connector aliases, and cross-turn ledger seeding. The model-facing contract is difficult to explain, and low-frequency tool schemas can add substantial context cost before the model needs them.

        Discussion #3621 reached agreement on the first implementation slice after working through binding authority, search-space discovery, activation timing, schema visibility, and the tradeoff between automatic activation and a separate confirmation command.

        Related tracker: #1382. This issue implements the provider-independent first slice agreed in #3621 rather than the original provider-native-first and cross-turn persistence assumptions in #1382.

        Desired outcome

        Provide one Maka-owned, provider-independent tool_search contract:

        tool_search(query, limit?)
        -> bounded top-k matches
        -> successful results become active immediately
        -> complete schemas become visible on the next provider step
        -> activation is monotonic within the current turn
        -> activation is cleared when the turn completes
        

        The search ranker selects which bounded schemas become visible. The model selects which visible tool to execute. Runtime binding and execution checks remain authoritative.

        Agreed semantics

        Authority and visibility

        • The tools actually bound to the current run are the capability ceiling.
        • Search metadata and the initial inventory are derived from those bindings.
        • A tool name in the inventory is discoverable metadata, not callable visibility.
        • A tool is visible for a provider step only when its complete callable definition is present in that request.
        • Search never binds a new executable tool and never escapes boundTools.
        • Tool visibility does not replace permission or execution-time validation.

        Initial discovery surface

        The model receives a lightweight inventory of deferred tools before searching:

        group:
        - canonical_tool_name
        - canonical_tool_name
        

        The inventory contains group names and canonical tool names only. Direct tools already have complete definitions and are not repeated. Dynamic client tools are grouped by their derived source metadata.

        Search contract

        Initial interface:

        tool_search({query: string,limit?: number,})

        The first index should use canonical name and description metadata derived from current bound deferred tools. Exact names may affect ranking but must not change the operation semantics: every successful search uniformly activates the matches it returns.

        The ordinary model-facing result stays thin:

        {
        "activated": ["browser_snapshot", "browser_click"]
        }

        Complete schemas must not be duplicated in the ordinary tool result. They enter the next request through the normal provider tool projection.

        Repeated and parallel searches

        • Successful searches add their matches to the current turn active set.
        • Repeated tools are deduplicated.
        • Parallel search results in one provider step are unioned.
        • The model may continue searching and expanding the active set.
        • There is no turn-wide activation budget or unload operation.
        • Each individual search remains bounded by result count and schema bytes.
        • The binding ceiling is the final upper bound.

        Step boundary

        A search result cannot rewrite the request in which the search call was emitted.

        For a search completed during provider step n:

        step n:
        tool_search executes and updates future active tools
        step n + 1:
        matching complete schemas enter the provider request
        

        A parallel hidden-tool call in the same step must still fail the step-start availability guard:

        tool_search("browser")
        browser_click(...)
        

        The search may affect only the next provider request.

        Runtime ownership

        The correct owner of mutable activation state is the existing per-send()TurnScope in packages/runtime/src/ai-sdk-backend.ts.

        classTurnScope{readonlyactiveTools=newMap<string,MakaTool>()// existing per-turn state}

        This matches the current lifecycle:

        • openTurnScope() creates one scope for one send();
        • every provider step and retry in that send shares the scope;
        • overlapping turns on one backend have separate scopes;
        • cleanupAfterTurn() drops the scope on completion, error, or cancellation.

        The backend-scoped ToolAvailabilityRuntime must remain immutable with respect to turn state. It may own bound catalog/index/projection logic, but it must not own mutable activeTools.

        Request projection computes the current provider-visible names from:

        direct tools
        union TurnScope.activeTools
        union context-required orchestration tools
        intersect current boundTools
        

        The execution guard must read the immutable step-start active set, not the live map mutated by a search that is settling in the same step.

        No additional public ActivationReceipt or VisibleSnapshot domain type is required. The active map is the state, the thin tool result reports what changed, and the actual provider request is the visibility fact.

        Direct baseline

        Keep the agreed frequent baseline direct when those tools are present in the current binding:

        • Bash
        • Read
        • ArchiveRead
        • Write
        • Edit
        • Glob
        • Grep
        • WebFetch
        • AskUserQuestion
        • StopBackgroundTask
        • tool_search

        Runtime-required tools may still be projected directly when current state requires them. Existing exact hosted-execution profiles and caller-provided boundTools remain hard ceilings.

        Implementation work

        1. Add TurnScope.activeTools: Map<string, MakaTool>.
        2. Replace the current economy/group availability policy with direct and searchable bound-tool derivation.
        3. Build a cached search index from canonical bound tool name and description metadata.
        4. Add the synthetic direct tool_search tool with a per-turn activation callback.
        5. Generate the grouped canonical-name inventory from the effective bound deferred surface.
        6. Project direct + active + required tools before every provider request.
        7. Preserve a step-start gating snapshot so same-step search and hidden-tool execution cannot race.
        8. Union and deduplicate successful repeated and parallel searches.
        9. Record search query, ranked names, activated names, schema characters, and subsequent actual calls for evaluation.
        10. Remove the old model-facing availability mechanisms and update documentation.

        Likely primary files:

        • packages/runtime/src/ai-sdk-backend.ts
        • packages/runtime/src/tool-availability.ts
        • packages/runtime/src/tool-catalog-derive.ts
        • packages/runtime-host/src/server/interactive-run-composer.ts
        • deferred-tool and execution-composition tests

        Migration

        Remove from the new model-facing contract:

        • economy/full mode;
        • MAKA_DISABLE_DEFERRED_TOOLS;
        • predefined groups as activation units;
        • load_tools;
        • load_tool;
        • connect_tool_source;
        • cross-turn activation replay and ledger seeding.

        Historical RuntimeEvents may remain readable when required for old transcript compatibility, but they must never seed a new turn active set.

        Provider-native tool search, if added later, must remain an optimization behind this same Maka-owned contract rather than a second semantic path.

        Acceptance criteria

        1. The initial provider request contains the direct baseline and tool_search, but not deferred complete schemas.
        2. The lightweight inventory lists only currently bound deferred canonical names.
        3. Search results can contain only tools in the current binding ceiling.
        4. The ordinary search result contains activated names without complete schemas.
        5. Search completed in step n exposes complete matching schemas in step n + 1, never step n.
        6. Repeated and parallel searches accumulate a deduplicated active set for the current turn.
        7. A same-step hidden-tool call remains rejected even when a parallel search activates it for the next step.
        8. Provider retries preserve the current turn active set without double activation.
        9. Completion, failure, and cancellation do not leak active tools into another turn.
        10. Exact hosted profiles and explicit boundTools cannot be widened by search.
        11. Direct and discovered tools cross the same permission, durable execution, output bounding, and artifact boundaries.
        12. New turns do not restore activation from historical load_tools or alias calls.
        13. Tests cover direct mode, code mode, graph/swarm required tools, dynamic client tools, retry, parallel calls, and turn cleanup.
        14. Telemetry can report exposed-but-unused tool count/schema characters, top-k recall, repeated searches, and time to first successful tool call.

        Evaluation

        Measure:

        • schemas exposed but never called;
        • schema characters exposed but unused;
        • top-k recall of the tool eventually called;
        • revised or repeated searches;
        • time to the first successful tool call;
        • tasks where the required tool falls outside the per-search activation cap.

        If the measurements show material context waste or retrieval misses, evaluate restoring an explicit model confirmation boundary through load_tools. The first slice intentionally starts with uniform search-and-activate semantics.

        Explicitly out of scope

        • Skill and SkillSearch discovery;
        • goal-tool redesign;
        • provider prompt-cache semantics;
        • provider-native search as a separate contract;
        • unload semantics;
        • cross-turn discovery persistence;
        • changing ToolRuntime execution authority.

        References

        AI assistance disclosure: Maka helped inspect the current Runtime lifecycle, synthesize the agreement from Discussion #3621, and draft this implementation issue. I reviewed and approved the final scope.

        Metadata

        Metadata

        Assignees

        Labels

        enhancementNew feature or request

        Type

        No type

        Projects

        No projects

          Milestone

          No milestone

          Relationships

          None yet

          Development

          No branches or pull requests

          Issue actions

          , 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' feat(runtime): implement turn-scoped tool_search activation · Issue #3752 · apache/maka · GitHub
          Skip to content

          feat(runtime): implement turn-scoped tool_search activation #3752

          Description

          @likun666661

          Problem

          Maka currently controls provider-visible tools through overlapping mechanisms: economy/full mode, predefined load_tools groups, MAKA_DISABLE_DEFERRED_TOOLS, historical connector aliases, and cross-turn ledger seeding. The model-facing contract is difficult to explain, and low-frequency tool schemas can add substantial context cost before the model needs them.

          Discussion #3621 reached agreement on the first implementation slice after working through binding authority, search-space discovery, activation timing, schema visibility, and the tradeoff between automatic activation and a separate confirmation command.

          Related tracker: #1382. This issue implements the provider-independent first slice agreed in #3621 rather than the original provider-native-first and cross-turn persistence assumptions in #1382.

          Desired outcome

          Provide one Maka-owned, provider-independent tool_search contract:

          tool_search(query, limit?)
          -> bounded top-k matches
          -> successful results become active immediately
          -> complete schemas become visible on the next provider step
          -> activation is monotonic within the current turn
          -> activation is cleared when the turn completes
          

          The search ranker selects which bounded schemas become visible. The model selects which visible tool to execute. Runtime binding and execution checks remain authoritative.

          Agreed semantics

          Authority and visibility

          • The tools actually bound to the current run are the capability ceiling.
          • Search metadata and the initial inventory are derived from those bindings.
          • A tool name in the inventory is discoverable metadata, not callable visibility.
          • A tool is visible for a provider step only when its complete callable definition is present in that request.
          • Search never binds a new executable tool and never escapes boundTools.
          • Tool visibility does not replace permission or execution-time validation.

          Initial discovery surface

          The model receives a lightweight inventory of deferred tools before searching:

          group:
          - canonical_tool_name
          - canonical_tool_name
          

          The inventory contains group names and canonical tool names only. Direct tools already have complete definitions and are not repeated. Dynamic client tools are grouped by their derived source metadata.

          Search contract

          Initial interface:

          tool_search({query: string,limit?: number,})

          The first index should use canonical name and description metadata derived from current bound deferred tools. Exact names may affect ranking but must not change the operation semantics: every successful search uniformly activates the matches it returns.

          The ordinary model-facing result stays thin:

          {
          "activated": ["browser_snapshot", "browser_click"]
          }

          Complete schemas must not be duplicated in the ordinary tool result. They enter the next request through the normal provider tool projection.

          Repeated and parallel searches

          • Successful searches add their matches to the current turn active set.
          • Repeated tools are deduplicated.
          • Parallel search results in one provider step are unioned.
          • The model may continue searching and expanding the active set.
          • There is no turn-wide activation budget or unload operation.
          • Each individual search remains bounded by result count and schema bytes.
          • The binding ceiling is the final upper bound.

          Step boundary

          A search result cannot rewrite the request in which the search call was emitted.

          For a search completed during provider step n:

          step n:
          tool_search executes and updates future active tools
          step n + 1:
          matching complete schemas enter the provider request
          

          A parallel hidden-tool call in the same step must still fail the step-start availability guard:

          tool_search("browser")
          browser_click(...)
          

          The search may affect only the next provider request.

          Runtime ownership

          The correct owner of mutable activation state is the existing per-send()TurnScope in packages/runtime/src/ai-sdk-backend.ts.

          classTurnScope{readonlyactiveTools=newMap<string,MakaTool>()// existing per-turn state}

          This matches the current lifecycle:

          • openTurnScope() creates one scope for one send();
          • every provider step and retry in that send shares the scope;
          • overlapping turns on one backend have separate scopes;
          • cleanupAfterTurn() drops the scope on completion, error, or cancellation.

          The backend-scoped ToolAvailabilityRuntime must remain immutable with respect to turn state. It may own bound catalog/index/projection logic, but it must not own mutable activeTools.

          Request projection computes the current provider-visible names from:

          direct tools
          union TurnScope.activeTools
          union context-required orchestration tools
          intersect current boundTools
          

          The execution guard must read the immutable step-start active set, not the live map mutated by a search that is settling in the same step.

          No additional public ActivationReceipt or VisibleSnapshot domain type is required. The active map is the state, the thin tool result reports what changed, and the actual provider request is the visibility fact.

          Direct baseline

          Keep the agreed frequent baseline direct when those tools are present in the current binding:

          • Bash
          • Read
          • ArchiveRead
          • Write
          • Edit
          • Glob
          • Grep
          • WebFetch
          • AskUserQuestion
          • StopBackgroundTask
          • tool_search

          Runtime-required tools may still be projected directly when current state requires them. Existing exact hosted-execution profiles and caller-provided boundTools remain hard ceilings.

          Implementation work

          1. Add TurnScope.activeTools: Map<string, MakaTool>.
          2. Replace the current economy/group availability policy with direct and searchable bound-tool derivation.
          3. Build a cached search index from canonical bound tool name and description metadata.
          4. Add the synthetic direct tool_search tool with a per-turn activation callback.
          5. Generate the grouped canonical-name inventory from the effective bound deferred surface.
          6. Project direct + active + required tools before every provider request.
          7. Preserve a step-start gating snapshot so same-step search and hidden-tool execution cannot race.
          8. Union and deduplicate successful repeated and parallel searches.
          9. Record search query, ranked names, activated names, schema characters, and subsequent actual calls for evaluation.
          10. Remove the old model-facing availability mechanisms and update documentation.

          Likely primary files:

          • packages/runtime/src/ai-sdk-backend.ts
          • packages/runtime/src/tool-availability.ts
          • packages/runtime/src/tool-catalog-derive.ts
          • packages/runtime-host/src/server/interactive-run-composer.ts
          • deferred-tool and execution-composition tests

          Migration

          Remove from the new model-facing contract:

          • economy/full mode;
          • MAKA_DISABLE_DEFERRED_TOOLS;
          • predefined groups as activation units;
          • load_tools;
          • load_tool;
          • connect_tool_source;
          • cross-turn activation replay and ledger seeding.

          Historical RuntimeEvents may remain readable when required for old transcript compatibility, but they must never seed a new turn active set.

          Provider-native tool search, if added later, must remain an optimization behind this same Maka-owned contract rather than a second semantic path.

          Acceptance criteria

          1. The initial provider request contains the direct baseline and tool_search, but not deferred complete schemas.
          2. The lightweight inventory lists only currently bound deferred canonical names.
          3. Search results can contain only tools in the current binding ceiling.
          4. The ordinary search result contains activated names without complete schemas.
          5. Search completed in step n exposes complete matching schemas in step n + 1, never step n.
          6. Repeated and parallel searches accumulate a deduplicated active set for the current turn.
          7. A same-step hidden-tool call remains rejected even when a parallel search activates it for the next step.
          8. Provider retries preserve the current turn active set without double activation.
          9. Completion, failure, and cancellation do not leak active tools into another turn.
          10. Exact hosted profiles and explicit boundTools cannot be widened by search.
          11. Direct and discovered tools cross the same permission, durable execution, output bounding, and artifact boundaries.
          12. New turns do not restore activation from historical load_tools or alias calls.
          13. Tests cover direct mode, code mode, graph/swarm required tools, dynamic client tools, retry, parallel calls, and turn cleanup.
          14. Telemetry can report exposed-but-unused tool count/schema characters, top-k recall, repeated searches, and time to first successful tool call.

          Evaluation

          Measure:

          • schemas exposed but never called;
          • schema characters exposed but unused;
          • top-k recall of the tool eventually called;
          • revised or repeated searches;
          • time to the first successful tool call;
          • tasks where the required tool falls outside the per-search activation cap.

          If the measurements show material context waste or retrieval misses, evaluate restoring an explicit model confirmation boundary through load_tools. The first slice intentionally starts with uniform search-and-activate semantics.

          Explicitly out of scope

          • Skill and SkillSearch discovery;
          • goal-tool redesign;
          • provider prompt-cache semantics;
          • provider-native search as a separate contract;
          • unload semantics;
          • cross-turn discovery persistence;
          • changing ToolRuntime execution authority.

          References

          AI assistance disclosure: Maka helped inspect the current Runtime lifecycle, synthesize the agreement from Discussion #3621, and draft this implementation issue. I reviewed and approved the final scope.

          Metadata

          Metadata

          Assignees

          Labels

          enhancementNew feature or request

          Type

          No type

          Projects

          No projects

            Milestone

            No milestone

            Relationships

            None yet

            Development

            No branches or pull requests

            Issue actions

            , 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' feat(runtime): implement turn-scoped tool_search activation · Issue #3752 · apache/maka · GitHub
            Skip to content

            feat(runtime): implement turn-scoped tool_search activation #3752

            Description

            @likun666661

            Problem

            Maka currently controls provider-visible tools through overlapping mechanisms: economy/full mode, predefined load_tools groups, MAKA_DISABLE_DEFERRED_TOOLS, historical connector aliases, and cross-turn ledger seeding. The model-facing contract is difficult to explain, and low-frequency tool schemas can add substantial context cost before the model needs them.

            Discussion #3621 reached agreement on the first implementation slice after working through binding authority, search-space discovery, activation timing, schema visibility, and the tradeoff between automatic activation and a separate confirmation command.

            Related tracker: #1382. This issue implements the provider-independent first slice agreed in #3621 rather than the original provider-native-first and cross-turn persistence assumptions in #1382.

            Desired outcome

            Provide one Maka-owned, provider-independent tool_search contract:

            tool_search(query, limit?)
            -> bounded top-k matches
            -> successful results become active immediately
            -> complete schemas become visible on the next provider step
            -> activation is monotonic within the current turn
            -> activation is cleared when the turn completes
            

            The search ranker selects which bounded schemas become visible. The model selects which visible tool to execute. Runtime binding and execution checks remain authoritative.

            Agreed semantics

            Authority and visibility

            • The tools actually bound to the current run are the capability ceiling.
            • Search metadata and the initial inventory are derived from those bindings.
            • A tool name in the inventory is discoverable metadata, not callable visibility.
            • A tool is visible for a provider step only when its complete callable definition is present in that request.
            • Search never binds a new executable tool and never escapes boundTools.
            • Tool visibility does not replace permission or execution-time validation.

            Initial discovery surface

            The model receives a lightweight inventory of deferred tools before searching:

            group:
            - canonical_tool_name
            - canonical_tool_name
            

            The inventory contains group names and canonical tool names only. Direct tools already have complete definitions and are not repeated. Dynamic client tools are grouped by their derived source metadata.

            Search contract

            Initial interface:

            tool_search({query: string,limit?: number,})

            The first index should use canonical name and description metadata derived from current bound deferred tools. Exact names may affect ranking but must not change the operation semantics: every successful search uniformly activates the matches it returns.

            The ordinary model-facing result stays thin:

            {
            "activated": ["browser_snapshot", "browser_click"]
            }

            Complete schemas must not be duplicated in the ordinary tool result. They enter the next request through the normal provider tool projection.

            Repeated and parallel searches

            • Successful searches add their matches to the current turn active set.
            • Repeated tools are deduplicated.
            • Parallel search results in one provider step are unioned.
            • The model may continue searching and expanding the active set.
            • There is no turn-wide activation budget or unload operation.
            • Each individual search remains bounded by result count and schema bytes.
            • The binding ceiling is the final upper bound.

            Step boundary

            A search result cannot rewrite the request in which the search call was emitted.

            For a search completed during provider step n:

            step n:
            tool_search executes and updates future active tools
            step n + 1:
            matching complete schemas enter the provider request
            

            A parallel hidden-tool call in the same step must still fail the step-start availability guard:

            tool_search("browser")
            browser_click(...)
            

            The search may affect only the next provider request.

            Runtime ownership

            The correct owner of mutable activation state is the existing per-send()TurnScope in packages/runtime/src/ai-sdk-backend.ts.

            classTurnScope{readonlyactiveTools=newMap<string,MakaTool>()// existing per-turn state}

            This matches the current lifecycle:

            • openTurnScope() creates one scope for one send();
            • every provider step and retry in that send shares the scope;
            • overlapping turns on one backend have separate scopes;
            • cleanupAfterTurn() drops the scope on completion, error, or cancellation.

            The backend-scoped ToolAvailabilityRuntime must remain immutable with respect to turn state. It may own bound catalog/index/projection logic, but it must not own mutable activeTools.

            Request projection computes the current provider-visible names from:

            direct tools
            union TurnScope.activeTools
            union context-required orchestration tools
            intersect current boundTools
            

            The execution guard must read the immutable step-start active set, not the live map mutated by a search that is settling in the same step.

            No additional public ActivationReceipt or VisibleSnapshot domain type is required. The active map is the state, the thin tool result reports what changed, and the actual provider request is the visibility fact.

            Direct baseline

            Keep the agreed frequent baseline direct when those tools are present in the current binding:

            • Bash
            • Read
            • ArchiveRead
            • Write
            • Edit
            • Glob
            • Grep
            • WebFetch
            • AskUserQuestion
            • StopBackgroundTask
            • tool_search

            Runtime-required tools may still be projected directly when current state requires them. Existing exact hosted-execution profiles and caller-provided boundTools remain hard ceilings.

            Implementation work

            1. Add TurnScope.activeTools: Map<string, MakaTool>.
            2. Replace the current economy/group availability policy with direct and searchable bound-tool derivation.
            3. Build a cached search index from canonical bound tool name and description metadata.
            4. Add the synthetic direct tool_search tool with a per-turn activation callback.
            5. Generate the grouped canonical-name inventory from the effective bound deferred surface.
            6. Project direct + active + required tools before every provider request.
            7. Preserve a step-start gating snapshot so same-step search and hidden-tool execution cannot race.
            8. Union and deduplicate successful repeated and parallel searches.
            9. Record search query, ranked names, activated names, schema characters, and subsequent actual calls for evaluation.
            10. Remove the old model-facing availability mechanisms and update documentation.

            Likely primary files:

            • packages/runtime/src/ai-sdk-backend.ts
            • packages/runtime/src/tool-availability.ts
            • packages/runtime/src/tool-catalog-derive.ts
            • packages/runtime-host/src/server/interactive-run-composer.ts
            • deferred-tool and execution-composition tests

            Migration

            Remove from the new model-facing contract:

            • economy/full mode;
            • MAKA_DISABLE_DEFERRED_TOOLS;
            • predefined groups as activation units;
            • load_tools;
            • load_tool;
            • connect_tool_source;
            • cross-turn activation replay and ledger seeding.

            Historical RuntimeEvents may remain readable when required for old transcript compatibility, but they must never seed a new turn active set.

            Provider-native tool search, if added later, must remain an optimization behind this same Maka-owned contract rather than a second semantic path.

            Acceptance criteria

            1. The initial provider request contains the direct baseline and tool_search, but not deferred complete schemas.
            2. The lightweight inventory lists only currently bound deferred canonical names.
            3. Search results can contain only tools in the current binding ceiling.
            4. The ordinary search result contains activated names without complete schemas.
            5. Search completed in step n exposes complete matching schemas in step n + 1, never step n.
            6. Repeated and parallel searches accumulate a deduplicated active set for the current turn.
            7. A same-step hidden-tool call remains rejected even when a parallel search activates it for the next step.
            8. Provider retries preserve the current turn active set without double activation.
            9. Completion, failure, and cancellation do not leak active tools into another turn.
            10. Exact hosted profiles and explicit boundTools cannot be widened by search.
            11. Direct and discovered tools cross the same permission, durable execution, output bounding, and artifact boundaries.
            12. New turns do not restore activation from historical load_tools or alias calls.
            13. Tests cover direct mode, code mode, graph/swarm required tools, dynamic client tools, retry, parallel calls, and turn cleanup.
            14. Telemetry can report exposed-but-unused tool count/schema characters, top-k recall, repeated searches, and time to first successful tool call.

            Evaluation

            Measure:

            • schemas exposed but never called;
            • schema characters exposed but unused;
            • top-k recall of the tool eventually called;
            • revised or repeated searches;
            • time to the first successful tool call;
            • tasks where the required tool falls outside the per-search activation cap.

            If the measurements show material context waste or retrieval misses, evaluate restoring an explicit model confirmation boundary through load_tools. The first slice intentionally starts with uniform search-and-activate semantics.

            Explicitly out of scope

            • Skill and SkillSearch discovery;
            • goal-tool redesign;
            • provider prompt-cache semantics;
            • provider-native search as a separate contract;
            • unload semantics;
            • cross-turn discovery persistence;
            • changing ToolRuntime execution authority.

            References

            AI assistance disclosure: Maka helped inspect the current Runtime lifecycle, synthesize the agreement from Discussion #3621, and draft this implementation issue. I reviewed and approved the final scope.

            Metadata

            Metadata

            Assignees

            Labels

            enhancementNew feature or request

            Type

            No type

            Projects

            No projects

              Milestone

              No milestone

              Relationships

              None yet

              Development

              No branches or pull requests

              Issue actions

              , 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' feat(runtime): implement turn-scoped tool_search activation · Issue #3752 · apache/maka · GitHub
              Skip to content

              feat(runtime): implement turn-scoped tool_search activation #3752

              Description

              @likun666661

              Problem

              Maka currently controls provider-visible tools through overlapping mechanisms: economy/full mode, predefined load_tools groups, MAKA_DISABLE_DEFERRED_TOOLS, historical connector aliases, and cross-turn ledger seeding. The model-facing contract is difficult to explain, and low-frequency tool schemas can add substantial context cost before the model needs them.

              Discussion #3621 reached agreement on the first implementation slice after working through binding authority, search-space discovery, activation timing, schema visibility, and the tradeoff between automatic activation and a separate confirmation command.

              Related tracker: #1382. This issue implements the provider-independent first slice agreed in #3621 rather than the original provider-native-first and cross-turn persistence assumptions in #1382.

              Desired outcome

              Provide one Maka-owned, provider-independent tool_search contract:

              tool_search(query, limit?)
              -> bounded top-k matches
              -> successful results become active immediately
              -> complete schemas become visible on the next provider step
              -> activation is monotonic within the current turn
              -> activation is cleared when the turn completes
              

              The search ranker selects which bounded schemas become visible. The model selects which visible tool to execute. Runtime binding and execution checks remain authoritative.

              Agreed semantics

              Authority and visibility

              • The tools actually bound to the current run are the capability ceiling.
              • Search metadata and the initial inventory are derived from those bindings.
              • A tool name in the inventory is discoverable metadata, not callable visibility.
              • A tool is visible for a provider step only when its complete callable definition is present in that request.
              • Search never binds a new executable tool and never escapes boundTools.
              • Tool visibility does not replace permission or execution-time validation.

              Initial discovery surface

              The model receives a lightweight inventory of deferred tools before searching:

              group:
              - canonical_tool_name
              - canonical_tool_name
              

              The inventory contains group names and canonical tool names only. Direct tools already have complete definitions and are not repeated. Dynamic client tools are grouped by their derived source metadata.

              Search contract

              Initial interface:

              tool_search({query: string,limit?: number,})

              The first index should use canonical name and description metadata derived from current bound deferred tools. Exact names may affect ranking but must not change the operation semantics: every successful search uniformly activates the matches it returns.

              The ordinary model-facing result stays thin:

              {
              "activated": ["browser_snapshot", "browser_click"]
              }

              Complete schemas must not be duplicated in the ordinary tool result. They enter the next request through the normal provider tool projection.

              Repeated and parallel searches

              • Successful searches add their matches to the current turn active set.
              • Repeated tools are deduplicated.
              • Parallel search results in one provider step are unioned.
              • The model may continue searching and expanding the active set.
              • There is no turn-wide activation budget or unload operation.
              • Each individual search remains bounded by result count and schema bytes.
              • The binding ceiling is the final upper bound.

              Step boundary

              A search result cannot rewrite the request in which the search call was emitted.

              For a search completed during provider step n:

              step n:
              tool_search executes and updates future active tools
              step n + 1:
              matching complete schemas enter the provider request
              

              A parallel hidden-tool call in the same step must still fail the step-start availability guard:

              tool_search("browser")
              browser_click(...)
              

              The search may affect only the next provider request.

              Runtime ownership

              The correct owner of mutable activation state is the existing per-send()TurnScope in packages/runtime/src/ai-sdk-backend.ts.

              classTurnScope{readonlyactiveTools=newMap<string,MakaTool>()// existing per-turn state}

              This matches the current lifecycle:

              • openTurnScope() creates one scope for one send();
              • every provider step and retry in that send shares the scope;
              • overlapping turns on one backend have separate scopes;
              • cleanupAfterTurn() drops the scope on completion, error, or cancellation.

              The backend-scoped ToolAvailabilityRuntime must remain immutable with respect to turn state. It may own bound catalog/index/projection logic, but it must not own mutable activeTools.

              Request projection computes the current provider-visible names from:

              direct tools
              union TurnScope.activeTools
              union context-required orchestration tools
              intersect current boundTools
              

              The execution guard must read the immutable step-start active set, not the live map mutated by a search that is settling in the same step.

              No additional public ActivationReceipt or VisibleSnapshot domain type is required. The active map is the state, the thin tool result reports what changed, and the actual provider request is the visibility fact.

              Direct baseline

              Keep the agreed frequent baseline direct when those tools are present in the current binding:

              • Bash
              • Read
              • ArchiveRead
              • Write
              • Edit
              • Glob
              • Grep
              • WebFetch
              • AskUserQuestion
              • StopBackgroundTask
              • tool_search

              Runtime-required tools may still be projected directly when current state requires them. Existing exact hosted-execution profiles and caller-provided boundTools remain hard ceilings.

              Implementation work

              1. Add TurnScope.activeTools: Map<string, MakaTool>.
              2. Replace the current economy/group availability policy with direct and searchable bound-tool derivation.
              3. Build a cached search index from canonical bound tool name and description metadata.
              4. Add the synthetic direct tool_search tool with a per-turn activation callback.
              5. Generate the grouped canonical-name inventory from the effective bound deferred surface.
              6. Project direct + active + required tools before every provider request.
              7. Preserve a step-start gating snapshot so same-step search and hidden-tool execution cannot race.
              8. Union and deduplicate successful repeated and parallel searches.
              9. Record search query, ranked names, activated names, schema characters, and subsequent actual calls for evaluation.
              10. Remove the old model-facing availability mechanisms and update documentation.

              Likely primary files:

              • packages/runtime/src/ai-sdk-backend.ts
              • packages/runtime/src/tool-availability.ts
              • packages/runtime/src/tool-catalog-derive.ts
              • packages/runtime-host/src/server/interactive-run-composer.ts
              • deferred-tool and execution-composition tests

              Migration

              Remove from the new model-facing contract:

              • economy/full mode;
              • MAKA_DISABLE_DEFERRED_TOOLS;
              • predefined groups as activation units;
              • load_tools;
              • load_tool;
              • connect_tool_source;
              • cross-turn activation replay and ledger seeding.

              Historical RuntimeEvents may remain readable when required for old transcript compatibility, but they must never seed a new turn active set.

              Provider-native tool search, if added later, must remain an optimization behind this same Maka-owned contract rather than a second semantic path.

              Acceptance criteria

              1. The initial provider request contains the direct baseline and tool_search, but not deferred complete schemas.
              2. The lightweight inventory lists only currently bound deferred canonical names.
              3. Search results can contain only tools in the current binding ceiling.
              4. The ordinary search result contains activated names without complete schemas.
              5. Search completed in step n exposes complete matching schemas in step n + 1, never step n.
              6. Repeated and parallel searches accumulate a deduplicated active set for the current turn.
              7. A same-step hidden-tool call remains rejected even when a parallel search activates it for the next step.
              8. Provider retries preserve the current turn active set without double activation.
              9. Completion, failure, and cancellation do not leak active tools into another turn.
              10. Exact hosted profiles and explicit boundTools cannot be widened by search.
              11. Direct and discovered tools cross the same permission, durable execution, output bounding, and artifact boundaries.
              12. New turns do not restore activation from historical load_tools or alias calls.
              13. Tests cover direct mode, code mode, graph/swarm required tools, dynamic client tools, retry, parallel calls, and turn cleanup.
              14. Telemetry can report exposed-but-unused tool count/schema characters, top-k recall, repeated searches, and time to first successful tool call.

              Evaluation

              Measure:

              • schemas exposed but never called;
              • schema characters exposed but unused;
              • top-k recall of the tool eventually called;
              • revised or repeated searches;
              • time to the first successful tool call;
              • tasks where the required tool falls outside the per-search activation cap.

              If the measurements show material context waste or retrieval misses, evaluate restoring an explicit model confirmation boundary through load_tools. The first slice intentionally starts with uniform search-and-activate semantics.

              Explicitly out of scope

              • Skill and SkillSearch discovery;
              • goal-tool redesign;
              • provider prompt-cache semantics;
              • provider-native search as a separate contract;
              • unload semantics;
              • cross-turn discovery persistence;
              • changing ToolRuntime execution authority.

              References

              AI assistance disclosure: Maka helped inspect the current Runtime lifecycle, synthesize the agreement from Discussion #3621, and draft this implementation issue. I reviewed and approved the final scope.

              Metadata

              Metadata

              Assignees

              Labels

              enhancementNew feature or request

              Type

              No type

              Projects

              No projects

                Milestone

                No milestone

                Relationships

                None yet

                Development

                No branches or pull requests

                Issue actions

                , 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); feat(runtime): implement turn-scoped tool_search activation · Issue #3752 · apache/maka · GitHub
                Skip to content

                feat(runtime): implement turn-scoped tool_search activation #3752

                Description

                @likun666661

                Problem

                Maka currently controls provider-visible tools through overlapping mechanisms: economy/full mode, predefined load_tools groups, MAKA_DISABLE_DEFERRED_TOOLS, historical connector aliases, and cross-turn ledger seeding. The model-facing contract is difficult to explain, and low-frequency tool schemas can add substantial context cost before the model needs them.

                Discussion #3621 reached agreement on the first implementation slice after working through binding authority, search-space discovery, activation timing, schema visibility, and the tradeoff between automatic activation and a separate confirmation command.

                Related tracker: #1382. This issue implements the provider-independent first slice agreed in #3621 rather than the original provider-native-first and cross-turn persistence assumptions in #1382.

                Desired outcome

                Provide one Maka-owned, provider-independent tool_search contract:

                tool_search(query, limit?)
                -> bounded top-k matches
                -> successful results become active immediately
                -> complete schemas become visible on the next provider step
                -> activation is monotonic within the current turn
                -> activation is cleared when the turn completes
                

                The search ranker selects which bounded schemas become visible. The model selects which visible tool to execute. Runtime binding and execution checks remain authoritative.

                Agreed semantics

                Authority and visibility

                • The tools actually bound to the current run are the capability ceiling.
                • Search metadata and the initial inventory are derived from those bindings.
                • A tool name in the inventory is discoverable metadata, not callable visibility.
                • A tool is visible for a provider step only when its complete callable definition is present in that request.
                • Search never binds a new executable tool and never escapes boundTools.
                • Tool visibility does not replace permission or execution-time validation.

                Initial discovery surface

                The model receives a lightweight inventory of deferred tools before searching:

                group:
                - canonical_tool_name
                - canonical_tool_name
                

                The inventory contains group names and canonical tool names only. Direct tools already have complete definitions and are not repeated. Dynamic client tools are grouped by their derived source metadata.

                Search contract

                Initial interface:

                tool_search({query: string,limit?: number,})

                The first index should use canonical name and description metadata derived from current bound deferred tools. Exact names may affect ranking but must not change the operation semantics: every successful search uniformly activates the matches it returns.

                The ordinary model-facing result stays thin:

                {
                "activated": ["browser_snapshot", "browser_click"]
                }

                Complete schemas must not be duplicated in the ordinary tool result. They enter the next request through the normal provider tool projection.

                Repeated and parallel searches

                • Successful searches add their matches to the current turn active set.
                • Repeated tools are deduplicated.
                • Parallel search results in one provider step are unioned.
                • The model may continue searching and expanding the active set.
                • There is no turn-wide activation budget or unload operation.
                • Each individual search remains bounded by result count and schema bytes.
                • The binding ceiling is the final upper bound.

                Step boundary

                A search result cannot rewrite the request in which the search call was emitted.

                For a search completed during provider step n:

                step n:
                tool_search executes and updates future active tools
                step n + 1:
                matching complete schemas enter the provider request
                

                A parallel hidden-tool call in the same step must still fail the step-start availability guard:

                tool_search("browser")
                browser_click(...)
                

                The search may affect only the next provider request.

                Runtime ownership

                The correct owner of mutable activation state is the existing per-send()TurnScope in packages/runtime/src/ai-sdk-backend.ts.

                classTurnScope{readonlyactiveTools=newMap<string,MakaTool>()// existing per-turn state}

                This matches the current lifecycle:

                • openTurnScope() creates one scope for one send();
                • every provider step and retry in that send shares the scope;
                • overlapping turns on one backend have separate scopes;
                • cleanupAfterTurn() drops the scope on completion, error, or cancellation.

                The backend-scoped ToolAvailabilityRuntime must remain immutable with respect to turn state. It may own bound catalog/index/projection logic, but it must not own mutable activeTools.

                Request projection computes the current provider-visible names from:

                direct tools
                union TurnScope.activeTools
                union context-required orchestration tools
                intersect current boundTools
                

                The execution guard must read the immutable step-start active set, not the live map mutated by a search that is settling in the same step.

                No additional public ActivationReceipt or VisibleSnapshot domain type is required. The active map is the state, the thin tool result reports what changed, and the actual provider request is the visibility fact.

                Direct baseline

                Keep the agreed frequent baseline direct when those tools are present in the current binding:

                • Bash
                • Read
                • ArchiveRead
                • Write
                • Edit
                • Glob
                • Grep
                • WebFetch
                • AskUserQuestion
                • StopBackgroundTask
                • tool_search

                Runtime-required tools may still be projected directly when current state requires them. Existing exact hosted-execution profiles and caller-provided boundTools remain hard ceilings.

                Implementation work

                1. Add TurnScope.activeTools: Map<string, MakaTool>.
                2. Replace the current economy/group availability policy with direct and searchable bound-tool derivation.
                3. Build a cached search index from canonical bound tool name and description metadata.
                4. Add the synthetic direct tool_search tool with a per-turn activation callback.
                5. Generate the grouped canonical-name inventory from the effective bound deferred surface.
                6. Project direct + active + required tools before every provider request.
                7. Preserve a step-start gating snapshot so same-step search and hidden-tool execution cannot race.
                8. Union and deduplicate successful repeated and parallel searches.
                9. Record search query, ranked names, activated names, schema characters, and subsequent actual calls for evaluation.
                10. Remove the old model-facing availability mechanisms and update documentation.

                Likely primary files:

                • packages/runtime/src/ai-sdk-backend.ts
                • packages/runtime/src/tool-availability.ts
                • packages/runtime/src/tool-catalog-derive.ts
                • packages/runtime-host/src/server/interactive-run-composer.ts
                • deferred-tool and execution-composition tests

                Migration

                Remove from the new model-facing contract:

                • economy/full mode;
                • MAKA_DISABLE_DEFERRED_TOOLS;
                • predefined groups as activation units;
                • load_tools;
                • load_tool;
                • connect_tool_source;
                • cross-turn activation replay and ledger seeding.

                Historical RuntimeEvents may remain readable when required for old transcript compatibility, but they must never seed a new turn active set.

                Provider-native tool search, if added later, must remain an optimization behind this same Maka-owned contract rather than a second semantic path.

                Acceptance criteria

                1. The initial provider request contains the direct baseline and tool_search, but not deferred complete schemas.
                2. The lightweight inventory lists only currently bound deferred canonical names.
                3. Search results can contain only tools in the current binding ceiling.
                4. The ordinary search result contains activated names without complete schemas.
                5. Search completed in step n exposes complete matching schemas in step n + 1, never step n.
                6. Repeated and parallel searches accumulate a deduplicated active set for the current turn.
                7. A same-step hidden-tool call remains rejected even when a parallel search activates it for the next step.
                8. Provider retries preserve the current turn active set without double activation.
                9. Completion, failure, and cancellation do not leak active tools into another turn.
                10. Exact hosted profiles and explicit boundTools cannot be widened by search.
                11. Direct and discovered tools cross the same permission, durable execution, output bounding, and artifact boundaries.
                12. New turns do not restore activation from historical load_tools or alias calls.
                13. Tests cover direct mode, code mode, graph/swarm required tools, dynamic client tools, retry, parallel calls, and turn cleanup.
                14. Telemetry can report exposed-but-unused tool count/schema characters, top-k recall, repeated searches, and time to first successful tool call.

                Evaluation

                Measure:

                • schemas exposed but never called;
                • schema characters exposed but unused;
                • top-k recall of the tool eventually called;
                • revised or repeated searches;
                • time to the first successful tool call;
                • tasks where the required tool falls outside the per-search activation cap.

                If the measurements show material context waste or retrieval misses, evaluate restoring an explicit model confirmation boundary through load_tools. The first slice intentionally starts with uniform search-and-activate semantics.

                Explicitly out of scope

                • Skill and SkillSearch discovery;
                • goal-tool redesign;
                • provider prompt-cache semantics;
                • provider-native search as a separate contract;
                • unload semantics;
                • cross-turn discovery persistence;
                • changing ToolRuntime execution authority.

                References

                AI assistance disclosure: Maka helped inspect the current Runtime lifecycle, synthesize the agreement from Discussion #3621, and draft this implementation issue. I reviewed and approved the final scope.

                Metadata

                Metadata

                Assignees

                Labels

                enhancementNew feature or request

                Type

                No type

                Projects

                No projects

                  Milestone

                  No milestone

                  Relationships

                  None yet

                  Development

                  No branches or pull requests

                  Issue actions