Compare commits

...

47 Commits

Author SHA1 Message Date
github-actions[bot]
584e0c8547 Update version to v1.4.63 and commit 2024-10-13 14:42:39 +00:00
Daniel Miessler
914b312c2e Merge pull request #862 from Thepathakarpit/patch-1
Create setup_fabric.bat, a batch script to automate setup and running…
2024-10-13 07:42:27 -07:00
github-actions[bot]
8153d690cc Update version to v1.4.62 and commit 2024-10-13 14:40:48 +00:00
Daniel Miessler
d03bdbeb9b Merge pull request #1044 from danielmiessler/feat/rest-api
Feat/rest api
2024-10-13 07:40:32 -07:00
github-actions[bot]
87730043b5 Update version to v1.4.61 and commit 2024-10-13 02:50:02 +00:00
Daniel Miessler
3285b8e330 Updated extract sponsors. 2024-10-12 19:49:44 -07:00
Eugen Eisler
686d039392 Merge branch 'main' into feat/rest-api 2024-10-12 23:06:29 +03:00
Eugen Eisler
d7683e4c39 feat: restructure for better reuse 2024-10-12 22:49:26 +03:00
Eugen Eisler
56f995afb4 feat: restructure for better reuse 2024-10-12 22:37:35 +03:00
Eugen Eisler
17bde814cc feat: restructure for better reuse 2024-10-12 22:25:17 +03:00
github-actions[bot]
525f972d22 Update version to v1.4.60 and commit 2024-10-12 15:27:28 +00:00
Eugen Eisler
161ce65ae6 fix: IsChatRequest rule; Close #1042 is 2024-10-12 18:27:04 +03:00
github-actions[bot]
72f1429db9 Update version to v1.4.59 and commit 2024-10-11 22:59:41 +00:00
Daniel Miessler
b5fe3f2ad8 Added ctw to Raycast. 2024-10-11 15:59:26 -07:00
github-actions[bot]
2155ff9fc0 Update version to v1.4.58 and commit 2024-10-11 20:30:50 +00:00
Eugen Eisler
d33175e5b6 chore: we don't need tp configure DryRun vendor 2024-10-11 23:28:56 +03:00
Eugen Eisler
6dbd24e541 fix: Close #1040. Configure vendors separately that were not configured yet 2024-10-11 23:25:33 +03:00
github-actions[bot]
d1c527c421 Update version to v1.4.57 and commit 2024-10-11 19:27:41 +00:00
Eugen Eisler
c0bd61ba49 docs: Close #1035, provide better example for pattern variables 2024-10-11 22:27:20 +03:00
github-actions[bot]
8f0cc85742 Update version to v1.4.56 and commit 2024-10-11 18:54:25 +00:00
Eugen Eisler
7275dfbd6b Merge pull request #1039 from hallelujah-shih/feature/set-default-lang
Feature/set default lang
2024-10-11 20:54:10 +02:00
hallelujah-shih
9f94cfb718 fmt 2024-10-10 19:45:39 +08:00
hallelujah-shih
e1fa674a3f support set default output language
# Conflicts:
#	cli/cli.go
#	core/fabric.go
2024-10-10 19:37:51 +08:00
github-actions[bot]
34f804be3a Update version to v1.4.55 and commit 2024-10-09 09:29:17 +00:00
Eugen Eisler
83cd8a1912 fix: Close #1036 2024-10-09 12:29:02 +03:00
github-actions[bot]
d347ef0dcc Update version to v1.4.54 and commit 2024-10-07 16:44:19 +00:00
Eugen Eisler
44cc9bbcac Merge pull request #1021 from joshuafuller/main
Corrected spelling and grammatical errors for consistency and clarity for transcribe_minutes
2024-10-07 18:44:06 +02:00
github-actions[bot]
4aa0b99c74 Update version to v1.4.53 and commit 2024-10-07 09:17:11 +00:00
Eugen Eisler
d90e8081ac fix: fix NP if response is empty, close #1026, #1027 2024-10-07 11:16:57 +02:00
github-actions[bot]
70d43c5252 Update version to v1.4.52 and commit 2024-10-06 19:50:30 +00:00
Daniel Miessler
fd8216f1bd Merge branch 'main' of github.com:danielmiessler/fabric 2024-10-06 12:50:12 -07:00
Daniel Miessler
ae0c9009d9 Added extract_core_message. 2024-10-06 12:50:05 -07:00
Eugen Eisler
4104317b34 feat: work on Rest API 2024-10-06 16:07:32 +02:00
Eugen Eisler
401f0da689 feat: work on Rest API 2024-10-06 16:06:05 +02:00
Eugen Eisler
6efe7960cd feat: work on Rest API 2024-10-06 15:43:18 +02:00
Eugen Eisler
a6d63f4d0e feat: work on Rest API 2024-10-06 15:40:29 +02:00
Eugen Eisler
8f3928f4b2 feat: work on Rest API 2024-10-06 15:31:06 +02:00
Eugen Eisler
3380972df1 feat: work on Rest API 2024-10-06 15:29:01 +02:00
Joshua Fuller
bad01040e3 Corrected spelling and grammatical errors for consistency and clarity
Description:

Changed "agreed within the meeting" to "agreed upon within the meeting" to improve grammatical accuracy.

Added missing periods to ensure consistency across list items.

Corrected the spelling of "highliting" to "highlighting."

Fixed the spelling of "exxactly" to "exactly."

Updated phrasing in "Write NEXT STEPS a 2-3 sentences" to "Write NEXT STEPS as 2-3 sentences" for grammatical correctness.

