Commit graph

8 commits

Author SHA1 Message Date
Devin Foley
bb7d040894
Switch OpenCode to explicit static/local-aware model selection (#5117)
> **Stacked PR (part 4 of 7).** Depends on:
  - PR #5114
  - PR #5115
  - PR #5116
> Diff against `master` includes commits from earlier PRs in the stack —
the new commit in this PR is the topmost one.

## Thinking Path

> - Paperclip orchestrates AI agents for zero-human companies
> - When creating an OpenCode-local agent, Paperclip currently validates
> `adapterConfig.model` against the *Paperclip host's* `opencode models`
output
> - SSH testing surfaced that this blocks creating an OpenCode agent for
an SSH
> environment: the model that exists on the SSH target isn't visible to
the
> host, so creation fails with "OpenCode requires `adapterConfig.model`
in
> provider/model format" even when the operator picked a real remote
model
> - The initial direction was environment-aware model discovery; the
final
> decision was to keep OpenCode on the same explicit-model pattern as
other
> adapters (default + curated list + manual override) and stop blocking
>   creation on host-side discovery
> - This PR does both: the adapter-models endpoint now accepts
`environmentId` and
> probes against the target environment, and the create-time hard gate
is
> replaced by `requireOpenCodeModelId` which validates `provider/model`
*format*
> without requiring host-local discovery. Test/run-time still surfaces
real
>   auth/availability problems
> - The benefit is that operators can create OpenCode agents for remote
> environments without out-of-band setup, and the model picker in the UI
>   reflects the actually-targeted environment

## What Changed

- Added `requireOpenCodeModelId(input)` in
`opencode-local/src/server/models.ts`,
  exported it from the adapter index
- `ensureOpenCodeModelConfiguredAndAvailable` now delegates the format
check to
  `requireOpenCodeModelId`
- `agentsApi.adapterModels(companyId, adapterType, { environmentId })`
now accepts
  an environment ID and passes it as a query parameter
- `queryKeys.agents.adapterModels` now keys on `(companyId, adapterType,
environmentId)`
- `server/src/routes/agents.ts` reads and validates the new query
parameter,
  forwarding it to the adapter's model probe
- `AgentConfigForm.tsx` and `OnboardingWizard.tsx` build the model query
key from
the currently selected default environment ID and disable autodetect for
  `opencode_local` (model selection is explicit)
- `NewAgent.tsx` simplified — no longer special-cases OpenCode
autodetect
- `company-portability.ts` no longer needs OpenCode-specific autodetect
handling
- Tests added/updated:
  `adapter-model-refresh-routes.test.ts`, `adapter-models.test.ts`,
`agent-permissions-routes.test.ts`,
`opencode-local/src/server/models.test.ts`

## Verification

- `pnpm --filter @paperclipai/server test -- adapter-models
adapter-model-refresh agent-permissions`
- `pnpm --filter @paperclipai/adapter-opencode-local test`
- `pnpm --filter @paperclipai/ui test -- AgentConfigForm
OnboardingWizard NewAgent`
- Manual QA in browser:
1. Boot Paperclip on Tailscale-bound port (so it's reachable from
another
machine), create an OpenCode-local agent, switch the default environment
between two installed sandboxes, and confirm the model list refreshes
     per-environment
  2. Submit with a malformed `provider/model` string and verify the new
     `requireOpenCodeModelId` error surfaces
- Before/after screenshots attached for `AgentConfigForm` model picker

## Risks

- Behavioural shift: switching default environment now triggers a model
refetch.
Should be cheap but introduces a new UI loading state for OpenCode
users.
- Removing dynamic autodetect for OpenCode: if any user configured an
agent
without specifying `model` and relied on autodetect populating it, that
agent
will now fail at submit time. Mitigation: validation error is explicit
and
  actionable.
- New query string parameter on `/api/companies/:id/adapter-models` —
older
clients that omit it still work (parameter is optional and defaults to
null).

## Model Used

- OpenAI GPT-5.4 (reasoning effort: high) via Codex CLI
- Provider: OpenAI
- Used to author the code changes in this PR

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] If this change affects the UI, I have included before/after
screenshots
- [ ] I have updated relevant documentation to reflect my changes — N/A
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
2026-05-03 13:01:34 -07:00
Devin Foley
72bc4ab403 fix(opencode): prevent opencode.json config pollution in workspace
Set OPENCODE_DISABLE_PROJECT_CONFIG=true in all OpenCode invocations
(execute, model discovery, environment test) to stop the OpenCode CLI
from writing an opencode.json file into the project working directory.
Model selection is already passed via the --model CLI flag.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-25 17:22:49 -07:00
John Wessel
5965266cb8
fix: guard os.userInfo() for UID-only containers, exclude HOME from cache key
Address Greptile review feedback:

1. Wrap os.userInfo() in try/catch — it throws SystemError when the
   current UID has no /etc/passwd entry (e.g. `docker run --user 1234`
   with a minimal image). Falls back to process.env.HOME gracefully.

2. Add HOME to VOLATILE_ENV_KEY_EXACT so the discovery cache key is
   not affected by the caller-supplied HOME vs the resolved HOME.
   os.userInfo().homedir is constant for the process lifetime, so
   HOME adds no useful cache differentiation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 13:05:23 -04:00
John Wessel
2aa607c828
fix(opencode-local): resolve HOME from os.userInfo() for model discovery
When Paperclip's server is started via `runuser -u node` (common in
Docker/Fly.io deployments), the HOME environment variable retains the
parent process's value (e.g. /root) instead of the target user's home
directory (/home/node). This causes `opencode models` to miss provider
auth credentials stored under the actual user's home, resulting in
"Configured OpenCode model is unavailable" errors for providers that
require API keys (e.g. zai/zhipuai).

Fix: use `os.userInfo().homedir` (reads from /etc/passwd, not env) to
ensure the child process always sees the correct HOME, regardless of
how the server was launched.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 12:58:13 -04:00
Dotta
f81d37fbf7 fix(heartbeat): prevent false process_lost failures on queued and non-child-process runs
- reapOrphanedRuns() now only scans running runs; queued runs are
  legitimately absent from runningProcesses (waiting on concurrency
  limits or issue locks) so including them caused false process_lost
  failures (closes #90)
- Add module-level activeRunExecutions set so non-child-process adapters
  (http, openclaw) are protected from the reaper during execution
- Add resumeQueuedRuns() to restart persisted queued runs after a server
  restart, called at startup and each periodic tick
- Add outer catch in executeRun() so setup failures (ensureRuntimeState,
  resolveWorkspaceForRun, etc.) are recorded as failed runs instead of
  leaving them stuck in running state
- Guard resumeQueuedRuns() against paused/terminated/pending_approval agents
- Increase opencode models discovery timeout from 20s to 45s
2026-03-12 17:24:50 -04:00
Aaron
b06e41bed2 Fix review feedback: duplicate wizard entry, command resolution, @types/node
- Remove duplicate opencode_local adapter entry in OnboardingWizard
  (old Code-icon version), keeping only the OpenCodeLogoIcon entry
- Extract resolveOpenCodeCommand() helper to deduplicate the
  PAPERCLIP_OPENCODE_COMMAND env-var fallback logic in models.ts
- Bump @types/node from ^22.12.0 to ^24.6.0 to match the monorepo

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 16:53:50 +00:00
Konan69
69c453b274 Address PR feedback for OpenCode integration 2026-03-05 15:52:59 +01:00
Konan69
6a101e0da1 Add OpenCode provider integration and strict model selection 2026-03-05 15:24:20 +01:00