Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 20 additions & 20 deletions cmd/attach/attach.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
"time"

tea "github.com/charmbracelet/bubbletea"
"github.com/coder/agentapi/lib/httpapi"
"github.com/coder/agentapi/lib/types"
"github.com/spf13/cobra"
sse "github.com/tmaxmax/go-sse"
"golang.org/x/term"
Expand All @@ -35,27 +35,27 @@ func (c *ChannelWriter) Receive() ([]byte, bool) {
}

type model struct {
screen string
conversation string
}

func (m model) Init() tea.Cmd {
// Just return `nil`, which means "no I/O right now, please."
return nil
}

type screenMsg struct {
screen string
type conversationMsg struct {
conversation string
}

type finishMsg struct{}

//lint:ignore U1000 The Update function is used by the Bubble Tea framework
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case screenMsg:
m.screen = msg.screen
if m.screen != "" && m.screen[len(m.screen)-1] != '\n' {
m.screen += "\n"
case conversationMsg:
m.conversation = msg.conversation
if m.conversation != "" && m.conversation[len(m.conversation)-1] != '\n' {
m.conversation += "\n"
}
case tea.KeyMsg:
if msg.String() == "ctrl+c" {
Expand All @@ -69,10 +69,10 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
}

func (m model) View() string {
return m.screen
return m.conversation
}

func ReadScreenOverHTTP(ctx context.Context, url string, ch chan<- httpapi.ScreenUpdateBody) error {
func ReadScreenOverHTTP(ctx context.Context, url string, ch chan<- types.ScreenUpdateBody) error {
req, _ := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
req.Header.Set("Content-Type", "application/json")

Expand All @@ -85,25 +85,25 @@ func ReadScreenOverHTTP(ctx context.Context, url string, ch chan<- httpapi.Scree
}()

for ev, err := range sse.Read(res.Body, &sse.ReadConfig{
// 256KB: screen can be big. The default terminal size is 80x1000,
// 256KB: conversation can be big. The default terminal size is 80x1000,
// which can be over 80000 bytes.
MaxEventSize: 256 * 1024,
}) {
if err != nil {
return xerrors.Errorf("failed to read sse: %w", err)
}
var screen httpapi.ScreenUpdateBody
var screen types.ScreenUpdateBody
if err := json.Unmarshal([]byte(ev.Data), &screen); err != nil {
return xerrors.Errorf("failed to unmarshal screen: %w", err)
return xerrors.Errorf("failed to unmarshal conversation: %w", err)
}
ch <- screen
}
return nil
}

func WriteRawInputOverHTTP(ctx context.Context, url string, msg string) error {
messageRequest := httpapi.MessageRequestBody{
Type: httpapi.MessageTypeRaw,
messageRequest := types.MessageRequestBody{
Type: types.MessageTypeRaw,
Content: msg,
}
messageRequestBytes, err := json.Marshal(messageRequest)
Expand Down Expand Up @@ -145,16 +145,16 @@ func runAttach(remoteUrl string) error {
}
tee := io.TeeReader(os.Stdin, stdinWriter)
p := tea.NewProgram(model{}, tea.WithInput(tee), tea.WithAltScreen())
screenCh := make(chan httpapi.ScreenUpdateBody, 64)
screenCh := make(chan types.ScreenUpdateBody, 64)

readScreenErrCh := make(chan error, 1)
go func() {
defer close(readScreenErrCh)
if err := ReadScreenOverHTTP(ctx, remoteUrl+"/internal/screen", screenCh); err != nil {
if err := ReadScreenOverHTTP(ctx, remoteUrl+"/internal/conversation", screenCh); err != nil {
if errors.Is(err, context.Canceled) {
return
}
readScreenErrCh <- xerrors.Errorf("failed to read screen: %w", err)
readScreenErrCh <- xerrors.Errorf("failed to read conversation: %w", err)
}
}()
writeRawInputErrCh := make(chan error, 1)
Expand Down Expand Up @@ -189,8 +189,8 @@ func runAttach(remoteUrl string) error {
if !ok {
return
}
p.Send(screenMsg{
screen: screenUpdate.Screen,
p.Send(conversationMsg{
conversation: screenUpdate.Screen,
})
}
}
Expand Down
49 changes: 31 additions & 18 deletions cmd/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@ import (
"sort"
"strings"

"github.com/coder/agentapi/lib/cli/msgfmt"
"github.com/coder/agentapi/lib/cli/termexec"
"github.com/coder/agentapi/lib/types"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"golang.org/x/xerrors"

"github.com/coder/agentapi/lib/httpapi"
"github.com/coder/agentapi/lib/logctx"
"github.com/coder/agentapi/lib/msgfmt"
"github.com/coder/agentapi/lib/termexec"
)

type AgentType = msgfmt.AgentType
Expand Down Expand Up @@ -68,14 +69,25 @@ func parseAgentType(firstArg string, agentTypeVar string) (AgentType, error) {
return AgentTypeCustom, nil
}

func parseInteractionType(interactionModeVar string) (types.InteractionType, error) {
return types.CLIInteractionType, nil
}

func runServer(ctx context.Context, logger *slog.Logger, argsToPass []string) error {
agent := argsToPass[0]
agentTypeValue := viper.GetString(FlagType)
interactionTypeValue := viper.GetString(FlagInteractionType)

agentType, err := parseAgentType(agent, agentTypeValue)
if err != nil {
return xerrors.Errorf("failed to parse agent type: %w", err)
}

interactionType, err := parseInteractionType(interactionTypeValue)
if err != nil {
return xerrors.Errorf("failed to parse interaction type: %w", err)
}

termWidth := viper.GetUint16(FlagTermWidth)
termHeight := viper.GetUint16(FlagTermHeight)

Expand Down Expand Up @@ -104,12 +116,13 @@ func runServer(ctx context.Context, logger *slog.Logger, argsToPass []string) er
}
port := viper.GetInt(FlagPort)
srv, err := httpapi.NewServer(ctx, httpapi.ServerConfig{
AgentType: agentType,
Process: process,
Port: port,
ChatBasePath: viper.GetString(FlagChatBasePath),
AllowedHosts: viper.GetStringSlice(FlagAllowedHosts),
AllowedOrigins: viper.GetStringSlice(FlagAllowedOrigins),
AgentType: agentType,
Process: process,
Port: port,
InteractionType: interactionType,
ChatBasePath: viper.GetString(FlagChatBasePath),
AllowedHosts: viper.GetStringSlice(FlagAllowedHosts),
AllowedOrigins: viper.GetStringSlice(FlagAllowedOrigins),
})
if err != nil {
return xerrors.Errorf("failed to create server: %w", err)
Expand All @@ -118,7 +131,6 @@ func runServer(ctx context.Context, logger *slog.Logger, argsToPass []string) er
fmt.Println(srv.GetOpenAPI())
return nil
}
srv.StartSnapshotLoop(ctx)
logger.Info("Starting server on port", "port", port)
processExitCh := make(chan error, 1)
go func() {
Expand Down Expand Up @@ -163,15 +175,16 @@ type flagSpec struct {
}

const (
FlagType = "type"
FlagPort = "port"
FlagPrintOpenAPI = "print-openapi"
FlagChatBasePath = "chat-base-path"
FlagTermWidth = "term-width"
FlagTermHeight = "term-height"
FlagAllowedHosts = "allowed-hosts"
FlagAllowedOrigins = "allowed-origins"
FlagExit = "exit"
FlagType = "type"
FlagPort = "port"
FlagPrintOpenAPI = "print-openapi"
FlagChatBasePath = "chat-base-path"
FlagTermWidth = "term-width"
FlagTermHeight = "term-height"
FlagAllowedHosts = "allowed-hosts"
FlagAllowedOrigins = "allowed-origins"
FlagExit = "exit"
FlagInteractionType = "interaction"
)

func CreateServerCmd() *cobra.Command {
Expand Down
6 changes: 3 additions & 3 deletions lib/httpapi/claude.go → lib/cli/claude.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package httpapi
package cli

import (
mf "github.com/coder/agentapi/lib/msgfmt"
st "github.com/coder/agentapi/lib/screentracker"
mf "github.com/coder/agentapi/lib/cli/msgfmt"
st "github.com/coder/agentapi/lib/cli/screentracker"
)

func formatPaste(message string) []st.MessagePart {
Expand Down
Loading