Skip to content

feat: modifications for provider configuration - #209

Merged
sergiofilhowz merged 3 commits into
mainfrom
feat/provider-configuration
Jun 1, 2026
Merged

feat: modifications for provider configuration#209
sergiofilhowz merged 3 commits into
mainfrom
feat/provider-configuration

Conversation

@sergiofilhowz

@sergiofilhowz sergiofilhowz commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • Architecture & Configuration

    • Credentials/settings moved to a centralized harness configuration; provider registration/resolution is centralized.
    • Model catalogs are populated by provider discovery and refresh rather than embedded static seeds.
  • Console Improvements

    • In-app provider settings removed; links deep‑link to harness configuration.
    • Model picker shows present providers and a refresh button to update catalogs.
  • Admin & Configuration

    • Default agent permission mode now configurable.
    • Providers can self-declare and refresh models at runtime.
  • Documentation

    • Updated guides for providers, harness layout, and configuration.

@vercel

vercel Bot commented Jun 1, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
workers Ready Ready Preview, Comment Jun 1, 2026 8:15pm

Request Review

@github-actions

github-actions Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

skill-check — worker

0 verified, 13 skipped (no docs/).

Layer Result
structure
vale
ai
render

Note

17 stale rendered artifact(s) detected on main, unrelated to this PR. This PR is fine; the drift was already there. A maintainer should open a chore PR to re-render these.

  • shell/README.md
  • shell/skill.md
  • shell/skills/chmod.md
  • shell/skills/exec.md
  • shell/skills/exec_bg.md
  • shell/skills/grep.md
  • shell/skills/kill.md
  • shell/skills/list.md
  • shell/skills/ls.md
  • shell/skills/mkdir.md
  • shell/skills/mv.md
  • shell/skills/read.md
  • …and 5 more (see the workflow logs)

@coderabbitai

coderabbitai Bot commented Jun 1, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@sergiofilhowz, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 3 minutes and 45 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3899c96b-fde0-4de2-82eb-c0e5679c71d2

📥 Commits

Reviewing files that changed from the base of the PR and between 6dfa30f and 470e38e.

📒 Files selected for processing (1)
  • harness/docs/architecture.md
📝 Walkthrough

Walkthrough

Consolidates provider credentials/settings into a harness-owned harness configuration entry and ProviderRegistry. Providers resolve via harness::provider::resolve, support upstream model discovery and provider::::refresh_models, models-catalog reads from state only, console UI deep-links to harness configuration and can refresh provider models, and legacy auth/provider-config modules/tests are removed.

Changes

Harness provider registry and console integration

