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
15 changes: 14 additions & 1 deletion components/workflow/config/action-config.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ import {
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip";
// start keeperhub
import { integrationRequiresCredentials } from "@/keeperhub/lib/integration-helpers";
// end keeperhub
import { aiGatewayStatusAtom } from "@/lib/ai-gateway/state";
import {
integrationsAtom,
Expand Down Expand Up @@ -393,6 +396,14 @@ export function ActionConfig({
return action?.integration as IntegrationType | undefined;
}, [actionType]);

// start keeperhub
// Check if integration requires credentials (some like web3 don't)
const requiresCredentials = useMemo(
() => integrationRequiresCredentials(integrationType),
[integrationType]
);
// end keeperhub

// Check if AI Gateway managed keys should be offered (user can have multiple for different teams)
const shouldUseManagedKeys =
integrationType === "ai-gateway" &&
Expand Down Expand Up @@ -496,7 +507,8 @@ export function ActionConfig({
</div>
</div>

{integrationType && isOwner && (
{/* start keeperhub - added requiresCredentials check (upstream: integrationType && isOwner) */}
{integrationType && isOwner && requiresCredentials && (
<div className="space-y-2">
<div className="ml-1 flex items-center justify-between">
<div className="flex items-center gap-1">
Expand Down Expand Up @@ -532,6 +544,7 @@ export function ActionConfig({
/>
</div>
)}
{/* end keeperhub */}

{/* System actions - hardcoded config fields */}
<SystemActionFields
Expand Down
56 changes: 1 addition & 55 deletions components/workflow/node-config-panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,7 @@ import {
updateNodeDataAtom,
} from "@/lib/workflow-store";

import { findActionById, getIntegration } from "@/plugins";
import { IntegrationSelector } from "../ui/integration-selector";
import { findActionById } from "@/plugins";

import { Tabs, TabsContent, TabsList, TabsTrigger } from "../ui/tabs";
import { ActionConfig } from "./config/action-config";
Expand Down Expand Up @@ -916,59 +915,6 @@ export const PanelInner = () => {
Delete
</Button>
</div>

{/* KeeperHub: Integration selector in footer */}
{selectedNode.data.type === "action" &&
(() => {
const actionType = selectedNode.data.config
?.actionType as string;

const SYSTEM_INTEGRATION_MAP: Record<string, string> = {
"Database Query": "database",
};

let integrationType: string | undefined;
let requiresCredentials = true;

if (actionType) {
if (SYSTEM_INTEGRATION_MAP[actionType]) {
integrationType = SYSTEM_INTEGRATION_MAP[actionType];
} else {
const action = findActionById(actionType);
if (action) {
integrationType = action.integration;
const plugin = getIntegration(action.integration);
requiresCredentials =
plugin?.requiresCredentials !== false;
}
}
}

if (integrationType && requiresCredentials) {
return (
<IntegrationSelector
integrationType={integrationType as IntegrationType}
onChange={(id) =>
handleUpdateConfig("integrationId", id)
}
value={
(selectedNode.data.config
?.integrationId as string) || ""
}
/>
);
}
if (integrationType && !requiresCredentials) {
return (
<div className="flex items-center gap-2 rounded-md bg-muted px-3 py-2">
<span className="text-muted-foreground text-sm">
No integration required
</span>
</div>
);
}
return null;
})()}
</div>
)}
</div>
Expand Down
22 changes: 22 additions & 0 deletions keeperhub/lib/integration-helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* KeeperHub integration helpers
* These helpers extend upstream functionality for KeeperHub-specific features
*/

import type { IntegrationType } from "@/lib/types/integration";
import { getIntegration } from "@/plugins";

/**
* Check if an integration type requires credentials
* Some integrations (like web3) don't require user credentials
*/
export function integrationRequiresCredentials(
integrationType: IntegrationType | string | undefined
): boolean {
if (!integrationType) {
return false;
}

const plugin = getIntegration(integrationType as IntegrationType);
return plugin?.requiresCredentials !== false;
}
4 changes: 3 additions & 1 deletion keeperhub/plugins/discord/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@ const discordPlugin: IntegrationPlugin = {
icon: DiscordIcon,

// Webhook URL is stored in the integration for centralized management
// start keeperhub - type is 'password' so it shows "Configured" state when editing (upstream: 'url')
formFields: [
{
id: "webhookUrl",
label: "Webhook URL",
type: "url",
type: "password",
placeholder: "https://discord.com/api/webhooks/...",
configKey: "webhookUrl",
envVar: "webhookUrl",
Expand All @@ -26,6 +27,7 @@ const discordPlugin: IntegrationPlugin = {
},
},
],
// end keeperhub

actions: [
{
Expand Down