Skip to content

Commit 7197699

Browse files
feat: 使用 repository_dispatch 提高数据上限到 64KB
1. 修改 llm-bot-runner.yml: - 添加 repository_dispatch 事件支持 (types: [llm-task]) - 重命名 job 为 prepare-context - 支持从 client_payload 读取数据 - 当数据过大时从 issue 读取存储的数据 2. 修改 server.py: - 使用 repository_dispatch 触发工作流 - 当数据超过 50KB 时,先创建 issue 存储完整数据 - 在 payload 中传递 issue_number,工作流从 issue 读取数据 - 添加 create_issue 辅助函数 - 保留 workflow_dispatch 作为回退方案 Co-Authored-By: Claude (mimo-v2-flash) <noreply@anthropic.com>
1 parent 94b94d2 commit 7197699

File tree

2 files changed

+117
-31
lines changed

2 files changed

+117
-31
lines changed

.github/workflows/llm-bot-runner.yml

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,52 +11,81 @@ on:
1111
description: '任务的JSON上下文'
1212
required: true
1313
type: string
14+
repository_dispatch:
15+
types: [llm-task]
1416

1517
jobs:
16-
create-issue:
18+
prepare-context:
1719
runs-on: ubuntu-latest
1820
permissions:
1921
issues: write
2022
outputs:
21-
issue_number: ${{ steps.create-issue.outputs.issue_number }}
23+
issue_number: ${{ steps.prepare-context.outputs.issue_number }}
24+
task_content: ${{ steps.prepare-context.outputs.task_content }}
2225