Layer / File(s) Summary
Runtime configuration & discovery helpers
harness/src/runtime/configuration.ts, harness/src/runtime/provider-resolve.ts, harness/src/runtime/models-discovery.ts, harness/src/runtime/harness-config.ts
Adds configuration client wrappers, provider-resolve/declaration helpers, model-discovery helpers, harness config shape/normalize/read utilities.
ProviderRegistry implementation and wiring
harness/src/harness/providers/registry.ts, harness/src/harness/providers/register.ts, harness/src/harness/register.ts, harness/src/harness/iii.worker.yaml, harness/engine.config.yaml, harness/tests/harness/providers/registry.test.ts
Implements in-memory ProviderRegistry, composes harness JSON schema, registers harness::provider::{register,resolve,list}, ensures harness entry, and adds tests for init/declare/resolve paths.
Providers: resolve + discovery/refresh
harness/src/provider-*/{auth,discover,refresh-fn,register,types}.ts, harness/src/provider-*/iii.worker.yaml, harness/src/runtime/models-discovery.ts, harness/docs/workers/provider-*.md, harness/tests/provider-*/auth.test.ts
Refactors providers to call resolveProvider for credentials/settings, adds discoverAndRegister and provider::::refresh_models handlers, declares providers into harness schema, schedules startup discovery, updates manifests/docs/tests.
Models catalog: state-only
harness/src/models-catalog/*, harness/docs/workers/models-catalog.md, harness/package.json
Removes embedded seed/catalog; list/get/supports read only from iii state; adds ListFilter type and updates docs and package scripts/bins for models-catalog.
Console/web integration
console/web/src/components/chat/ModelPicker.tsx, console/web/src/hooks/use-model-picker-source.ts, console/web/src/lib/{models-catalog,providers}.ts, console/web/src/lib/conversations-context.tsx, console/web/src/pages/Configuration/tabs/ConsoleSettingsTab.tsx, console/web/src/types/chat.ts, console/web/src/lib/providers.test.ts
ModelPicker deep-links to harness configuration and shows refresh; hook exposes presentProviders and refresh; conversations context exposes refreshModels/refreshingModels and presentProviders; settings tab replaced with deep-link to harness config; provider-registry & provider settings dialog removed; tests updated.
Deprecations, manifests, workflows, docs, tests cleanup
.github/workflows/_publish-registry.yml, README.md, harness/src/index.ts, harness/docs/{architecture,storage,workers/*}, iii-permissions.yaml, harness/tests/auth-credentials/*
Removes auth-credentials and provider-config workers and their tests, replaces dependencies with configuration where needed, updates engine/worker manifests, CI workflow comments, permissions deny rules, and related documentation.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Console as Console UI
  participant Harness as harness::provider::list/resolve
  participant Providers as provider::<id>::refresh_models
  participant Config as configuration::get/set/register
  Console->>Harness: list providers
  Console->>Providers: refresh_models (parallel)
  Providers-->>Harness: models::register (via discovery)
  Console->>Harness: resolve(provider) for selection
  Harness->>Config: get('harness') (composed schema/value)
  Config-->>Harness: providers + permissions
  Harness-->>Console: {credential, api_url, max_tokens}
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

  • iii-hq/workers#185: Changes related to approval-gate wiring and approvals persistence; overlaps on approval-gate adjustments.
  • iii-hq/workers#40: Modifies the same CI workflow (.github/workflows/_publish-registry.yml) as this PR.
  • iii-hq/workers#173: Related work touching provider credential/config flows for Kimi/ Moonshot provider.

Poem

A rabbit taps the registry tree,
Keys and tokens set free.
Models whisper, then refresh,
Console hops to settings—no more mess.
Thump-thump: configuration snug as can be. 🐇✨

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/provider-configuration

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
harness/src/provider-lmstudio/auth.ts (1)

120-141: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Ensure the lm-studio fallback token cannot be sent as Authorization to non-loopback hosts.
In harness/src/provider-lmstudio/auth.ts (lines 120-141), when selectAuthKey(...) returns null, effective is still set to { type: 'api_key', key: FALLBACK_API_KEY }, so configFromCredential(...) will carry "lm-studio" into ChatCompletionsConfig.api_key. But harness/docs/workers/provider-lmstudio.md states that when auth is missing, the worker falls back to the literal lm-studio token so the Authorization header is always present—contradicting the inline claim that the null-key case omits Authorization. Update/align the implementation so the fallback is only used for loopback (or otherwise guarantee Authorization is omitted for non-loopback when no credential is available).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@harness/src/provider-lmstudio/auth.ts` around lines 120 - 141, The code
currently injects FALLBACK_API_KEY into effective when selectAuthKey(...)
returns null, which causes configFromCredential(...) to carry an api_key and may
send Authorization to remote hosts; change the logic so the FALLBACK_API_KEY is
only applied for loopback/local URLs: add or use a small helper (e.g.,
isLoopbackApiUrl or isLoopbackHost) to detect loopback origins from apiUrl
(normalizeChatCompletionsUrl output), and only set effective = { type:
'api_key', key: FALLBACK_API_KEY } when key === null AND
isLoopbackApiUrl(apiUrl) is true; otherwise set effective to a sentinel that
causes no Authorization (e.g., null/undefined or a { type: 'none' } value that
configFromCredential/buildAuthHeaders treat as no auth), keeping references to
selectAuthKey, normalizeChatCompletionsUrl, configFromCredential, and
FALLBACK_API_KEY to locate the change.
🧹 Nitpick comments (7)
.github/workflows/_publish-registry.yml (1)

375-380: 💤 Low value

Stale iii-database references left behind.

With the database pre-start removed (per the new comment at Lines 105-108), no step writes iii-database.pid or iii-database.log anymore, so the "Stop dependency workers" step here and the iii-database.log dump at Lines 362-366 are now dead no-ops. They're harmless (both file-existence guarded) but contradict the new comment; consider removing them for clarity.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/_publish-registry.yml around lines 375 - 380, Remove the
now-dead "Stop dependency workers" step and the separate `iii-database.log` dump
step from the GitHub Actions workflow, and delete any remaining checks or
commands that reference `iii-database.pid` or `iii-database.log` (these include
the kill guarded by `if [[ -f iii-database.pid ]]; then ...` and the cat/dump of
`iii-database.log`), so the workflow no longer contains stale `iii-database`
references that are never created.
console/web/src/pages/Configuration/tabs/ConsoleSettingsTab.tsx (1)

22-24: ⚡ Quick win

Duplicate HARNESS_CONFIG_HASH constant.

This constant is also defined in ModelPicker.tsx (line 15). Consider extracting it to a shared location (e.g., a routes/constants module) to avoid drift if the hash format changes.

♻️ Example extraction

Create a shared constant:

// e.g., in `@/lib/routes.ts` or similar
export const HARNESS_CONFIG_HASH = '`#/configuration/workers/harness`'

Then import in both files.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@console/web/src/pages/Configuration/tabs/ConsoleSettingsTab.tsx` around lines
22 - 24, The HARNESS_CONFIG_HASH constant is duplicated (defined in
ConsoleSettingsTab and ModelPicker); extract it into a shared module (e.g., a
routes/constants file) and replace the local definitions with an import of that
single exported constant (update ConsoleSettingsTab and ModelPicker to import
HARNESS_CONFIG_HASH). Ensure the new module exports the exact string and update
both files to remove their local HARNESS_CONFIG_HASH definitions and reference
the shared symbol instead.
console/web/src/lib/conversations-context.tsx (1)

64-81: 💤 Low value

Stale presentProviders reference in dependency array could cause unnecessary re-renders.

The refreshModels callback captures presentProviders in its closure but also lists it as a dependency. This means refreshModels gets a new identity every time the provider list changes (e.g., after every successful fetch), which may cause downstream useEffect or memoization dependencies to re-trigger unnecessarily.

If this is intentional (to always use the latest providers), consider using a ref to hold presentProviders to avoid re-creating the callback. However, if the current behavior is acceptable for your use case, this is a minor consideration.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@console/web/src/lib/conversations-context.tsx` around lines 64 - 81, The
callback refreshModels closes over presentProviders and lists it in the
dependency array, causing refreshModels to be re-created whenever provider list
updates; change it to read presentProviders from a stable ref instead: create a
useRef (e.g., presentProvidersRef), update presentProvidersRef.current whenever
presentProviders changes, then inside refreshModels read ids from
presentProvidersRef.current and remove presentProviders from the dependency
array; ensure other real dependencies like refresh, refreshProviderModels and
backend.id remain in the array so refreshModels identity is stable while still
using the latest provider list.
console/web/src/lib/models-catalog.ts (1)

55-64: 💤 Low value

Redundant .catch() when using Promise.allSettled.

Promise.allSettled already handles rejections without throwing, so the inner .catch(() => undefined) is redundant. Either approach works, but using both adds unnecessary complexity.

♻️ Suggested simplification
 export async function refreshProviderModels(
   providers: readonly string[],
 ): Promise<void> {
   const client = await getIiiClient()
   await Promise.allSettled(
-    providers.map((p) =>
-      client.call(`provider::${p}::refresh_models`, {}).catch(() => undefined),
-    ),
+    providers.map((p) => client.call(`provider::${p}::refresh_models`, {})),
   )
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@console/web/src/lib/models-catalog.ts` around lines 55 - 64, The inner
.catch(() => undefined) within refreshProviderModels is redundant because
Promise.allSettled already captures rejections; remove the per-call catch and
let Promise.allSettled handle outcomes. Update refreshProviderModels to await
Promise.allSettled over providers.map(p =>
client.call(`provider::${p}::refresh_models`, {})) and keep getIiiClient and
client.call usage unchanged so failures are represented in the settled results
instead of being swallowed by the inner catch.
harness/src/runtime/models-discovery.ts (1)

32-32: ⚡ Quick win

Use a template literal here.

The lint check flagged this string concatenation; align it to avoid a CI lint failure.

♻️ Proposed fix
-    return apiUrl.replace(/\/+$/, '') + '/models';
+    return `${apiUrl.replace(/\/+$/, '')}/models`;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@harness/src/runtime/models-discovery.ts` at line 32, Replace the string
concatenation that builds the models endpoint by using a template literal:
instead of returning apiUrl.replace(/\/+$/, '') + '/models', return a template
string that interpolates the trimmed apiUrl and appends /models (e.g.,
`${apiUrl.replace(/\/+$/, '')}/models`) so the lint rule is satisfied; update
the return in the function that uses the apiUrl variable accordingly.
harness/src/provider-lmstudio/auth.ts (2)

26-76: 💤 Low value

EMPTY_RESOLVE + resolveTolerant are duplicated verbatim across local-first providers.

This block is identical to the one in harness/src/provider-llamacpp/auth.ts (only the log message/code string differ). Consider hoisting a shared tolerant resolver helper (parameterized by provider id and log code) into runtime/provider-resolve.js to avoid drift.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@harness/src/provider-lmstudio/auth.ts` around lines 26 - 76, The
EMPTY_RESOLVE constant and resolveTolerant function (used in
harness/src/provider-lmstudio/auth.ts) are duplicated across local-first
providers; extract a shared helper into runtime/provider-resolve.js that exports
a factory or function like createTolerantResolver(providerId: string, warnCode:
string) or resolveProviderTolerant(iii, providerId, warnCode) and replace the
local EMPTY_RESOLVE and resolveTolerant usages (which reference PROVIDER_ID and
call logger.warn) with calls to that shared helper so each provider only passes
its PROVIDER_ID and log code string to avoid drift.

120-128: ⚖️ Poor tradeoff

Redundant provider resolution on the request path.

buildConfig calls resolveTolerant once, but the actual headers are produced by buildAuthHeadersfetchCredentialresolveTolerant again, so each request triggers harness::provider::resolve (a cross-worker bus call) at least twice. Consider resolving once and threading the result (or the selected key) through to header construction.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@harness/src/provider-lmstudio/auth.ts` around lines 120 - 128, The code calls
resolveTolerant twice per request (once in buildConfig and again via
buildAuthHeaders → fetchCredential → resolveTolerant), causing redundant
cross-worker resolution; fix this by resolving once in buildConfig and threading
the resolved result (or the selected key) into header construction instead of
calling resolveTolerant again — update buildConfig to pass the resolved object
or selected auth key (from selectAuthKey) down into
buildAuthHeaders/fetchCredential (or change fetchCredential signature to accept
the resolved credential), remove the second resolveTolerant call, and ensure
overrideUrl/apiUrl and maxTokens are derived from the already-resolved object
(resolved) so fetchCredential/buildAuthHeaders use the passed-in values.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@harness/docs/architecture.md`:
- Line 27: The architecture doc line for models-catalog is stale: it incorrectly
mentions an “embedded fallback.” Update harness/docs/architecture.md to remove
the “embedded fallback” wording and describe models-catalog as state-first with
no embedded seed/fallback (consistent with harness/src/models-catalog/state.ts
and the provider::<name>::refresh_models behavior); also ensure any linked
worker doc reference (workers/models-catalog.md) matches the corrected phrasing
so docs and code (state.ts handlers) are consistent.

In `@harness/src/harness/providers/register.ts`:
- Around line 1-71: This file's formatting doesn't match the repo formatter; run
the project formatter (e.g. pnpm format or prettier --write) and commit the
resulting changes so CI passes. Locate the module that defines
DeclarationSchema, ResolveSchema and the export async function
registerProviderRegistry (which constructs ProviderRegistry and calls
iii.registerFunction for 'harness::provider::register',
'harness::provider::resolve', and 'harness::provider::list') and let the
formatter reflow spacing/line breaks in this file (and the companion registry
implementation) before committing the formatted files.

In `@harness/src/provider-anthropic/discover.ts`:
- Around line 50-55: The discovery code is sending OAuth credentials as
x-api-key instead of the proper Authorization header; update the header
construction in the block that calls deriveModelsUrl and fetchModelsJson to use
the existing authHeaderFor helper (from types.ts) for the credential (cred) and
merge it with the 'anthropic-version' header (and any other required headers)
before passing to fetchModelsJson; keep using deriveModelsUrl(resolved?.api_url
?? worker.default_api_url) and ANTHROPIC_VERSION but replace the hardcoded
{'x-api-key': key} with the result of authHeaderFor(cred) so OAuth tokens are
sent as Authorization: Bearer … and API keys still work.

In `@harness/src/provider-kimi/register.ts`:
- Around line 19-28: The fire-and-forget call to declareProvider(...) (the call
that uses PROVIDER_ID and worker defaults) returns a promise that's currently
discarded with void and has no rejection handler; attach a .catch to that
promise (similar to how discoverAndRegister is guarded) to handle transient
startup failures — e.g., call declareProvider(...).catch(err =>
processLogger.error(`Failed to declare provider ${PROVIDER_ID}`, err)) so the
error is logged (include the error details and PROVIDER_ID) instead of causing
an unhandled rejection.

In `@harness/src/provider-lmstudio/register.ts`:
- Around line 26-32: The call to declareProvider(iii, { id: PROVIDER_ID, ... })
is fire-and-forget and can cause unhandled promise rejections; change it to
handle promise failures by either awaiting the call or appending a .catch
handler that logs the error (consistent with the setImmediate discovery call
below), e.g. await declareProvider(...) inside an async initializer or
declareProvider(...).catch(err => /* log or handle error */), referencing the
declareProvider invocation and PROVIDER_ID so the rejection is handled.

