@chamvi/core

中文文档
0.8.0发布于 2026/11/09Apache-2.0TypeScriptES Module构建来源已验证近 30 天下载 5279

用于自发托管,触发驱动的AI代理的核心引擎:代理,触发和可持久运行.

中文使用文档
文档目录16 节
  1. 为什么?
  2. 安装
  3. 使用量
  4. 代理人和渠道
  5. 效果工具
  6. 核准
  7. 内容不可信
  8. 输入器和工具访问
  9. 代理状态
  10. 储存和储存库
  11. A. 背景情况
  12. 选项
  13. 结构化指令
  14. API 密码
  15. 页:1
  16. 许可证

@chamvi/core

@ chamvi/ 核心

自发主机,频道驱动AI代理机的核心引擎:代理机,频道和可持久运行.
你用AI SDK给特工写信 引擎排队运行, 检查每一个步骤,
暂停批准和中断的接头又在平坦的节点过程中运行.

npm version CI License

安装 • 妇女 使用量 • 妇女 选项 • 妇女 API 密码 • 妇女 页:1


为什么?

AI SDK运行模型及其工具回路,并站在那里. 一个对webhooks和日程表作出反应的代理商也需要一个工作排队的地方,一个在跑道上半程重启的被吊舱生存的方法,一个在重试后两次发出相同评论的戒备,以及一个等待人类批准呼叫的一天的方法. 这通常是指主机管弦乐手,或者很多胶相编码.

@chamvi/core 该图层作为库,没有管弦乐服务器,也没有Redis:

关切AI SDK 独自行动@ chamvi/ 核心
摄入量你打电话 generateText 从您的处理器dispatch() 存储 a queued 运行; a idempotencyKey 将重交付转换为当前运行
货币两个同一期的网友互相比赛每跑一次一次 concurrencyKey,通过复制品的商店执行
重复性撞车会失去对话每一步后都有一个检查站;从最近一个检查站恢复运行
副作用重审工具呼叫帖defineEffectTool() 记录每个效果键的每个结果,并可以在动作前检查远程系统
核准你建起暂停,存储和召回await approve(ctx, { title }) 在工具中暂停运行 waiting,跨越重启; engine.approve() 或者说 resume(token, decision) 答案和电话随决定重播
限制stopWhen 每个呼叫maxSteps, (中文(简体) ), maxTokens 财务报告和审定财务报表 timeoutMs 每跑一次,以 completed 或者说 failed
关闭运行随进程而死drain() 等待飞行,然后标记其余部分 interrupted 用于另一个复制

模型、消息和工具保留AI SDK类型: defineModelAgent() 使用一个 LanguageModel (或 a 个) '<provider>/<model id>' 串起引擎解决 EngineOptions.models和一个平地 ToolSet (与 tool(),或 defineTool() 用于读取运行上下文的工具),而没有任何东西被chamvi类型所包裹.

dispatch() stores a queued run, deduplicated by idempotency key. The engine claims it and runs it: every LLM or tool step is followed by a checkpoint in the store. A run ends completed, failed or cancelled. A tool that awaits approve() pauses the run in waiting; approving or denying it requeues the run, and the call runs again with the decision. drain() or a crashed process leaves a run interrupted or with an expired claim; recover() requeues it, and the next execution continues from the latest checkpoint.

目录

安装

npm install @chamvi/core ai --save

仅限无害环境管理,节点.js >=26.0.0。 。 。 . ai@^7 (Vercel AI SDK)是一个对等依赖; 添加您的模型的提供者包, 例如 @ai-sdk/anthropic。 。 。 .

使用量

一个代理商、一个内存商店、一个开发控制台频道和一个手动发送的运行,其答案来自:

import type { LanguageModel } from 'ai';
import { z } from 'zod';
import {
    Engine,
    consoleChannel,
    createMemoryStore,
    defineEffectTool,
    defineModelAgent,
} from '@chamvi/core';

