name: Hedera Agent Kit v4 Migration
description: This skill should be used when the user asks to "migrate to hedera-agent-kit v4", "upgrade hak v3 to v4", "convert plugin to BaseTool", "migrate Tool to BaseTool", "rename hedera-agent-kit imports", "fix v3 deprecation warnings", or has a project still on hedera-agent-kit@3.x / @hashgraph/sdk that needs to move to @hashgraph/hedera-agent-kit@4.x / @hiero-ledger/sdk. Covers both custom-plugin migration (Tool → BaseTool) and toolkit-consumer migration (LangChain/AI SDK/ElizaOS/MCP).
version: 1.0.0
Migrating Hedera Agent Kit v3 → v4
This skill drives a complete v3 → v4 migration. v4 is the current major; v3 (hedera-agent-kit@3.x) no longer receives updates. Use this skill whenever you see code importing from hedera-agent-kit (unscoped) or @hashgraph/sdk.
Quick triage — what kind of v3 code is this?
Before editing anything, classify the file you are migrating. The migration steps differ.
| If the file… | It's a… | Apply |
|---|---|---|
Defines a Plugin and exports tool factories that return object literals with an execute function |
Custom plugin | Plugin migration + BaseTool migration |
Calls new HederaLangchainToolkit / HederaAIToolkit / HederaElizaOSToolkit / HederaMCPToolkit |
Toolkit consumer | Toolkit migration |
Imports plugins like coreTokenPlugin, coreAccountPlugin, coreHTSPlugin |
Toolkit consumer (uses built-in plugins) | Toolkit migration + alias rename |
Imports ResponseParserService or HederaMCPServer from hedera-agent-kit |
Toolkit consumer | Toolkit migration (these moved to toolkit packages) |
| Both | Run toolkit migration first, then plugin migration for each tool |
Migration workflow
Step 1 — find every v3 entry point
Run these searches at the project root before editing anything. They give you the migration surface in one shot:
# Old package name in source and dependency manifests
grep -rn "from ['\"]hedera-agent-kit" .
grep -n '"hedera-agent-kit"' package.json
# Old SDK package
grep -rn "from ['\"]@hashgraph/sdk" .
grep -n '"@hashgraph/sdk"' package.json
# Deprecated plugin aliases
grep -rn "coreHTSPlugin\|coreSCSPlugin\|coreQueriesPlugin" .
# Old subpath import
grep -rn "from ['\"]hedera-agent-kit/elizaos" .
# v3 functional Tool pattern (object literal with execute)
grep -rn "execute: " . --include="*.ts" | grep -i "tool"
Build a list of files to edit; do not start mutating yet.
Step 2 — update package.json
Replace dependencies, then run install. See references/breaking-changes.md § "Package mapping" for the complete table and § "Versioning" for version ranges. Quick form:
- Remove:
hedera-agent-kit,@hashgraph/sdk. Drop@langchain/core,langchain,@langchain/langgraph,aionly if your code never imports from them directly — they are transitive deps of the toolkit, so package managers with strict resolution (bun, pnpm) won't satisfy direct imports unless you keep them. When in doubt, keep them as devDeps. - Add:
@hashgraph/hedera-agent-kit(use^4.0.0) and@hiero-ledger/sdk(use^2.81.0), plus exactly one toolkit package for your framework. Toolkit packages are NOT on^4— they re-baselined at1.0.0for this release. Use^1.0.0for@hashgraph/hedera-agent-kit-langchain/-ai-sdk/-elizaos/-mcp. Runnpm view <pkg> versionto confirm before pinning. - Keep: the LLM provider (
@langchain/openai,@ai-sdk/openai,@langchain/anthropic, etc.) — toolkits never bundle providers. LangChain consumers must also bump the provider package to its1.xline (e.g.@langchain/openai@^1); the0.xline depends on@langchain/core@^0.3and produces dual-package type errors against the toolkit's@langchain/core@^1. Seereferences/breaking-changes.md§ "LangChain ecosystem bump".
Step 3 — rewrite imports
Apply the find-and-replace map from references/import-cheatsheet.md. Key moves:
- from 'hedera-agent-kit' → from '@hashgraph/hedera-agent-kit'
- from '@hashgraph/sdk' → from '@hiero-ledger/sdk'
- from 'hedera-agent-kit/elizaos' → from '@hashgraph/hedera-agent-kit-elizaos'
Plugins must come from the /plugins subpath:
- import { coreTokenPlugin } from 'hedera-agent-kit'
+ import { coreTokenPlugin } from '@hashgraph/hedera-agent-kit/plugins'
Rename deprecated aliases:
| Removed | Replacement |
|---|---|
coreHTSPlugin |
coreTokenPlugin |
coreSCSPlugin |
coreEVMPlugin |
coreQueriesPlugin |
Individual plugins: coreAccountQueryPlugin, coreTokenQueryPlugin, coreConsensusQueryPlugin, coreEVMQueryPlugin, coreMiscQueriesPlugin, coreTransactionQueryPlugin |
Toolkits and their helpers each moved to a dedicated package:
- import { HederaLangchainToolkit, ResponseParserService } from 'hedera-agent-kit'
+ import { HederaLangchainToolkit, ResponseParserService } from '@hashgraph/hedera-agent-kit-langchain'
- import { HederaAIToolkit } from 'hedera-agent-kit'
+ import { HederaAIToolkit } from '@hashgraph/hedera-agent-kit-ai-sdk'
- import { HederaMCPToolkit } from 'hedera-agent-kit'
+ import { HederaMCPToolkit } from '@hashgraph/hedera-agent-kit-mcp'
AgentMode, Configuration, Context, Plugin, Tool, BaseTool, handleTransaction, output parsers, mirrornode types — all stay in @hashgraph/hedera-agent-kit.
Step 4 — fix the silent behaviour change in toolkit configuration
In v3 an empty plugins: [] may have loaded default tools. In v4, empty means zero tools. This will not throw — the agent will silently have nothing to call. Audit every toolkit construction:
// v4: pass plugins explicitly
import { allCorePlugins } from '@hashgraph/hedera-agent-kit/plugins';
new HederaLangchainToolkit({
client,
configuration: {
plugins: allCorePlugins, // or list specific plugins
context: { mode: AgentMode.AUTONOMOUS },
},
});
Use allCorePlugins to preserve v3's "everything" default. Prefer explicit lists when the user wants a smaller tool surface; bundlers tree-shake either way.
Step 5 — handle RETURN_BYTES consumers
If any code reads parsedData.raw.bytes from ResponseParserService and converts it (e.g. Buffer.isBuffer(...), Buffer.from(obj.data)), delete the conversion. v4 standardises raw.bytes to Uint8Array everywhere; passing it directly to Transaction.fromBytes() works in Node and browser. See references/breaking-changes.md § "RETURN_BYTES".
Step 6 — migrate every custom plugin tool to BaseTool
BaseTool is the supported shape for tools in v4. Every custom tool must be migrated — the v3 functional pattern (object literal with an execute function) is no longer the supported authoring style and bypasses the hooks/policies system (HcsAuditTrailHook, MaxRecipientsPolicy, RejectToolPolicy, and any subclass of AbstractHook/AbstractPolicy). Migrate every tool the plugin exports; do not leave a mix of old- and new-style tools.
Full step-by-step recipe with annotated before/after: references/basetool-migration.md.
Mechanical summary:
- Replace
import type { Tool }withimport { BaseTool }from@hashgraph/hedera-agent-kit. - Rewrite the factory:
(context: Context): Tool => ({ ... execute })becomes a class extendingBaseTooland a one-line factory(context) => new MyTool(context). - Split the body of the old
executefunction into:normalizeParams(resolve defaults, validate format)coreAction(build theTransactionfor mutations, fetch the data for queries)secondaryAction(callhandleTransaction(...)for mutations; pass-through for queries)
- For query-only tools, override
shouldSecondaryActionto returnfalseand provide a no-opsecondaryAction. - Move the
try/catchbody into anhandleError(error, context)override (BaseTool calls it from any failed stage). - Keep the factory return type
BaseTool—Plugin.tools()accepts it directly.
The example under examples/transfer-hbar-migration/ shows the full transformation on the canonical transfer_hbar tool.
Step 7 — verify
After mutating files, run in this order:
npm install(orbun install/pnpm install) — confirmspackage.jsonresolves. Watch for "no version matching X" errors; toolkit packages are on^1, not^4.tsc --noEmit(ornpm run build) — picks up missing imports and type drifts (e.g.setTreasuryAccountIdcomplaining because a normalised type was not declared, ornoImplicitOverridecomplaining about a missingoverridekeyword onhandleError/secondaryAction).- For LangChain consumers, type errors mentioning two different
@langchain/corepaths (one nested under your provider package, one nested under the toolkit) indicate a dual-package situation — the provider package is still on0.x. Bump it to1.xper Step 2. - For LangChain consumers, errors like
Cannot find module 'langchain/agents'or'langchain/memory'indicate the legacyAgentExecutor/BufferMemorypattern — these subpaths were removed inlangchain@1.x. The fix is a separate framework migration tocreateReactAgentfrom@langchain/langgraph/prebuilt. Seereferences/breaking-changes.md§ "LangChain ecosystem bump". - Smoke-test the agent: instantiate the toolkit, list tools (
toolkit.getTools().lengthmust be > 0), invoke one tool end-to-end. A passing build does not prove the migration worked — the empty-plugins-array footgun is type-safe and silent.
What this skill does NOT cover
- Solidity / system-contracts migration — see the
system-contractsplugin. - Native JS SDK changes inside
@hiero-ledger/sdkitself — only the import path changes; the API surface remained stable across the rename. - Plugin authoring patterns from scratch — see the
agent-kit-pluginskill. - Writing new hooks/policies — see
agent-kit-hookandagent-kit-policyskills. Migration toBaseToolis the prerequisite for those features. - LangChain framework migration (
AgentExecutor→createReactAgent,BufferMemory→messages-based history). The v4 LangChain toolkit forces a bump tolangchain@1.x, which removes these APIs, but rewriting the agent setup is a LangChain-side concern.references/breaking-changes.md§ "LangChain ecosystem bump" sketches the shape of the change; consult LangChain's own migration guide for details.
Reference index
references/breaking-changes.md— every breaking change, package mapping, install commands, version-bump notes.references/import-cheatsheet.md— flat find-and-replace table; load this when sweeping files.references/basetool-migration.md— annotated before/after for converting one tool from theToolobject literal to aBaseToolsubclass, including the query-only variant.examples/transfer-hbar-migration/—before-v3.tsandafter-v4.tsof the same tool, side by side, with aREADME.mdwalking through every change.