In `@harness/tests/harness/providers/registry.test.ts`:
- Around line 106-108: The finally block currently sets
process.env.III_TEST_PROVIDER_KEY = undefined which leaves a string "undefined"
in the env; replace that assignment with using the delete operator to remove
process.env.III_TEST_PROVIDER_KEY so the environment variable is truly unset and
cannot leak into other tests (locate the finally block in the test teardown
where process.env.III_TEST_PROVIDER_KEY is manipulated).

---

Outside diff comments:
In `@harness/src/provider-lmstudio/auth.ts`:
- Around line 120-141: The code currently injects FALLBACK_API_KEY into
effective when selectAuthKey(...) returns null, which causes
configFromCredential(...) to carry an api_key and may send Authorization to
remote hosts; change the logic so the FALLBACK_API_KEY is only applied for
loopback/local URLs: add or use a small helper (e.g., isLoopbackApiUrl or
isLoopbackHost) to detect loopback origins from apiUrl
(normalizeChatCompletionsUrl output), and only set effective = { type:
'api_key', key: FALLBACK_API_KEY } when key === null AND
isLoopbackApiUrl(apiUrl) is true; otherwise set effective to a sentinel that
causes no Authorization (e.g., null/undefined or a { type: 'none' } value that
configFromCredential/buildAuthHeaders treat as no auth), keeping references to
selectAuthKey, normalizeChatCompletionsUrl, configFromCredential, and
FALLBACK_API_KEY to locate the change.

