Skip to content

feat: implement Nova automation features and enhance API integrations: - #326

Merged
yashdev9274 merged 2 commits into
mainfrom
supercode-cli
Oct 13, 2026
Merged

yashdev9274 merged 2 commits into
mainfrom
supercode-cli

Conversation

@yashdev9274

@yashdev9274 yashdev9274 commented Oct 13, 2026 •

Copy link
Copy Markdown
Owner

Description

  • Introduced new API routes for managing automations, including creation, listing, updating, and deletion.
  • Added support for webhook triggers and automation event processing, allowing for dynamic responses to external events.
  • Implemented automation context retrieval and user authorization checks to ensure secure access to automation functionalities.
  • Enhanced automation input validation and error handling for improved reliability and user experience.
  • Created utility functions for managing automation templates and triggers, streamlining the automation setup process.
  • Integrated automation event normalization for Slack, GitHub, and Linear, enabling seamless interaction with external services.

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Refactor (no functional changes)

How Has This Been Tested?

Please describe the tests that you ran to verify your changes.

  • bun test passes
  • bun run typecheck passes
  • bun run lint passes (if applicable)

Checklist:

  • My code follows the project's style guidelines
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works

Summary by CodeRabbit

  • New Features
    • Added automation management for creating, editing, testing, pausing, resuming, and deleting automations, with run history and ready-to-use templates.
    • Automations can respond to Slack, GitHub, and Linear events, run on a schedule, or be triggered by a webhook.
    • Added automatic chat, planning, and agent mode selection, plus native GitHub tools for browsing pull requests.
    • Expanded tool access so agent mode can use write-capable tools while chat mode remains read-only.
  • Bug Fixes
    • Improved recognition of read and write tools, and updated integration event handling to process automation events.

- Introduced new API routes for managing automations, including creation, listing, updating, and deletion.
- Added support for webhook triggers and automation event processing, allowing for dynamic responses to external events.
- Implemented automation context retrieval and user authorization checks to ensure secure access to automation functionalities.
- Enhanced automation input validation and error handling for improved reliability and user experience.
- Created utility functions for managing automation templates and triggers, streamlining the automation setup process.
- Integrated automation event normalization for Slack, GitHub, and Linear, enabling seamless interaction with external services.
@vercel

vercel Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated
supercli Ready Ready Preview Oct 13, 2026 5:51am UTC
supercli-client Ready Ready Preview Oct 13, 2026 5:51am UTC
supercli-docs Ready Ready Preview Oct 13, 2026 5:51am UTC
vercel-supercodeai-integration Ready Ready Preview Oct 13, 2026 5:51am UTC

@coderabbitai

coderabbitai Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 003de44c-bde3-42b2-8821-37ead1afaa3a
📥 Commits

Reviewing files that changed from the base of the PR and between 46fbec0 and a961288.

📒 Files selected for processing (35)
  • apps/supercode-cli/server/src/lib/composio.ts
  • apps/web/app/(nova-app)/nova-app-internal/automations/[[...segments]]/page.tsx
  • apps/web/app/api/inngest/route.ts
  • apps/web/app/api/nova/automations/[id]/credential/route.ts
  • apps/web/app/api/nova/automations/[id]/route.ts
  • apps/web/app/api/nova/automations/[id]/test/route.ts
  • apps/web/app/api/nova/automations/[id]/webhook/route.ts
  • apps/web/app/api/nova/automations/route.ts
  • apps/web/app/api/nova/webhooks/github/route.ts
  • apps/web/app/api/nova/webhooks/linear/route.ts
  • apps/web/app/api/nova/webhooks/slack/route.ts
  • apps/web/inngest/functions/automations.ts
  • apps/web/modules/nova-web/components/automations.tsx
  • apps/web/modules/nova-web/components/sidebar.tsx
  • apps/web/modules/nova-web/nova-app.tsx
  • apps/web/modules/nova-web/resolve-mode.test.ts
  • apps/web/modules/nova-web/resolve-mode.ts
  • apps/web/modules/nova-web/types.ts
  • apps/web/modules/nova/automations/contracts.ts
  • apps/web/modules/nova/automations/http.ts
  • apps/web/modules/nova/automations/providers.ts
  • apps/web/modules/nova/automations/runner.ts
  • apps/web/modules/nova/automations/security.ts
  • apps/web/modules/nova/automations/service.ts
  • apps/web/modules/nova/automations/templates.ts
  • apps/web/modules/nova/harness/agent.test.ts
  • apps/web/modules/nova/harness/agent.ts
  • apps/web/modules/nova/harness/auth.ts
  • apps/web/modules/nova/harness/native-github-tools.ts
  • apps/web/modules/nova/harness/tool-policy.test.ts
  • apps/web/modules/nova/harness/tool-policy.ts
  • apps/web/modules/nova/sessions/turn.ts
  • packages/db/index.ts
  • packages/db/prisma/migrations/20261013051000_nova_automations/migration.sql
  • packages/db/prisma/schema.prisma
 _________________________________________________________________________
< Performing code review exorcisms to the eerie strains of Tubular Bells. >
 -------------------------------------------------------------------------
  \
   \   (\__/)
       (•ㅅ•)
       /   づ
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Comment thread apps/web/modules/nova/automations/runner.ts Outdated
- Changed the import of Prisma to explicitly include the type keyword for better type inference.
- Updated related files in the automation module and database index to maintain consistency in type usage.
@greptile-apps

greptile-apps Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 0/5 Tier: plus

[Critical impact] Adds automation execution engine with database schema and webhook ingestion.

This PR needs fixes before merging because automation model calls fail, provider setup checks the wrong connection, and unattended runs retain write access.

Findings

  1. P1 Criteria checks always fail ▶
  2. P1 Default runs cannot execute ▶
  3. P1 Security Automations can change connected apps ▶
  4. P1 Setup misses required connections ▶
  5. P2 Connected tools disappear ▶
  6. P2 Dispatch skips saved automations ▶
  7. P2 Older runs evade daily limits ▶
  8. P2 Waiting approvals lose their entry ▶
  9. P2 Follow-ups lose the trigger ▶
  10. P2 Automatic mode leaves files unapplied ▶

Summary

Adds Nova automations with saved triggers, provider webhooks, weekly schedules, run limits, criteria checks, and linked result threads. It also adds native GitHub reads and changes connected-tool permissions and automatic turn-mode selection.

  • Nova automations can be set up, managed, and followed in one place.
  • Automation events become tracked Nova runs and threads.
  • Nova picks a chat mode and connected tools for each turn.
  • Composio classifies more tool names as reads or writes.

Source review only; tests and browser checks were not run.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  P[Verified provider webhook] --> Q[Match active automations]
  W[Bearer webhook or manual test] --> R[Save delivery and input snapshot]
  S[Weekly schedule] --> R
  Q --> R
  R --> I[Inngest worker]
  I --> B[Reserve daily budget]
  B --> C[Check optional criteria]
  C --> T[Create Nova thread]
  T --> A[Run harness agent]
  A --> X[Connected-app tools]
  A --> O[Save response and complete run]
  O --> H[Open result thread]
Loading

Reviews (1) · Last reviewed commit: "feat: implement Nova automation features..." · Reviewed by Greptile

const { token } = await ensureHarnessToken({ ...member.user, background: true })
let text = ""
let finished = false
for await (const part of streamHarnessChat({ token, model: "gemini-2.5-flash", provider: "supercode", signal: AbortSignal.timeout(45_000), messages: [

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Criteria checks always fail

classifyAutomationRun requests gemini-2.5-flash through supercode, but that provider rejects models outside CLOUD_ALLOWED_MODELS, which excludes this model. Every automation with nonempty onlyRunWhen, including every enabled template, fails before checking the event. Changing the execution model does not help because this request is fixed. Use an allowed cloud model here.

Suggested change
for await (const part of streamHarnessChat({ token, model: "gemini-2.5-flash", provider: "supercode", signal: AbortSignal.timeout(45_000), messages: [
for await (const part of streamHarnessChat({ token, model: "deepseek-v4-flash", provider: "supercode", signal: AbortSignal.timeout(45_000), messages: [

instructions: template?.instructions ?? "",
onlyRunWhen: template?.onlyRunWhen ?? "",
triggers: [defaultTrigger(template?.type ?? "slack.message")],
model: "x-ai/grok-4-5", provider: "concentrateai", effort: "medium",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Default runs cannot execute

templateDraft defaults every new automation to concentrateai and x-ai/grok-4-5, but streamHarnessChat never sends concentrateAiKey. Without that key, the server restricts this provider to CLOUD_ALLOWED_MODELS, which excludes this model. Even with empty criteria, a new automation fails at execution unless the user changes its model. Default to a model the web request can call.

Suggested change
model: "x-ai/grok-4-5", provider: "concentrateai", effort: "medium",
model: "deepseek-v4-flash", provider: "supercode", effort: "medium",

const { token } = await ensureHarnessToken({ ...member.user, background: true })
let body = ""
let finished = false
for await (const part of streamHarnessAgent({ token, model: input.model, provider: input.provider, signal: AbortSignal.timeout(240_000), messages: [

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 security Automations can change connected apps

executeAutomationRun omits mode, so streamHarnessAgent defaults to agent, offers write tools, and appends instructions allowing mutations. This contradicts the page’s read-only promise and externalPosting: false. With a callable model and empty criteria, third-party event text reaches a write-enabled agent running as the selected account. Pass a read-only mode and enforce it when tools execute.

How this was verified: Automation event text reaches streamHarnessAgent without a mode, and its default policy allows connected write calls through to executeTool.

Suggested change
for await (const part of streamHarnessAgent({ token, model: input.model, provider: input.provider, signal: AbortSignal.timeout(240_000), messages: [
for await (const part of streamHarnessAgent({ token, model: input.model, provider: input.provider, mode: "chat", signal: AbortSignal.timeout(240_000), messages: [

Comment on lines +140 to +142
const missingApps = appsLoaded && !appsError
? requiredProviders.filter((provider) => !apps.some((app) => app.slug === provider.toLowerCase() && app.connected))
: []

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Setup misses required connections

The banner checks only Composio accounts and tells users to connect providers through Composio. Provider triggers require an active externalInstallation, which that connection flow never creates. A user can follow the instructions, clear the banner, and save an automation whose provider events are still ignored. Check context.connections for trigger readiness and guide users through native connector setup separately from tool access.

Comment on lines +80 to +87
const ranked = preferTools(catalog.tools, mode).slice(0, MAX_TOOLS_TO_MODEL)
const composioTools: HarnessChatTool[] = ranked.map((tool) => ({
type: "function",
function: { name: tool.name, description: tool.description, parameters: tool.parameters },
}))
const toolkits = [...new Set(readTools.map((tool) => tool.toolkit))]
const extraTools = input.extraTools ?? []
const tools: HarnessChatTool[] = [...extraTools, ...composioTools]
const toolkits = [...new Set(ranked.map((tool) => tool.toolkit).filter(Boolean))]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Connected tools disappear

The first 64 tools are chosen by provider order, not the user’s request. If connected apps supply more than 64 allowed tools, later tools disappear with no way for the model to discover them. toolkits also comes from the shortened list, so the prompt can describe a connected app as unavailable. Keep the cap, but select tools for the request or let the model discover omitted tools.

export async function reconcileAutomations(now = new Date()): Promise<{ queued: number; scheduled: number }> {
const pending = await prisma.novaAutomationRun.findMany({ where: { status: "queued", automation: { status: "active" } }, select: { id: true, automationId: true }, orderBy: { createdAt: "asc" }, take: 100 })
for (const run of pending) await inngest.send({ name: "nova/automation.run", data: { automationId: run.automationId, runId: run.id } })
const rows = await prisma.novaAutomation.findMany({ where: { status: "active" }, select: { id: true, organizationId: true, triggers: true }, take: 1000 })

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Dispatch skips saved automations

reconcileAutomations reads at most 1,000 active automations without paging. If there are 1,001, at least one is not checked during its scheduled minute and can miss its weekly run. Provider dispatch has the same problem at 200 automations per organization. Page through the candidates instead of silently dropping rows.

Comment on lines +79 to +80
const dayStart = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()))
const count = await tx.novaAutomationRun.count({ where: { automationId: row.automationId, createdAt: { gte: dayStart }, status: { in: ["classifying", "running", "completed", "failed", "filtered"] } } })

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Older runs evade daily limits

The daily budget counts createdAt, not when a run reserves its budget. Runs queued before midnight but claimed afterward consume today’s model calls without appearing in today’s count. With cooldownMinutes: 0, yesterday’s backlog can exceed maxRunsPerDay. Record and count the reservation time instead.

Comment on lines 111 to 116
<NavItem
active={view === "approvals"}
icon={<ShieldCheck className="size-3.5" strokeWidth={1.75} />}
label="Approvals"
badge={pendingApprovals > 0 ? pendingApprovals : undefined}
onClick={() => onNavigate("/approvals")}
active={view === "automations"}
icon={<Zap className="size-3.5" strokeWidth={1.75} />}
label="Automations"
onClick={() => onNavigate("/automations")}
/>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Waiting approvals lose their entry

Adding Automations removes the only navigation link and pending-count badge for Approvals. The page still exists, but users must know its URL or find each affected thread individually. Keep the Approvals entry, or move its link and count somewhere visible, so users can find jobs waiting for a decision.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

const input = automationInputSchema.parse(row.snapshot)
const session = await tx.agentSession.create({ data: { organizationId: row.automation.organizationId, initiatorMembershipId: input.runAsMembershipId, objective: input.name, mode: "agent", nextSequence: 2, policySnapshot: { automationId: row.automationId, externalPosting: false } } })
await tx.sessionSurface.create({ data: { agentSessionId: session.id, provider: "web", surfaceKey: `${row.automation.organizationId}:web:${session.id}`, externalSurfaceId: session.id } })
await tx.agentSessionMessage.create({ data: { agentSessionId: session.id, sequence: 1, role: "user", content: input.instructions, senderType: "automation", senderId: row.automationId, metadata: { automationRunId: row.id, event: row.event } } })

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Follow-ups lose the trigger

createAutomationSession saves the trigger event only in message metadata. Follow-up turns use buildTurnContext, which reads message content and prior responses but not metadata. The model loses the original event when a user continues the thread. Include it in the conversation context so follow-up questions can refer to the original details.

Comment on lines +605 to +607
const turnMode = resolved.mode
if (resolved.auto && turnMode !== agentMode) {
setAgentMode(turnMode)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Automatic mode leaves files unapplied

Auto-selection changes the mode sent to the server, but the file-apply branch still checks opts?.mode ?? agentMode. Those values belong to the old render; setAgentMode does not update this running callback. After a chat turn, a request that switches to agent can produce file proposals without applying them even when write permission is already granted. Use the resolved turnMode for that branch too.

This branch was successfully deployed

4 active deployments
Preview – supercli — a9612883 Deployed Oct 13, 2026 by vercel[bot]
Preview – vercel-supercodeai-integration — a9612883 Deployed Oct 13, 2026 by vercel[bot]
Preview – supercli-client — a9612883 Deployed Oct 13, 2026 by vercel[bot]
Preview – supercli-docs — a9612883 Deployed Oct 13, 2026 by vercel[bot]
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.

1 participant