mirror of
https://github.com/danielmiessler/Fabric.git
synced 2026-01-09 22:38:10 -05:00
Compare commits
40 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
12d83dad6d | ||
|
|
14ef9fd41c | ||
|
|
584e0c8547 | ||
|
|
914b312c2e | ||
|
|
8153d690cc | ||
|
|
d03bdbeb9b | ||
|
|
87730043b5 | ||
|
|
3285b8e330 | ||
|
|
686d039392 | ||
|
|
d7683e4c39 | ||
|
|
56f995afb4 | ||
|
|
17bde814cc | ||
|
|
525f972d22 | ||
|
|
161ce65ae6 | ||
|
|
72f1429db9 | ||
|
|
b5fe3f2ad8 | ||
|
|
2155ff9fc0 | ||
|
|
d33175e5b6 | ||
|
|
6dbd24e541 | ||
|
|
d1c527c421 | ||
|
|
c0bd61ba49 | ||
|
|
8f0cc85742 | ||
|
|
7275dfbd6b | ||
|
|
9f94cfb718 | ||
|
|
e1fa674a3f | ||
|
|
34f804be3a | ||
|
|
83cd8a1912 | ||
|
|
d347ef0dcc | ||
|
|
44cc9bbcac | ||
|
|
4aa0b99c74 | ||
|
|
d90e8081ac | ||
|
|
4104317b34 | ||
|
|
401f0da689 | ||
|
|
6efe7960cd | ||
|
|
a6d63f4d0e | ||
|
|
8f3928f4b2 | ||
|
|
3380972df1 | ||
|
|
bad01040e3 | ||
|
|
5ad9943462 | ||
|
|
cf0b9d2c3d |
57
README.md
57
README.md
@@ -50,25 +50,26 @@
|
||||
|
||||
## Updates
|
||||
|
||||
> [!NOTE]
|
||||
September 15, 2024 — Lots of new stuff!
|
||||
> * Fabric now supports calling the new `o1-preview` model using the `-r` switch (which stands for raw. Normal queries won't work with `o1-preview` because they disabled System access and don't allow us to set `Temperature`.
|
||||
> * We have early support for Raycast! Under the `/patterns` directory there's a `raycast` directory with scripts that can be called from Raycast. If you add a scripts directory within Raycast and point it to your `~/.config/fabric/patterns/raycast` directory, you'll then be able to 1) invoke Raycast, type the name of the script, and then 2) paste in the content to be passed, and the results will return in Raycast. There's currently only one script in there but I am (Daniel) adding more.
|
||||
> * **Go Migration: The following command line options were changed during the migration to Go:**
|
||||
> * You now need to use the -c option instead of -C to copy the result to the clipboard.
|
||||
> * You now need to use the -s option instead of -S to stream results in realtime.
|
||||
> * The following command line options have been removed `--agents` (-a), `--gui`, `--clearsession`, `--remoteOllamaServer`, and `--sessionlog`
|
||||
> * You can now use (-S) to configure an Ollama server.
|
||||
> * **We're working on a GUI rewrite in Go as well**
|
||||
> [!NOTE]
|
||||
> September 15, 2024 — Lots of new stuff!
|
||||
>
|
||||
> - Fabric now supports calling the new `o1-preview` model using the `-r` switch (which stands for raw. Normal queries won't work with `o1-preview` because they disabled System access and don't allow us to set `Temperature`.
|
||||
> - We have early support for Raycast! Under the `/patterns` directory there's a `raycast` directory with scripts that can be called from Raycast. If you add a scripts directory within Raycast and point it to your `~/.config/fabric/patterns/raycast` directory, you'll then be able to 1) invoke Raycast, type the name of the script, and then 2) paste in the content to be passed, and the results will return in Raycast. There's currently only one script in there but I am (Daniel) adding more.
|
||||
> - **Go Migration: The following command line options were changed during the migration to Go:**
|
||||
> - You now need to use the -c option instead of -C to copy the result to the clipboard.
|
||||
> - You now need to use the -s option instead of -S to stream results in realtime.
|
||||
> - The following command line options have been removed `--agents` (-a), `--gui`, `--clearsession`, `--remoteOllamaServer`, and `--sessionlog`
|
||||
> - You can now use (-S) to configure an Ollama server.
|
||||
> - **We're working on a GUI rewrite in Go as well**
|
||||
|
||||
## Intro videos
|
||||
|
||||
Keep in mind that many of these were recorded when Fabric was Python-based, so remember to use the current [install instructions](#Installation) below.
|
||||
|
||||
* [Network Chuck](https://www.youtube.com/watch?v=UbDyjIIGaxQ)
|
||||
* [David Bombal](https://www.youtube.com/watch?v=vF-MQmVxnCs)
|
||||
* [My Own Intro to the Tool](https://www.youtube.com/watch?v=wPEyyigh10g)
|
||||
* [More Fabric YouTube Videos](https://www.youtube.com/results?search_query=fabric+ai)
|
||||
- [Network Chuck](https://www.youtube.com/watch?v=UbDyjIIGaxQ)
|
||||
- [David Bombal](https://www.youtube.com/watch?v=vF-MQmVxnCs)
|
||||
- [My Own Intro to the Tool](https://www.youtube.com/watch?v=wPEyyigh10g)
|
||||
- [More Fabric YouTube Videos](https://www.youtube.com/results?search_query=fabric+ai)
|
||||
|
||||
## What and why
|
||||
|
||||
@@ -124,10 +125,10 @@ curl -L https://github.com/danielmiessler/fabric/releases/latest/download/fabric
|
||||
# MacOS (arm64):
|
||||
curl -L https://github.com/danielmiessler/fabric/releases/latest/download/fabric-darwin-arm64 > fabric && chmod +x fabric && ./fabric --version
|
||||
|
||||
# MacOS (amd64):
|
||||
# MacOS (amd64):
|
||||
curl -L https://github.com/danielmiessler/fabric/releases/latest/download/fabric-darwin-amd64 > fabric && chmod +x fabric && ./fabric --version
|
||||
|
||||
# Linux (amd64):
|
||||
# Linux (amd64):
|
||||
curl -L https://github.com/danielmiessler/fabric/releases/latest/download/fabric-linux-amd64 > fabric && chmod +x fabric && ./fabric --version
|
||||
|
||||
# Linux (arm64):
|
||||
@@ -148,6 +149,7 @@ go install github.com/danielmiessler/fabric@latest
|
||||
You may need to set some environment variables in your `~/.bashrc` on linux or `~/.zshrc` file on mac to be able to run the `fabric` command. Here is an example of what you can add:
|
||||
|
||||
For Intel based macs or linux
|
||||
|
||||
```bash
|
||||
# Golang environment variables
|
||||
export GOROOT=/usr/local/go
|
||||
@@ -158,6 +160,7 @@ export PATH=$GOPATH/bin:$GOROOT/bin:$HOME/.local/bin:$PATH
|
||||
```
|
||||
|
||||
for Apple Silicon based macs
|
||||
|
||||
```bash
|
||||
# Golang environment variables
|
||||
export GOROOT=$(brew --prefix go)/libexec
|
||||
@@ -166,13 +169,15 @@ export PATH=$GOPATH/bin:$GOROOT/bin:$HOME/.local/bin:$PATH
|
||||
```
|
||||
|
||||
### Setup
|
||||
|
||||
Now run the following command
|
||||
|
||||
```bash
|
||||
# Run the setup to set up your directories and keys
|
||||
fabric --setup
|
||||
```
|
||||
If everything works you are good to go.
|
||||
|
||||
If everything works you are good to go.
|
||||
|
||||
### Migration
|
||||
|
||||
@@ -195,11 +200,13 @@ Then [set your environmental variables](#environmental-variables) as shown above
|
||||
### Upgrading
|
||||
|
||||
The great thing about Go is that it's super easy to upgrade. Just run the same command you used to install it in the first place and you'll always get the latest version.
|
||||
|
||||
```bash
|
||||
go install -ldflags "-X main.version=$(git describe --tags --always)" github.com/danielmiessler/fabric@latest
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Once you have it all set up, here's how to use it.
|
||||
|
||||
```bash
|
||||
@@ -213,7 +220,7 @@ Usage:
|
||||
|
||||
Application Options:
|
||||
-p, --pattern= Choose a pattern from the available patterns
|
||||
-v, --variable= Values for pattern variables, e.g. -v=$name:John -v=$age:30
|
||||
-v, --variable= Values for pattern variables, e.g. -v=#role:expert -v=#points:30"
|
||||
-C, --context= Choose a context from the available contexts
|
||||
--session= Choose a session from the available sessions
|
||||
-S, --setup Run setup for all reconfigurable parts of fabric
|
||||
@@ -293,7 +300,7 @@ pbpaste | fabric --stream --pattern analyze_claims
|
||||
3. Run the `extract_wisdom` Pattern with the `--stream` option to get immediate and streaming results from any Youtube video (much like in the original introduction video).
|
||||
|
||||
```bash
|
||||
fabric -y "https://youtube.com/watch?v=uXs-zPc63kM" | --stream --pattern extract_wisdom
|
||||
fabric -y "https://youtube.com/watch?v=uXs-zPc63kM" --stream --pattern extract_wisdom
|
||||
```
|
||||
|
||||
4. Create patterns- you must create a .md file with the pattern and save it to ~/.config/fabric/patterns/[yourpatternname].
|
||||
@@ -317,7 +324,7 @@ The wisdom of crowds for the win.
|
||||
|
||||
You may want to use Fabric to create your own custom Patterns—but not share them with others. No problem!
|
||||
|
||||
Just make a directory in `~/.config/custompatterns/` (or wherever) and put your `.md` files in there.
|
||||
Just make a directory in `~/.config/custompatterns/` (or wherever) and put your `.md` files in there.
|
||||
|
||||
When you're ready to use them, copy them into:
|
||||
|
||||
@@ -327,9 +334,16 @@ When you're ready to use them, copy them into:
|
||||
|
||||
You can then use them like any other Patterns, but they won't be public unless you explicitly submit them as Pull Requests to the Fabric project. So don't worry—they're private to you.
|
||||
|
||||
|
||||
This feature works with all openai and ollama models but does NOT work with claude. You can specify your model with the -m flag
|
||||
|
||||
## sessions
|
||||
|
||||
Fabric also allows for persistant sessions. A session is a way to keep track of the context of a conversation. You can create a session with the --session flag and then use that session with the --session flag in subsequent calls. This is useful for keeping track of the context of a conversation.
|
||||
|
||||
```bash
|
||||
pbpaste | fabric --pattern summarize --session mysession
|
||||
```
|
||||
|
||||
## Helper Apps
|
||||
|
||||
Fabric also makes use of some core helper apps (tools) to make it easier to integrate with your various workflows. Here are some examples:
|
||||
@@ -374,6 +388,7 @@ Make sure you have a LaTeX distribution (like TeX Live or MiKTeX) installed on y
|
||||
- _Joseph Thacker_ for the idea of a `-c` context flag that adds pre-created context in the `./config/fabric/` directory to all Pattern queries.
|
||||
- _Jason Haddix_ for the idea of a stitch (chained Pattern) to filter content using a local model before sending on to a cloud model, i.e., cleaning customer data using `llama2` before sending on to `gpt-4` for analysis.
|
||||
- _Andre Guerra_ for assisting with numerous components to make things simpler and more maintainable.
|
||||
- Dave Peters\_ for designing the frontend for FabricUI
|
||||
|
||||
### Primary contributors
|
||||
|
||||
|
||||
36
cli/cli.go
36
cli/cli.go
@@ -2,14 +2,15 @@ package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/danielmiessler/fabric/converter"
|
||||
"github.com/danielmiessler/fabric/db/fs"
|
||||
"github.com/danielmiessler/fabric/plugins/tools/converter"
|
||||
"github.com/danielmiessler/fabric/restapi"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/danielmiessler/fabric/core"
|
||||
"github.com/danielmiessler/fabric/db"
|
||||
)
|
||||
|
||||
// Cli Controls the cli. It takes in the flags and runs the appropriate functions
|
||||
@@ -29,7 +30,7 @@ func Cli(version string) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
fabricDb := db.NewDb(filepath.Join(homedir, ".config/fabric"))
|
||||
fabricDb := fs.NewDb(filepath.Join(homedir, ".config/fabric"))
|
||||
|
||||
// if the setup flag is set, run the setup function
|
||||
if currentFlags.Setup || currentFlags.SetupSkipPatterns || currentFlags.SetupVendor != "" {
|
||||
@@ -55,6 +56,11 @@ func Cli(version string) (err error) {
|
||||
}
|
||||
}
|
||||
|
||||
if currentFlags.Serve {
|
||||
err = restapi.Serve(fabricDb, currentFlags.ServeAddress)
|
||||
return
|
||||
}
|
||||
|
||||
if currentFlags.UpdatePatterns {
|
||||
err = fabric.PopulateDB()
|
||||
return
|
||||
@@ -146,8 +152,12 @@ func Cli(version string) (err error) {
|
||||
if !currentFlags.YouTubeComments || currentFlags.YouTubeTranscript {
|
||||
var transcript string
|
||||
var language = "en"
|
||||
if currentFlags.Language != "" {
|
||||
language = currentFlags.Language
|
||||
if currentFlags.Language != "" || fabric.DefaultLanguage.Value != "" {
|
||||
if currentFlags.Language != "" {
|
||||
language = currentFlags.Language
|
||||
} else {
|
||||
language = fabric.DefaultLanguage.Value
|
||||
}
|
||||
}
|
||||
if transcript, err = fabric.YouTube.GrabTranscript(videoId, language); err != nil {
|
||||
return
|
||||
@@ -207,8 +217,12 @@ func Cli(version string) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
var session *db.Session
|
||||
if session, err = chatter.Send(currentFlags.BuildChatRequest(strings.Join(os.Args[1:], " ")), currentFlags.BuildChatOptions()); err != nil {
|
||||
var session *fs.Session
|
||||
chatReq := currentFlags.BuildChatRequest(strings.Join(os.Args[1:], " "))
|
||||
if chatReq.Language == "" {
|
||||
chatReq.Language = fabric.DefaultLanguage.Value
|
||||
}
|
||||
if session, err = chatter.Send(chatReq, currentFlags.BuildChatOptions()); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -238,7 +252,7 @@ func Cli(version string) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func Setup(db *db.Db, skipUpdatePatterns bool) (ret *core.Fabric, err error) {
|
||||
func Setup(db *fs.Db, skipUpdatePatterns bool) (ret *core.Fabric, err error) {
|
||||
instance := core.NewFabricForSetup(db)
|
||||
|
||||
if err = instance.Setup(); err != nil {
|
||||
@@ -254,10 +268,8 @@ func Setup(db *db.Db, skipUpdatePatterns bool) (ret *core.Fabric, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func SetupVendor(db *db.Db, vendorName string) (ret *core.Fabric, err error) {
|
||||
func SetupVendor(db *fs.Db, vendorName string) (ret *core.Fabric, err error) {
|
||||
ret = core.NewFabricForSetup(db)
|
||||
if err = ret.SetupVendor(vendorName); err != nil {
|
||||
return
|
||||
}
|
||||
err = ret.SetupVendor(vendorName)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -2,10 +2,10 @@ package cli
|
||||
|
||||
import (
|
||||
"github.com/danielmiessler/fabric/core"
|
||||
"github.com/danielmiessler/fabric/db/fs"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/danielmiessler/fabric/db"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@@ -21,7 +21,7 @@ func TestCli(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSetup(t *testing.T) {
|
||||
mockDB := db.NewDb(os.TempDir())
|
||||
mockDB := fs.NewDb(os.TempDir())
|
||||
|
||||
fabric, err := Setup(mockDB, false)
|
||||
assert.Error(t, err)
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
// Flags create flags struct. the users flags go into this, this will be passed to the chat struct in cli
|
||||
type Flags struct {
|
||||
Pattern string `short:"p" long:"pattern" description:"Choose a pattern from the available patterns" default:""`
|
||||
PatternVariables map[string]string `short:"v" long:"variable" description:"Values for pattern variables, e.g. -v=$name:John -v=$age:30"`
|
||||
PatternVariables map[string]string `short:"v" long:"variable" description:"Values for pattern variables, e.g. -v=#role:expert -v=#points:30"`
|
||||
Context string `short:"C" long:"context" description:"Choose a context from the available contexts" default:""`
|
||||
Session string `long:"session" description:"Choose a session from the available sessions"`
|
||||
Setup bool `short:"S" long:"setup" description:"Run setup for all reconfigurable parts of fabric"`
|
||||
@@ -52,6 +52,8 @@ type Flags struct {
|
||||
PrintSession string `long:"printsession" description:"Print session"`
|
||||
HtmlReadability bool `long:"readability" description:"Convert HTML input into a clean, readable view"`
|
||||
DryRun bool `long:"dry-run" description:"Show what would be sent to the model without actually sending it"`
|
||||
Serve bool `long:"serve" description:"Serve the Fabric Rest API"`
|
||||
ServeAddress string `long:"address" description:"The address to bind the REST API" default:":8080"`
|
||||
Version bool `long:"version" description:"Print current version"`
|
||||
}
|
||||
|
||||
@@ -141,6 +143,6 @@ func (o *Flags) AppendMessage(message string) {
|
||||
}
|
||||
|
||||
func (o *Flags) IsChatRequest() (ret bool) {
|
||||
ret = o.Message != "" || o.Session != ""
|
||||
ret = (o.Message != "" || o.Context != "") && (o.Session != "" || o.Pattern != "")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -4,23 +4,23 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/danielmiessler/fabric/common"
|
||||
"github.com/danielmiessler/fabric/db"
|
||||
"github.com/danielmiessler/fabric/vendors"
|
||||
"github.com/danielmiessler/fabric/db/fs"
|
||||
"github.com/danielmiessler/fabric/plugins/ai"
|
||||
goopenai "github.com/sashabaranov/go-openai"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Chatter struct {
|
||||
db *db.Db
|
||||
db *fs.Db
|
||||
|
||||
Stream bool
|
||||
DryRun bool
|
||||
|
||||
model string
|
||||
vendor vendors.Vendor
|
||||
vendor ai.Vendor
|
||||
}
|
||||
|
||||
func (o *Chatter) Send(request *common.ChatRequest, opts *common.ChatOptions) (session *db.Session, err error) {
|
||||
func (o *Chatter) Send(request *common.ChatRequest, opts *common.ChatOptions) (session *fs.Session, err error) {
|
||||
if session, err = o.BuildSession(request, opts.Raw); err != nil {
|
||||
return
|
||||
}
|
||||
@@ -52,6 +52,7 @@ func (o *Chatter) Send(request *common.ChatRequest, opts *common.ChatOptions) (s
|
||||
if message == "" {
|
||||
session = nil
|
||||
err = fmt.Errorf("empty response")
|
||||
return
|
||||
}
|
||||
|
||||
session.Append(&common.Message{Role: goopenai.ChatMessageRoleAssistant, Content: message})
|
||||
@@ -62,16 +63,16 @@ func (o *Chatter) Send(request *common.ChatRequest, opts *common.ChatOptions) (s
|
||||
return
|
||||
}
|
||||
|
||||
func (o *Chatter) BuildSession(request *common.ChatRequest, raw bool) (session *db.Session, err error) {
|
||||
func (o *Chatter) BuildSession(request *common.ChatRequest, raw bool) (session *fs.Session, err error) {
|
||||
if request.SessionName != "" {
|
||||
var sess *db.Session
|
||||
if sess, err = o.db.Sessions.GetOrCreateSession(request.SessionName); err != nil {
|
||||
var sess *fs.Session
|
||||
if sess, err = o.db.Sessions.Get(request.SessionName); err != nil {
|
||||
err = fmt.Errorf("could not find session %s: %v", request.SessionName, err)
|
||||
return
|
||||
}
|
||||
session = sess
|
||||
} else {
|
||||
session = &db.Session{}
|
||||
session = &fs.Session{}
|
||||
}
|
||||
|
||||
if request.Meta != "" {
|
||||
@@ -80,8 +81,8 @@ func (o *Chatter) BuildSession(request *common.ChatRequest, raw bool) (session *
|
||||
|
||||
var contextContent string
|
||||
if request.ContextName != "" {
|
||||
var ctx *db.Context
|
||||
if ctx, err = o.db.Contexts.GetContext(request.ContextName); err != nil {
|
||||
var ctx *fs.Context
|
||||
if ctx, err = o.db.Contexts.Get(request.ContextName); err != nil {
|
||||
err = fmt.Errorf("could not find context %s: %v", request.ContextName, err)
|
||||
return
|
||||
}
|
||||
@@ -90,8 +91,8 @@ func (o *Chatter) BuildSession(request *common.ChatRequest, raw bool) (session *
|
||||
|
||||
var patternContent string
|
||||
if request.PatternName != "" {
|
||||
var pattern *db.Pattern
|
||||
if pattern, err = o.db.Patterns.GetPattern(request.PatternName, request.PatternVariables); err != nil {
|
||||
var pattern *fs.Pattern
|
||||
if pattern, err = o.db.Patterns.GetApplyVariables(request.PatternName, request.PatternVariables); err != nil {
|
||||
err = fmt.Errorf("could not find pattern %s: %v", request.PatternName, err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -3,24 +3,26 @@ package core
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/atotto/clipboard"
|
||||
"github.com/danielmiessler/fabric/common"
|
||||
"github.com/danielmiessler/fabric/db"
|
||||
"github.com/danielmiessler/fabric/jina"
|
||||
"github.com/danielmiessler/fabric/vendors/anthropic"
|
||||
"github.com/danielmiessler/fabric/vendors/azure"
|
||||
"github.com/danielmiessler/fabric/vendors/dryrun"
|
||||
"github.com/danielmiessler/fabric/vendors/gemini"
|
||||
"github.com/danielmiessler/fabric/vendors/groq"
|
||||
"github.com/danielmiessler/fabric/vendors/mistral"
|
||||
"github.com/danielmiessler/fabric/vendors/ollama"
|
||||
"github.com/danielmiessler/fabric/vendors/openai"
|
||||
"github.com/danielmiessler/fabric/vendors/openrouter"
|
||||
"github.com/danielmiessler/fabric/vendors/siliconcloud"
|
||||
"github.com/danielmiessler/fabric/youtube"
|
||||
"github.com/pkg/errors"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"github.com/atotto/clipboard"
|
||||
"github.com/danielmiessler/fabric/common"
|
||||
"github.com/danielmiessler/fabric/db/fs"
|
||||
"github.com/danielmiessler/fabric/plugins/ai/anthropic"
|
||||
"github.com/danielmiessler/fabric/plugins/ai/azure"
|
||||
"github.com/danielmiessler/fabric/plugins/ai/dryrun"
|
||||
"github.com/danielmiessler/fabric/plugins/ai/gemini"
|
||||
"github.com/danielmiessler/fabric/plugins/ai/groq"
|
||||
"github.com/danielmiessler/fabric/plugins/ai/mistral"
|
||||
"github.com/danielmiessler/fabric/plugins/ai/ollama"
|
||||
"github.com/danielmiessler/fabric/plugins/ai/openai"
|
||||
"github.com/danielmiessler/fabric/plugins/ai/openrouter"
|
||||
"github.com/danielmiessler/fabric/plugins/ai/siliconcloud"
|
||||
"github.com/danielmiessler/fabric/plugins/tools/jina"
|
||||
"github.com/danielmiessler/fabric/plugins/tools/lang"
|
||||
"github.com/danielmiessler/fabric/plugins/tools/youtube"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const DefaultPatternsGitRepoUrl = "https://github.com/danielmiessler/fabric.git"
|
||||
@@ -28,20 +30,20 @@ const DefaultPatternsGitRepoFolder = "patterns"
|
||||
|
||||
const NoSessionPatternUserMessages = "no session, pattern or user messages provided"
|
||||
|
||||
func NewFabric(db *db.Db) (ret *Fabric, err error) {
|
||||
func NewFabric(db *fs.Db) (ret *Fabric, err error) {
|
||||
ret = NewFabricBase(db)
|
||||
err = ret.Configure()
|
||||
return
|
||||
}
|
||||
|
||||
func NewFabricForSetup(db *db.Db) (ret *Fabric) {
|
||||
func NewFabricForSetup(db *fs.Db) (ret *Fabric) {
|
||||
ret = NewFabricBase(db)
|
||||
_ = ret.Configure()
|
||||
return
|
||||
}
|
||||
|
||||
// NewFabricBase Create a new Fabric from a list of already configured VendorsController
|
||||
func NewFabricBase(db *db.Db) (ret *Fabric) {
|
||||
func NewFabricBase(db *fs.Db) (ret *Fabric) {
|
||||
|
||||
ret = &Fabric{
|
||||
VendorsManager: NewVendorsManager(),
|
||||
@@ -49,6 +51,7 @@ func NewFabricBase(db *db.Db) (ret *Fabric) {
|
||||
VendorsAll: NewVendorsManager(),
|
||||
PatternsLoader: NewPatternsLoader(db.Patterns),
|
||||
YouTube: youtube.NewYouTube(),
|
||||
Language: lang.NewLanguage(),
|
||||
Jina: jina.NewClient(),
|
||||
}
|
||||
|
||||
@@ -64,7 +67,7 @@ func NewFabricBase(db *db.Db) (ret *Fabric) {
|
||||
"Enter the index the name of your default model")
|
||||
|
||||
ret.VendorsAll.AddVendors(openai.NewClient(), azure.NewClient(), ollama.NewClient(), groq.NewClient(),
|
||||
gemini.NewClient(), anthropic.NewClient(), siliconcloud.NewClient(), openrouter.NewClient(), mistral.NewClient(), dryrun.NewClient())
|
||||
gemini.NewClient(), anthropic.NewClient(), siliconcloud.NewClient(), openrouter.NewClient(), mistral.NewClient())
|
||||
|
||||
return
|
||||
}
|
||||
@@ -75,9 +78,10 @@ type Fabric struct {
|
||||
VendorsAll *VendorsManager
|
||||
*PatternsLoader
|
||||
*youtube.YouTube
|
||||
*lang.Language
|
||||
Jina *jina.Client
|
||||
|
||||
Db *db.Db
|
||||
Db *fs.Db
|
||||
|
||||
DefaultVendor *common.Setting
|
||||
DefaultModel *common.SetupQuestion
|
||||
@@ -101,6 +105,7 @@ func (o *Fabric) SaveEnvFile() (err error) {
|
||||
|
||||
o.YouTube.SetupFillEnvFileContent(&envFileContent)
|
||||
o.Jina.SetupFillEnvFileContent(&envFileContent)
|
||||
o.Language.SetupFillEnvFileContent(&envFileContent)
|
||||
|
||||
err = o.Db.SaveEnv(envFileContent.String())
|
||||
return
|
||||
@@ -125,6 +130,10 @@ func (o *Fabric) Setup() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
if err = o.Language.SetupOrSkip(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = o.SaveEnvFile()
|
||||
|
||||
return
|
||||
@@ -179,7 +188,7 @@ func (o *Fabric) SetupVendors() (err error) {
|
||||
}
|
||||
|
||||
func (o *Fabric) SetupVendor(vendorName string) (err error) {
|
||||
if err = o.VendorsAll.SetupVendor(vendorName); err != nil {
|
||||
if err = o.VendorsAll.SetupVendor(vendorName, o.Vendors); err != nil {
|
||||
return
|
||||
}
|
||||
err = o.SaveEnvFile()
|
||||
@@ -200,6 +209,7 @@ func (o *Fabric) configure() (err error) {
|
||||
//YouTube and Jina are not mandatory, so ignore not configured error
|
||||
_ = o.YouTube.Configure()
|
||||
_ = o.Jina.Configure()
|
||||
_ = o.Language.Configure()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1,21 +1,20 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"github.com/danielmiessler/fabric/db/fs"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/danielmiessler/fabric/db"
|
||||
)
|
||||
|
||||
func TestNewFabric(t *testing.T) {
|
||||
_, err := NewFabric(db.NewDb(os.TempDir()))
|
||||
_, err := NewFabric(fs.NewDb(os.TempDir()))
|
||||
if err == nil {
|
||||
t.Fatal("without setup error expected")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSaveEnvFile(t *testing.T) {
|
||||
fabric := NewFabricBase(db.NewDb(os.TempDir()))
|
||||
fabric := NewFabricBase(fs.NewDb(os.TempDir()))
|
||||
|
||||
err := fabric.SaveEnvFile()
|
||||
if err != nil {
|
||||
@@ -25,7 +24,7 @@ func TestSaveEnvFile(t *testing.T) {
|
||||
|
||||
func TestCopyToClipboard(t *testing.T) {
|
||||
t.Skip("skipping test, because of docker env. in ci.")
|
||||
fabric := NewFabricBase(db.NewDb(os.TempDir()))
|
||||
fabric := NewFabricBase(fs.NewDb(os.TempDir()))
|
||||
|
||||
message := "test message"
|
||||
err := fabric.CopyToClipboard(message)
|
||||
@@ -35,7 +34,7 @@ func TestCopyToClipboard(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCreateOutputFile(t *testing.T) {
|
||||
mockDb := &db.Db{}
|
||||
mockDb := &fs.Db{}
|
||||
fabric := NewFabricBase(mockDb)
|
||||
|
||||
fileName := "test_output.txt"
|
||||
|
||||
@@ -2,6 +2,7 @@ package core
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/danielmiessler/fabric/db/fs"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -9,7 +10,6 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/danielmiessler/fabric/common"
|
||||
"github.com/danielmiessler/fabric/db"
|
||||
"github.com/go-git/go-git/v5"
|
||||
"github.com/go-git/go-git/v5/plumbing"
|
||||
"github.com/go-git/go-git/v5/plumbing/object"
|
||||
@@ -17,7 +17,7 @@ import (
|
||||
"github.com/otiai10/copy"
|
||||
)
|
||||
|
||||
func NewPatternsLoader(patterns *db.Patterns) (ret *PatternsLoader) {
|
||||
func NewPatternsLoader(patterns *fs.PatternsEntity) (ret *PatternsLoader) {
|
||||
label := "Patterns Loader"
|
||||
ret = &PatternsLoader{
|
||||
Patterns: patterns,
|
||||
@@ -42,7 +42,7 @@ func NewPatternsLoader(patterns *db.Patterns) (ret *PatternsLoader) {
|
||||
|
||||
type PatternsLoader struct {
|
||||
*common.Configurable
|
||||
Patterns *db.Patterns
|
||||
Patterns *fs.PatternsEntity
|
||||
|
||||
DefaultGitRepoUrl *common.SetupQuestion
|
||||
DefaultFolder *common.SetupQuestion
|
||||
@@ -90,7 +90,7 @@ func (o *PatternsLoader) PersistPatterns() (err error) {
|
||||
if currentPattern.Name() == newPattern.Name() {
|
||||
break
|
||||
}
|
||||
copy.Copy(filepath.Join(o.Patterns.Dir, newPattern.Name()), filepath.Join(newPatternsFolder, newPattern.Name()))
|
||||
err = copy.Copy(filepath.Join(o.Patterns.Dir, newPattern.Name()), filepath.Join(newPatternsFolder, newPattern.Name()))
|
||||
}
|
||||
}
|
||||
return
|
||||
@@ -98,14 +98,18 @@ func (o *PatternsLoader) PersistPatterns() (err error) {
|
||||
|
||||
// movePatterns copies the new patterns into the config directory
|
||||
func (o *PatternsLoader) movePatterns() (err error) {
|
||||
os.MkdirAll(o.Patterns.Dir, os.ModePerm)
|
||||
if err = os.MkdirAll(o.Patterns.Dir, os.ModePerm); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
patternsDir := o.tempPatternsFolder
|
||||
if err = o.PersistPatterns(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
copy.Copy(patternsDir, o.Patterns.Dir) // copies the patterns to the config directory
|
||||
if err = copy.Copy(patternsDir, o.Patterns.Dir); err != nil { // copies the patterns to the config directory
|
||||
return
|
||||
}
|
||||
err = os.RemoveAll(patternsDir)
|
||||
return
|
||||
}
|
||||
@@ -152,10 +156,10 @@ func (o *PatternsLoader) gitCloneAndCopy() (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
var changes []db.DirectoryChange
|
||||
var changes []fs.DirectoryChange
|
||||
// ... iterates over the commits
|
||||
if err = cIter.ForEach(func(c *object.Commit) (err error) {
|
||||
// Get the files changed in this commit by comparing with its parents
|
||||
// GetApplyVariables the files changed in this commit by comparing with its parents
|
||||
parentIter := c.Parents()
|
||||
if err = parentIter.ForEach(func(parent *object.Commit) (err error) {
|
||||
var patch *object.Patch
|
||||
@@ -167,7 +171,7 @@ func (o *PatternsLoader) gitCloneAndCopy() (err error) {
|
||||
for _, fileStat := range patch.Stats() {
|
||||
if strings.HasPrefix(fileStat.Name, o.pathPatternsPrefix) {
|
||||
dir := filepath.Dir(fileStat.Name)
|
||||
changes = append(changes, db.DirectoryChange{Dir: dir, Timestamp: c.Committer.When})
|
||||
changes = append(changes, fs.DirectoryChange{Dir: dir, Timestamp: c.Committer.When})
|
||||
}
|
||||
}
|
||||
return
|
||||
@@ -186,7 +190,9 @@ func (o *PatternsLoader) gitCloneAndCopy() (err error) {
|
||||
return changes[i].Timestamp.Before(changes[j].Timestamp)
|
||||
})
|
||||
|
||||
o.makeUniqueList(changes)
|
||||
if err = o.makeUniqueList(changes); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var commit *object.Commit
|
||||
if commit, err = r.CommitObject(ref.Hash()); err != nil {
|
||||
@@ -250,7 +256,7 @@ func (o *PatternsLoader) writeBlobToFile(blob *object.Blob, path string) (err er
|
||||
return
|
||||
}
|
||||
|
||||
func (o *PatternsLoader) makeUniqueList(changes []db.DirectoryChange) {
|
||||
func (o *PatternsLoader) makeUniqueList(changes []fs.DirectoryChange) (err error) {
|
||||
uniqueItems := make(map[string]bool)
|
||||
for _, change := range changes {
|
||||
if strings.TrimSpace(change.Dir) != "" && !strings.Contains(change.Dir, "=>") {
|
||||
@@ -271,5 +277,6 @@ func (o *PatternsLoader) makeUniqueList(changes []db.DirectoryChange) {
|
||||
}
|
||||
|
||||
joined := strings.Join(finalList, "\n")
|
||||
os.WriteFile(o.Patterns.UniquePatternsFilePath, []byte(joined), 0o644)
|
||||
err = os.WriteFile(o.Patterns.UniquePatternsFilePath, []byte(joined), 0o644)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -3,23 +3,22 @@ package core
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/danielmiessler/fabric/plugins/ai"
|
||||
"sync"
|
||||
|
||||
"github.com/danielmiessler/fabric/vendors"
|
||||
)
|
||||
|
||||
func NewVendorsManager() *VendorsManager {
|
||||
return &VendorsManager{
|
||||
Vendors: map[string]vendors.Vendor{},
|
||||
Vendors: map[string]ai.Vendor{},
|
||||
}
|
||||
}
|
||||
|
||||
type VendorsManager struct {
|
||||
Vendors map[string]vendors.Vendor
|
||||
Vendors map[string]ai.Vendor
|
||||
Models *VendorsModels
|
||||
}
|
||||
|
||||
func (o *VendorsManager) AddVendors(vendors ...vendors.Vendor) {
|
||||
func (o *VendorsManager) AddVendors(vendors ...ai.Vendor) {
|
||||
for _, vendor := range vendors {
|
||||
o.Vendors[vendor.GetName()] = vendor
|
||||
}
|
||||
@@ -36,7 +35,7 @@ func (o *VendorsManager) HasVendors() bool {
|
||||
return len(o.Vendors) > 0
|
||||
}
|
||||
|
||||
func (o *VendorsManager) FindByName(name string) vendors.Vendor {
|
||||
func (o *VendorsManager) FindByName(name string) ai.Vendor {
|
||||
return o.Vendors[name]
|
||||
}
|
||||
|
||||
@@ -72,7 +71,7 @@ func (o *VendorsManager) readModels() {
|
||||
}
|
||||
|
||||
func (o *VendorsManager) fetchVendorModels(
|
||||
ctx context.Context, wg *sync.WaitGroup, vendor vendors.Vendor, resultsChan chan<- modelResult) {
|
||||
ctx context.Context, wg *sync.WaitGroup, vendor ai.Vendor, resultsChan chan<- modelResult) {
|
||||
|
||||
defer wg.Done()
|
||||
|
||||
@@ -86,30 +85,33 @@ func (o *VendorsManager) fetchVendorModels(
|
||||
}
|
||||
}
|
||||
|
||||
func (o *VendorsManager) Setup() (ret map[string]vendors.Vendor, err error) {
|
||||
ret = map[string]vendors.Vendor{}
|
||||
func (o *VendorsManager) Setup() (ret map[string]ai.Vendor, err error) {
|
||||
ret = map[string]ai.Vendor{}
|
||||
for _, vendor := range o.Vendors {
|
||||
fmt.Println()
|
||||
if vendorErr := vendor.Setup(); vendorErr == nil {
|
||||
fmt.Printf("[%v] configured\n", vendor.GetName())
|
||||
ret[vendor.GetName()] = vendor
|
||||
} else {
|
||||
fmt.Printf("[%v] skipped\n", vendor.GetName())
|
||||
}
|
||||
o.setupVendorTo(vendor, ret)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (o *VendorsManager) SetupVendor(vendorName string) (err error) {
|
||||
func (o *VendorsManager) setupVendorTo(vendor ai.Vendor, configuredVendors map[string]ai.Vendor) {
|
||||
if vendorErr := vendor.Setup(); vendorErr == nil {
|
||||
fmt.Printf("[%v] configured\n", vendor.GetName())
|
||||
configuredVendors[vendor.GetName()] = vendor
|
||||
} else {
|
||||
delete(configuredVendors, vendor.GetName())
|
||||
fmt.Printf("[%v] skipped\n", vendor.GetName())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (o *VendorsManager) SetupVendor(vendorName string, configuredVendors map[string]ai.Vendor) (err error) {
|
||||
vendor := o.FindByName(vendorName)
|
||||
if vendor == nil {
|
||||
err = fmt.Errorf("vendor %s not found", vendorName)
|
||||
return
|
||||
}
|
||||
err = vendor.Setup()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
o.setupVendorTo(vendor, configuredVendors)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
13
db/api.go
Normal file
13
db/api.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package db
|
||||
|
||||
type Storage[T any] interface {
|
||||
Configure() (err error)
|
||||
Get(name string) (ret *T, err error)
|
||||
GetNames() (ret []string, err error)
|
||||
Delete(name string) (err error)
|
||||
Exists(name string) (ret bool)
|
||||
Rename(oldName, newName string) (err error)
|
||||
Save(name string, content []byte) (err error)
|
||||
Load(name string) (ret []byte, err error)
|
||||
ListNames() (err error)
|
||||
}
|
||||
@@ -1,13 +1,13 @@
|
||||
package db
|
||||
package fs
|
||||
|
||||
import "fmt"
|
||||
|
||||
type Contexts struct {
|
||||
*Storage
|
||||
type ContextsEntity struct {
|
||||
*StorageEntity
|
||||
}
|
||||
|
||||
// GetContext Load a context from file
|
||||
func (o *Contexts) GetContext(name string) (ret *Context, err error) {
|
||||
// Get Load a context from file
|
||||
func (o *ContextsEntity) Get(name string) (ret *Context, err error) {
|
||||
var content []byte
|
||||
if content, err = o.Load(name); err != nil {
|
||||
return
|
||||
@@ -17,9 +17,9 @@ func (o *Contexts) GetContext(name string) (ret *Context, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (o *Contexts) PrintContext(name string) (err error) {
|
||||
func (o *ContextsEntity) PrintContext(name string) (err error) {
|
||||
var context *Context
|
||||
if context, err = o.GetContext(name); err != nil {
|
||||
if context, err = o.Get(name); err != nil {
|
||||
return
|
||||
}
|
||||
fmt.Println(context.Content)
|
||||
@@ -1,4 +1,4 @@
|
||||
package db
|
||||
package fs
|
||||
|
||||
import (
|
||||
"os"
|
||||
@@ -8,8 +8,8 @@ import (
|
||||
|
||||
func TestContexts_GetContext(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
contexts := &Contexts{
|
||||
Storage: &Storage{Dir: dir},
|
||||
contexts := &ContextsEntity{
|
||||
StorageEntity: &StorageEntity{Dir: dir},
|
||||
}
|
||||
contextName := "testContext"
|
||||
contextPath := filepath.Join(dir, contextName)
|
||||
@@ -18,7 +18,7 @@ func TestContexts_GetContext(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("failed to write context file: %v", err)
|
||||
}
|
||||
context, err := contexts.GetContext(contextName)
|
||||
context, err := contexts.Get(contextName)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to get context: %v", err)
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package db
|
||||
package fs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -14,17 +14,17 @@ func NewDb(dir string) (db *Db) {
|
||||
|
||||
db.EnvFilePath = db.FilePath(".env")
|
||||
|
||||
db.Patterns = &Patterns{
|
||||
Storage: &Storage{Label: "Patterns", Dir: db.FilePath("patterns"), ItemIsDir: true},
|
||||
db.Patterns = &PatternsEntity{
|
||||
StorageEntity: &StorageEntity{Label: "Patterns", Dir: db.FilePath("patterns"), ItemIsDir: true},
|
||||
SystemPatternFile: "system.md",
|
||||
UniquePatternsFilePath: db.FilePath("unique_patterns.txt"),
|
||||
}
|
||||
|
||||
db.Sessions = &Sessions{
|
||||
&Storage{Label: "Sessions", Dir: db.FilePath("sessions"), FileExtension: ".json"}}
|
||||
db.Sessions = &SessionsEntity{
|
||||
&StorageEntity{Label: "Sessions", Dir: db.FilePath("sessions"), FileExtension: ".json"}}
|
||||
|
||||
db.Contexts = &Contexts{
|
||||
&Storage{Label: "Contexts", Dir: db.FilePath("contexts")}}
|
||||
db.Contexts = &ContextsEntity{
|
||||
&StorageEntity{Label: "Contexts", Dir: db.FilePath("contexts")}}
|
||||
|
||||
return
|
||||
}
|
||||
@@ -32,9 +32,9 @@ func NewDb(dir string) (db *Db) {
|
||||
type Db struct {
|
||||
Dir string
|
||||
|
||||
Patterns *Patterns
|
||||
Sessions *Sessions
|
||||
Contexts *Contexts
|
||||
Patterns *PatternsEntity
|
||||
Sessions *SessionsEntity
|
||||
Contexts *ContextsEntity
|
||||
|
||||
EnvFilePath string
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package db
|
||||
package fs
|
||||
|
||||
import (
|
||||
"os"
|
||||
@@ -1,4 +1,4 @@
|
||||
package db
|
||||
package fs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -7,14 +7,13 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Patterns struct {
|
||||
*Storage
|
||||
type PatternsEntity struct {
|
||||
*StorageEntity
|
||||
SystemPatternFile string
|
||||
UniquePatternsFilePath string
|
||||
}
|
||||
|
||||
// GetPattern finds a pattern by name and returns the pattern as an entry or an error
|
||||
func (o *Patterns) GetPattern(name string, variables map[string]string) (ret *Pattern, err error) {
|
||||
func (o *PatternsEntity) Get(name string) (ret *Pattern, err error) {
|
||||
patternPath := filepath.Join(o.Dir, name, o.SystemPatternFile)
|
||||
|
||||
var pattern []byte
|
||||
@@ -23,13 +22,6 @@ func (o *Patterns) GetPattern(name string, variables map[string]string) (ret *Pa
|
||||
}
|
||||
|
||||
patternStr := string(pattern)
|
||||
|
||||
if variables != nil && len(variables) > 0 {
|
||||
for variableName, value := range variables {
|
||||
patternStr = strings.ReplaceAll(patternStr, variableName, value)
|
||||
}
|
||||
}
|
||||
|
||||
ret = &Pattern{
|
||||
Name: name,
|
||||
Pattern: patternStr,
|
||||
@@ -37,7 +29,22 @@ func (o *Patterns) GetPattern(name string, variables map[string]string) (ret *Pa
|
||||
return
|
||||
}
|
||||
|
||||
func (o *Patterns) PrintLatestPatterns(latestNumber int) (err error) {
|
||||
// GetApplyVariables finds a pattern by name and returns the pattern as an entry or an error
|
||||
func (o *PatternsEntity) GetApplyVariables(name string, variables map[string]string) (ret *Pattern, err error) {
|
||||
|
||||
if ret, err = o.Get(name); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if variables != nil && len(variables) > 0 {
|
||||
for variableName, value := range variables {
|
||||
ret.Pattern = strings.ReplaceAll(ret.Pattern, variableName, value)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (o *PatternsEntity) PrintLatestPatterns(latestNumber int) (err error) {
|
||||
var contents []byte
|
||||
if contents, err = os.ReadFile(o.UniquePatternsFilePath); err != nil {
|
||||
err = fmt.Errorf("could not read unique patterns file. Pleas run --updatepatterns (%s)", err)
|
||||
1
db/fs/patterns_test.go
Normal file
1
db/fs/patterns_test.go
Normal file
@@ -0,0 +1 @@
|
||||
package fs
|
||||
@@ -1,15 +1,15 @@
|
||||
package db
|
||||
package fs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/danielmiessler/fabric/common"
|
||||
)
|
||||
|
||||
type Sessions struct {
|
||||
*Storage
|
||||
type SessionsEntity struct {
|
||||
*StorageEntity
|
||||
}
|
||||
|
||||
func (o *Sessions) GetOrCreateSession(name string) (session *Session, err error) {
|
||||
func (o *SessionsEntity) Get(name string) (session *Session, err error) {
|
||||
session = &Session{Name: name}
|
||||
|
||||
if o.Exists(name) {
|
||||
@@ -20,7 +20,7 @@ func (o *Sessions) GetOrCreateSession(name string) (session *Session, err error)
|
||||
return
|
||||
}
|
||||
|
||||
func (o *Sessions) PrintSession(name string) (err error) {
|
||||
func (o *SessionsEntity) PrintSession(name string) (err error) {
|
||||
if o.Exists(name) {
|
||||
var session Session
|
||||
if err = o.LoadAsJson(name, &session.Messages); err == nil {
|
||||
@@ -30,7 +30,7 @@ func (o *Sessions) PrintSession(name string) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (o *Sessions) SaveSession(session *Session) (err error) {
|
||||
func (o *SessionsEntity) SaveSession(session *Session) (err error) {
|
||||
return o.SaveAsJson(session.Name, session.Messages)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package db
|
||||
package fs
|
||||
|
||||
import (
|
||||
"testing"
|
||||
@@ -8,11 +8,11 @@ import (
|
||||
|
||||
func TestSessions_GetOrCreateSession(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
sessions := &Sessions{
|
||||
Storage: &Storage{Dir: dir, FileExtension: ".json"},
|
||||
sessions := &SessionsEntity{
|
||||
StorageEntity: &StorageEntity{Dir: dir, FileExtension: ".json"},
|
||||
}
|
||||
sessionName := "testSession"
|
||||
session, err := sessions.GetOrCreateSession(sessionName)
|
||||
session, err := sessions.Get(sessionName)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to get or create session: %v", err)
|
||||
}
|
||||
@@ -23,8 +23,8 @@ func TestSessions_GetOrCreateSession(t *testing.T) {
|
||||
|
||||
func TestSessions_SaveSession(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
sessions := &Sessions{
|
||||
Storage: &Storage{Dir: dir, FileExtension: ".json"},
|
||||
sessions := &SessionsEntity{
|
||||
StorageEntity: &StorageEntity{Dir: dir, FileExtension: ".json"},
|
||||
}
|
||||
sessionName := "testSession"
|
||||
session := &Session{Name: sessionName, Messages: []*common.Message{{Content: "message1"}}}
|
||||
@@ -1,4 +1,4 @@
|
||||
package db
|
||||
package fs
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
@@ -10,14 +10,14 @@ import (
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
type Storage struct {
|
||||
type StorageEntity struct {
|
||||
Label string
|
||||
Dir string
|
||||
ItemIsDir bool
|
||||
FileExtension string
|
||||
}
|
||||
|
||||
func (o *Storage) Configure() (err error) {
|
||||
func (o *StorageEntity) Configure() (err error) {
|
||||
if err = os.MkdirAll(o.Dir, os.ModePerm); err != nil {
|
||||
return
|
||||
}
|
||||
@@ -25,7 +25,7 @@ func (o *Storage) Configure() (err error) {
|
||||
}
|
||||
|
||||
// GetNames finds all patterns in the patterns directory and enters the id, name, and pattern into a slice of Entry structs. it returns these entries or an error
|
||||
func (o *Storage) GetNames() (ret []string, err error) {
|
||||
func (o *StorageEntity) GetNames() (ret []string, err error) {
|
||||
var entries []os.DirEntry
|
||||
if entries, err = os.ReadDir(o.Dir); err != nil {
|
||||
err = fmt.Errorf("could not read items from directory: %v", err)
|
||||
@@ -59,7 +59,41 @@ func (o *Storage) GetNames() (ret []string, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (o *Storage) ListNames() (err error) {
|
||||
func (o *StorageEntity) Delete(name string) (err error) {
|
||||
if err = os.Remove(o.BuildFilePathByName(name)); err != nil {
|
||||
err = fmt.Errorf("could not delete %s: %v", name, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (o *StorageEntity) Exists(name string) (ret bool) {
|
||||
_, err := os.Stat(o.BuildFilePathByName(name))
|
||||
ret = !os.IsNotExist(err)
|
||||
return
|
||||
}
|
||||
|
||||
func (o *StorageEntity) Rename(oldName, newName string) (err error) {
|
||||
if err = os.Rename(o.BuildFilePathByName(oldName), o.BuildFilePathByName(newName)); err != nil {
|
||||
err = fmt.Errorf("could not rename %s to %s: %v", oldName, newName, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (o *StorageEntity) Save(name string, content []byte) (err error) {
|
||||
if err = os.WriteFile(o.BuildFilePathByName(name), content, 0644); err != nil {
|
||||
err = fmt.Errorf("could not save %s: %v", name, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (o *StorageEntity) Load(name string) (ret []byte, err error) {
|
||||
if ret, err = os.ReadFile(o.BuildFilePathByName(name)); err != nil {
|
||||
err = fmt.Errorf("could not load %s: %v", name, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (o *StorageEntity) ListNames() (err error) {
|
||||
var names []string
|
||||
if names, err = o.GetNames(); err != nil {
|
||||
return
|
||||
@@ -76,55 +110,21 @@ func (o *Storage) ListNames() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (o *Storage) BuildFilePathByName(name string) (ret string) {
|
||||
func (o *StorageEntity) BuildFilePathByName(name string) (ret string) {
|
||||
ret = o.BuildFilePath(o.buildFileName(name))
|
||||
return
|
||||
}
|
||||
|
||||
func (o *Storage) BuildFilePath(fileName string) (ret string) {
|
||||
func (o *StorageEntity) BuildFilePath(fileName string) (ret string) {
|
||||
ret = filepath.Join(o.Dir, fileName)
|
||||
return
|
||||
}
|
||||
|
||||
func (o *Storage) buildFileName(name string) string {
|
||||
func (o *StorageEntity) buildFileName(name string) string {
|
||||
return fmt.Sprintf("%s%v", name, o.FileExtension)
|
||||
}
|
||||
|
||||
func (o *Storage) Delete(name string) (err error) {
|
||||
if err = os.Remove(o.BuildFilePathByName(name)); err != nil {
|
||||
err = fmt.Errorf("could not delete %s: %v", name, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (o *Storage) Exists(name string) (ret bool) {
|
||||
_, err := os.Stat(o.BuildFilePathByName(name))
|
||||
ret = !os.IsNotExist(err)
|
||||
return
|
||||
}
|
||||
|
||||
func (o *Storage) Rename(oldName, newName string) (err error) {
|
||||
if err = os.Rename(o.BuildFilePathByName(oldName), o.BuildFilePathByName(newName)); err != nil {
|
||||
err = fmt.Errorf("could not rename %s to %s: %v", oldName, newName, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (o *Storage) Save(name string, content []byte) (err error) {
|
||||
if err = os.WriteFile(o.BuildFilePathByName(name), content, 0644); err != nil {
|
||||
err = fmt.Errorf("could not save %s: %v", name, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (o *Storage) Load(name string) (ret []byte, err error) {
|
||||
if ret, err = os.ReadFile(o.BuildFilePathByName(name)); err != nil {
|
||||
err = fmt.Errorf("could not load %s: %v", name, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (o *Storage) SaveAsJson(name string, item interface{}) (err error) {
|
||||
func (o *StorageEntity) SaveAsJson(name string, item interface{}) (err error) {
|
||||
var jsonString []byte
|
||||
if jsonString, err = json.Marshal(item); err == nil {
|
||||
err = o.Save(name, jsonString)
|
||||
@@ -135,7 +135,7 @@ func (o *Storage) SaveAsJson(name string, item interface{}) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
func (o *Storage) LoadAsJson(name string, item interface{}) (err error) {
|
||||
func (o *StorageEntity) LoadAsJson(name string, item interface{}) (err error) {
|
||||
var content []byte
|
||||
if content, err = o.Load(name); err != nil {
|
||||
return
|
||||
@@ -1,4 +1,4 @@
|
||||
package db
|
||||
package fs
|
||||
|
||||
import (
|
||||
"testing"
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
|
||||
func TestStorage_SaveAndLoad(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
storage := &Storage{Dir: dir}
|
||||
storage := &StorageEntity{Dir: dir}
|
||||
name := "test"
|
||||
content := []byte("test content")
|
||||
if err := storage.Save(name, content); err != nil {
|
||||
@@ -23,7 +23,7 @@ func TestStorage_SaveAndLoad(t *testing.T) {
|
||||
|
||||
func TestStorage_Exists(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
storage := &Storage{Dir: dir}
|
||||
storage := &StorageEntity{Dir: dir}
|
||||
name := "test"
|
||||
if storage.Exists(name) {
|
||||
t.Errorf("expected file to not exist")
|
||||
@@ -38,7 +38,7 @@ func TestStorage_Exists(t *testing.T) {
|
||||
|
||||
func TestStorage_Delete(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
storage := &Storage{Dir: dir}
|
||||
storage := &StorageEntity{Dir: dir}
|
||||
name := "test"
|
||||
if err := storage.Save(name, []byte("test content")); err != nil {
|
||||
t.Fatalf("failed to save content: %v", err)
|
||||
@@ -1 +0,0 @@
|
||||
package db
|
||||
29
go.mod
29
go.mod
@@ -5,6 +5,7 @@ go 1.22.5
|
||||
require (
|
||||
github.com/anaskhan96/soup v1.2.5
|
||||
github.com/atotto/clipboard v0.1.4
|
||||
github.com/gin-gonic/gin v1.10.0
|
||||
github.com/go-git/go-git/v5 v5.12.0
|
||||
github.com/go-shiori/go-readability v0.0.0-20240923125239-59a7bd165825
|
||||
github.com/google/generative-ai-go v0.18.0
|
||||
@@ -17,7 +18,7 @@ require (
|
||||
github.com/samber/lo v1.47.0
|
||||
github.com/sashabaranov/go-openai v1.30.0
|
||||
github.com/stretchr/testify v1.9.0
|
||||
golang.org/x/text v0.18.0
|
||||
golang.org/x/text v0.19.0
|
||||
google.golang.org/api v0.197.0
|
||||
)
|
||||
|
||||
@@ -33,16 +34,26 @@ require (
|
||||
github.com/ProtonMail/go-crypto v1.0.0 // indirect
|
||||
github.com/andybalholm/cascadia v1.3.2 // indirect
|
||||
github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de // indirect
|
||||
github.com/bytedance/sonic v1.11.6 // indirect
|
||||
github.com/bytedance/sonic/loader v0.1.1 // indirect
|
||||
github.com/cloudflare/circl v1.4.0 // indirect
|
||||
github.com/cloudwego/base64x v0.1.4 // indirect
|
||||
github.com/cloudwego/iasm v0.2.0 // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.3.2 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/emirpasic/gods v1.18.1 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
|
||||
github.com/go-git/go-billy/v5 v5.5.0 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.20.0 // indirect
|
||||
github.com/go-shiori/dom v0.0.0-20230515143342-73569d674e1c // indirect
|
||||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/google/s2a-go v0.1.8 // indirect
|
||||
@@ -50,11 +61,20 @@ require (
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.13.0 // indirect
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/kevinburke/ssh_config v1.2.0 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
||||
github.com/leodido/go-urn v1.4.0 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||
github.com/pjbgf/sha1cd v0.3.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
|
||||
github.com/skeema/knownhosts v1.3.0 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.12 // indirect
|
||||
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.55.0 // indirect
|
||||
@@ -62,11 +82,12 @@ require (
|
||||
go.opentelemetry.io/otel v1.30.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.30.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.30.0 // indirect
|
||||
golang.org/x/crypto v0.27.0 // indirect
|
||||
golang.org/x/net v0.29.0 // indirect
|
||||
golang.org/x/arch v0.8.0 // indirect
|
||||
golang.org/x/crypto v0.28.0 // indirect
|
||||
golang.org/x/net v0.30.0 // indirect
|
||||
golang.org/x/oauth2 v0.23.0 // indirect
|
||||
golang.org/x/sync v0.8.0 // indirect
|
||||
golang.org/x/sys v0.25.0 // indirect
|
||||
golang.org/x/sys v0.26.0 // indirect
|
||||
golang.org/x/time v0.6.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect
|
||||
|
||||
74
go.sum
74
go.sum
@@ -32,11 +32,19 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkY
|
||||
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
|
||||
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
|
||||
github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
|
||||
github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0=
|
||||
github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4=
|
||||
github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM=
|
||||
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
|
||||
github.com/cloudflare/circl v1.4.0 h1:BV7h5MgrktNzytKmWjpOtdYrf0lkkbF8YMlBGPhJQrY=
|
||||
github.com/cloudflare/circl v1.4.0/go.mod h1:PDRU+oXvdD7KCtgKxW95M5Z8BpSCJXQORiZFnBQS5QU=
|
||||
github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
|
||||
github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
|
||||
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
|
||||
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cyphar/filepath-securejoin v0.3.2 h1:QhZu5AxQ+o1XZH0Ye05YzvJ0kAdK6VQc0z9NNMek7gc=
|
||||
github.com/cyphar/filepath-securejoin v0.3.2/go.mod h1:F7i41x/9cBF7lzCrVsYs9fuzwRZm4NQsGTBdpp6mETc=
|
||||
@@ -53,6 +61,12 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
|
||||
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
|
||||
github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
|
||||
github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE=
|
||||
github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8=
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
|
||||
@@ -68,10 +82,20 @@ github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8=
|
||||
github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
||||
github.com/go-shiori/dom v0.0.0-20230515143342-73569d674e1c h1:wpkoddUomPfHiOziHZixGO5ZBS73cKqVzZipfrLmO1w=
|
||||
github.com/go-shiori/dom v0.0.0-20230515143342-73569d674e1c/go.mod h1:oVDCh3qjJMLVUSILBRwrm+Bc6RNXGZYtoh9xdvf1ffM=
|
||||
github.com/go-shiori/go-readability v0.0.0-20240923125239-59a7bd165825 h1:CpSi7xiWqGaAqVn/2MsbRoDmPwXMvvQUu3hLjX1QrOM=
|
||||
github.com/go-shiori/go-readability v0.0.0-20240923125239-59a7bd165825/go.mod h1:YWa00ashoPZMAOElrSn4E1cJErhDVU6PWAll4Hxzn+w=
|
||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f h1:3BSP1Tbs2djlpprl7wCLuiqMaUh5SJkkzI2gDs+FgLs=
|
||||
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f/go.mod h1:Pcatq5tYkCW2Q6yrR2VRHlbHpZ/R4/7qyL1TCF7vl14=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
@@ -100,6 +124,7 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/s2a-go v0.1.8 h1:zZDs9gcbt9ZPLV0ndSyQk6Kacx2g/X+SKYovpnz3SMM=
|
||||
github.com/google/s2a-go v0.1.8/go.mod h1:6iNWHTpQ+nfNRN5E00MSdfDwVesa8hhS32PhPO8deJA=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
@@ -115,8 +140,14 @@ github.com/jessevdk/go-flags v1.6.1 h1:Cvu5U8UGrLay1rZfv/zP7iLpSHGUZ/Ou68T0iX1bB
|
||||
github.com/jessevdk/go-flags v1.6.1/go.mod h1:Mk8T1hIAWpOiJiHa9rJASDK2UGWji0EuPGBnNLMooyc=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
|
||||
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
|
||||
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
@@ -124,9 +155,18 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||
github.com/liushuangls/go-anthropic/v2 v2.8.0 h1:0zH2jDNycbrlszxnLrG+Gx8vVT0yJAPWU4s3ZTkWzgI=
|
||||
github.com/liushuangls/go-anthropic/v2 v2.8.0/go.mod h1:8BKv/fkeTaL5R9R9bGkaknYBueyw2WxY20o7bImbOek=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/ollama/ollama v0.3.11 h1:Fs1B5WjXYUvr5bkMZZpUJfiqIAxrymujRidFABwMeV8=
|
||||
github.com/ollama/ollama v0.3.11/go.mod h1:YrWoNkFnPOYsnDvsf/Ztb1wxU9/IXrNsQHqcxbY2r94=
|
||||
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
|
||||
@@ -135,6 +175,8 @@ github.com/otiai10/copy v1.14.0 h1:dCI/t1iTdYGtkvCuBG2BgR6KZa83PTclw4U5n2wAllU=
|
||||
github.com/otiai10/copy v1.14.0/go.mod h1:ECfuL02W+/FkTWZWgQqXPWZgW9oeKCSQ5qVfSc4qc4w=
|
||||
github.com/otiai10/mint v1.5.1 h1:XaPLeE+9vGbuyEHem1JNk3bYc7KKqyI/na0/mLd/Kks=
|
||||
github.com/otiai10/mint v1.5.1/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM=
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
|
||||
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
||||
github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
|
||||
github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
@@ -158,15 +200,22 @@ github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
|
||||
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
|
||||
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
@@ -182,14 +231,17 @@ go.opentelemetry.io/otel/metric v1.30.0 h1:4xNulvn9gjzo4hjg+wzIKG7iNFEaBMX00Qd4Q
|
||||
go.opentelemetry.io/otel/metric v1.30.0/go.mod h1:aXTfST94tswhWEb+5QjlSqG+cZlmyXy/u8jFpor3WqQ=
|
||||
go.opentelemetry.io/otel/trace v1.30.0 h1:7UBkkYzeg3C7kQX8VAidWh2biiQbtAKjyIML8dQ9wmc=
|
||||
go.opentelemetry.io/otel/trace v1.30.0/go.mod h1:5EyKqTzzmyqB9bwtCCq6pDLktPK6fmGf/Dph+8VI02o=
|
||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
|
||||
golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
|
||||
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
|
||||
golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
|
||||
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
@@ -211,8 +263,8 @@ golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
|
||||
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
|
||||
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
|
||||
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
|
||||
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs=
|
||||
golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
@@ -240,16 +292,16 @@ golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
|
||||
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
|
||||
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
||||
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
|
||||
golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM=
|
||||
golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8=
|
||||
golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24=
|
||||
golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
@@ -258,8 +310,8 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
|
||||
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
|
||||
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
|
||||
golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
@@ -314,3 +366,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
|
||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||
|
||||
41
lang/language.go
Normal file
41
lang/language.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package lang
|
||||
|
||||
import (
|
||||
"github.com/danielmiessler/fabric/common"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
func NewLanguage() (ret *Language) {
|
||||
|
||||
label := "Language"
|
||||
ret = &Language{}
|
||||
|
||||
ret.Configurable = &common.Configurable{
|
||||
Label: label,
|
||||
EnvNamePrefix: common.BuildEnvVariablePrefix(label),
|
||||
ConfigureCustom: ret.configure,
|
||||
}
|
||||
|
||||
ret.DefaultLanguage = ret.Configurable.AddSetupQuestionCustom("Output", false,
|
||||
"Enter your default want output lang (for example: zh_CN)")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
type Language struct {
|
||||
*common.Configurable
|
||||
DefaultLanguage *common.SetupQuestion
|
||||
}
|
||||
|
||||
func (o *Language) configure() error {
|
||||
if o.DefaultLanguage.Value != "" {
|
||||
langTag, err := language.Parse(o.DefaultLanguage.Value)
|
||||
if err == nil {
|
||||
o.DefaultLanguage.Value = langTag.String()
|
||||
} else {
|
||||
o.DefaultLanguage.Value = ""
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -5,7 +5,9 @@ You are an expert at extracting the sponsors and potential sponsors from a given
|
||||
# Steps
|
||||
|
||||
- Consume the whole transcript so you understand what is content, what is meta information, etc.
|
||||
|
||||
- Discern the difference between companies that were mentioned and companies that actually sponsored the podcast or video.
|
||||
|
||||
- Output the following:
|
||||
|
||||
## OFFICIAL SPONSORS
|
||||
@@ -15,36 +17,20 @@ You are an expert at extracting the sponsors and potential sponsors from a given
|
||||
- $SOURCE_CHANNEL$ | $SPONSOR3$ | $SPONSOR3_DESCRIPTION$ | $SPONSOR3_LINK$
|
||||
- And so on…
|
||||
|
||||
## POTENTIAL SPONSORS
|
||||
|
||||
- $SOURCE_CHANNEL$ | $SPONSOR1$ | $SPONSOR1_DESCRIPTION$ | $SPONSOR1_LINK$
|
||||
- $SOURCE_CHANNEL$ | $SPONSOR2$ | $SPONSOR2_DESCRIPTION$ | $SPONSOR2_LINK$
|
||||
- $SOURCE_CHANNEL$ | $SPONSOR3$ | $SPONSOR3_DESCRIPTION$ | $SPONSOR3_LINK$
|
||||
- And so on…
|
||||
|
||||
# EXAMPLE OUTPUT
|
||||
|
||||
## OFFICIAL SPONSORS
|
||||
|
||||
- AI Jason's YouTube Channel | Flair | Flair is a threat intel platform powered by AI. | https://flair.ai
|
||||
- Matthew Berman's YouTube Channel | Weaviate | Weviate is an open-source knowledge graph powered by ML. | https://weaviate.com
|
||||
- Unsupervised Learning Website | JunaAI | JunaAI is a platform for AI-powered content creation. | https://junaai.com
|
||||
- The AI Junkie Podcast | JunaAI | JunaAI is a platform for AI-powered content creation. | https://junaai.com
|
||||
|
||||
## POTENTIAL SPONSORS
|
||||
|
||||
- AI Jason's YouTube Channel | Flair | Flair is a threat intel platform powered by AI. | https://flair.ai
|
||||
- Matthew Berman's YouTube Channel | Weaviate | Weviate is an open-source knowledge graph powered by ML. | https://weaviate.com
|
||||
- Unsupervised Learning Website | JunaAI | JunaAI is a platform for AI-powered content creation. | https://junaai.com
|
||||
- The AI Junkie Podcast | JunaAI | JunaAI is a platform for AI-powered content creation. | https://junaai.com
|
||||
- Flair | Flair is a threat intel platform powered by AI. | https://flair.ai
|
||||
- Weaviate | Weviate is an open-source knowledge graph powered by ML. | https://weaviate.com
|
||||
- JunaAI | JunaAI is a platform for AI-powered content creation. | https://junaai.com
|
||||
- JunaAI | JunaAI is a platform for AI-powered content creation. | https://junaai.com
|
||||
|
||||
## END EXAMPLE OUTPUT
|
||||
|
||||
# OUTPUT INSTRUCTIONS
|
||||
|
||||
- The official sponsor list should only include companies that officially sponsored the content in question.
|
||||
- The potential sponsor list should include companies that were mentioned during the content but that didn't officially sponsor.
|
||||
- Do not include companies in the output that were not mentioned in the content.
|
||||
- Do not output warnings or notes—just the requested sections.
|
||||
|
||||
# INPUT:
|
||||
|
||||
27
patterns/raycast/capture_thinkers_work
Executable file
27
patterns/raycast/capture_thinkers_work
Executable file
@@ -0,0 +1,27 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Required parameters:
|
||||
# @raycast.schemaVersion 1
|
||||
# @raycast.title Capture Thinkers Work
|
||||
# @raycast.mode fullOutput
|
||||
|
||||
# Optional parameters:
|
||||
# @raycast.icon 🧠
|
||||
# @raycast.argument1 { "type": "text", "placeholder": "Input text", "optional": false, "percentEncoded": true}
|
||||
|
||||
# Documentation:
|
||||
# @raycast.description Run fabric capture_thinkers_work on the input text
|
||||
# @raycast.author Daniel Miessler
|
||||
# @raycast.authorURL https://github.com/danielmiessler
|
||||
|
||||
# Set PATH to include common locations and $HOME/go/bin
|
||||
PATH="/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:$HOME/go/bin:$PATH"
|
||||
|
||||
# Use the PATH to find and execute fabric
|
||||
if command -v fabric >/dev/null 2>&1; then
|
||||
fabric -sp capture_thinkers_work "${1}"
|
||||
else
|
||||
echo "Error: fabric command not found in PATH"
|
||||
echo "Current PATH: $PATH"
|
||||
exit 1
|
||||
fi
|
||||
@@ -8,15 +8,15 @@ Take a step back and think step-by-step about how to achieve the best possible r
|
||||
|
||||
- Fully digest the content provided.
|
||||
|
||||
- Extract all actionables agreed within the meeting.
|
||||
- Extract all actionables agreed upon within the meeting.
|
||||
|
||||
- Extract any interesting ideas brought up in the meeting.
|
||||
|
||||
- In a section called TITLE, write a 1 to 5 word title for the meeting
|
||||
- In a section called TITLE, write a 1 to 5 word title for the meeting.
|
||||
|
||||
- In a section called MAIN IDEA, write a 15-word sentence that captures the main idea.
|
||||
|
||||
- In a section called MINUTES, write 20 to 50 bullet points, highliting of the most surprising, insightful, and/or interesting ideas that come up in the conversation. If there are less than 50 then collect all of them. Make sure you extract at least 20.
|
||||
- In a section called MINUTES, write 20 to 50 bullet points, highlighting of the most surprising, insightful, and/or interesting ideas that come up in the conversation. If there are less than 50 then collect all of them. Make sure you extract at least 20.
|
||||
|
||||
- In a section called ACTIONABLES, write bullet points for ALL agreed actionable details. This includes cases where a speaker agrees to do or look into something. If there is a deadline mentioned, include it here.
|
||||
|
||||
@@ -24,16 +24,16 @@ Take a step back and think step-by-step about how to achieve the best possible r
|
||||
|
||||
- In a section called CHALLENGES, identify and document any challenges or issues discussed during the meeting. Note any potential solutions or strategies proposed to address these challenges.
|
||||
|
||||
- In a section caled NEXT STEPS, outline the next steps and actions to be taken after the meeting
|
||||
- In a section called NEXT STEPS, outline the next steps and actions to be taken after the meeting.
|
||||
|
||||
# OUTPUT INSTRUCTIONS
|
||||
|
||||
- Only output Markdown.
|
||||
- Write MINUTES as exxactly 15 words.
|
||||
- Write MINUTES as exactly 15 words.
|
||||
- Write ACTIONABLES as exactly 15 words.
|
||||
- Write DECISIONS as exactly 15 words.
|
||||
- Write CHALLENGES as 2-3 sentences.
|
||||
- Write NEXT STEPS a 2-3 sentences.
|
||||
- Write NEXT STEPS as 2-3 sentences.
|
||||
- Do not give warnings or notes; only output the requested sections.
|
||||
- Do not repeat ideas, quotes, facts, or resources.
|
||||
- You use bulleted lists for output, not numbered lists.
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package azure
|
||||
|
||||
import (
|
||||
"github.com/danielmiessler/fabric/plugins/ai/openai"
|
||||
"strings"
|
||||
|
||||
"github.com/danielmiessler/fabric/common"
|
||||
"github.com/danielmiessler/fabric/vendors/openai"
|
||||
goopenai "github.com/sashabaranov/go-openai"
|
||||
)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package groq
|
||||
|
||||
import (
|
||||
"github.com/danielmiessler/fabric/vendors/openai"
|
||||
"github.com/danielmiessler/fabric/plugins/ai/openai"
|
||||
)
|
||||
|
||||
func NewClient() (ret *Client) {
|
||||
@@ -1,7 +1,7 @@
|
||||
package mistral
|
||||
|
||||
import (
|
||||
"github.com/danielmiessler/fabric/vendors/openai"
|
||||
"github.com/danielmiessler/fabric/plugins/ai/openai"
|
||||
)
|
||||
|
||||
func NewClient() (ret *Client) {
|
||||
@@ -1,7 +1,7 @@
|
||||
package openrouter
|
||||
|
||||
import (
|
||||
"github.com/danielmiessler/fabric/vendors/openai"
|
||||
"github.com/danielmiessler/fabric/plugins/ai/openai"
|
||||
)
|
||||
|
||||
func NewClient() (ret *Client) {
|
||||
@@ -1,7 +1,7 @@
|
||||
package siliconcloud
|
||||
|
||||
import (
|
||||
"github.com/danielmiessler/fabric/vendors/openai"
|
||||
"github.com/danielmiessler/fabric/plugins/ai/openai"
|
||||
)
|
||||
|
||||
func NewClient() (ret *Client) {
|
||||
@@ -1,4 +1,4 @@
|
||||
package vendors
|
||||
package ai
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
41
plugins/tools/lang/language.go
Normal file
41
plugins/tools/lang/language.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package lang
|
||||
|
||||
import (
|
||||
"github.com/danielmiessler/fabric/common"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
func NewLanguage() (ret *Language) {
|
||||
|
||||
label := "Language"
|
||||
ret = &Language{}
|
||||
|
||||
ret.Configurable = &common.Configurable{
|
||||
Label: label,
|
||||
EnvNamePrefix: common.BuildEnvVariablePrefix(label),
|
||||
ConfigureCustom: ret.configure,
|
||||
}
|
||||
|
||||
ret.DefaultLanguage = ret.Configurable.AddSetupQuestionCustom("Output", false,
|
||||
"Enter your default want output lang (for example: zh_CN)")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
type Language struct {
|
||||
*common.Configurable
|
||||
DefaultLanguage *common.SetupQuestion
|
||||
}
|
||||
|
||||
func (o *Language) configure() error {
|
||||
if o.DefaultLanguage.Value != "" {
|
||||
langTag, err := language.Parse(o.DefaultLanguage.Value)
|
||||
if err == nil {
|
||||
o.DefaultLanguage.Value = langTag.String()
|
||||
} else {
|
||||
o.DefaultLanguage.Value = ""
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
19
restapi/contexts.go
Normal file
19
restapi/contexts.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package restapi
|
||||
|
||||
import (
|
||||
"github.com/danielmiessler/fabric/db/fs"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// ContextsHandler defines the handler for contexts-related operations
|
||||
type ContextsHandler struct {
|
||||
*StorageHandler[fs.Context]
|
||||
contexts *fs.ContextsEntity
|
||||
}
|
||||
|
||||
// NewContextsHandler creates a new ContextsHandler
|
||||
func NewContextsHandler(r *gin.Engine, contexts *fs.ContextsEntity) (ret *ContextsHandler) {
|
||||
ret = &ContextsHandler{
|
||||
StorageHandler: NewStorageHandler[fs.Context](r, "contexts", contexts), contexts: contexts}
|
||||
return
|
||||
}
|
||||
35
restapi/patterns.go
Normal file
35
restapi/patterns.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package restapi
|
||||
|
||||
import (
|
||||
"github.com/danielmiessler/fabric/db/fs"
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// PatternsHandler defines the handler for patterns-related operations
|
||||
type PatternsHandler struct {
|
||||
*StorageHandler[fs.Pattern]
|
||||
patterns *fs.PatternsEntity
|
||||
}
|
||||
|
||||
// NewPatternsHandler creates a new PatternsHandler
|
||||
func NewPatternsHandler(r *gin.Engine, patterns *fs.PatternsEntity) (ret *PatternsHandler) {
|
||||
ret = &PatternsHandler{
|
||||
StorageHandler: NewStorageHandler[fs.Pattern](r, "patterns", patterns), patterns: patterns}
|
||||
|
||||
// TODO: Add custom, replacement routes here
|
||||
//r.GET("/patterns/:name", ret.Get)
|
||||
return
|
||||
}
|
||||
|
||||
// Get handles the GET /patterns/:name route
|
||||
func (h *PatternsHandler) Get(c *gin.Context) {
|
||||
name := c.Param("name")
|
||||
variables := make(map[string]string) // Assuming variables are passed somehow
|
||||
pattern, err := h.patterns.GetApplyVariables(name, variables)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, pattern)
|
||||
}
|
||||
27
restapi/serve.go
Normal file
27
restapi/serve.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package restapi
|
||||
|
||||
import (
|
||||
"github.com/danielmiessler/fabric/db/fs"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func Serve(fabricDb *fs.Db, address string) (err error) {
|
||||
r := gin.Default()
|
||||
|
||||
// Middleware
|
||||
r.Use(gin.Logger())
|
||||
r.Use(gin.Recovery())
|
||||
|
||||
// Register routes
|
||||
NewPatternsHandler(r, fabricDb.Patterns)
|
||||
NewContextsHandler(r, fabricDb.Contexts)
|
||||
NewSessionsHandler(r, fabricDb.Sessions)
|
||||
|
||||
// Start server
|
||||
err = r.Run(address)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
19
restapi/sessions.go
Normal file
19
restapi/sessions.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package restapi
|
||||
|
||||
import (
|
||||
"github.com/danielmiessler/fabric/db/fs"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// SessionsHandler defines the handler for sessions-related operations
|
||||
type SessionsHandler struct {
|
||||
*StorageHandler[fs.Session]
|
||||
sessions *fs.SessionsEntity
|
||||
}
|
||||
|
||||
// NewSessionsHandler creates a new SessionsHandler
|
||||
func NewSessionsHandler(r *gin.Engine, sessions *fs.SessionsEntity) (ret *SessionsHandler) {
|
||||
ret = &SessionsHandler{
|
||||
StorageHandler: NewStorageHandler[fs.Session](r, "sessions", sessions), sessions: sessions}
|
||||
return ret
|
||||
}
|
||||
100
restapi/storage.go
Normal file
100
restapi/storage.go
Normal file
@@ -0,0 +1,100 @@
|
||||
package restapi
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/danielmiessler/fabric/db"
|
||||
"github.com/gin-gonic/gin"
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// StorageHandler defines the handler for storage-related operations
|
||||
type StorageHandler[T any] struct {
|
||||
storage db.Storage[T]
|
||||
}
|
||||
|
||||
// NewStorageHandler creates a new StorageHandler
|
||||
func NewStorageHandler[T any](r *gin.Engine, entityType string, storage db.Storage[T]) (ret *StorageHandler[T]) {
|
||||
ret = &StorageHandler[T]{storage: storage}
|
||||
r.GET(fmt.Sprintf("/%s/:name", entityType), ret.Get)
|
||||
r.GET(fmt.Sprintf("/%s/names", entityType), ret.GetNames)
|
||||
r.DELETE(fmt.Sprintf("/%s/:name", entityType), ret.Delete)
|
||||
r.GET(fmt.Sprintf("/%s/exists/:name", entityType), ret.Exists)
|
||||
r.PUT(fmt.Sprintf("/%s/rename/:oldName/:newName", entityType), ret.Rename)
|
||||
r.POST(fmt.Sprintf("/%s/:name", entityType), ret.Save)
|
||||
return
|
||||
}
|
||||
|
||||
// Get handles the GET /storage/:name route
|
||||
func (h *StorageHandler[T]) Get(c *gin.Context) {
|
||||
name := c.Param("name")
|
||||
item, err := h.storage.Get(name)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, item)
|
||||
}
|
||||
|
||||
// GetNames handles the GET /storage/names route
|
||||
func (h *StorageHandler[T]) GetNames(c *gin.Context) {
|
||||
names, err := h.storage.GetNames()
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, names)
|
||||
}
|
||||
|
||||
// Delete handles the DELETE /storage/:name route
|
||||
func (h *StorageHandler[T]) Delete(c *gin.Context) {
|
||||
name := c.Param("name")
|
||||
err := h.storage.Delete(name)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
c.Status(http.StatusOK)
|
||||
}
|
||||
|
||||
// Exists handles the GET /storage/exists/:name route
|
||||
func (h *StorageHandler[T]) Exists(c *gin.Context) {
|
||||
name := c.Param("name")
|
||||
exists := h.storage.Exists(name)
|
||||
c.JSON(http.StatusOK, exists)
|
||||
}
|
||||
|
||||
// Rename handles the PUT /storage/rename/:oldName/:newName route
|
||||
func (h *StorageHandler[T]) Rename(c *gin.Context) {
|
||||
oldName := c.Param("oldName")
|
||||
newName := c.Param("newName")
|
||||
err := h.storage.Rename(oldName, newName)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
c.Status(http.StatusOK)
|
||||
}
|
||||
|
||||
// Save handles the POST /storage/save/:name route
|
||||
func (h *StorageHandler[T]) Save(c *gin.Context) {
|
||||
name := c.Param("name")
|
||||
|
||||
// Read the request body
|
||||
body := c.Request.Body
|
||||
defer body.Close()
|
||||
|
||||
content, err := io.ReadAll(body)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// Save the content to storage
|
||||
err = h.storage.Save(name, content)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
c.Status(http.StatusOK)
|
||||
}
|
||||
112
setup_fabric.bat
Normal file
112
setup_fabric.bat
Normal file
@@ -0,0 +1,112 @@
|
||||
@echo off
|
||||
setlocal enabledelayedexpansion
|
||||
|
||||
:: Check if running with administrator privileges
|
||||
net session >nul 2>&1
|
||||
if %errorlevel% neq 0 (
|
||||
echo Please run this script as an administrator.
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
:: Install Chocolatey (package manager for Windows)
|
||||
if not exist "%ProgramData%\chocolatey\bin\choco.exe" (
|
||||
echo Installing Chocolatey...
|
||||
@"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "[System.Net.ServicePointManager]::SecurityProtocol = 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"
|
||||
)
|
||||
|
||||
:: Install Go
|
||||
where go >nul 2>&1
|
||||
if %errorlevel% neq 0 (
|
||||
echo Installing Go...
|
||||
choco install golang -y
|
||||
set "PATH=%PATH%;C:\Program Files\Go\bin"
|
||||
)
|
||||
|
||||
:: Install Git
|
||||
where git >nul 2>&1
|
||||
if %errorlevel% neq 0 (
|
||||
echo Installing Git...
|
||||
choco install git -y
|
||||
)
|
||||
|
||||
:: Refresh environment variables
|
||||
call refreshenv
|
||||
|
||||
:: Install Fabric
|
||||
echo Installing Fabric...
|
||||
go install github.com/danielmiessler/fabric@latest
|
||||
|
||||
:: Run Fabric setup
|
||||
echo Running Fabric setup...
|
||||
fabric --setup
|
||||
|
||||
:: Install yt helper
|
||||
echo Installing yt helper...
|
||||
go install github.com/danielmiessler/yt@latest
|
||||
|
||||
:: Prompt user for YouTube API Key
|
||||
set /p YOUTUBE_API_KEY=Enter your YouTube API Key (press Enter to skip):
|
||||
if not "!YOUTUBE_API_KEY!"=="" (
|
||||
echo YOUTUBE_API_KEY=!YOUTUBE_API_KEY!>> %USERPROFILE%\.config\fabric\.env
|
||||
)
|
||||
|
||||
:: Prompt user for OpenAI API Key
|
||||
set /p OPENAI_API_KEY=Enter your OpenAI API Key (press Enter to skip):
|
||||
if not "!OPENAI_API_KEY!"=="" (
|
||||
echo OPENAI_API_KEY=!OPENAI_API_KEY!>> %USERPROFILE%\.config\fabric\.env
|
||||
)
|
||||
|
||||
:: Run Fabric
|
||||
:run_fabric
|
||||
cls
|
||||
echo Fabric is now installed and ready to use.
|
||||
echo.
|
||||
echo Available options:
|
||||
echo 1. Run Fabric with custom options
|
||||
echo 2. List patterns
|
||||
echo 3. List models
|
||||
echo 4. Update patterns
|
||||
echo 5. Exit
|
||||
echo.
|
||||
set /p CHOICE=Enter your choice (1-5):
|
||||
|
||||
if "%CHOICE%"=="1" (
|
||||
set /p PATTERN=Enter pattern (or press Enter to skip):
|
||||
set /p CONTEXT=Enter context (or press Enter to skip):
|
||||
set /p SESSION=Enter session (or press Enter to skip):
|
||||
set /p MODEL=Enter model (or press Enter to skip):
|
||||
set /p TEMPERATURE=Enter temperature (or press Enter for default):
|
||||
set /p STREAM=Do you want to stream output? (Y/N):
|
||||
|
||||
set "FABRIC_CMD=fabric"
|
||||
if not "!PATTERN!"=="" set "FABRIC_CMD=!FABRIC_CMD! --pattern !PATTERN!"
|
||||
if not "!CONTEXT!"=="" set "FABRIC_CMD=!FABRIC_CMD! --context !CONTEXT!"
|
||||
if not "!SESSION!"=="" set "FABRIC_CMD=!FABRIC_CMD! --session !SESSION!"
|
||||
if not "!MODEL!"=="" set "FABRIC_CMD=!FABRIC_CMD! --model !MODEL!"
|
||||
if not "!TEMPERATURE!"=="" set "FABRIC_CMD=!FABRIC_CMD! --temperature !TEMPERATURE!"
|
||||
if /i "!STREAM!"=="Y" set "FABRIC_CMD=!FABRIC_CMD! --stream"
|
||||
|
||||
echo Running Fabric with command: !FABRIC_CMD!
|
||||
!FABRIC_CMD!
|
||||
pause
|
||||
goto run_fabric
|
||||
) else if "%CHOICE%"=="2" (
|
||||
fabric --listpatterns
|
||||
pause
|
||||
goto run_fabric
|
||||
) else if "%CHOICE%"=="3" (
|
||||
fabric --listmodels
|
||||
pause
|
||||
goto run_fabric
|
||||
) else if "%CHOICE%"=="4" (
|
||||
fabric --updatepatterns
|
||||
pause
|
||||
goto run_fabric
|
||||
) else if "%CHOICE%"=="5" (
|
||||
exit /b 0
|
||||
) else (
|
||||
echo Invalid choice. Please try again.
|
||||
pause
|
||||
goto run_fabric
|
||||
)
|
||||
@@ -1,3 +1,3 @@
|
||||
package main
|
||||
|
||||
var version = "v1.4.52"
|
||||
var version = "v1.4.64"
|
||||
|
||||
Reference in New Issue
Block a user