Skip to content

refactor: Group tool-call params into lifetime-scoped contexts #1156

Description

@jirispilka

Problem

The shared tool-call path threads flat plain values through every layer, so each signature is the union of everything below it: executeToolAndUpdateTask takes ~20 fields, dispatchToolCall ~19, prepareToolCall ~13, executeSyncToolCall ~11. Adding or removing one value touches every layer — e.g. removing loadedToolNames in #1155 changed four signatures.

Proposal

Group params by lifetime into plain-data context objects, built once at the adapter boundary:

  • SessionContext — fixed after initialize: tools, actorStore, paymentProvider, allowUnauthMode, telemetryEnabled, telemetryEnv, transportType, clientContext, taskStore
  • RequestContext — one per tools/call: apifyToken, apifyClient, mcpSessionId, progressToken, signal, sendNotification, emitLog, requestHeaders
  • Call-specific args stay inline: tool, toolArgs, logSafeArgs, taskMode, logContext

Engine functions declare the narrowest view they read (Pick<SessionContext, ...> or a small interface), callers pass the whole context — call sites shrink to ~3 arguments while signatures still document real dependencies.

Non-goals

  • No single merged Context holding all lifetimes (that's the server object again).
  • No behavior in contexts beyond the existing sendNotification/emitLog capabilities.
  • No behavior change; mechanical refactor only.

Sequencing

After #1140 — a request-scoped tool map moves tools from session to request scope, so decide that boundary first. Relevant to #1128: a stateless adapter would build the same contexts from its own request state, making the context types the protocol-neutral contract.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions