2024-01-04 10:44:07 -03:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
module DiscourseAi
|
2025-05-29 15:40:46 +10:00
|
|
|
module Agents
|
2024-01-04 10:44:07 -03:00
|
|
|
module Tools
|
|
|
|
class Tool
|
2024-06-27 14:06:52 +10:00
|
|
|
# Why 30 mega bytes?
|
|
|
|
# This general limit is mainly a security feature to avoid tools
|
|
|
|
# forcing infinite downloads or causing memory exhaustion.
|
|
|
|
# The limit is somewhat arbitrary and can be increased in future if needed.
|
|
|
|
MAX_RESPONSE_BODY_LENGTH = 30.megabyte
|
|
|
|
|
2024-01-04 10:44:07 -03:00
|
|
|
class << self
|
|
|
|
def signature
|
|
|
|
raise NotImplemented
|
|
|
|
end
|
|
|
|
|
|
|
|
def name
|
|
|
|
raise NotImplemented
|
|
|
|
end
|
|
|
|
|
2024-06-27 17:27:40 +10:00
|
|
|
def custom?
|
|
|
|
false
|
|
|
|
end
|
|
|
|
|
2024-01-04 10:44:07 -03:00
|
|
|
def accepted_options
|
|
|
|
[]
|
|
|
|
end
|
|
|
|
|
DEV: artifact system update (#1096)
### Why
This pull request fundamentally restructures how AI bots create and update web artifacts to address critical limitations in the previous approach:
1. **Improved Artifact Context for LLMs**: Previously, artifact creation and update tools included the *entire* artifact source code directly in the tool arguments. This overloaded the Language Model (LLM) with raw code, making it difficult for the LLM to maintain a clear understanding of the artifact's current state when applying changes. The LLM would struggle to differentiate between the base artifact and the requested modifications, leading to confusion and less effective updates.
2. **Reduced Token Usage and History Bloat**: Including the full artifact source code in every tool interaction was extremely token-inefficient. As conversations progressed, this redundant code in the history consumed a significant number of tokens unnecessarily. This not only increased costs but also diluted the context for the LLM with less relevant historical information.
3. **Enabling Updates for Large Artifacts**: The lack of a practical diff or targeted update mechanism made it nearly impossible to efficiently update larger web artifacts. Sending the entire source code for every minor change was both computationally expensive and prone to errors, effectively blocking the use of AI bots for meaningful modifications of complex artifacts.
**This pull request addresses these core issues by**:
* Introducing methods for the AI bot to explicitly *read* and understand the current state of an artifact.
* Implementing efficient update strategies that send *targeted* changes rather than the entire artifact source code.
* Providing options to control the level of artifact context included in LLM prompts, optimizing token usage.
### What
The main changes implemented in this PR to resolve the above issues are:
1. **`Read Artifact` Tool for Contextual Awareness**:
- A new `read_artifact` tool is introduced, enabling AI bots to fetch and process the current content of a web artifact from a given URL (local or external).
- This provides the LLM with a clear and up-to-date representation of the artifact's HTML, CSS, and JavaScript, improving its understanding of the base to be modified.
- By cloning local artifacts, it allows the bot to work with a fresh copy, further enhancing context and control.
2. **Refactored `Update Artifact` Tool with Efficient Strategies**:
- The `update_artifact` tool is redesigned to employ more efficient update strategies, minimizing token usage and improving update precision:
- **`diff` strategy**: Utilizes a search-and-replace diff algorithm to apply only the necessary, targeted changes to the artifact's code. This significantly reduces the amount of code sent to the LLM and focuses its attention on the specific modifications.
- **`full` strategy**: Provides the option to replace the entire content sections (HTML, CSS, JavaScript) when a complete rewrite is required.
- Tool options enhance the control over the update process:
- `editor_llm`: Allows selection of a specific LLM for artifact updates, potentially optimizing for code editing tasks.
- `update_algorithm`: Enables choosing between `diff` and `full` update strategies based on the nature of the required changes.
- `do_not_echo_artifact`: Defaults to true, and by *not* echoing the artifact in prompts, it further reduces token consumption in scenarios where the LLM might not need the full artifact context for every update step (though effectiveness might be slightly reduced in certain update scenarios).
3. **System and General Persona Tool Option Visibility and Customization**:
- Tool options, including those for system personas, are made visible and editable in the admin UI. This allows administrators to fine-tune the behavior of all personas and their tools, including setting specific LLMs or update algorithms. This was previously limited or hidden for system personas.
4. **Centralized and Improved Content Security Policy (CSP) Management**:
- The CSP for AI artifacts is consolidated and made more maintainable through the `ALLOWED_CDN_SOURCES` constant. This improves code organization and future updates to the allowed CDN list, while maintaining the existing security posture.
5. **Codebase Improvements**:
- Refactoring of diff utilities, introduction of strategy classes, enhanced error handling, new locales, and comprehensive testing all contribute to a more robust, efficient, and maintainable artifact management system.
By addressing the issues of LLM context confusion, token inefficiency, and the limitations of updating large artifacts, this pull request significantly improves the practicality and effectiveness of AI bots in managing web artifacts within Discourse.
2025-02-04 16:27:27 +11:00
|
|
|
def option(name, type:, values: nil, default: nil)
|
|
|
|
Option.new(tool: self, name: name, type: type, values: values, default: default)
|
2024-01-04 10:44:07 -03:00
|
|
|
end
|
|
|
|
|
|
|
|
def help
|
2024-06-11 18:14:14 +10:00
|
|
|
I18n.t("discourse_ai.ai_bot.tool_help.#{signature[:name]}")
|
2024-01-04 10:44:07 -03:00
|
|
|
end
|
|
|
|
|
|
|
|
def custom_system_message
|
|
|
|
nil
|
|
|
|
end
|
2024-11-19 09:22:39 +11:00
|
|
|
|
|
|
|
def allow_partial_tool_calls?
|
|
|
|
false
|
|
|
|
end
|
DEV: artifact system update (#1096)
### Why
This pull request fundamentally restructures how AI bots create and update web artifacts to address critical limitations in the previous approach:
1. **Improved Artifact Context for LLMs**: Previously, artifact creation and update tools included the *entire* artifact source code directly in the tool arguments. This overloaded the Language Model (LLM) with raw code, making it difficult for the LLM to maintain a clear understanding of the artifact's current state when applying changes. The LLM would struggle to differentiate between the base artifact and the requested modifications, leading to confusion and less effective updates.
2. **Reduced Token Usage and History Bloat**: Including the full artifact source code in every tool interaction was extremely token-inefficient. As conversations progressed, this redundant code in the history consumed a significant number of tokens unnecessarily. This not only increased costs but also diluted the context for the LLM with less relevant historical information.
3. **Enabling Updates for Large Artifacts**: The lack of a practical diff or targeted update mechanism made it nearly impossible to efficiently update larger web artifacts. Sending the entire source code for every minor change was both computationally expensive and prone to errors, effectively blocking the use of AI bots for meaningful modifications of complex artifacts.
**This pull request addresses these core issues by**:
* Introducing methods for the AI bot to explicitly *read* and understand the current state of an artifact.
* Implementing efficient update strategies that send *targeted* changes rather than the entire artifact source code.
* Providing options to control the level of artifact context included in LLM prompts, optimizing token usage.
### What
The main changes implemented in this PR to resolve the above issues are:
1. **`Read Artifact` Tool for Contextual Awareness**:
- A new `read_artifact` tool is introduced, enabling AI bots to fetch and process the current content of a web artifact from a given URL (local or external).
- This provides the LLM with a clear and up-to-date representation of the artifact's HTML, CSS, and JavaScript, improving its understanding of the base to be modified.
- By cloning local artifacts, it allows the bot to work with a fresh copy, further enhancing context and control.
2. **Refactored `Update Artifact` Tool with Efficient Strategies**:
- The `update_artifact` tool is redesigned to employ more efficient update strategies, minimizing token usage and improving update precision:
- **`diff` strategy**: Utilizes a search-and-replace diff algorithm to apply only the necessary, targeted changes to the artifact's code. This significantly reduces the amount of code sent to the LLM and focuses its attention on the specific modifications.
- **`full` strategy**: Provides the option to replace the entire content sections (HTML, CSS, JavaScript) when a complete rewrite is required.
- Tool options enhance the control over the update process:
- `editor_llm`: Allows selection of a specific LLM for artifact updates, potentially optimizing for code editing tasks.
- `update_algorithm`: Enables choosing between `diff` and `full` update strategies based on the nature of the required changes.
- `do_not_echo_artifact`: Defaults to true, and by *not* echoing the artifact in prompts, it further reduces token consumption in scenarios where the LLM might not need the full artifact context for every update step (though effectiveness might be slightly reduced in certain update scenarios).
3. **System and General Persona Tool Option Visibility and Customization**:
- Tool options, including those for system personas, are made visible and editable in the admin UI. This allows administrators to fine-tune the behavior of all personas and their tools, including setting specific LLMs or update algorithms. This was previously limited or hidden for system personas.
4. **Centralized and Improved Content Security Policy (CSP) Management**:
- The CSP for AI artifacts is consolidated and made more maintainable through the `ALLOWED_CDN_SOURCES` constant. This improves code organization and future updates to the allowed CDN list, while maintaining the existing security posture.
5. **Codebase Improvements**:
- Refactoring of diff utilities, introduction of strategy classes, enhanced error handling, new locales, and comprehensive testing all contribute to a more robust, efficient, and maintainable artifact management system.
By addressing the issues of LLM context confusion, token inefficiency, and the limitations of updating large artifacts, this pull request significantly improves the practicality and effectiveness of AI bots in managing web artifacts within Discourse.
2025-02-04 16:27:27 +11:00
|
|
|
|
2025-05-29 15:40:46 +10:00
|
|
|
def inject_prompt(prompt:, context:, agent:)
|
DEV: artifact system update (#1096)
### Why
This pull request fundamentally restructures how AI bots create and update web artifacts to address critical limitations in the previous approach:
1. **Improved Artifact Context for LLMs**: Previously, artifact creation and update tools included the *entire* artifact source code directly in the tool arguments. This overloaded the Language Model (LLM) with raw code, making it difficult for the LLM to maintain a clear understanding of the artifact's current state when applying changes. The LLM would struggle to differentiate between the base artifact and the requested modifications, leading to confusion and less effective updates.
2. **Reduced Token Usage and History Bloat**: Including the full artifact source code in every tool interaction was extremely token-inefficient. As conversations progressed, this redundant code in the history consumed a significant number of tokens unnecessarily. This not only increased costs but also diluted the context for the LLM with less relevant historical information.
3. **Enabling Updates for Large Artifacts**: The lack of a practical diff or targeted update mechanism made it nearly impossible to efficiently update larger web artifacts. Sending the entire source code for every minor change was both computationally expensive and prone to errors, effectively blocking the use of AI bots for meaningful modifications of complex artifacts.
**This pull request addresses these core issues by**:
* Introducing methods for the AI bot to explicitly *read* and understand the current state of an artifact.
* Implementing efficient update strategies that send *targeted* changes rather than the entire artifact source code.
* Providing options to control the level of artifact context included in LLM prompts, optimizing token usage.
### What
The main changes implemented in this PR to resolve the above issues are:
1. **`Read Artifact` Tool for Contextual Awareness**:
- A new `read_artifact` tool is introduced, enabling AI bots to fetch and process the current content of a web artifact from a given URL (local or external).
- This provides the LLM with a clear and up-to-date representation of the artifact's HTML, CSS, and JavaScript, improving its understanding of the base to be modified.
- By cloning local artifacts, it allows the bot to work with a fresh copy, further enhancing context and control.
2. **Refactored `Update Artifact` Tool with Efficient Strategies**:
- The `update_artifact` tool is redesigned to employ more efficient update strategies, minimizing token usage and improving update precision:
- **`diff` strategy**: Utilizes a search-and-replace diff algorithm to apply only the necessary, targeted changes to the artifact's code. This significantly reduces the amount of code sent to the LLM and focuses its attention on the specific modifications.
- **`full` strategy**: Provides the option to replace the entire content sections (HTML, CSS, JavaScript) when a complete rewrite is required.
- Tool options enhance the control over the update process:
- `editor_llm`: Allows selection of a specific LLM for artifact updates, potentially optimizing for code editing tasks.
- `update_algorithm`: Enables choosing between `diff` and `full` update strategies based on the nature of the required changes.
- `do_not_echo_artifact`: Defaults to true, and by *not* echoing the artifact in prompts, it further reduces token consumption in scenarios where the LLM might not need the full artifact context for every update step (though effectiveness might be slightly reduced in certain update scenarios).
3. **System and General Persona Tool Option Visibility and Customization**:
- Tool options, including those for system personas, are made visible and editable in the admin UI. This allows administrators to fine-tune the behavior of all personas and their tools, including setting specific LLMs or update algorithms. This was previously limited or hidden for system personas.
4. **Centralized and Improved Content Security Policy (CSP) Management**:
- The CSP for AI artifacts is consolidated and made more maintainable through the `ALLOWED_CDN_SOURCES` constant. This improves code organization and future updates to the allowed CDN list, while maintaining the existing security posture.
5. **Codebase Improvements**:
- Refactoring of diff utilities, introduction of strategy classes, enhanced error handling, new locales, and comprehensive testing all contribute to a more robust, efficient, and maintainable artifact management system.
By addressing the issues of LLM context confusion, token inefficiency, and the limitations of updating large artifacts, this pull request significantly improves the practicality and effectiveness of AI bots in managing web artifacts within Discourse.
2025-02-04 16:27:27 +11:00
|
|
|
end
|
2024-01-04 10:44:07 -03:00
|
|
|
end
|
|
|
|
|
2025-05-14 12:36:16 +10:00
|
|
|
# llm being public makes it a bit easier to test
|
|
|
|
attr_accessor :custom_raw, :parameters, :llm
|
2025-05-29 15:40:46 +10:00
|
|
|
attr_reader :tool_call_id, :agent_options, :bot_user, :context
|
2024-05-07 21:55:46 +10:00
|
|
|
|
|
|
|
def initialize(
|
|
|
|
parameters,
|
|
|
|
tool_call_id: "",
|
2025-05-29 15:40:46 +10:00
|
|
|
agent_options: {},
|
2024-05-07 21:55:46 +10:00
|
|
|
bot_user:,
|
|
|
|
llm:,
|
2025-04-01 02:39:07 +11:00
|
|
|
context: nil
|
2024-05-07 21:55:46 +10:00
|
|
|
)
|
2024-01-04 10:44:07 -03:00
|
|
|
@parameters = parameters
|
|
|
|
@tool_call_id = tool_call_id
|
2025-05-29 15:40:46 +10:00
|
|
|
@agent_options = agent_options
|
2024-05-07 21:55:46 +10:00
|
|
|
@bot_user = bot_user
|
|
|
|
@llm = llm
|
2025-05-29 15:40:46 +10:00
|
|
|
@context = context.nil? ? DiscourseAi::Agents::BotContext.new(messages: []) : context
|
|
|
|
if !@context.is_a?(DiscourseAi::Agents::BotContext)
|
|
|
|
raise ArgumentError, "context must be a DiscourseAi::Agents::Context"
|
2025-04-01 02:39:07 +11:00
|
|
|
end
|
2024-01-04 10:44:07 -03:00
|
|
|
end
|
|
|
|
|
|
|
|
def name
|
|
|
|
self.class.name
|
|
|
|
end
|
|
|
|
|
|
|
|
def summary
|
2024-06-11 18:14:14 +10:00
|
|
|
I18n.t("discourse_ai.ai_bot.tool_summary.#{name}")
|
2024-01-04 10:44:07 -03:00
|
|
|
end
|
|
|
|
|
|
|
|
def details
|
2024-06-11 18:14:14 +10:00
|
|
|
I18n.t("discourse_ai.ai_bot.tool_description.#{name}", description_args)
|
2024-01-04 10:44:07 -03:00
|
|
|
end
|
|
|
|
|
|
|
|
def help
|
2024-06-11 18:14:14 +10:00
|
|
|
I18n.t("discourse_ai.ai_bot.tool_help.#{name}")
|
2024-01-04 10:44:07 -03:00
|
|
|
end
|
|
|
|
|
|
|
|
def options
|
2024-05-10 11:32:34 +10:00
|
|
|
result = HashWithIndifferentAccess.new
|
|
|
|
self.class.accepted_options.each do |option|
|
2025-05-29 15:40:46 +10:00
|
|
|
val = @agent_options[option.name]
|
2024-05-10 11:32:34 +10:00
|
|
|
if val
|
|
|
|
case option.type
|
|
|
|
when :boolean
|
2024-06-19 15:49:36 +10:00
|
|
|
val = (val.to_s == "true")
|
2024-05-10 11:32:34 +10:00
|
|
|
when :integer
|
|
|
|
val = val.to_i
|
DEV: artifact system update (#1096)
### Why
This pull request fundamentally restructures how AI bots create and update web artifacts to address critical limitations in the previous approach:
1. **Improved Artifact Context for LLMs**: Previously, artifact creation and update tools included the *entire* artifact source code directly in the tool arguments. This overloaded the Language Model (LLM) with raw code, making it difficult for the LLM to maintain a clear understanding of the artifact's current state when applying changes. The LLM would struggle to differentiate between the base artifact and the requested modifications, leading to confusion and less effective updates.
2. **Reduced Token Usage and History Bloat**: Including the full artifact source code in every tool interaction was extremely token-inefficient. As conversations progressed, this redundant code in the history consumed a significant number of tokens unnecessarily. This not only increased costs but also diluted the context for the LLM with less relevant historical information.
3. **Enabling Updates for Large Artifacts**: The lack of a practical diff or targeted update mechanism made it nearly impossible to efficiently update larger web artifacts. Sending the entire source code for every minor change was both computationally expensive and prone to errors, effectively blocking the use of AI bots for meaningful modifications of complex artifacts.
**This pull request addresses these core issues by**:
* Introducing methods for the AI bot to explicitly *read* and understand the current state of an artifact.
* Implementing efficient update strategies that send *targeted* changes rather than the entire artifact source code.
* Providing options to control the level of artifact context included in LLM prompts, optimizing token usage.
### What
The main changes implemented in this PR to resolve the above issues are:
1. **`Read Artifact` Tool for Contextual Awareness**:
- A new `read_artifact` tool is introduced, enabling AI bots to fetch and process the current content of a web artifact from a given URL (local or external).
- This provides the LLM with a clear and up-to-date representation of the artifact's HTML, CSS, and JavaScript, improving its understanding of the base to be modified.
- By cloning local artifacts, it allows the bot to work with a fresh copy, further enhancing context and control.
2. **Refactored `Update Artifact` Tool with Efficient Strategies**:
- The `update_artifact` tool is redesigned to employ more efficient update strategies, minimizing token usage and improving update precision:
- **`diff` strategy**: Utilizes a search-and-replace diff algorithm to apply only the necessary, targeted changes to the artifact's code. This significantly reduces the amount of code sent to the LLM and focuses its attention on the specific modifications.
- **`full` strategy**: Provides the option to replace the entire content sections (HTML, CSS, JavaScript) when a complete rewrite is required.
- Tool options enhance the control over the update process:
- `editor_llm`: Allows selection of a specific LLM for artifact updates, potentially optimizing for code editing tasks.
- `update_algorithm`: Enables choosing between `diff` and `full` update strategies based on the nature of the required changes.
- `do_not_echo_artifact`: Defaults to true, and by *not* echoing the artifact in prompts, it further reduces token consumption in scenarios where the LLM might not need the full artifact context for every update step (though effectiveness might be slightly reduced in certain update scenarios).
3. **System and General Persona Tool Option Visibility and Customization**:
- Tool options, including those for system personas, are made visible and editable in the admin UI. This allows administrators to fine-tune the behavior of all personas and their tools, including setting specific LLMs or update algorithms. This was previously limited or hidden for system personas.
4. **Centralized and Improved Content Security Policy (CSP) Management**:
- The CSP for AI artifacts is consolidated and made more maintainable through the `ALLOWED_CDN_SOURCES` constant. This improves code organization and future updates to the allowed CDN list, while maintaining the existing security posture.
5. **Codebase Improvements**:
- Refactoring of diff utilities, introduction of strategy classes, enhanced error handling, new locales, and comprehensive testing all contribute to a more robust, efficient, and maintainable artifact management system.
By addressing the issues of LLM context confusion, token inefficiency, and the limitations of updating large artifacts, this pull request significantly improves the practicality and effectiveness of AI bots in managing web artifacts within Discourse.
2025-02-04 16:27:27 +11:00
|
|
|
when :enum
|
|
|
|
val = val.to_s
|
|
|
|
val = option.default if option.values && !option.values.include?(val)
|
2024-05-10 11:32:34 +10:00
|
|
|
end
|
|
|
|
result[option.name] = val
|
DEV: artifact system update (#1096)
### Why
This pull request fundamentally restructures how AI bots create and update web artifacts to address critical limitations in the previous approach:
1. **Improved Artifact Context for LLMs**: Previously, artifact creation and update tools included the *entire* artifact source code directly in the tool arguments. This overloaded the Language Model (LLM) with raw code, making it difficult for the LLM to maintain a clear understanding of the artifact's current state when applying changes. The LLM would struggle to differentiate between the base artifact and the requested modifications, leading to confusion and less effective updates.
2. **Reduced Token Usage and History Bloat**: Including the full artifact source code in every tool interaction was extremely token-inefficient. As conversations progressed, this redundant code in the history consumed a significant number of tokens unnecessarily. This not only increased costs but also diluted the context for the LLM with less relevant historical information.
3. **Enabling Updates for Large Artifacts**: The lack of a practical diff or targeted update mechanism made it nearly impossible to efficiently update larger web artifacts. Sending the entire source code for every minor change was both computationally expensive and prone to errors, effectively blocking the use of AI bots for meaningful modifications of complex artifacts.
**This pull request addresses these core issues by**:
* Introducing methods for the AI bot to explicitly *read* and understand the current state of an artifact.
* Implementing efficient update strategies that send *targeted* changes rather than the entire artifact source code.
* Providing options to control the level of artifact context included in LLM prompts, optimizing token usage.
### What
The main changes implemented in this PR to resolve the above issues are:
1. **`Read Artifact` Tool for Contextual Awareness**:
- A new `read_artifact` tool is introduced, enabling AI bots to fetch and process the current content of a web artifact from a given URL (local or external).
- This provides the LLM with a clear and up-to-date representation of the artifact's HTML, CSS, and JavaScript, improving its understanding of the base to be modified.
- By cloning local artifacts, it allows the bot to work with a fresh copy, further enhancing context and control.
2. **Refactored `Update Artifact` Tool with Efficient Strategies**:
- The `update_artifact` tool is redesigned to employ more efficient update strategies, minimizing token usage and improving update precision:
- **`diff` strategy**: Utilizes a search-and-replace diff algorithm to apply only the necessary, targeted changes to the artifact's code. This significantly reduces the amount of code sent to the LLM and focuses its attention on the specific modifications.
- **`full` strategy**: Provides the option to replace the entire content sections (HTML, CSS, JavaScript) when a complete rewrite is required.
- Tool options enhance the control over the update process:
- `editor_llm`: Allows selection of a specific LLM for artifact updates, potentially optimizing for code editing tasks.
- `update_algorithm`: Enables choosing between `diff` and `full` update strategies based on the nature of the required changes.
- `do_not_echo_artifact`: Defaults to true, and by *not* echoing the artifact in prompts, it further reduces token consumption in scenarios where the LLM might not need the full artifact context for every update step (though effectiveness might be slightly reduced in certain update scenarios).
3. **System and General Persona Tool Option Visibility and Customization**:
- Tool options, including those for system personas, are made visible and editable in the admin UI. This allows administrators to fine-tune the behavior of all personas and their tools, including setting specific LLMs or update algorithms. This was previously limited or hidden for system personas.
4. **Centralized and Improved Content Security Policy (CSP) Management**:
- The CSP for AI artifacts is consolidated and made more maintainable through the `ALLOWED_CDN_SOURCES` constant. This improves code organization and future updates to the allowed CDN list, while maintaining the existing security posture.
5. **Codebase Improvements**:
- Refactoring of diff utilities, introduction of strategy classes, enhanced error handling, new locales, and comprehensive testing all contribute to a more robust, efficient, and maintainable artifact management system.
By addressing the issues of LLM context confusion, token inefficiency, and the limitations of updating large artifacts, this pull request significantly improves the practicality and effectiveness of AI bots in managing web artifacts within Discourse.
2025-02-04 16:27:27 +11:00
|
|
|
elsif val.nil?
|
|
|
|
result[option.name] = option.default
|
2024-01-04 10:44:07 -03:00
|
|
|
end
|
2024-05-10 11:32:34 +10:00
|
|
|
end
|
|
|
|
result
|
2024-01-04 10:44:07 -03:00
|
|
|
end
|
|
|
|
|
|
|
|
def chain_next_response?
|
|
|
|
true
|
|
|
|
end
|
|
|
|
|
|
|
|
protected
|
|
|
|
|
2024-05-30 06:33:50 +10:00
|
|
|
def fetch_default_branch(repo)
|
|
|
|
api_url = "https://api.github.com/repos/#{repo}"
|
|
|
|
|
|
|
|
response_code = "unknown error"
|
|
|
|
repo_data = nil
|
|
|
|
|
|
|
|
send_http_request(
|
|
|
|
api_url,
|
|
|
|
headers: {
|
|
|
|
"Accept" => "application/vnd.github.v3+json",
|
|
|
|
},
|
|
|
|
authenticate_github: true,
|
|
|
|
) do |response|
|
|
|
|
response_code = response.code
|
|
|
|
if response_code == "200"
|
|
|
|
begin
|
|
|
|
repo_data = JSON.parse(read_response_body(response))
|
|
|
|
rescue JSON::ParserError
|
|
|
|
response_code = "500 - JSON parse error"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
response_code == "200" ? repo_data["default_branch"] : "main"
|
|
|
|
end
|
|
|
|
|
2024-06-27 17:27:40 +10:00
|
|
|
def send_http_request(
|
|
|
|
url,
|
|
|
|
headers: {},
|
|
|
|
authenticate_github: false,
|
|
|
|
follow_redirects: false,
|
|
|
|
method: :get,
|
|
|
|
body: nil,
|
|
|
|
&blk
|
|
|
|
)
|
|
|
|
self.class.send_http_request(
|
|
|
|
url,
|
|
|
|
headers: headers,
|
|
|
|
authenticate_github: authenticate_github,
|
|
|
|
follow_redirects: follow_redirects,
|
|
|
|
method: method,
|
|
|
|
body: body,
|
|
|
|
&blk
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.send_http_request(
|
|
|
|
url,
|
|
|
|
headers: {},
|
|
|
|
authenticate_github: false,
|
|
|
|
follow_redirects: false,
|
|
|
|
method: :get,
|
|
|
|
body: nil
|
|
|
|
)
|
2024-03-28 16:01:58 +11:00
|
|
|
raise "Expecting caller to use a block" if !block_given?
|
|
|
|
|
|
|
|
uri = nil
|
|
|
|
url = UrlHelper.normalized_encode(url)
|
|
|
|
uri =
|
|
|
|
begin
|
|
|
|
URI.parse(url)
|
|
|
|
rescue StandardError
|
|
|
|
nil
|
|
|
|
end
|
|
|
|
|
|
|
|
return if !uri
|
|
|
|
|
|
|
|
if follow_redirects
|
|
|
|
fd =
|
|
|
|
FinalDestination.new(
|
|
|
|
url,
|
|
|
|
validate_uri: true,
|
|
|
|
max_redirects: 5,
|
|
|
|
follow_canonical: true,
|
|
|
|
)
|
|
|
|
|
|
|
|
uri = fd.resolve
|
|
|
|
end
|
|
|
|
|
|
|
|
return if uri.blank?
|
|
|
|
|
2024-06-27 17:27:40 +10:00
|
|
|
request = nil
|
|
|
|
if method == :get
|
|
|
|
request = FinalDestination::HTTP::Get.new(uri)
|
|
|
|
elsif method == :post
|
|
|
|
request = FinalDestination::HTTP::Post.new(uri)
|
2024-11-04 10:07:17 +11:00
|
|
|
elsif method == :put
|
|
|
|
request = FinalDestination::HTTP::Put.new(uri)
|
|
|
|
elsif method == :patch
|
|
|
|
request = FinalDestination::HTTP::Patch.new(uri)
|
|
|
|
elsif method == :delete
|
|
|
|
request = FinalDestination::HTTP::Delete.new(uri)
|
2024-06-27 17:27:40 +10:00
|
|
|
end
|
|
|
|
|
|
|
|
raise ArgumentError, "Invalid method: #{method}" if !request
|
|
|
|
|
|
|
|
request.body = body if body
|
|
|
|
|
2024-03-08 06:37:23 +11:00
|
|
|
request["User-Agent"] = DiscourseAi::AiBot::USER_AGENT
|
|
|
|
headers.each { |k, v| request[k] = v }
|
2024-03-08 09:54:05 +11:00
|
|
|
if authenticate_github && SiteSetting.ai_bot_github_access_token.present?
|
2024-03-08 06:37:23 +11:00
|
|
|
request["Authorization"] = "Bearer #{SiteSetting.ai_bot_github_access_token}"
|
|
|
|
end
|
|
|
|
|
|
|
|
FinalDestination::HTTP.start(uri.hostname, uri.port, use_ssl: uri.port != 80) do |http|
|
2024-03-28 16:01:58 +11:00
|
|
|
http.request(request) { |response| yield response }
|
2024-03-08 06:37:23 +11:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2024-06-27 14:06:52 +10:00
|
|
|
def self.read_response_body(response, max_length: nil)
|
|
|
|
max_length ||= MAX_RESPONSE_BODY_LENGTH
|
|
|
|
|
2024-03-28 16:01:58 +11:00
|
|
|
body = +""
|
|
|
|
response.read_body do |chunk|
|
|
|
|
body << chunk
|
|
|
|
break if body.bytesize > max_length
|
|
|
|
end
|
|
|
|
|
2024-06-27 14:06:52 +10:00
|
|
|
if body.bytesize > max_length
|
|
|
|
body[0...max_length].scrub
|
|
|
|
else
|
|
|
|
body.scrub
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def read_response_body(response, max_length: nil)
|
|
|
|
self.class.read_response_body(response, max_length: max_length)
|
2024-03-28 16:01:58 +11:00
|
|
|
end
|
|
|
|
|
2024-03-08 06:37:23 +11:00
|
|
|
def truncate(text, llm:, percent_length: nil, max_length: nil)
|
|
|
|
if !percent_length && !max_length
|
|
|
|
raise ArgumentError, "You must provide either percent_length or max_length"
|
|
|
|
end
|
|
|
|
|
|
|
|
target = llm.max_prompt_tokens
|
|
|
|
target = (target * percent_length).to_i if percent_length
|
|
|
|
|
|
|
|
if max_length
|
|
|
|
target = max_length if target > max_length
|
|
|
|
end
|
|
|
|
|
|
|
|
llm.tokenizer.truncate(text, target)
|
|
|
|
end
|
|
|
|
|
2024-01-04 10:44:07 -03:00
|
|
|
def accepted_options
|
|
|
|
[]
|
|
|
|
end
|
|
|
|
|
|
|
|
def option(name, type:)
|
|
|
|
Option.new(tool: self, name: name, type: type)
|
|
|
|
end
|
|
|
|
|
|
|
|
def description_args
|
|
|
|
{}
|
|
|
|
end
|
|
|
|
|
|
|
|
def format_results(rows, column_names = nil, args: nil)
|
|
|
|
rows = rows&.map { |row| yield row } if block_given?
|
|
|
|
|
|
|
|
if !column_names
|
|
|
|
index = -1
|
|
|
|
column_indexes = {}
|
|
|
|
|
|
|
|
rows =
|
|
|
|
rows&.map do |data|
|
|
|
|
new_row = []
|
|
|
|
data.each do |key, value|
|
|
|
|
found_index = column_indexes[key.to_s] ||= (index += 1)
|
|
|
|
new_row[found_index] = value
|
|
|
|
end
|
|
|
|
new_row
|
|
|
|
end
|
|
|
|
column_names = column_indexes.keys
|
|
|
|
end
|
|
|
|
|
|
|
|
# this is not the most efficient format
|
|
|
|
# however this is needed cause GPT 3.5 / 4 was steered using JSON
|
|
|
|
result = { column_names: column_names, rows: rows }
|
|
|
|
result[:args] = args if args
|
|
|
|
result
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|