export async function triageIssue(model: LanguageModel) {
    const labels: string[] = [];
    const lines: string[] = [];

    const triage = defineModelAgent({
        name: 'triage',
        model,
        instructions: 'Label the issue in the trigger payload as bug, feature or question.',
        budget: { maxSteps: 5 },
        tools: {
            // the result is recorded per (run, tool, input): a resumed run reuses it
            addLabel: defineEffectTool({
                description: 'Adds a label to the issue.',
                inputSchema: z.object({ label: z.enum(['bug', 'feature', 'question']) }),
                execute: async ({ label }, { context }) => {
                    labels.push(label);
                    // answers where the run came from, at most once per message
                    await context.channels.findOne()?.emit({ body: `Labelled as ${label}.` });

                    return { added: label };
                },
            }),
        },
    });

    const engine = new Engine({
        store: createMemoryStore(),
        agents: [triage],
        channels: [consoleChannel({
            write: (line) => {
                lines.push(line);
            },
        })],
    });

    await engine.start();

    const { runId } = await engine.dispatch({
        agent: 'triage',
        trigger: 'manual',
        channel: 'console',
        address: 'issue-1',
        payload: { title: 'App crashes on start' },
    });

    await engine.idle();
    await engine.stop();

    return {
        run: await engine.getRun(runId),
        labels,
        lines,
    };
}

跑步解决了 completed,以及 output 是模型最后答案的文本(结构化为 output,解析值;控制台频道已写入 Labelled as bug. 一次 一次吗 这是代码 test/fixtures/readme-example.ts,测试套房运行 与脚本模型.

代理人和渠道

  • defineModelAgent() 检查名称( n)^[a-z0-9]+(-[a-z0-9]+)*$,最多64个字符),且订阅代号是独一无二的,并填写默认预算(maxSteps: 20, (中文(简体) ), timeoutMs: 900_000) (中文(简体) ).
  • tools 一个简单的AI SDK ToolSet,在模块范围或工厂中定义一次 (ctx) => ToolSet 用于动态集(称为每次执行一次)。 工具构建 defineTool() (或 defineEffectTool())将运行上下文读取为 context 内 execute数字 : run (单位:千美元)runId, (中文(简体) ), agent, (中文(简体) ), trigger, (中文(简体) ), signal),经纪人的 state 和运行 artifacts每一次执行一次,每个呼叫和工厂都有一个上下文;视之为不可改变.
const lookup = defineTool({
    inputSchema: z.object({ issue: z.number() }),
    execute: async ({ issue }, { context }) => fetchIssue(issue, { signal: context.run.signal }),
});
  • 只有工具,他们 contextSchema 是查姆维的 toolContextSchema 获取背景。 具有自身能力的第三方工具 contextSchema 获得代理的输入 toolsContext,通过参考。 输入工具的计程器失败运行 validation_error,而不记录值。 命名一个 chamvi 工具或没有工具的条目是一个 InvalidAgentDefinitionError (推着) defineModelAgent() 对于一个平地的集, 一个工厂失败运行.
tools: { search: searchTool },
toolsContext: { search: { apiKey: process.env.SEARCH_KEY } },
  • 一个频道( A)IChannel数字 : name选项 defaultAddress, (中文(简体) ), start, (中文(简体) ), stop, (中文(简体) ), in, (中文(简体) ), out任何来自跑步或交谈的事物; new Engine({ channels }) 注册它们(名称遵循代理名称规则,每个引擎独有). start() 第一次恢复后启动每个频道(start({ channels: false }) 开始无, drain() 财务报告和审定财务报表 stop() 先拦住他们 代理用户通过 channels: ChannelSubscription[],每个指定一个注册频道(拒绝一个未知频道)。 一个频道通过其 ChannelContext,设置 channel 以自己的名义.
  • 出道由工具驱动:引擎从未发出自己的信息. 在一个工具, ctx.channels.findOne(name) 返回注册频道上的控件 out,或 undefined;没有名称,它是运行的源频道,与其源地址相接. ctx.channels.findOneOrFail(name?) 掷出 ChannelNotFoundError (单位:千美元)channel_not_found改为 undefined,以及 ctx.channels.find() 返回每个频道 out。 。 。 . handle.emit({ title?, body, key? }, address?) 通过频道发送 out;地址默认为源频道上的源地址,否则为频道的 defaultAddress (单位:千美元)consoleChannel() 有它的名称, OpenClaw 频道 deliver.to) ;没有两者皆是 validation_error 工具错误。 发射是一种效应:其关键(<runId>:emit:<channel>:<sha256 of address and message>时,或您的 key)被记录在效应商店中,所以在一次坠机发送后,一个步骤和一个步骤的再发音相同 out 把它当作 message.key 打开; 扔出 out 没有记录,而且是一个工具错误. emit 在工具调用( 在工具厂) 外抛出 InvalidRunStateError。 。 。 .
  • consoleChannel({ name?, write? }) 是开发通道( 仅退出, 默认名称) console默认值 write console.log:每条消息有一条标题行,车体行并需要批准,直到它等待的时候;它从不扔.
  • 触发信封(频道、订阅代号、有效载荷); address )成为了运行的第一个用户消息,作为JSON块.
  • dispatch({ ..., attachments: [{ mediaType, filename?, data }] }) 启动带有文件的运行: 在运行创建之前, 每个运行被存储为运行的一件文物( 复制的发送存储什么也没有) , 它的元数据登陆 run.trigger.attachments (单位:美元) <runId>.0000, (中文(简体) ), <runId>.0001,...,所以列表会保持输入顺序,模型会得到字节作为第一个消息的文件部分. 检查点保留一个引用, 绝不是字节; 丢失的文物失败 artifact_not_found。 。 。 .
  • 工具上下文(也是工厂的论点) artifacts,范围为运行: put({ mediaType, filename?, data }), (中文(简体) ), get(id) 财务报告和审定财务报表 list()。 。 。 . put() 本身没有效果 defineEffectTool 保存文件一次.
  • output 取一个AI SDK Output (例如:. Output.object({ schema }): 完成运行 output 然后是解析的数值而不是文本,最后一个不解析的答案会以 validation_error (引用的原因被切为500个字符;整个答案留在 llm 步骤)。 在输出符号限制下断掉的答案, 或者在工具上结束的回路, 没有执行, 失败了 incomplete_response。 。 。 .
  • 引擎流 每一个模型调用: engine.on('run.delta', ({ delta }) => ...) 获得 { runId, step, kind: 'text' | 'reasoning', text } 在模特儿写的时候 德尔塔从未被存储,并且在执行运行的过程中只接触到听众.
  • 一个失败的模型调用 中流仍然结束其步骤: llm 步数( 到目前为止的文本, 结束原因) error),并写出一个检查点,然后运行会随着模型的错误而失败. 一个没有提供者完成部分的流关闭失败运行 incomplete_response 从不运行该步骤的工具呼叫.

