@chamvi/github (英语)
GitHub 频道和chamvi代理的工具.
经核实的交付成为每个匹配代理的一次重复运行,回答土地作为问题评论,
gitHub 在重试、恢复或崩溃后.
目录
安装
npm install @chamvi/github @chamvi/http @chamvi/core ai --save
仅限无害环境管理,节点.js >=26.0.0。 。 。 . @chamvi/core, (中文(简体) ), @chamvi/http (服务于频道的交付)和 ai 是同伴的依赖关系。 GitHub 通过 @octokit/core 带有页形插件; App JWT、 安装符和 Webhook 签名 node:crypto。 。 。 .
GitHub 应用程序设置
每个代理仓库(或组织)一个 GitHub App :
- 创建 GitHub 应用程序。设置 网络锁定 URL 改为
https://<host><basePath>/channels/github(频道名称) 内容类型为application/json(手工创建的钩子默认为application/x-www-form-urlencoded,该频道以415)和a 数据 网络隐藏秘诀。 。 。 . - 授予您所需的工具权限 : 问题 阅读和写作标签、评论、收尾和
github_create_issue· ; 调取请求 读取( 写为github_create_pull_request财务报告和审定财务报表github_merge_pull_request(三); 检查 财务报告和审定财务报表 提交状态 读取为github_get_pull_request_checks和合一的守护者; 元数据 读取; 目录 读取为github_get_file, (中文(简体) ),github_get_latest_release, (中文(简体) ),github_list_releases财务报告和审定财务报表github_compare(为推动的工作空间读写, 工作流量 写入以将更改推入.github/workflows) (中文(简体) ). 订阅您的订阅名称( 例如 ) . 问题) (中文(简体) ). - 生成一个私人密钥, 并在代理商可能操作的寄存器上安装 App( 若干账户和组织都很好: 每个工具都能找到它命名的寄存器的安装) 。 从不将 App 放在规则绕行列表或分支保护例外中:
github_merge_pull_request拒绝不安全的合并本身, 但是一个绕行会让 GitHub 报告一个被屏蔽的拉动请求为clean。 。 。 . - 递接 App id, 私钥 (PKCS# 1 或 PKCS# 8 PEM; 有字面的一行 env var)
\n和网络隐藏的秘密createGithubApp()设置slug在生产中,所以机器人登录不需要GET /app。 。 。 .
使用量
createGithubApp() 持有App证书. githubChannel({ app }) 是频道: 在引擎上注册并列出 createHttpApp({ channels })服务于在 POST /channels/github。代理人订阅 github.on(events)· ; gh.readTools() 编号 : gh.writeTools() 是简单的AI SDK ToolSet编号:
import type { LanguageModel } from 'ai';
import {
Engine,
ToolDeniedError,
createMemoryStore,
defineModelAgent,
} from '@chamvi/core';
import { createGithubApp, github, githubChannel } from '@chamvi/github';
import type { GithubAppOptions } from '@chamvi/github';
import { createHttpApp, createShutdown, staticTokens } from '@chamvi/http';
export async function createTriageServer(
model: LanguageModel,
options: Pick<GithubAppOptions, 'fetch' | 'clock'> = {},
) {
const {
GITHUB_APP_ID,
GITHUB_PRIVATE_KEY,
GITHUB_WEBHOOK_SECRET,
CHAMVI_TOKEN,
} = process.env;
if (!GITHUB_APP_ID || !GITHUB_PRIVATE_KEY || !GITHUB_WEBHOOK_SECRET || !CHAMVI_TOKEN) {
throw new Error('Set GITHUB_APP_ID, GITHUB_PRIVATE_KEY, GITHUB_WEBHOOK_SECRET and CHAMVI_TOKEN.');
}
const gh = createGithubApp({
appId: GITHUB_APP_ID,
privateKey: GITHUB_PRIVATE_KEY,
webhookSecret: GITHUB_WEBHOOK_SECRET,
...options,
});
// deliveries in, issue comments out
const channel = githubChannel({ app: gh, clock: options.clock });
const triage = defineModelAgent({
name: 'triage',
model,
instructions: 'Label new issues and thank the author in one comment.',
// one run per issues.opened delivery, deduplicated by the delivery id
channels: [github.on('issues.opened')],
tools: () => ({ ...gh.readTools(), ...gh.writeTools() }),
hooks: {
// closing waits for the owner, asked in a comment on the issue
async beforeToolExecution({ toolName, input }, ctx) {
if (toolName !== 'github_close_issue') {
return undefined;
}
const { approved } = await ctx.channels.findOneOrFail('github').approve({
title: 'Close this issue?',
body: JSON.stringify(input),
});
if (!approved) {
throw new ToolDeniedError('The owner keeps the issue open.');
}
return undefined;
},
},
});
const engine = new Engine({
store: createMemoryStore(),
agents: [triage],
channels: [channel],
});
const shutdown = createShutdown({ engine });
const app = createHttpApp({
engine,
auth: staticTokens({
tokens: [{
value: CHAMVI_TOKEN,
id: 'ci',
permissions: ['*'],
}],
}),
// POST /channels/github: point the App's webhook URL here
channels: [channel],
shutdown,
});
await engine.start();
return {
app,
engine,
shutdown,
};
}
入境:交货
POST /channels/github (频道的) in在 http 应用程序下 basePath; 第二个信道 githubChannel({ name: 'github-ent' }) 服务于 /channels/github-ent检查,按此顺序:
| 检查 | 答复 |
|---|---|
频道以下的路径( A) :/channels/github/...(中文(简体) ) | 404 |
X-Hub-Signature-256 缺少 | 401 |
X-GitHub-Event 没有 ^[a-z0-9_]+$, (中文(简体) ), X-GitHub-Delivery 非 1至 255 个字符 | 400 |
在频道上方 bodyLimit (默认为 1 MiB) | 413 |
非JSON内容类型(例如. application/x-www-form-urlencoded(中文(简体) ) | 415 |
sha256= 原生体的 HMAC 字节在任何网络隐藏的秘密下 | 401 |
| 身体不是 JSON 对象 | 400 |
向每个有匹配的代理人发送经核实的交货 github.on() 订阅此频道, 每个代理最多运行一次 (它第一次匹配订阅),与 channel: 'github',则 GithubEvent (或 check_suite 或者说 check_run 准确列出一个牵引请求, 发送存储处,地址 <owner>/<repo>#<number> (单位:千美元)run.address时 ctx.channels.findOne() 页:1 答案是,我们.. 202 { delivery, runs: [{ agent, runId, deduplicated }] },用于 ping,对于没有订阅匹配的事件和 App 自己发送的事件 (runs: []) (中文(简体) ).
- 脚踏车: 二重奏键是送出id(或订阅)
idempotencyKey(event)),所以重递返回现有的运行deduplicated: true。签名只涵盖身体,而不涵盖X-GitHub-Delivery也没有X-GitHub-Event页眉 (e)e.delivery, (中文(简体) ),e.name:无论谁持有一个签名的快递(一个代理日志,一个支持的垃圾堆),都可以在新的快递ID下重放,或者在另一个事件名下,一个代理监听,每次开始一个新的跑. 在被曝光的端点上,仅从体域中取出密钥,例如:.idempotencyKey: (e) => `${e.action}:${e.payload.repository?.full_name}#${e.payload.issue?.number}@${e.payload.issue?.updated_at}`,然后让一个filter检查身体是否带有事件名称的含义(issue无comment页:1issues, (中文(简体) ),comment页:1issue_comment, (中文(简体) ),pull_request页:1pull_request) (中文(简体) ). - 失败: 物剂的匹配和发送顺序和故障(抛出)
filter或键函数,键dispatch拒绝,发送失败)不会阻止其他人;每次失败都到频道的onError,而答案是,现在500。 。 。 . GitHub 不自动转发失败的交付: 转发4xx编号 :5xx手递(App's 高级 选项卡)或通过再发送 API。 重递会保存送货的ID, 所以已经得到他们的运行的代理被复制. - 自卫队: 其
sender是 App 的自有机器人 (<slug>[bot], (中文(简体) ),type: 'Bot')开始不跑,所以一个特工不会被自己的评论所唤醒. 其他项目(dependabot[bot],同一寄存器上的第二个 chamvi App)是普通发件人;使用订阅filter以打破两个 Apps 之间的循环. - 体积: 问题和评论交付量远远低于1个小米
bodyLimit打开githubChannel()用于大型push或者说pull_request交货(GitHub发送最多25 MB),否则答复413。 。 。 . - 频道路由与http app的每条路由一样受限(默认情况下每客户端地址每分钟300个路由),从未被其认证人认证:签名为证书.
订阅
github.on(['issues.opened', 'issue_comment.created'], { // 'issues' matches every action
filter: (event) => event.payload.repository?.full_name === 'octo/demo',
});
| 选项 | 默认 | 说明 |
|---|---|---|
events | 所需经费 | '<event>' 或者说 '<event>.<action>',一个或多个数组 |
id | github:<events joined by ','> | 订阅 id; 对相同事件的两次订阅需要不同的ID |
filter | 无 | (event) => boolean,在事件匹配之后; 也可以打破两个 Apps 之间的环路,它们互相视同普通bots |
idempotencyKey | 发送编号 | (event) => string | undefined |
concurrencyKey | <owner>/<repo>#<issue or pull request number> (检查套件或检查跑道:关于地址,它唯一的拉动请求),否则 <owner>/<repo> | (event) => string | undefined; 在一个问题上运行, 互相等待 |
selfEvents | 无 | 活动name 或者说 name.action) App的自有bot可能开始此订阅,例如. ['pull_request.opened', 'pull_request.synchronize', 'check_suite.completed'] 对于拉动请求,代理机打开或推入( 将动作命名为: 空 pull_request 也带 labeled, (中文(简体) ), closed, (中文(简体) ), synchronize 代理商自己的标签,合并和推出原因, 所以每次这样的写作重新开始, 每一次发送一个新的运行; 一个推动的代理商 synchronize 每推一次重新启动本身; 第一次订阅, 匹配开始的名称; issue_comment, (中文(简体) ), issues 财务报告和审定财务报表 pull_request_review_comment 被拒绝,因为机器人自己的评论 会重新开始代理 |
github.on() 订阅命名的频道 github;第二个频道使用自己的订阅 channel.on()运行的有效载荷是 GithubEvent { name, action?, delivery, installationId?, payload }时 payload 是整个GitHub的身体。 超过 255 个字符或带有 NUL 的密钥会像掷出一样失败 filter (见 失败) (中文(简体) ).
输出: 注释
频道的 out 评论某一问题或拉动请求。 工具通过核心到达 : ctx.channels.findOne() 关于频道开始运行问题的回答, ctx.channels.findOne('github') 涉及任何问题github.to({ repo, number }) 构建地址 <owner>/<repo>#<number>:
import { defineTool } from '@chamvi/core';
import { github } from '@chamvi/github';
const answer = defineTool({
description: 'Answer on the issue.',
inputSchema: z.object({ body: z.string() }),
async execute({ body }, { context }) {
await context.channels.findOne()?.emit({ body });
await context.channels.findOneOrFail('github').emit({ title: 'Triage log', body }, github.to({ repo: 'octo/ops', number: 1 }));
return 'sent';
},
});
每个消息频道 :
- 解析地址( 仅此而已 )
owner/repo#n是一个ValidationError)并选择安装:该事件是运行此频道从同一个寄存器上启动,否则App在地址的寄存器上安装(installationFor()),否则事件,否则installationId从createGithubApp()没有它扔InvalidAgentDefinitionError在任何评论请求之前, - 列出自运行以来更新的问题评论
receivedAt倒数一个小时, 当 App bot 旁边有一个时返回(<slug>[bot],比较不敏感大小写)effectMarker(message.key), (中文(简体) ), - 其它则张贴评论:
mention登录,### <title>(当给定时),栅栏中的尸体,为了批准,批准线,跑道和标志:
@octocat
### Close this issue?
```
{ "repo": "octo/demo", "number": 7 }
```
Waiting for approval until 2026-10-22T09:00:00.000Z. Approve or deny: https://chamvi.example/ui/approvals?run=<runId>&approval=<approvalId>
Run `<runId>` of agent `triage`.
<!-- chamvi:effect=<runId>:<approvalId> -->
消息密钥( a) emit'内容处理键,一个批准' <runId>:<approvalId>)按原样入入入标记;带有字符的密钥为 HTML 注释无法持有(--,白空间)或超过255个字符被替换为 sha256:<hex>因此,失去反应是无害的:下一次尝试会发现评论。 每一次失败都意味着 ChamviError 有代码 github_request (单位:千美元)GitHub <status>: <message>),如不内部回复的 GitHub timeoutMs (30 s, 用于评论列表和帖子;符号交换和 GET /app 以App本身为界限; 终止了打电话者的信号拒绝及其理由.
核准
打开代理工具 hooks.beforeToolExecution 具有耐用性 approve(),如用法示例对 github_close_issue数字 : ctx.channels.findOneOrFail('github').approve({ title, body }) 暂停运行,引擎将请求作为对运行问题的一则评论(关键) <runId>:<approvalId>,由 tick() 直到它熄灭, 从来没有两次。 车主在Chamvi UI(approvalUrl 链接)或通过 POST /runs/:id/approve;然后从头开始 approve() 返回决定. approve(ctx, { title }) 从核心问起,没有注释(仅输入和API).
工具
每个工具都起到安装它命名的寄存器的作用: github 频道从该寄存器上启动( 没有请求), 否则 App 的安装 installationFor(), (中文(简体) ), GET /repos/{owner}/{repo}/installation 与App JWT,缓存10分钟),否则交付的或 installationId 从 createGithubApp() (所以App未安装的公用寄存器仍可读取). 没有,这个调用是一个工具错误(github_request),从未失败运行. 输入将寄存器命名为 owner/name (GitHub的名字字符; ); . 财务报告和审定财务报表 .. (b) 拒绝。 每一个安装请求都带有运行的信号,所以取消,排出和运行的超时中止一个被停顿的GitHub呼叫. App认证请求(代号交换和 GET /app 为bot登录)由每个等待运行和送出共享,所以它们携带无运行信号;每个在应用程序的时钟上30s后中止,下一个呼叫者重复. 一个失败的 GitHub 呼叫到达模型为 GitHub <status>: <message>永远不要与请求或它的象征.
| 工具 | 仁爱 | 投入 | 结果 |
|---|---|---|---|
github_get_issue | 读取 | repo, (中文(简体) ), number | number, (中文(简体) ), title, (中文(简体) ), body, (中文(简体) ), state, (中文(简体) ), labels, (中文(简体) ), author, (中文(简体) ), url, (中文(简体) ), createdAt, (中文(简体) ), comments, (中文(简体) ), isPullRequest |
github_search_issues | 读取 | query, (中文(简体) ), limit? (1至20,默认为10) | total, (中文(简体) ), items: [{ repo, number, title, state, url }] |
github_list_labels | 读取 | repo | [{ name, description }]每页 |
github_get_pull_request | 读取 | repo, (中文(简体) ), number | number, (中文(简体) ), title, (中文(简体) ), body, (中文(简体) ), state, (中文(简体) ), draft, (中文(简体) ), merged, (中文(简体) ), base, (中文(简体) ), head, (中文(简体) ), author, (中文(简体) ), url, (中文(简体) ), changedFiles, (中文(简体) ), headSha, (中文(简体) ), headRepo (一个被删除的分叉的空白), fork, (中文(简体) ), authorType, (中文(简体) ), labels, (中文(简体) ), mergeable (在GitHub计算它时,不要动), mergeableState, (中文(简体) ), maintainerCanModify, (中文(简体) ), mergeCommitSha |
github_get_file | 读取 | repo, (中文(简体) ), path, (中文(简体) ), ref? | { path, size, content, truncated } (切到65 536个字符)或 { path, entries } 用于目录 |
github_get_latest_release | 读取 | repo | { tag, name, publishedAt, url, body } 或者说 { none: true } |
github_list_releases | 读取 | repo, (中文(简体) ), from?, (中文(简体) ), to?, (中文(简体) ), tagPrefix?, (中文(简体) ), exhaustive? | { releases: [{ tag, name, publishedAt, url, prerelease, body, bodyTruncated }], truncated }: 发布后 from 最高和包括 to (单位:千美元)v1.2.3 财务报告和审定财务报表 1.2.3 两者都匹配),最古老的,最多为20个,音符被切为8000个字符;没有 from 最新20份; 草稿被跳过; 阅读在100份的第一页停止,其发行量均在或低于 from (按出版日期列出), exhaustive: true 每页读取最多1 000页 |
github_compare | 读取 | repo, (中文(简体) ), base, (中文(简体) ), head | { status, aheadBy, behindBy, totalCommits, url, commits: [{ sha, message, author, date }], files: [{ path, status, additions, deletions }], truncated }: 承诺一行(最多100行)并更改文件(最多300行) |
github_list_repositories | 读取 | includeArchived? | { repositories: [{ repo, installationId, account, private, archived, fork, defaultBranch, url }], truncated }:每个安装的每一个存储器(GET /app/installations),按名称排序,存档者不按要求丢弃,最多1000个 |
github_list_issues | 读取 | repo, (中文(简体) ), labels?, (中文(简体) ), limit? (1至100,默认为100) | { issues: [{ number, title, author, labels, comments, createdAt, updatedAt, url }], truncated }: 未决问题, 将请求拉出, 最近一次更新 |
github_list_pull_requests | 读取 | repo, (中文(简体) ), base?, (中文(简体) ), limit? (1至100,默认为100) | { pullRequests: [{ number, title, author, authorType, draft, base, head, headSha, headRepo, fork, labels, createdAt, updatedAt, url }], truncated }: 打开拉出请求 |
github_get_pull_request_checks | 读取 | repo, (中文(简体) ), number | { number, headSha, base, state, pending, failing, checks: [{ name, kind, status, conclusion, outcome, required, url }], required: { known, contexts, missing }, truncated }: 最新的检查运行(最多300次)并输入头部状态; 分支保护和规则所需的上下文(known: false 当时,GitHub拒绝给他们看; state 实值 none 没有任何报告 pending 当检查运行或所需的上下文没有报告时, 永远不要绿色 |
github_get_push_target | 读取 | repo, (中文(简体) ), number | { number, headRepo, headBranch, headSha, fork, installationId, contents, workflows, maintainerCanModify, canPush, reason }: App能否将固定器推向头分支(App从未安装在一分叉上是: App sords不能使用维护者编辑) |
github_add_labels | 效果 | repo, (中文(简体) ), number, (中文(简体) ), labels (1至20个) | { labels }: 每次运行和输入一次(标签是一组) |
github_create_comment | 效果 | repo, (中文(简体) ), number, (中文(简体) ), body | { id, url }数字 : 每个示范步骤每期1个评论 |
github_close_issue | 效果 | repo, (中文(简体) ), number, (中文(简体) ), reason? (单位:千美元)completed, (中文(简体) ), not_planned(中文(简体) ) | { number, state, stateReason }; 已经关闭的问题不再补丁 |
github_create_issue | 效果 | repo, (中文(简体) ), title, (中文(简体) ), body, (中文(简体) ), labels? | { number, url }: 一旦每次运行和输入; 机体带有效果标记, 所以一个再操作步骤会发现 App 的问题而不是打开第二个 |
github_create_pull_request | 效果 | repo, (中文(简体) ), head (单位:千美元)branch 或者说 owner:branch, (中文(简体) ), base? (默认分行), title, (中文(简体) ), body, (中文(简体) ), draft? | { number, url, base, head }: 每次运行和输入后,再次以其标记查找; GitHub 的 422 对于一个已有的拉动请求是一个工具错误 |
github_propose_change | 效果( opt- in) | repo, (中文(简体) ), path, (中文(简体) ), content, (中文(简体) ), reason | { number, url, base, head }: 为此代理/ 路径创建或更新一个稳定的分支并打开 PR, 永远不合并 |
github_merge_pull_request | 效果 | repo, (中文(简体) ), number, (中文(简体) ), sha, (中文(简体) ), method?, (中文(简体) ), commitTitle?, (中文(简体) ), commitMessage? | { number, sha, method, alreadyMerged }: 见下面的合并后警卫 |
github_propose_change 缺席,除非 createGithubApp() (或 githubModule()获得 proposals: { repos: { 'owner/repo': { paths: ['config/**', 'README.md'] } } }。此政策在创建时被验证和复制 writeTools() 揭发了工具. 这需要 目录 财务报告和审定财务报表 调取请求 写作。 路径是寄存器相对的光彩,与节点相匹配 path.matchesGlob绝对的路径,倒行逆施, .github/**, (中文(简体) ), .husky/**, (中文(简体) ), CODEOWNERS 财务报告和审定财务报表 .gitmodules 在任何文件夹和Unicode格式字符(类别 Cf: bodi 覆盖, 0-width 字符)中,在 GitHub 请求之前总是被拒绝,同样作为允许列表 globs 。 提案总是外出 所以有污点的运行需要通过核心的外出门得到批准.
最初的分支是 chamvi/<agent>/<path-slug>-<path-hash>,基于寄存器的默认分支。 后来运行再使用其开放的PR. 关闭或合并后,新提案使用新分支,其中 -g-<previous-pr-number> 后缀来自当前默认分支;针对该基点的相同建议失败,因为没有更改验证错误,而不是打开空的PR. 效果键 <runId>:propose:<repo>:<path>:<sha256 of content>:<model step> 允许每跑一次建议,路径,内容和模式步骤,所以同一路径在一次运行中更正的内容是新的承诺,而后退一步则是回到更早的内容,而不是第一个建议的记录. 被 Pagized PR 承诺列表对丢失的效果记录进行校正,即使在另一个运行改变内容后,PR被合并,或者分支被删除,而不与可变的后相提并论的SHA. 未公布的分行通过他们自己拥有的,单亲家庭的承诺链回溯到被绑定的比较的合并基础;模棱两可的先祖未能关闭. 调和还原原公关而不恢复后期运行. 关于公开公关的成功不变提案也记录了一项标记承诺。 保留建议书和公关所有权标识用于回收。 发现者要求每一代的分支(head=<owner>:<branch>)),因此寄存器的PR计数无关紧要,在一个分支的完整第10个100-PR页上或250代后未能关闭;每个历史PR都有独立的历史限制,并立即有一个匹配的标记返回. 在 GitHub 250 承诺的 PR 封口中缺失的标记失败了 。 一旦有249个公开提案承诺:关闭或合并后,新的更新就会被拒绝,以便下一次更新可以使用新一代. 已经封装的历史公关可能需要人工回收。 执行会刷新PR的发现, 以保证货币安全, 而不是缓冲调节快照 .
工具走被绑起的 Git 树并需要正则文件模式(100644 或者说 100755; 符号链接,子模块和非指令性父母被拒绝,包括当内容已经匹配时. 它以被观察的头目作为它的独生母构建一个承诺,并且无武力推进裁判. 完整 diff 对照被钉底/ 头 SHA 进行检查, 包括重命名源; 缺失/ 被记录的数据和 GitHub 的 300 文件比较封顶失败 。 它既检查了公关发布前的活性迁移的参考文献,又检查了之后的建议书分支(写作后移动的默认分支不是一个错误). 现有的公关需要一个建议标记;没有公关的非空分行需要一个标记头的承诺.
提议分支需要该工具的专属写入. 序列化运行针对同一种代理/存储/路径,不外推,强制重置或删除活性建议分支. 鉴定范围包括被观察的头,而不是所有未来的分支状态. GitHub的 ref更新和PR发布是独立的操作,而不是原子交易:被检测到的移动失败了关闭,但可以留下已经发布的PR或无法到达的Git对象进行复核. 这些检查不能使公关分支永久化,也不能在最后观察之后保证其内容。 合并前审查当前PR头.
写作工具是效果工具(defineEffectTool (从核心). github_create_comment 按运行、发行和模式步骤键<runId>:github_create_comment:<owner>/<repo>#<n>:<step>,自 GitHub 以不敏感方式解决它们后, 将密钥嵌入为隐藏标记(<!-- chamvi:effect=... -->) (中文(简体) ). 当效果记录被丢失(GitHub接受评论和检查点之间发生相撞事件)后,再取出App自己用该标记的评论(自收到运行记录后更新了评论,少于一小时)并返回,而不是再次发帖,尽管模型写了不同的文字. 同一步骤中第二次呼吁同一问题回回首评论,因此工具描述要求模型将一个问题的所有内容都放入一个评论.
github_merge_pull_request 绝不绕过保护:在合并请求之前,它拒绝(ToolDeniedError,工具错误),一个已关闭或合并的拉取请求,一个从 sha (再次读取支票),一个草稿,一个可合并的 GitHub 尚未计算, a mergeable_state 外部 MERGE_STATES (单位:千美元)clean, (中文(简体) ), unstable, (中文(简体) ), has_hooks· ; dirty 冲突, blocked 保护, behind 没有绿色或未报告的任何要求的检查,要求的检查,它不能读取(在基准分支或其规则上是403或404:绕行列表上的符号不能合并它看不到的过去检查;用手将这样的拉取请求合并),一个尚未报告过任何检查的头(CI尚未开始),以及任何仍在运行,需要或没有进行的检查. 不需要的失败检查不能阻止它(unstable); 代理想要每张支票绿色读取 github_get_pull_request_checks 并请求 state === 'success' 自己来 合并请求只发送 sha, (中文(简体) ), merge_method gitHub的专辑 405编号 :409 保留工具错误。 方法是 method,则 writeTools({ mergeMethod }),则 DEFAULT_MERGE_METHOD (单位:千美元)squash) (中文(简体) ). 哪个拉并请求(作者,版本出错)是代理商的政策,从来不是工具的.
大门破坏性工具github_close_issue, (中文(简体) ), github_merge_pull_request 任何您的政策不单独合并),并获得批准 hooks.beforeToolExecution,参见 核准。 。 。 .
警卫
- 安装标志每次安装都会被缓存,并在到期前5分钟被更换,因此在批准后数小时后恢复运行. 托肯斯,私钥和JWT从未被登录,也从未被存储在跑道,步道或效果中.
- 这些工具可以到达安装可以到达的每一个寄存器. 问题机构是不信任的输入:它所引导的模型可以在其中任何一个寄存器上行动,因此只有在代理人可能采取行动时才安装App,并且通过批准来打开破坏性工具.
- 审批意见向能读出问题的人公开. 与
approvalUrl它在 chamvi UI(仅运行和批准id)中链接到批准,所有者在其中签名(agent:<agent>:approve来回答,run:read或者说agent:<agent>:run没有它,线说在UI里或者通过POST /runs/:id/approve。 。 。 . - 信息体坐在一个栅栏里 一个背影比任何背影都长 所以
@login, (中文(简体) ),@org/team或者说#123里面没有通知任何人 连线什么也没有 没有输入可以关闭围栏 Backtick跑出超过31个被先用U+200B零宽空格打破,所以栅栏会保持短距离;车身被切成6万个字符(GitHub拒绝超过65 53.6个评论),从未在一对代行者中出现. 标题中的"白空间"运行被倒塌为一个空间. 仅配置mention登录被通知,除App bot之外,任何人的评论,复制一个标记不计为发送. requireToolPermission()从@chamvi/core拒绝每个工具在没有引用器的情况下运行,而交付运行则没有. 使用 GitHub 代理requireToolPermission({ withoutInvoker: 'allow' })或者把它包起来.- Webhook 秘密可以旋转:通过
webhookSecret: [old, new]gitHub 开关时.
工作空间的 Git 证书
githubAppCredentials(app, { permissions? }) 让工作空间 @chamvi/sandbox 检查并按下 App 的寄存器, 仅限一个寄存器 : contents: read 读取, contents: write 加号 permissions 来推动。 它不会为另一个主机或App未安装的寄存器解答任何问题,所以下一个源(或匿名取出)会随之而来. 它在结构上打入,所以此软件包不依赖于 @chamvi/sandbox。 。 。 .
const workspaces = createWorkspaceManager({
provider,
credentials: githubAppCredentials(gh, { permissions: { workflows: 'write' } }),
author: await gh.botIdentity(), // { name: '<slug>[bot]', email: '<id>+<slug>[bot]@users.noreply.github.com' }
});
gh.repositoryToken({ owner, repo }, { permissions }) 代码是相同的,缓存到到期前5分钟.
A. 背景情况
provideGithubContext(engine, gh) 提供引擎上的 App; 工具或工具厂读取它 injectGithubContext(ctx),因此工具无需关闭实例:
import { injectGithubContext, provideGithubContext } from '@chamvi/github';
const triage = defineModelAgent({
name: 'triage',
model,
instructions: 'Label the issue.',
tools: (ctx) => injectGithubContext(ctx).readTools(),
});
provideGithubContext(engine, gh); // once, after new Engine()
缺少 App 丢弃 ContextNotProvidedError 名称 github (在工厂,运行失败 之前任何型号呼叫).
使用@ chamvi/ app
githubModule({ channel? }) 从 @chamvi/github/module 构建 App 从 GITHUB_APP_ID, (中文(简体) ), GITHUB_APP_PRIVATE_KEY, (中文(简体) ), GITHUB_WEBHOOK_SECRET, (中文(简体) ), GITHUB_INSTALLATION_ID, (中文(简体) ), GITHUB_APP_SLUG 财务报告和审定财务报表 GITHUB_API_URL 当唤作是.app 捐款 githubChannel() (单位:千美元) channel 选项,来自 CHAMVI_PUBLIC_URL 除非 channel.approvalUrl 被赋予, app的时钟) 到应用程序的频道, http模块在其中服务 /channels/github,贡献 githubAppCredentials() (单位:千美元) credentials 选项; credentials: false 关掉) sandboxModule()'工作空间,并提供引擎上的 App. @chamvi/app 是可选的对等点;主条目从不导入.
import { createApp } from '@chamvi/app';
import { githubModule } from '@chamvi/github/module';
export default createApp({ agents: [triage], modules: [githubModule()] });
选项
createGithubApp(options)数字 :
| 选项 | 类型 | 默认 | 说明 |
|---|---|---|---|
appId | string | number | 所需经费 | App 代码 |
privateKey | string | 所需经费 | PEM( PKCS# 1 或 PKCS# 8); 文字 \n 序列成为新行 |
webhookSecret | string | string[] | 所需经费 | 交付经过其中任何一种检验 |
installationId | number | 无 | 对于不是以快递开始的运行,以及代表他们的评论 |
slug | string | GET /app 一次 | App的弹片是 github.com/apps/<slug> (小写),用于机器人登录 <slug>[bot] |
baseUrl | string | https://api.github.com | GitHub 企业服务器 : https://<host>/api/v3 (绝对 https URL; 空指默认) |
clock | IClock | systemClock | 托肯过期和JWT时间 |
fetch | typeof fetch | 全球 fetch | 每个 GitHub 请求 |
createGithubApp 掷出 InvalidAgentDefinitionError 为空 appId,一个没有RSA私有密钥的密钥,一个空密钥,一个 installationId 这不是正整数, a baseUrl 不是绝对的 https URL( 或有查询或散列) 和 a slug 这不是App的小写弹片(^[a-z0-9]+(-[a-z0-9]+)*$时,如 github.com/apps/<slug>被误杀的人会无声地禁用自卫队).
githubChannel(options)数字 :
| 选项 | 类型 | 默认 | 说明 |
|---|---|---|---|
app | IGithubApp | 所需经费 | 从 createGithubApp() |
name | string | 'github' | 频道名称(代理名称规则),服务于 /channels/<name> |
mention | string | string[] | 无 | 登录( 无) @在每条评论的顶端提及 |
approvalUrl | ({ runId, approvalId, agent }) => string | 无 | 与chamvi UI中的批准相关联,例如. https://<app>/ui/approvals?run=<runId>&approval=<approvalId>它没有符号 |
timeoutMs | number | 30_000 | 注释列表和帖子的边界 clock |
bodyLimit | number | 1_048_576 | 交付可能包含的字节(413 上文) |
onError | (error) => void | console.error | 每个代理人都无法向 |
clock | IClock | systemClock | 超时的时间来源 |
每个选项都会在 githubChannel() 被叫作;一个被弃置的 InvalidAgentDefinitionError。 。 。 .
API 密码
| 导出 | 仁爱 | 目的 |
|---|---|---|
createGithubApp | 函数 | 应用: octokit(installationId), (中文(简体) ), botLogin(), (中文(简体) ), botIdentity(), (中文(简体) ), installationFor({ owner, repo }), (中文(简体) ), repositoryInstallation({ owner, repo }) (包括同一缓存中的全部安装、权限), installations(), (中文(简体) ), repositoryToken(), (中文(简体) ), verifySignature(), (中文(简体) ), readTools(), (中文(简体) ), writeTools({ mergeMethod? }) |
githubAppCredentials | 函数 | 存储范围 : @chamvi/sandbox 工作空间 |
DEFAULT_GITHUB_GIT_HOST, (中文(简体) ), GITHUB_TOKEN_USERNAME | 常数 | 'github.com', (中文(简体) ), 'x-access-token' |
githubChannel | 函数 | 频道:交付 in,评论 out附加时 on() 财务报告和审定财务报表 to() 约束在名称上 |
github | 对象 | github.on(events, options?) 订阅费和 github.to({ repo, number }) 命名频道的地址 github |
GITHUB_CHANNEL_NAME, (中文(简体) ), GITHUB_CHANNEL_TIMEOUT_MS, (中文(简体) ), COMMENT_BODY_MAX_LENGTH | 常数 | 'github', (中文(简体) ), 30_000, (中文(简体) ), 60_000 |
DEFAULT_GITHUB_API_URL | 常数 | https://api.github.com |
INSTALLATION_CACHE_TTL_MS | 常数 | 600_000,多长时间 installationFor() 保存仓库的安装 |
DEFAULT_MERGE_METHOD, (中文(简体) ), MERGE_METHODS, (中文(简体) ), MERGE_STATES | 常数 | 'squash', (中文(简体) ), ['merge', 'squash', 'rebase'], (中文(简体) ), ['clean', 'unstable', 'has_hooks'] |
GITHUB_REQUEST_ERROR_CODE | 常数 | 'github_request',则 code gitHub 请求失败 |
provideGithubContext, (中文(简体) ), injectGithubContext | 函数 | 在引擎上提供App,从a读取 ToolContext |
REPO_PATTERN | 常数 | 这个 owner/name 格式化接受的工具(正则表达式源; . 财务报告和审定财务报表 .. 区段不匹配) |
类型 : GithubAppOptions, (中文(简体) ), IGithubApp, (中文(简体) ), GithubOctokit, (中文(简体) ), GithubPermissions, (中文(简体) ), GithubRepositoryToken, (中文(简体) ), GithubBotIdentity, (中文(简体) ), GithubInstallation, (中文(简体) ), GithubWriteToolsOptions, (中文(简体) ), GithubMergeMethod, (中文(简体) ), IGithubGitCredentials, (中文(简体) ), GithubGitCredentialRequest, (中文(简体) ), GithubGitCredential, (中文(简体) ), GithubAppCredentialsOptions, (中文(简体) ), GithubChannel, (中文(简体) ), GithubChannelOptions, (中文(简体) ), GithubApprovalRef, (中文(简体) ), GithubEvent, (中文(简体) ), GithubPayload, (中文(简体) ), GithubSubscriber, (中文(简体) ), GithubSubscriptionOptions, (中文(简体) ), GithubTarget, (中文(简体) ), GithubWebhookResult, (中文(简体) ), GithubIssue, (中文(简体) ), GithubIssueSearch, (中文(简体) ), GithubLabel, (中文(简体) ), GithubPullRequest, (中文(简体) ), GithubFile, (中文(简体) ), GithubDirectory, (中文(简体) ), GithubRelease, (中文(简体) ), GithubComment, (中文(简体) ), GithubIssueLabels, (中文(简体) ), GithubClosedIssue, (中文(简体) ), GithubRepository, (中文(简体) ), GithubRepositoryList, (中文(简体) ), GithubIssueSummary, (中文(简体) ), GithubIssueList, (中文(简体) ), GithubPullRequestSummary, (中文(简体) ), GithubPullRequestList, (中文(简体) ), GithubPushTarget, (中文(简体) ), GithubCheck, (中文(简体) ), GithubCheckOutcome, (中文(简体) ), GithubChecksState, (中文(简体) ), GithubPullRequestChecks, (中文(简体) ), GithubCreatedIssue, (中文(简体) ), GithubCreatedPullRequest, (中文(简体) ), GithubMergeResult。 。 。 .
@chamvi/github/module数字 : githubModule, (中文(简体) ), GithubModule, (中文(简体) ), GITHUB_MODULE_NAME,类型 GithubModuleOptions, (中文(简体) ), GithubModuleChannelOptions。 。 。 .
许可证
原载 Apache 许可证 2.0。 。 。 .