Skip to content

Refactor: Native Format Generation for Workspace Services #58

@allenhutchison

Description

@allenhutchison

Issue: Native Format Generation for Workspace Services

Background

Currently, the extension assumes the model outputs Markdown for all services. We then convert this Markdown to the target format on the client side:

  • Gmail: Model outputs Markdown -> marked (presumably) -> HTML (or just raw Markdown sent as text).
  • Docs: Model outputs Markdown -> marked -> HTML -> JSDOM -> docs.batchUpdate requests.
  • Chat: Model outputs Markdown -> Sent as text (Chat supports a subset of Markdown).

Objective

Remove the intermediate Markdown translation layer and instruct the model to generate the specific allowed format for each service directly. This reduces complexity, improves reliability, and allows for better formatting control (e.g., tables in Gmail, specific highlighting in Docs).

Research Findings

  • Gmail API: Supports HTML bodies. Best practices include using inline CSS and standard tags (b, i, a, table, ul, ol, etc.). Scripts and external stylesheets are not supported.
  • Google Chat API: Text messages support a specific subset of Markdown (*bold*, _italic_, ~strike~, `code`, ```codeblock```, links, user mentions). It does not support general HTML or standard Markdown tables.
  • Google Docs API: Does not support inserting HTML directly. It requires batchUpdate requests. However, we can instruct the model to output an "HTML subset" (tags like b, i, h1-6, p, code, a) that we parse directly into API requests, skipping the Markdown conversion step.

Technical Plan

1. New Architecture & Directory Structure

To adhere to DRY principles and Separation of Concerns, we will introduce a new directory src/utils/formatting/ to centralize formatting logic and instructions.

2. Format Instructions (src/utils/formatting/constants.ts)

We will create a constants file to define the exact formatting rules for each service. These constants will be used to:

  1. Instruct the Model: Appended to tool descriptions in src/index.ts.
  2. Validate/Parse Input: Used by the service logic where applicable.
  • DOCS_FORMAT_INSTRUCTIONS: "Provide content in HTML format using supported tags: <h1> to <h6> for headings, <p> for paragraphs, <b> or <strong> for bold, <i> or <em> for italics, <a> for links, and <code> for formatted code."
  • GMAIL_FORMAT_INSTRUCTIONS: "Format the body as HTML. Use inline CSS for styling. Supported tags include b, i, a, ul, ol, li, table, tr, td, etc."
  • CHAT_FORMAT_INSTRUCTIONS: "Use the following Markdown syntax only: *bold*, _italic_, ~strikethrough~, `inline code`, code block. Standard Markdown tables and headers are NOT supported."

3. Refactor Google Docs Parsing

  • New Parser: Create src/utils/formatting/HtmlToDocsParser.ts.
    • Responsibility: Convert an HTML string directly into docs_v1.Schema$Request[].
    • Logic: Use JSDOM to traverse the HTML (similar to the current markdownToDocsRequests.ts but without the marked step) and map elements to insertText and updateTextStyle/updateParagraphStyle requests.
  • DocsService: Update create, insertText, appendText, and replaceText to accept HTML directly and use HtmlToDocsParser.
  • Cleanup: Delete markdownToDocsRequests.ts and remove the marked dependency from the project.

4. Update Gmail & Chat Services

  • Gmail: Ensure GmailService methods (send, createDraft) pass the body directly as HTML when isHtml is true.
  • Chat: No code changes needed for message formatting, but we must ensure the tool descriptions in src/index.ts include the CHAT_FORMAT_INSTRUCTIONS to prevent the model from generating unsupported Markdown.

Tasks

  • Create src/utils/formatting/constants.ts with format instructions.
  • Create src/utils/formatting/HtmlToDocsParser.ts (refactoring markdownToDocsRequests.ts).
  • Update src/index.ts to append format instructions to tool descriptions.
  • Update DocsService to use HtmlToDocsParser.
  • Update GmailService / ChatService tool descriptions in src/index.ts.
  • Delete markdownToDocsRequests.ts.
  • Remove marked dependency.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions