Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ scripts/ Repo tooling (run-app, cli-sandbox, release-notes)
- **No gratuitous defensive code.** Don't add try/catch, null checks, or input validation the surrounding file doesn't have — especially on paths already validated upstream. Match the file's level of paranoia.
- **No silent fallbacks.** No empty `catch`, no `?? default` that masks a bug, no `as any` to silence TypeScript. If something can fail, let it fail loudly or handle it explicitly.
- **Comments are rare and earn their place.** Only for constraints the code can't express (a protocol quirk, a deliberate perf trade-off). Never paraphrase the code, never narrate a change. When in doubt: no comment.
- **A comment states a durable constraint, not the moment you wrote it.** One or two lines. No issue ids, no measurements, no before/after story, no "I found that…" — that belongs in the PR body, the changeset, or a doc. Code outlives the task that produced it; a paragraph pinned to last Tuesday's investigation reads as noise six months later and nobody dares delete it.
- **This extends to all prose**: test names, error/log messages, changeset descriptions, PR bodies. Factual and plain — no emoji, no superlatives, no filler.
- **No speculative code.** No unrequested options or parameters, no "just in case" branches, no keeping the old code path alongside the new one. Delete dead code; public API deprecations are a maintainer decision — ask first.
- **Prefer deleting and simplifying over working around.** If the fix needs a workaround, question the design before adding the workaround.
Expand Down
5 changes: 3 additions & 2 deletions apps/evi/agent/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ export default defineAgent({
}),
/** This model honors only `high` and `xhigh`. */
reasoning: 'high',
/** Bounds a runaway session, not cost: one real thread runs a few million in. */
limits: {
maxInputTokensPerSession: 5_000_000,
maxOutputTokensPerSession: 100_000,
maxInputTokensPerSession: 20_000_000,
maxOutputTokensPerSession: 250_000,
},
modelOptions: {
providerOptions: { gateway: { ...gatewayRouting, tags: sessionTags() } },
Expand Down
8 changes: 0 additions & 8 deletions apps/evi/agent/connections/linear.ts

This file was deleted.

7 changes: 2 additions & 5 deletions apps/evi/agent/lib/channel.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
/**
* The channel name eve reports, without its prefix.
*
* Framework channels arrive bare (`http`, `schedule`, `subagent`); authored ones
* as `channel:<filename>`, so `agent/channels/github.ts` is `channel:github`.
* Comparing against the bare name without stripping never matches.
* The channel name eve reports, without its prefix. Framework channels arrive
* bare (`http`, `schedule`); authored ones as `channel:<filename>`.
*/
export function channelName(kind?: string): string {
return (kind ?? 'unknown').replace(/^channel:/, '')
Expand Down
8 changes: 3 additions & 5 deletions apps/evi/agent/lib/environment.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
/**
* Where this process is running, as one label.
*
* Shared by the gateway spend tags and the evlog wide events so a run that bills
* as `eval` also logs as `eval`. `EVE_RUN_MODE` is set by the `eval` script; it
* does not reach a deployment behind `eve eval --url`.
* Where this process is running. Shared by the gateway spend tags and the evlog
* wide events so both label a run the same way. `EVE_RUN_MODE` comes from the
* `eval` script and does not reach a deployment behind `eve eval --url`.
*/
export function environment(): string {
if (process.env.EVE_RUN_MODE === 'eval') return 'eval'
Expand Down
6 changes: 2 additions & 4 deletions apps/evi/agent/lib/gateway.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,8 @@ export const gatewayRouting = {
} as const

/**
* Tags stamped on every gateway request, read back through the spend report.
*
* One tag per dimension, not one compound string: the report groups by a single
* dimension at a time, so this yields a row per environment and a row per surface.
* Tags stamped on every gateway request. One tag per dimension, not a compound
* string: the spend report groups by a single dimension at a time.
*/
export function sessionTags(kind?: string): string[] {
return [`evi:env:${environment()}`, `evi:surface:${channelName(kind)}`]
Expand Down
9 changes: 9 additions & 0 deletions apps/evi/docs/notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,15 @@ Because app-scoped is non-interactive, eve never emits a challenge:
anyone can approve, on every turn. User-scoped at least fails loudly with
`principal_required`.

**A misconfigured OAuth connection does not degrade, it breaks the whole run.**
On EVL-213, the Linear MCP connection took every GitHub tool down with it: five
calls, all `Cannot read properties of undefined (reading 'toLowerCase')`, thrown
from `isProvisionableConnectorUid` in
`@vercel/connect/dist/eve/provision-oauth-connector.js`. Local evals never saw it
because `provisionEveOAuthConnector` returns early without an OIDC token; in
production it runs. The connection is removed until Connect can mint the token —
assuming the agent simply answers without that connection is wrong.

**`vercel connect token` from the CLI proves nothing about app-scoped auth** — it
resolves through your own Vercel identity, the user-scoped path.

Expand Down
Loading