Bold questions
This commit is contained in:
@@ -34,6 +34,7 @@ type Options struct {
|
||||
ForkSession bool
|
||||
GitName string
|
||||
GitEmail string
|
||||
Guidance string
|
||||
Hooks map[string][]HookMatcher
|
||||
MCPServers []*mcp.Server
|
||||
Transcript io.Writer
|
||||
@@ -127,6 +128,27 @@ func (e Event) Blocks() ([]Block, error) {
|
||||
return blocks, nil
|
||||
}
|
||||
|
||||
func (e Event) TextDelta() (string, error) {
|
||||
msg := struct {
|
||||
ParentToolUseID *string `json:"parent_tool_use_id"`
|
||||
Event struct {
|
||||
Type string `json:"type"`
|
||||
Delta struct {
|
||||
Type string `json:"type"`
|
||||
Text string `json:"text"`
|
||||
} `json:"delta"`
|
||||
} `json:"event"`
|
||||
}{}
|
||||
err := json.Unmarshal(e.Raw, &msg)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if msg.ParentToolUseID != nil || msg.Event.Type != "content_block_delta" || msg.Event.Delta.Type != "text_delta" {
|
||||
return "", nil
|
||||
}
|
||||
return msg.Event.Delta.Text, nil
|
||||
}
|
||||
|
||||
func (e Event) Result() (Result, error) {
|
||||
res := Result{}
|
||||
err := json.Unmarshal(e.Raw, &res)
|
||||
@@ -250,6 +272,7 @@ func (s *Session) buildArgs(opts Options) ([]string, error) {
|
||||
"--output-format", "stream-json",
|
||||
"--input-format", "stream-json",
|
||||
"--verbose",
|
||||
"--include-partial-messages",
|
||||
"--permission-mode", "bypassPermissions",
|
||||
"--allow-dangerously-skip-permissions",
|
||||
"--settings", string(settings),
|
||||
@@ -260,6 +283,10 @@ func (s *Session) buildArgs(opts Options) ([]string, error) {
|
||||
args = append(args, "--model", opts.Model)
|
||||
}
|
||||
|
||||
if opts.Guidance != "" {
|
||||
args = append(args, "--append-system-prompt", opts.Guidance)
|
||||
}
|
||||
|
||||
if opts.SessionID != "" {
|
||||
args = append(args, "--session-id="+opts.SessionID)
|
||||
}
|
||||
@@ -464,7 +491,9 @@ func (s *Session) handleLine(line []byte) {
|
||||
if env.Type == "control_response" {
|
||||
s.learnScrub(env.Response)
|
||||
}
|
||||
s.record("recv", line)
|
||||
if env.Type != "stream_event" {
|
||||
s.record("recv", line)
|
||||
}
|
||||
s.writeMu.Unlock()
|
||||
|
||||
switch env.Type {
|
||||
|
||||
@@ -14,7 +14,6 @@ import (
|
||||
|
||||
"g.fc.run/misc/byre/internal/claude"
|
||||
"g.fc.run/misc/byre/internal/mcp"
|
||||
"g.fc.run/misc/byre/internal/report"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -23,25 +22,30 @@ const (
|
||||
gitEmail = "test@byre.invalid"
|
||||
)
|
||||
|
||||
func TestCommitIdentityHooksAndReport(t *testing.T) {
|
||||
func TestCommitIdentityHooksAndMCP(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := testContext(t)
|
||||
repo := scratchRepo(t)
|
||||
|
||||
reports := []report.Report{}
|
||||
finished := 0
|
||||
mu := sync.Mutex{}
|
||||
gate := &report.Gate{OnReport: func(r report.Report) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
reports = append(reports, r)
|
||||
}}
|
||||
finish := mcp.Tool{
|
||||
Name: "finish",
|
||||
Description: "Call this once the task is complete.",
|
||||
InputSchema: json.RawMessage(`{"type": "object", "properties": {}}`),
|
||||
Handler: func(ctx context.Context, args json.RawMessage) (string, error) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
finished++
|
||||
return "noted", nil
|
||||
},
|
||||
}
|
||||
|
||||
tools := []string{}
|
||||
s := start(t, ctx, claude.Options{
|
||||
Cwd: repo,
|
||||
MCPServers: []*mcp.Server{{Name: "byre", Version: "0.0.0", Tools: []mcp.Tool{gate.Tool()}}},
|
||||
MCPServers: []*mcp.Server{{Name: "byre", Version: "0.0.0", Tools: []mcp.Tool{finish}}},
|
||||
Hooks: map[string][]claude.HookMatcher{
|
||||
"Stop": {{Func: gate.StopHook}},
|
||||
"PostToolUse": {{Func: func(ctx context.Context, input json.RawMessage) (map[string]any, error) {
|
||||
in := struct {
|
||||
ToolName string `json:"tool_name"`
|
||||
@@ -58,15 +62,15 @@ func TestCommitIdentityHooksAndReport(t *testing.T) {
|
||||
},
|
||||
})
|
||||
|
||||
send(t, s, `Create a file hello.txt containing exactly the word hi, then git add and git commit it with the message "add hello".`)
|
||||
send(t, s, `Create a file hello.txt containing exactly the word hi, then git add and git commit it with the message "add hello", then call the finish tool.`)
|
||||
waitResult(t, ctx, s, nil)
|
||||
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
t.Logf("tools=%v reports=%d nudges=%d", tools, len(reports), gate.Nudges())
|
||||
t.Logf("tools=%v finished=%d", tools, finished)
|
||||
|
||||
if len(reports) == 0 {
|
||||
t.Fatalf("report was never called")
|
||||
if finished == 0 {
|
||||
t.Fatalf("the MCP finish tool was never called")
|
||||
}
|
||||
if len(tools) == 0 {
|
||||
t.Fatalf("PostToolUse hook never fired")
|
||||
@@ -118,6 +122,34 @@ func TestStopHookBlocks(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTextDeltas(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := testContext(t)
|
||||
s := start(t, ctx, claude.Options{Cwd: scratchRepo(t)})
|
||||
|
||||
send(t, s, "Without using any tools, count from one to twenty in words, separated by spaces.")
|
||||
deltas := []string{}
|
||||
text := waitResult(t, ctx, s, func(ev claude.Event) {
|
||||
if ev.Type != "stream_event" {
|
||||
return
|
||||
}
|
||||
d, err := ev.TextDelta()
|
||||
if err != nil {
|
||||
t.Fatalf("parse stream event: %v", err)
|
||||
}
|
||||
if d != "" {
|
||||
deltas = append(deltas, d)
|
||||
}
|
||||
})
|
||||
|
||||
if len(deltas) < 2 {
|
||||
t.Fatalf("expected several text deltas, got %d", len(deltas))
|
||||
}
|
||||
if strings.Join(deltas, "") != text {
|
||||
t.Fatalf("deltas %q don't add up to the final text %q", deltas, text)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInterrupt(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := testContext(t)
|
||||
|
||||
+40
-40
File diff suppressed because one or more lines are too long
+16
-21
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+15
-15
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user