2326
steps:
24-
- name: Create issue
25-
id: create-issue
27+
- name: Prepare context
28+
id: prepare-context
2629
env:
2730
GH_TOKEN: ${{ github.token }}
28-
TASK_CONTENT: ${{ inputs.task }}
29-
CONTEXT_RAW: ${{ inputs.context }}
31+
TASK_CONTENT: ${{ github.event.client_payload.task || inputs.task }}
32+
CONTEXT_RAW: ${{ github.event.client_payload.context || inputs.context }}
33+
ISSUE_NUMBER_FROM_PAYLOAD: ${{ github.event.client_payload.issue_number }}
3034
GITHUB_RUN_ID: ${{ github.run_id }}
3135
GITHUB_REPOSITORY: ${{ github.repository }}
36+
EVENT_TYPE: ${{ github.event_name }}
3237
run: |
33-
# 1. 格式化 Context
34-
FORMATTED_CONTEXT=$(echo "$CONTEXT_RAW" | sed 's/^"//; s/"$//' | jq '.')
38+
echo "Event type: $EVENT_TYPE"
3539
36-
# 2. 构建 Markdown 正文
37-
printf "[工作流运行 #$GITHUB_RUN_ID](https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID)\n\n## Task\n%s\n\n## Context\n\`\`\`json\n%s\n\`\`\`" \
40+
# 1. 从 repository_dispatch 或 workflow_dispatch 获取数据
41+
if [ "$EVENT_TYPE" = "repository_dispatch" ]; then
42+
echo "Using repository_dispatch payload"
43+
44+
# 检查是否需要从 issue 读取(如果 payload 中的 context 为空或太大)
45+
if [ -z "$CONTEXT_RAW" ] || [ "${#CONTEXT_RAW}" -gt 50000 ]; then
46+
echo "Context from payload is empty or too large, reading from issue..."
47+
# 从 payload 的 issue_number 字段获取存储数据的 issue
48+
if [ -n "$ISSUE_NUMBER_FROM_PAYLOAD" ]; then
49+
echo "Reading context from issue #$ISSUE_NUMBER_FROM_PAYLOAD"
50+
# 从 issue body 读取数据
51+
ISSUE_BODY=$(gh issue view "$ISSUE_NUMBER_FROM_PAYLOAD" --repo "$GITHUB_REPOSITORY" --json body --jq '.body')
52+
# 提取 TASK 和 CONTEXT
53+
TASK_CONTENT=$(echo "$ISSUE_BODY" | sed -n 's/.*<!-- TASK_START -->\(.*\)<!-- TASK_END -->.*/\1/p')
54+
CONTEXT_RAW=$(echo "$ISSUE_BODY" | sed -n 's/.*<!-- CONTEXT_START -->\(.*\)<!-- CONTEXT_END -->.*/\1/p')
55+
fi
56+
fi
57+
else
58+
echo "Using workflow_dispatch inputs"
59+
fi
60+
61+
# 2. 格式化 Context
62+
FORMATTED_CONTEXT=$(echo "$CONTEXT_RAW" | sed 's/^"//; s/"$//' | jq '.' 2>/dev/null || echo "$CONTEXT_RAW")
63+
64+
# 3. 构建 Markdown 正文
65+
printf "[工作流运行 #$GITHUB_RUN_ID](https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID)\\n\\n## Task\\n%s\\n\\n## Context\\n\\`\\`\\`json\\n%s\\n\\`\\`\\`" \
3866
"$TASK_CONTENT" "$FORMATTED_CONTEXT" > body.md
3967
40-
# 3. 创建 Issue(硬编码标签 workflow)
68+
# 4. 创建 Issue(硬编码标签 workflow)
4169
ISSUE_URL=$(gh issue create \
4270
--repo "$GITHUB_REPOSITORY" \
4371
--title "[工作流] Run $GITHUB_RUN_ID" \
4472
--body-file body.md \
4573
--label "workflow")
4674
47-
# 4. 提取 Issue 编号
75+
# 5. 提取 Issue 编号
4876
ISSUE_NUMBER=${ISSUE_URL##*/}
4977
echo "issue_number=$ISSUE_NUMBER" >> "$GITHUB_OUTPUT"
78+
echo "task_content=$TASK_CONTENT" >> "$GITHUB_OUTPUT"
5079
5180
echo "成功创建 Issue: $ISSUE_NUMBER"
5281
5382
run-llm-bot:
54-
needs: create-issue
83+
needs: prepare-context
5584
runs-on: ubuntu-latest
5685
env:
57-
LLM_TASK: ${{ inputs.task }}
58-
LLM_CONTEXT: ${{ inputs.context }}
59-
LOG_ISSUE_NUMBER: ${{ needs.create-issue.outputs.issue_number }}
86+
LLM_TASK: ${{ needs.prepare-context.outputs.task_content }}
87+
LLM_CONTEXT: ${{ github.event.client_payload.context || inputs.context }}
88+
LOG_ISSUE_NUMBER: ${{ needs.prepare-context.outputs.issue_number }}
6089
# GitHub身份令牌(4个名称都设置)- 使用agent的token
6190
GITHUB_TOKEN: ${{ secrets.WEINAR_API_KEY }}
6291
GH_TOKEN: ${{ secrets.WEINAR_API_KEY }}
@@ -213,7 +242,7 @@ jobs:
213242
echo ""
214243
215244
# 构建新任务字符串,包含读取context.json的指示
216-
ENHANCED_TASK=$(printf "%s\n\n> 任务上下文已保存到/app/context.json,共%s字符。阅读该文件以了解上下文!" "$LLM_TASK" "$CONTEXT_CHARS")
245+
ENHANCED_TASK=$(printf "%s\\n\\n> 任务上下文已保存到/app/context.json,共%s字符。阅读该文件以了解上下文!" "$LLM_TASK" "$CONTEXT_CHARS")
217246
echo "增强任务: $ENHANCED_TASK"
218247
219248
claude \

server.py

Lines changed: 71 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -937,7 +937,7 @@ async def trigger_workflow(client: httpx.AsyncClient, ctx: TaskContext, task_tex
937937
# 检查上下文大小
938938
context_str = ctx.to_json_string()
939939
logger.info(f"Context size: {len(context_str)} chars")
940-
940+
941941
# 调试信息
942942
if ctx.comments_history:
943943
logger.info(f"Comments history: {len(ctx.comments_history)} items")
@@ -951,35 +951,66 @@ async def trigger_workflow(client: httpx.AsyncClient, ctx: TaskContext, task_tex
951951
logger.info(f" ReviewComment[{i}]: @{comment.get('user')} - {comment.get('path')}: {comment.get('body', '')[:50]}...")
952952
if ctx.is_truncated is not None:
953953
logger.info(f"Context was truncated: {ctx.is_truncated}")
954-
954+
955955
# 检查是否有重复/空字段
956956
logger.info(f"diff_content present: {bool(ctx.diff_content)}")
957957
logger.info(f"clone_url: {ctx.clone_url}")
958958
logger.info(f"head_ref: {ctx.head_ref}, base_ref: {ctx.base_ref}")
959959
logger.info(f"head_repo: {ctx.head_repo}, base_repo: {ctx.base_repo}")
960-
960+
961961
# 记录任务描述
962962
logger.info(f"LLM_TASK to send: '{task_text[:200]}{'...' if len(task_text) > 200 else ''}'")
963-
964-
if len(context_str) > 60000: # GitHub限制
965-
logger.warning(f"Context too large ({len(context_str)} chars), truncating...")
966-
# 简化上下文
967-
ctx.diff_content = "[Diff truncated due to size limits]"
968-
if ctx.comments_history and len(ctx.comments_history) > 10:
969-
logger.info(f"Reducing comments history from {len(ctx.comments_history)} to 10 items")
970-
ctx.comments_history = ctx.comments_history[-10:] # 只保留最近10条
971-
context_str = ctx.to_json_string()
963+
964+
# 检查是否需要将数据存储到 issue(因为 repository_dispatch 的 payload 也有 64KB 限制)
965+
issue_number = None
966+
use_repository_dispatch = True
967+
968+
# 如果数据太大,需要先创建 issue 存储数据
969+
if len(context_str) > 50000 or len(task_text) > 10000:
970+
logger.warning(f"Data too large (context: {len(context_str)}, task: {len(task_text)}), storing in issue...")
971+
972+
# 创建 issue 来存储数据
973+
issue_body = f"""<!-- TASK_START -->{task_text}<!-- TASK_END -->
974+
<!-- CONTEXT_START -->{context_str}<!-- CONTEXT_END -->
975+
976+
> 这个 issue 用于存储 workflow 的上下文数据,由 repository_dispatch 触发。
977+
> Run ID: {os.getenv('GITHUB_RUN_ID', 'unknown')}
978+
> Triggered by: {ctx.trigger_user}
979+
"""
980+
981+
issue_url = await create_issue(client, f"[数据存储] Context for node {node_id}", issue_body)
982+
if issue_url:
983+
issue_number = issue_url.split('/')[-1]
984+
logger.info(f"Created issue #{issue_number} to store context data")
985+
# 清空数据,因为将从 issue 读取
986+
context_str = ""
987+
task_text = ""
988+
else:
989+
logger.error("Failed to create issue for large data, falling back to truncation")
990+
# 回退到截断方案
991+
use_repository_dispatch = False
972992

973993
url = f"{REST_API}/repos/{CONTROL_REPO}/actions/workflows/llm-bot-runner.yml/dispatches"
974994
headers = {"Authorization": f"token {GQL_TOKEN}", "Accept": "application/vnd.github.v3+json"}
975995

996+
# 构建 payload
976997
payload = {
977998
"ref": "main",
978-
"inputs": {
999+
"client_payload": {}
1000+
}
1001+
1002+
if use_repository_dispatch:
1003+
# 使用 repository_dispatch
1004+
payload["client_payload"]["task"] = task_text[:2000] if task_text else ""
1005+
payload["client_payload"]["context"] = context_str if context_str else ""
1006+
if issue_number:
1007+
payload["client_payload"]["issue_number"] = issue_number
1008+
else:
1009+
# 回退到 workflow_dispatch(数据已截断)
1010+
payload["inputs"] = {
9791011
"task": task_text[:2000],
9801012
"context": context_str
9811013
}
982-
}
9831014

9841015
try:
9851016
r = await client.post(url, headers=headers, json=payload)
@@ -1012,6 +1043,32 @@ async def trigger_workflow(client: httpx.AsyncClient, ctx: TaskContext, task_tex
10121043
logger.error(f"Exception during workflow dispatch: {e}")
10131044
return False
10141045

1046+
1047+
async def create_issue(client: httpx.AsyncClient, title: str, body: str) -> Optional[str]:
1048+
"""
1049+
创建 GitHub Issue 并返回 URL
1050+
"""
1051+
url = f"{REST_API}/repos/{CONTROL_REPO}/issues"
1052+
headers = {"Authorization": f"token {GQL_TOKEN}", "Accept": "application/vnd.github.v3+json"}
1053+
1054+
payload = {
1055+
"title": title,
1056+
"body": body,
1057+
"labels": ["context-data"]
1058+
}
1059+
1060+
try:
1061+
r = await client.post(url, headers=headers, json=payload)
1062+
if r.status_code == 201:
1063+
data = r.json()
1064+
return data.get("html_url")
1065+
else:
1066+
logger.error(f"Failed to create issue: {r.status_code} - {r.text}")
1067+
return None
1068+
except Exception as e:
1069+
logger.error(f"Exception creating issue: {e}")
1070+
return None
1071+
10151072
# --- 轮询逻辑 ---
10161073
async def poll_loop():
10171074
"""

0 commit comments

Comments
 (0)