效果工具

const comment = defineEffectTool({
    inputSchema: z.object({ issue: z.number(), body: z.string() }),
    effectKey: ({ issue }, ctx) => `${ctx.run.runId}:comment:${issue}`,
    // finds a comment an earlier, crashed attempt already posted
    alreadyApplied: async (key, { issue }) => findComment(issue, effectMarker(key)),
    execute: async ({ issue, body }, { context }) => postComment(
        issue,
        `${body}\n${effectMarker(`${context.run.runId}:comment:${issue}`)}`,
    ),
});

const agent = defineModelAgent({
    name: 'responder',
    model,
    instructions: 'Answer new issues.',
    tools: { comment },
});
  • 效果密钥默认为 ${ctx.run.runId}:${toolName}:${sha256(input)}· ; effectKey(input, ctx) 替换它. effectKey 财务报告和审定财务报表 alreadyApplied 获取与 execute (单位:千美元)ctx.run, (中文(简体) ), ctx.state, (中文(简体) ), ctx.artifacts)在核心0.1中,他们得到了运行上下文,所以 ctx.runId 现在 ctx.run.runId。 。 。 .
  • 每次通话时,引擎先尝试记录结果,然后 alreadyApplied,则 execute之后记录结果 execute 返回。 扔东西 execute 没有记录,所以可以重试.
  • effectMarker(key) 是一个隐藏的 HTML 注释,以嵌入工具创建的内容,这样 alreadyApplied 还能再找到它.

核准

const deploy = defineTool({
    description: 'Deploy a version.',
    inputSchema: z.object({ version: z.string() }),
    execute: async ({ version }, { context }) => {
        // pauses the run until the owner answers; the call then runs again and gets the decision
        const decision = await approve(context, { title: `Deploy ${version}?`, timeoutMs: 60 * 60 * 1000 });
        if (!decision.approved) return `Not deployed: ${decision.reason ?? 'denied'}`;
        return deployVersion(version);
    },
});

const deployer = defineModelAgent({
    name: 'deployer',
    model,
    instructions: 'Deploy the requested version.',
    tools: { deploy },
});

const engine = new Engine({
    store,
    agents: [deployer],
});

