Skip to content

Commit 60e0d2a

Browse files
committed
docs: document agent tool adapters
1 parent 634174f commit 60e0d2a

14 files changed

Lines changed: 85 additions & 10 deletions

src/agents/agent-tool-definition-adapter.after-tool-call.test.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
/**
2+
* Regression tests for adapter interaction with after_tool_call hooks.
3+
* Ensures embedded run subscription handling remains the single after-hook
4+
* execution path.
5+
*/
16
import type { AgentTool } from "openclaw/plugin-sdk/agent-core";
27
import { Type } from "typebox";
38
import { beforeEach, describe, expect, it, vi } from "vitest";

src/agents/agent-tool-definition-adapter.logging.test.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
/**
2+
* Logging tests for tool adapter failures.
3+
* Verifies retryable parameter errors expose useful context while intentional
4+
* hook blocks and exec secrets stay out of raw logs.
5+
*/
16
import type { AgentTool } from "openclaw/plugin-sdk/agent-core";
27
import { Type } from "typebox";
38
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";

src/agents/agent-tool-definition-adapter.test.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
/**
2+
* Unit coverage for adapting runtime and client-hosted tools.
3+
* Exercises result coercion, error wrapping, client delegation, and conflict
4+
* detection at the ToolDefinition boundary.
5+
*/
16
import type { AgentTool } from "openclaw/plugin-sdk/agent-core";
27
import { Type } from "typebox";
38
import { describe, expect, it } from "vitest";

