mirror of
https://github.com/danielmiessler/Fabric.git
synced 2026-01-09 22:38:10 -05:00
Compare commits
80 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0150c3a37d | ||
|
|
2a0216b9aa | ||
|
|
a6d14d86b8 | ||
|
|
a9374c128b | ||
|
|
f32b9f81da | ||
|
|
bf3af8e98e | ||
|
|
095c295ee5 | ||
|
|
93ecc9cfea | ||
|
|
e7aaa23fc2 | ||
|
|
197d3454f8 | ||
|
|
50a4f8b491 | ||
|
|
894b4967dd | ||
|
|
9837bd6664 | ||
|
|
6ca1b5dac4 | ||
|
|
c85135c04e | ||
|
|
31e4e42a94 | ||
|
|
196db04fc2 | ||
|
|
b3b1b5a471 | ||
|
|
892439a177 | ||
|
|
ba2e178e03 | ||
|
|
ed298bcedd | ||
|
|
6b04e6e674 | ||
|
|
04c0f6a0a5 | ||
|
|
486ff42b59 | ||
|
|
f7ab484510 | ||
|
|
f50a14305a | ||
|
|
d5f0cd7616 | ||
|
|
67c658f5b4 | ||
|
|
ef3bc03343 | ||
|
|
e31cb2b46a | ||
|
|
6ca7142ea4 | ||
|
|
8b2174897a | ||
|
|
ac5eab0563 | ||
|
|
65414dcc1c | ||
|
|
5db352f5be | ||
|
|
9e7830ff77 | ||
|
|
5945c0e16b | ||
|
|
29ee141822 | ||
|
|
8a69621e87 | ||
|
|
1645b0c4ea | ||
|
|
45205574d5 | ||
|
|
71a5e0394a | ||
|
|
f286936c23 | ||
|
|
9000f92a55 | ||
|
|
8c84d4b3c8 | ||
|
|
1d77afcc44 | ||
|
|
835bc6044b | ||
|
|
ef895a1ab9 | ||
|
|
82039cedaf | ||
|
|
973df61dfd | ||
|
|
661c85d7a6 | ||
|
|
4638f67fb7 | ||
|
|
ab71dbcd4f | ||
|
|
2abdabc100 | ||
|
|
9f78a2c8e1 | ||
|
|
76f78601f2 | ||
|
|
4eaba2dc56 | ||
|
|
2dcd9cb5f7 | ||
|
|
2943872bde | ||
|
|
b901542a48 | ||
|
|
c122ff8960 | ||
|
|
e128d818c4 | ||
|
|
5e9d6d0a91 | ||
|
|
70edf9cbe3 | ||
|
|
e61a0a9391 | ||
|
|
f8ddf98404 | ||
|
|
55219467f3 | ||
|
|
74d4be1ac6 | ||
|
|
9e57f8c6f1 | ||
|
|
3d2903cb47 | ||
|
|
13e9d22ec6 | ||
|
|
01d12c47cf | ||
|
|
c3258a2c3f | ||
|
|
746885e263 | ||
|
|
b25895c1d2 | ||
|
|
e40b1c1f66 | ||
|
|
ef2ec8bffe | ||
|
|
589991e6a6 | ||
|
|
965392ebbd | ||
|
|
6f615baf53 |
@@ -1,5 +1,5 @@
|
||||
# Use official golang image as builder
|
||||
FROM golang:1.23.3-alpine AS builder
|
||||
FROM golang:1.24.2-alpine AS builder
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
|
||||
@@ -1693,8 +1693,87 @@
|
||||
},
|
||||
{
|
||||
"patternName": "extract_wisdom_short",
|
||||
"description": "Extract condensed insightful ideas and recommendations focusing on life wisdom.",
|
||||
"tags": [
|
||||
"EXTRACT",
|
||||
"WISDOM",
|
||||
"SELF"
|
||||
]
|
||||
},
|
||||
{
|
||||
"patternName": "analyze_bill",
|
||||
"description": "Analyze a legislative bill and implications.",
|
||||
"tags": [
|
||||
"ANALYSIS",
|
||||
"BILL"
|
||||
]
|
||||
},
|
||||
{
|
||||
"patternName": "analyze_bill_short",
|
||||
"description": "Consended - Analyze a legislative bill and implications.",
|
||||
"tags": [
|
||||
"ANALYSIS",
|
||||
"BILL"
|
||||
]
|
||||
},
|
||||
{
|
||||
"patternName": "create_coding_feature",
|
||||
"description": "[Description pending]",
|
||||
"tags": []
|
||||
"tags": [
|
||||
"DEVELOPMENT"
|
||||
]
|
||||
},
|
||||
{
|
||||
"patternName": "create_excalidraw_visualization",
|
||||
"description": "Create visualizations using Excalidraw.",
|
||||
"tags": [
|
||||
"VISUALIZATION"
|
||||
]
|
||||
},
|
||||
{
|
||||
"patternName": "create_flash_cards",
|
||||
"description": "Generate flashcards for key concepts and definitions.",
|
||||
"tags": [
|
||||
"LEARNING"
|
||||
]
|
||||
},
|
||||
{
|
||||
"patternName": "create_loe_document",
|
||||
"description": "Create detailed Level of Effort (LOE) estimation documents.",
|
||||
"tags": [
|
||||
"DEVELOPMENT",
|
||||
"BUSINESS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"patternName": "extract_domains",
|
||||
"description": "Extract key content and source.",
|
||||
"tags": [
|
||||
"EXTRACT",
|
||||
"ANALYSIS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"patternName": "extract_main_activities",
|
||||
"description": "Extract and list main events from transcripts.",
|
||||
"tags": [
|
||||
"EXTRACT",
|
||||
"ANALYSIS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"patternName": "find_female_life_partner",
|
||||
"description": "Clarify and summarize partner criteria in direct language.",
|
||||
"tags": [
|
||||
"SELF"
|
||||
]
|
||||
},
|
||||
{
|
||||
"patternName": "youtube_summary",
|
||||
"description": "Summarize YouTube videos with key points and timestamps.",
|
||||
"tags": [
|
||||
"SUMMARIZE"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -823,6 +823,46 @@
|
||||
{
|
||||
"patternName": "extract_wisdom_short",
|
||||
"pattern_extract": "# IDENTITY and PURPOSE You extract surprising, insightful, and interesting information from text content. You are interested in insights related to the purpose and meaning of life, human flourishing, the role of technology in the future of humanity, artificial intelligence and its affect on humans, memes, learning, reading, books, continuous improvement, and similar topics. Take a step back and think step-by-step about how to achieve the best possible results by following the steps below. # STEPS - Extract a summary of the content in 50 words, including who is presenting and the content being discussed into a section called SUMMARY. - Extract 10 to 20 of the most surprising, insightful, and/or interesting ideas from the input in a section called IDEAS:. If there are less than 50 then collect all of them. Make sure you extract at least 20. - Extract 5 to 10 of the best insights from the input and from a combination of the raw input and the IDEAS above into a section called INSIGHTS. These INSIGHTS should be fewer, more refined, more insightful, and more abstracted versions of the best ideas in the content. - Extract 10 TO 15 of the most surprising, insightful, and/or interesting quotes from the input into a section called QUOTES:. Use the exact quote text from the input. - Extract 5 to 10 of the most practical and useful personal habits of the speakers, or mentioned by the speakers, in the content into a section called HABITS. Examples include but aren't limited to: sleep schedule, reading habits, things they always do, things they always avoid, productivity tips, diet, exercise, etc. - Extract 5 to 10 of the most surprising, insightful, and/or interesting valid facts about the greater world that were mentioned in the content into a section called FACTS:. - Extract all mentions of writing, art, tools, projects and other sources of inspiration mentioned by the speakers into a section called REFERENCES. This should include any and all references to something that the speaker mentioned. - Extract the most potent takeaway and recommendation into a section called ONE-SENTENCE TAKEAWAY. This should be a 15-word sentence that captures the most important essence of the content. - Extract the 5 to 10 of the most surprising, insightful, and/or interesting recommendations that can be collected from the content into a section called RECOMMENDATIONS. # OUTPUT INSTRUCTIONS - Only output Markdown. - Write the IDEAS bullets as exactly 16 words. - Write the RECOMMENDATIONS bullets as exactly 16 words. - Write the HABITS bullets as exactly 16 words. - Write the FACTS bullets as exactly 16 words. - Write the INSIGHTS bullets as exactly 16 words. - Extract at least 25 IDEAS from the content. - Extract at least 5 INSIGHTS from the content. - Extract at least 10 items for the other output sections. - Do not give warnings or notes; only output the requested sections. - You use bulleted lists for output, not numbered lists. - Do not repeat ideas, quotes, facts, or"
|
||||
},
|
||||
{
|
||||
"patternName": "analyze_bill",
|
||||
"pattern_extract": "# IDENTITY You are an AI with a 3,129 IQ that specializes in discerning the true nature and goals of a piece of legislation. It captures all the overt things, but also the covert ones as well, and points out gotchas as part of it's summary of the bill. # STEPS 1. Read the entire bill 37 times using different perspectives. 2. Map out all the stuff it's trying to do on a 10 KM by 10K mental whiteboard. 3. Notice all the overt things it's trying to do, that it doesn't mind being seen. 4. Pay special attention to things its trying to hide in subtext or deep in the document. # OUTPUT 1. Give the metadata for the bill, such as who proposed it, when, etc. 2. Create a 24-word summary of the bill and what it's trying to accomplish. 3. Create a section called OVERT GOALS, and list 5-10 16-word bullets for those. 4. Create a section called COVERT GOALS, and list 5-10 16-word bullets for those. 5. Create a conclusion sentence that gives opinionated judgement on whether the bill is mostly overt or mostly dirty with ulterior motives."
|
||||
},
|
||||
{
|
||||
"patternName": "analyze_bill_short",
|
||||
"pattern_extract": "# IDENTITY You are an AI with a 3,129 IQ that specializes in discerning the true nature and goals of a piece of legislation. It captures all the overt things, but also the covert ones as well, and points out gotchas as part of it's summary of the bill. # STEPS 1. Read the entire bill 37 times using different perspectives. 2. Map out all the stuff it's trying to do on a 10 KM by 10K mental whiteboard. 3. Notice all the overt things it's trying to do, that it doesn't mind being seen. 4. Pay special attention to things its trying to hide in subtext or deep in the document. # OUTPUT 1. Give the metadata for the bill, such as who proposed it, when, etc. 2. Create a 16-word summary of the bill and what it's trying to accomplish. 3. Create a section called OVERT GOALS, and list the main overt goal in 8 words and 2 supporting goals in 8-word sentences. 3. Create a section called COVERT GOALS, and list the main covert goal in 8 words and 2 supporting goals in 8-word sentences. 5. Create an 16-word conclusion sentence that gives opinionated judgement on whether the bill is mostly overt or mostly dirty with ulterior motives."
|
||||
},
|
||||
{
|
||||
"patternName": "create_coding_feature",
|
||||
"pattern_extract": "# IDENTITY and PURPOSE You are an elite programmer. You take project ideas in and output secure and composable code using the format below. You always use the latest technology and best practices. Take a deep breath and think step by step about how to best accomplish this goal using the following steps. Input is a JSON file with the following format: Example input: ```json [ { \"type\": \"directory\", \"name\": \".\", \"contents\": [ { \"type\": \"file\", \"name\": \"README.md\", \"content\": \"This is the README.md file content\" }, { \"type\": \"file\", \"name\": \"system.md\", \"content\": \"This is the system.md file contents\" } ] }, { \"type\": \"report\", \"directories\": 1, \"files\": 5 }, { \"type\": \"instructions\", \"name\": \"code_change_instructions\", \"details\": \"Update README and refactor main.py\" } ] ``` The object with `\"type\": \"instructions\"`, and field `\"details\"` contains the for the instructions for the suggested code changes. The `\"name\"` field is always `\"code_change_instructions\"` The `\"details\"` field above, with type `\"instructions\"` contains the instructions for the suggested code changes. ## File Management Interface Instructions You have access to a powerful file management system with the following capabilities: ### File Creation and Modification - Use the **EXACT** JSON format below to define files that you want to be changed - If the file listed does not exist, it will be created - If a directory listed does not exist, it will be created - If the file already exists, it will be overwritten - It is **not possible** to delete files ```plaintext __CREATE_CODING_FEATURE_FILE_CHANGES__ [ { \"operation\": \"create\", \"path\": \"README.md\", \"content\": \"This is the new README.md file content\" }, { \"operation\": \"update\", \"path\": \"src/main.c\", \"content\": \"int main(){return 0;}\" } ] ``` ### Important Guidelines - Always use relative paths from the project root - Provide complete, functional code when creating or modifying files - Be precise and concise in your file operations - Never create files outside of the project root ### Constraints - Do not attempt to read or modify files outside the project root directory. - Ensure code follows best practices and is production-ready. - Handle potential errors gracefully in your code suggestions. - Do not trust external input to applications, assume users are malicious. ### Workflow 1. Analyze the user's request 2. Determine necessary file operations 3. Provide clear, executable file creation/modification instructions 4. Explain the purpose and functionality of proposed changes ## Output Sections - Output a summary of the file changes - Output directory and file changes according to File Management Interface Instructions, in a json array marked by `__CREATE_CODING_FEATURE_FILE_CHANGES__` - Be exact in the `__CREATE_CODING_FEATURE_FILE_CHANGES__` section, and do not deviate from the proposed JSON format. - **never** omit the `__CREATE_CODING_FEATURE_FILE_CHANGES__` section. - If the proposed changes change how the project is built and installed, document these changes in the projects README.md - Implement build configurations changes if needed, prefer ninja if nothing already exists in the project, or is otherwise specified. - Document new dependencies according to best practices for the language used in the project. - Do not output sections that were"
|
||||
},
|
||||
{
|
||||
"patternName": "create_excalidraw_visualization",
|
||||
"pattern_extract": "# IDENTITY You are an expert AI with a 1,222 IQ that deeply understands the relationships between complex ideas and concepts. You are also an expert in the Excalidraw tool and schema. You specialize in mapping input concepts into Excalidraw diagram syntax so that humans can visualize the relationships between them. # STEPS 1. Deeply study the input. 2. Think for 47 minutes about each of the sections in the input. 3. Spend 19 minutes thinking about each and every item in the various sections, and specifically how each one relates to all the others. E.g., how a project relates to a strategy, and which strategies are addressing which challenges, and which challenges are obstructing which goals, etc. 4. Build out this full mapping in on a 9KM x 9KM whiteboard in your mind. 5. Analyze and improve this mapping for 13 minutes. # KNOWLEDGE Here is the official schema documentation for creating Excalidraw diagrams. Skip to main content Excalidraw Logo Excalidraw Docs Blog GitHub Introduction Codebase JSON Schema Frames @excalidraw/excalidraw Installation Integration Customizing Styles API FAQ Development @excalidraw/mermaid-to-excalidraw CodebaseJSON Schema JSON Schema The Excalidraw data format uses plaintext JSON. Excalidraw files When saving an Excalidraw scene locally to a file, the JSON file (.excalidraw) is using the below format. Attributes Attribute Description Value type The type of the Excalidraw schema \"excalidraw\" version The version of the Excalidraw schema number source The source URL of the Excalidraw application \"https://excalidraw.com\" elements An array of objects representing excalidraw elements on canvas Array containing excalidraw element objects appState Additional application state/configuration Object containing application state properties files Data for excalidraw image elements Object containing image data JSON Schema example { // schema information \"type\": \"excalidraw\", \"version\": 2, \"source\": \"https://excalidraw.com\", // elements on canvas \"elements\": [ // example element { \"id\": \"pologsyG-tAraPgiN9xP9b\", \"type\": \"rectangle\", \"x\": 928, \"y\": 319, \"width\": 134, \"height\": 90 /* ...other element properties */ } /* other elements */ ], // editor state (canvas config, preferences, ...) \"appState\": { \"gridSize\": 20, \"viewBackgroundColor\": \"#ffffff\" }, // files data for \"image\" elements, using format `{ [fileId]: fileData }` \"files\": { // example of an image data object \"3cebd7720911620a3938ce77243696149da03861\": { \"mimeType\": \"image/png\", \"id\": \"3cebd7720911620a3938c.77243626149da03861\", \"dataURL\": \"data:image/png;base64,iVBORWOKGgoAAAANSUhEUgA=\", \"created\": 1690295874454, \"lastRetrieved\": 1690295874454 } /* ...other image data objects */ } } Excalidraw clipboard format When copying selected excalidraw elements to clipboard, the JSON schema is similar to .excalidraw format, except it differs in attributes. Attributes Attribute Description Example Value type The type of the Excalidraw document. \"excalidraw/clipboard\" elements An array of objects representing excalidraw elements on canvas. Array containing excalidraw element objects (see example below) files Data for excalidraw image elements. Object containing image data Edit this page Previous Contributing Next Frames Excalidraw files Attributes JSON Schema example Excalidraw clipboard format Attributes Docs Get Started Community Discord Twitter Linkedin More Blog GitHub Copyright © 2023 Excalidraw community. Built with Docusaurus ❤️ # OUTPUT 1. Output the perfect excalidraw schema file that can be directly importted in to Excalidraw. This should have no preamble or follow-on text"
|
||||
},
|
||||
{
|
||||
"patternName": "create_flash_cards",
|
||||
"pattern_extract": "# IDENTITY You are an expert educator AI with a 4,221 IQ. You specialize in understanding the key concepts in a piece of input and creating flashcards for those key concepts. # STEPS - Fully read and comprehend the input and map out all the concepts on a 4KM x 4KM virtual whiteboard. - Make a list of the key concepts, definitions, terms, etc. that are associated with the input. - Create flashcards for each key concept, definition, term, etc. that you have identified. - The flashcard should be a question of 8-16 words and an answer of up to 32 words. # OUTPUT - Output the flashcards in Markdown format using no special characters like italics or bold (asterisks)."
|
||||
},
|
||||
{
|
||||
"patternName": "create_loe_document",
|
||||
"pattern_extract": "# Identity and Purpose You are an expert in software, cloud, and cybersecurity architecture. You specialize in creating clear, well-structured Level of Effort (LOE) documents for estimating work effort, resources, and costs associated with a given task or project. # Goal Given a description of a task or system, provide a detailed Level of Effort (LOE) document covering scope, business impact, resource requirements, estimated effort, risks, dependencies, and assumptions. # Steps 1. Analyze the input task thoroughly to ensure full comprehension. 2. Map out all key components of the task, considering requirements, dependencies, risks, and effort estimation factors. 3. Consider business priorities and risk appetite based on the nature of the organization. 4. Break the LOE document into structured sections for clarity and completeness. --- # Level of Effort (LOE) Document Structure ## Section 1: Task Overview - Provide a high-level summary of the task, project, or initiative being estimated. - Define objectives and expected outcomes. - Identify key stakeholders and beneficiaries. ## Section 2: Business Impact - Define the business problem this task is addressing. - List the expected benefits and value to the organization. - Highlight any business risks or regulatory considerations. ## Section 3: Scope & Deliverables - Outline in-scope and out-of-scope work. - Break down major deliverables and milestones. - Specify acceptance criteria for successful completion. ## Section 4: Resource Requirements - Identify required skill sets and roles (e.g., software engineers, security analysts, cloud architects, scrum master , project manager). - Estimate the number of personnel needed , in tabular format. - List tooling, infrastructure, or licenses required. ## Section 5: Estimated Effort - Break down tasks into granular units (e.g., design, development, testing, deployment). - Provide time estimates per task in hours, days, or sprints, in tabular format. - Aggregate total effort for the entire task or project. - Include buffer time for unforeseen issues or delays. - Use T-shirt sizing (S/M/L/XL) or effort points to classify work complexity. ## Section 6: Dependencies - List external dependencies (e.g., APIs, third-party vendors, internal teams). - Specify hardware/software requirements that may impact effort. ## Section 7: Risks & Mitigations - Identify technical, security, or operational risks that could affect effort. - Propose mitigation strategies to address risks. - Indicate if risks could lead to effort overruns. ## Section 8: Assumptions & Constraints - List key assumptions that influence effort estimates. - Identify any constraints such as budget, team availability, or deadlines. ## Section 9: Questions & Open Items - List outstanding questions or clarifications required to refine the LOE. - Highlight areas needing further input from stakeholders. --- # Output Instructions - Output the LOE document in valid Markdown format. - Do not use bold or italic formatting. - Do not provide commentary or disclaimers, just execute the request. # Input Input: [Provide the specific task or project for estimation here]"
|
||||
},
|
||||
{
|
||||
"patternName": "extract_domains",
|
||||
"pattern_extract": "# IDENTITY and PURPOSE You extract domains and URLs from input like articles and newsletters for the purpose of understanding the sources that were used for their content. # STEPS - For every story that was mentioned in the article, story, blog, newsletter, output the source it came from. - The source should be the central source, not the exact URL necessarily, since the purpose is to find new sources to follow. - As such, if it's a person, link their profile that was in the input. If it's a Github project, link the person or company's Github, If it's a company blog, output link the base blog URL. If it's a paper, link the publication site. Etc. - Only output each source once. - Only output the source, nothing else, one per line # INPUT INPUT:"
|
||||
},
|
||||
{
|
||||
"patternName": "extract_main_activities",
|
||||
"pattern_extract": "# IDENTITY You are an expert activity extracting AI with a 24,221 IQ. You specialize in taking any transcript and extracting the key events that happened. # STEPS - Fully understand the input transcript or log. - Extract the key events and map them on a 24KM x 24KM virtual whiteboard. - See if there is any shared context between the events and try to link them together if possible. # OUTPUT - Write a 16 word summary sentence of the activity. - Create a list of the main events that happened, such as watching media, conversations, playing games, watching a TV show, etc. # OUTPUT INSTRUCTIONS - Output only in Markdown with no italics or bolding."
|
||||
},
|
||||
{
|
||||
"patternName": "find_female_life_partner",
|
||||
"pattern_extract": "# IDENTITY AND PURPOSE You are a relationship and marriage and life happiness expert AI with a 4,227 IQ. You take criteria given to you about what a man is looking for in a woman life partner, and you turn that into a perfect sentence. # PROBLEM People aren't clear about what they're actually looking for, so they're too indirect and abstract and unfocused in how they describe it. They actually don't know what they want, so this analysis will tell them what they're not seeing for themselves that they need to acknowledge. # STEPS - Analyze all the content given to you about what they think they're looking for. - Figure out what they're skirting around and not saying directly. - Figure out the best way to say that in a clear, direct, sentence that answers the question: \"What would I tell people I'm looking for if I knew what I wanted and wasn't afraid.\" - Write the perfect 24-word sentence in these versions: 1. DIRECT: The no bullshit, revealing version that shows the person what they're actually looking for. Only 8 words in extremely straightforward language. 2. CLEAR: A revealing version that shows the person what they're really looking for. 3. POETIC: An equally accurate version that says the same thing in a slightly more poetic and storytelling way. # OUTPUT INSTRUCTIONS - Only output those two sentences, nothing else."
|
||||
},
|
||||
{
|
||||
"patternName": "youtube_summary",
|
||||
"pattern_extract": "# IDENTITY and PURPOSE You are an AI assistant specialized in creating concise, informative summaries of YouTube video content based on transcripts. Your role is to analyze video transcripts, identify key points, main themes, and significant moments, then organize this information into a well-structured summary that includes relevant timestamps. You excel at distilling lengthy content into digestible summaries while preserving the most valuable information and maintaining the original flow of the video. Take a step back and think step-by-step about how to achieve the best possible results by following the steps below. ## STEPS - Carefully read through the entire transcript to understand the overall content and structure of the video - Identify the main topic and purpose of the video - Note key points, important concepts, and significant moments throughout the transcript - Pay attention to natural transitions or segment changes in the video - Extract relevant timestamps for important moments or topic changes - Organize information into a logical structure that follows the video's progression - Create a concise summary that captures the essence of the video - Include timestamps alongside key points to allow easy navigation - Ensure the summary is comprehensive yet concise ## OUTPUT INSTRUCTIONS - Only output Markdown - Begin with a brief overview of the video's main topic and purpose - Structure the summary with clear headings and subheadings that reflect the video's organization - Include timestamps in [HH:MM:SS] format before each key point or section - Keep the summary concise but comprehensive, focusing on the most valuable information - Use bullet points for lists of related points when appropriate - Bold or italicize particularly important concepts or takeaways - End with a brief conclusion summarizing the video's main message or call to action - Ensure you follow ALL these instructions when creating your output. ## INPUT INPUT:"
|
||||
}
|
||||
]
|
||||
}
|
||||
67
README.md
67
README.md
@@ -1,4 +1,7 @@
|
||||
<div align="center">
|
||||
Fabric is graciously supported by…
|
||||
|
||||
[](https://warp.dev/fabric)
|
||||
|
||||
<img src="./images/fabric-logo-gif.gif" alt="fabriclogo" width="400" height="400"/>
|
||||
|
||||
@@ -56,6 +59,10 @@
|
||||
- [Save your files in markdown using aliases](#save-your-files-in-markdown-using-aliases)
|
||||
- [Migration](#migration)
|
||||
- [Upgrading](#upgrading)
|
||||
- [Shell Completions](#shell-completions)
|
||||
- [Zsh Completion](#zsh-completion)
|
||||
- [Bash Completion](#bash-completion)
|
||||
- [Fish Completion](#fish-completion)
|
||||
- [Usage](#usage)
|
||||
- [Our approach to prompting](#our-approach-to-prompting)
|
||||
- [Examples](#examples)
|
||||
@@ -73,15 +80,16 @@
|
||||
- [Clipboard Support](#clipboard-support)
|
||||
- [Meta](#meta)
|
||||
- [Primary contributors](#primary-contributors)
|
||||
- [Contributors](#contributors)
|
||||
|
||||
<br />
|
||||
|
||||
## Updates
|
||||
|
||||
> [!NOTE]
|
||||
> February 24, 2025
|
||||
> April 16, 2025
|
||||
>
|
||||
> - Fabric now supports Sonnet 3.7! Update and use `-S` to select it as your default if you want, or just use the shortcut `-m claude-3-7-sonnet-latest`. Enjoy!
|
||||
> - Fabric now supports Grok (from XAI)! Update and use `-S` to select it as your default if you want, or just use the shortcut `-m grok-3-beta`. Enjoy!
|
||||
|
||||
## What and why
|
||||
|
||||
@@ -407,6 +415,48 @@ The great thing about Go is that it's super easy to upgrade. Just run the same c
|
||||
go install github.com/danielmiessler/fabric@latest
|
||||
```
|
||||
|
||||
### Shell Completions
|
||||
|
||||
Fabric provides shell completion scripts for Zsh, Bash, and Fish
|
||||
shells, making it easier to use the CLI by providing tab completion
|
||||
for commands and options.
|
||||
|
||||
#### Zsh Completion
|
||||
|
||||
To enable Zsh completion:
|
||||
|
||||
```bash
|
||||
# Copy the completion file to a directory in your $fpath
|
||||
mkdir -p ~/.zsh/completions
|
||||
cp completions/_fabric ~/.zsh/completions/
|
||||
|
||||
# Add the directory to fpath in your .zshrc before compinit
|
||||
echo 'fpath=(~/.zsh/completions $fpath)' >> ~/.zshrc
|
||||
echo 'autoload -Uz compinit && compinit' >> ~/.zshrc
|
||||
```
|
||||
|
||||
#### Bash Completion
|
||||
|
||||
To enable Bash completion:
|
||||
|
||||
```bash
|
||||
# Source the completion script in your .bashrc
|
||||
echo 'source /path/to/fabric/completions/fabric.bash' >> ~/.bashrc
|
||||
|
||||
# Or copy to the system-wide bash completion directory
|
||||
sudo cp completions/fabric.bash /etc/bash_completion.d/
|
||||
```
|
||||
|
||||
#### Fish Completion
|
||||
|
||||
To enable Fish completion:
|
||||
|
||||
```bash
|
||||
# Copy the completion file to the fish completions directory
|
||||
mkdir -p ~/.config/fish/completions
|
||||
cp completions/fabric.fish ~/.config/fish/completions/
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Once you have it all set up, here's how to use it.
|
||||
@@ -415,7 +465,7 @@ Once you have it all set up, here's how to use it.
|
||||
fabric -h
|
||||
```
|
||||
|
||||
```bash
|
||||
```plaintext
|
||||
|
||||
Usage:
|
||||
fabric [OPTIONS]
|
||||
@@ -465,6 +515,7 @@ Application Options:
|
||||
--serve Serve the Fabric Rest API
|
||||
--serveOllama Serve the Fabric Rest API with ollama endpoints
|
||||
--address= The address to bind the REST API (default: :8080)
|
||||
--api-key= API key used to secure server routes
|
||||
--config= Path to YAML config file
|
||||
--version Print current version
|
||||
--listextensions List all registered extensions
|
||||
@@ -472,6 +523,8 @@ Application Options:
|
||||
--rmextension= Remove a registered extension by name
|
||||
--strategy= Choose a strategy from the available strategies
|
||||
--liststrategies List all strategies
|
||||
--listvendors List all vendors
|
||||
--shell-complete-list Output raw list without headers/formatting (for shell completion)
|
||||
|
||||
Help Options:
|
||||
-h, --help Show this help message
|
||||
@@ -713,6 +766,14 @@ The Streamlit UI supports clipboard operations across different platforms:
|
||||
<a href="https://github.com/sbehrens"><img src="https://avatars.githubusercontent.com/u/688589?v=4" title="Scott Behrens" width="50" height="50"></a>
|
||||
<a href="https://github.com/agu3rra"><img src="https://avatars.githubusercontent.com/u/10410523?v=4" title="Andre Guerra" width="50" height="50"></a>
|
||||
|
||||
### Contributors
|
||||
|
||||
<a href="https://github.com/danielmiessler/fabric/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=danielmiessler/fabric" />
|
||||
</a>
|
||||
|
||||
Made with [contrib.rocks](https://contrib.rocks).
|
||||
|
||||
`fabric` was created by <a href="https://danielmiessler.com/subscribe" target="_blank">Daniel Miessler</a> in January of 2024.
|
||||
<br /><br />
|
||||
<a href="https://twitter.com/intent/user?screen_name=danielmiessler"></a>
|
||||
|
||||
@@ -1,20 +1,25 @@
|
||||
# YAML Configuration Support
|
||||
|
||||
## Overview
|
||||
|
||||
Fabric now supports YAML configuration files for commonly used options. This allows users to persist settings and share configurations across multiple runs.
|
||||
|
||||
## Usage
|
||||
|
||||
Use the `--config` flag to specify a YAML configuration file:
|
||||
|
||||
```bash
|
||||
fabric --config ~/.config/fabric/config.yaml "Tell me about APIs"
|
||||
```
|
||||
|
||||
## Configuration Precedence
|
||||
|
||||
1. CLI flags (highest priority)
|
||||
2. YAML config values
|
||||
3. Default values (lowest priority)
|
||||
|
||||
## Supported Configuration Options
|
||||
|
||||
```yaml
|
||||
# Model selection
|
||||
model: gpt-4
|
||||
@@ -36,6 +41,7 @@ raw: false
|
||||
```
|
||||
|
||||
## Rules and Behavior
|
||||
|
||||
- Only long flag names are supported in YAML (e.g., `temperature` not `-t`)
|
||||
- CLI flags always override YAML values
|
||||
- Unknown YAML declarations are ignored
|
||||
@@ -43,12 +49,15 @@ raw: false
|
||||
- The order of YAML declarations doesn't matter
|
||||
|
||||
## Type Conversions
|
||||
|
||||
The following string-to-type conversions are supported:
|
||||
|
||||
- String to number: `"42"` → `42`
|
||||
- String to float: `"42.5"` → `42.5`
|
||||
- String to boolean: `"true"` → `true`
|
||||
|
||||
## Example Config
|
||||
|
||||
```yaml
|
||||
# ~/.config/fabric/config.yaml
|
||||
model: gpt-4
|
||||
@@ -61,8 +70,8 @@ frequencypenalty: 0.2
|
||||
```
|
||||
|
||||
## CLI Override Example
|
||||
|
||||
```bash
|
||||
# Override temperature from config
|
||||
fabric --config ~/.config/fabric/config.yaml --temperature 0.9 "Query"
|
||||
```
|
||||
|
||||
|
||||
19
cli/cli.go
19
cli/cli.go
@@ -93,7 +93,7 @@ func Cli(version string) (err error) {
|
||||
}
|
||||
|
||||
if currentFlags.ListPatterns {
|
||||
err = fabricDb.Patterns.ListNames()
|
||||
err = fabricDb.Patterns.ListNames(currentFlags.ShellCompleteOutput)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -102,17 +102,17 @@ func Cli(version string) (err error) {
|
||||
if models, err = registry.VendorManager.GetModels(); err != nil {
|
||||
return
|
||||
}
|
||||
models.Print()
|
||||
models.Print(currentFlags.ShellCompleteOutput)
|
||||
return
|
||||
}
|
||||
|
||||
if currentFlags.ListAllContexts {
|
||||
err = fabricDb.Contexts.ListNames()
|
||||
err = fabricDb.Contexts.ListNames(currentFlags.ShellCompleteOutput)
|
||||
return
|
||||
}
|
||||
|
||||
if currentFlags.ListAllSessions {
|
||||
err = fabricDb.Sessions.ListNames()
|
||||
err = fabricDb.Sessions.ListNames(currentFlags.ShellCompleteOutput)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -160,7 +160,12 @@ func Cli(version string) (err error) {
|
||||
}
|
||||
|
||||
if currentFlags.ListStrategies {
|
||||
err = registry.Strategies.ListStrategies()
|
||||
err = registry.Strategies.ListStrategies(currentFlags.ShellCompleteOutput)
|
||||
return
|
||||
}
|
||||
|
||||
if currentFlags.ListVendors {
|
||||
err = registry.ListVendors(os.Stdout)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -211,7 +216,9 @@ func Cli(version string) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
messageTools, err = processYoutubeVideo(currentFlags, registry, videoId)
|
||||
if messageTools, err = processYoutubeVideo(currentFlags, registry, videoId); err != nil {
|
||||
return
|
||||
}
|
||||
if !currentFlags.IsChatRequest() {
|
||||
err = currentFlags.WriteOutput(messageTools)
|
||||
return
|
||||
|
||||
@@ -72,6 +72,8 @@ type Flags struct {
|
||||
RemoveExtension string `long:"rmextension" description:"Remove a registered extension by name"`
|
||||
Strategy string `long:"strategy" description:"Choose a strategy from the available strategies" default:""`
|
||||
ListStrategies bool `long:"liststrategies" description:"List all strategies"`
|
||||
ListVendors bool `long:"listvendors" description:"List all vendors"`
|
||||
ShellCompleteOutput bool `long:"shell-complete-list" description:"Output raw list without headers/formatting (for shell completion)"`
|
||||
}
|
||||
|
||||
var debug = false
|
||||
@@ -334,7 +336,6 @@ func (o *Flags) BuildChatRequest(Meta string) (ret *common.ChatRequest, err erro
|
||||
|
||||
func (o *Flags) AppendMessage(message string) {
|
||||
o.Message = AppendMessage(o.Message, message)
|
||||
return
|
||||
}
|
||||
|
||||
func (o *Flags) IsChatRequest() (ret bool) {
|
||||
|
||||
@@ -2,6 +2,8 @@ package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
@@ -40,13 +42,43 @@ func (o *GroupsItemsSelector[I]) AddGroupItems(group string, items ...I) {
|
||||
o.GroupsItems = append(o.GroupsItems, &GroupItems[I]{group, items})
|
||||
}
|
||||
|
||||
// getSortedGroupsItems returns a new slice of GroupItems with both groups and their items
|
||||
// sorted alphabetically in a case-insensitive manner. The original GroupsItems are not modified.
|
||||
func (o *GroupsItemsSelector[I]) getSortedGroupsItems() []*GroupItems[I] {
|
||||
// Copy and sort groups (case‑insensitive)
|
||||
sortedGroupsItems := make([]*GroupItems[I], len(o.GroupsItems))
|
||||
copy(sortedGroupsItems, o.GroupsItems)
|
||||
sort.SliceStable(sortedGroupsItems, func(i, j int) bool {
|
||||
return strings.ToLower(sortedGroupsItems[i].Group) < strings.ToLower(sortedGroupsItems[j].Group)
|
||||
})
|
||||
|
||||
// For each group, sort its items
|
||||
for i, groupItems := range sortedGroupsItems {
|
||||
sortedItems := make([]I, len(groupItems.Items))
|
||||
copy(sortedItems, groupItems.Items)
|
||||
sort.SliceStable(sortedItems, func(i, j int) bool {
|
||||
return strings.ToLower(o.GetItemKey(sortedItems[i])) < strings.ToLower(o.GetItemKey(sortedItems[j]))
|
||||
})
|
||||
|
||||
// Create a new GroupItems with the sorted items
|
||||
sortedGroupsItems[i] = &GroupItems[I]{
|
||||
Group: groupItems.Group,
|
||||
Items: sortedItems,
|
||||
}
|
||||
}
|
||||
|
||||
return sortedGroupsItems
|
||||
}
|
||||
|
||||
func (o *GroupsItemsSelector[I]) GetGroupAndItemByItemNumber(number int) (group string, item I, err error) {
|
||||
var currentItemNumber int
|
||||
found := false
|
||||
|
||||
for _, groupItems := range o.GroupsItems {
|
||||
if currentItemNumber+groupItems.Count() < number {
|
||||
currentItemNumber += groupItems.Count()
|
||||
sortedGroupsItems := o.getSortedGroupsItems()
|
||||
|
||||
for _, groupItems := range sortedGroupsItems {
|
||||
if currentItemNumber+len(groupItems.Items) < number {
|
||||
currentItemNumber += len(groupItems.Items)
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -59,6 +91,10 @@ func (o *GroupsItemsSelector[I]) GetGroupAndItemByItemNumber(number int) (group
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if found {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
@@ -67,19 +103,30 @@ func (o *GroupsItemsSelector[I]) GetGroupAndItemByItemNumber(number int) (group
|
||||
return
|
||||
}
|
||||
|
||||
func (o *GroupsItemsSelector[I]) Print() {
|
||||
fmt.Printf("\n%v:\n", o.SelectionLabel)
|
||||
func (o *GroupsItemsSelector[I]) Print(shellCompleteList bool) {
|
||||
// Only print the section header if not in plain output mode
|
||||
if !shellCompleteList {
|
||||
fmt.Printf("\n%v:\n", o.SelectionLabel)
|
||||
}
|
||||
|
||||
var currentItemIndex int
|
||||
for _, groupItems := range o.GroupsItems {
|
||||
fmt.Println()
|
||||
fmt.Printf("%s\n", groupItems.Group)
|
||||
fmt.Println()
|
||||
sortedGroupsItems := o.getSortedGroupsItems()
|
||||
|
||||
for _, groupItems := range sortedGroupsItems {
|
||||
if !shellCompleteList {
|
||||
fmt.Println()
|
||||
fmt.Printf("%s\n\n", groupItems.Group)
|
||||
}
|
||||
|
||||
for _, item := range groupItems.Items {
|
||||
currentItemIndex++
|
||||
fmt.Printf("\t[%d]\t%s\n", currentItemIndex, o.GetItemKey(item))
|
||||
|
||||
if shellCompleteList {
|
||||
// plain mode: "index key"
|
||||
fmt.Printf("%s\n", o.GetItemKey(item))
|
||||
} else {
|
||||
// formatted mode: "[index] key"
|
||||
fmt.Printf("\t[%d]\t%s\n", currentItemIndex, o.GetItemKey(item))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
111
completions/_fabric
Normal file
111
completions/_fabric
Normal file
@@ -0,0 +1,111 @@
|
||||
#compdef fabric
|
||||
|
||||
# Zsh completion for fabric CLI
|
||||
# Place this file in a directory in your $fpath (e.g. /usr/local/share/zsh/site-functions)
|
||||
|
||||
_fabric_patterns() {
|
||||
local -a patterns
|
||||
patterns=(${(f)"$(fabric --listpatterns --shell-complete-list 2>/dev/null)"})
|
||||
compadd -X "Patterns:" ${patterns}
|
||||
}
|
||||
|
||||
_fabric_models() {
|
||||
local -a models
|
||||
models=(${(f)"$(fabric --listmodels --shell-complete-list 2>/dev/null)"})
|
||||
compadd -X "Models:" ${models}
|
||||
}
|
||||
_fabric_contexts() {
|
||||
local -a contexts
|
||||
contexts=(${(f)"$(fabric --listcontexts --shell-complete-list 2>/dev/null)"})
|
||||
compadd -X "Contexts:" ${contexts}
|
||||
}
|
||||
_fabric_sessions() {
|
||||
local -a sessions
|
||||
sessions=(${(f)"$(fabric --listsessions --shell-complete-list 2>/dev/null)"})
|
||||
compadd -X "Sessions:" ${sessions}
|
||||
}
|
||||
_fabric_strategies() {
|
||||
local -a strategies
|
||||
strategies=(${(f)"$(fabric --liststrategies --shell-complete-list 2>/dev/null)"})
|
||||
compadd -X "Strategies:" ${strategies}
|
||||
}
|
||||
|
||||
_fabric_extensions() {
|
||||
local -a extensions
|
||||
extensions=(${(f)"$(fabric --listextensions --shell-complete-list 2>/dev/null)"})
|
||||
compadd -X "Extensions:" ${extensions}
|
||||
'(-L --listmodels)'{-L,--listmodels}'[List all available models]:list models:_fabric_models' \
|
||||
'(-x --listcontexts)'{-x,--listcontexts}'[List all contexts]:list contexts:_fabric_contexts' \
|
||||
'(-X --listsessions)'{-X,--listsessions}'[List all sessions]:list sessions:_fabric_sessions' \
|
||||
'(--listextensions)--listextensions[List all registered extensions]' \
|
||||
'(--liststrategies)--liststrategies[List all strategies]:list strategies:_fabric_strategies' \
|
||||
'(--listvendors)--listvendors[List all vendors]' \
|
||||
vendors=(${(f)"$(fabric --listvendors 2>/dev/null)"})
|
||||
compadd -X "Vendors:" ${vendors}
|
||||
}
|
||||
|
||||
_fabric() {
|
||||
local curcontext="$curcontext" state line
|
||||
typeset -A opt_args
|
||||
|
||||
_arguments -C \
|
||||
'(-p --pattern)'{-p,--pattern}'[Choose a pattern from the available patterns]:pattern:_fabric_patterns' \
|
||||
'(-v --variable)'{-v,--variable}'[Values for pattern variables, e.g. -v=#role:expert -v=#points:30]:variable:' \
|
||||
'(-C --context)'{-C,--context}'[Choose a context from the available contexts]:context:_fabric_contexts' \
|
||||
'(--session)--session[Choose a session from the available sessions]:session:_fabric_sessions' \
|
||||
'(-a --attachment)'{-a,--attachment}'[Attachment path or URL (e.g. for OpenAI image recognition messages)]:file:_files' \
|
||||
'(-S --setup)'{-S,--setup}'[Run setup for all reconfigurable parts of fabric]' \
|
||||
'(-t --temperature)'{-t,--temperature}'[Set temperature (default: 0.7)]:temperature:' \
|
||||
'(-T --topp)'{-T,--topp}'[Set top P (default: 0.9)]:topp:' \
|
||||
'(-s --stream)'{-s,--stream}'[Stream]' \
|
||||
'(-P --presencepenalty)'{-P,--presencepenalty}'[Set presence penalty (default: 0.0)]:presence penalty:' \
|
||||
'(-r --raw)'{-r,--raw}'[Use the defaults of the model without sending chat options]' \
|
||||
'(-F --frequencypenalty)'{-F,--frequencypenalty}'[Set frequency penalty (default: 0.0)]:frequency penalty:' \
|
||||
'(-l --listpatterns)'{-l,--listpatterns}'[List all patterns]' \
|
||||
'(-L --listmodels)'{-L,--listmodels}'[List all available models]' \
|
||||
'(-x --listcontexts)'{-x,--listcontexts}'[List all contexts]' \
|
||||
'(-X --listsessions)'{-X,--listsessions}'[List all sessions]' \
|
||||
'(-U --updatepatterns)'{-U,--updatepatterns}'[Update patterns]' \
|
||||
'(-c --copy)'{-c,--copy}'[Copy to clipboard]' \
|
||||
'(-m --model)'{-m,--model}'[Choose model]:model:_fabric_models' \
|
||||
'(--modelContextLength)--modelContextLength[Model context length (only affects ollama)]:length:' \
|
||||
'(-o --output)'{-o,--output}'[Output to file]:file:_files' \
|
||||
'(--output-session)--output-session[Output the entire session to the output file]' \
|
||||
'(-n --latest)'{-n,--latest}'[Number of latest patterns to list (default: 0)]:number:' \
|
||||
'(-d --changeDefaultModel)'{-d,--changeDefaultModel}'[Change default model]' \
|
||||
'(-y --youtube)'{-y,--youtube}'[YouTube video or play list URL]:youtube url:' \
|
||||
'(--playlist)--playlist[Prefer playlist over video if both ids are present in the URL]' \
|
||||
'(--transcript)--transcript[Grab transcript from YouTube video and send to chat]' \
|
||||
'(--transcript-with-timestamps)--transcript-with-timestamps[Grab transcript from YouTube video with timestamps]' \
|
||||
'(--comments)--comments[Grab comments from YouTube video and send to chat]' \
|
||||
'(--metadata)--metadata[Output video metadata]' \
|
||||
'(-g --language)'{-g,--language}'[Specify the Language Code for the chat, e.g. -g=en -g=zh]:language:' \
|
||||
'(-u --scrape_url)'{-u,--scrape_url}'[Scrape website URL to markdown using Jina AI]:url:' \
|
||||
'(-q --scrape_question)'{-q,--scrape_question}'[Search question using Jina AI]:question:' \
|
||||
'(-e --seed)'{-e,--seed}'[Seed to be used for LMM generation]:seed:' \
|
||||
'(-w --wipecontext)'{-w,--wipecontext}'[Wipe context]:context:_fabric_contexts' \
|
||||
'(-W --wipesession)'{-W,--wipesession}'[Wipe session]:session:_fabric_sessions' \
|
||||
'(--printcontext)--printcontext[Print context]:context:_fabric_contexts' \
|
||||
'(--printsession)--printsession[Print session]:session:_fabric_sessions' \
|
||||
'(--readability)--readability[Convert HTML input into a clean, readable view]' \
|
||||
'(--input-has-vars)--input-has-vars[Apply variables to user input]' \
|
||||
'(--dry-run)--dry-run[Show what would be sent to the model without actually sending it]' \
|
||||
'(--serve)--serve[Serve the Fabric Rest API]' \
|
||||
'(--serveOllama)--serveOllama[Serve the Fabric Rest API with ollama endpoints]' \
|
||||
'(--address)--address[The address to bind the REST API (default: :8080)]:address:' \
|
||||
'(--api-key)--api-key[API key used to secure server routes]:api-key:' \
|
||||
'(--config)--config[Path to YAML config file]:config file:_files -g "*.yaml *.yml"' \
|
||||
'(--version)--version[Print current version]' \
|
||||
'(--listextensions)--listextensions[List all registered extensions]' \
|
||||
'(--addextension)--addextension[Register a new extension from config file path]:config file:_files -g "*.yaml *.yml"' \
|
||||
'(--rmextension)--rmextension[Remove a registered extension by name]:extension:_fabric_extensions' \
|
||||
'(--strategy)--strategy[Choose a strategy from the available strategies]:strategy:_fabric_strategies' \
|
||||
'(--liststrategies)--liststrategies[List all strategies]' \
|
||||
'(--listvendors)--listvendors[List all vendors]' \
|
||||
'(--shell-complete-list)--shell-complete-list[Output raw list without headers/formatting (for shell completion)]' \
|
||||
'(-h --help)'{-h,--help}'[Show this help message]' \
|
||||
'*:arguments:'
|
||||
}
|
||||
|
||||
_fabric "$@"
|
||||
|
||||
90
completions/fabric.bash
Normal file
90
completions/fabric.bash
Normal file
@@ -0,0 +1,90 @@
|
||||
# Bash completion for fabric CLI
|
||||
#
|
||||
# Installation:
|
||||
# 1. Place this file in a standard completion directory, e.g.,
|
||||
# - /etc/bash_completion.d/
|
||||
# - /usr/local/etc/bash_completion.d/
|
||||
# - ~/.local/share/bash-completion/completions/
|
||||
# 2. Or, source it directly in your ~/.bashrc or ~/.bash_profile:
|
||||
# source /path/to/fabric.bash
|
||||
|
||||
_fabric() {
|
||||
local cur prev words cword
|
||||
_get_comp_words_by_ref -n : cur prev words cword
|
||||
|
||||
# Define all possible options/flags
|
||||
local opts="--pattern -p --variable -v --context -C --session --attachment -a --setup -S --temperature -t --topp -T --stream -s --presencepenalty -P --raw -r --frequencypenalty -F --listpatterns -l --listmodels -L --listcontexts -x --listsessions -X --updatepatterns -U --copy -c --model -m --modelContextLength --output -o --output-session --latest -n --changeDefaultModel -d --youtube -y --playlist --transcript --transcript-with-timestamps --comments --metadata --language -g --scrape_url -u --scrape_question -q --seed -e --wipecontext -w --wipesession -W --printcontext --printsession --readability --input-has-vars --dry-run --serve --serveOllama --address --api-key --config --version --listextensions --addextension --rmextension --strategy --liststrategies --listvendors --shell-complete-list --help -h"
|
||||
|
||||
# Helper function for dynamic completions
|
||||
_fabric_get_list() {
|
||||
fabric "$1" --shell-complete-list 2>/dev/null
|
||||
}
|
||||
|
||||
# Handle completions based on the previous word
|
||||
case "${prev}" in
|
||||
-p | --pattern)
|
||||
COMPREPLY=($(compgen -W "$(_fabric_get_list --listpatterns)" -- "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
-C | --context)
|
||||
COMPREPLY=($(compgen -W "$(_fabric_get_list --listcontexts)" -- "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--session)
|
||||
COMPREPLY=($(compgen -W "$(_fabric_get_list --listsessions)" -- "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
-m | --model)
|
||||
COMPREPLY=($(compgen -W "$(_fabric_get_list --listmodels)" -- "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
-w | --wipecontext)
|
||||
COMPREPLY=($(compgen -W "$(_fabric_get_list --listcontexts)" -- "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
-W | --wipesession)
|
||||
COMPREPLY=($(compgen -W "$(_fabric_get_list --listsessions)" -- "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--printcontext)
|
||||
COMPREPLY=($(compgen -W "$(_fabric_get_list --listcontexts)" -- "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--printsession)
|
||||
COMPREPLY=($(compgen -W "$(_fabric_get_list --listsessions)" -- "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--rmextension)
|
||||
COMPREPLY=($(compgen -W "$(_fabric_get_list --listextensions)" -- "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--strategy)
|
||||
COMPREPLY=($(compgen -W "$(_fabric_get_list --liststrategies)" -- "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
# Options requiring file/directory paths
|
||||
-a | --attachment | -o | --output | --config | --addextension)
|
||||
_filedir
|
||||
return 0
|
||||
;;
|
||||
# Options requiring simple arguments (no specific completion logic here)
|
||||
-v | --variable | -t | --temperature | -T | --topp | -P | --presencepenalty | -F | --frequencypenalty | --modelContextLength | -n | --latest | -y | --youtube | -g | --language | -u | --scrape_url | -q | --scrape_question | -e | --seed | --address | --api-key)
|
||||
# No specific completion suggestions, user types the value
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
|
||||
# If the current word starts with '-', suggest options
|
||||
if [[ "${cur}" == -* ]]; then
|
||||
COMPREPLY=($(compgen -W "${opts}" -- "${cur}"))
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Default: complete files/directories if no other rule matches
|
||||
# _filedir
|
||||
# Or provide no completions if it's not an option or argument following a known flag
|
||||
COMPREPLY=()
|
||||
|
||||
}
|
||||
|
||||
complete -F _fabric fabric
|
||||
94
completions/fabric.fish
Executable file
94
completions/fabric.fish
Executable file
@@ -0,0 +1,94 @@
|
||||
# Fish shell completion for fabric CLI
|
||||
#
|
||||
# Installation:
|
||||
# Copy this file to ~/.config/fish/completions/fabric.fish
|
||||
# or run:
|
||||
# mkdir -p ~/.config/fish/completions
|
||||
# cp completions/fabric.fish ~/.config/fish/completions/
|
||||
|
||||
# Helper functions for dynamic completions
|
||||
function __fabric_get_patterns
|
||||
fabric --listpatterns --shell-complete-list 2>/dev/null
|
||||
end
|
||||
|
||||
function __fabric_get_models
|
||||
fabric --listmodels --shell-complete-list 2>/dev/null
|
||||
end
|
||||
|
||||
function __fabric_get_contexts
|
||||
fabric --listcontexts --shell-complete-list 2>/dev/null
|
||||
end
|
||||
|
||||
function __fabric_get_sessions
|
||||
fabric --listsessions --shell-complete-list 2>/dev/null
|
||||
end
|
||||
|
||||
function __fabric_get_strategies
|
||||
fabric --liststrategies --shell-complete-list 2>/dev/null
|
||||
end
|
||||
|
||||
function __fabric_get_extensions
|
||||
fabric --listextensions --shell-complete-list 2>/dev/null
|
||||
end
|
||||
|
||||
# Main completion function
|
||||
complete -c fabric -f
|
||||
|
||||
# Flag completions with arguments
|
||||
complete -c fabric -s p -l pattern -d "Choose a pattern from the available patterns" -a "(__fabric_get_patterns)"
|
||||
complete -c fabric -s v -l variable -d "Values for pattern variables, e.g. -v=#role:expert -v=#points:30"
|
||||
complete -c fabric -s C -l context -d "Choose a context from the available contexts" -a "(__fabric_get_contexts)"
|
||||
complete -c fabric -l session -d "Choose a session from the available sessions" -a "(__fabric_get_sessions)"
|
||||
complete -c fabric -s a -l attachment -d "Attachment path or URL (e.g. for OpenAI image recognition messages)" -r
|
||||
complete -c fabric -s t -l temperature -d "Set temperature (default: 0.7)"
|
||||
complete -c fabric -s T -l topp -d "Set top P (default: 0.9)"
|
||||
complete -c fabric -s P -l presencepenalty -d "Set presence penalty (default: 0.0)"
|
||||
complete -c fabric -s F -l frequencypenalty -d "Set frequency penalty (default: 0.0)"
|
||||
complete -c fabric -s m -l model -d "Choose model" -a "(__fabric_get_models)"
|
||||
complete -c fabric -l modelContextLength -d "Model context length (only affects ollama)"
|
||||
complete -c fabric -s o -l output -d "Output to file" -r
|
||||
complete -c fabric -s n -l latest -d "Number of latest patterns to list (default: 0)"
|
||||
complete -c fabric -s y -l youtube -d "YouTube video or play list URL to grab transcript, comments from it"
|
||||
complete -c fabric -s g -l language -d "Specify the Language Code for the chat, e.g. -g=en -g=zh"
|
||||
complete -c fabric -s u -l scrape_url -d "Scrape website URL to markdown using Jina AI"
|
||||
complete -c fabric -s q -l scrape_question -d "Search question using Jina AI"
|
||||
complete -c fabric -s e -l seed -d "Seed to be used for LMM generation"
|
||||
complete -c fabric -s w -l wipecontext -d "Wipe context" -a "(__fabric_get_contexts)"
|
||||
complete -c fabric -s W -l wipesession -d "Wipe session" -a "(__fabric_get_sessions)"
|
||||
complete -c fabric -l printcontext -d "Print context" -a "(__fabric_get_contexts)"
|
||||
complete -c fabric -l printsession -d "Print session" -a "(__fabric_get_sessions)"
|
||||
complete -c fabric -l address -d "The address to bind the REST API (default: :8080)"
|
||||
complete -c fabric -l api-key -d "API key used to secure server routes"
|
||||
complete -c fabric -l config -d "Path to YAML config file" -r -a "*.yaml *.yml"
|
||||
complete -c fabric -l addextension -d "Register a new extension from config file path" -r -a "*.yaml *.yml"
|
||||
complete -c fabric -l rmextension -d "Remove a registered extension by name" -a "(__fabric_get_extensions)"
|
||||
complete -c fabric -l strategy -d "Choose a strategy from the available strategies" -a "(__fabric_get_strategies)"
|
||||
|
||||
# Boolean flags (no arguments)
|
||||
complete -c fabric -s S -l setup -d "Run setup for all reconfigurable parts of fabric"
|
||||
complete -c fabric -s s -l stream -d "Stream"
|
||||
complete -c fabric -s r -l raw -d "Use the defaults of the model without sending chat options"
|
||||
complete -c fabric -s l -l listpatterns -d "List all patterns"
|
||||
complete -c fabric -s L -l listmodels -d "List all available models"
|
||||
complete -c fabric -s x -l listcontexts -d "List all contexts"
|
||||
complete -c fabric -s X -l listsessions -d "List all sessions"
|
||||
complete -c fabric -s U -l updatepatterns -d "Update patterns"
|
||||
complete -c fabric -s c -l copy -d "Copy to clipboard"
|
||||
complete -c fabric -l output-session -d "Output the entire session to the output file"
|
||||
complete -c fabric -s d -l changeDefaultModel -d "Change default model"
|
||||
complete -c fabric -l playlist -d "Prefer playlist over video if both ids are present in the URL"
|
||||
complete -c fabric -l transcript -d "Grab transcript from YouTube video and send to chat"
|
||||
complete -c fabric -l transcript-with-timestamps -d "Grab transcript from YouTube video with timestamps"
|
||||
complete -c fabric -l comments -d "Grab comments from YouTube video and send to chat"
|
||||
complete -c fabric -l metadata -d "Output video metadata"
|
||||
complete -c fabric -l readability -d "Convert HTML input into a clean, readable view"
|
||||
complete -c fabric -l input-has-vars -d "Apply variables to user input"
|
||||
complete -c fabric -l dry-run -d "Show what would be sent to the model without actually sending it"
|
||||
complete -c fabric -l serve -d "Serve the Fabric Rest API"
|
||||
complete -c fabric -l serveOllama -d "Serve the Fabric Rest API with ollama endpoints"
|
||||
complete -c fabric -l version -d "Print current version"
|
||||
complete -c fabric -l listextensions -d "List all registered extensions"
|
||||
complete -c fabric -l liststrategies -d "List all strategies"
|
||||
complete -c fabric -l listvendors -d "List all vendors"
|
||||
complete -c fabric -l shell-complete-list -d "Output raw list without headers/formatting (for shell completion)"
|
||||
complete -c fabric -s h -l help -d "Show this help message"
|
||||
@@ -185,22 +185,26 @@ func (o *Chatter) BuildSession(request *common.ChatRequest, raw bool) (session *
|
||||
}
|
||||
}
|
||||
|
||||
if request.Language != "" {
|
||||
systemMessage = fmt.Sprintf("%s. Please use the language '%s' for the output.", systemMessage, request.Language)
|
||||
// Apply refined language instruction if specified
|
||||
if request.Language != "" && request.Language != "en" {
|
||||
// Refined instruction: Execute pattern using user input, then translate the entire response.
|
||||
systemMessage = fmt.Sprintf("%s\n\nIMPORTANT: First, execute the instructions provided in this prompt using the user's input. Second, ensure your entire final response, including any section headers or titles generated as part of executing the instructions, is written ONLY in the %s language.", systemMessage, request.Language)
|
||||
}
|
||||
|
||||
if raw {
|
||||
if request.Message != nil {
|
||||
if systemMessage != "" {
|
||||
request.Message.Content = systemMessage
|
||||
// system contains pattern which contains user input
|
||||
// In raw mode, combine system message (potentially with strategy) and user message into a single user message
|
||||
if systemMessage != "" {
|
||||
if request.Message != nil {
|
||||
// Prepend system message to user content, ensuring user input is preserved
|
||||
request.Message.Content = fmt.Sprintf("%s\n\n%s", systemMessage, request.Message.Content)
|
||||
request.Message.Role = goopenai.ChatMessageRoleUser // Ensure role is User in raw mode
|
||||
} else {
|
||||
// If no user message, create one with the system content, marked as User role
|
||||
request.Message = &goopenai.ChatCompletionMessage{Role: goopenai.ChatMessageRoleUser, Content: systemMessage}
|
||||
}
|
||||
} else {
|
||||
if systemMessage != "" {
|
||||
request.Message = &goopenai.ChatCompletionMessage{Role: goopenai.ChatMessageRoleSystem, Content: systemMessage}
|
||||
}
|
||||
}
|
||||
} // else: no system message, user message (if any) remains unchanged
|
||||
} else {
|
||||
// Not raw mode, append system message separately if it exists
|
||||
if systemMessage != "" {
|
||||
session.Append(&goopenai.ChatCompletionMessage{Role: goopenai.ChatMessageRoleSystem, Content: systemMessage})
|
||||
}
|
||||
|
||||
@@ -3,9 +3,12 @@ package core
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/danielmiessler/fabric/plugins/ai/exolab"
|
||||
"github.com/danielmiessler/fabric/plugins/strategy"
|
||||
@@ -17,17 +20,12 @@ import (
|
||||
"github.com/danielmiessler/fabric/plugins/ai"
|
||||
"github.com/danielmiessler/fabric/plugins/ai/anthropic"
|
||||
"github.com/danielmiessler/fabric/plugins/ai/azure"
|
||||
"github.com/danielmiessler/fabric/plugins/ai/deepseek"
|
||||
"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/litellm"
|
||||
"github.com/danielmiessler/fabric/plugins/ai/lmstudio"
|
||||
"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/ai/openai_compatible"
|
||||
"github.com/danielmiessler/fabric/plugins/db/fsdb"
|
||||
"github.com/danielmiessler/fabric/plugins/template"
|
||||
"github.com/danielmiessler/fabric/plugins/tools"
|
||||
@@ -56,27 +54,49 @@ func NewPluginRegistry(db *fsdb.Db) (ret *PluginRegistry, err error) {
|
||||
|
||||
ret.Defaults = tools.NeeDefaults(ret.GetModels)
|
||||
|
||||
ret.VendorsAll.AddVendors(
|
||||
// Create a vendors slice to hold all vendors (order doesn't matter initially)
|
||||
vendors := []ai.Vendor{}
|
||||
|
||||
// Add non-OpenAI compatible clients
|
||||
vendors = append(vendors,
|
||||
openai.NewClient(),
|
||||
ollama.NewClient(),
|
||||
azure.NewClient(),
|
||||
groq.NewClient(),
|
||||
gemini.NewClient(),
|
||||
//gemini_openai.NewClient(),
|
||||
anthropic.NewClient(),
|
||||
siliconcloud.NewClient(),
|
||||
openrouter.NewClient(),
|
||||
lmstudio.NewClient(),
|
||||
mistral.NewClient(),
|
||||
deepseek.NewClient(),
|
||||
exolab.NewClient(),
|
||||
litellm.NewClient(),
|
||||
)
|
||||
|
||||
// Add all OpenAI-compatible providers
|
||||
for providerName := range openai_compatible.ProviderMap {
|
||||
provider, _ := openai_compatible.GetProviderByName(providerName)
|
||||
vendors = append(vendors, openai_compatible.NewClient(provider))
|
||||
}
|
||||
|
||||
// Sort vendors by name for consistent ordering (case-insensitive)
|
||||
sort.Slice(vendors, func(i, j int) bool {
|
||||
return strings.ToLower(vendors[i].GetName()) < strings.ToLower(vendors[j].GetName())
|
||||
})
|
||||
|
||||
// Add all sorted vendors to VendorsAll
|
||||
ret.VendorsAll.AddVendors(vendors...)
|
||||
_ = ret.Configure()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (o *PluginRegistry) ListVendors(out io.Writer) error {
|
||||
vendors := lo.Map(o.VendorsAll.Vendors, func(vendor ai.Vendor, _ int) string {
|
||||
return vendor.GetName()
|
||||
})
|
||||
fmt.Fprint(out, "Available Vendors:\n\n")
|
||||
for _, vendor := range vendors {
|
||||
fmt.Fprintf(out, "%s\n", vendor)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type PluginRegistry struct {
|
||||
Db *fsdb.Db
|
||||
|
||||
@@ -129,10 +149,10 @@ func (o *PluginRegistry) Setup() (err error) {
|
||||
return vendor
|
||||
})...)
|
||||
|
||||
groupsPlugins.AddGroupItems("Tools", o.Defaults, o.PatternsLoader, o.YouTube, o.Language, o.Jina, o.Strategies)
|
||||
groupsPlugins.AddGroupItems("Tools", o.Defaults, o.Jina, o.Language, o.PatternsLoader, o.Strategies, o.YouTube)
|
||||
|
||||
for {
|
||||
groupsPlugins.Print()
|
||||
groupsPlugins.Print(false)
|
||||
|
||||
if answerErr := setupQuestion.Ask("Plugin Number"); answerErr != nil {
|
||||
break
|
||||
|
||||
18
flake.lock
generated
18
flake.lock
generated
@@ -26,11 +26,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1733668782,
|
||||
"narHash": "sha256-tPsqU00FhgdFr0JiQUiBMgPVbl1jbPCY5gbFiJycL3I=",
|
||||
"lastModified": 1742209644,
|
||||
"narHash": "sha256-jMy1XqXqD0/tJprEbUmKilTkvbDY/C0ZGSsJJH4TNCE=",
|
||||
"owner": "nix-community",
|
||||
"repo": "gomod2nix",
|
||||
"rev": "514283ec89c39ad0079ff2f3b1437404e4cba608",
|
||||
"rev": "8f3534eb8f6c5c3fce799376dc3b91bae6b11884",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -41,11 +41,11 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1736344531,
|
||||
"narHash": "sha256-8YVQ9ZbSfuUk2bUf2KRj60NRraLPKPS0Q4QFTbc+c2c=",
|
||||
"lastModified": 1745234285,
|
||||
"narHash": "sha256-GfpyMzxwkfgRVN0cTGQSkTC0OHhEkv3Jf6Tcjm//qZ0=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "bffc22eb12172e6db3c5dde9e3e5628f8e3e7912",
|
||||
"rev": "c11863f1e964833214b767f4a369c6e6a7aba141",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -100,11 +100,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1736154270,
|
||||
"narHash": "sha256-p2r8xhQZ3TYIEKBoiEhllKWQqWNJNoT9v64Vmg4q8Zw=",
|
||||
"lastModified": 1744961264,
|
||||
"narHash": "sha256-aRmUh0AMwcbdjJHnytg1e5h5ECcaWtIFQa6d9gI85AI=",
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"rev": "13c913f5deb3a5c08bb810efd89dc8cb24dd968b",
|
||||
"rev": "8d404a69efe76146368885110f29a2ca3700bee6",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
||||
12
flake.nix
12
flake.nix
@@ -28,6 +28,8 @@
|
||||
let
|
||||
forAllSystems = nixpkgs.lib.genAttrs (import systems);
|
||||
|
||||
getGoVersion = system: nixpkgs.legacyPackages.${system}.go_1_24;
|
||||
|
||||
treefmtEval = forAllSystems (
|
||||
system:
|
||||
let
|
||||
@@ -47,10 +49,14 @@
|
||||
system:
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
goEnv = gomod2nix.legacyPackages.${system}.mkGoEnv { pwd = ./.; };
|
||||
goVersion = getGoVersion system;
|
||||
goEnv = gomod2nix.legacyPackages.${system}.mkGoEnv {
|
||||
pwd = ./.;
|
||||
go = goVersion;
|
||||
};
|
||||
in
|
||||
import ./nix/shell.nix {
|
||||
inherit pkgs goEnv;
|
||||
inherit pkgs goEnv goVersion;
|
||||
inherit (gomod2nix.legacyPackages.${system}) gomod2nix;
|
||||
}
|
||||
);
|
||||
@@ -59,10 +65,12 @@
|
||||
system:
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
goVersion = getGoVersion system;
|
||||
in
|
||||
{
|
||||
default = self.packages.${system}.fabric;
|
||||
fabric = pkgs.callPackage ./nix/pkgs/fabric {
|
||||
go = goVersion;
|
||||
inherit (gomod2nix.legacyPackages.${system}) buildGoApplication;
|
||||
};
|
||||
inherit (gomod2nix.legacyPackages.${system}) gomod2nix;
|
||||
|
||||
76
go.mod
76
go.mod
@@ -1,65 +1,67 @@
|
||||
module github.com/danielmiessler/fabric
|
||||
|
||||
go 1.23.4
|
||||
go 1.24.0
|
||||
|
||||
toolchain go1.24.2
|
||||
|
||||
require (
|
||||
github.com/anaskhan96/soup v1.2.5
|
||||
github.com/anthropics/anthropic-sdk-go v0.2.0-alpha.11
|
||||
github.com/anthropics/anthropic-sdk-go v0.2.0-beta.3
|
||||
github.com/atotto/clipboard v0.1.4
|
||||
github.com/gabriel-vasile/mimetype v1.4.8
|
||||
github.com/gabriel-vasile/mimetype v1.4.9
|
||||
github.com/gin-gonic/gin v1.10.0
|
||||
github.com/go-git/go-git/v5 v5.13.2
|
||||
github.com/go-git/go-git/v5 v5.16.0
|
||||
github.com/go-shiori/go-readability v0.0.0-20250217085726-9f5bf5ca7612
|
||||
github.com/google/generative-ai-go v0.19.0
|
||||
github.com/jessevdk/go-flags v1.6.1
|
||||
github.com/joho/godotenv v1.5.1
|
||||
github.com/ollama/ollama v0.5.12
|
||||
github.com/ollama/ollama v0.6.6
|
||||
github.com/otiai10/copy v1.14.1
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/samber/lo v1.49.1
|
||||
github.com/sashabaranov/go-openai v1.38.0
|
||||
github.com/sashabaranov/go-openai v1.38.2
|
||||
github.com/stretchr/testify v1.10.0
|
||||
golang.org/x/text v0.22.0
|
||||
google.golang.org/api v0.223.0
|
||||
golang.org/x/text v0.24.0
|
||||
google.golang.org/api v0.230.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.118.3 // indirect
|
||||
cloud.google.com/go/ai v0.10.0 // indirect
|
||||
cloud.google.com/go/auth v0.15.0 // indirect
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.7 // indirect
|
||||
cloud.google.com/go v0.120.1 // indirect
|
||||
cloud.google.com/go/ai v0.10.2 // indirect
|
||||
cloud.google.com/go/auth v0.16.1 // indirect
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.6.0 // indirect
|
||||
cloud.google.com/go/longrunning v0.6.4 // indirect
|
||||
cloud.google.com/go/longrunning v0.6.7 // indirect
|
||||
dario.cat/mergo v1.0.1 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||
github.com/ProtonMail/go-crypto v1.1.5 // indirect
|
||||
github.com/ProtonMail/go-crypto v1.2.0 // indirect
|
||||
github.com/andybalholm/cascadia v1.3.3 // indirect
|
||||
github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de // indirect
|
||||
github.com/bytedance/sonic v1.12.9 // indirect
|
||||
github.com/bytedance/sonic/loader v0.2.3 // indirect
|
||||
github.com/cloudflare/circl v1.6.0 // indirect
|
||||
github.com/bytedance/sonic v1.13.2 // indirect
|
||||
github.com/bytedance/sonic/loader v0.2.4 // indirect
|
||||
github.com/cloudflare/circl v1.6.1 // indirect
|
||||
github.com/cloudwego/base64x v0.1.5 // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.4.1 // 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/gin-contrib/sse v1.0.0 // indirect
|
||||
github.com/gin-contrib/sse v1.1.0 // indirect
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
|
||||
github.com/go-git/go-billy/v5 v5.6.2 // 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.25.0 // indirect
|
||||
github.com/go-playground/validator/v10 v10.26.0 // indirect
|
||||
github.com/go-shiori/dom v0.0.0-20230515143342-73569d674e1c // indirect
|
||||
github.com/goccy/go-json v0.10.5 // indirect
|
||||
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f // indirect
|
||||
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
|
||||
github.com/google/s2a-go v0.1.9 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.14.1 // indirect
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
@@ -70,7 +72,7 @@ require (
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/otiai10/mint v1.6.3 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||
github.com/pjbgf/sha1cd v0.3.2 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
|
||||
@@ -83,21 +85,21 @@ require (
|
||||
github.com/ugorji/go/codec v1.2.12 // indirect
|
||||
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 // indirect
|
||||
go.opentelemetry.io/otel v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.34.0 // indirect
|
||||
golang.org/x/arch v0.14.0 // indirect
|
||||
golang.org/x/crypto v0.35.0 // indirect
|
||||
golang.org/x/net v0.36.0 // indirect
|
||||
golang.org/x/oauth2 v0.27.0 // indirect
|
||||
golang.org/x/sync v0.11.0 // indirect
|
||||
golang.org/x/sys v0.30.0 // indirect
|
||||
golang.org/x/time v0.10.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250224174004-546df14abb99 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250224174004-546df14abb99 // indirect
|
||||
google.golang.org/grpc v1.70.0 // indirect
|
||||
google.golang.org/protobuf v1.36.5 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect
|
||||
go.opentelemetry.io/otel v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.35.0 // indirect
|
||||
golang.org/x/arch v0.16.0 // indirect
|
||||
golang.org/x/crypto v0.37.0 // indirect
|
||||
golang.org/x/net v0.39.0 // indirect
|
||||
golang.org/x/oauth2 v0.29.0 // indirect
|
||||
golang.org/x/sync v0.13.0 // indirect
|
||||
golang.org/x/sys v0.32.0 // indirect
|
||||
golang.org/x/time v0.11.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250422160041-2d3770c4ea7f // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250422160041-2d3770c4ea7f // indirect
|
||||
google.golang.org/grpc v1.72.0 // indirect
|
||||
google.golang.org/protobuf v1.36.6 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
)
|
||||
|
||||
170
go.sum
170
go.sum
@@ -1,43 +1,43 @@
|
||||
cloud.google.com/go v0.118.3 h1:jsypSnrE/w4mJysioGdMBg4MiW/hHx/sArFpaBWHdME=
|
||||
cloud.google.com/go v0.118.3/go.mod h1:Lhs3YLnBlwJ4KA6nuObNMZ/fCbOQBPuWKPoE0Wa/9Vc=
|
||||
cloud.google.com/go/ai v0.10.0 h1:hwj6CI6sMKubXodoJJGTy/c2T1RbbLGM6TL3QoAvzU8=
|
||||
cloud.google.com/go/ai v0.10.0/go.mod h1:kvnt2KeHqX8+41PVeMRBETDyQAp/RFvBWGdx/aGjNMo=
|
||||
cloud.google.com/go/auth v0.15.0 h1:Ly0u4aA5vG/fsSsxu98qCQBemXtAtJf+95z9HK+cxps=
|
||||
cloud.google.com/go/auth v0.15.0/go.mod h1:WJDGqZ1o9E9wKIL+IwStfyn/+s59zl4Bi+1KQNVXLZ8=
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.7 h1:/Lc7xODdqcEw8IrZ9SvwnlLX6j9FHQM74z6cBk9Rw6M=
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.7/go.mod h1:NTbTTzfvPl1Y3V1nPpOgl2w6d/FjO7NNUQaWSox6ZMc=
|
||||
cloud.google.com/go v0.120.1 h1:Z+5V7yd383+9617XDCyszmK5E4wJRJL+tquMfDj9hLM=
|
||||
cloud.google.com/go v0.120.1/go.mod h1:56Vs7sf/i2jYM6ZL9NYlC82r04PThNcPS5YgFmb0rp8=
|
||||
cloud.google.com/go/ai v0.10.2 h1:5NHzmZlRs+3kvlsVdjT0cTnLrjQdROJ/8VOljVfs+8o=
|
||||
cloud.google.com/go/ai v0.10.2/go.mod h1:xZuZuE9d3RgsR132meCnPadiU9XV0qXjpLr+P4J46eE=
|
||||
cloud.google.com/go/auth v0.16.1 h1:XrXauHMd30LhQYVRHLGvJiYeczweKQXZxsTbV9TiguU=
|
||||
cloud.google.com/go/auth v0.16.1/go.mod h1:1howDHJ5IETh/LwYs3ZxvlkXF48aSqqJUM+5o02dNOI=
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc=
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=
|
||||
cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I=
|
||||
cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg=
|
||||
cloud.google.com/go/longrunning v0.6.4 h1:3tyw9rO3E2XVXzSApn1gyEEnH2K9SynNQjMlBi3uHLg=
|
||||
cloud.google.com/go/longrunning v0.6.4/go.mod h1:ttZpLCe6e7EXvn9OxpBRx7kZEB0efv8yBO6YnVMfhJs=
|
||||
cloud.google.com/go/longrunning v0.6.7 h1:IGtfDWHhQCgCjwQjV9iiLnUta9LBCo8R9QmAFsS/PrE=
|
||||
cloud.google.com/go/longrunning v0.6.7/go.mod h1:EAFV3IZAKmM56TyiE6VAP3VoTzhZzySwI/YI1s/nRsY=
|
||||
dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
|
||||
dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
||||
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
|
||||
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||
github.com/ProtonMail/go-crypto v1.1.5 h1:eoAQfK2dwL+tFSFpr7TbOaPNUbPiJj4fLYwwGE1FQO4=
|
||||
github.com/ProtonMail/go-crypto v1.1.5/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
|
||||
github.com/ProtonMail/go-crypto v1.2.0 h1:+PhXXn4SPGd+qk76TlEePBfOfivE0zkWFenhGhFLzWs=
|
||||
github.com/ProtonMail/go-crypto v1.2.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE=
|
||||
github.com/anaskhan96/soup v1.2.5 h1:V/FHiusdTrPrdF4iA1YkVxsOpdNcgvqT1hG+YtcZ5hM=
|
||||
github.com/anaskhan96/soup v1.2.5/go.mod h1:6YnEp9A2yywlYdM4EgDz9NEHclocMepEtku7wg6Cq3s=
|
||||
github.com/andybalholm/cascadia v1.3.3 h1:AG2YHrzJIm4BZ19iwJ/DAua6Btl3IwJX+VI4kktS1LM=
|
||||
github.com/andybalholm/cascadia v1.3.3/go.mod h1:xNd9bqTn98Ln4DwST8/nG+H0yuB8Hmgu1YHNnWw0GeA=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
|
||||
github.com/anthropics/anthropic-sdk-go v0.2.0-alpha.11 h1:O3/AMObKntZyu1KH6Xks6E0gbE8w6HVaKHE+/vXARzM=
|
||||
github.com/anthropics/anthropic-sdk-go v0.2.0-alpha.11/go.mod h1:GJxtdOs9K4neo8Gg65CjJ7jNautmldGli5/OFNabOoo=
|
||||
github.com/anthropics/anthropic-sdk-go v0.2.0-beta.3 h1:b5t1ZJMvV/l99y4jbz7kRFdUp3BSDkI8EhSlHczivtw=
|
||||
github.com/anthropics/anthropic-sdk-go v0.2.0-beta.3/go.mod h1:AapDW22irxK2PSumZiQXYUFvsdQgkwIWlpESweWZI/c=
|
||||
github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de h1:FxWPpzIjnTlhPwqqXc4/vE0f7GvRjuAsbW+HOIe8KnA=
|
||||
github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de/go.mod h1:DCaWoUhZrYW9p1lxo/cm8EmUOOzAPSEZNGF2DK1dJgw=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
|
||||
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
|
||||
github.com/bytedance/sonic v1.12.9 h1:Od1BvK55NnewtGaJsTDeAOSnLVO2BTSLOe0+ooKokmQ=
|
||||
github.com/bytedance/sonic v1.12.9/go.mod h1:uVvFidNmlt9+wa31S1urfwwthTWteBgG0hWuoKAXTx8=
|
||||
github.com/bytedance/sonic v1.13.2 h1:8/H1FempDZqC4VqjptGo14QQlJx8VdZJegxs6wwfqpQ=
|
||||
github.com/bytedance/sonic v1.13.2/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4=
|
||||
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||
github.com/bytedance/sonic/loader v0.2.3 h1:yctD0Q3v2NOGfSWPLPvG2ggA2kV6TS6s4wioyEqssH0=
|
||||
github.com/bytedance/sonic/loader v0.2.3/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI=
|
||||
github.com/cloudflare/circl v1.6.0 h1:cr5JKic4HI+LkINy2lg3W2jF8sHCVTBncJr5gIIq7qk=
|
||||
github.com/cloudflare/circl v1.6.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
|
||||
github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY=
|
||||
github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI=
|
||||
github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0=
|
||||
github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
|
||||
github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4=
|
||||
github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
|
||||
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
||||
@@ -46,16 +46,16 @@ github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGL
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/elazarl/goproxy v1.4.0 h1:4GyuSbFa+s26+3rmYNSuUVsx+HgPrV1bk1jXI0l9wjM=
|
||||
github.com/elazarl/goproxy v1.4.0/go.mod h1:X/5W/t+gzDyLfHW4DrMdpjqYjpXsURlBt9lpBDxZZZQ=
|
||||
github.com/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o=
|
||||
github.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE=
|
||||
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
|
||||
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
|
||||
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.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
|
||||
github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
|
||||
github.com/gin-contrib/sse v1.0.0 h1:y3bT1mUWUxDpW4JLQg/HnTqV4rozuW4tC9eFKTxYI9E=
|
||||
github.com/gin-contrib/sse v1.0.0/go.mod h1:zNuFdwarAygJBht0NTKiSi3jRf6RbqeILZ9Sp6Slhe0=
|
||||
github.com/gabriel-vasile/mimetype v1.4.9 h1:5k+WDwEsD9eTLL8Tz3L0VnmVh9QxGjRmjBvAG7U/oYY=
|
||||
github.com/gabriel-vasile/mimetype v1.4.9/go.mod h1:WnSQhFKJuBlRyLiKohA/2DtIlPFAbguNaG7QCHcyGok=
|
||||
github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w=
|
||||
github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM=
|
||||
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.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c=
|
||||
@@ -66,8 +66,8 @@ github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UN
|
||||
github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
|
||||
github.com/go-git/go-git/v5 v5.13.2 h1:7O7xvsK7K+rZPKW6AQR1YyNhfywkv7B8/FsP3ki6Zv0=
|
||||
github.com/go-git/go-git/v5 v5.13.2/go.mod h1:hWdW5P4YZRjmpGHwRH2v3zkWcNl6HeXaXQEMGb3NJ9A=
|
||||
github.com/go-git/go-git/v5 v5.16.0 h1:k3kuOEpkc0DeY7xlL6NaaNg39xdgQbtH5mwCafHO9AQ=
|
||||
github.com/go-git/go-git/v5 v5.16.0/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
@@ -79,8 +79,8 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o
|
||||
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.25.0 h1:5Dh7cjvzR7BRZadnsVOzPhWsrwUr0nmsZJxEAnFLNO8=
|
||||
github.com/go-playground/validator/v10 v10.25.0/go.mod h1:GGzBIJMuE98Ic/kJsBXbz1x/7cByt++cQ+YOuDM5wus=
|
||||
github.com/go-playground/validator/v10 v10.26.0 h1:SP05Nqhjcvz81uJaRfEV0YBSSSGMc/iMaVtFbr3Sw2k=
|
||||
github.com/go-playground/validator/v10 v10.26.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo=
|
||||
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-20250217085726-9f5bf5ca7612 h1:BYLNYdZaepitbZreRIa9xeCQZocWmy/wj4cGIH0qyw0=
|
||||
@@ -103,8 +103,8 @@ github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0=
|
||||
github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.4 h1:XYIDZApgAnrN1c855gTgghdIA6Stxb52D5RnLI1SLyw=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.4/go.mod h1:YKe7cfqYXjKGpGvmSg28/fFvhNzinZQm8DGnaburhGA=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA=
|
||||
github.com/googleapis/gax-go/v2 v2.14.1 h1:hb0FFeiPaQskmvakKu5EbCbpntQn48jyHuvrkurSS/Q=
|
||||
github.com/googleapis/gax-go/v2 v2.14.1/go.mod h1:Hb/NubMaVM88SrNkvl8X/o8XWwDJEPqouaLeN2IUxoA=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
||||
@@ -138,16 +138,16 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
|
||||
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.5.12 h1:qM+k/ozyHLJzEQoAEPrUQ0qXqsgDEEdpIVwuwScrd2U=
|
||||
github.com/ollama/ollama v0.5.12/go.mod h1:ibdmDvb/TjKY1OArBWIazL3pd1DHTk8eG2MMjEkWhiI=
|
||||
github.com/ollama/ollama v0.6.6 h1:rnCQTSTiRD3Dsvd35dh2j2YB9DlQMFQR/y3XOhWZOmI=
|
||||
github.com/ollama/ollama v0.6.6/go.mod h1:pGgtoNyc9DdM6oZI6yMfI6jTk2Eh4c36c2GpfQCH7PY=
|
||||
github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k=
|
||||
github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY=
|
||||
github.com/otiai10/copy v1.14.1 h1:5/7E6qsUMBaH5AnQ0sSLzzTg1oTECmcCmT6lvF45Na8=
|
||||
github.com/otiai10/copy v1.14.1/go.mod h1:oQwrEDDOci3IM8dJF0d8+jnbfPDllW6vUjNc3DoZm9I=
|
||||
github.com/otiai10/mint v1.6.3 h1:87qsV/aw1F5as1eH1zS/yqHY85ANKVMgkDrf9rcxbQs=
|
||||
github.com/otiai10/mint v1.6.3/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM=
|
||||
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
|
||||
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
|
||||
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
|
||||
github.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4=
|
||||
github.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
@@ -155,12 +155,12 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
||||
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
||||
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
||||
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||
github.com/samber/lo v1.49.1 h1:4BIFyVfuQSEpluc7Fua+j1NolZHiEHEpaSEKdsH0tew=
|
||||
github.com/samber/lo v1.49.1/go.mod h1:dO6KHFzUKXgP8LDhU0oI8d2hekjXnGOu0DB8Jecxd6o=
|
||||
github.com/sashabaranov/go-openai v1.38.0 h1:hNN5uolKwdbpiqOn7l+Z2alch/0n0rSFyg4n+GZxR5k=
|
||||
github.com/sashabaranov/go-openai v1.38.0/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
|
||||
github.com/sashabaranov/go-openai v1.38.2 h1:akrssjj+6DY3lWuDwHv6cBvJ8Z+FZDM9XEaaYFt0Auo=
|
||||
github.com/sashabaranov/go-openai v1.38.2/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
|
||||
github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4/go.mod h1:C1a7PQSMz9NShzorzCiG2fk9+xuCgLkPeCvMHYR2OWg=
|
||||
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
|
||||
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
|
||||
@@ -170,7 +170,6 @@ github.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQ
|
||||
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=
|
||||
@@ -179,7 +178,6 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
||||
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.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
@@ -201,22 +199,22 @@ github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 h1:rgMkmiGfix9vFJDcDi1PK8WEQP4FLQwLDfhp5ZLpFeE=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0/go.mod h1:ijPqXp5P6IRRByFVVg9DY8P5HkxkHE5ARIa+86aXPf4=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 h1:CV7UdSGJt/Ao6Gp4CXckLxVRRsRgDHoI8XjbL3PDl8s=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0/go.mod h1:FRmFuRJfag1IZ2dPkHnEoSFVgTVPUd2qf5Vi69hLb8I=
|
||||
go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
|
||||
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
|
||||
go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
|
||||
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
|
||||
go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
|
||||
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ=
|
||||
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
|
||||
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
|
||||
golang.org/x/arch v0.14.0 h1:z9JUEZWr8x4rR0OU6c4/4t6E6jOZ8/QBS2bBYBm4tx4=
|
||||
golang.org/x/arch v0.14.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 h1:x7wzEgXfnzJcHDwStJT+mxOz4etr2EcexjqhBvmoakw=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0/go.mod h1:rg+RlpR5dKwaS95IyyZqj5Wd4E13lk/msnTS0Xl9lJM=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ=
|
||||
go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ=
|
||||
go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y=
|
||||
go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M=
|
||||
go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE=
|
||||
go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY=
|
||||
go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w=
|
||||
go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs=
|
||||
go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc=
|
||||
golang.org/x/arch v0.16.0 h1:foMtLTdyOmIniqWCHjY6+JxuC54XP1fDwx4N0ASyW+U=
|
||||
golang.org/x/arch v0.16.0/go.mod h1:JmwW7aLIoRUKgaTzhkiEFxvcEiQGyOg9BMonBJUS7EE=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
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=
|
||||
@@ -224,10 +222,10 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
|
||||
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
|
||||
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
|
||||
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
|
||||
golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa h1:t2QcU6V556bFjYgu4L6C+6VrCPyJZ+eyRsABUPs1mz4=
|
||||
golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa/go.mod h1:BHOTPb3L19zxehTsLoJXVaTktb06DFgmdW6Wb9s8jqk=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
@@ -244,10 +242,10 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
||||
golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA=
|
||||
golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I=
|
||||
golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M=
|
||||
golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
|
||||
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
|
||||
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
|
||||
golang.org/x/oauth2 v0.29.0 h1:WdYw2tdTK1S8olAzWHdgeqfy+Mtm9XNhv/xJsY65d98=
|
||||
golang.org/x/oauth2 v0.29.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -255,8 +253,8 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
|
||||
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610=
|
||||
golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -273,8 +271,8 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
|
||||
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
||||
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=
|
||||
@@ -284,8 +282,8 @@ golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
||||
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
|
||||
golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU=
|
||||
golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s=
|
||||
golang.org/x/term v0.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o=
|
||||
golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw=
|
||||
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=
|
||||
@@ -296,10 +294,10 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
|
||||
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
|
||||
golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4=
|
||||
golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
|
||||
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
|
||||
golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0=
|
||||
golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
@@ -307,16 +305,16 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.223.0 h1:JUTaWEriXmEy5AhvdMgksGGPEFsYfUKaPEYXd4c3Wvc=
|
||||
google.golang.org/api v0.223.0/go.mod h1:C+RS7Z+dDwds2b+zoAk5hN/eSfsiCn0UDrYof/M4d2M=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250224174004-546df14abb99 h1:ilJhrCga0AptpJZXmUYG4MCrx/zf3l1okuYz7YK9PPw=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250224174004-546df14abb99/go.mod h1:Xsh8gBVxGCcbV8ZeTB9wI5XPyZ5RvC6V3CTeeplHbiA=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250224174004-546df14abb99 h1:ZSlhAUqC4r8TPzqLXQ0m3upBNZeF+Y8jQ3c4CR3Ujms=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250224174004-546df14abb99/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I=
|
||||
google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
|
||||
google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
|
||||
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
|
||||
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
google.golang.org/api v0.230.0 h1:2u1hni3E+UXAXrONrrkfWpi/V6cyKVAbfGVeGtC3OxM=
|
||||
google.golang.org/api v0.230.0/go.mod h1:aqvtoMk7YkiXx+6U12arQFExiRV9D/ekvMCwCd/TksQ=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250422160041-2d3770c4ea7f h1:tjZsroqekhC63+WMqzmWyW5Twj/ZfR5HAlpd5YQ1Vs0=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250422160041-2d3770c4ea7f/go.mod h1:Cd8IzgPo5Akum2c9R6FsXNaZbH3Jpa2gpHlW89FqlyQ=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250422160041-2d3770c4ea7f h1:N/PrbTw4kdkqNRzVfWPrBekzLuarFREcbFOiOLkXon4=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250422160041-2d3770c4ea7f/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
|
||||
google.golang.org/grpc v1.72.0 h1:S7UkcVa60b5AAQTaO6ZKamFp1zMZSU0fGDK2WZLbBnM=
|
||||
google.golang.org/grpc v1.72.0/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM=
|
||||
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
|
||||
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
lib,
|
||||
buildGoApplication,
|
||||
go,
|
||||
}:
|
||||
|
||||
buildGoApplication {
|
||||
@@ -17,6 +18,8 @@ buildGoApplication {
|
||||
"-w"
|
||||
];
|
||||
|
||||
inherit go;
|
||||
|
||||
meta = with lib; {
|
||||
description = "Fabric is an open-source framework for augmenting humans using AI. It provides a modular framework for solving specific problems using a crowdsourced set of AI prompts that can be used anywhere";
|
||||
homepage = "https://github.com/danielmiessler/fabric";
|
||||
|
||||
@@ -2,23 +2,23 @@ schema = 3
|
||||
|
||||
[mod]
|
||||
[mod."cloud.google.com/go"]
|
||||
version = "v0.118.3"
|
||||
hash = "sha256-y3YHioDLx9/asf2AWuincnq4BVO2S/GQFxpa1dEpxKs="
|
||||
version = "v0.120.1"
|
||||
hash = "sha256-yWaLc06rGXk16K53rix8O4uPSX+AOZDgIpIXf+wlh10="
|
||||
[mod."cloud.google.com/go/ai"]
|
||||
version = "v0.10.0"
|
||||
hash = "sha256-huE2q1HBA6d9FQ152HFQhOe9fX0QlLFVuFO3XAfln8U="
|
||||
version = "v0.10.2"
|
||||
hash = "sha256-bsqvdylG8kk+AHtyvMRMv1TOjUmvONAgJ+14mKcwuzs="
|
||||
[mod."cloud.google.com/go/auth"]
|
||||
version = "v0.15.0"
|
||||
hash = "sha256-N9xjLPDLhG5cqUx94tNccv74Q/fIlukWU6NbWpuNi+I="
|
||||
version = "v0.16.1"
|
||||
hash = "sha256-rMPMNQh/YM/67b9Grfu0BFccWpS1SRhBepubQqXRAyg="
|
||||
[mod."cloud.google.com/go/auth/oauth2adapt"]
|
||||
version = "v0.2.7"
|
||||
hash = "sha256-U+pXaY0kPnSeBzHWxELZ75bZnb74nygwIVZDdXYcP5g="
|
||||
version = "v0.2.8"
|
||||
hash = "sha256-GoXFqAbp1WO1tDj07PF5EyxDYvCBP0l0qwxY2oV2hfc="
|
||||
[mod."cloud.google.com/go/compute/metadata"]
|
||||
version = "v0.6.0"
|
||||
hash = "sha256-E8/cwio4xR8buCryR4HwR7+agb4M3zqgXSm7rBglmIY="
|
||||
[mod."cloud.google.com/go/longrunning"]
|
||||
version = "v0.6.4"
|
||||
hash = "sha256-Q0JtsyxSgVwi91ZhvefpAq8fKbblRrtQ2bQhQYiTY48="
|
||||
version = "v0.6.7"
|
||||
hash = "sha256-9I0Nc2KWAEVoxDngNkqFUdASmZIAySfMEELlPh3Q3xA="
|
||||
[mod."dario.cat/mergo"]
|
||||
version = "v1.0.1"
|
||||
hash = "sha256-wcG6+x0k6KzOSlaPA+1RFxa06/RIAePJTAjjuhLbImw="
|
||||
@@ -26,8 +26,8 @@ schema = 3
|
||||
version = "v0.6.2"
|
||||
hash = "sha256-tVNWDUMILZbJvarcl/E7tpSnkn7urqgSHa2Eaka5vSU="
|
||||
[mod."github.com/ProtonMail/go-crypto"]
|
||||
version = "v1.1.5"
|
||||
hash = "sha256-N5Zn0f/NF3ezyGou2kRw9BwM25feJqnp7TPkRt6oK6I="
|
||||
version = "v1.2.0"
|
||||
hash = "sha256-5fKgWUz6BoyFNNZ1OD9QjhBrhNEBCuVfO2WqH+X59oo="
|
||||
[mod."github.com/anaskhan96/soup"]
|
||||
version = "v1.2.5"
|
||||
hash = "sha256-t8yCyK2y7x2qaI/3Yw16q3zVFqu+3acLcPgTr1MIKWg="
|
||||
@@ -35,8 +35,8 @@ schema = 3
|
||||
version = "v1.3.3"
|
||||
hash = "sha256-jv7ZshpSd7FZzKKN6hqlUgiR8C3y85zNIS/hq7g76Ho="
|
||||
[mod."github.com/anthropics/anthropic-sdk-go"]
|
||||
version = "v0.2.0-alpha.11"
|
||||
hash = "sha256-0wl62e6AVhDY3KkoYrfAHFtBrwNC4nzqrR55iyCJlwk="
|
||||
version = "v0.2.0-beta.3"
|
||||
hash = "sha256-QnR7MWiLPVii9jy7rjrZfg1UDgXCXkc2latdzFurrFM="
|
||||
[mod."github.com/araddon/dateparse"]
|
||||
version = "v0.0.0-20210429162001-6b43995a97de"
|
||||
hash = "sha256-UuX84naeRGMsFOgIgRoBHG5sNy1CzBkWPKmd6VbLwFw="
|
||||
@@ -44,14 +44,14 @@ schema = 3
|
||||
version = "v0.1.4"
|
||||
hash = "sha256-ZZ7U5X0gWOu8zcjZcWbcpzGOGdycwq0TjTFh/eZHjXk="
|
||||
[mod."github.com/bytedance/sonic"]
|
||||
version = "v1.12.9"
|
||||
hash = "sha256-smlXGC4n6fkOiVR+A3VGd71xp+cYo42MSHuWq7H3jew="
|
||||
version = "v1.13.2"
|
||||
hash = "sha256-IF2qmt4IxTwivMWHUJC8sg6d85/ORb2SWvJ54fvoAMI="
|
||||
[mod."github.com/bytedance/sonic/loader"]
|
||||
version = "v0.2.3"
|
||||
hash = "sha256-c0m1nl1jv76LVaUgFFNjZU9jss/hoSWXyCRimhRWYjM="
|
||||
version = "v0.2.4"
|
||||
hash = "sha256-rv9LnePpm4OspSVbfSoVbohXzhu+dxE1BH1gm3mTmTc="
|
||||
[mod."github.com/cloudflare/circl"]
|
||||
version = "v1.6.0"
|
||||
hash = "sha256-a+SVfnHYC8Fb+NQLboNg5P9sry+WutzuNetVHFVAAo0="
|
||||
version = "v1.6.1"
|
||||
hash = "sha256-Dc69V12eIFnJoUNmwg6VKXHfAMijbAeEVSDe8AiOaLo="
|
||||
[mod."github.com/cloudwego/base64x"]
|
||||
version = "v0.1.5"
|
||||
hash = "sha256-MyUYTveN48DhnL8mwAgCRuMExLct98uzSPsmYlfaa4I="
|
||||
@@ -68,11 +68,11 @@ schema = 3
|
||||
version = "v1.0.4"
|
||||
hash = "sha256-c1JKoRSndwwOyOxq9ddCe+8qn7mG9uRq2o/822x5O/c="
|
||||
[mod."github.com/gabriel-vasile/mimetype"]
|
||||
version = "v1.4.8"
|
||||
hash = "sha256-ElqfQtnoGHyVqtN0mJjeWakQ6N5x+nVaX3+uOV7Q5Xk="
|
||||
version = "v1.4.9"
|
||||
hash = "sha256-75uELLqb01djHTe7KdXvUidBK7SuejarYouEUuxaj8Q="
|
||||
[mod."github.com/gin-contrib/sse"]
|
||||
version = "v1.0.0"
|
||||
hash = "sha256-xnaabOxDN+ojnHQC7mHd/876Z9nWFScW+JrMm1HWREw="
|
||||
version = "v1.1.0"
|
||||
hash = "sha256-2VP6zHEsPi0u2ZYpOTcLulwj1Gsmb6oA19qcP2/AzVM="
|
||||
[mod."github.com/gin-gonic/gin"]
|
||||
version = "v1.10.0"
|
||||
hash = "sha256-esJasHrJtuTBwGPGAoc/XSb428J8va+tPGcZ0gTfsgc="
|
||||
@@ -83,8 +83,8 @@ schema = 3
|
||||
version = "v5.6.2"
|
||||
hash = "sha256-VgbxcLkHjiSyRIfKS7E9Sn8OynCrMGUDkwFz6K2TVL4="
|
||||
[mod."github.com/go-git/go-git/v5"]
|
||||
version = "v5.13.2"
|
||||
hash = "sha256-voZQHN2OSYcoQF2bIjsdRrHT5NohZ/8q9RrmY7j2Lbc="
|
||||
version = "v5.16.0"
|
||||
hash = "sha256-01obPHvt1PG3r8XH8TgnNfcOhaYwWEkJ0TR5QGdZqmE="
|
||||
[mod."github.com/go-logr/logr"]
|
||||
version = "v1.4.2"
|
||||
hash = "sha256-/W6qGilFlZNTb9Uq48xGZ4IbsVeSwJiAMLw4wiNYHLI="
|
||||
@@ -98,8 +98,8 @@ schema = 3
|
||||
version = "v0.18.1"
|
||||
hash = "sha256-2/B2qP51zfiY+k8G0w0D03KXUc7XpWj6wKY7NjNP/9E="
|
||||
[mod."github.com/go-playground/validator/v10"]
|
||||
version = "v10.25.0"
|
||||
hash = "sha256-198CQ0f+WC7UNxCCPg6rpogez6c5ivpignJNhx+z0W4="
|
||||
version = "v10.26.0"
|
||||
hash = "sha256-/jMKICp8LTcJVt+b4YRTnJM84r7HK6aT0oqO7Q8SRs8="
|
||||
[mod."github.com/go-shiori/dom"]
|
||||
version = "v0.0.0-20230515143342-73569d674e1c"
|
||||
hash = "sha256-4lm9KZfR2XnfZU9KTG+4jqLYZqbfL74AMO4y3dKpIbg="
|
||||
@@ -125,8 +125,8 @@ schema = 3
|
||||
version = "v1.6.0"
|
||||
hash = "sha256-VWl9sqUzdOuhW0KzQlv0gwwUQClYkmZwSydHG2sALYw="
|
||||
[mod."github.com/googleapis/enterprise-certificate-proxy"]
|
||||
version = "v0.3.4"
|
||||
hash = "sha256-RVHWa0I68CTegjlXnM/GlishoZhmmwG4z+9KBucAJ1A="
|
||||
version = "v0.3.6"
|
||||
hash = "sha256-hPMF0s+X4/ul98GvVuw/ZNOupEXhIDB1yvWymZWYEbU="
|
||||
[mod."github.com/googleapis/gax-go/v2"]
|
||||
version = "v2.14.1"
|
||||
hash = "sha256-iRS/KsAVTePrvTlwA7vKcQnwY6Jz329WdgzFw0hF8wk="
|
||||
@@ -161,8 +161,8 @@ schema = 3
|
||||
version = "v1.0.2"
|
||||
hash = "sha256-+W9EIW7okXIXjWEgOaMh58eLvBZ7OshW2EhaIpNLSBU="
|
||||
[mod."github.com/ollama/ollama"]
|
||||
version = "v0.5.12"
|
||||
hash = "sha256-Uf4GZdD77RZ5KJtz3iYVRDVCHqEh0UEihzquO4/nrss="
|
||||
version = "v0.6.6"
|
||||
hash = "sha256-a2Be14e+pcJo15fM/+0ksE9HVl8I4hW6ujqbpNh9bpA="
|
||||
[mod."github.com/otiai10/copy"]
|
||||
version = "v1.14.1"
|
||||
hash = "sha256-8RR7u17SbYg9AeBXVHIv5ZMU+kHmOcx0rLUKyz6YtU0="
|
||||
@@ -170,8 +170,8 @@ schema = 3
|
||||
version = "v1.6.3"
|
||||
hash = "sha256-/FT3dYP2+UiW/qe1pxQ7HiS8et4+KHGPIMhc+8mHvzw="
|
||||
[mod."github.com/pelletier/go-toml/v2"]
|
||||
version = "v2.2.3"
|
||||
hash = "sha256-fE++SVgnCGdnFZoROHWuYjIR7ENl7k9KKxQrRTquv/o="
|
||||
version = "v2.2.4"
|
||||
hash = "sha256-8qQIPldbsS5RO8v/FW/se3ZsAyvLzexiivzJCbGRg2Q="
|
||||
[mod."github.com/pjbgf/sha1cd"]
|
||||
version = "v0.3.2"
|
||||
hash = "sha256-jdbiRhU8xc1C5c8m7BSCj71PUXHY3f7TWFfxDKKpUMk="
|
||||
@@ -185,8 +185,8 @@ schema = 3
|
||||
version = "v1.49.1"
|
||||
hash = "sha256-xMQS9Sx2Bpvwo/9JvSVkJ4RXYOSHm642WRqWA6y0AnU="
|
||||
[mod."github.com/sashabaranov/go-openai"]
|
||||
version = "v1.38.0"
|
||||
hash = "sha256-p6C/7oTWgnRjZLNrLLdIzaXvm+1WCrUd1fjZkjuiz1s="
|
||||
version = "v1.38.2"
|
||||
hash = "sha256-AnBycaxufzWlLS1YBq7MiHDED+Jqtu9oAySKcoL4HOA="
|
||||
[mod."github.com/sergi/go-diff"]
|
||||
version = "v1.3.2-0.20230802210424-5b0b94c5c0d3"
|
||||
hash = "sha256-UcLU83CPMbSoKI8RLvLJ7nvGaE2xRSL1RjoHCVkMzUM="
|
||||
@@ -221,59 +221,59 @@ schema = 3
|
||||
version = "v1.1.0"
|
||||
hash = "sha256-cA9qCCu8P1NSJRxgmpfkfa5rKyn9X+Y/9FSmSd5xjyo="
|
||||
[mod."go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"]
|
||||
version = "v0.59.0"
|
||||
hash = "sha256-jItb6nG5/urw6Pv3zb8i5ywianqTQfrheyAIsPIQcnY="
|
||||
version = "v0.60.0"
|
||||
hash = "sha256-DkIpL4xUy+UIQBUK6VgbsI79TbZUltaIhXl4UJWym6E="
|
||||
[mod."go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"]
|
||||
version = "v0.59.0"
|
||||
hash = "sha256-zeC30S2MV7W2xxS5rVfPGhZO4jcdPpxxfy3QvBkt/pQ="
|
||||
version = "v0.60.0"
|
||||
hash = "sha256-twGSnNbXzcw5qvRiFc/zz5rS+nhmbgSVPcd5jrZjlDg="
|
||||
[mod."go.opentelemetry.io/otel"]
|
||||
version = "v1.34.0"
|
||||
hash = "sha256-hnuuTSxaf9yMO/23xWdcTGNzvnnJiqUiL4nzYwUV5bc="
|
||||
version = "v1.35.0"
|
||||
hash = "sha256-LHrBtBnyDtvJGtrXHMPIFe7U53B4bZzpePB4u8Xo4Bg="
|
||||
[mod."go.opentelemetry.io/otel/metric"]
|
||||
version = "v1.34.0"
|
||||
hash = "sha256-JklGKJiMf1fpsE9pmnuLUq26g6wVp173v4GWJ7Xp5s4="
|
||||
version = "v1.35.0"
|
||||
hash = "sha256-K9I0LRZqSLrC09Cuk7tp0VEk3cUVDs8S5MGnu9jw92Q="
|
||||
[mod."go.opentelemetry.io/otel/trace"]
|
||||
version = "v1.34.0"
|
||||
hash = "sha256-u11KJ4WTDtcb0tVv7d/HOdhq8Ea+c1QPBO8MbsCQu9Q="
|
||||
version = "v1.35.0"
|
||||
hash = "sha256-HC2+OGDe2rg0+E8WymQbUNoc249NXM1gIBJzK4UhcQE="
|
||||
[mod."golang.org/x/arch"]
|
||||
version = "v0.14.0"
|
||||
hash = "sha256-9akWthLBB+Au/JIg3WKcSx1YAfHEHOCnQF62sJoMJG4="
|
||||
version = "v0.16.0"
|
||||
hash = "sha256-+DMOuIw9GVyhM4VHdYCZepTU/EEHqDfrxJ2F83TOs5k="
|
||||
[mod."golang.org/x/crypto"]
|
||||
version = "v0.35.0"
|
||||
hash = "sha256-XT1VU0+m1nZbhrMYXN2+eaKBlScfiT4bCBgXu4mfa1Q="
|
||||
version = "v0.37.0"
|
||||
hash = "sha256-9NwDEcii1e2JYM/+3y1yNzWnt/ChMm27e9OtfuF39OM="
|
||||
[mod."golang.org/x/net"]
|
||||
version = "v0.36.0"
|
||||
hash = "sha256-2c9AvnizBMCaqKPzwF2IMlRfvjRNDFmxIYhrgZjhOm0="
|
||||
version = "v0.39.0"
|
||||
hash = "sha256-IP29+yGphWKUT7wHTyzqA2rnRT4AJ7oWcT6NKLzkWcM="
|
||||
[mod."golang.org/x/oauth2"]
|
||||
version = "v0.27.0"
|
||||
hash = "sha256-TBKV2c/m0SgPqrJSE0ltJXfImrYPafNuziLN25jgsYY="
|
||||
version = "v0.29.0"
|
||||
hash = "sha256-IzAypzW8cN5ZbQiIdMTcTiVuUNpMSkwuxeFrJZxcDl8="
|
||||
[mod."golang.org/x/sync"]
|
||||
version = "v0.11.0"
|
||||
hash = "sha256-5ZBfDJvNaUBM4Vhk0fgYblCGL3eBxiJL85nIE8LiKl0="
|
||||
version = "v0.13.0"
|
||||
hash = "sha256-CElRNe74Or/ysUkb/m3Wcz/juO/tB5fhQbAaxA5AizY="
|
||||
[mod."golang.org/x/sys"]
|
||||
version = "v0.30.0"
|
||||
hash = "sha256-BuhWtwDkciVioc03rxty6G2vcZVnPX85lI7tgQOFVP8="
|
||||
version = "v0.32.0"
|
||||
hash = "sha256-c9RRnyKQy9Kl8hpbtcgkm1O5H7gOdk9Rv925F8fZS6E="
|
||||
[mod."golang.org/x/text"]
|
||||
version = "v0.22.0"
|
||||
hash = "sha256-kUwLNFk9K/YuWmO5/u2IshrmhT2CCuk+mAShSlTTeZo="
|
||||
version = "v0.24.0"
|
||||
hash = "sha256-qFbmteGOvJfvbLXiOSI8Fsz5Ixt2ZhSYx0/sIqApC7Y="
|
||||
[mod."golang.org/x/time"]
|
||||
version = "v0.10.0"
|
||||
hash = "sha256-vnlAME3gDR6R4cbCmSYAlR1Rjc0yUpkufTOPNvCdf6Q="
|
||||
version = "v0.11.0"
|
||||
hash = "sha256-ImTej/e5iUHbWPZMA4M2GYbsbiiZQxIrgcnYsc7uD68="
|
||||
[mod."google.golang.org/api"]
|
||||
version = "v0.223.0"
|
||||
hash = "sha256-sNLRocS4vcjPj0vsInI/ioZ29rSVdGD0bGz8ZzBSbus="
|
||||
version = "v0.230.0"
|
||||
hash = "sha256-ihEdZnRbQdwpbgj9AZEZLNY14FqHmacFGFocOqExSVY="
|
||||
[mod."google.golang.org/genproto/googleapis/api"]
|
||||
version = "v0.0.0-20250224174004-546df14abb99"
|
||||
hash = "sha256-8er5KyVDLmuuOZEDd8cHHTkpb/JifejdHwcHfqAD83o="
|
||||
version = "v0.0.0-20250422160041-2d3770c4ea7f"
|
||||
hash = "sha256-Y4wbEHh9Un0QKplTl2S5lhWDUha9QThx5DhWJbDG9fo="
|
||||
[mod."google.golang.org/genproto/googleapis/rpc"]
|
||||
version = "v0.0.0-20250224174004-546df14abb99"
|
||||
hash = "sha256-l/2ByVhr10DBqSp5y1d8mtEY3++RUZKg89FCEptT0nQ="
|
||||
version = "v0.0.0-20250422160041-2d3770c4ea7f"
|
||||
hash = "sha256-WK7iDtAhH19NPe3TywTQlGjDawNaDKWnxhFL9PgVUwM="
|
||||
[mod."google.golang.org/grpc"]
|
||||
version = "v1.70.0"
|
||||
hash = "sha256-7SCJx6Y35O/0P3cFtELDXrOSOb+HshxaTQYdzv2gVmg="
|
||||
version = "v1.72.0"
|
||||
hash = "sha256-tqu+ACMfKjhqdCGN3jLEmtaHB5ywgHGaS/eDeDRnf+M="
|
||||
[mod."google.golang.org/protobuf"]
|
||||
version = "v1.36.5"
|
||||
hash = "sha256-isupBiQUrKPEFzK94k5cgzM3Ab5fMXp352/zcsXV1JU="
|
||||
version = "v1.36.6"
|
||||
hash = "sha256-lT5qnefI5FDJnowz9PEkAGylH3+fE+A3DJDkAyy9RMc="
|
||||
[mod."gopkg.in/warnings.v0"]
|
||||
version = "v0.1.2"
|
||||
hash = "sha256-ATVL9yEmgYbkJ1DkltDGRn/auGAjqGOfjQyBYyUo8s8="
|
||||
|
||||
@@ -1 +1 @@
|
||||
"1.4.168"
|
||||
"1.4.185"
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
pkgs,
|
||||
gomod2nix,
|
||||
goEnv,
|
||||
goVersion,
|
||||
}:
|
||||
|
||||
{
|
||||
default = pkgs.mkShell {
|
||||
nativeBuildInputs = [
|
||||
pkgs.go
|
||||
goVersion
|
||||
pkgs.gopls
|
||||
pkgs.gotools
|
||||
pkgs.go-tools
|
||||
|
||||
20
patterns/analyze_bill/system.md
Normal file
20
patterns/analyze_bill/system.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# IDENTITY
|
||||
|
||||
You are an AI with a 3,129 IQ that specializes in discerning the true nature and goals of a piece of legislation.
|
||||
|
||||
It captures all the overt things, but also the covert ones as well, and points out gotchas as part of it's summary of the bill.
|
||||
|
||||
# STEPS
|
||||
|
||||
1. Read the entire bill 37 times using different perspectives.
|
||||
2. Map out all the stuff it's trying to do on a 10 KM by 10K mental whiteboard.
|
||||
3. Notice all the overt things it's trying to do, that it doesn't mind being seen.
|
||||
4. Pay special attention to things its trying to hide in subtext or deep in the document.
|
||||
|
||||
# OUTPUT
|
||||
|
||||
1. Give the metadata for the bill, such as who proposed it, when, etc.
|
||||
2. Create a 24-word summary of the bill and what it's trying to accomplish.
|
||||
3. Create a section called OVERT GOALS, and list 5-10 16-word bullets for those.
|
||||
4. Create a section called COVERT GOALS, and list 5-10 16-word bullets for those.
|
||||
5. Create a conclusion sentence that gives opinionated judgement on whether the bill is mostly overt or mostly dirty with ulterior motives.
|
||||
20
patterns/analyze_bill_short/system.md
Normal file
20
patterns/analyze_bill_short/system.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# IDENTITY
|
||||
|
||||
You are an AI with a 3,129 IQ that specializes in discerning the true nature and goals of a piece of legislation.
|
||||
|
||||
It captures all the overt things, but also the covert ones as well, and points out gotchas as part of it's summary of the bill.
|
||||
|
||||
# STEPS
|
||||
|
||||
1. Read the entire bill 37 times using different perspectives.
|
||||
2. Map out all the stuff it's trying to do on a 10 KM by 10K mental whiteboard.
|
||||
3. Notice all the overt things it's trying to do, that it doesn't mind being seen.
|
||||
4. Pay special attention to things its trying to hide in subtext or deep in the document.
|
||||
|
||||
# OUTPUT
|
||||
|
||||
1. Give the metadata for the bill, such as who proposed it, when, etc.
|
||||
2. Create a 16-word summary of the bill and what it's trying to accomplish.
|
||||
3. Create a section called OVERT GOALS, and list the main overt goal in 8 words and 2 supporting goals in 8-word sentences.
|
||||
3. Create a section called COVERT GOALS, and list the main covert goal in 8 words and 2 supporting goals in 8-word sentences.
|
||||
5. Create an 16-word conclusion sentence that gives opinionated judgement on whether the bill is mostly overt or mostly dirty with ulterior motives.
|
||||
131
patterns/create_excalidraw_visualization/system.md
Normal file
131
patterns/create_excalidraw_visualization/system.md
Normal file
@@ -0,0 +1,131 @@
|
||||
# IDENTITY
|
||||
|
||||
You are an expert AI with a 1,222 IQ that deeply understands the relationships between complex ideas and concepts. You are also an expert in the Excalidraw tool and schema.
|
||||
|
||||
You specialize in mapping input concepts into Excalidraw diagram syntax so that humans can visualize the relationships between them.
|
||||
|
||||
# STEPS
|
||||
|
||||
1. Deeply study the input.
|
||||
2. Think for 47 minutes about each of the sections in the input.
|
||||
3. Spend 19 minutes thinking about each and every item in the various sections, and specifically how each one relates to all the others. E.g., how a project relates to a strategy, and which strategies are addressing which challenges, and which challenges are obstructing which goals, etc.
|
||||
4. Build out this full mapping in on a 9KM x 9KM whiteboard in your mind.
|
||||
5. Analyze and improve this mapping for 13 minutes.
|
||||
|
||||
# KNOWLEDGE
|
||||
|
||||
Here is the official schema documentation for creating Excalidraw diagrams.
|
||||
|
||||
Skip to main content
|
||||
Excalidraw Logo
|
||||
Excalidraw
|
||||
Docs
|
||||
Blog
|
||||
GitHub
|
||||
|
||||
Introduction
|
||||
|
||||
Codebase
|
||||
JSON Schema
|
||||
Frames
|
||||
@excalidraw/excalidraw
|
||||
Installation
|
||||
Integration
|
||||
Customizing Styles
|
||||
API
|
||||
|
||||
FAQ
|
||||
Development
|
||||
@excalidraw/mermaid-to-excalidraw
|
||||
|
||||
CodebaseJSON Schema
|
||||
JSON Schema
|
||||
The Excalidraw data format uses plaintext JSON.
|
||||
|
||||
Excalidraw files
|
||||
When saving an Excalidraw scene locally to a file, the JSON file (.excalidraw) is using the below format.
|
||||
|
||||
Attributes
|
||||
Attribute Description Value
|
||||
type The type of the Excalidraw schema "excalidraw"
|
||||
version The version of the Excalidraw schema number
|
||||
source The source URL of the Excalidraw application "https://excalidraw.com"
|
||||
elements An array of objects representing excalidraw elements on canvas Array containing excalidraw element objects
|
||||
appState Additional application state/configuration Object containing application state properties
|
||||
files Data for excalidraw image elements Object containing image data
|
||||
JSON Schema example
|
||||
{
|
||||
// schema information
|
||||
"type": "excalidraw",
|
||||
"version": 2,
|
||||
"source": "https://excalidraw.com",
|
||||
|
||||
// elements on canvas
|
||||
"elements": [
|
||||
// example element
|
||||
{
|
||||
"id": "pologsyG-tAraPgiN9xP9b",
|
||||
"type": "rectangle",
|
||||
"x": 928,
|
||||
"y": 319,
|
||||
"width": 134,
|
||||
"height": 90
|
||||
/* ...other element properties */
|
||||
}
|
||||
/* other elements */
|
||||
],
|
||||
|
||||
// editor state (canvas config, preferences, ...)
|
||||
"appState": {
|
||||
"gridSize": 20,
|
||||
"viewBackgroundColor": "#ffffff"
|
||||
},
|
||||
|
||||
// files data for "image" elements, using format `{ [fileId]: fileData }`
|
||||
"files": {
|
||||
// example of an image data object
|
||||
"3cebd7720911620a3938ce77243696149da03861": {
|
||||
"mimeType": "image/png",
|
||||
"id": "3cebd7720911620a3938c.77243626149da03861",
|
||||
"dataURL": "data:image/png;base64,iVBORWOKGgoAAAANSUhEUgA=",
|
||||
"created": 1690295874454,
|
||||
"lastRetrieved": 1690295874454
|
||||
}
|
||||
/* ...other image data objects */
|
||||
}
|
||||
}
|
||||
|
||||
Excalidraw clipboard format
|
||||
When copying selected excalidraw elements to clipboard, the JSON schema is similar to .excalidraw format, except it differs in attributes.
|
||||
|
||||
Attributes
|
||||
Attribute Description Example Value
|
||||
type The type of the Excalidraw document. "excalidraw/clipboard"
|
||||
elements An array of objects representing excalidraw elements on canvas. Array containing excalidraw element objects (see example below)
|
||||
files Data for excalidraw image elements. Object containing image data
|
||||
Edit this page
|
||||
Previous
|
||||
Contributing
|
||||
Next
|
||||
Frames
|
||||
Excalidraw files
|
||||
Attributes
|
||||
JSON Schema example
|
||||
Excalidraw clipboard format
|
||||
Attributes
|
||||
Docs
|
||||
Get Started
|
||||
Community
|
||||
Discord
|
||||
Twitter
|
||||
Linkedin
|
||||
More
|
||||
Blog
|
||||
GitHub
|
||||
Copyright © 2023 Excalidraw community. Built with Docusaurus ❤️
|
||||
|
||||
# OUTPUT
|
||||
|
||||
1. Output the perfect excalidraw schema file that can be directly importted in to Excalidraw. This should have no preamble or follow-on text that breaks the format. It should be pure Excalidraw schema JSON.
|
||||
2. Ensure all components are high contrast on a white background, and that you include all the arrows and appropriate relationship components that preserve the meaning of the original input.
|
||||
3. Do not output the first and last lines of the schema, , e.g., json and backticks and then ending backticks. as this is automatically added by Excalidraw when importing.
|
||||
@@ -52,18 +52,18 @@ type Client struct {
|
||||
defaultRequiredUserMessage string
|
||||
models []string
|
||||
|
||||
client *anthropic.Client
|
||||
client anthropic.Client
|
||||
}
|
||||
|
||||
func (an *Client) configure() (err error) {
|
||||
if an.ApiBaseURL.Value != "" {
|
||||
baseURL := an.ApiBaseURL.Value
|
||||
|
||||
if strings.Contains(baseURL, "-") && !strings.HasSuffix(baseURL, "/v1") {
|
||||
if strings.HasSuffix(baseURL, "/") {
|
||||
baseURL = strings.TrimSuffix(baseURL, "/")
|
||||
}
|
||||
baseURL = baseURL + "/v1"
|
||||
// As of 2.0beta1, using v2 API endpoint.
|
||||
// https://github.com/anthropics/anthropic-sdk-go/blob/main/CHANGELOG.md#020-beta1-2025-03-25
|
||||
if strings.Contains(baseURL, "-") && !strings.HasSuffix(baseURL, "/v2") {
|
||||
baseURL = strings.TrimSuffix(baseURL, "/")
|
||||
baseURL = baseURL + "/v2"
|
||||
}
|
||||
|
||||
an.client = anthropic.NewClient(
|
||||
@@ -87,21 +87,19 @@ func (an *Client) SendStream(
|
||||
|
||||
ctx := context.Background()
|
||||
stream := an.client.Messages.NewStreaming(ctx, anthropic.MessageNewParams{
|
||||
Model: anthropic.F(opts.Model),
|
||||
MaxTokens: anthropic.F(int64(an.maxTokens)),
|
||||
TopP: anthropic.F(opts.TopP),
|
||||
Temperature: anthropic.F(opts.Temperature),
|
||||
Messages: anthropic.F(messages),
|
||||
Model: opts.Model,
|
||||
MaxTokens: int64(an.maxTokens),
|
||||
TopP: anthropic.Opt(opts.TopP),
|
||||
Temperature: anthropic.Opt(opts.Temperature),
|
||||
Messages: messages,
|
||||
})
|
||||
|
||||
for stream.Next() {
|
||||
event := stream.Current()
|
||||
|
||||
switch delta := event.Delta.(type) {
|
||||
case anthropic.ContentBlockDeltaEventDelta:
|
||||
if delta.Text != "" {
|
||||
channel <- delta.Text
|
||||
}
|
||||
// directly send any non-empty delta text
|
||||
if event.Delta.Text != "" {
|
||||
channel <- event.Delta.Text
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,11 +115,11 @@ func (an *Client) Send(ctx context.Context, msgs []*goopenai.ChatCompletionMessa
|
||||
|
||||
var message *anthropic.Message
|
||||
if message, err = an.client.Messages.New(ctx, anthropic.MessageNewParams{
|
||||
Model: anthropic.F(opts.Model),
|
||||
MaxTokens: anthropic.F(int64(an.maxTokens)),
|
||||
TopP: anthropic.F(opts.TopP),
|
||||
Temperature: anthropic.F(opts.Temperature),
|
||||
Messages: anthropic.F(messages),
|
||||
Model: opts.Model,
|
||||
MaxTokens: int64(an.maxTokens),
|
||||
TopP: anthropic.Opt(opts.TopP),
|
||||
Temperature: anthropic.Opt(opts.Temperature),
|
||||
Messages: messages,
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
package deepseek
|
||||
|
||||
import (
|
||||
"github.com/danielmiessler/fabric/plugins/ai/openai"
|
||||
)
|
||||
|
||||
func NewClient() (ret *Client) {
|
||||
ret = &Client{}
|
||||
ret.Client = openai.NewClientCompatible("DeepSeek", "https://api.deepseek.com", nil)
|
||||
return
|
||||
}
|
||||
|
||||
type Client struct {
|
||||
*openai.Client
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package deepseek
|
||||
|
||||
// Test generated using Keploy
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNewClient_EmbeddedClientNotNil(t *testing.T) {
|
||||
client := NewClient()
|
||||
if client.Client == nil {
|
||||
t.Fatalf("Expected embedded openai.Client to be non-nil, got nil")
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package groq
|
||||
|
||||
import (
|
||||
"github.com/danielmiessler/fabric/plugins/ai/openai"
|
||||
)
|
||||
|
||||
// NewClient initializes and returns a new Groq Client.
|
||||
func NewClient() (ret *Client) {
|
||||
ret = &Client{}
|
||||
ret.Client = openai.NewClientCompatible("Groq", "https://api.groq.com/openai/v1", nil)
|
||||
return
|
||||
}
|
||||
|
||||
// Client wraps the openai.Client to provide additional functionality specific to Groq.
|
||||
type Client struct {
|
||||
*openai.Client
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package groq
|
||||
|
||||
// Test generated using Keploy
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNewClientEmbeddedClientNotNil(t *testing.T) {
|
||||
client := NewClient()
|
||||
if client.Client == nil {
|
||||
t.Fatalf("Expected embedded openai.Client to be non-nil, got nil")
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package litellm
|
||||
|
||||
import (
|
||||
"github.com/danielmiessler/fabric/plugins/ai/openai"
|
||||
)
|
||||
|
||||
func NewClient() (ret *Client) {
|
||||
ret = &Client{}
|
||||
ret.Client = openai.NewClientCompatible("LiteLLM", "http://localhost:4000", nil)
|
||||
return
|
||||
}
|
||||
|
||||
type Client struct {
|
||||
*openai.Client
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package mistral
|
||||
|
||||
import (
|
||||
"github.com/danielmiessler/fabric/plugins/ai/openai"
|
||||
)
|
||||
|
||||
func NewClient() (ret *Client) {
|
||||
ret = &Client{}
|
||||
ret.Client = openai.NewClientCompatible("Mistral", "https://api.mistral.ai/v1", nil)
|
||||
return
|
||||
}
|
||||
|
||||
type Client struct {
|
||||
*openai.Client
|
||||
}
|
||||
74
plugins/ai/openai_compatible/providers_config.go
Normal file
74
plugins/ai/openai_compatible/providers_config.go
Normal file
@@ -0,0 +1,74 @@
|
||||
package openai_compatible
|
||||
|
||||
import (
|
||||
"github.com/danielmiessler/fabric/plugins/ai/openai"
|
||||
)
|
||||
|
||||
// ProviderConfig defines the configuration for an OpenAI-compatible API provider
|
||||
type ProviderConfig struct {
|
||||
Name string
|
||||
BaseURL string
|
||||
}
|
||||
|
||||
// Client is the common structure for all OpenAI-compatible providers
|
||||
type Client struct {
|
||||
*openai.Client
|
||||
}
|
||||
|
||||
// NewClient creates a new OpenAI-compatible client for the specified provider
|
||||
func NewClient(providerConfig ProviderConfig) *Client {
|
||||
client := &Client{}
|
||||
client.Client = openai.NewClientCompatible(providerConfig.Name, providerConfig.BaseURL, nil)
|
||||
return client
|
||||
}
|
||||
|
||||
// ProviderMap is a map of provider name to ProviderConfig for O(1) lookup
|
||||
var ProviderMap = map[string]ProviderConfig{
|
||||
"Mistral": {
|
||||
Name: "Mistral",
|
||||
BaseURL: "https://api.mistral.ai/v1",
|
||||
},
|
||||
"LiteLLM": {
|
||||
Name: "LiteLLM",
|
||||
BaseURL: "http://localhost:4000",
|
||||
},
|
||||
"Groq": {
|
||||
Name: "Groq",
|
||||
BaseURL: "https://api.groq.com/openai/v1",
|
||||
},
|
||||
"GrokAI": {
|
||||
Name: "GrokAI",
|
||||
BaseURL: "https://api.x.ai/v1",
|
||||
},
|
||||
"DeepSeek": {
|
||||
Name: "DeepSeek",
|
||||
BaseURL: "https://api.deepseek.com",
|
||||
},
|
||||
"Cerebras": {
|
||||
Name: "Cerebras",
|
||||
BaseURL: "https://api.cerebras.ai/v1",
|
||||
},
|
||||
"OpenRouter": {
|
||||
Name: "OpenRouter",
|
||||
BaseURL: "https://openrouter.ai/api/v1",
|
||||
},
|
||||
"SiliconCloud": {
|
||||
Name: "SiliconCloud",
|
||||
BaseURL: "https://api.siliconflow.cn/v1",
|
||||
},
|
||||
}
|
||||
|
||||
// GetProviderByName returns the provider configuration for a given name with O(1) lookup
|
||||
func GetProviderByName(name string) (ProviderConfig, bool) {
|
||||
provider, found := ProviderMap[name]
|
||||
return provider, found
|
||||
}
|
||||
|
||||
// CreateClient creates a new client for a provider by name
|
||||
func CreateClient(providerName string) (*Client, bool) {
|
||||
providerConfig, found := GetProviderByName(providerName)
|
||||
if !found {
|
||||
return nil, false
|
||||
}
|
||||
return NewClient(providerConfig), true
|
||||
}
|
||||
42
plugins/ai/openai_compatible/providers_config_test.go
Normal file
42
plugins/ai/openai_compatible/providers_config_test.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package openai_compatible
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCreateClient(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
provider string
|
||||
exists bool
|
||||
}{
|
||||
{
|
||||
name: "Existing provider - Mistral",
|
||||
provider: "Mistral",
|
||||
exists: true,
|
||||
},
|
||||
{
|
||||
name: "Existing provider - Groq",
|
||||
provider: "Groq",
|
||||
exists: true,
|
||||
},
|
||||
{
|
||||
name: "Non-existent provider",
|
||||
provider: "NonExistent",
|
||||
exists: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
client, exists := CreateClient(tc.provider)
|
||||
if exists != tc.exists {
|
||||
t.Errorf("Expected exists=%v for provider %s, got %v",
|
||||
tc.exists, tc.provider, exists)
|
||||
}
|
||||
if exists && client == nil {
|
||||
t.Errorf("Expected non-nil client for provider %s", tc.provider)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package openrouter
|
||||
|
||||
import (
|
||||
"github.com/danielmiessler/fabric/plugins/ai/openai"
|
||||
)
|
||||
|
||||
func NewClient() (ret *Client) {
|
||||
ret = &Client{}
|
||||
ret.Client = openai.NewClientCompatible("OpenRouter", "https://openrouter.ai/api/v1", nil)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
type Client struct {
|
||||
*openai.Client
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
package openrouter
|
||||
@@ -1,15 +0,0 @@
|
||||
package siliconcloud
|
||||
|
||||
import (
|
||||
"github.com/danielmiessler/fabric/plugins/ai/openai"
|
||||
)
|
||||
|
||||
func NewClient() (ret *Client) {
|
||||
ret = &Client{}
|
||||
ret.Client = openai.NewClientCompatible("SiliconCloud", "https://api.siliconflow.cn/v1", nil)
|
||||
return
|
||||
}
|
||||
|
||||
type Client struct {
|
||||
*openai.Client
|
||||
}
|
||||
@@ -4,6 +4,8 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/danielmiessler/fabric/plugins"
|
||||
@@ -95,6 +97,9 @@ func (o *VendorsManager) readModels() (err error) {
|
||||
if result.err != nil {
|
||||
fmt.Println(result.vendorName, result.err)
|
||||
} else {
|
||||
sort.Slice(result.models, func(i, j int) bool {
|
||||
return strings.ToLower(result.models[i]) < strings.ToLower(result.models[j])
|
||||
})
|
||||
o.Models.AddGroupItems(result.vendorName, result.models...)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,5 +9,5 @@ type Storage[T any] interface {
|
||||
Rename(oldName, newName string) (err error)
|
||||
Save(name string, content []byte) (err error)
|
||||
Load(name string) (ret []byte, err error)
|
||||
ListNames() (err error)
|
||||
ListNames(shellCompleteList bool) (err error)
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ func (o *StorageEntity) GetNames() (ret []string, err error) {
|
||||
}
|
||||
|
||||
func (o *StorageEntity) Delete(name string) (err error) {
|
||||
if err = os.Remove(o.BuildFilePathByName(name)); err != nil {
|
||||
if err = os.RemoveAll(o.BuildFilePathByName(name)); err != nil {
|
||||
err = fmt.Errorf("could not delete %s: %v", name, err)
|
||||
}
|
||||
return
|
||||
@@ -100,14 +100,16 @@ func (o *StorageEntity) Load(name string) (ret []byte, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (o *StorageEntity) ListNames() (err error) {
|
||||
func (o *StorageEntity) ListNames(shellCompleteList bool) (err error) {
|
||||
var names []string
|
||||
if names, err = o.GetNames(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if len(names) == 0 {
|
||||
fmt.Printf("\nNo %v\n", o.Label)
|
||||
if !shellCompleteList {
|
||||
fmt.Printf("\nNo %v\n", o.Label)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -197,12 +197,13 @@ func LoadStrategy(filename string) (*Strategy, error) {
|
||||
}
|
||||
|
||||
// ListStrategies prints available strategies
|
||||
func (sm *StrategiesManager) ListStrategies() error {
|
||||
func (sm *StrategiesManager) ListStrategies(shellCompleteList bool) error {
|
||||
if len(sm.Strategies) == 0 {
|
||||
return fmt.Errorf("no strategies found. Please run 'fabric --setup' to download strategies")
|
||||
}
|
||||
fmt.Print("Available Strategies:\n\n")
|
||||
|
||||
if !shellCompleteList {
|
||||
fmt.Print("Available Strategies:\n\n")
|
||||
}
|
||||
// Get all strategy names for sorting
|
||||
names := []string{}
|
||||
for name := range sm.Strategies {
|
||||
@@ -224,7 +225,11 @@ func (sm *StrategiesManager) ListStrategies() error {
|
||||
formatString := "%-" + fmt.Sprintf("%d", maxNameLength+2) + "s %s\n"
|
||||
for _, name := range names {
|
||||
strategy := sm.Strategies[name]
|
||||
fmt.Printf(formatString, strategy.Name, strategy.Description)
|
||||
if shellCompleteList {
|
||||
fmt.Printf("%s\n", strategy.Name)
|
||||
} else {
|
||||
fmt.Printf(formatString, strategy.Name, strategy.Description)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -117,8 +117,12 @@ func (e *ExtensionExecutor) executeWithFile(cmd *exec.Cmd, ext *ExtensionDefinit
|
||||
// Create context with timeout
|
||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||
defer cancel()
|
||||
// Store the original environment
|
||||
originalEnv := cmd.Env
|
||||
// Create a new command with context. This might reset Env, depending on the Go version.
|
||||
cmd = exec.CommandContext(ctx, cmd.Path, cmd.Args[1:]...)
|
||||
cmd.Env = cmd.Env
|
||||
// Restore the environment variables explicitly
|
||||
cmd.Env = originalEnv
|
||||
|
||||
fileConfig := ext.GetFileConfig()
|
||||
if fileConfig == nil {
|
||||
|
||||
@@ -47,7 +47,7 @@ func (o *Defaults) Setup() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
vendorsModels.Print()
|
||||
vendorsModels.Print(false)
|
||||
|
||||
if err = o.Ask(o.Name); err != nil {
|
||||
return
|
||||
|
||||
@@ -3,8 +3,11 @@ package restapi
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
goopenai "github.com/sashabaranov/go-openai"
|
||||
@@ -21,15 +24,17 @@ type ChatHandler struct {
|
||||
}
|
||||
|
||||
type PromptRequest struct {
|
||||
UserInput string `json:"userInput"`
|
||||
Vendor string `json:"vendor"`
|
||||
Model string `json:"model"`
|
||||
ContextName string `json:"contextName"`
|
||||
PatternName string `json:"patternName"`
|
||||
UserInput string `json:"userInput"`
|
||||
Vendor string `json:"vendor"`
|
||||
Model string `json:"model"`
|
||||
ContextName string `json:"contextName"`
|
||||
PatternName string `json:"patternName"`
|
||||
StrategyName string `json:"strategyName"` // Optional strategy name
|
||||
}
|
||||
|
||||
type ChatRequest struct {
|
||||
Prompts []PromptRequest `json:"prompts"`
|
||||
Language string `json:"language"` // Add Language field to bind from request
|
||||
common.ChatOptions // Embed the ChatOptions from common package
|
||||
}
|
||||
|
||||
@@ -60,7 +65,8 @@ func (h *ChatHandler) HandleChat(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
log.Printf("Received chat request with %d prompts", len(request.Prompts))
|
||||
// Add log to check received language field
|
||||
log.Printf("Received chat request - Language: '%s', Prompts: %d", request.Language, len(request.Prompts))
|
||||
|
||||
// Set headers for SSE
|
||||
c.Writer.Header().Set("Content-Type", "text/readystream")
|
||||
@@ -80,13 +86,25 @@ func (h *ChatHandler) HandleChat(c *gin.Context) {
|
||||
log.Printf("Processing prompt %d: Model=%s Pattern=%s Context=%s",
|
||||
i+1, prompt.Model, prompt.PatternName, prompt.ContextName)
|
||||
|
||||
// Create chat channel for streaming
|
||||
streamChan := make(chan string)
|
||||
|
||||
// Start chat processing in goroutine
|
||||
go func(p PromptRequest) {
|
||||
defer close(streamChan)
|
||||
|
||||
// Load and prepend strategy prompt if strategyName is set
|
||||
if p.StrategyName != "" {
|
||||
strategyFile := filepath.Join(os.Getenv("HOME"), ".config", "fabric", "strategies", p.StrategyName+".json")
|
||||
data, err := ioutil.ReadFile(strategyFile)
|
||||
if err == nil {
|
||||
var s struct {
|
||||
Prompt string `json:"prompt"`
|
||||
}
|
||||
if err := json.Unmarshal(data, &s); err == nil && s.Prompt != "" {
|
||||
p.UserInput = s.Prompt + "\n" + p.UserInput
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
chatter, err := h.registry.GetChatter(p.Model, 2048, "", false, false)
|
||||
if err != nil {
|
||||
log.Printf("Error creating chatter: %v", err)
|
||||
@@ -94,6 +112,7 @@ func (h *ChatHandler) HandleChat(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// Pass the language received in the initial request to the common.ChatRequest
|
||||
chatReq := &common.ChatRequest{
|
||||
Message: &goopenai.ChatCompletionMessage{
|
||||
Role: "user",
|
||||
@@ -101,6 +120,7 @@ func (h *ChatHandler) HandleChat(c *gin.Context) {
|
||||
},
|
||||
PatternName: p.PatternName,
|
||||
ContextName: p.ContextName,
|
||||
Language: request.Language, // Pass the language field
|
||||
}
|
||||
|
||||
opts := &common.ChatOptions{
|
||||
@@ -124,7 +144,6 @@ func (h *ChatHandler) HandleChat(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// Get the last message from the session
|
||||
lastMsg := session.GetLastMessage()
|
||||
if lastMsg != nil {
|
||||
streamChan <- lastMsg.Content
|
||||
@@ -134,37 +153,32 @@ func (h *ChatHandler) HandleChat(c *gin.Context) {
|
||||
}
|
||||
}(prompt)
|
||||
|
||||
// Read from streamChan and write to client
|
||||
for content := range streamChan {
|
||||
select {
|
||||
case <-clientGone:
|
||||
return
|
||||
default:
|
||||
var response StreamResponse
|
||||
if strings.HasPrefix(content, "Error:") {
|
||||
response := StreamResponse{
|
||||
response = StreamResponse{
|
||||
Type: "error",
|
||||
Format: "plain",
|
||||
Content: content,
|
||||
}
|
||||
if err := writeSSEResponse(c.Writer, response); err != nil {
|
||||
log.Printf("Error writing error response: %v", err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
response := StreamResponse{
|
||||
response = StreamResponse{
|
||||
Type: "content",
|
||||
Format: detectFormat(content),
|
||||
Content: content,
|
||||
}
|
||||
if err := writeSSEResponse(c.Writer, response); err != nil {
|
||||
log.Printf("Error writing content response: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
if err := writeSSEResponse(c.Writer, response); err != nil {
|
||||
log.Printf("Error writing response: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Signal completion of this prompt
|
||||
completeResponse := StreamResponse{
|
||||
Type: "complete",
|
||||
Format: "plain",
|
||||
@@ -192,26 +206,6 @@ func writeSSEResponse(w gin.ResponseWriter, response StreamResponse) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
/*
|
||||
func detectFormat(content string) string {
|
||||
if strings.HasPrefix(content, "graph TD") ||
|
||||
strings.HasPrefix(content, "gantt") ||
|
||||
strings.HasPrefix(content, "flowchart") ||
|
||||
strings.HasPrefix(content, "sequenceDiagram") ||
|
||||
strings.HasPrefix(content, "classDiagram") ||
|
||||
strings.HasPrefix(content, "stateDiagram") {
|
||||
return "mermaid"
|
||||
}
|
||||
if strings.Contains(content, "```") ||
|
||||
strings.Contains(content, "#") ||
|
||||
strings.Contains(content, "*") ||
|
||||
strings.Contains(content, "_") ||
|
||||
strings.Contains(content, "-") {
|
||||
return "markdown"
|
||||
}
|
||||
return "plain"
|
||||
}
|
||||
*/
|
||||
func detectFormat(content string) string {
|
||||
if strings.HasPrefix(content, "graph TD") ||
|
||||
strings.HasPrefix(content, "gantt") ||
|
||||
|
||||
@@ -45,6 +45,7 @@ func (h *ConfigHandler) GetConfig(c *gin.Context) {
|
||||
"openrouter": "",
|
||||
"silicon": "",
|
||||
"deepseek": "",
|
||||
"grokai": "",
|
||||
})
|
||||
return
|
||||
}
|
||||
@@ -65,6 +66,7 @@ func (h *ConfigHandler) GetConfig(c *gin.Context) {
|
||||
"openrouter": os.Getenv("OPENROUTER_API_KEY"),
|
||||
"silicon": os.Getenv("SILICON_API_KEY"),
|
||||
"deepseek": os.Getenv("DEEPSEEK_API_KEY"),
|
||||
"grokai": os.Getenv("GROKAI_API_KEY"),
|
||||
"lmstudio": os.Getenv("LM_STUDIO_API_BASE_URL"),
|
||||
}
|
||||
|
||||
@@ -87,6 +89,7 @@ func (h *ConfigHandler) UpdateConfig(c *gin.Context) {
|
||||
OpenRouterApiKey string `json:"openrouter_api_key"`
|
||||
SiliconApiKey string `json:"silicon_api_key"`
|
||||
DeepSeekApiKey string `json:"deepseek_api_key"`
|
||||
GrokaiApiKey string `json:"grokai_api_key"`
|
||||
LMStudioURL string `json:"lm_studio_base_url"`
|
||||
}
|
||||
|
||||
@@ -105,6 +108,7 @@ func (h *ConfigHandler) UpdateConfig(c *gin.Context) {
|
||||
"OPENROUTER_API_KEY": config.OpenRouterApiKey,
|
||||
"SILICON_API_KEY": config.SiliconApiKey,
|
||||
"DEEPSEEK_API_KEY": config.DeepSeekApiKey,
|
||||
"GROKAI_API_KEY": config.GrokaiApiKey,
|
||||
"LM_STUDIO_API_BASE_URL": config.LMStudioURL,
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ func Serve(registry *core.PluginRegistry, address string, apiKey string) (err er
|
||||
NewChatHandler(r, registry, fabricDb)
|
||||
NewConfigHandler(r, fabricDb)
|
||||
NewModelsHandler(r, registry.VendorManager)
|
||||
NewStrategiesHandler(r)
|
||||
|
||||
// Start server
|
||||
err = r.Run(address)
|
||||
|
||||
62
restapi/strategies.go
Normal file
62
restapi/strategies.go
Normal file
@@ -0,0 +1,62 @@
|
||||
package restapi
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// StrategyMeta represents the minimal info about a strategy
|
||||
type StrategyMeta struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Prompt string `json:"prompt"`
|
||||
}
|
||||
|
||||
// NewStrategiesHandler registers the /strategies GET endpoint
|
||||
func NewStrategiesHandler(r *gin.Engine) {
|
||||
r.GET("/strategies", func(c *gin.Context) {
|
||||
strategiesDir := filepath.Join(os.Getenv("HOME"), ".config", "fabric", "strategies")
|
||||
|
||||
files, err := ioutil.ReadDir(strategiesDir)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to read strategies directory"})
|
||||
return
|
||||
}
|
||||
|
||||
var strategies []StrategyMeta
|
||||
|
||||
for _, file := range files {
|
||||
if file.IsDir() || filepath.Ext(file.Name()) != ".json" {
|
||||
continue
|
||||
}
|
||||
|
||||
fullPath := filepath.Join(strategiesDir, file.Name())
|
||||
data, err := ioutil.ReadFile(fullPath)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
var s struct {
|
||||
Description string `json:"description"`
|
||||
Prompt string `json:"prompt"`
|
||||
}
|
||||
if err := json.Unmarshal(data, &s); err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
strategies = append(strategies, StrategyMeta{
|
||||
Name: strings.TrimSuffix(file.Name(), ".json"),
|
||||
Description: s.Description,
|
||||
Prompt: s.Prompt,
|
||||
})
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, strategies)
|
||||
})
|
||||
}
|
||||
4
strategies/aot.json
Normal file
4
strategies/aot.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"description": "Atom-of-Thought (AoT) Prompting",
|
||||
"prompt": "To solve this problem, break it down into the smallest independent 'atomic' sub-problems. For each atomic sub-problem: 1. Label it as 'Atom X: [brief description]' 2. Solve that specific subproblem completely 3. Make sure each atom can be solved independently. After solving all atomic sub-problems, provide a synthesis that combines them into a final answer. Return the final answer in the required format."
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
package main
|
||||
|
||||
var version = "v1.4.168"
|
||||
var version = "v1.4.185"
|
||||
|
||||
@@ -35,6 +35,11 @@ https://youtu.be/fcVitd4Kb98
|
||||
|
||||
The tag filtering system has been deeply integrated into the Pattern Selection interface through several UI enhancements:
|
||||
|
||||
### 5. Strategy flags
|
||||
- strategies are fetch from .config/fabric/strategies for server processing
|
||||
- for gui, they are fetched from static/strategies
|
||||
|
||||
|
||||
1. **Dual-Position Tag Panel**
|
||||
- Sliding panel positioned to the right of pattern modal
|
||||
- Dynamic toggle button that adapts position and text based on panel state
|
||||
|
||||
@@ -305,10 +305,11 @@ async function readFileContent(file: File): Promise<string> {
|
||||
}
|
||||
}
|
||||
|
||||
// Centralized language instruction logic in ChatService.ts; YouTube flow now passes plain transcript and system prompt
|
||||
async function processYouTubeURL(input: string) {
|
||||
console.log('\n=== YouTube Flow Start ===');
|
||||
const originalLanguage = get(languageStore);
|
||||
|
||||
|
||||
try {
|
||||
// Add processing message first
|
||||
messageStore.update(messages => [...messages, {
|
||||
@@ -316,16 +317,11 @@ async function readFileContent(file: File): Promise<string> {
|
||||
content: 'Processing YouTube video...',
|
||||
format: 'loading'
|
||||
}]);
|
||||
|
||||
|
||||
// Get transcript but don't display it
|
||||
const { transcript } = await getTranscript(input);
|
||||
|
||||
// Log system prompt BEFORE createChatRequest
|
||||
console.log('System prompt BEFORE createChatRequest in YouTube flow:', $systemPrompt);
|
||||
|
||||
// Log system prompt BEFORE streamChat
|
||||
console.log(`System prompt BEFORE streamChat in YouTube flow: ${$systemPrompt}`);
|
||||
|
||||
// Pass plain transcript and system prompt; ChatService will handle language instruction
|
||||
const stream = await chatService.streamChat(transcript, $systemPrompt);
|
||||
await chatService.processStream(
|
||||
stream,
|
||||
@@ -447,21 +443,16 @@ async function readFileContent(file: File): Promise<string> {
|
||||
newMessages.splice(loadingIndex, 1);
|
||||
}
|
||||
|
||||
// Add or update the assistant message
|
||||
const assistantIndex = newMessages.findIndex(m => m.role === 'assistant');
|
||||
if (assistantIndex !== -1) {
|
||||
newMessages[assistantIndex].content = content;
|
||||
newMessages[assistantIndex].format = response?.format;
|
||||
} else {
|
||||
newMessages.push({
|
||||
role: 'assistant',
|
||||
content,
|
||||
format: response?.format
|
||||
});
|
||||
}
|
||||
// Always append a new assistant message
|
||||
newMessages.push({
|
||||
role: 'assistant',
|
||||
content,
|
||||
format: response?.format
|
||||
});
|
||||
return newMessages;
|
||||
});
|
||||
},
|
||||
|
||||
(error) => {
|
||||
// Make sure to remove loading message on error
|
||||
messageStore.update(messages =>
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
import ModelConfig from "./ModelConfig.svelte";
|
||||
import { Select } from "$lib/components/ui/select";
|
||||
import { languageStore } from '$lib/store/language-store';
|
||||
import { strategies, selectedStrategy, fetchStrategies } from '$lib/store/strategy-store';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
const languages = [
|
||||
{ code: '', name: 'Default Language' },
|
||||
@@ -15,6 +17,10 @@
|
||||
{ code: 'ja', name: 'Japanese' },
|
||||
{ code: 'it', name: 'Italian' }
|
||||
];
|
||||
|
||||
onMount(() => {
|
||||
fetchStrategies();
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="flex gap-4">
|
||||
@@ -36,6 +42,17 @@
|
||||
{/each}
|
||||
</Select>
|
||||
</div>
|
||||
<div>
|
||||
<Select
|
||||
bind:value={$selectedStrategy}
|
||||
class="bg-primary-800/30 border-none hover:bg-primary-800/40 transition-colors"
|
||||
>
|
||||
<option value="">None</option>
|
||||
{#each $strategies as strategy}
|
||||
<option value={strategy.name}>{strategy.name} - {strategy.description}</option>
|
||||
{/each}
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Right side - Model Config -->
|
||||
|
||||
@@ -15,23 +15,31 @@
|
||||
});
|
||||
|
||||
// Watch selectedPreset changes
|
||||
$: if (selectedPreset) {
|
||||
console.log('Pattern selected from dropdown:', selectedPreset);
|
||||
// Always call selectPattern when the dropdown value changes.
|
||||
// The patternAPI.selectPattern function handles empty strings correctly.
|
||||
$: {
|
||||
// Log the change regardless of the value
|
||||
console.log('Dropdown selection changed to:', selectedPreset);
|
||||
try {
|
||||
// Call the function to select the pattern (or reset if selectedPreset is empty)
|
||||
patternAPI.selectPattern(selectedPreset);
|
||||
// Verify the selection
|
||||
|
||||
// Optional: Keep verification logs if helpful for debugging
|
||||
const currentSystemPrompt = get(systemPrompt);
|
||||
const currentPattern = get(selectedPatternName);
|
||||
console.log('After dropdown selection - Pattern:', currentPattern);
|
||||
console.log('After dropdown selection - System Prompt length:', currentSystemPrompt?.length);
|
||||
|
||||
if (!currentPattern || !currentSystemPrompt) {
|
||||
console.error('Pattern selection verification failed:');
|
||||
console.error('- Selected Pattern:', currentPattern);
|
||||
console.error('- System Prompt:', currentSystemPrompt);
|
||||
}
|
||||
|
||||
// Optional: Refine verification logic if needed
|
||||
// For example, only log error if a pattern was expected but not set
|
||||
// if (selectedPreset && (!currentPattern || !currentSystemPrompt)) {
|
||||
// console.error('Pattern selection verification failed:');
|
||||
// console.error('- Selected Pattern:', currentPattern);
|
||||
// console.error('- System Prompt:', currentSystemPrompt);
|
||||
// }
|
||||
} catch (error) {
|
||||
console.error('Error in pattern selection:', error);
|
||||
// Log any errors during the pattern selection process
|
||||
console.error('Error processing pattern selection:', error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,8 @@ export interface ChatPrompt {
|
||||
userInput: string;
|
||||
systemPrompt: string;
|
||||
model: string;
|
||||
patternName: string;
|
||||
patternName?: string;
|
||||
strategyName?: string; // Optional strategy name to prepend strategy prompt
|
||||
}
|
||||
|
||||
export interface ChatConfig {
|
||||
@@ -23,6 +24,7 @@ export interface ChatRequest {
|
||||
top_p: number;
|
||||
frequency_penalty: number;
|
||||
presence_penalty: number;
|
||||
language?: string;
|
||||
}
|
||||
|
||||
export interface Message {
|
||||
|
||||
@@ -10,6 +10,7 @@ import { systemPrompt, selectedPatternName } from '$lib/store/pattern-store';
|
||||
import { chatConfig } from '$lib/store/chat-config';
|
||||
import { messageStore } from '$lib/store/chat-store';
|
||||
import { languageStore } from '$lib/store/language-store';
|
||||
import { selectedStrategy } from '$lib/store/strategy-store';
|
||||
|
||||
class LanguageValidator {
|
||||
constructor(private targetLanguage: string) {}
|
||||
@@ -47,6 +48,8 @@ export class ChatService {
|
||||
promptCount: request.prompts?.length,
|
||||
messageCount: request.messages?.length
|
||||
});
|
||||
// NEW: Log the full payload before sending to backend
|
||||
console.log('Final ChatRequest payload:', JSON.stringify(request, null, 2));
|
||||
|
||||
const response = await fetch('/api/chat', {
|
||||
method: 'POST',
|
||||
@@ -179,7 +182,8 @@ export class ChatService {
|
||||
userInput: finalUserInput,
|
||||
systemPrompt: finalSystemPrompt,
|
||||
model: config.model,
|
||||
patternName: get(selectedPatternName)
|
||||
patternName: get(selectedPatternName),
|
||||
strategyName: get(selectedStrategy) // Add selected strategy to prompt
|
||||
};
|
||||
}
|
||||
|
||||
@@ -191,10 +195,12 @@ export class ChatService {
|
||||
public async createChatRequest(userInput: string, systemPromptText?: string, isPattern: boolean = false): Promise<ChatRequest> {
|
||||
const prompt = this.createChatPrompt(userInput, systemPromptText);
|
||||
const config = get(chatConfig);
|
||||
|
||||
const language = get(languageStore);
|
||||
|
||||
return {
|
||||
prompts: [prompt],
|
||||
messages: [],
|
||||
language: language, // Add language at the top level for backend compatibility
|
||||
...config
|
||||
};
|
||||
}
|
||||
|
||||
32
web/src/lib/store/strategy-store.ts
Normal file
32
web/src/lib/store/strategy-store.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import { writable } from 'svelte/store';
|
||||
|
||||
/**
|
||||
* List of available strategies fetched from backend.
|
||||
* Each strategy has a name and description.
|
||||
*/
|
||||
export const strategies = writable<Array<{ name: string; description: string }>>([]);
|
||||
|
||||
/**
|
||||
* Currently selected strategy name.
|
||||
* Default is empty string meaning "None".
|
||||
*/
|
||||
export const selectedStrategy = writable<string>("");
|
||||
|
||||
/**
|
||||
* Fetches available strategies from the backend `/strategies` endpoint.
|
||||
* Populates the `strategies` store.
|
||||
*/
|
||||
export async function fetchStrategies() {
|
||||
try {
|
||||
const response = await fetch('/strategies/strategies.json');
|
||||
if (!response.ok) {
|
||||
console.error('Failed to fetch strategies:', response.statusText);
|
||||
return;
|
||||
}
|
||||
const data = await response.json();
|
||||
// Expecting an array of { name, description }
|
||||
strategies.set(data);
|
||||
} catch (error) {
|
||||
console.error('Error fetching strategies:', error);
|
||||
}
|
||||
}
|
||||
@@ -61,16 +61,16 @@ export const POST: RequestHandler = async ({ request }) => {
|
||||
language: body.language
|
||||
});
|
||||
|
||||
// Ensure language instruction is present
|
||||
if (body.prompts?.[0] && body.language && body.language !== 'en') {
|
||||
const languageInstruction = `. Please use the language '${body.language}' for the output.`;
|
||||
if (!body.prompts[0].userInput?.includes(languageInstruction)) {
|
||||
body.prompts[0].userInput = (body.prompts[0].userInput || '') + languageInstruction;
|
||||
}
|
||||
}
|
||||
// Removed redundant language instruction logic; Go backend handles this
|
||||
// if (body.prompts?.[0] && body.language && body.language !== 'en') {
|
||||
// const languageInstruction = `. Please use the language '${body.language}' for the output.`;
|
||||
// if (!body.prompts[0].userInput?.includes(languageInstruction)) {
|
||||
// body.prompts[0].userInput = (body.prompts[0].userInput || '') + languageInstruction;
|
||||
// }
|
||||
// }
|
||||
|
||||
console.log('2. Language analysis:', {
|
||||
input: body.prompts?.[0]?.userInput?.substring(0, 100),
|
||||
input: body.prompts?.[0]?.userInput?.substring(0, 100), // Note: This input no longer has the instruction appended here
|
||||
hasLanguageInstruction: body.prompts?.[0]?.userInput?.includes('language'),
|
||||
containsFr: body.prompts?.[0]?.userInput?.includes('fr'),
|
||||
containsEn: body.prompts?.[0]?.userInput?.includes('en'),
|
||||
|
||||
@@ -1693,8 +1693,87 @@
|
||||
},
|
||||
{
|
||||
"patternName": "extract_wisdom_short",
|
||||
"description": "Extract condensed insightful ideas and recommendations focusing on life wisdom.",
|
||||
"tags": [
|
||||
"EXTRACT",
|
||||
"WISDOM",
|
||||
"SELF"
|
||||
]
|
||||
},
|
||||
{
|
||||
"patternName": "analyze_bill",
|
||||
"description": "Analyze a legislative bill and implications.",
|
||||
"tags": [
|
||||
"ANALYSIS",
|
||||
"BILL"
|
||||
]
|
||||
},
|
||||
{
|
||||
"patternName": "analyze_bill_short",
|
||||
"description": "Consended - Analyze a legislative bill and implications.",
|
||||
"tags": [
|
||||
"ANALYSIS",
|
||||
"BILL"
|
||||
]
|
||||
},
|
||||
{
|
||||
"patternName": "create_coding_feature",
|
||||
"description": "[Description pending]",
|
||||
"tags": []
|
||||
"tags": [
|
||||
"DEVELOPMENT"
|
||||
]
|
||||
},
|
||||
{
|
||||
"patternName": "create_excalidraw_visualization",
|
||||
"description": "Create visualizations using Excalidraw.",
|
||||
"tags": [
|
||||
"VISUALIZATION"
|
||||
]
|
||||
},
|
||||
{
|
||||
"patternName": "create_flash_cards",
|
||||
"description": "Generate flashcards for key concepts and definitions.",
|
||||
"tags": [
|
||||
"LEARNING"
|
||||
]
|
||||
},
|
||||
{
|
||||
"patternName": "create_loe_document",
|
||||
"description": "Create detailed Level of Effort (LOE) estimation documents.",
|
||||
"tags": [
|
||||
"DEVELOPMENT",
|
||||
"BUSINESS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"patternName": "extract_domains",
|
||||
"description": "Extract key content and source.",
|
||||
"tags": [
|
||||
"EXTRACT",
|
||||
"ANALYSIS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"patternName": "extract_main_activities",
|
||||
"description": "Extract and list main events from transcripts.",
|
||||
"tags": [
|
||||
"EXTRACT",
|
||||
"ANALYSIS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"patternName": "find_female_life_partner",
|
||||
"description": "Clarify and summarize partner criteria in direct language.",
|
||||
"tags": [
|
||||
"SELF"
|
||||
]
|
||||
},
|
||||
{
|
||||
"patternName": "youtube_summary",
|
||||
"description": "Summarize YouTube videos with key points and timestamps.",
|
||||
"tags": [
|
||||
"SUMMARIZE"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
11
web/static/strategies/strategies.json
Normal file
11
web/static/strategies/strategies.json
Normal file
@@ -0,0 +1,11 @@
|
||||
[
|
||||
{ "name": "aot", "description": "Atom-of-Thought (AoT)" },
|
||||
{ "name": "cod", "description": "Chain-of-Draft (CoD)" },
|
||||
{ "name": "cot", "description": "Chain-of-Thought (CoT) Prompting" },
|
||||
{ "name": "ltm", "description": "Least-to-Most Prompting" },
|
||||
{ "name": "reflexion", "description": "Reflexion Prompting" },
|
||||
{ "name": "self-consistent", "description": "Self-Consistency Prompting" },
|
||||
{ "name": "self-refine", "description": "Self-Refinement" },
|
||||
{ "name": "standard", "description": "Standard Prompting" },
|
||||
{ "name": "tot", "description": "Tree-of-Thoughts (ToT)" }
|
||||
]
|
||||
Reference in New Issue
Block a user