// later, from the owner's answer to run.waiting
await engine.approve(runId, { approvalId, approved: true });
  • approve(ctx, { title, body?, timeoutMs? }) 在一个工具调用内运行( 它 execute 或代理人的 hooks) (中文(简体) ). 它把跑步进入 waiting (单位:千美元)run.waiting 请注明批准日期, <stepIndex>:<toolCallId>:<n>),并放出其槽;批准存活了重启. 一旦回了电话 电话就从头开始 approve() 返回时 { approved, reason?, approver? }代码之前,它必须是一能。 要求采取同样步骤以保持其成果的其他要求.
  • ctx.channels.findOneOrFail(name).approve({ title, address? }) 同样的,请求是通过该渠道提出的.
  • 要打开一个您没有写的工具, 请打电话 approve() 在经纪人的 beforeToolExecution 钩子和掷出 ToolDeniedError 为拒绝.
  • engine.approve(runId, { approvalId, approved, reason?, approver? }) 回答当前等待点, 对于一个给批准者本身授权的呼叫者。 答案是单用.
  • 批准书未在其 timeoutMs (默认24小时)被拒绝的原因 approval timed out。 。 。 .

内容不可信

工具可以声明 trust: { taint: true, guardWhenTainted: true } 打开 defineTool() 或者说 defineEffectTool()。 。 。 . taint 在结果或执行错误暴露于模型之前标记运行; guardWhenTainted 要求批准或拒绝在运行已被污染时执行。 每个旗帜接受布尔或 (input, ctx) => boolean | Promise<boolean> 上观相. 频道与 untrusted: true 开始被污染的跑道。 第三方工具默认可信; 用代理工具的名称分类 trust.tools 超载.

trust: {
    onTainted: 'approve', // default; use 'deny' to refuse outbound calls
    tools: {
        externalSearch: { taint: true },
        publish: { guardWhenTainted: true },
    },
},

第一次接触持续存在,因为 run.taint: { at: Date, source: string } 在结果到达模型之前 它在检查站存活下来并重新开始运行;被派遣的运行继承它,等待被污染儿童的父母在结果达到其模式之前被玷污,谈话保守地玷污了接收运行。 自定义商店必须保存此可选字段 。 数据库的迁移也标志着先前存在的未完成的行经被污染了,因为它们的检查站可能已经包含外部内容.

用停机时间升级,而不是滚动部署 : 停止所有老入侵者,工人和批准人 在每个复制品和预定工作, 等待他们离开, 然后迁移/回填, 然后只开始新的二进制。 不要在同一家商店混合新旧运行时间 。 旧的传票人可以向其源道透露出一个新的自动审批的自有争辩体;旧的工人可以在一次性回填后创建出未被污染的跑道. 仅靠处决是不够的。 自定义商店需要相同的停止/回填/启动序列. 见 多个复制品。 。 。 .

曝光后,出行工具需要持久的批准(或被拒绝). 门运行在最后验证的输入后 beforeToolExecution,在效果检查之前;改变参数需要新的决定。 完整的论证保留在批准信箱/API中. 自动源渠道通知只包含一个通用审查请求. 直接通道的出入口也被封入,除了发送到同一通道的源地址或由代码配置的默认地址. 这些是 固定目的地例外,不能保证信息体.

extract(ctx, { schema, content, instructions?, model? }) 调用结构化输出且没有工具的单独模型。 在可信任的工具代码中获取原始内容并只返回提取;一个普通的不可信读取后再取取不会去除纹章. 只有保守的受约束的策略可以避免 ta:字面常数(包括: null),布林斯/null,数字,固定的enum,被关闭的对象,数组被绑定为10个项,而图案字符串被绑定为200个字符. 自由文本、参考文献、梳理器和未知的图案特性会给运行造成影响。 结果有效果;提取从未清除出已存在的污点。 呼叫者仍然拥有对所提取值的授权和语义验证.

限制 : 这不是一个快速注射防沙箱。 被启用的 shell 执行可以绕出出道工具门,包括通过脚本和嵌入过程. Shell命令政策和可选权限分类器是单独的工作. 国家出处、供应商执行的工具、沙盒网络入侵和向模型提供者披露信息都不属于这一界限。 来源答复/默认地址发送和未分类的第三方工具仍然是可信赖的能力。 GitHub 读取工具将模式选择的查询、路径和校对发送到 GitHub API , 但没有出入口; 将这些工具归类为出入口 trust.tools 如果API操作员或其日志未经批准不得接收任意运行的数据.

输入器和工具访问

跑跑可以携带起跑者:谁发动跑跑跑,作为认证者解决跑跑跑(英语:@chamvi/http 由请求的委托人提供). toolPolicy 决定每个工具运行是否可以使用;不向模型提供被拒绝的工具.