---

Nitpick comments:
In @.github/workflows/_publish-registry.yml:
- Around line 375-380: Remove the now-dead "Stop dependency workers" step and
the separate `iii-database.log` dump step from the GitHub Actions workflow, and
delete any remaining checks or commands that reference `iii-database.pid` or
`iii-database.log` (these include the kill guarded by `if [[ -f iii-database.pid
]]; then ...` and the cat/dump of `iii-database.log`), so the workflow no longer
contains stale `iii-database` references that are never created.

In `@console/web/src/lib/conversations-context.tsx`:
- Around line 64-81: The callback refreshModels closes over presentProviders and
lists it in the dependency array, causing refreshModels to be re-created
whenever provider list updates; change it to read presentProviders from a stable
ref instead: create a useRef (e.g., presentProvidersRef), update
presentProvidersRef.current whenever presentProviders changes, then inside
refreshModels read ids from presentProvidersRef.current and remove
presentProviders from the dependency array; ensure other real dependencies like
refresh, refreshProviderModels and backend.id remain in the array so
refreshModels identity is stable while still using the latest provider list.

In `@console/web/src/lib/models-catalog.ts`:
- Around line 55-64: The inner .catch(() => undefined) within
refreshProviderModels is redundant because Promise.allSettled already captures
rejections; remove the per-call catch and let Promise.allSettled handle
outcomes. Update refreshProviderModels to await Promise.allSettled over
providers.map(p => client.call(`provider::${p}::refresh_models`, {})) and keep
getIiiClient and client.call usage unchanged so failures are represented in the
settled results instead of being swallowed by the inner catch.

In `@console/web/src/pages/Configuration/tabs/ConsoleSettingsTab.tsx`:
- Around line 22-24: The HARNESS_CONFIG_HASH constant is duplicated (defined in
ConsoleSettingsTab and ModelPicker); extract it into a shared module (e.g., a
routes/constants file) and replace the local definitions with an import of that
single exported constant (update ConsoleSettingsTab and ModelPicker to import
HARNESS_CONFIG_HASH). Ensure the new module exports the exact string and update
both files to remove their local HARNESS_CONFIG_HASH definitions and reference
the shared symbol instead.

In `@harness/src/provider-lmstudio/auth.ts`:
- Around line 26-76: The EMPTY_RESOLVE constant and resolveTolerant function
(used in harness/src/provider-lmstudio/auth.ts) are duplicated across
local-first providers; extract a shared helper into runtime/provider-resolve.js
that exports a factory or function like createTolerantResolver(providerId:
string, warnCode: string) or resolveProviderTolerant(iii, providerId, warnCode)
and replace the local EMPTY_RESOLVE and resolveTolerant usages (which reference
PROVIDER_ID and call logger.warn) with calls to that shared helper so each
provider only passes its PROVIDER_ID and log code string to avoid drift.
- Around line 120-128: The code calls resolveTolerant twice per request (once in
buildConfig and again via buildAuthHeaders → fetchCredential → resolveTolerant),
causing redundant cross-worker resolution; fix this by resolving once in
buildConfig and threading the resolved result (or the selected key) into header
construction instead of calling resolveTolerant again — update buildConfig to
pass the resolved object or selected auth key (from selectAuthKey) down into
buildAuthHeaders/fetchCredential (or change fetchCredential signature to accept
the resolved credential), remove the second resolveTolerant call, and ensure
overrideUrl/apiUrl and maxTokens are derived from the already-resolved object
(resolved) so fetchCredential/buildAuthHeaders use the passed-in values.

In `@harness/src/runtime/models-discovery.ts`:
- Line 32: Replace the string concatenation that builds the models endpoint by
using a template literal: instead of returning apiUrl.replace(/\/+$/, '') +
'/models', return a template string that interpolates the trimmed apiUrl and
appends /models (e.g., `${apiUrl.replace(/\/+$/, '')}/models`) so the lint rule
is satisfied; update the return in the function that uses the apiUrl variable
accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0ba00f62-b981-445a-bdd2-747e99d81731

📥 Commits

Reviewing files that changed from the base of the PR and between 28fb49a and bfc1106.

📒 Files selected for processing (120)
  • .github/workflows/_publish-registry.yml
  • README.md
  • console/web/src/components/chat/ModelPicker.tsx
  • console/web/src/components/providers/ProviderRow.tsx
  • console/web/src/components/providers/ProviderSettingsDialog.tsx
  • console/web/src/components/providers/StatusBadge.tsx
  • console/web/src/components/providers/provider-registry.ts
  • console/web/src/hooks/use-model-picker-source.ts
  • console/web/src/hooks/use-providers.ts
  • console/web/src/lib/conversations-context.tsx
  • console/web/src/lib/models-catalog.ts
  • console/web/src/lib/providers.test.ts
  • console/web/src/lib/providers.ts
  • console/web/src/pages/Configuration/tabs/ConsoleSettingsTab.tsx
  • console/web/src/types/chat.ts
  • harness/README.md
  • harness/docs/architecture.md
  • harness/docs/storage.md
  • harness/docs/workers/auth-credentials.md
  • harness/docs/workers/harness.md
  • harness/docs/workers/models-catalog.md
  • harness/docs/workers/provider-anthropic.md
  • harness/docs/workers/provider-config.md
  • harness/docs/workers/provider-kimi.md
  • harness/docs/workers/provider-lmstudio.md
  • harness/docs/workers/provider-openai.md
  • harness/engine.config.yaml
  • harness/iii.worker.yaml
  • harness/package.json
  • harness/src/approval-gate/main.ts
  • harness/src/approval-gate/settings/default-mode.ts
  • harness/src/approval-gate/settings/store.ts
  • harness/src/auth-credentials/config.ts
  • harness/src/auth-credentials/handlers/delete-token.ts
  • harness/src/auth-credentials/handlers/get-token.ts
  • harness/src/auth-credentials/handlers/list-providers.ts
  • harness/src/auth-credentials/handlers/set-token.ts
  • harness/src/auth-credentials/handlers/status.ts
  • harness/src/auth-credentials/iii.worker.yaml
  • harness/src/auth-credentials/main.ts
  • harness/src/auth-credentials/register.ts
  • harness/src/auth-credentials/resolve.ts
  • harness/src/auth-credentials/store.ts
  • harness/src/auth-credentials/types.ts
  • harness/src/harness/iii.worker.yaml
  • harness/src/harness/providers/register.ts
  • harness/src/harness/providers/registry.ts
  • harness/src/harness/register.ts
  • harness/src/index.ts
  • harness/src/models-catalog/catalog.ts
  • harness/src/models-catalog/handlers/get.ts
  • harness/src/models-catalog/handlers/list.ts
  • harness/src/models-catalog/handlers/supports.ts
  • harness/src/models-catalog/models.json
  • harness/src/models-catalog/register.ts
  • harness/src/models-catalog/state.ts
  • harness/src/models-catalog/types.ts
  • harness/src/provider-anthropic/auth.ts
  • harness/src/provider-anthropic/discover.ts
  • harness/src/provider-anthropic/iii.worker.yaml
  • harness/src/provider-anthropic/refresh-fn.ts
  • harness/src/provider-anthropic/register.ts
  • harness/src/provider-anthropic/types.ts
  • harness/src/provider-config/config.ts
  • harness/src/provider-config/handlers/clear.ts
  • harness/src/provider-config/handlers/get.ts
  • harness/src/provider-config/handlers/list.ts
  • harness/src/provider-config/handlers/set.ts
  • harness/src/provider-config/iii.worker.yaml
  • harness/src/provider-config/main.ts
  • harness/src/provider-config/register.ts
  • harness/src/provider-config/store.ts
  • harness/src/provider-config/types.ts
  • harness/src/provider-kimi/auth.ts
  • harness/src/provider-kimi/discover.ts
  • harness/src/provider-kimi/iii.worker.yaml
  • harness/src/provider-kimi/refresh-fn.ts
  • harness/src/provider-kimi/register.ts
  • harness/src/provider-kimi/types.ts
  • harness/src/provider-llamacpp/auth.ts
  • harness/src/provider-llamacpp/iii.worker.yaml
  • harness/src/provider-llamacpp/register.ts
  • harness/src/provider-llamacpp/types.ts
  • harness/src/provider-lmstudio/auth.ts
  • harness/src/provider-lmstudio/iii.worker.yaml
  • harness/src/provider-lmstudio/register.ts
  • harness/src/provider-lmstudio/types.ts
  • harness/src/provider-openai/auth.ts
  • harness/src/provider-openai/discover.ts
  • harness/src/provider-openai/iii.worker.yaml
  • harness/src/provider-openai/refresh-fn.ts
  • harness/src/provider-openai/register.ts
  • harness/src/provider-openai/types.ts
  • harness/src/runtime/configuration.ts
  • harness/src/runtime/database-store.ts
  • harness/src/runtime/fetch-overrides.ts
  • harness/src/runtime/harness-config.ts
  • harness/src/runtime/models-discovery.ts
  • harness/src/runtime/provider-resolve.ts
  • harness/src/runtime/storage-config.ts
  • harness/src/web/register.ts
  • harness/tests/auth-credentials/env-map-kimi.test.ts
  • harness/tests/auth-credentials/env-map-llamacpp.test.ts
  • harness/tests/auth-credentials/env-map-lmstudio.test.ts
  • harness/tests/auth-credentials/resolve.test.ts
  • harness/tests/auth-credentials/store.test.ts
  • harness/tests/harness/policy.test.ts
  • harness/tests/harness/providers/registry.test.ts
  • harness/tests/models-catalog/catalog.test.ts
  • harness/tests/models-catalog/seed-kimi.test.ts
  • harness/tests/models-catalog/seed-llamacpp.test.ts
  • harness/tests/models-catalog/seed-lmstudio.test.ts
  • harness/tests/provider-config/handlers.test.ts
  • harness/tests/provider-config/store.test.ts
  • harness/tests/provider-llamacpp/auth.test.ts
  • harness/tests/provider-lmstudio/auth.test.ts
  • harness/tests/runtime/database-store.test.ts
  • harness/tests/runtime/fake-database-sdk.ts
  • harness/tests/runtime/storage-config.test.ts
  • iii-permissions.yaml
