discourse-ai/app/controllers/discourse_ai/ai_bot/artifacts_controller.rb

345 lines
12 KiB
Ruby
Raw Permalink Normal View History

FEATURE: AI artifacts (#898) This is a significant PR that introduces AI Artifacts functionality to the discourse-ai plugin along with several other improvements. Here are the key changes: 1. AI Artifacts System: - Adds a new `AiArtifact` model and database migration - Allows creation of web artifacts with HTML, CSS, and JavaScript content - Introduces security settings (`strict`, `lax`, `disabled`) for controlling artifact execution - Implements artifact rendering in iframes with sandbox protection - New `CreateArtifact` tool for AI to generate interactive content 2. Tool System Improvements: - Adds support for partial tool calls, allowing incremental updates during generation - Better handling of tool call states and progress tracking - Improved XML tool processing with CDATA support - Fixes for tool parameter handling and duplicate invocations 3. LLM Provider Updates: - Updates for Anthropic Claude models with correct token limits - Adds support for native/XML tool modes in Gemini integration - Adds new model configurations including Llama 3.1 models - Improvements to streaming response handling 4. UI Enhancements: - New artifact viewer component with expand/collapse functionality - Security controls for artifact execution (click-to-run in strict mode) - Improved dialog and response handling - Better error management for tool execution 5. Security Improvements: - Sandbox controls for artifact execution - Public/private artifact sharing controls - Security settings to control artifact behavior - CSP and frame-options handling for artifacts 6. Technical Improvements: - Better post streaming implementation - Improved error handling in completions - Better memory management for partial tool calls - Enhanced testing coverage 7. Configuration: - New site settings for artifact security - Extended LLM model configurations - Additional tool configuration options This PR significantly enhances the plugin's capabilities for generating and displaying interactive content while maintaining security and providing flexible configuration options for administrators.
2024-11-19 09:22:39 +11:00
# frozen_string_literal: true
module DiscourseAi
module AiBot
class ArtifactsController < ApplicationController
requires_plugin DiscourseAi::PLUGIN_NAME
before_action :require_site_settings!
skip_before_action :preload_json, :check_xhr, only: %i[show]
def show
artifact = AiArtifact.find(params[:id])
post = Post.find_by(id: artifact.post_id)
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
if artifact.public?
FEATURE: AI artifacts (#898) This is a significant PR that introduces AI Artifacts functionality to the discourse-ai plugin along with several other improvements. Here are the key changes: 1. AI Artifacts System: - Adds a new `AiArtifact` model and database migration - Allows creation of web artifacts with HTML, CSS, and JavaScript content - Introduces security settings (`strict`, `lax`, `disabled`) for controlling artifact execution - Implements artifact rendering in iframes with sandbox protection - New `CreateArtifact` tool for AI to generate interactive content 2. Tool System Improvements: - Adds support for partial tool calls, allowing incremental updates during generation - Better handling of tool call states and progress tracking - Improved XML tool processing with CDATA support - Fixes for tool parameter handling and duplicate invocations 3. LLM Provider Updates: - Updates for Anthropic Claude models with correct token limits - Adds support for native/XML tool modes in Gemini integration - Adds new model configurations including Llama 3.1 models - Improvements to streaming response handling 4. UI Enhancements: - New artifact viewer component with expand/collapse functionality - Security controls for artifact execution (click-to-run in strict mode) - Improved dialog and response handling - Better error management for tool execution 5. Security Improvements: - Sandbox controls for artifact execution - Public/private artifact sharing controls - Security settings to control artifact behavior - CSP and frame-options handling for artifacts 6. Technical Improvements: - Better post streaming implementation - Improved error handling in completions - Better memory management for partial tool calls - Enhanced testing coverage 7. Configuration: - New site settings for artifact security - Extended LLM model configurations - Additional tool configuration options This PR significantly enhances the plugin's capabilities for generating and displaying interactive content while maintaining security and providing flexible configuration options for administrators.
2024-11-19 09:22:39 +11:00
# no guardian needed
else
raise Discourse::NotFound if !post&.topic&.private_message?
raise Discourse::NotFound if !guardian.can_see?(post)
end
name = artifact.name
FEATURE: persistent key-value storage for AI Artifacts (#1417) Introduces a persistent, user-scoped key-value storage system for AI Artifacts, enabling them to be stateful and interactive. This transforms artifacts from static content into mini-applications that can save user input, preferences, and other data. The core components of this feature are: 1. **Model and API**: - A new `AiArtifactKeyValue` model and corresponding database table to store data associated with a user and an artifact. - A new `ArtifactKeyValuesController` provides a RESTful API for CRUD operations (`index`, `set`, `destroy`) on the key-value data. - Permissions are enforced: users can only modify their own data but can view public data from other users. 2. **Secure JavaScript Bridge**: - A `postMessage` communication bridge is established between the sandboxed artifact `iframe` and the parent Discourse window. - A JavaScript API is exposed to the artifact as `window.discourseArtifact` with async methods: `get(key)`, `set(key, value, options)`, `delete(key)`, and `index(filter)`. - The parent window handles these requests, makes authenticated calls to the new controller, and returns the results to the iframe. This ensures security by keeping untrusted JS isolated. 3. **AI Tool Integration**: - The `create_artifact` tool is updated with a `requires_storage` boolean parameter. - If an artifact requires storage, its metadata is flagged, and the system prompt for the code-generating AI is augmented with detailed documentation for the new storage API. 4. **Configuration**: - Adds hidden site settings `ai_artifact_kv_value_max_length` and `ai_artifact_max_keys_per_user_per_artifact` for throttling. This also includes a minor fix to use `jsonb_set` when updating artifact metadata, ensuring other metadata fields are preserved.
2025-06-11 06:59:46 +10:00
artifact_version = nil
if params[:version].present?
FEATURE: persistent key-value storage for AI Artifacts (#1417) Introduces a persistent, user-scoped key-value storage system for AI Artifacts, enabling them to be stateful and interactive. This transforms artifacts from static content into mini-applications that can save user input, preferences, and other data. The core components of this feature are: 1. **Model and API**: - A new `AiArtifactKeyValue` model and corresponding database table to store data associated with a user and an artifact. - A new `ArtifactKeyValuesController` provides a RESTful API for CRUD operations (`index`, `set`, `destroy`) on the key-value data. - Permissions are enforced: users can only modify their own data but can view public data from other users. 2. **Secure JavaScript Bridge**: - A `postMessage` communication bridge is established between the sandboxed artifact `iframe` and the parent Discourse window. - A JavaScript API is exposed to the artifact as `window.discourseArtifact` with async methods: `get(key)`, `set(key, value, options)`, `delete(key)`, and `index(filter)`. - The parent window handles these requests, makes authenticated calls to the new controller, and returns the results to the iframe. This ensures security by keeping untrusted JS isolated. 3. **AI Tool Integration**: - The `create_artifact` tool is updated with a `requires_storage` boolean parameter. - If an artifact requires storage, its metadata is flagged, and the system prompt for the code-generating AI is augmented with detailed documentation for the new storage API. 4. **Configuration**: - Adds hidden site settings `ai_artifact_kv_value_max_length` and `ai_artifact_max_keys_per_user_per_artifact` for throttling. This also includes a minor fix to use `jsonb_set` when updating artifact metadata, ensuring other metadata fields are preserved.
2025-06-11 06:59:46 +10:00
artifact_version = artifact.versions.find_by(version_number: params[:version])
raise Discourse::NotFound if !artifact_version
end
FEATURE: persistent key-value storage for AI Artifacts (#1417) Introduces a persistent, user-scoped key-value storage system for AI Artifacts, enabling them to be stateful and interactive. This transforms artifacts from static content into mini-applications that can save user input, preferences, and other data. The core components of this feature are: 1. **Model and API**: - A new `AiArtifactKeyValue` model and corresponding database table to store data associated with a user and an artifact. - A new `ArtifactKeyValuesController` provides a RESTful API for CRUD operations (`index`, `set`, `destroy`) on the key-value data. - Permissions are enforced: users can only modify their own data but can view public data from other users. 2. **Secure JavaScript Bridge**: - A `postMessage` communication bridge is established between the sandboxed artifact `iframe` and the parent Discourse window. - A JavaScript API is exposed to the artifact as `window.discourseArtifact` with async methods: `get(key)`, `set(key, value, options)`, `delete(key)`, and `index(filter)`. - The parent window handles these requests, makes authenticated calls to the new controller, and returns the results to the iframe. This ensures security by keeping untrusted JS isolated. 3. **AI Tool Integration**: - The `create_artifact` tool is updated with a `requires_storage` boolean parameter. - If an artifact requires storage, its metadata is flagged, and the system prompt for the code-generating AI is augmented with detailed documentation for the new storage API. 4. **Configuration**: - Adds hidden site settings `ai_artifact_kv_value_max_length` and `ai_artifact_max_keys_per_user_per_artifact` for throttling. This also includes a minor fix to use `jsonb_set` when updating artifact metadata, ensuring other metadata fields are preserved.
2025-06-11 06:59:46 +10:00
untrusted_html = build_untrusted_html(artifact_version || artifact, name)
trusted_html = build_trusted_html(artifact, artifact_version, name, untrusted_html)
set_security_headers
render html: trusted_html.html_safe, layout: false, content_type: "text/html"
end
private
def build_untrusted_html(artifact, name)
js = prepare_javascript(artifact.js)
<<~HTML
FEATURE: AI artifacts (#898) This is a significant PR that introduces AI Artifacts functionality to the discourse-ai plugin along with several other improvements. Here are the key changes: 1. AI Artifacts System: - Adds a new `AiArtifact` model and database migration - Allows creation of web artifacts with HTML, CSS, and JavaScript content - Introduces security settings (`strict`, `lax`, `disabled`) for controlling artifact execution - Implements artifact rendering in iframes with sandbox protection - New `CreateArtifact` tool for AI to generate interactive content 2. Tool System Improvements: - Adds support for partial tool calls, allowing incremental updates during generation - Better handling of tool call states and progress tracking - Improved XML tool processing with CDATA support - Fixes for tool parameter handling and duplicate invocations 3. LLM Provider Updates: - Updates for Anthropic Claude models with correct token limits - Adds support for native/XML tool modes in Gemini integration - Adds new model configurations including Llama 3.1 models - Improvements to streaming response handling 4. UI Enhancements: - New artifact viewer component with expand/collapse functionality - Security controls for artifact execution (click-to-run in strict mode) - Improved dialog and response handling - Better error management for tool execution 5. Security Improvements: - Sandbox controls for artifact execution - Public/private artifact sharing controls - Security settings to control artifact behavior - CSP and frame-options handling for artifacts 6. Technical Improvements: - Better post streaming implementation - Improved error handling in completions - Better memory management for partial tool calls - Enhanced testing coverage 7. Configuration: - New site settings for artifact security - Extended LLM model configurations - Additional tool configuration options This PR significantly enhances the plugin's capabilities for generating and displaying interactive content while maintaining security and providing flexible configuration options for administrators.
2024-11-19 09:22:39 +11:00
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>#{ERB::Util.html_escape(name)}</title>
FEATURE: AI artifacts (#898) This is a significant PR that introduces AI Artifacts functionality to the discourse-ai plugin along with several other improvements. Here are the key changes: 1. AI Artifacts System: - Adds a new `AiArtifact` model and database migration - Allows creation of web artifacts with HTML, CSS, and JavaScript content - Introduces security settings (`strict`, `lax`, `disabled`) for controlling artifact execution - Implements artifact rendering in iframes with sandbox protection - New `CreateArtifact` tool for AI to generate interactive content 2. Tool System Improvements: - Adds support for partial tool calls, allowing incremental updates during generation - Better handling of tool call states and progress tracking - Improved XML tool processing with CDATA support - Fixes for tool parameter handling and duplicate invocations 3. LLM Provider Updates: - Updates for Anthropic Claude models with correct token limits - Adds support for native/XML tool modes in Gemini integration - Adds new model configurations including Llama 3.1 models - Improvements to streaming response handling 4. UI Enhancements: - New artifact viewer component with expand/collapse functionality - Security controls for artifact execution (click-to-run in strict mode) - Improved dialog and response handling - Better error management for tool execution 5. Security Improvements: - Sandbox controls for artifact execution - Public/private artifact sharing controls - Security settings to control artifact behavior - CSP and frame-options handling for artifacts 6. Technical Improvements: - Better post streaming implementation - Improved error handling in completions - Better memory management for partial tool calls - Enhanced testing coverage 7. Configuration: - New site settings for artifact security - Extended LLM model configurations - Additional tool configuration options This PR significantly enhances the plugin's capabilities for generating and displaying interactive content while maintaining security and providing flexible configuration options for administrators.
2024-11-19 09:22:39 +11:00
<style>
#{artifact.css}
</style>
FEATURE: persistent key-value storage for AI Artifacts (#1417) Introduces a persistent, user-scoped key-value storage system for AI Artifacts, enabling them to be stateful and interactive. This transforms artifacts from static content into mini-applications that can save user input, preferences, and other data. The core components of this feature are: 1. **Model and API**: - A new `AiArtifactKeyValue` model and corresponding database table to store data associated with a user and an artifact. - A new `ArtifactKeyValuesController` provides a RESTful API for CRUD operations (`index`, `set`, `destroy`) on the key-value data. - Permissions are enforced: users can only modify their own data but can view public data from other users. 2. **Secure JavaScript Bridge**: - A `postMessage` communication bridge is established between the sandboxed artifact `iframe` and the parent Discourse window. - A JavaScript API is exposed to the artifact as `window.discourseArtifact` with async methods: `get(key)`, `set(key, value, options)`, `delete(key)`, and `index(filter)`. - The parent window handles these requests, makes authenticated calls to the new controller, and returns the results to the iframe. This ensures security by keeping untrusted JS isolated. 3. **AI Tool Integration**: - The `create_artifact` tool is updated with a `requires_storage` boolean parameter. - If an artifact requires storage, its metadata is flagged, and the system prompt for the code-generating AI is augmented with detailed documentation for the new storage API. 4. **Configuration**: - Adds hidden site settings `ai_artifact_kv_value_max_length` and `ai_artifact_max_keys_per_user_per_artifact` for throttling. This also includes a minor fix to use `jsonb_set` when updating artifact metadata, ensuring other metadata fields are preserved.
2025-06-11 06:59:46 +10:00
#{build_iframe_javascript}
FEATURE: AI artifacts (#898) This is a significant PR that introduces AI Artifacts functionality to the discourse-ai plugin along with several other improvements. Here are the key changes: 1. AI Artifacts System: - Adds a new `AiArtifact` model and database migration - Allows creation of web artifacts with HTML, CSS, and JavaScript content - Introduces security settings (`strict`, `lax`, `disabled`) for controlling artifact execution - Implements artifact rendering in iframes with sandbox protection - New `CreateArtifact` tool for AI to generate interactive content 2. Tool System Improvements: - Adds support for partial tool calls, allowing incremental updates during generation - Better handling of tool call states and progress tracking - Improved XML tool processing with CDATA support - Fixes for tool parameter handling and duplicate invocations 3. LLM Provider Updates: - Updates for Anthropic Claude models with correct token limits - Adds support for native/XML tool modes in Gemini integration - Adds new model configurations including Llama 3.1 models - Improvements to streaming response handling 4. UI Enhancements: - New artifact viewer component with expand/collapse functionality - Security controls for artifact execution (click-to-run in strict mode) - Improved dialog and response handling - Better error management for tool execution 5. Security Improvements: - Sandbox controls for artifact execution - Public/private artifact sharing controls - Security settings to control artifact behavior - CSP and frame-options handling for artifacts 6. Technical Improvements: - Better post streaming implementation - Improved error handling in completions - Better memory management for partial tool calls - Enhanced testing coverage 7. Configuration: - New site settings for artifact security - Extended LLM model configurations - Additional tool configuration options This PR significantly enhances the plugin's capabilities for generating and displaying interactive content while maintaining security and providing flexible configuration options for administrators.
2024-11-19 09:22:39 +11:00
</head>
<body>
#{artifact.html}
#{js}
FEATURE: AI artifacts (#898) This is a significant PR that introduces AI Artifacts functionality to the discourse-ai plugin along with several other improvements. Here are the key changes: 1. AI Artifacts System: - Adds a new `AiArtifact` model and database migration - Allows creation of web artifacts with HTML, CSS, and JavaScript content - Introduces security settings (`strict`, `lax`, `disabled`) for controlling artifact execution - Implements artifact rendering in iframes with sandbox protection - New `CreateArtifact` tool for AI to generate interactive content 2. Tool System Improvements: - Adds support for partial tool calls, allowing incremental updates during generation - Better handling of tool call states and progress tracking - Improved XML tool processing with CDATA support - Fixes for tool parameter handling and duplicate invocations 3. LLM Provider Updates: - Updates for Anthropic Claude models with correct token limits - Adds support for native/XML tool modes in Gemini integration - Adds new model configurations including Llama 3.1 models - Improvements to streaming response handling 4. UI Enhancements: - New artifact viewer component with expand/collapse functionality - Security controls for artifact execution (click-to-run in strict mode) - Improved dialog and response handling - Better error management for tool execution 5. Security Improvements: - Sandbox controls for artifact execution - Public/private artifact sharing controls - Security settings to control artifact behavior - CSP and frame-options handling for artifacts 6. Technical Improvements: - Better post streaming implementation - Improved error handling in completions - Better memory management for partial tool calls - Enhanced testing coverage 7. Configuration: - New site settings for artifact security - Extended LLM model configurations - Additional tool configuration options This PR significantly enhances the plugin's capabilities for generating and displaying interactive content while maintaining security and providing flexible configuration options for administrators.
2024-11-19 09:22:39 +11:00
</body>
</html>
HTML
FEATURE: persistent key-value storage for AI Artifacts (#1417) Introduces a persistent, user-scoped key-value storage system for AI Artifacts, enabling them to be stateful and interactive. This transforms artifacts from static content into mini-applications that can save user input, preferences, and other data. The core components of this feature are: 1. **Model and API**: - A new `AiArtifactKeyValue` model and corresponding database table to store data associated with a user and an artifact. - A new `ArtifactKeyValuesController` provides a RESTful API for CRUD operations (`index`, `set`, `destroy`) on the key-value data. - Permissions are enforced: users can only modify their own data but can view public data from other users. 2. **Secure JavaScript Bridge**: - A `postMessage` communication bridge is established between the sandboxed artifact `iframe` and the parent Discourse window. - A JavaScript API is exposed to the artifact as `window.discourseArtifact` with async methods: `get(key)`, `set(key, value, options)`, `delete(key)`, and `index(filter)`. - The parent window handles these requests, makes authenticated calls to the new controller, and returns the results to the iframe. This ensures security by keeping untrusted JS isolated. 3. **AI Tool Integration**: - The `create_artifact` tool is updated with a `requires_storage` boolean parameter. - If an artifact requires storage, its metadata is flagged, and the system prompt for the code-generating AI is augmented with detailed documentation for the new storage API. 4. **Configuration**: - Adds hidden site settings `ai_artifact_kv_value_max_length` and `ai_artifact_max_keys_per_user_per_artifact` for throttling. This also includes a minor fix to use `jsonb_set` when updating artifact metadata, ensuring other metadata fields are preserved.
2025-06-11 06:59:46 +10:00
end
FEATURE: AI artifacts (#898) This is a significant PR that introduces AI Artifacts functionality to the discourse-ai plugin along with several other improvements. Here are the key changes: 1. AI Artifacts System: - Adds a new `AiArtifact` model and database migration - Allows creation of web artifacts with HTML, CSS, and JavaScript content - Introduces security settings (`strict`, `lax`, `disabled`) for controlling artifact execution - Implements artifact rendering in iframes with sandbox protection - New `CreateArtifact` tool for AI to generate interactive content 2. Tool System Improvements: - Adds support for partial tool calls, allowing incremental updates during generation - Better handling of tool call states and progress tracking - Improved XML tool processing with CDATA support - Fixes for tool parameter handling and duplicate invocations 3. LLM Provider Updates: - Updates for Anthropic Claude models with correct token limits - Adds support for native/XML tool modes in Gemini integration - Adds new model configurations including Llama 3.1 models - Improvements to streaming response handling 4. UI Enhancements: - New artifact viewer component with expand/collapse functionality - Security controls for artifact execution (click-to-run in strict mode) - Improved dialog and response handling - Better error management for tool execution 5. Security Improvements: - Sandbox controls for artifact execution - Public/private artifact sharing controls - Security settings to control artifact behavior - CSP and frame-options handling for artifacts 6. Technical Improvements: - Better post streaming implementation - Improved error handling in completions - Better memory management for partial tool calls - Enhanced testing coverage 7. Configuration: - New site settings for artifact security - Extended LLM model configurations - Additional tool configuration options This PR significantly enhances the plugin's capabilities for generating and displaying interactive content while maintaining security and providing flexible configuration options for administrators.
2024-11-19 09:22:39 +11:00
FEATURE: persistent key-value storage for AI Artifacts (#1417) Introduces a persistent, user-scoped key-value storage system for AI Artifacts, enabling them to be stateful and interactive. This transforms artifacts from static content into mini-applications that can save user input, preferences, and other data. The core components of this feature are: 1. **Model and API**: - A new `AiArtifactKeyValue` model and corresponding database table to store data associated with a user and an artifact. - A new `ArtifactKeyValuesController` provides a RESTful API for CRUD operations (`index`, `set`, `destroy`) on the key-value data. - Permissions are enforced: users can only modify their own data but can view public data from other users. 2. **Secure JavaScript Bridge**: - A `postMessage` communication bridge is established between the sandboxed artifact `iframe` and the parent Discourse window. - A JavaScript API is exposed to the artifact as `window.discourseArtifact` with async methods: `get(key)`, `set(key, value, options)`, `delete(key)`, and `index(filter)`. - The parent window handles these requests, makes authenticated calls to the new controller, and returns the results to the iframe. This ensures security by keeping untrusted JS isolated. 3. **AI Tool Integration**: - The `create_artifact` tool is updated with a `requires_storage` boolean parameter. - If an artifact requires storage, its metadata is flagged, and the system prompt for the code-generating AI is augmented with detailed documentation for the new storage API. 4. **Configuration**: - Adds hidden site settings `ai_artifact_kv_value_max_length` and `ai_artifact_max_keys_per_user_per_artifact` for throttling. This also includes a minor fix to use `jsonb_set` when updating artifact metadata, ensuring other metadata fields are preserved.
2025-06-11 06:59:46 +10:00
def build_trusted_html(artifact, artifact_version, name, untrusted_html)
<<~HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>#{ERB::Util.html_escape(name)}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, user-scalable=yes, viewport-fit=cover, interactive-widget=resizes-content">
FEATURE: persistent key-value storage for AI Artifacts (#1417) Introduces a persistent, user-scoped key-value storage system for AI Artifacts, enabling them to be stateful and interactive. This transforms artifacts from static content into mini-applications that can save user input, preferences, and other data. The core components of this feature are: 1. **Model and API**: - A new `AiArtifactKeyValue` model and corresponding database table to store data associated with a user and an artifact. - A new `ArtifactKeyValuesController` provides a RESTful API for CRUD operations (`index`, `set`, `destroy`) on the key-value data. - Permissions are enforced: users can only modify their own data but can view public data from other users. 2. **Secure JavaScript Bridge**: - A `postMessage` communication bridge is established between the sandboxed artifact `iframe` and the parent Discourse window. - A JavaScript API is exposed to the artifact as `window.discourseArtifact` with async methods: `get(key)`, `set(key, value, options)`, `delete(key)`, and `index(filter)`. - The parent window handles these requests, makes authenticated calls to the new controller, and returns the results to the iframe. This ensures security by keeping untrusted JS isolated. 3. **AI Tool Integration**: - The `create_artifact` tool is updated with a `requires_storage` boolean parameter. - If an artifact requires storage, its metadata is flagged, and the system prompt for the code-generating AI is augmented with detailed documentation for the new storage API. 4. **Configuration**: - Adds hidden site settings `ai_artifact_kv_value_max_length` and `ai_artifact_max_keys_per_user_per_artifact` for throttling. This also includes a minor fix to use `jsonb_set` when updating artifact metadata, ensuring other metadata fields are preserved.
2025-06-11 06:59:46 +10:00
<meta name="csrf-token" content="#{form_authenticity_token}">
<style>
html, body, iframe {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
border: 0;
overflow: hidden;
}
iframe {
overflow: auto;
}
</style>
</head>
<body>
<iframe sandbox="allow-scripts allow-forms" height="100%" width="100%" srcdoc="#{ERB::Util.html_escape(untrusted_html)}" frameborder="0"></iframe>
FEATURE: persistent key-value storage for AI Artifacts (#1417) Introduces a persistent, user-scoped key-value storage system for AI Artifacts, enabling them to be stateful and interactive. This transforms artifacts from static content into mini-applications that can save user input, preferences, and other data. The core components of this feature are: 1. **Model and API**: - A new `AiArtifactKeyValue` model and corresponding database table to store data associated with a user and an artifact. - A new `ArtifactKeyValuesController` provides a RESTful API for CRUD operations (`index`, `set`, `destroy`) on the key-value data. - Permissions are enforced: users can only modify their own data but can view public data from other users. 2. **Secure JavaScript Bridge**: - A `postMessage` communication bridge is established between the sandboxed artifact `iframe` and the parent Discourse window. - A JavaScript API is exposed to the artifact as `window.discourseArtifact` with async methods: `get(key)`, `set(key, value, options)`, `delete(key)`, and `index(filter)`. - The parent window handles these requests, makes authenticated calls to the new controller, and returns the results to the iframe. This ensures security by keeping untrusted JS isolated. 3. **AI Tool Integration**: - The `create_artifact` tool is updated with a `requires_storage` boolean parameter. - If an artifact requires storage, its metadata is flagged, and the system prompt for the code-generating AI is augmented with detailed documentation for the new storage API. 4. **Configuration**: - Adds hidden site settings `ai_artifact_kv_value_max_length` and `ai_artifact_max_keys_per_user_per_artifact` for throttling. This also includes a minor fix to use `jsonb_set` when updating artifact metadata, ensuring other metadata fields are preserved.
2025-06-11 06:59:46 +10:00
#{build_parent_javascript(artifact)}
</body>
</html>
HTML
FEATURE: persistent key-value storage for AI Artifacts (#1417) Introduces a persistent, user-scoped key-value storage system for AI Artifacts, enabling them to be stateful and interactive. This transforms artifacts from static content into mini-applications that can save user input, preferences, and other data. The core components of this feature are: 1. **Model and API**: - A new `AiArtifactKeyValue` model and corresponding database table to store data associated with a user and an artifact. - A new `ArtifactKeyValuesController` provides a RESTful API for CRUD operations (`index`, `set`, `destroy`) on the key-value data. - Permissions are enforced: users can only modify their own data but can view public data from other users. 2. **Secure JavaScript Bridge**: - A `postMessage` communication bridge is established between the sandboxed artifact `iframe` and the parent Discourse window. - A JavaScript API is exposed to the artifact as `window.discourseArtifact` with async methods: `get(key)`, `set(key, value, options)`, `delete(key)`, and `index(filter)`. - The parent window handles these requests, makes authenticated calls to the new controller, and returns the results to the iframe. This ensures security by keeping untrusted JS isolated. 3. **AI Tool Integration**: - The `create_artifact` tool is updated with a `requires_storage` boolean parameter. - If an artifact requires storage, its metadata is flagged, and the system prompt for the code-generating AI is augmented with detailed documentation for the new storage API. 4. **Configuration**: - Adds hidden site settings `ai_artifact_kv_value_max_length` and `ai_artifact_max_keys_per_user_per_artifact` for throttling. This also includes a minor fix to use `jsonb_set` when updating artifact metadata, ensuring other metadata fields are preserved.
2025-06-11 06:59:46 +10:00
end
def prepare_javascript(js)
return "" if js.blank?
FEATURE: persistent key-value storage for AI Artifacts (#1417) Introduces a persistent, user-scoped key-value storage system for AI Artifacts, enabling them to be stateful and interactive. This transforms artifacts from static content into mini-applications that can save user input, preferences, and other data. The core components of this feature are: 1. **Model and API**: - A new `AiArtifactKeyValue` model and corresponding database table to store data associated with a user and an artifact. - A new `ArtifactKeyValuesController` provides a RESTful API for CRUD operations (`index`, `set`, `destroy`) on the key-value data. - Permissions are enforced: users can only modify their own data but can view public data from other users. 2. **Secure JavaScript Bridge**: - A `postMessage` communication bridge is established between the sandboxed artifact `iframe` and the parent Discourse window. - A JavaScript API is exposed to the artifact as `window.discourseArtifact` with async methods: `get(key)`, `set(key, value, options)`, `delete(key)`, and `index(filter)`. - The parent window handles these requests, makes authenticated calls to the new controller, and returns the results to the iframe. This ensures security by keeping untrusted JS isolated. 3. **AI Tool Integration**: - The `create_artifact` tool is updated with a `requires_storage` boolean parameter. - If an artifact requires storage, its metadata is flagged, and the system prompt for the code-generating AI is augmented with detailed documentation for the new storage API. 4. **Configuration**: - Adds hidden site settings `ai_artifact_kv_value_max_length` and `ai_artifact_max_keys_per_user_per_artifact` for throttling. This also includes a minor fix to use `jsonb_set` when updating artifact metadata, ensuring other metadata fields are preserved.
2025-06-11 06:59:46 +10:00
if !js.match?(%r{\A\s*<script.*</script>}mi)
mod = ""
mod = " type=\"module\"" if js.match?(/\A\s*import.*/)
js = "<script#{mod}>\n#{js}\n</script>"
end
js
end
def user_data
{
username: current_user ? current_user.username : nil,
user_id: current_user ? current_user.id : nil,
name: current_user ? current_user.name : nil,
}
end
def build_iframe_javascript
<<~JAVASCRIPT
<script>
window._discourse_user_data = #{user_data.to_json};
window.discourseArtifactReady = new Promise(resolve => {
window._resolveArtifactData = resolve;
});
// Key-value store API
window.discourseArtifact = {
get: function(key) {
return window._postMessageRequest('get', { key: key });
},
set: function(key, value, options = {}) {
return window._postMessageRequest('set', {
key: key,
value: value,
public: options.public || false
});
},
delete: function(key) {
return window._postMessageRequest('delete', { key: key });
},
index: function(filter = {}) {
return window._postMessageRequest('index', filter);
}
};
window._postMessageRequest = function(action, data) {
return new Promise((resolve, reject) => {
const requestId = Math.random().toString(36).substr(2, 9);
const messageHandler = function(event) {
if (event.data && event.data.requestId === requestId) {
window.removeEventListener('message', messageHandler);
if (event.data.error) {
reject(new Error(event.data.error));
} else {
resolve(event.data.result);
}
}
};
window.addEventListener('message', messageHandler);
window.parent.postMessage({
type: 'discourse-artifact-kv',
action: action,
data: data,
requestId: requestId
}, '*');
});
};
window.addEventListener('message', function(event) {
if (event.data && event.data.type === 'discourse-artifact-data') {
window.discourseArtifactData = event.data.dataset || {};
Object.assign(window.discourseArtifactData, window._discourse_user_data);
window._resolveArtifactData(window.discourseArtifactData);
}
});
</script>
JAVASCRIPT
end
def build_parent_javascript(artifact)
<<~JAVASCRIPT
<script>
document.querySelector('iframe').addEventListener('load', function() {
try {
const iframeWindow = this.contentWindow;
const message = { type: 'discourse-artifact-data', dataset: {} };
if (window.frameElement && window.frameElement.dataset) {
Object.assign(message.dataset, window.frameElement.dataset);
}
iframeWindow.postMessage(message, '*');
} catch (e) {
console.error('Error passing data to artifact:', e);
}
});
// Handle key-value store requests from iframe
window.addEventListener('message', async function(event) {
if (event.data && event.data.type === 'discourse-artifact-kv') {
const { action, data, requestId } = event.data;
const artifactId = #{artifact.id};
try {
const result = await handleKeyValueRequest(action, data, artifactId);
event.source.postMessage({
requestId: requestId,
result: result
}, '*');
} catch (error) {
event.source.postMessage({
requestId: requestId,
error: error.message
}, '*');
}
}
});
async function handleKeyValueRequest(action, data, artifactId) {
const baseUrl = '/discourse-ai/ai-bot/artifact-key-values/' + artifactId + ".json";
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.content || '';
switch (action) {
case 'get':
return await handleGetRequest(baseUrl, data, csrfToken);
case 'set':
return await handleSetRequest(baseUrl, data, csrfToken);
case 'index':
return await handleIndexRequest(baseUrl, data, csrfToken);
case 'delete':
return await handleDeleteRequest(baseUrl, data, csrfToken);
default:
throw new Error('Unknown action: ' + action);
}
}
async function handleGetRequest(baseUrl, data, csrfToken) {
const response = await fetch(baseUrl + '?key=' + encodeURIComponent(data.key), {
method: 'GET',
headers: {
'X-CSRF-Token': csrfToken,
'Content-Type': 'application/json'
},
credentials: 'same-origin'
});
if (!response.ok) throw new Error('Failed to get key-value');
const result = await response.json();
const keyValue = result.key_values.find(kv => kv.key === data.key);
return keyValue ? keyValue.value : null;
}
async function handleSetRequest(baseUrl, data, csrfToken) {
const response = await fetch(baseUrl, {
method: 'POST',
headers: {
'X-CSRF-Token': csrfToken,
'Content-Type': 'application/json'
},
credentials: 'same-origin',
body: JSON.stringify({
key: data.key,
value: data.value,
public: data.public
})
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(errorData.errors ? errorData.errors.join(', ') : 'Failed to set key-value');
}
return await response.json();
}
async function handleDeleteRequest(baseUrl, data, csrfToken) {
const response = await fetch(baseUrl, {
method: 'DELETE',
body: JSON.stringify({ key: data.key }),
headers: {
'X-CSRF-Token': csrfToken,
'Content-Type': 'application/json'
},
credentials: 'same-origin'
});
if (!response.ok) {
if (response.status === 404) {
throw new Error('Key not found');
}
const errorData = await response.json();
throw new Error(errorData.errors ? errorData.errors.join(', ') : 'Failed to delete key-value');
}
return true;
}
async function handleIndexRequest(baseUrl, data, csrfToken) {
const params = new URLSearchParams();
if (data.key) params.append('key', data.key);
if (data.all_users) params.append('all_users', data.all_users);
if (data.keys_only) params.append('keys_only', data.keys_only);
if (data.page) params.append('page', data.page);
if (data.per_page) params.append('per_page', data.per_page);
const response = await fetch(baseUrl + '?' + params.toString(), {
method: 'GET',
headers: {
'X-CSRF-Token': csrfToken,
'Content-Type': 'application/json'
},
credentials: 'same-origin'
});
if (!response.ok) throw new Error('Failed to get key-values');
const result = await response.json();
const userMap = {};
result.users.forEach(user => {
userMap[user.id] = user;
});
result.key_values.forEach(kv => {
if (kv.user_id && userMap[kv.user_id]) {
kv.user = userMap[kv.user_id];
}
});
return result;
}
</script>
JAVASCRIPT
end
def set_security_headers
FEATURE: AI artifacts (#898) This is a significant PR that introduces AI Artifacts functionality to the discourse-ai plugin along with several other improvements. Here are the key changes: 1. AI Artifacts System: - Adds a new `AiArtifact` model and database migration - Allows creation of web artifacts with HTML, CSS, and JavaScript content - Introduces security settings (`strict`, `lax`, `disabled`) for controlling artifact execution - Implements artifact rendering in iframes with sandbox protection - New `CreateArtifact` tool for AI to generate interactive content 2. Tool System Improvements: - Adds support for partial tool calls, allowing incremental updates during generation - Better handling of tool call states and progress tracking - Improved XML tool processing with CDATA support - Fixes for tool parameter handling and duplicate invocations 3. LLM Provider Updates: - Updates for Anthropic Claude models with correct token limits - Adds support for native/XML tool modes in Gemini integration - Adds new model configurations including Llama 3.1 models - Improvements to streaming response handling 4. UI Enhancements: - New artifact viewer component with expand/collapse functionality - Security controls for artifact execution (click-to-run in strict mode) - Improved dialog and response handling - Better error management for tool execution 5. Security Improvements: - Sandbox controls for artifact execution - Public/private artifact sharing controls - Security settings to control artifact behavior - CSP and frame-options handling for artifacts 6. Technical Improvements: - Better post streaming implementation - Improved error handling in completions - Better memory management for partial tool calls - Enhanced testing coverage 7. Configuration: - New site settings for artifact security - Extended LLM model configurations - Additional tool configuration options This PR significantly enhances the plugin's capabilities for generating and displaying interactive content while maintaining security and providing flexible configuration options for administrators.
2024-11-19 09:22:39 +11:00
response.headers.delete("X-Frame-Options")
response.headers[
"Content-Security-Policy"
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
] = "script-src 'self' 'unsafe-inline' 'wasm-unsafe-eval' #{AiArtifact::ALLOWED_CDN_SOURCES.join(" ")};"
response.headers["X-Robots-Tag"] = "noindex"
FEATURE: AI artifacts (#898) This is a significant PR that introduces AI Artifacts functionality to the discourse-ai plugin along with several other improvements. Here are the key changes: 1. AI Artifacts System: - Adds a new `AiArtifact` model and database migration - Allows creation of web artifacts with HTML, CSS, and JavaScript content - Introduces security settings (`strict`, `lax`, `disabled`) for controlling artifact execution - Implements artifact rendering in iframes with sandbox protection - New `CreateArtifact` tool for AI to generate interactive content 2. Tool System Improvements: - Adds support for partial tool calls, allowing incremental updates during generation - Better handling of tool call states and progress tracking - Improved XML tool processing with CDATA support - Fixes for tool parameter handling and duplicate invocations 3. LLM Provider Updates: - Updates for Anthropic Claude models with correct token limits - Adds support for native/XML tool modes in Gemini integration - Adds new model configurations including Llama 3.1 models - Improvements to streaming response handling 4. UI Enhancements: - New artifact viewer component with expand/collapse functionality - Security controls for artifact execution (click-to-run in strict mode) - Improved dialog and response handling - Better error management for tool execution 5. Security Improvements: - Sandbox controls for artifact execution - Public/private artifact sharing controls - Security settings to control artifact behavior - CSP and frame-options handling for artifacts 6. Technical Improvements: - Better post streaming implementation - Improved error handling in completions - Better memory management for partial tool calls - Enhanced testing coverage 7. Configuration: - New site settings for artifact security - Extended LLM model configurations - Additional tool configuration options This PR significantly enhances the plugin's capabilities for generating and displaying interactive content while maintaining security and providing flexible configuration options for administrators.
2024-11-19 09:22:39 +11:00
end
def require_site_settings!
if !SiteSetting.discourse_ai_enabled ||
!SiteSetting.ai_artifact_security.in?(%w[lax hybrid strict])
FEATURE: AI artifacts (#898) This is a significant PR that introduces AI Artifacts functionality to the discourse-ai plugin along with several other improvements. Here are the key changes: 1. AI Artifacts System: - Adds a new `AiArtifact` model and database migration - Allows creation of web artifacts with HTML, CSS, and JavaScript content - Introduces security settings (`strict`, `lax`, `disabled`) for controlling artifact execution - Implements artifact rendering in iframes with sandbox protection - New `CreateArtifact` tool for AI to generate interactive content 2. Tool System Improvements: - Adds support for partial tool calls, allowing incremental updates during generation - Better handling of tool call states and progress tracking - Improved XML tool processing with CDATA support - Fixes for tool parameter handling and duplicate invocations 3. LLM Provider Updates: - Updates for Anthropic Claude models with correct token limits - Adds support for native/XML tool modes in Gemini integration - Adds new model configurations including Llama 3.1 models - Improvements to streaming response handling 4. UI Enhancements: - New artifact viewer component with expand/collapse functionality - Security controls for artifact execution (click-to-run in strict mode) - Improved dialog and response handling - Better error management for tool execution 5. Security Improvements: - Sandbox controls for artifact execution - Public/private artifact sharing controls - Security settings to control artifact behavior - CSP and frame-options handling for artifacts 6. Technical Improvements: - Better post streaming implementation - Improved error handling in completions - Better memory management for partial tool calls - Enhanced testing coverage 7. Configuration: - New site settings for artifact security - Extended LLM model configurations - Additional tool configuration options This PR significantly enhances the plugin's capabilities for generating and displaying interactive content while maintaining security and providing flexible configuration options for administrators.
2024-11-19 09:22:39 +11:00
raise Discourse::NotFound
end
end
end
end
end