src/agents/agent-tool-definition-adapter.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
/**
2+
* Adapts runtime AgentTool objects into session ToolDefinition entries.
3+
* Owns hook execution, client-tool delegation, result coercion, and safe
4+
* logging for failed tool calls.
5+
*/
16
import { createHash } from "node:crypto";
27
import { logDebug, logError } from "../logger.js";
38
import { redactToolDetail } from "../logging/redact.js";
@@ -304,6 +309,7 @@ function finalizeToolParamsBeforeExecute(params: {
304309

305310
export const CLIENT_TOOL_NAME_CONFLICT_PREFIX = "client tool name conflict:";
306311

312+
/** Find client-hosted tool names that collide with runtime or sibling tools. */
307313
export function findClientToolNameConflicts(params: {
308314
tools: ClientToolDefinition[];
309315
existingToolNames?: Iterable<string>;
@@ -338,14 +344,17 @@ export function findClientToolNameConflicts(params: {
338344
return Array.from(conflicts);
339345
}
340346

347+
/** Build a recognizable error for rejecting conflicting client tool names. */
341348
export function createClientToolNameConflictError(conflicts: string[]): Error {
342349
return new Error(`${CLIENT_TOOL_NAME_CONFLICT_PREFIX} ${conflicts.join(", ")}`);
343350
}
344351

352+
/** Detect client tool conflict errors without depending on object identity. */
345353
export function isClientToolNameConflictError(err: unknown): err is Error {
346354
return err instanceof Error && err.message.startsWith(CLIENT_TOOL_NAME_CONFLICT_PREFIX);
347355
}
348356

357+
/** Convert executable agent tools into session definitions with hook handling. */
349358
export function toToolDefinitions(
350359
tools: AnyAgentTool[],
351360
hookContext?: HookContext,
@@ -477,8 +486,7 @@ function coerceParamsRecord(value: unknown): Record<string, unknown> {
477486
return {};
478487
}
479488

480-
// Convert client tools (OpenResponses hosted tools) to ToolDefinition format
481-
// These tools are intercepted to return a "pending" result instead of executing
489+
/** Convert client-hosted tools into pending session definitions. */
482490
export function toClientToolDefinitions(
483491
tools: ClientToolDefinition[],
484492
onClientToolCall?: ClientToolCallRecorder,

src/agents/agent-tool-handler-state.test-helpers.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1+
/**
2+
* Fixtures for embedded agent tool-handler state tests.
3+
* Keeps large mutable handler state construction centralized so assertions can
4+
* focus on the field under test.
5+
*/
16
import { createEmbeddedRunReplayState } from "./embedded-agent-runner/replay-state.js";
27

3-
// Shared fixture for tests that exercise embedded agent tool handler state.
48
/** Build the minimal mutable state object expected by tool handler tests. */
59
export function createBaseToolHandlerState() {
610
return {

src/agents/agent-tools-parameter-schema.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
/**
2+
* Normalizes model-facing tool parameter schemas across provider quirks.
3+
* Handles local JSON Schema refs, OpenAPI nullable syntax, top-level unions,
4+
* and provider-specific unsupported keyword stripping.
5+
*/
16
import { isRecord as isSchemaRecord } from "@openclaw/normalization-core/record-coerce";
27
import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce";
38
import { uniqueValues } from "@openclaw/normalization-core/string-normalization";
@@ -589,6 +594,7 @@ function inlineLocalSchemaRefsWithDefs(
589594
return result;
590595
}
591596

597+
/** Inline local $ref pointers so providers receive self-contained tool schemas. */
592598
export function inlineLocalToolSchemaRefs(schema: unknown): TSchema {
593599
if (!schema || typeof schema !== "object") {
594600
return schema as TSchema;
@@ -881,6 +887,7 @@ function normalizeToolParameterSchemaUncached(
881887
return applyProviderCleaning(flattenedSchema);
882888
}
883889

890+
/** Return a provider-compatible JSON schema for a model-facing tool. */
884891
export function normalizeToolParameterSchema(
885892
schema: unknown,
886893
options?: ToolParameterSchemaOptions,

src/agents/agent-tools.deferred-followup-guidance.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
/**
2+
* Tests cron-aware deferred follow-up guidance in exec/process descriptions.
3+
* Protects the model-facing text selected after tool filtering.
4+
*/
15
import { describe, expect, it } from "vitest";
26
import { applyDeferredFollowupToolDescriptions } from "./agent-tools.deferred-followup.js";
37
import type { AnyAgentTool } from "./agent-tools.types.js";

src/agents/agent-tools.deferred-followup.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1+
/**
2+
* Adjusts exec/process tool descriptions for long-running follow-up behavior.
3+
* Cron-aware runs can point models at scheduled follow-ups; cronless runs keep
4+
* guidance constrained to process polling and wake handling.
5+
*/
16
import type { AnyAgentTool } from "./agent-tools.types.js";
27
import { describeExecTool, describeProcessTool } from "./bash-tools.descriptions.js";
38

4-
// Updates exec/process tool descriptions with deferred-followup guidance based
5-
// on the tools available in the current run.
69
/** Return tools with exec/process descriptions adjusted for cron availability. */
710
export function applyDeferredFollowupToolDescriptions(
811
tools: AnyAgentTool[],

src/agents/agent-tools.message-provider-policy.test.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
/**
2+
* Tests message-provider tool filtering.
3+
* Voice-like transports should not expose text-to-speech when that surface is
4+
* unsafe or redundant for the active channel.
5+
*/
16
import { describe, expect, it } from "vitest";
27
import { filterToolNamesByMessageProvider } from "./agent-tools.message-provider-policy.js";
38

src/agents/agent-tools.message-provider-policy.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
/**
2+
* Message-provider tool filtering.
3+
* Channels can restrict tool names after runtime assembly when the active
4+
* transport cannot safely render or execute a class of tools.
5+
*/
16
import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce";
27

3-
// Message providers can narrow the tool surface when a channel cannot safely
4-
// render or execute a tool class. The policy is name-based because channel
5-
// delivery happens after tools are already assembled.
68
const TOOL_DENY_BY_MESSAGE_PROVIDER: Readonly<Record<string, readonly string[]>> = {
79
"discord-voice": ["tts"],
810
voice: ["tts"],

0 commit comments

Comments
 (0)