const ops = defineModelAgent({
    name: 'ops',
    model,
    instructions: 'Operate the service.',
    tools: { deploy, rollback },
    // offers a tool only when the invoker holds tool:ops:<tool>; cron and webhook runs get none
    toolPolicy: requireToolPermission(),
    hooks: {
        // release managers deploy without asking
        async beforeToolExecution({ toolName, input }, ctx) {
            const { invoker } = ctx.run.trigger;
            if (toolName !== 'deploy' || (invoker && hasPermission(invoker.permissions, 'release:manage'))) return input;
            const decision = await approve(ctx, { title: 'Deploy?' });
            if (!decision.approved) throw new ToolDeniedError('Deploy denied.');
            return input;
        },
    },
});

const { runId } = await engine.dispatch({
    agent: 'ops',
    trigger: 'http',
    channel: 'http',
    payload: {},
    invoker: { id: 'u-42', kind: 'user', permissions: ['tool:ops:deploy'] },
});

// later, once the run waits: the approver is recorded on the run's wait step
const { approvalId } = (await engine.getRun(runId))!.waiting!;
await engine.approve(runId, { approvalId, approved: true, approver: { id: 'u-7', kind: 'user', permissions: [] } });
  • 援引者({ id, kind, name?, permissions })是即时拍摄的快照. 运行会贯穿审批和重启;取消赠款不会达到已经持有的运行.
  • 与援引者 idempotencyKey 范围包括:<agent>:<channel>:<kind>:<id>:只有同一引用者的重试被去重复,另一个具有相同密钥的引用者得到自己的运行.
  • 工具代码视其为 context.run.trigger.invoker 在工具和工厂 ctx.run.trigger.invoker 实际上,钩和代理钩.
  • 该政策还包括国家工具。 给一个仍作为工具出错到达的被拒绝工具的呼叫失败, 运行继续进行: 步骤将其记录为 tool_not_allowed (单位:千美元)ToolNotAllowedError),无论是该型号总称它(该型号看到AI SDK的不可用工具出错),还是一个来自更古老历史的经批准的呼叫到达了引擎的再检查.
  • 权限是 :- 分开的: * 单是给一切,a * 区段匹配一个区段,区段计数必须匹配. requireToolPermission({ withoutInvoker: 'allow' }) 让运行时没有引用器使用每个工具.

代理状态

const digest = defineModelAgent({
    name: 'digest',
    model,
    instructions: 'Track open loops across days.',
    state: { loops: z.object({ title: z.string(), due: z.string().optional() }) },
    tools: ({ state }) => ({
        countLoops: tool({
            inputSchema: z.object({}),
            execute: async () => (await state.collection('loops').list()).length,
        }),
    }),
});
  • state.get 财务报告和审定财务报表 state.set 是每个代理商的密钥价值商店。 每个申报的集合都持有文件,并经过其标准Schema关于上升的验证.
  • 模型还获得每个收藏作为 state_<collection>_list, (中文(简体) ), state_<collection>_upsert 财务报告和审定财务报表 state_<collection>_remove 工具; 更新和去除是效果工具.

储存和储存库

createMemoryStore() 将一切保存在过程中的记忆中,用于开发和测试. 工厂将独立的容量储存库(运行、台阶、检查站、一能钥匙、锁、效果、状态、文物、代理修改和可选对话)装入平地 IStore 汇总,而不是带有转发方法的外表,并证明他们与共用合同套房的合同来自 @chamvi/test-kit数字 :

import { describeRepositoryContract } from '@chamvi/test-kit';

describeRepositoryContract((clock) => createMemoryStore({ clock }));

工厂收到 ControllableClock 并且必须使用它 每一个过期决定。 该套房运行于维特.

仓库查询的使用 findOne 财务报告和审定财务报表 find匹配 findOneOrFail 财务报告和审定财务报表 findOrFail 方法,当缺席应该抛出。 收集结果保持现有形状: runs.find 返回时 { data, total }时 artifacts.find 返回数组. OrFail 检查所选结果, 所以一个空页即使其总计为非零也会丢出 。 国家价值观,例如: null, (中文(简体) ), false 财务报告和审定财务报表 0 在场。 域突变保留其具体名称,例如: claim 财务报告和审定财务报表 beginTurn。 。 。 .

A. 背景情况

