Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ const triage = agent({
```

Rig defaults agent tools to `skipPermission: true`, and you can also place plain tool objects in `tools`; rig will convert `s.*` parameter schemas into JSON Schema before creating the Copilot session.
When `parameters` uses `s.*` schemas, `handler` args are inferred automatically; for plain JSON Schema, pass an explicit generic like `defineTool<{ issue: string }>(...)`.

## Evaluating agentic performance

Expand Down
1 change: 1 addition & 0 deletions skills/rig/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ s.nonEmptyArray(s.string) // string[] with at least one element
## Tools

Register custom tools with `defineTool` using an SDK-neutral tool shape. Use `s.*` schemas for `parameters`. Rig defaults tools to `skipPermission: true`.
When `parameters` uses `s.*` schemas, `handler` args are inferred automatically; for plain JSON Schema, pass an explicit generic like `defineTool<{ issue: string }>(...)`.

```ts
import { agent, defineTool, s } from "rig";
Expand Down
10 changes: 8 additions & 2 deletions skills/rig/rig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -540,8 +540,14 @@ export type ToolConfig<TArgs = unknown> = {
overridesBuiltInTool?: boolean;
skipPermission?: boolean;
};

export function defineTool<T = unknown>(name: string, config: ToolConfig<T>): Tool<T> {
type InferToolArgs<TParameters extends ToolParameters> = TParameters extends Schema ? InferSchema<TParameters> : unknown;

export function defineTool<const TParameters extends ToolParameters>(
name: string,
config: Omit<ToolConfig<InferToolArgs<TParameters>>, "parameters"> & { parameters: TParameters },
): Tool<InferToolArgs<TParameters>>;
export function defineTool<T = unknown>(name: string, config: ToolConfig<T>): Tool<T>;
export function defineTool(name: string, config: ToolConfig<any>): Tool<any> {
return {
name,
...normalizeToolConfig(config),
Expand Down
8 changes: 5 additions & 3 deletions src/rig.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ vi.mock("@github/copilot-sdk", () => ({
}));

import { AgentError, PromptBuilder, agent, analyzeResponse, configureAgent, copilotEngine, defineTool, p, s, toJsonSchema } from "rig";
import type { Tool } from "rig";
import { oncePerAgent, repair, steering, timeout } from "rig/addons";

beforeEach(() => {
Expand Down Expand Up @@ -537,18 +538,19 @@ describe("agent invocation", () => {
});

it("defines tools with rig schemas using the Copilot SDK helper shape", () => {
const handler = vi.fn(async ({ issue }: { issue: string }) => `Issue ${issue}`);
const lookupIssue = defineTool("lookup_issue", {
description: "Look up an issue by id.",
parameters: s.object({ issue: s.string }),
handler,
handler: vi.fn(async ({ issue }) => `Issue ${issue}`),
});
const expectIssueTool = (_tool: Tool<{ issue: string }>) => true;
expect(expectIssueTool(lookupIssue)).toBe(true);

expect(lookupIssue).toEqual({
name: "lookup_issue",
description: "Look up an issue by id.",
parameters: toJsonSchema(s.object({ issue: s.string })),
handler,
handler: expect.any(Function),
skipPermission: true,
});
});
Expand Down