node-deepresearch

repository·main·Indexed 23 days ago

https://github.com/jina-ai/node-deepresearch

An iterative reasoning and search agent designed to find accurate answers to complex queries through a loop of searching, reading, and reasoning. It supports multiple LLM providers including Gemini, OpenAI, and local LLMs via Ollama or LMStudio. The package can be run as a CLI tool or as an OpenAI-compatible server providing a /v1/chat/completions endpoint with the model jina-deepsearch-v1.

Tokens
5.1K
Snippets
10
Records
27
Agent score
89%

What's inside node-deepresearch

  1. Configure Local LLM (Ollama/LMStudio)

    main

    To use a local LLM instead of a cloud provider, redirect the reasoning requests by setting the LLM_PROVIDER to openai and configuring the OPENAI_BASE_URL to point to your local endpoint. Note that the LLM must support structured output (JSON Schema/object output) for the reasoning flow to work.

    export LLM_PROVIDER=openai
    export OPENAI_BASE_URL=http://127.0.0.1:1234/v1
    export OPENAI_API_KEY=whatever
    export DEFAULT_MODEL_NAME=qwen2.5-7b
    export LLM_PROVIDER=openai  # yes, that's right - for local llm we still use openai client
    export OPENAI_BASE_URL=http://127.0.0.1:1234/v1  # your local llm endpoint
    export OPENAI_API_KEY=whatever  # random string would do, as we don't use it (unless your local LLM has authentication)
    export DEFAULT_MODEL_NAME=qwen2.5-7b  # your local llm model name
  2. Run DeepResearch via CLI

    main

    You can run the DeepResearch agent directly from the command line by providing a query. You must set up the required environment variables for your LLM provider (Gemini or OpenAI) and your Jina API key.

    Required Environment Variables:

    • GEMINI_API_KEY (if using Gemini)
    • OPENAI_API_KEY (if using OpenAI)
    • LLM_PROVIDER (set to openai if using OpenAI)
    • JINA_API_KEY (get from https://jina.ai/reader)

    Execution:

    npm run dev "your query here"
    export GEMINI_API_KEY=...  # for gemini
    # export OPENAI_API_KEY=... # for openai
    # export LLM_PROVIDER=openai # for openai
    export JINA_API_KEY=jina_...  # free jina api key, get from https://jina.ai/reader
    
    npm run dev "your query here"
  3. Run DeepResearch as an OpenAI-Compatible Server

    main

    You can run the project as a local server that provides an OpenAI-compatible /v1/chat/completions endpoint. This allows you to connect GUI clients like CherryStudio or Chatbox.

    Start the server:

    • Without authentication: npm run serve
    • With authentication: npm run serve --secret=your_secret_token (clients must provide this as a Bearer token).

    The server defaults to http://localhost:3000.

    Example Request (Authenticated):

    curl http://localhost:3000/v1/chat/completions \
      -H "Content-Type: application/json" \
      -H "Authorization: Bearer your_secret_token" \
      -d '{
        "model": "jina-deepsearch-v1",
        "messages": [{"role": "user", "content": "Hello!"}],
        "stream": true
      }'
    # Without authentication
    npm run serve
    
    # With authentication (clients must provide this secret as Bearer token)
    npm run serve --secret=your_secret_token
  4. Deploy DeepResearch with Docker

    main

    You can containerize the application using Docker.

    Build the image:

    docker build -t deepresearch:latest .

    Run the container:

    docker run -p 3000:3000 --env GEMINI_API_KEY=your_gemini_api_key --env JINA_API_KEY=your_jina_api_key deepresearch:latest

    Using Docker Compose:

    docker-compose up
    docker build -t deepresearch:latest .
    
    docker run -p 3000:3000 --env GEMINI_API_KEY=your_gemini_api_key --env JINA_API_KEY=your_jina_api_key deepresearch:latest
    
    docker-compose up
  5. Configure LLM Provider and API Keys

    main

    DeepResearch supports multiple LLM providers. You must set the LLM_PROVIDER environment variable and provide the corresponding API key(s).

    Supported Providers:

    • openai: Requires OPENAI_API_KEY. You can optionally set OPENAI_BASE_URL for custom endpoints.
    • gemini: Requires GEMINI_API_KEY.
    • vertex: Requires GCLOUD_PROJECT and uses Google Vertex AI settings.

    Required Keys for all providers:

    • JINA_API_KEY is required regardless of the LLM provider selected.
  6. Configure environment variables for Docker deployment

    main

    When running node-deepresearch via Docker Compose, you must provide the following environment variables in your host environment or a .env file to enable different AI providers and search capabilities:

    • GEMINI_API_KEY: API key for Google Gemini.
    • OPENAI_API_KEY: API key for OpenAI.
    • JINA_API_KEY: API key for Jina AI services.
    • BRAVE_API_KEY: API key for Brave Search.

    The application service maps port 3000 on the host to port 3000 in the container.

    services:
      app:
        environment:
          - GEMINI_API_KEY=${GEMINI_API_KEY}
          - OPENAI_API_KEY=${OPENAI_API_KEY}
          - JINA_API_KEY=${JINA_API_KEY}
          - BRAVE_API_KEY=${BRAVE_API_KEY}
        ports:
          - "3000:3000"
  7. Configure Search and Proxy Settings

    main

    You can configure search providers and network proxy settings via environment variables:

    • BRAVE_API_KEY: API key for Brave search.
    • SERPER_API_KEY: API key for Serper search.
    • https_proxy: Set this to a proxy URL (e.g., http://proxy.example.com:8080) to route all outgoing requests through a proxy using undici's ProxyAgent.
  8. Configure ChatCompletionRequest options

    main

    When interacting with the model via ChatCompletionRequest, you can use the following configuration options:

    • model: The model ID.
    • messages: Array of CoreMessage.
    • reasoning_effort: 'low' | 'medium' | 'high'.
    • max_completion_tokens: Maximum tokens for completion.
    • budget_tokens: Token budget for the task.
    • max_attempts: Maximum number of retry attempts.
    • response_format: { type: 'json_schema' | 'json_object', json_schema?: any }.
    • no_direct_answer: Boolean to prevent immediate answering.
    • max_returned_urls: Limit on URLs returned.
    • boost_hostnames: Array of hostnames to prioritize.
    • bad_hostnames: Array of hostnames to avoid.
    • only_hostnames: Array of hostnames to restrict to.
    • max_annotations: Limit on citations/annotations.
    • min_annotation_relevance: Threshold for citation relevance.
    • with_images: Boolean to enable image processing.
    • language_code: Primary language code.
    • search_language_code: Language code for search queries.
    • search_provider: Specific search provider to use.
    • team_size: Integer for scaling context.
  9. Reference: OpenAI-Compatible Server API Schema

    main

    The local server implements the OpenAI Chat Completions schema.

    Endpoint: POST /v1/chat/completions Model Name: jina-deepsearch-v1

    Response Format (Non-streaming):

    {
      "id": "chatcmpl-123",
      "object": "chat.completion",
      "created": 1677652288,
      "model": "jina-deepsearch-v1",
      "system_fingerprint": "fp_44709d6fcb",
      "choices": [{
        "index": 0,
        "message": {
          "role": "assistant",
          "content": "YOUR FINAL ANSWER"
        },
        "logprobs": null,
        "finish_reason": "stop"
      }],
      "usage": {
        "prompt_tokens": 9,
        "completion_tokens": 12,
        "total_tokens": 21
      }
    }

    Streaming Response Format: When stream: true is used, the server sends chunks where the thinking process is wrapped in <think>...</think> XML tags.

    {
      "id": "chatcmpl-123",
      "object": "chat.completion.chunk",
      "created": 1694268190,
      "system_fingerprint": "fp_44709d6fcb",
      "choices": [{
        "index": 0,
        "delta": {
          "content": "..."
        },
        "logprobs": null,
        "finish_reason": null
      }]
    }
  10. Handle DeepResearch service and credit errors

    main

    When using the DeepResearch service, you may encounter specific error classes that indicate service availability, authentication, or billing issues. These errors are instances of ApplicationError and include specific status codes for programmatic handling.

    Service Availability Errors

    • ServiceDisabledError (Status Code: 50301): The service is currently disabled.
    • ServiceCrashedError (Status Code: 50302): The service has encountered a crash.
    • ServiceNodeResourceDrainError (Status Code: 50303): The service node is undergoing resource draining.

    Authentication and Content Errors

    • EmailUnverifiedError (Status Code: 40104): The user's email address is not verified.
    • HarmfulContentError (Status Code: 45101): The request contains harmful content.
    • SecurityCompromiseError (Status Code: 45102): A security compromise was detected.

    Billing and Credit Errors

    • InsufficientCreditsError (Status Code: 40201): Not enough credits available.
    • FreeFeatureLimitError (Status Code: 40202): The limit for free features has been reached.
    • InsufficientBalanceError (Status Code: 40203): Insufficient account balance.
    • BudgetExceededError (Status Code: 40904): The set budget has been exceeded.

    Rate Limiting and Constraints

    • RateLimitTriggeredError (Status Code: 42903): Rate limits have been hit. This error may include retryAfter (seconds) or retryAfterDate (Date object) properties to indicate when to retry.
    • BatchSizeTooLargeError (Status Code: 41201): The requested batch size is too large.
    • LockConflictError (Status Code: 40903): A conflict occurred due to a resource lock.
  11. Reference Search and Read response interfaces

    main

    The project uses several interfaces for handling search and web content retrieval:

    • JinaSearchResponse: Standard Jina search output with results (title, snippet, url) and meta (query, num_results, latency, credits).
    • SearchResponse: Generic search response containing code, status, and data (array of title, description, url, content, and usage).
    • ReadResponse: Response from reading a specific URL, including links (array of [anchor, url]) and images (record of image: url).
    • WebContent: Represents parsed web content with full text, chunks (string array), and chunk_positions (array of index arrays).