]> git.giacomolli.uk - onechat/blobdiff - chain.go
Send terminal images by local path
[onechat] / chain.go
index 0211787132ad6c940cfeed0005d2a06c264da3fa..23c7dec14a6053d8ec38d5201a06f6dc916b4532 100644 (file)
--- a/chain.go
+++ b/chain.go
@@ -32,6 +32,7 @@ type Chain struct {
        tools   *Toolbox
        request ModelRequest
        take    func() []Message
        tools   *Toolbox
        request ModelRequest
        take    func() []Message
+       images  *ImageStore
 }
 
 // Run runs the chain from input, the input of its first request, and returns
 }
 
 // Run runs the chain from input, the input of its first request, and returns
@@ -47,6 +48,7 @@ func (c *Chain) Run(ctx context.Context, input []any) (string, error) {
                }
 
                var text string
                }
 
                var text string
+
                input, text, err = c.handle(ctx, input, response)
                if err != nil {
                        return "", err
                input, text, err = c.handle(ctx, input, response)
                if err != nil {
                        return "", err
@@ -63,8 +65,11 @@ func (c *Chain) Run(ctx context.Context, input []any) (string, error) {
 // the messages of take. After the final answer it returns no input, and the
 // replies of the answer as its text.
 func (c *Chain) handle(ctx context.Context, input []any, response ModelResponse) ([]any, string, error) {
 // the messages of take. After the final answer it returns no input, and the
 // replies of the answer as its text.
 func (c *Chain) handle(ctx context.Context, input []any, response ModelResponse) ([]any, string, error) {
-       var outputs []any
-       var replies []string
+       var (
+               outputs []any
+               replies []string
+       )
+
        for _, raw := range response.Output {
                item, err := chainInputItem(raw)
                if err != nil {
        for _, raw := range response.Output {
                item, err := chainInputItem(raw)
                if err != nil {
@@ -74,6 +79,7 @@ func (c *Chain) handle(ctx context.Context, input []any, response ModelResponse)
                input = append(input, item)
 
                var call ChainFunctionCall
                input = append(input, item)
 
                var call ChainFunctionCall
+
                err = json.Unmarshal(raw, &call)
                if err != nil {
                        return nil, "", fmt.Errorf("decode output item: %w", err)
                err = json.Unmarshal(raw, &call)
                if err != nil {
                        return nil, "", fmt.Errorf("decode output item: %w", err)
@@ -117,7 +123,12 @@ func (c *Chain) handle(ctx context.Context, input []any, response ModelResponse)
 
        input = append(input, outputs...)
        for _, message := range c.take() {
 
        input = append(input, outputs...)
        for _, message := range c.take() {
-               input = append(input, modelUserMessage(message.Text))
+               item, err := imageUserMessage(c.images, message.Text)
+               if err != nil {
+                       return nil, "", fmt.Errorf("read queued images: %w", err)
+               }
+
+               input = append(input, item)
        }
 
        return input, "", nil
        }
 
        return input, "", nil
@@ -136,7 +147,7 @@ type ChainFunctionCall struct {
 type ChainFunctionCallOutput struct {
        Type   string `json:"type"`
        CallID string `json:"call_id"`
 type ChainFunctionCallOutput struct {
        Type   string `json:"type"`
        CallID string `json:"call_id"`
-       Output string `json:"output"`
+       Output any    `json:"output"`
 }
 
 // chainInputItem returns an output item as an input item for the next request.
 }
 
 // chainInputItem returns an output item as an input item for the next request.
@@ -144,6 +155,7 @@ type ChainFunctionCallOutput struct {
 // id.
 func chainInputItem(raw json.RawMessage) (map[string]any, error) {
        var item map[string]any
 // id.
 func chainInputItem(raw json.RawMessage) (map[string]any, error) {
        var item map[string]any
+
        err := json.Unmarshal(raw, &item)
        if err != nil {
                return nil, fmt.Errorf("decode output item: %w", err)
        err := json.Unmarshal(raw, &item)
        if err != nil {
                return nil, fmt.Errorf("decode output item: %w", err)