These changes improve the readability and consistency of the document, ensuring all instructions are clear and error-free.
2024-10-05 17:29:12 -05:00
github-actions[bot]
0b26b930f9 Update version to v1.4.51 and commit 2024-10-05 16:48:46 +00:00
Eugen Eisler
5dbaf4f28f fix: tests 2024-10-05 18:48:22 +02:00
github-actions[bot]
1d9cce5adf Update version to v1.4.50 and commit 2024-10-05 16:44:19 +00:00
Eugen Eisler
76622105e2 fix: windows release 2024-10-05 18:43:54 +02:00
github-actions[bot]
e6e3e34f53 Update version to v1.4.49 and commit 2024-10-05 16:42:19 +00:00
Eugen Eisler
7192ddbaa6 fix: windows release 2024-10-05 18:41:58 +02:00
Arpit Pathak
5ad9943462 Merge branch 'main' into patch-1 2024-09-13 23:19:19 +05:30
Arpit Pathak
cf0b9d2c3d Create setup_fabric.bat, a batch script to automate setup and running fabric on windows. 2024-08-22 09:02:30 +05:30
56 changed files with 818 additions and 256 deletions

View File

@@ -94,11 +94,19 @@ jobs:
path: fabric-windows-${{ matrix.arch }}.exe
- name: Get latest tag
if: matrix.os != 'windows-latest'
id: get_latest_tag
run: |
latest_tag=$(git tag --sort=-creatordate | head -n 1)
echo "latest_tag=$latest_tag" >> $GITHUB_ENV
- name: Get latest tag
if: matrix.os == 'windows-latest'
id: get_latest_tag_windows
run: |
$latest_tag = git tag --sort=-creatordate | Select-Object -First 1
Add-Content -Path $env:GITHUB_ENV -Value "latest_tag=$latest_tag"
- name: Create release if it doesn't exist
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -213,7 +213,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 +293,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].

View File

@@ -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
}

View File

@@ -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)

View File

@@ -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
}

View File

@@ -101,7 +101,8 @@ func TestBuildChatRequest(t *testing.T) {
SessionName: "test-session",
PatternName: "test-pattern",
Message: "test-message",
Meta: "test",
}
request := flags.BuildChatRequest()
request := flags.BuildChatRequest("test")
assert.Equal(t, expectedRequest, request)
}

View File

@@ -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
}

View File

@@ -1,21 +0,0 @@
package core
import (
"testing"
)
func TestBuildChatSession(t *testing.T) {
chat := &Chat{
Context: "test context",
Pattern: "test pattern",
Message: "test message",
}
session, err := chat.BuildChatSession(false)
if err != nil {
t.Fatalf("BuildChatSession() error = %v", err)
}
if session == nil {
t.Fatalf("BuildChatSession() returned nil session")
}
}

View File

@@ -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
}

View File

@@ -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"

View File

@@ -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
}

View File

@@ -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
View 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)
}

View File

@@ -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)

View File

@@ -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)
}

View File

@@ -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
}

View File

@@ -1,4 +1,4 @@
package db
package fs
import (
"os"

View File

@@ -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
View File

@@ -0,0 +1 @@
package fs

View File

@@ -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)
}

View File

@@ -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"}}}

View File

@@ -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

View File

@@ -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)

View File

@@ -1 +0,0 @@
package db

29
go.mod
View File

@@ -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
View File

@@ -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
View 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
}

View File

@@ -0,0 +1,39 @@
# IDENTITY
You are an expert at looking at a presentation, an essay, or a full body of lifetime work, and clearly and accurately articulating what the core message is.
# GOAL
- Produce a clear sentence that perfectly articulates the core message as presented in a given text or body of work.
# EXAMPLE
If the input is all of Victor Frankl's work, then the core message would be:
Finding meaning in suffering is key to human resilience, purpose, and enduring lifes challenges.
END EXAMPLE
# STEPS
- Fully digest the input.
- Determine if the input is a single text or a body of work.
- Based on which it is, parse the thing that's supposed to be parsed.
- Extract the core message from the parsed text into a single sentence.
# OUTPUT
- Output a single, 15-word sentence that perfectly articulates the core message as presented in the input.
# OUTPUT INSTRUCTIONS
- The sentence should be a single sentence that is 15 words or fewer, with no special formatting or anything else.
- Do not include any setup to the sentence, e.g., "The core message is to…", etc. Just list the core message and nothing else.
- ONLY OUTPUT THE CORE MESSAGE, not a setup to it, commentary on it, or anything else.
- Do not ask questions or complain in any way about the task.

View File

@@ -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:

View 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

View File

@@ -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.

View File

@@ -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"
)

View File

@@ -1,7 +1,7 @@
package groq
import (
"github.com/danielmiessler/fabric/vendors/openai"
"github.com/danielmiessler/fabric/plugins/ai/openai"
)
func NewClient() (ret *Client) {

View File

@@ -1,7 +1,7 @@
package mistral
import (
"github.com/danielmiessler/fabric/vendors/openai"
"github.com/danielmiessler/fabric/plugins/ai/openai"
)
func NewClient() (ret *Client) {

View File

@@ -1,7 +1,7 @@
package openrouter
import (
"github.com/danielmiessler/fabric/vendors/openai"
"github.com/danielmiessler/fabric/plugins/ai/openai"
)
func NewClient() (ret *Client) {

View File

@@ -1,7 +1,7 @@
package siliconcloud
import (
"github.com/danielmiessler/fabric/vendors/openai"
"github.com/danielmiessler/fabric/plugins/ai/openai"
)
func NewClient() (ret *Client) {

View File

@@ -1,4 +1,4 @@
package vendors
package ai
import (
"bytes"

View 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
View 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
View 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
View 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
View 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
View 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
View 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
)

View File

@@ -1,3 +1,3 @@
package main
var version = "v1.4.48"
var version = "v1.4.63"