一个工具通过打出键而不是关闭到达共享实例(API客户端,GitHub App,工作空间管理器). 发动机以参考方式保持其价值; inject(ctx, key) 在工具的读取它 execute,在工具厂和效应钩中,任何规定的都从未储存或序列化(ToolContext 实值 { run, state, artifacts, channels } 并且没有给定值的字段.

import { defineContextKey, defineTool, inject } from '@chamvi/core';

const DEPLOY = defineContextKey<IDeployClient>('deploy');

const deploy = defineTool({
    description: 'Deploys a version.',
    inputSchema: z.object({ version: z.string() }),
    execute: async ({ version }, { context }) => inject(context, DEPLOY).deploy(version),
});

engine.provide(DEPLOY, client); // once per key, after new Engine()

缺少值抛出 ContextNotProvidedError (单位:千美元)context_not_provided,只命名密钥:在 execute 和效果钩,一个失败的运行(在任何型号呼叫之前) 在工具厂. tryInject(ctx, key) 返回时 undefined 换句话说. provide 拒绝 undefined键,不是来自 defineContextKey() 一个键的第二个值.

选项

new Engine(options)数字 :

选项类型默认说明
storeIStore所需经费跑道、台阶、检查站和国家
agentsAgent[]所需经费这个引擎运行的代理商
channelsIChannel[][]频道由独有的名称开始 start() 然后先停下来 drain()编号 :stop(); 工具通过 ctx.channels
concurrencyMaxRunsnumber4在此过程中立即执行
modelModelRef无没有代理的模型; 检查字符串 models 建筑业
modelsIModelResolver无决定: '<provider>/<model id>' 字符串; 注册检查每个字符串校对通过它; 没有它,字符串校正是一个 InvalidAgentDefinitionError (通过a) LanguageModel 对象)
claimTtlMsnumber60_000租一次跑步,每次续约 claimTtlMs / 3;新工作的民意调查,过期的审批和被废弃的运行使用相同的间隔
ownerstring`${hostname}-${pid}`索赔中该复制品的身份
clockIClocksystemClock时间源,可在测试中替换
onError(error, run?) => voidconsole.error没有呼叫器可丢的错误, 如租赁丢失

defineModelAgent(definition)数字 :

外地类型默认说明
namestring所需经费每个应用程序独有, 小写单词由 -
modelModelRefEngineOptions.modelA 类 '<provider>/<model id>' 字符串解析通过 EngineOptions.models,或任何AI SDK LanguageModel
instructionsAgentInstructions所需经费本地系统/ 用户/ 协助信件的字符串或只命令重读的数组
channelsChannelSubscription[]无订阅引擎注册的频道
toolsToolSet | (ctx) => ToolSet无一个简单的工具集,或者一个工厂要求每次执行
toolsContextRecord<string, unknown>无每个工具名,不是 chamvi 的工具的上下文,通过引用传递
stateRecord<string, StandardSchemaV1>无输入状态收藏
toolPolicy(toolName, { run }) => boolean无运行可能使用的工具,例如:. requireToolPermission()
budget{ maxSteps, maxTokens?, timeoutMs? }{ maxSteps: 20, timeoutMs: 900_000 }每次运行; 超时适用于每次执行
hooksAgentHooks无beforeToolExecution 编号 : afterToolExecution 环绕每个工具调用: 重写输入或输出, 闸门工具 approve()
outputOutput无AI SDK 结构输出; 已完成运行 output 是解析值

结构化指令

一个系统消息的字符串仍然是简写. 本地信件类型可以从核心直接获取 :

import { defineModelAgent } from '@chamvi/core';
import type { AgentInstructions, SystemModelMessage, UserModelMessage } from '@chamvi/core';

const policy: SystemModelMessage = { role: 'system', content: 'Summarize the report.' };
const example: UserModelMessage = { role: 'user', content: [{ type: 'text', text: 'All checks passed.' }] };
const instructions: AgentInstructions = [policy, example, { role: 'assistant', content: 'Ready to release.' }];
const agent = defineModelAgent({ name: 'reporter', instructions });

系统内容是一个字符串; 用户/助理内容和 providerOptions 使用本地的 SDK 类型 。 引导系统块通过 SDK instructions;剩余消息在运行记录之前会保持顺序,包括任何后期的系统块. 一级技能附加一个单独的元数据系统块. 这些被配置的信息是短暂的:它们为模型/工具上下文提供水分的文物标记,远离检查站和对话历史,永远不会成为等待重播的电话。 重新回顾的对话信息遵循这个已配置的前缀,批准恢复使用被捕获的对话快照. 恢复处决从目前的定义中重建。 存储的誊本系统角色在重放/模型工作前被拒绝. 手动 SkillCatalog.instructions 仍然是明确构成的字符串.

见 指南 用于输入的示例和特定角色的内容限制.

API 密码

