Image input
This commit is contained in:
+29
-15
@@ -83,11 +83,11 @@ func New(st *store.Store, limits Limits, worktreeRoot string) *Manager {
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Manager) Create(ctx context.Context, task api.Task, creator api.User, prompt, model string) (api.AgentSession, error) {
|
||||
return m.create(ctx, task, creator, prompt, model, creator.Login)
|
||||
func (m *Manager) Create(ctx context.Context, task api.Task, creator api.User, prompt, model string, images ...string) (api.AgentSession, error) {
|
||||
return m.create(ctx, task, creator, prompt, model, creator.Login, images)
|
||||
}
|
||||
|
||||
func (m *Manager) create(ctx context.Context, task api.Task, creator api.User, prompt, model, actor string) (api.AgentSession, error) {
|
||||
func (m *Manager) create(ctx context.Context, task api.Task, creator api.User, prompt, model, actor string, images []string) (api.AgentSession, error) {
|
||||
if creator.GitName == "" || creator.GitEmail == "" {
|
||||
return api.AgentSession{}, ErrNoGitIdentity
|
||||
}
|
||||
@@ -124,10 +124,10 @@ func (m *Manager) create(ctx context.Context, task api.Task, creator api.User, p
|
||||
return api.AgentSession{}, err
|
||||
}
|
||||
|
||||
return m.turn(ctx, sess, task, actor, prompt)
|
||||
return m.turn(ctx, sess, task, actor, prompt, images)
|
||||
}
|
||||
|
||||
func (m *Manager) Send(ctx context.Context, sessionID, actor, text, model string) (api.AgentSession, error) {
|
||||
func (m *Manager) Send(ctx context.Context, sessionID, actor, text, model string, images ...string) (api.AgentSession, error) {
|
||||
sess, err := m.store.GetSession(ctx, sessionID)
|
||||
if err != nil {
|
||||
return api.AgentSession{}, err
|
||||
@@ -150,7 +150,7 @@ func (m *Manager) Send(ctx context.Context, sessionID, actor, text, model string
|
||||
return api.AgentSession{}, err
|
||||
}
|
||||
|
||||
return m.turn(ctx, sess, task, actor, text)
|
||||
return m.turn(ctx, sess, task, actor, text, images)
|
||||
}
|
||||
|
||||
func (m *Manager) Interrupt(ctx context.Context, sessionID string) (api.AgentSession, error) {
|
||||
@@ -249,7 +249,7 @@ func (m *Manager) Recover(ctx context.Context) error {
|
||||
continue
|
||||
}
|
||||
|
||||
err = m.message(ctx, l, "byre", restartNotice)
|
||||
err = m.message(ctx, l, "byre", restartNotice, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -310,7 +310,7 @@ func (m *Manager) Usage(ctx context.Context) (Usage, error) {
|
||||
return u, nil
|
||||
}
|
||||
|
||||
func (m *Manager) turn(ctx context.Context, sess api.AgentSession, task api.Task, actor, text string) (api.AgentSession, error) {
|
||||
func (m *Manager) turn(ctx context.Context, sess api.AgentSession, task api.Task, actor, text string, images []string) (api.AgentSession, error) {
|
||||
m.capMu.Lock()
|
||||
defer m.capMu.Unlock()
|
||||
|
||||
@@ -320,7 +320,7 @@ func (m *Manager) turn(ctx context.Context, sess api.AgentSession, task api.Task
|
||||
}
|
||||
|
||||
if room {
|
||||
return m.start(ctx, sess, task, actor, text, api.AgentSessionStateIdle)
|
||||
return m.start(ctx, sess, task, actor, text, images, api.AgentSessionStateIdle)
|
||||
}
|
||||
|
||||
err = transition(ctx, m.store, sess.Id, api.AgentSessionStateIdle, api.AgentSessionStateQueued, actor)
|
||||
@@ -333,6 +333,7 @@ func (m *Manager) turn(ctx context.Context, sess api.AgentSession, task api.Task
|
||||
Vendor: sess.Vendor,
|
||||
Actor: actor,
|
||||
Text: text,
|
||||
Images: images,
|
||||
CreatedAt: time.Now().UTC(),
|
||||
})
|
||||
if err != nil {
|
||||
@@ -342,7 +343,7 @@ func (m *Manager) turn(ctx context.Context, sess api.AgentSession, task api.Task
|
||||
return m.store.GetSession(ctx, sess.Id)
|
||||
}
|
||||
|
||||
func (m *Manager) start(ctx context.Context, sess api.AgentSession, task api.Task, actor, text string, from api.AgentSessionState) (api.AgentSession, error) {
|
||||
func (m *Manager) start(ctx context.Context, sess api.AgentSession, task api.Task, actor, text string, images []string, from api.AgentSessionState) (api.AgentSession, error) {
|
||||
err := transition(ctx, m.store, sess.Id, from, api.AgentSessionStateRunning, actor)
|
||||
if err != nil {
|
||||
return api.AgentSession{}, err
|
||||
@@ -360,7 +361,7 @@ func (m *Manager) start(ctx context.Context, sess api.AgentSession, task api.Tas
|
||||
return api.AgentSession{}, err
|
||||
}
|
||||
|
||||
err = m.message(ctx, l, actor, text)
|
||||
err = m.message(ctx, l, actor, text, images)
|
||||
if err != nil {
|
||||
return api.AgentSession{}, err
|
||||
}
|
||||
@@ -430,7 +431,7 @@ func (m *Manager) drain(ctx context.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = m.start(ctx, sess, task, q.Actor, q.Text, api.AgentSessionStateQueued)
|
||||
_, err = m.start(ctx, sess, task, q.Actor, q.Text, q.Images, api.AgentSessionStateQueued)
|
||||
if err != nil {
|
||||
slog.Error("start queued turn", "session", q.SessionID, "err", err)
|
||||
}
|
||||
@@ -467,12 +468,25 @@ func transition(ctx context.Context, st *store.Store, id string, from, to api.Ag
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *Manager) message(ctx context.Context, l *live, actor, text string) error {
|
||||
func (m *Manager) message(ctx context.Context, l *live, actor, text string, images []string) error {
|
||||
imgs := []claude.Image{}
|
||||
for _, id := range images {
|
||||
b, data, err := m.store.ReadBlob(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
imgs = append(imgs, claude.Image{MediaType: b.ContentType, Data: data})
|
||||
}
|
||||
|
||||
head, err := git.Head(l.dir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = m.emit(ctx, l, actor, "user.message", map[string]any{"text": text, "head": head})
|
||||
payload := map[string]any{"text": text, "head": head}
|
||||
if len(images) > 0 {
|
||||
payload["images"] = images
|
||||
}
|
||||
err = m.emit(ctx, l, actor, "user.message", payload)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -485,7 +499,7 @@ func (m *Manager) message(ctx context.Context, l *live, actor, text string) erro
|
||||
l.rateLimited = nil
|
||||
m.mu.Unlock()
|
||||
|
||||
return l.sess.Send(text)
|
||||
return l.sess.Send(text, imgs...)
|
||||
}
|
||||
|
||||
func (m *Manager) ensureLive(ctx context.Context, sess api.AgentSession, task api.Task) (*live, error) {
|
||||
|
||||
Reference in New Issue
Block a user