diff --git a/README.md b/README.md index 2534135b..cbfe6e96 100644 --- a/README.md +++ b/README.md @@ -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]. diff --git a/cli/cli.go b/cli/cli.go index 4c4cafdb..a51a86ef 100644 --- a/cli/cli.go +++ b/cli/cli.go @@ -152,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 @@ -214,7 +218,11 @@ func Cli(version string) (err error) { } var session *fs.Session - if session, err = chatter.Send(currentFlags.BuildChatRequest(strings.Join(os.Args[1:], " ")), currentFlags.BuildChatOptions()); err != nil { + 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 } @@ -262,8 +270,6 @@ func Setup(db *fs.Db, skipUpdatePatterns bool) (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 } diff --git a/core/chatter.go b/core/chatter.go index 7b75399f..df130a48 100644 --- a/core/chatter.go +++ b/core/chatter.go @@ -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}) diff --git a/core/fabric.go b/core/fabric.go index 5fa384d6..dfbb481a 100644 --- a/core/fabric.go +++ b/core/fabric.go @@ -3,6 +3,9 @@ package core import ( "bytes" "fmt" + "os" + "strconv" + "github.com/atotto/clipboard" "github.com/danielmiessler/fabric/common" "github.com/danielmiessler/fabric/db/fs" @@ -20,8 +23,6 @@ import ( "github.com/danielmiessler/fabric/plugins/tools/lang" "github.com/danielmiessler/fabric/plugins/tools/youtube" "github.com/pkg/errors" - "os" - "strconv" ) const DefaultPatternsGitRepoUrl = "https://github.com/danielmiessler/fabric.git" @@ -66,7 +67,7 @@ func NewFabricBase(db *fs.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 } diff --git a/lang/language.go b/lang/language.go new file mode 100644 index 00000000..48d76e8e --- /dev/null +++ b/lang/language.go @@ -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 +} diff --git a/patterns/extract_core_message/system.md b/patterns/extract_core_message/system.md new file mode 100644 index 00000000..895b17d0 --- /dev/null +++ b/patterns/extract_core_message/system.md @@ -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 life’s 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. diff --git a/patterns/raycast/capture_thinkers_work b/patterns/raycast/capture_thinkers_work new file mode 100755 index 00000000..6cc44ced --- /dev/null +++ b/patterns/raycast/capture_thinkers_work @@ -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 diff --git a/patterns/transcribe_minutes/system.md b/patterns/transcribe_minutes/system.md index 6a7a5cae..6e66aa71 100644 --- a/patterns/transcribe_minutes/system.md +++ b/patterns/transcribe_minutes/system.md @@ -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. diff --git a/version.go b/version.go index add07e05..c07b9586 100644 --- a/version.go +++ b/version.go @@ -1,3 +1,3 @@ package main -var version = "v1.4.51" +var version = "v1.4.60"