@harpua/agent-tools 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +68 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/think.d.ts +28 -0
- package/dist/think.d.ts.map +1 -0
- package/dist/think.js +55 -0
- package/dist/think.js.map +1 -0
- package/package.json +68 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Leath Cooper
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# @harpua/agent-tools
|
|
2
|
+
|
|
3
|
+
Framework-agnostic prebuilt [LangChain](https://github.com/langchain-ai/langchainjs)
|
|
4
|
+
tools for agents. Each tool is a plain `tool()` instance, so it drops into any
|
|
5
|
+
LangChain / LangGraph TypeScript app — a `ToolNode`, `createReactAgent`,
|
|
6
|
+
`bindTools`, or your own executor. The package depends only on
|
|
7
|
+
`@langchain/core` and `zod` (both peers): no NestJS, no LangGraph runtime.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pnpm add @harpua/agent-tools
|
|
13
|
+
# peers you almost certainly already have:
|
|
14
|
+
pnpm add @langchain/core zod
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Tools
|
|
18
|
+
|
|
19
|
+
### `thinkTool(options?)`
|
|
20
|
+
|
|
21
|
+
The Anthropic-style [think tool](https://www.anthropic.com/engineering/claude-think-tool):
|
|
22
|
+
a no-op scratchpad the model calls to record reasoning between tool calls. The
|
|
23
|
+
handler returns an empty string — nothing executes; the thought is simply logged
|
|
24
|
+
for the model's own benefit. Useful before an irreversible action, when policies
|
|
25
|
+
conflict, or when a tool result is surprising.
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
import { thinkTool } from "@harpua/agent-tools";
|
|
29
|
+
import { ToolNode } from "@langchain/langgraph/prebuilt";
|
|
30
|
+
|
|
31
|
+
// Vanilla LangGraph: mount it in a ToolNode like any other tool.
|
|
32
|
+
const toolNode = new ToolNode([thinkTool()]);
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Tune the when-to-think guidance per domain by overriding the description:
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
const think = thinkTool({
|
|
39
|
+
description:
|
|
40
|
+
"Think before cancelling or refunding: confirm the order state and that " +
|
|
41
|
+
"the customer's request matches policy.",
|
|
42
|
+
});
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
`options` is validated with zod (`{ description?: string }`, unknown keys
|
|
46
|
+
rejected). The tool's input schema is `z.object({ thought: z.string() })`.
|
|
47
|
+
|
|
48
|
+
## Using with `@harpua/langgraph`
|
|
49
|
+
|
|
50
|
+
[`@harpua/langgraph`](../langgraph) accepts these tools directly in a graph's
|
|
51
|
+
`tools` array, mixed freely with its own `@LangGraphTool` provider classes:
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
import { LangGraph, defineEdges, START, TOOLS, END } from "@harpua/langgraph";
|
|
55
|
+
import { thinkTool } from "@harpua/agent-tools";
|
|
56
|
+
|
|
57
|
+
@LangGraph({ name: "agent", state: AgentState, tools: [OrderTools, thinkTool()] })
|
|
58
|
+
export class AgentGraph {
|
|
59
|
+
edges = defineEdges<AgentState>([
|
|
60
|
+
{ from: START, to: CallModel },
|
|
61
|
+
{ from: CallModel, to: route<AgentState>(shouldContinue, [TOOLS, END]) },
|
|
62
|
+
{ from: TOOLS, to: CallModel },
|
|
63
|
+
]);
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
The raw tool is mounted into the same `ToolNode` and traced with a
|
|
68
|
+
`langgraph.tool think` span like any DI-bound tool.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,YAAY,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.thinkTool = void 0;
|
|
4
|
+
// Framework-agnostic prebuilt LangChain tools for agents. Every tool is exposed
|
|
5
|
+
// as a small `factory(options?)` returning a `tool()` instance — the shape all
|
|
6
|
+
// future tools follow.
|
|
7
|
+
var think_1 = require("./think");
|
|
8
|
+
Object.defineProperty(exports, "thinkTool", { enumerable: true, get: function () { return think_1.thinkTool; } });
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,gFAAgF;AAChF,+EAA+E;AAC/E,uBAAuB;AACvB,iCAAoC;AAA3B,kGAAA,SAAS,OAAA"}
|
package/dist/think.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { StructuredToolInterface } from "@langchain/core/tools";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
/** Options accepted by {@link thinkTool}. Extra keys are rejected. */
|
|
4
|
+
declare const thinkToolOptionsSchema: z.ZodObject<{
|
|
5
|
+
/** Overrides the default when-to-think description (some domains tune it). */
|
|
6
|
+
description: z.ZodOptional<z.ZodString>;
|
|
7
|
+
}, "strict", z.ZodTypeAny, {
|
|
8
|
+
description?: string | undefined;
|
|
9
|
+
}, {
|
|
10
|
+
description?: string | undefined;
|
|
11
|
+
}>;
|
|
12
|
+
export type ThinkToolOptions = z.input<typeof thinkToolOptionsSchema>;
|
|
13
|
+
/**
|
|
14
|
+
* The Anthropic-style `think` tool: a no-op scratchpad an agent calls to record
|
|
15
|
+
* reasoning between tool calls. The handler returns an empty string, so calling
|
|
16
|
+
* it executes nothing and produces no output beyond the recorded thought.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* import { thinkTool } from "@harpua/agent-tools";
|
|
21
|
+
* import { ToolNode } from "@langchain/langgraph/prebuilt";
|
|
22
|
+
*
|
|
23
|
+
* const toolNode = new ToolNode([thinkTool()]);
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export declare function thinkTool(options?: ThinkToolOptions): StructuredToolInterface;
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=think.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"think.d.ts","sourceRoot":"","sources":["../src/think.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA4BxB,sEAAsE;AACtE,QAAA,MAAM,sBAAsB;IAExB,8EAA8E;;;;;;EAGvE,CAAC;AAEZ,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,uBAAuB,CAO7E"}
|
package/dist/think.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.thinkTool = thinkTool;
|
|
4
|
+
const tools_1 = require("@langchain/core/tools");
|
|
5
|
+
const zod_1 = require("zod");
|
|
6
|
+
/**
|
|
7
|
+
* General-purpose "when to think" guidance, modelled on Anthropic's published
|
|
8
|
+
* guidance for the think tool. Consumers may override it per domain via
|
|
9
|
+
* {@link ThinkToolOptions.description}.
|
|
10
|
+
*/
|
|
11
|
+
const DEFAULT_DESCRIPTION = "Use this tool to reason through a problem before acting. It fetches nothing " +
|
|
12
|
+
"and changes nothing — it only records your reasoning so you can work through " +
|
|
13
|
+
"it step by step. Reach for it between tool calls: before an irreversible " +
|
|
14
|
+
"action, when instructions or policies conflict, or when a tool result is " +
|
|
15
|
+
"surprising and you need to decide what to do next. The thought is recorded " +
|
|
16
|
+
"for your own benefit; nothing is executed.";
|
|
17
|
+
/**
|
|
18
|
+
* Input schema for the think tool. The model fills `thought`; the handler is a
|
|
19
|
+
* no-op, so the field only ever serves as a place to write reasoning.
|
|
20
|
+
*/
|
|
21
|
+
const thinkInputSchema = zod_1.z.object({
|
|
22
|
+
thought: zod_1.z
|
|
23
|
+
.string()
|
|
24
|
+
.describe("Your reasoning. Nothing runs — this is a private scratchpad for working " +
|
|
25
|
+
"through the problem."),
|
|
26
|
+
});
|
|
27
|
+
/** Options accepted by {@link thinkTool}. Extra keys are rejected. */
|
|
28
|
+
const thinkToolOptionsSchema = zod_1.z
|
|
29
|
+
.object({
|
|
30
|
+
/** Overrides the default when-to-think description (some domains tune it). */
|
|
31
|
+
description: zod_1.z.string().min(1).optional(),
|
|
32
|
+
})
|
|
33
|
+
.strict();
|
|
34
|
+
/**
|
|
35
|
+
* The Anthropic-style `think` tool: a no-op scratchpad an agent calls to record
|
|
36
|
+
* reasoning between tool calls. The handler returns an empty string, so calling
|
|
37
|
+
* it executes nothing and produces no output beyond the recorded thought.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* import { thinkTool } from "@harpua/agent-tools";
|
|
42
|
+
* import { ToolNode } from "@langchain/langgraph/prebuilt";
|
|
43
|
+
*
|
|
44
|
+
* const toolNode = new ToolNode([thinkTool()]);
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
function thinkTool(options) {
|
|
48
|
+
const { description } = thinkToolOptionsSchema.parse(options ?? {});
|
|
49
|
+
return (0, tools_1.tool)(() => "", {
|
|
50
|
+
name: "think",
|
|
51
|
+
description: description ?? DEFAULT_DESCRIPTION,
|
|
52
|
+
schema: thinkInputSchema,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=think.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"think.js","sourceRoot":"","sources":["../src/think.ts"],"names":[],"mappings":";;AAqDA,8BAOC;AA5DD,iDAA6C;AAE7C,6BAAwB;AAExB;;;;GAIG;AACH,MAAM,mBAAmB,GACvB,8EAA8E;IAC9E,+EAA+E;IAC/E,2EAA2E;IAC3E,2EAA2E;IAC3E,6EAA6E;IAC7E,4CAA4C,CAAC;AAE/C;;;GAGG;AACH,MAAM,gBAAgB,GAAG,OAAC,CAAC,MAAM,CAAC;IAChC,OAAO,EAAE,OAAC;SACP,MAAM,EAAE;SACR,QAAQ,CACP,0EAA0E;QACxE,sBAAsB,CACzB;CACJ,CAAC,CAAC;AAEH,sEAAsE;AACtE,MAAM,sBAAsB,GAAG,OAAC;KAC7B,MAAM,CAAC;IACN,8EAA8E;IAC9E,WAAW,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;CAC1C,CAAC;KACD,MAAM,EAAE,CAAC;AAIZ;;;;;;;;;;;;GAYG;AACH,SAAgB,SAAS,CAAC,OAA0B;IAClD,MAAM,EAAE,WAAW,EAAE,GAAG,sBAAsB,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;IACpE,OAAO,IAAA,YAAI,EAAC,GAAG,EAAE,CAAC,EAAE,EAAE;QACpB,IAAI,EAAE,OAAO;QACb,WAAW,EAAE,WAAW,IAAI,mBAAmB;QAC/C,MAAM,EAAE,gBAAgB;KACzB,CAAC,CAAC;AACL,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@harpua/agent-tools",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"description": "Framework-agnostic prebuilt LangChain tools for agents (works with any LangChain/LangGraph app)",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/IcculusC/harpua.git",
|
|
9
|
+
"directory": "packages/agent-tools"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/IcculusC/harpua/tree/main/packages/agent-tools#readme",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/IcculusC/harpua/issues"
|
|
14
|
+
},
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"access": "public"
|
|
17
|
+
},
|
|
18
|
+
"main": "dist/index.js",
|
|
19
|
+
"types": "dist/index.d.ts",
|
|
20
|
+
"files": [
|
|
21
|
+
"dist",
|
|
22
|
+
"README.md"
|
|
23
|
+
],
|
|
24
|
+
"jest": {
|
|
25
|
+
"moduleFileExtensions": [
|
|
26
|
+
"js",
|
|
27
|
+
"json",
|
|
28
|
+
"ts"
|
|
29
|
+
],
|
|
30
|
+
"rootDir": "src",
|
|
31
|
+
"testRegex": ".*\\.spec\\.ts$",
|
|
32
|
+
"transform": {
|
|
33
|
+
"^.+\\.(t|j)s$": [
|
|
34
|
+
"ts-jest",
|
|
35
|
+
{
|
|
36
|
+
"tsconfig": "<rootDir>/../tsconfig.json"
|
|
37
|
+
}
|
|
38
|
+
]
|
|
39
|
+
},
|
|
40
|
+
"collectCoverageFrom": [
|
|
41
|
+
"**/*.(t|j)s"
|
|
42
|
+
],
|
|
43
|
+
"coverageDirectory": "../coverage",
|
|
44
|
+
"testEnvironment": "node",
|
|
45
|
+
"testTimeout": 30000
|
|
46
|
+
},
|
|
47
|
+
"peerDependencies": {
|
|
48
|
+
"@langchain/core": "^1",
|
|
49
|
+
"zod": "^3 || ^4"
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@langchain/core": "1.2.1",
|
|
53
|
+
"@types/jest": "30.0.0",
|
|
54
|
+
"@types/node": "22.15.30",
|
|
55
|
+
"eslint": "9.39.4",
|
|
56
|
+
"jest": "30.4.2",
|
|
57
|
+
"ts-jest": "29.4.11",
|
|
58
|
+
"typescript": "5.9.3",
|
|
59
|
+
"zod": "3.25.76",
|
|
60
|
+
"@harpua/eslint-config": "0.0.0",
|
|
61
|
+
"@harpua/typescript-config": "0.0.0"
|
|
62
|
+
},
|
|
63
|
+
"scripts": {
|
|
64
|
+
"build": "tsc -p tsconfig.build.json",
|
|
65
|
+
"lint": "eslint \"src/**/*.ts\"",
|
|
66
|
+
"test": "jest"
|
|
67
|
+
}
|
|
68
|
+
}
|