导出仁爱目的
AgentInstruction, (中文(简体) ), AgentInstructions类型原生系统/用户/助理信息联盟和字符串/只读阵列配置
SystemModelMessage, (中文(简体) ), UserModelMessage, (中文(简体) ), AssistantModelMessage, (中文(简体) ), ModelMessage类型保存本地 SDK 信件类型
UserContent, (中文(简体) ), AssistantContent, (中文(简体) ), TextPart, (中文(简体) ), ImagePart, (中文(简体) ), FilePart类型原始 SDK 内容和部分类型
defineModelAgent函数验证代理定义并应用默认值
DEFAULT_MAX_STEPS, (中文(简体) ), DEFAULT_TIMEOUT_MS常数默认预算 : 20 步骤, 900_000 分钟
Engine类store, (中文(简体) ), clock, (中文(简体) ), getAgent, (中文(简体) ), listAgents, (中文(简体) ), putAgent, (中文(简体) ), removeAgent, (中文(简体) ), getChannel, (中文(简体) ), listChannels, (中文(简体) ), provide, (中文(简体) ), start, (中文(简体) ), dispatch, (中文(简体) ), getRun, (中文(简体) ), on, (中文(简体) ), approve, (中文(简体) ), cancel, (中文(简体) ), recover, (中文(简体) ), tick, (中文(简体) ), idle, (中文(简体) ), stop, (中文(简体) ), drain
createMemoryStore()函数包括对话在内的独立内存集合
defineTool函数一个AI SDK tool() 谁 execute 得到运行 ToolContext 作为 context
defineContextKey, (中文(简体) ), inject, (中文(简体) ), tryInject函数键入上下文键,从 a 读取引擎上提供的值 ToolContext
toolContextSchema对象这个 contextSchema 这标志着一个chamvi工具
defineEffectTool, (中文(简体) ), effectMarker函数记录的副作用工具及其隐藏标记
EFFECT符号标记创建的工具 defineEffectTool()
wrapToolsForRun函数wrapToolsForRun(tools, ctx, store, { allow?, hooks? }): 应用效果记录和代理钩对 a ToolSet 在引擎外,有一个 ToolContext; 可选 allow(toolName) 重新检查每次呼叫( 拒绝的呼叫) ToolNotAllowedError(中文(简体) )
approve函数approve(ctx, { title, body?, timeoutMs? }): 从工具调用内部持久批准
DEFAULT_APPROVAL_TIMEOUT_MS, (中文(简体) ), APPROVAL_TIMEOUT_MAX_MS常数86_400_000 (24小时), 2_147_483_647
createAgentState, (中文(简体) ), createStateTools函数国家API在商店,和 createStateTools(schema),生成状态工具(它们读取 context.state(中文(简体) )
hasPermission, (中文(简体) ), matchesPermission, (中文(简体) ), toolPermission函数权限匹配和 tool:<agent>:<tool> 权限
requireToolPermission函数A 类 toolPolicy 检查引用者的权限
consoleChannel函数consoleChannel({ name?, write? }): 开发通道, 仅输出, 记录每个消息( 默认名称) console默认值 write console.log(中文(简体) )
assertTriggerKey, (中文(简体) ), normalizeEnvelope函数信封密钥和地址的255个字符,无 NUL 规则;在频道之前存储的信封的回读(source, (中文(简体) ), thread用于存储执行
isArtifactMediaType函数关于附件和文物的媒体类型规则(type/subtype,无参数)
artifactFilePart函数文件项为工具 toModelOutput 返回一件文物:步骤和检查站的标记,模型的字节
ChamviError类下面每个错误的基准类
InvalidAgentDefinitionError, (中文(简体) ), InvalidRunStateError, (中文(简体) ), RunNotFoundError, (中文(简体) ), ArtifactNotFoundError类拒绝定义和引擎呼叫
BudgetExceededError, (中文(简体) ), FatalToolError, (中文(简体) ), IncompleteResponseError, (中文(简体) ), LeaseLostError, (中文(简体) ), TimeoutError, (中文(简体) ), ValidationError类运行失败和报告的条件; ValidationError.issues 保留有效问题
ContextNotProvidedError类inject() 找不到密钥的值( e)context_not_provided(中文(简体) )
ChannelNotFoundError类ctx.channels.findOneOrFail() 指定一个频道,引擎没有或没有 out (单位:千美元)channel_not_found(中文(简体) )
ToolNotAllowedError类用于调用工具的工具错误记录 toolPolicy 拒绝
ToolDeniedError类大门(例如: beforeToolExecution hook)拒绝一个工具呼叫(tool_denied); 工具出错,绝不致命
SandboxError类沙盒工作空间或提供者失败( S)@chamvi/sandbox 及其提供者; 工具出错, 从未失败运行
ErrorCode对象这个 code 上方每个错误
systemClock对象默认 IClock

类型 : Agent, (中文(简体) ), AgentDefinition, (中文(简体) ), ToolContext, (中文(简体) ), ContextKey, (中文(简体) ), IContextProvider, (中文(简体) ), ToolPolicy, (中文(简体) ), AgentHooks, (中文(简体) ), ToolCallInfo, (中文(简体) ), TriggerEnvelope, (中文(简体) ), Invoker, (中文(简体) ), Run, (中文(简体) ), RunStatus, (中文(简体) ), Step, (中文(简体) ), Checkpoint, (中文(简体) ), WaitPoint, (中文(简体) ), Budget, (中文(简体) ), Usage, (中文(简体) ), ApprovalRequestInput, (中文(简体) ), ApprovalDecision, (中文(简体) ), ApprovalAnswer, (中文(简体) ), IStore 及其能力接口, MemoryStoreOptions, (中文(简体) ), Artifact, (中文(简体) ), ArtifactInput, (中文(简体) ), IRunArtifacts, (中文(简体) ), IChannel, (中文(简体) ), ChannelSubscription, (中文(简体) ), ChannelContext, (中文(简体) ), ChannelMessage, (中文(简体) ), ChannelSendOptions, (中文(简体) ), ChannelHandle, (中文(简体) ), EmitMessage, (中文(简体) ), ConsoleChannelOptions, (中文(简体) ), IAgentState, (中文(简体) ), RunEvent, (中文(简体) ), EngineOptions, (中文(简体) ), ModelRef, (中文(简体) ), IModelResolver, (中文(简体) ), IClock。 。 。 .

测试助手( E)ControllableClock, (中文(简体) ), describeRepositoryContract住在这里 @chamvi/test-kit。 。 。 .

页:1

EngineOptions.skills 每个代理设备的供应缺省; AgentDefinition.skills 增加范围外加. 两个都接受通用 SkillInput 协议从核心。 导入技能数据类型, gitSkills, (中文(简体) ), loadSkillBundle,自定义适配器(defineSkill, (中文(简体) ), defineSkillSource和可选目录 @chamvi/skills。它的工厂值自动带有运行时间,没有模块注册。 核心坐标准备,取消和普通的贡献工具执行;可选软件包拥有验证,内容,目录和缓存. 核心工作没有安装技能.

  • 工具错误不会失败运行 . 它作为工具出错的结果回到模型. 掷出 FatalToolError 以失败运行; 步骤预算上限重试循环.
  • 预算结算. 跑步经过 maxSteps 或者说 maxTokens 当模型仍然想要调用工具时, 代码失败 BudgetExceeded; 点击其超时的运行失败 Timeout。 。 。 .
  • 效果会在发生后记录下来. 工具的副作用和商店写入之间发生相撞, 重复恢复时的效果, 除非 alreadyApplied 发现它.
  • 一步一步的几项批准是一次处理的. 跑步按呼叫顺序在第一个等待;另一个被暂停的呼叫在恢复后继续等待,并在任何进一步的型号呼叫之前再次询问.
  • createMemoryStore() 不持久. 一切随过程而去;使用一长串商店来活下来重启或运行复制品.
  • stop() 停止投票 和渠道. 一旦每个频道停止运行,它就会解决 drain() 关闭.

许可证

原载 Apache 许可证 2.0。 。 。 .

版本与发布记录

@chamvi/core 共发布 15 个版本,首次发布于 2026/10/25;过去 12 个月发布了 15 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.8.0latest2026/11/09今天
0.7.32026/11/063 天前
0.7.22026/11/053 天前
0.7.12026/11/054 天前
0.7.02026/11/045 天前
0.6.12026/11/045 天前

关于 @chamvi/core 的常见问题

@chamvi/core 是什么?

用于自发托管,触发驱动的AI代理的核心引擎:代理,触发和可持久运行.

如何安装 @chamvi/core?

在项目目录运行 npm install @chamvi/core,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:ai(^7)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@chamvi/core 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@chamvi/core 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@chamvi/core 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=26.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@chamvi/core 可以商用吗?

@chamvi/core 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@chamvi/core 的下载量有多少?

根据 npm 官方下载统计,@chamvi/core 在 2026/10/10 – 2026/11/08 这 30 天内被下载 5,279 次,日均约 176 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@chamvi/core 还在维护吗?

最新版本 0.8.0 发布于 2026/11/09(今天);至今共发布 15 个版本,其中过去 12 个月发布了 15 个;首次发布于 2026/10/25。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。