💤 Files with no reviewable changes (50)
  • harness/src/auth-credentials/handlers/get-token.ts
  • harness/docs/workers/auth-credentials.md
  • harness/src/auth-credentials/iii.worker.yaml
  • harness/src/provider-config/types.ts
  • harness/tests/models-catalog/seed-kimi.test.ts
  • harness/src/provider-config/iii.worker.yaml
  • harness/src/auth-credentials/handlers/set-token.ts
  • harness/tests/provider-config/store.test.ts
  • harness/src/auth-credentials/handlers/list-providers.ts
  • harness/src/auth-credentials/register.ts
  • harness/src/models-catalog/models.json
  • harness/tests/models-catalog/seed-llamacpp.test.ts
  • harness/src/auth-credentials/types.ts
  • harness/src/auth-credentials/main.ts
  • harness/src/auth-credentials/handlers/status.ts
  • harness/src/provider-config/handlers/list.ts
  • harness/src/auth-credentials/resolve.ts
  • harness/tests/auth-credentials/env-map-kimi.test.ts
  • console/web/src/components/providers/ProviderSettingsDialog.tsx
  • harness/src/runtime/storage-config.ts
  • harness/src/runtime/fetch-overrides.ts
  • harness/tests/runtime/storage-config.test.ts
  • harness/tests/runtime/fake-database-sdk.ts
  • harness/tests/models-catalog/seed-lmstudio.test.ts
  • harness/tests/auth-credentials/env-map-llamacpp.test.ts
  • harness/src/runtime/database-store.ts
  • harness/src/provider-config/handlers/clear.ts
  • harness/tests/provider-config/handlers.test.ts
  • harness/tests/auth-credentials/resolve.test.ts
  • harness/src/provider-config/config.ts
  • harness/src/models-catalog/catalog.ts
  • console/web/src/hooks/use-providers.ts
  • console/web/src/components/providers/StatusBadge.tsx
  • harness/src/provider-config/register.ts
  • harness/src/provider-config/handlers/set.ts
  • harness/docs/workers/provider-config.md
  • harness/src/auth-credentials/config.ts
  • harness/tests/runtime/database-store.test.ts
  • harness/tests/models-catalog/catalog.test.ts
  • harness/src/provider-config/store.ts
  • harness/src/provider-config/handlers/get.ts
  • harness/tests/auth-credentials/store.test.ts
  • harness/package.json
  • harness/src/auth-credentials/store.ts
  • harness/tests/auth-credentials/env-map-lmstudio.test.ts
  • harness/src/auth-credentials/handlers/delete-token.ts
  • console/web/src/components/providers/ProviderRow.tsx
  • console/web/src/lib/providers.test.ts
  • harness/src/provider-config/main.ts
  • console/web/src/components/providers/provider-registry.ts

