> ## Documentation Index
> Fetch the complete documentation index at: https://docs.flexinference.com/llms.txt
> Use this file to discover all available pages before exploring further.

# OpenScience

> Point OpenScience at FlexInference with config only.

OpenScience reads a provider entry out of a JSON file. A stock build needs no source change.

OpenScience can set `start_within` in config, so an agent key is optional here. The key is still the simpler path, because it changes without a restart. See [agent keys](/agent-keys).

## Set this up with an agent

Open the block below and copy it into any coding agent. The prompt never asks for your API key: the agent configures everything else, then prints the one export line for you to run yourself.

<Accordion title="Copy agent setup prompt">
  ```text theme={null}
  Configure OpenScience to send its requests to FlexInference. This is config only: no source change, no fork, no patch.

  You will never see or handle my API key. The provider entry stores only the `{env:FLEXINFERENCE_API_KEY}` template, and I export the value myself. Do not ask me for the key, and do not read it from my environment.

  1. Create a directory named `config/` and put `openscience.json` in it with this content:

  {
    "$schema": "https://syntheticsciences.ai/config.json",
    "model": "flexinference/gpt-5.6-sol",
    "provider": {
      "flexinference": {
        "name": "FlexInference",
        "env": ["FLEXINFERENCE_API_KEY"],
        "npm": "@ai-sdk/openai-compatible",
        "options": {
          "apiKey": "{env:FLEXINFERENCE_API_KEY}",
          "baseURL": "https://api.flexinference.com/v1"
        },
        "models": {
          "gpt-5.6-sol": {
            "name": "GPT-5.6 Sol",
            "reasoning": true,
            "tool_call": true
          }
        }
      }
    }
  }

  2. Print these lines for me to run. Do not run the export and do not ask for the value:

  export FLEXINFERENCE_API_KEY=<paste your key here>
  OPENSCIENCE_CONFIG_DIR=./config bun run dev

  3. Add `config/package.json`, `config/bun.lock`, and `config/node_modules/` to `.gitignore`. OpenScience writes those into any directory it loads config from on first run.

  Rules that matter, do not deviate:
  - Use `OPENSCIENCE_CONFIG_DIR`, not `OPENSCIENCE_CONFIG`. The first names a directory and scans it for commands, agents, and plugins. The second names a single file and scans nothing.
  - If I ask for a plugin, place the file at `config/plugins/<name>.js` and leave the `plugin` key out of the JSON entirely.
  - Tell me that any `.openscience` or `.synsc` directory inside a repository I open is also scanned for plugins, and that those plugins run with my exported key in the environment. Recommend I export the key only in the launch shell. Every entry in that array without a `file://` prefix is treated as an npm package name and handed to `bun add`, which fails and takes plugin startup down. The directory scan is one level deep and loads every `.js` and `.ts` sitting directly in `plugins/`, so keep shared modules outside it.
  - Do NOT put `start_within` in any model's `options`. FlexInference injects a key default only when the field is ABSENT, so writing it here permanently overrides my agent key's deadline with whatever you hardcoded. Only add it if I tell you I am not using an agent key.
  - Keep `options.apiKey` as the literal `{env:FLEXINFERENCE_API_KEY}` template. Never inline my key.
  - The top-level `model` field is what selects the provider. Without it OpenScience stays on its built-in default.
  - Every key under `models` is a slug sent verbatim on the wire, so it must be one FlexInference serves.

  Verify the file is valid JSON, then report what you created and the exact command to run.
  ```
</Accordion>

## Configure OpenScience

1. Export the key in the shell that starts OpenScience.

   ```bash theme={null}
   export FLEXINFERENCE_API_KEY=flex_live_...
   ```

2. Write the provider entry to `openscience.json`.

   ```json theme={null}
   {
     "$schema": "https://syntheticsciences.ai/config.json",
     "model": "flexinference/gpt-5.6-sol",
     "provider": {
       "flexinference": {
         "name": "FlexInference",
         "env": ["FLEXINFERENCE_API_KEY"],
         "npm": "@ai-sdk/openai-compatible",
         "options": {
           "apiKey": "{env:FLEXINFERENCE_API_KEY}",
           "baseURL": "https://api.flexinference.com/v1"
         },
         "models": {
           "gpt-5.6-sol": {
             "name": "GPT-5.6 Sol",
             "reasoning": true,
             "tool_call": true
           }
         }
       }
     }
   }
   ```

3. Start OpenScience with the config directory set.

   ```bash theme={null}
   OPENSCIENCE_CONFIG_DIR=/path/to/config bun run dev
   ```

Leave `start_within` out of `options` when your key holds the deadline. We only fill a stored default in when the field is absent, so a value here would override the key on every request.

Set `"start_within": "default"` on every model instead when you're **not** using an agent key. That's the safe baseline, because a model picked with no session selection then routes standard rather than racing by accident.

## Where the file goes

OpenScience merges config from several places, and a later source wins.

* The global user config in OpenScience's config directory.
* `OPENSCIENCE_CONFIG`, a path to one config file.
* `synsc.jsonc`, `synsc.json`, `openscience.jsonc`, and `openscience.json` found walking up to the worktree root, unless `OPENSCIENCE_DISABLE_PROJECT_CONFIG` is set.
* `OPENSCIENCE_CONFIG_CONTENT`, holding the JSON inline.
* Those same four names inside each `.openscience` or `.synsc` directory on that walk, plus any directory named by `OPENSCIENCE_CONFIG_DIR`.

The two path variables aren't interchangeable. `OPENSCIENCE_CONFIG` names one file. `OPENSCIENCE_CONFIG_DIR` names a directory and treats the whole thing as config, scanning it for commands, agents, and plugins. Use the directory form when the bundle holds more than JSON.

## Load a plugin by placing it

OpenScience scans each config directory for `{plugin,plugins}/*.{ts,js}` and loads what it finds as a local file. Put the file at `plugins/flex.js` and leave `plugin` out of the JSON.

```
config/
  openscience.json
  plugins/
    flex.js
```

Writing the path into `plugin` doesn't work. OpenScience reads every entry there without a `file://` prefix as an npm package name and hands it to `bun add`, so `"./plugins/flex.js"` fails to install and takes plugin startup down with it.

The scan is one level deep, and it takes every `.js` and `.ts` sitting in `plugins/` itself. Keep shared modules outside that directory, or OpenScience loads them as plugins too.

The first time OpenScience loads config from a directory it writes `package.json`, `bun.lock`, `node_modules/`, and a `.gitignore` covering them into it. Expect those, and keep them out of Git.

## Confirm the key applied

Every response comes with `x-flexinference-defaults-applied`. OpenScience doesn't show response headers in the workspace, so read the request in the dashboard under **Logs** instead.

## Troubleshooting

**A plugin never loaded.** Naming it in `plugin` sends it to `bun add` as a package name, which fails and takes plugin startup down. Put the file at `plugins/flex.js` inside the config directory and leave `plugin` out of the JSON.

**A helper module loaded as a plugin.** The scan takes every `.js` and `.ts` sitting in `plugins/` itself. Move shared modules outside that directory.

**Requests never reach us.** The top-level `model` field is what selects the provider. Without it OpenScience stays on its built-in default.

**[`401 invalid_api_key`](/errors#invalid_api_key).** `FLEXINFERENCE_API_KEY` is unset in the shell that started OpenScience. Export it before launching.

**[`400 flex_unsupported_for_anthropic`](/errors#flex_unsupported_for_anthropic).** A duration in `options` reached a `claude-*` model on your own Anthropic key. The [race](/deadline-routing#claude-durations-need-a-longer-window) a Claude duration runs takes managed keys. Remove the duration and let the key carry the deadline.

**The key's deadline never applies.** A `start_within` in a model's `options` wins over the key, because we only fill a stored default in when the field is absent. Remove it from the entry.

See [errors](/errors) for every refusal we return, [agent keys](/agent-keys#troubleshooting-faq) for the ones that are not specific to OpenScience, and [OpenCode](/opencode) for the per-model and per-variant deadline options, which OpenScience shares.
