Skip to content

Commit 0313c05

Browse files
committed
Docs: Add checkpoint-filter.ts explanation to README
1 parent d13b7ec commit 0313c05

File tree

1 file changed

+81
-5
lines changed

1 file changed

+81
-5
lines changed

examples/github-issue-bot/README.md

Lines changed: 81 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,82 @@ Add `ANTHROPIC_API_KEY` with your Anthropic API key.
5050

5151
---
5252

53+
## How checkpoint-filter.ts Works
54+
55+
`checkpoint-filter.ts` is a working example of processing Perstack's event stream.
56+
57+
### Event Stream
58+
59+
When you run `perstack run --stream-events`, it outputs JSON events to stdout:
60+
61+
```json
62+
{"type":"callTool","toolCall":{"toolName":"think","args":{"thought":"..."}}}
63+
{"type":"callTool","toolCall":{"toolName":"readTextFile","args":{"path":"..."}}}
64+
{"type":"completeRun","text":"Final answer here"}
65+
```
66+
67+
### Processing Events
68+
69+
The filter reads stdin line by line, parses JSON, and formats human-readable output:
70+
71+
```typescript
72+
function formatEvent(event: Record<string, unknown>): string | null {
73+
const type = event.type as string
74+
switch (type) {
75+
case "callTool": {
76+
const toolCall = event.toolCall as Record<string, unknown>
77+
const toolName = toolCall?.toolName as string
78+
const args = toolCall?.args as Record<string, unknown>
79+
if (toolName === "think") {
80+
return `💭 ${args?.thought}`
81+
}
82+
if (toolName === "readTextFile") {
83+
return `📖 Reading: ${args?.path}`
84+
}
85+
// ... more tool handlers
86+
}
87+
case "completeRun": {
88+
finalAnswer = event.text as string
89+
return "✅ Done"
90+
}
91+
}
92+
}
93+
```
94+
95+
### Real-time Updates
96+
97+
The filter updates a GitHub comment in real-time using the GitHub API:
98+
99+
```typescript
100+
const res = await fetch(
101+
`https://api.github.com/repos/${GITHUB_REPO}/issues/comments/${COMMENT_ID}`,
102+
{
103+
method: "PATCH",
104+
headers: { Authorization: `Bearer ${GH_TOKEN}` },
105+
body: JSON.stringify({ body: formattedLog }),
106+
}
107+
)
108+
```
109+
110+
### Event Types
111+
112+
| Event Type | Description | Example Output |
113+
| ------------- | ------------------------------ | ----------------------- |
114+
| `callTool` | Tool invocation | `📖 Reading: src/app.ts` |
115+
| `completeRun` | Run completed with final text | `✅ Done` |
116+
117+
### Tool-specific Formatting
118+
119+
| Tool Name | Icon | Output |
120+
| ------------------- | ---- | ------------------------------- |
121+
| `think` | 💭 | Thought content (truncated) |
122+
| `readTextFile` | 📖 | File path |
123+
| `listDirectory` | 📁 | Directory path |
124+
| `exec` || Command + args |
125+
| `attemptCompletion` || "Generating answer..." |
126+
127+
---
128+
53129
## Trigger Conditions
54130

55131
| Event | Trigger |
@@ -73,8 +149,8 @@ For OpenAI, add `OPENAI_API_KEY` secret instead.
73149

74150
## Files
75151

76-
| File | Purpose |
77-
| ---------------------- | ----------------------- |
78-
| `issue-bot.yml` | GitHub Actions workflow |
79-
| `checkpoint-filter.ts` | Real-time log formatter |
80-
| `perstack.toml` | Expert definition |
152+
| File | Purpose |
153+
| ---------------------- | ---------------------------------------- |
154+
| `issue-bot.yml` | GitHub Actions workflow |
155+
| `checkpoint-filter.ts` | Event stream processor (working example) |
156+
| `perstack.toml` | Expert definition |

0 commit comments

Comments
 (0)