Comment thread harness/docs/architecture.md Outdated
Comment thread harness/src/harness/providers/register.ts
Comment on lines +50 to +55
const key = cred.type === 'api_key' ? cred.key : cred.access_token;
const url = deriveModelsUrl(resolved?.api_url ?? worker.default_api_url);
const json = await fetchModelsJson(url, {
'x-api-key': key,
'anthropic-version': ANTHROPIC_VERSION,
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Discovery sends the wrong auth header for OAuth credentials.

For an oauth_bearer credential the access token is sent as x-api-key, but Anthropic expects Authorization: Bearer … for OAuth (see authHeaderFor in types.ts). The /v1/models request will then fail auth and discovery silently returns [], so OAuth-authenticated users never get a live model list.

🐛 Proposed fix
-  const key = cred.type === 'api_key' ? cred.key : cred.access_token;
   const url = deriveModelsUrl(resolved?.api_url ?? worker.default_api_url);
-  const json = await fetchModelsJson(url, {
-    'x-api-key': key,
-    'anthropic-version': ANTHROPIC_VERSION,
-  });
+  const authHeader: Record<string, string> =
+    cred.type === 'api_key'
+      ? { 'x-api-key': cred.key }
+      : { authorization: `Bearer ${cred.access_token}` };
+  const json = await fetchModelsJson(url, {
+    ...authHeader,
+    'anthropic-version': ANTHROPIC_VERSION,
+  });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@harness/src/provider-anthropic/discover.ts` around lines 50 - 55, The
discovery code is sending OAuth credentials as x-api-key instead of the proper
Authorization header; update the header construction in the block that calls
deriveModelsUrl and fetchModelsJson to use the existing authHeaderFor helper
(from types.ts) for the credential (cred) and merge it with the
'anthropic-version' header (and any other required headers) before passing to
fetchModelsJson; keep using deriveModelsUrl(resolved?.api_url ??
worker.default_api_url) and ANTHROPIC_VERSION but replace the hardcoded
{'x-api-key': key} with the result of authHeaderFor(cred) so OAuth tokens are
sent as Authorization: Bearer … and API keys still work.

Comment on lines +19 to +28
void declareProvider(iii, {
id: PROVIDER_ID,
display_name: 'kimi (moonshot)',
credential_env_var: 'MOONSHOT_API_KEY',
defaults: {
api_url: worker.default_api_url,
max_tokens: worker.default_max_tokens,
},
supports_model_listing: true,
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Attach a rejection handler to the fire-and-forget declareProvider call.

void declareProvider(...) discards the returned promise without a .catch. A transient failure during startup self-registration would surface as an unhandled rejection (process termination on current Node defaults), crashing the worker at boot. The neighboring discoverAndRegister call already guards with .catch; mirror that here.

🛡️ Proposed fix
-  void declareProvider(iii, {
-    id: PROVIDER_ID,
-    display_name: 'kimi (moonshot)',
-    credential_env_var: 'MOONSHOT_API_KEY',
-    defaults: {
-      api_url: worker.default_api_url,
-      max_tokens: worker.default_max_tokens,
-    },
-    supports_model_listing: true,
-  });
+  void declareProvider(iii, {
+    id: PROVIDER_ID,
+    display_name: 'kimi (moonshot)',
+    credential_env_var: 'MOONSHOT_API_KEY',
+    defaults: {
+      api_url: worker.default_api_url,
+      max_tokens: worker.default_max_tokens,
+    },
+    supports_model_listing: true,
+  }).catch((err) => {
+    logger.warn('kimi declareProvider failed', { err: String(err) });
+  });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
void declareProvider(iii, {
id: PROVIDER_ID,
display_name: 'kimi (moonshot)',
credential_env_var: 'MOONSHOT_API_KEY',
defaults: {
api_url: worker.default_api_url,
max_tokens: worker.default_max_tokens,
},
supports_model_listing: true,
});
void declareProvider(iii, {
id: PROVIDER_ID,
display_name: 'kimi (moonshot)',
credential_env_var: 'MOONSHOT_API_KEY',
defaults: {
api_url: worker.default_api_url,
max_tokens: worker.default_max_tokens,
},
supports_model_listing: true,
}).catch((err) => {
logger.warn('kimi declareProvider failed', { err: String(err) });
});
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@harness/src/provider-kimi/register.ts` around lines 19 - 28, The
fire-and-forget call to declareProvider(...) (the call that uses PROVIDER_ID and
worker defaults) returns a promise that's currently discarded with void and has
no rejection handler; attach a .catch to that promise (similar to how
discoverAndRegister is guarded) to handle transient startup failures — e.g.,
call declareProvider(...).catch(err => processLogger.error(`Failed to declare
provider ${PROVIDER_ID}`, err)) so the error is logged (include the error
details and PROVIDER_ID) instead of causing an unhandled rejection.

Comment on lines +26 to +32
void declareProvider(iii, {
id: PROVIDER_ID,
display_name: 'lm studio',
credential_env_var: 'LMSTUDIO_API_KEY',
defaults: { max_tokens: worker.default_max_tokens },
supports_model_listing: true,
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

void declareProvider(...) can produce an unhandled promise rejection.

Unlike the setImmediate discovery below (which has a .catch), this fire-and-forget call discards the returned promise with void and has no rejection handler. If declareProvider rejects (e.g. the configuration worker isn't ready yet — the same race the discovery comment warns about), it surfaces as an unhandled rejection. Attach a .catch (or await it).

🛡️ Proposed fix
-  void declareProvider(iii, {
-    id: PROVIDER_ID,
-    display_name: 'lm studio',
-    credential_env_var: 'LMSTUDIO_API_KEY',
-    defaults: { max_tokens: worker.default_max_tokens },
-    supports_model_listing: true,
-  });
+  declareProvider(iii, {
+    id: PROVIDER_ID,
+    display_name: 'lm studio',
+    credential_env_var: 'LMSTUDIO_API_KEY',
+    defaults: { max_tokens: worker.default_max_tokens },
+    supports_model_listing: true,
+  }).catch((err) => {
+    logger.warn('lmstudio declareProvider failed', { err: String(err) });
+  });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
void declareProvider(iii, {
id: PROVIDER_ID,
display_name: 'lm studio',
credential_env_var: 'LMSTUDIO_API_KEY',
defaults: { max_tokens: worker.default_max_tokens },
supports_model_listing: true,
});
declareProvider(iii, {
id: PROVIDER_ID,
display_name: 'lm studio',
credential_env_var: 'LMSTUDIO_API_KEY',
defaults: { max_tokens: worker.default_max_tokens },
supports_model_listing: true,
}).catch((err) => {
logger.warn('lmstudio declareProvider failed', { err: String(err) });
});
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@harness/src/provider-lmstudio/register.ts` around lines 26 - 32, The call to
declareProvider(iii, { id: PROVIDER_ID, ... }) is fire-and-forget and can cause
unhandled promise rejections; change it to handle promise failures by either
awaiting the call or appending a .catch handler that logs the error (consistent
with the setImmediate discovery call below), e.g. await declareProvider(...)
inside an async initializer or declareProvider(...).catch(err => /* log or
handle error */), referencing the declareProvider invocation and PROVIDER_ID so
the rejection is handled.

Comment on lines +106 to +108
} finally {
process.env.III_TEST_PROVIDER_KEY = undefined;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

In Node.js, does assigning undefined to a process.env property delete it or coerce it to the string "undefined"?

💡 Result:

Assigning undefined to a process.env property does not delete it; it gets coerced to the string value "undefined" (i.e., the property remains present with the literal string value). [1] To actually remove/unset an environment variable from process.env, use delete, e.g. delete process.env.MY_VAR. [1]

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail
sed -n '90,125p' harness/tests/harness/providers/registry.test.ts

Repository: iii-hq/workers

Length of output: 1335


🏁 Script executed:

#!/bin/bash
set -euo pipefail
sed -n '90,125p' harness/tests/harness/providers/registry.test.ts

Repository: iii-hq/workers

Length of output: 1335


Use delete to unset the env var in finally.

process.env.III_TEST_PROVIDER_KEY = undefined leaves the variable set to the string "undefined" (truthy), so it can leak into subsequent tests. Replace it with delete.

💚 Proposed fix
-    } finally {
-      process.env.III_TEST_PROVIDER_KEY = undefined;
-    }
+    } finally {
+      delete process.env.III_TEST_PROVIDER_KEY;
+    }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
} finally {
process.env.III_TEST_PROVIDER_KEY = undefined;
}
} finally {
delete process.env.III_TEST_PROVIDER_KEY;
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@harness/tests/harness/providers/registry.test.ts` around lines 106 - 108, The
finally block currently sets process.env.III_TEST_PROVIDER_KEY = undefined which
leaves a string "undefined" in the env; replace that assignment with using the
delete operator to remove process.env.III_TEST_PROVIDER_KEY so the environment
variable is truly unset and cannot leak into other tests (locate the finally
block in the test teardown where process.env.III_TEST_PROVIDER_KEY is
manipulated).

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@harness/docs/workers/authoring-a-provider.md`:
- Around line 40-41: The markdown in authoring-a-provider.md uses incorrect
relative links like harness/docs/storage.md and
harness/docs/workers/models-catalog.md that will 404 from this file’s directory;
update those links to correct relative paths (e.g., change
harness/docs/storage.md → ../storage.md, harness/docs/workers/models-catalog.md
→ ./models-catalog.md or ../models-catalog.md as appropriate) and similarly fix
other targets referenced (e.g., provider-openai.md → ./provider-openai.md, any
src references → ../../src/...) so all links resolve from
authoring-a-provider.md; apply the same path corrections to the other reported
occurrences in this file.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 15e8dc69-4345-46e6-926b-34c5815de1d3

📥 Commits

Reviewing files that changed from the base of the PR and between bfc1106 and 6dfa30f.

📒 Files selected for processing (5)
  • harness/docs/architecture.md
  • harness/docs/workers/authoring-a-provider.md
  • harness/src/harness/providers/register.ts
  • harness/src/harness/providers/registry.ts
  • harness/tests/harness/providers/registry.test.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • harness/src/harness/providers/register.ts
  • harness/tests/harness/providers/registry.test.ts
  • harness/docs/architecture.md
  • harness/src/harness/providers/registry.ts

Comment on lines +40 to +41
[storage.md](harness/docs/storage.md). Models come exclusively from provider
registration — see [models-catalog.md](harness/docs/workers/models-catalog.md).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix relative links; several targets are likely broken from this file’s location.

From harness/docs/workers/authoring-a-provider.md, links written as harness/... resolve relative to the current directory and likely 404. Please switch to correct relative paths (e.g., ../storage.md, ./provider-openai.md, ../../src/..., etc.) or repo-root absolute paths if your renderer supports them.

Suggested patch pattern
-[storage.md](harness/docs/storage.md)
+[storage.md](../storage.md)

-[provider-openai](harness/docs/workers/provider-openai.md)
+[provider-openai](./provider-openai.md)

-[runtime/provider-resolve.ts](harness/src/runtime/provider-resolve.ts)
+[runtime/provider-resolve.ts](../../src/runtime/provider-resolve.ts)

Also applies to: 44-47, 97-97, 130-130, 135-135, 256-256, 262-262, 330-330, 341-341, 346-346, 353-353, 366-366, 369-369

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@harness/docs/workers/authoring-a-provider.md` around lines 40 - 41, The
markdown in authoring-a-provider.md uses incorrect relative links like
harness/docs/storage.md and harness/docs/workers/models-catalog.md that will 404
from this file’s directory; update those links to correct relative paths (e.g.,
change harness/docs/storage.md → ../storage.md,
harness/docs/workers/models-catalog.md → ./models-catalog.md or
../models-catalog.md as appropriate) and similarly fix other targets referenced
(e.g., provider-openai.md → ./provider-openai.md, any src references →
../../src/...) so all links resolve from authoring-a-provider.md; apply the same
path corrections to the other reported occurrences in this file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants