ChatMock

repository·main·Indexed 23 days ago

https://github.com/raybytes/chatmock

ChatMock provides an OpenAI-compatible local server that allows users to integrate their ChatGPT account models into favorite chat applications and coding tools. It features a CLI for authentication and server management, support for reasoning effort levels, web search capabilities, and a 'fast mode' for supported models. It can be installed via Homebrew, pipx, or as a GUI for macOS and Windows, and integrates with tools like Raycast and Terax.

Tokens
13.2K
Snippets
9
Records
95
Agent score
80%

What's inside chatmock

  1. Install ChatMock

    main

    You can install ChatMock using Homebrew, pipx, or by downloading the GUI for macOS and Windows from the official releases page. For Docker users, refer to the DOCKER.md file in the repository.

    # Homebrew
    brew tap RayBytes/chatmock
    brew install chatmock
    
    # pipx / pip
    pipx install chatmock
  2. Integrate ChatMock with Terax (Agentic Terminal)

    main

    To use ChatMock with Terax:

    1. Open Terax settings and navigate to the Models tab.
    2. Add a new provider of type OpenAI Compatible.
    3. Input the host URL: http://127.0.0.1:8000/v1.
    4. Provide the model IDs you wish to use (the API key can be any value).
    5. In the main chat window, select the model via the OpenAI Compatible icon.
  3. Integrate ChatMock with Raycast

    main

    To use ChatMock with Raycast:

    1. Open Raycast Extensions preferences and go to the Ollama settings section.
    2. Set the host URL to 127.0.0.1:8000 (the default).
    3. Click the Sync Models button to register available models.
    4. Open the Raycast AI Chat interface to see and use the available model slugs.
  4. Deploy ChatMock using Docker Compose

    main

    Follow these steps to set up and run ChatMock in a Docker environment:

    1. Setup environment variables: Copy the example environment file to create your local configuration.

      cp .env.example .env
    2. Authenticate with ChatGPT: Run the login service to obtain authentication tokens. This process requires a browser.

      docker compose run --rm --service-ports chatmock-login login
      • The command will print an auth URL. Copy and paste this into your browser.
      • If your browser cannot reach the container's localhost callback, copy the full redirect URL from the browser address bar and paste it back into the terminal when prompted.
      • The server should stop automatically once tokens are received and saved.
    3. Start the server: Launch the ChatMock service in detached mode.

      docker compose up -d chatmock
      • The service uses the PORT defined in your .env file.
      • By default, ports bind to localhost. To allow remote connections, set CHATMOCK_PUBLISH_HOST=0.0.0.0 in your .env file.
    cp .env.example .env
    docker compose run --rm --service-ports chatmock-login login
    docker compose up -d chatmock
  5. Get started with ChatMock

    main

    To use ChatMock, you must first sign in with your ChatGPT account and then start the local server. If you are running on a headless server, use the --headless flag during login.

    By default, the server runs at http://127.0.0.1:8000. For applications requiring an OpenAI-compatible API, use http://127.0.0.1:8000/v1 as the base URL.

    # 1. Sign in with your ChatGPT account
    # If you are running this on a headless server, append --headless
    chatmock login
    
    # 2. Start the server
    chatmock serve
  6. Ollama-compatible API endpoints in ChatMock

    main

    ChatMock implements an Ollama-compatible API surface, allowing developers to use ChatMock as a drop-in replacement for an Ollama server. It provides endpoints for checking versions, listing available models, inspecting model details, and performing chat completions (both streaming and non-streaming).

    Key features include:

    • Model Management: Retrieve version info and list models via /api/tags.
    • Chat Completions: The /api/chat endpoint supports standard Ollama message formats, tool calling, and reasoning (thinking) models.
    • Reasoning Compatibility: Supports different reasoning output formats via the REASONING_COMPAT configuration (e.g., think-tags or o3).
    • Tool Support: Handles standard tool definitions and includes a ChatMock extension for responses_tools (supporting web_search and web_search_preview).
  7. Configure ChatMock via environment variables

    main

    ChatMock can be configured using a .env file or by passing environment variables. Key configuration options include:

    VariableDescription
    PORTContainer listening port and published host port (default: 8000)
    CHATMOCK_PUBLISH_HOSTHost interface for published ports (default: 127.0.0.1; use 0.0.0.0 for remote access)
    CHATMOCK_IMAGEImage tag to run (default: storagetime/chatmock:latest)
    VERBOSEEnable request/stream logs (true or false)
    CHATGPT_LOCAL_REASONING_EFFORTReasoning effort level: minimal|low|medium|high|xhigh|max|ultra
    CHATGPT_LOCAL_REASONING_SUMMARYReasoning summary style: auto|concise|detailed|none
    CHATGPT_LOCAL_REASONING_COMPATReasoning compatibility mode: legacy|o3|think-tags|current
    CHATGPT_LOCAL_FAST_MODEEnable fast mode by default for supported models (true or false)
    CHATGPT_LOCAL_CLIENT_IDOAuth client id override
    CHATGPT_LOCAL_EXPOSE_REASONING_MODELSAdd reasoning model variants to /v1/models (true or false)
    CHATGPT_LOCAL_ENABLE_WEB_SEARCHEnable default web search tool (true or false)
    CHATGPT_LOCAL_MODEL_SYNCAutomatically discover account models (true or false, default: true)
    CHATGPT_LOCAL_MODEL_REFRESH_INTERVALModel catalog refresh interval in seconds (default: 3600)
  8. How OAuth authentication flows work in ChatMock

    main

    ChatMock supports two primary authentication patterns:

    1. Device Code Flow: Ideal for CLI/Headless use. run_device_code_login requests a user code, the user enters it on a remote device, and the client polls for the resulting tokens.
    2. Authorization Code Flow with PKCE: Ideal for desktop/local use. OAuthHTTPServer starts a local listener. The user is redirected to the issuer, and after authorizing, the browser redirects back to localhost:[PORT]/auth/callback. The server then exchanges the code for an AuthBundle and persists it.

    Both flows aim to produce an AuthBundle containing TokenData (id, access, and refresh tokens) and an api_key (obtained via a token exchange if organization/project IDs are present).

  9. How ModelCatalog refresh logic works

    main

    The ModelCatalog uses a background thread to fetch updates from the Codex API to ensure the proxy remains responsive.

    1. Caching: On initialization, it attempts to load a cache from cache_path (defaults to ~/chatmock_models_cache.json).
    2. Stale-While-Revalidate: When models() or visible_models() is called, the catalog checks if the data is older than refresh_interval_seconds.
    3. Background Refresh: If the data is stale, a daemon thread (chatmock-model-catalog-refresh) is spawned to fetch new data.
    4. Non-Blocking: By default, calls to models() return the cached data immediately even if a refresh is in progress. If you require the absolute latest data, you must pass wait_for_refresh=True.
    5. Error Resilience: If a background refresh fails, the catalog retains the last successful cache and continues to serve it, preventing model discovery failures from crashing the proxy.
  10. Configure ChatMock server settings

    main

    Configuration options can be passed as flags after chatmock serve or set via environment variables.

    FlagEnv varOptionsDefaultDescription
    --reasoning-effortCHATGPT_LOCAL_REASONING_EFFORTnone, minimal, low, medium, high, xhigh, max, ultramediumHow hard the model thinks
    --reasoning-summaryCHATGPT_LOCAL_REASONING_SUMMARYauto, concise, detailed, noneautoThinking summary verbosity
    --reasoning-compatCHATGPT_LOCAL_REASONING_COMPATlegacy, o3, think-tagsthink-tagsHow reasoning is returned to the client
    --fast-modeCHATGPT_LOCAL_FAST_MODEtrue/falsefalsePriority processing for supported models
    --enable-web-searchCHATGPT_LOCAL_ENABLE_WEB_SEARCHtrue/falsefalseAllow the model to search the web
    --expose-reasoning-modelsCHATGPT_LOCAL_EXPOSE_REASONING_MODELStrue/falsefalseList each reasoning level as its own model
    --model-syncCHATGPT_LOCAL_MODEL_SYNCtrue/falsetrueDiscover account models automatically
    --model-refresh-intervalCHATGPT_LOCAL_MODEL_REFRESH_INTERVALseconds3600Refresh interval for model discovery
  11. How session management and request optimization work

    main

    ChatMock implements a session-based optimization layer to facilitate prompt caching and reduce redundant data transfer.

    The Workflow:

    1. Session Identification: ensure_session_id creates a unique ID based on the conversation's starting instructions and first user message.
    2. Request Preparation: When a user sends a request, prepare_responses_request_for_session checks if the input list contains the history of the previous turn. If it does, it strips the history and attaches a previous_response_id to the payload.
    3. State Tracking: As the model responds, the developer must call note_responses_stream_event (for streaming) or note_responses_final_response (for non-streaming) to store the response items and ID in the session state.
    4. Reuse: The next request uses the stored state to perform the optimization described in step 2.

    This mechanism relies on the _ResponsesSessionState which tracks last_request_payload, last_response_id, and last_response_items for every active session.

  12. Deploy ChatMock using Docker Compose

    main

    You can deploy ChatMock using Docker Compose with two primary services: the main server (chatmock) and a login helper (chatmock-login).

    • chatmock service: Runs the main server using the serve command. It listens on a configurable port and persists data to a volume.
    • chatmock-login service: Used to sign in with your ChatGPT account. This service uses the login command and is part of the login profile. To run it, you must specify the profile in your docker-compose command.

    Data is persisted via the chatmock_data volume, which is mapped to /data inside the containers.

    services:
      chatmock:
        image: ${CHATMOCK_IMAGE:-storagetime/chatmock:latest}
        container_name: chatmock
        command: ["serve"]
        env_file: .env
        environment:
          - CHATGPT_LOCAL_HOME=/data
          - PORT=${PORT:-8000}
        ports:
          - "${CHATMOCK_PUBLISH_HOST:-127.0.0.1}:${PORT:-8000}:${PORT:-8000}"
        volumes:
          - chatmock_data:/data
    
      chatmock-login:
        image: ${CHATMOCK_IMAGE:-storagetime/chatmock:latest}
        profiles: ["login"]
        command: ["login"]
        environment:
          - CHATGPT_LOCAL_HOME=/data
          - CHATGPT_LOCAL_LOGIN_BIND=0.0.0.0
        volumes:
          - chatmock_data:/data
        ports:
          - "${CHATMOCK_PUBLISH_HOST:-127.0.0.1}:1455:1455"
    
    volumes:
      chatmock_data: