@kalphq/cli 0.0.0-dev-20260416063606 → 0.0.0-dev-20260416084549
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/acorn-I3UGQPDC.js +3132 -0
- package/dist/acorn-I3UGQPDC.js.map +1 -0
- package/dist/angular-5QCYWYQS.js +3032 -0
- package/dist/angular-5QCYWYQS.js.map +1 -0
- package/dist/babel-VVMWCS4G.js +7298 -0
- package/dist/babel-VVMWCS4G.js.map +1 -0
- package/dist/chunk-2H7UOFLK.js +11 -0
- package/dist/chunk-2H7UOFLK.js.map +1 -0
- package/dist/chunk-GFEVTHUW.js +19843 -0
- package/dist/chunk-GFEVTHUW.js.map +1 -0
- package/dist/chunk-LAKPXKSS.js +37 -0
- package/dist/chunk-LAKPXKSS.js.map +1 -0
- package/dist/create-T76IFYRP.js +72 -0
- package/dist/create-T76IFYRP.js.map +1 -0
- package/dist/estree-3QNQSWX3.js +4614 -0
- package/dist/estree-3QNQSWX3.js.map +1 -0
- package/dist/flow-CCY52CGJ.js +27548 -0
- package/dist/flow-CCY52CGJ.js.map +1 -0
- package/dist/glimmer-WEH5BTZ2.js +2896 -0
- package/dist/glimmer-WEH5BTZ2.js.map +1 -0
- package/dist/graphql-UERTLN2S.js +1268 -0
- package/dist/graphql-UERTLN2S.js.map +1 -0
- package/dist/html-2G7A573F.js +2928 -0
- package/dist/html-2G7A573F.js.map +1 -0
- package/dist/index.js +56 -3
- package/dist/index.js.map +1 -1
- package/dist/{init-FLJXMJQZ.js → init-SDITDMG6.js} +24 -36
- package/dist/init-SDITDMG6.js.map +1 -0
- package/dist/link-YKDZ7Y6K.js +23 -0
- package/dist/link-YKDZ7Y6K.js.map +1 -0
- package/dist/login-LBEXP7ET.js +27 -0
- package/dist/login-LBEXP7ET.js.map +1 -0
- package/dist/logout-S3PV4WE7.js +27 -0
- package/dist/logout-S3PV4WE7.js.map +1 -0
- package/dist/markdown-XILCBMG4.js +3553 -0
- package/dist/markdown-XILCBMG4.js.map +1 -0
- package/dist/meriyah-THC5AUEQ.js +2686 -0
- package/dist/meriyah-THC5AUEQ.js.map +1 -0
- package/dist/postcss-WBGWHY5F.js +5082 -0
- package/dist/postcss-WBGWHY5F.js.map +1 -0
- package/dist/push-YFAB7TWQ.js +104 -0
- package/dist/push-YFAB7TWQ.js.map +1 -0
- package/dist/typescript-NS3CY6IL.js +13205 -0
- package/dist/typescript-NS3CY6IL.js.map +1 -0
- package/dist/yaml-2RE4A77K.js +4226 -0
- package/dist/yaml-2RE4A77K.js.map +1 -0
- package/package.json +2 -2
- package/templates/agents/b2b-sales/index.ts +32 -3
- package/templates/agents/b2b-sales/signals/deal-won.ts +31 -0
- package/templates/agents/b2b-sales/signals/hot-lead-alert.ts +29 -0
- package/templates/agents/b2b-sales/steps/qualify-prospect.ts +50 -0
- package/templates/agents/b2b-sales/tools/send-slack-notification.ts +26 -0
- package/templates/agents/b2b-sales/webhooks/crm-inbound.ts +27 -0
- package/templates/agents/b2b-sales/webhooks/stripe-payment.ts +27 -0
- package/templates/agents/customer-support/index.ts +37 -5
- package/templates/agents/customer-support/signals/escalation-needed.ts +28 -0
- package/templates/agents/customer-support/signals/ticket-resolved.ts +29 -0
- package/templates/agents/customer-support/steps/escalate-ticket.ts +53 -0
- package/templates/agents/customer-support/tools/create-jira-issue.ts +30 -0
- package/templates/agents/customer-support/webhooks/slack-escalation.ts +27 -0
- package/templates/agents/customer-support/webhooks/zendesk-ticket.ts +29 -0
- package/templates/agents/financial-agent/index.ts +24 -2
- package/templates/agents/financial-agent/signals/market-alert.ts +31 -0
- package/templates/agents/financial-agent/signals/portfolio-rebalance.ts +27 -0
- package/templates/agents/financial-agent/steps/rebalance-check.ts +55 -0
- package/templates/agents/financial-agent/tools/send-email-alert.ts +31 -0
- package/templates/agents/financial-agent/webhooks/exchange-webhook.ts +33 -0
- package/templates/agents/financial-agent/webhooks/tradingview-alert.ts +30 -0
- package/templates/agents/minimal/index.ts +10 -2
- package/templates/agents/minimal/signals/error-alert.ts +26 -0
- package/templates/agents/minimal/signals/task-complete.ts +25 -0
- package/templates/agents/minimal/steps/transform-data.ts +32 -0
- package/templates/agents/minimal/tools/http-request.ts +26 -0
- package/templates/agents/minimal/webhooks/generic-inbound.ts +25 -0
- package/templates/agents/minimal/webhooks/health-check.ts +23 -0
- package/dist/build-2V4OQ3G3.js +0 -122
- package/dist/build-2V4OQ3G3.js.map +0 -1
- package/dist/chunk-FBVCQTQN.js +0 -108
- package/dist/chunk-FBVCQTQN.js.map +0 -1
- package/dist/create-AMCRXGOA.js +0 -116
- package/dist/create-AMCRXGOA.js.map +0 -1
- package/dist/init-FLJXMJQZ.js.map +0 -1
- package/templates/agents/b2b-sales/signals/.gitkeep +0 -0
- package/templates/agents/b2b-sales/webhooks/.gitkeep +0 -0
- package/templates/agents/customer-support/signals/.gitkeep +0 -0
- package/templates/agents/customer-support/webhooks/.gitkeep +0 -0
- package/templates/agents/financial-agent/signals/.gitkeep +0 -0
- package/templates/agents/financial-agent/webhooks/.gitkeep +0 -0
- package/templates/agents/minimal/signals/.gitkeep +0 -0
- package/templates/agents/minimal/webhooks/.gitkeep +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kalphq/cli",
|
|
3
|
-
"version": "0.0.0-dev-
|
|
3
|
+
"version": "0.0.0-dev-20260416084549",
|
|
4
4
|
"description": "Zero-config CLI for deploying Kalp agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"nypm": "^0.3.12",
|
|
25
25
|
"picocolors": "^1.1.1",
|
|
26
26
|
"zod": "^3.25.76",
|
|
27
|
-
"@kalphq/sdk": "0.0.0-dev-
|
|
27
|
+
"@kalphq/sdk": "0.0.0-dev-20260416084549"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@types/node": "^22.15.3",
|
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
import { asAgentId, defineAgent } from "@kalphq/sdk";
|
|
2
2
|
import { scoreLead } from "./steps/score-lead.js";
|
|
3
|
+
import { qualifyProspect } from "./steps/qualify-prospect.js";
|
|
3
4
|
import { enrichCompany } from "./tools/enrich-company.js";
|
|
5
|
+
import { sendSlackNotification } from "./tools/send-slack-notification.js";
|
|
6
|
+
import { crmInbound } from "./webhooks/crm-inbound.js";
|
|
7
|
+
import { stripePayment } from "./webhooks/stripe-payment.js";
|
|
8
|
+
import { hotLeadAlert } from "./signals/hot-lead-alert.js";
|
|
9
|
+
import { dealWon } from "./signals/deal-won.js";
|
|
4
10
|
|
|
5
11
|
export default defineAgent({
|
|
6
12
|
id: asAgentId("__AGENT_NAME__"),
|
|
7
13
|
name: "__AGENT_NAME__",
|
|
8
14
|
description: "Automates B2B outreach with lead scoring and CRM enrichment.",
|
|
9
|
-
steps: [scoreLead],
|
|
10
|
-
tools: [enrichCompany],
|
|
15
|
+
steps: [scoreLead, qualifyProspect],
|
|
16
|
+
tools: [enrichCompany, sendSlackNotification],
|
|
17
|
+
webhooks: [crmInbound, stripePayment],
|
|
18
|
+
signals: [hotLeadAlert, dealWon],
|
|
11
19
|
|
|
12
20
|
systemPrompt:
|
|
13
21
|
"You are a B2B sales assistant. Score leads, enrich company data, and draft personalized outreach messages.",
|
|
@@ -19,10 +27,31 @@ export default defineAgent({
|
|
|
19
27
|
return { text: "Lead score too low — skipping outreach." };
|
|
20
28
|
}
|
|
21
29
|
|
|
30
|
+
// Qualify the prospect
|
|
31
|
+
const qualified = await ctx.runStep(qualifyProspect, {
|
|
32
|
+
company: message.text,
|
|
33
|
+
score: lead.score,
|
|
34
|
+
domain: lead.domain,
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
if (!qualified.qualified) {
|
|
38
|
+
return { text: `Prospect not qualified: ${qualified.reason}` };
|
|
39
|
+
}
|
|
40
|
+
|
|
22
41
|
const enriched = await ctx.callTool(enrichCompany, { domain: lead.domain });
|
|
23
42
|
|
|
43
|
+
// Notify for high-priority leads
|
|
44
|
+
if (qualified.priority === "high") {
|
|
45
|
+
await ctx.callTool(sendSlackNotification, {
|
|
46
|
+
company: message.text,
|
|
47
|
+
score: lead.score,
|
|
48
|
+
domain: lead.domain,
|
|
49
|
+
channel: "sales-alerts",
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
24
53
|
return {
|
|
25
|
-
text: `${enriched.companyName} (${lead.score}/100) — Ready for outreach.`,
|
|
54
|
+
text: `${enriched.companyName} (${lead.score}/100, ${qualified.priority} priority) — Ready for outreach.`,
|
|
26
55
|
};
|
|
27
56
|
},
|
|
28
57
|
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { createSignal } from "@kalphq/sdk";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Signal sent when a deal is won for commission tracking
|
|
6
|
+
*/
|
|
7
|
+
export const dealWon = createSignal({
|
|
8
|
+
id: "deal_won",
|
|
9
|
+
input: z.object({
|
|
10
|
+
customerId: z.string(),
|
|
11
|
+
leadId: z.string().optional(),
|
|
12
|
+
amount: z.number().optional(),
|
|
13
|
+
currency: z.string(),
|
|
14
|
+
source: z.string(),
|
|
15
|
+
repId: z.string().optional(),
|
|
16
|
+
}),
|
|
17
|
+
async handler({ customerId, leadId, amount, currency, source, repId }) {
|
|
18
|
+
// Signal received - in real implementation this would:
|
|
19
|
+
// - Update CRM with deal status
|
|
20
|
+
// - Notify sales manager
|
|
21
|
+
// - Track commission for rep
|
|
22
|
+
return {
|
|
23
|
+
recorded: true,
|
|
24
|
+
dealId: leadId ?? customerId,
|
|
25
|
+
amount,
|
|
26
|
+
currency,
|
|
27
|
+
source,
|
|
28
|
+
commissionRep: repId,
|
|
29
|
+
};
|
|
30
|
+
},
|
|
31
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { createSignal } from "@kalphq/sdk";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Signal broadcast when a hot lead is identified
|
|
6
|
+
*/
|
|
7
|
+
export const hotLeadAlert = createSignal({
|
|
8
|
+
id: "hot_lead_alert",
|
|
9
|
+
input: z.object({
|
|
10
|
+
leadId: z.string(),
|
|
11
|
+
company: z.string(),
|
|
12
|
+
score: z.number(),
|
|
13
|
+
email: z.string(),
|
|
14
|
+
priority: z.string(), // "high", "medium", "low"
|
|
15
|
+
qualified: z.boolean(),
|
|
16
|
+
}),
|
|
17
|
+
async handler({ leadId, company, score, email, priority, qualified }) {
|
|
18
|
+
// Signal received by other agents (SalesManager, NotificationAgent, etc.)
|
|
19
|
+
// In real implementation, this would trigger notifications
|
|
20
|
+
return {
|
|
21
|
+
acknowledged: true,
|
|
22
|
+
leadId,
|
|
23
|
+
company,
|
|
24
|
+
score,
|
|
25
|
+
priority,
|
|
26
|
+
qualified,
|
|
27
|
+
};
|
|
28
|
+
},
|
|
29
|
+
});
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { createStep } from "@kalphq/sdk";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
export const qualifyProspect = createStep({
|
|
5
|
+
id: "qualify_prospect",
|
|
6
|
+
description:
|
|
7
|
+
"Deep qualification of prospects based on lead score and company data.",
|
|
8
|
+
input: z.object({
|
|
9
|
+
company: z.string(),
|
|
10
|
+
score: z.number(),
|
|
11
|
+
domain: z.string(),
|
|
12
|
+
}),
|
|
13
|
+
output: z.object({
|
|
14
|
+
qualified: z.boolean(),
|
|
15
|
+
reason: z.string(),
|
|
16
|
+
priority: z.string(), // "high" | "medium" | "low"
|
|
17
|
+
}),
|
|
18
|
+
async run({ company, score, domain }, ctx) {
|
|
19
|
+
ctx.logger.info("Qualifying prospect", { company, score, domain });
|
|
20
|
+
|
|
21
|
+
// Auto-qualify high scores
|
|
22
|
+
if (score >= 80) {
|
|
23
|
+
return {
|
|
24
|
+
qualified: true,
|
|
25
|
+
reason: "High engagement score indicates strong interest",
|
|
26
|
+
priority: "high",
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Qualify medium scores with domain check
|
|
31
|
+
if (score >= 50) {
|
|
32
|
+
const isEnterprise =
|
|
33
|
+
domain.includes("enterprise") || domain.endsWith(".corp");
|
|
34
|
+
return {
|
|
35
|
+
qualified: isEnterprise,
|
|
36
|
+
reason: isEnterprise
|
|
37
|
+
? "Enterprise domain with decent engagement"
|
|
38
|
+
: "Score too low for non-enterprise domain",
|
|
39
|
+
priority: isEnterprise ? "medium" : "low",
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Low scores - not qualified
|
|
44
|
+
return {
|
|
45
|
+
qualified: false,
|
|
46
|
+
reason: "Low engagement score",
|
|
47
|
+
priority: "low",
|
|
48
|
+
};
|
|
49
|
+
},
|
|
50
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { createTool } from "@kalphq/sdk";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
export const sendSlackNotification = createTool({
|
|
5
|
+
id: "send_slack_notification",
|
|
6
|
+
description: "Sends a notification to Slack channel for hot leads.",
|
|
7
|
+
input: z.object({
|
|
8
|
+
company: z.string(),
|
|
9
|
+
score: z.number(),
|
|
10
|
+
domain: z.string(),
|
|
11
|
+
channel: z.string().default("#sales-hot-leads"),
|
|
12
|
+
}),
|
|
13
|
+
async execute({ company, score, domain, channel }, ctx) {
|
|
14
|
+
ctx.logger.info("Sending Slack notification", { company, score, channel });
|
|
15
|
+
|
|
16
|
+
// Replace with actual Slack API call using webhook or bot token
|
|
17
|
+
// Example: await fetch("https://hooks.slack.com/services/...", {...})
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
sent: true,
|
|
21
|
+
channel,
|
|
22
|
+
message: `🔥 Hot Lead Alert: ${company} (${domain}) scored ${score}/100`,
|
|
23
|
+
timestamp: new Date().toISOString(),
|
|
24
|
+
};
|
|
25
|
+
},
|
|
26
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { defineWebhook } from "@kalphq/sdk";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Inbound webhook to receive new lead events from CRM (HubSpot, Salesforce, etc.)
|
|
6
|
+
*/
|
|
7
|
+
export const crmInbound = defineWebhook({
|
|
8
|
+
id: "crm_inbound",
|
|
9
|
+
input: z.object({
|
|
10
|
+
leadId: z.string(),
|
|
11
|
+
email: z.string().email(),
|
|
12
|
+
company: z.string(),
|
|
13
|
+
source: z.string(),
|
|
14
|
+
metadata: z.record(z.unknown()).optional(),
|
|
15
|
+
}),
|
|
16
|
+
async handler({ leadId, email, company, source }) {
|
|
17
|
+
// Process new lead from CRM
|
|
18
|
+
// In real implementation, this would trigger agent processing
|
|
19
|
+
return {
|
|
20
|
+
success: true,
|
|
21
|
+
message: "Lead received",
|
|
22
|
+
leadId,
|
|
23
|
+
company,
|
|
24
|
+
source,
|
|
25
|
+
};
|
|
26
|
+
},
|
|
27
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { defineWebhook } from "@kalphq/sdk";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Stripe webhook for payment events - tracks trial conversions and payments
|
|
6
|
+
*/
|
|
7
|
+
export const stripePayment = defineWebhook({
|
|
8
|
+
id: "stripe_payment",
|
|
9
|
+
input: z.object({
|
|
10
|
+
type: z.string(), // "payment_intent.succeeded", "invoice.paid", etc.
|
|
11
|
+
customerId: z.string(),
|
|
12
|
+
amount: z.number().optional(),
|
|
13
|
+
currency: z.string().default("usd"),
|
|
14
|
+
metadata: z.record(z.unknown()).optional(),
|
|
15
|
+
}),
|
|
16
|
+
async handler({ type, customerId, amount, currency }) {
|
|
17
|
+
// Process Stripe payment event
|
|
18
|
+
// In real implementation, this would update CRM and notify agents
|
|
19
|
+
return {
|
|
20
|
+
received: true,
|
|
21
|
+
eventType: type,
|
|
22
|
+
customerId,
|
|
23
|
+
amount,
|
|
24
|
+
currency,
|
|
25
|
+
};
|
|
26
|
+
},
|
|
27
|
+
});
|
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
import { asAgentId, defineAgent } from "@kalphq/sdk";
|
|
2
2
|
import { classifyTicket } from "./steps/classify-ticket.js";
|
|
3
|
+
import { escalateTicket } from "./steps/escalate-ticket.js";
|
|
3
4
|
import { searchKnowledgeBase } from "./tools/search-kb.js";
|
|
5
|
+
import { createJiraIssue } from "./tools/create-jira-issue.js";
|
|
6
|
+
import { slackEscalation } from "./webhooks/slack-escalation.js";
|
|
7
|
+
import { zendeskTicket } from "./webhooks/zendesk-ticket.js";
|
|
8
|
+
import { escalationNeeded } from "./signals/escalation-needed.js";
|
|
9
|
+
import { ticketResolved } from "./signals/ticket-resolved.js";
|
|
4
10
|
|
|
5
11
|
export default defineAgent({
|
|
6
12
|
id: asAgentId("__AGENT_NAME__"),
|
|
7
13
|
name: "__AGENT_NAME__",
|
|
8
14
|
description: "Handles incoming support tickets with AI-powered routing.",
|
|
9
|
-
steps: [classifyTicket],
|
|
10
|
-
tools: [searchKnowledgeBase],
|
|
15
|
+
steps: [classifyTicket, escalateTicket],
|
|
16
|
+
tools: [searchKnowledgeBase, createJiraIssue],
|
|
17
|
+
webhooks: [slackEscalation, zendeskTicket],
|
|
18
|
+
signals: [escalationNeeded, ticketResolved],
|
|
11
19
|
|
|
12
20
|
systemPrompt:
|
|
13
21
|
"You are a friendly support agent. Classify tickets, search the knowledge base, and resolve issues efficiently.",
|
|
@@ -15,14 +23,38 @@ export default defineAgent({
|
|
|
15
23
|
async onMessage(message, ctx) {
|
|
16
24
|
const ticket = await ctx.runStep(classifyTicket, { text: message.text });
|
|
17
25
|
|
|
18
|
-
if
|
|
19
|
-
|
|
26
|
+
// Check if escalation is needed
|
|
27
|
+
const escalation = await ctx.runStep(escalateTicket, {
|
|
28
|
+
category: ticket.category,
|
|
29
|
+
priority: ticket.priority,
|
|
30
|
+
sentiment: "neutral", // Could be detected from message
|
|
31
|
+
previousAttempts: 0,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
if (escalation.escalate) {
|
|
35
|
+
// Create Jira issue for technical problems
|
|
36
|
+
if (ticket.category === "technical") {
|
|
37
|
+
const jira = await ctx.callTool(createJiraIssue, {
|
|
38
|
+
summary: `Support Ticket: ${message.text.slice(0, 50)}...`,
|
|
39
|
+
description: message.text,
|
|
40
|
+
priority: ticket.priority,
|
|
41
|
+
reporter: "support-agent",
|
|
42
|
+
});
|
|
43
|
+
return {
|
|
44
|
+
text: `Escalated to engineering team. Issue: ${jira.issueKey}`,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
text: `Escalating to ${escalation.assignTo}: ${escalation.reason}`,
|
|
50
|
+
};
|
|
20
51
|
}
|
|
21
52
|
|
|
53
|
+
// Try knowledge base for non-escalated issues
|
|
22
54
|
const results = await ctx.callTool(searchKnowledgeBase, {
|
|
23
55
|
query: message.text,
|
|
24
56
|
});
|
|
25
57
|
|
|
26
|
-
return { text: results.answer ?? "Let me
|
|
58
|
+
return { text: results.answer ?? "Let me connect you with a specialist." };
|
|
27
59
|
},
|
|
28
60
|
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { createSignal } from "@kalphq/sdk";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Signal to alert senior support agents about escalation
|
|
6
|
+
*/
|
|
7
|
+
export const escalationNeeded = createSignal({
|
|
8
|
+
id: "escalation_needed",
|
|
9
|
+
input: z.object({
|
|
10
|
+
ticketId: z.string(),
|
|
11
|
+
customerId: z.string(),
|
|
12
|
+
issue: z.string(),
|
|
13
|
+
priority: z.string(),
|
|
14
|
+
previousAttempts: z.number(),
|
|
15
|
+
sentiment: z.string(),
|
|
16
|
+
}),
|
|
17
|
+
async handler({ ticketId, customerId, issue, priority, previousAttempts, sentiment }) {
|
|
18
|
+
// Signal received by senior support agents
|
|
19
|
+
// In real implementation, this triggers notifications
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
received: true,
|
|
23
|
+
ticketId,
|
|
24
|
+
assignedTier: priority === "high" ? "tier3" : "tier2",
|
|
25
|
+
estimatedHandleTime: priority === "high" ? "15 min" : "1 hour",
|
|
26
|
+
};
|
|
27
|
+
},
|
|
28
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { createSignal } from "@kalphq/sdk";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Signal broadcast when a ticket is resolved
|
|
6
|
+
*/
|
|
7
|
+
export const ticketResolved = createSignal({
|
|
8
|
+
id: "ticket_resolved",
|
|
9
|
+
input: z.object({
|
|
10
|
+
ticketId: z.string(),
|
|
11
|
+
customerId: z.string(),
|
|
12
|
+
resolution: z.string(),
|
|
13
|
+
satisfaction: z.string(), // "positive", "neutral", "negative"
|
|
14
|
+
resolutionTime: z.number(), // minutes
|
|
15
|
+
}),
|
|
16
|
+
async handler({ ticketId, customerId, resolution, satisfaction, resolutionTime }) {
|
|
17
|
+
// Broadcast resolution for analytics and notifications
|
|
18
|
+
// In real implementation, update dashboards and notify customer
|
|
19
|
+
|
|
20
|
+
return {
|
|
21
|
+
recorded: true,
|
|
22
|
+
ticketId,
|
|
23
|
+
customerId,
|
|
24
|
+
satisfaction,
|
|
25
|
+
resolutionTime,
|
|
26
|
+
timestamp: new Date().toISOString(),
|
|
27
|
+
};
|
|
28
|
+
},
|
|
29
|
+
});
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { createStep } from "@kalphq/sdk";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
export const escalateTicket = createStep({
|
|
5
|
+
id: "escalate_ticket",
|
|
6
|
+
description: "Determines if a ticket should be escalated to human support.",
|
|
7
|
+
input: z.object({
|
|
8
|
+
category: z.string(), // "billing", "technical", "general"
|
|
9
|
+
priority: z.string(), // "low", "medium", "high"
|
|
10
|
+
sentiment: z.string(), // "frustrated", "angry", "neutral", "satisfied"
|
|
11
|
+
previousAttempts: z.number().default(0),
|
|
12
|
+
}),
|
|
13
|
+
output: z.object({
|
|
14
|
+
escalate: z.boolean(),
|
|
15
|
+
reason: z.string(),
|
|
16
|
+
assignTo: z.string(), // "tier1", "tier2", "tier3", "human"
|
|
17
|
+
}),
|
|
18
|
+
async run({ category, priority, sentiment, previousAttempts }) {
|
|
19
|
+
// Auto-escalate frustrated/angry customers with technical issues
|
|
20
|
+
if ((sentiment === "frustrated" || sentiment === "angry") && category === "technical") {
|
|
21
|
+
return {
|
|
22
|
+
escalate: true,
|
|
23
|
+
reason: "Frustrated customer with technical issue",
|
|
24
|
+
assignTo: "tier2",
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Escalate high priority billing issues immediately
|
|
29
|
+
if (priority === "high" && category === "billing") {
|
|
30
|
+
return {
|
|
31
|
+
escalate: true,
|
|
32
|
+
reason: "High priority billing issue",
|
|
33
|
+
assignTo: "tier3",
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Escalate after multiple failed attempts
|
|
38
|
+
if (previousAttempts >= 3) {
|
|
39
|
+
return {
|
|
40
|
+
escalate: true,
|
|
41
|
+
reason: `Multiple failed resolution attempts (${previousAttempts})`,
|
|
42
|
+
assignTo: "human",
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// No escalation needed
|
|
47
|
+
return {
|
|
48
|
+
escalate: false,
|
|
49
|
+
reason: "Within agent capabilities",
|
|
50
|
+
assignTo: "tier1",
|
|
51
|
+
};
|
|
52
|
+
},
|
|
53
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { createTool } from "@kalphq/sdk";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
export const createJiraIssue = createTool({
|
|
5
|
+
id: "create_jira_issue",
|
|
6
|
+
description: "Creates a bug ticket in Jira for technical issues requiring engineering.",
|
|
7
|
+
input: z.object({
|
|
8
|
+
summary: z.string(),
|
|
9
|
+
description: z.string(),
|
|
10
|
+
priority: z.string(), // "Low", "Medium", "High", "Critical"
|
|
11
|
+
component: z.string().optional(),
|
|
12
|
+
reporter: z.string(),
|
|
13
|
+
}),
|
|
14
|
+
async execute({ summary, description, priority, component, reporter }) {
|
|
15
|
+
// In real implementation, call Jira REST API
|
|
16
|
+
// POST /rest/api/2/issue
|
|
17
|
+
|
|
18
|
+
const issueKey = `PROJ-${Math.floor(Math.random() * 10000)}`;
|
|
19
|
+
|
|
20
|
+
return {
|
|
21
|
+
created: true,
|
|
22
|
+
issueKey,
|
|
23
|
+
summary,
|
|
24
|
+
priority,
|
|
25
|
+
component: component ?? "General",
|
|
26
|
+
reporter,
|
|
27
|
+
url: `https://jira.example.com/browse/${issueKey}`,
|
|
28
|
+
};
|
|
29
|
+
},
|
|
30
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { defineWebhook } from "@kalphq/sdk";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Webhook for Slack /escalate command or button
|
|
6
|
+
*/
|
|
7
|
+
export const slackEscalation = defineWebhook({
|
|
8
|
+
id: "slack_escalation",
|
|
9
|
+
input: z.object({
|
|
10
|
+
userId: z.string(),
|
|
11
|
+
channelId: z.string(),
|
|
12
|
+
ticketId: z.string(),
|
|
13
|
+
reason: z.string(),
|
|
14
|
+
urgency: z.string(), // "low", "medium", "high"
|
|
15
|
+
}),
|
|
16
|
+
async handler({ userId, channelId, ticketId, reason, urgency }) {
|
|
17
|
+
// Process escalation request from Slack
|
|
18
|
+
// In real implementation, notify on-call support
|
|
19
|
+
|
|
20
|
+
return {
|
|
21
|
+
acknowledged: true,
|
|
22
|
+
ticketId,
|
|
23
|
+
escalationId: `ESC-${Date.now()}`,
|
|
24
|
+
estimatedResponse: urgency === "high" ? "5 minutes" : "30 minutes",
|
|
25
|
+
};
|
|
26
|
+
},
|
|
27
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { defineWebhook } from "@kalphq/sdk";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Zendesk ticket sync webhook
|
|
6
|
+
*/
|
|
7
|
+
export const zendeskTicket = defineWebhook({
|
|
8
|
+
id: "zendesk_ticket",
|
|
9
|
+
input: z.object({
|
|
10
|
+
ticketId: z.string(),
|
|
11
|
+
status: z.string(), // "new", "open", "pending", "solved", "closed"
|
|
12
|
+
subject: z.string(),
|
|
13
|
+
requesterEmail: z.string(),
|
|
14
|
+
tags: z.array(z.string()),
|
|
15
|
+
customFields: z.record(z.unknown()).optional(),
|
|
16
|
+
}),
|
|
17
|
+
async handler({ ticketId, status, subject, requesterEmail, tags, customFields }) {
|
|
18
|
+
// Sync external Zendesk ticket with internal system
|
|
19
|
+
// In real implementation, update internal ticket store
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
synced: true,
|
|
23
|
+
externalId: ticketId,
|
|
24
|
+
localId: `LOCAL-${ticketId}`,
|
|
25
|
+
status,
|
|
26
|
+
tags,
|
|
27
|
+
};
|
|
28
|
+
},
|
|
29
|
+
});
|
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
import { asAgentId, defineAgent } from "@kalphq/sdk";
|
|
2
2
|
import { analyzeSignal } from "./steps/analyze-signal.js";
|
|
3
|
+
import { rebalanceCheck } from "./steps/rebalance-check.js";
|
|
3
4
|
import { fetchMarketData } from "./tools/fetch-market-data.js";
|
|
5
|
+
import { sendEmailAlert } from "./tools/send-email-alert.js";
|
|
6
|
+
import { tradingviewAlert } from "./webhooks/tradingview-alert.js";
|
|
7
|
+
import { exchangeWebhook } from "./webhooks/exchange-webhook.js";
|
|
8
|
+
import { marketAlert } from "./signals/market-alert.js";
|
|
9
|
+
import { portfolioRebalance } from "./signals/portfolio-rebalance.js";
|
|
4
10
|
|
|
5
11
|
export default defineAgent({
|
|
6
12
|
id: asAgentId("__AGENT_NAME__"),
|
|
7
13
|
name: "__AGENT_NAME__",
|
|
8
14
|
description: "Monitors market signals and provides financial analysis.",
|
|
9
|
-
steps: [analyzeSignal],
|
|
10
|
-
tools: [fetchMarketData],
|
|
15
|
+
steps: [analyzeSignal, rebalanceCheck],
|
|
16
|
+
tools: [fetchMarketData, sendEmailAlert],
|
|
17
|
+
webhooks: [tradingviewAlert, exchangeWebhook],
|
|
18
|
+
signals: [marketAlert, portfolioRebalance],
|
|
11
19
|
|
|
12
20
|
systemPrompt:
|
|
13
21
|
"You are a financial analysis agent. Interpret market signals, fetch live data, and provide actionable insights.",
|
|
@@ -23,6 +31,20 @@ export default defineAgent({
|
|
|
23
31
|
change: market.change,
|
|
24
32
|
});
|
|
25
33
|
|
|
34
|
+
// Send alert for significant movements
|
|
35
|
+
if (Math.abs(market.change) > 5) {
|
|
36
|
+
await ctx.callTool(sendEmailAlert, {
|
|
37
|
+
to: "portfolio@example.com",
|
|
38
|
+
subject: `Alert: ${market.symbol} moved ${market.change}%`,
|
|
39
|
+
alertType: "price_movement",
|
|
40
|
+
data: {
|
|
41
|
+
symbol: market.symbol,
|
|
42
|
+
change: market.change,
|
|
43
|
+
price: market.price,
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
26
48
|
return { text: analysis.summary };
|
|
27
49
|
},
|
|
28
50
|
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { createSignal } from "@kalphq/sdk";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Signal for unusual market movements
|
|
6
|
+
*/
|
|
7
|
+
export const marketAlert = createSignal({
|
|
8
|
+
id: "market_alert",
|
|
9
|
+
input: z.object({
|
|
10
|
+
symbol: z.string(),
|
|
11
|
+
eventType: z.string(), // "gap_up", "gap_down", "high_volume", "volatility_spike"
|
|
12
|
+
changePercent: z.number(),
|
|
13
|
+
volume: z.number(),
|
|
14
|
+
averageVolume: z.number(),
|
|
15
|
+
}),
|
|
16
|
+
async handler({ symbol, eventType, changePercent, volume, averageVolume }) {
|
|
17
|
+
// Broadcast market alert to portfolio agents
|
|
18
|
+
// In real implementation, trigger risk management
|
|
19
|
+
|
|
20
|
+
const volumeRatio = volume / averageVolume;
|
|
21
|
+
|
|
22
|
+
return {
|
|
23
|
+
broadcast: true,
|
|
24
|
+
symbol,
|
|
25
|
+
eventType,
|
|
26
|
+
severity: Math.abs(changePercent) > 5 || volumeRatio > 3 ? "high" : "medium",
|
|
27
|
+
changePercent,
|
|
28
|
+
volumeRatio: Number(volumeRatio.toFixed(2)),
|
|
29
|
+
};
|
|
30
|
+
},
|
|
31
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { createSignal } from "@kalphq/sdk";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Signal to trigger portfolio rebalancing
|
|
6
|
+
*/
|
|
7
|
+
export const portfolioRebalance = createSignal({
|
|
8
|
+
id: "portfolio_rebalance",
|
|
9
|
+
input: z.object({
|
|
10
|
+
portfolioId: z.string(),
|
|
11
|
+
driftPercent: z.number(),
|
|
12
|
+
triggeredBy: z.string(), // "scheduled", "threshold", "manual"
|
|
13
|
+
targetAllocation: z.record(z.number()),
|
|
14
|
+
}),
|
|
15
|
+
async handler({ portfolioId, driftPercent, triggeredBy, targetAllocation }) {
|
|
16
|
+
// Signal portfolio agents to execute rebalancing
|
|
17
|
+
// In real implementation, generate orders for execution
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
acknowledged: true,
|
|
21
|
+
portfolioId,
|
|
22
|
+
priority: driftPercent > 10 ? "urgent" : "normal",
|
|
23
|
+
triggeredBy,
|
|
24
|
+
estimatedTrades: Object.keys(targetAllocation).length,
|
|
25
|
+
};
|
|
26
|
+
},
|
|
27
|
+
});
|