@kalphq/cli 0.0.0-dev-20260416091527 → 0.0.0-dev-20260420023057
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/add-5NOYFTJV.js +133 -0
- package/dist/add-5NOYFTJV.js.map +1 -0
- package/dist/build-SUIPVJO6.js +80 -0
- package/dist/build-SUIPVJO6.js.map +1 -0
- package/dist/chunk-6LLXGS2P.js +25 -0
- package/dist/chunk-6LLXGS2P.js.map +1 -0
- package/dist/chunk-CJCIZDCF.js +298 -0
- package/dist/chunk-CJCIZDCF.js.map +1 -0
- package/dist/{chunk-GFEVTHUW.js → chunk-HD5FT7T6.js} +98 -65
- package/dist/chunk-HD5FT7T6.js.map +1 -0
- package/dist/{create-XJURMQC4.js → create-RSQEKCI6.js} +6 -5
- package/dist/{create-XJURMQC4.js.map → create-RSQEKCI6.js.map} +1 -1
- package/dist/delete-ZJB2JGAL.js +136 -0
- package/dist/delete-ZJB2JGAL.js.map +1 -0
- package/dist/index.js +7 -3
- package/dist/index.js.map +1 -1
- package/dist/{init-K7EASUMM.js → init-CUBJEWPE.js} +3 -5
- package/dist/init-CUBJEWPE.js.map +1 -0
- package/dist/list-BOE33VSI.js +120 -0
- package/dist/list-BOE33VSI.js.map +1 -0
- package/dist/push-L3BXB6OC.js +79 -0
- package/dist/push-L3BXB6OC.js.map +1 -0
- package/dist/secrets-3SKCSAGD.js +33 -0
- package/dist/secrets-3SKCSAGD.js.map +1 -0
- package/package.json +2 -2
- package/templates/project/meta/manifest-registry.json +1 -0
- package/dist/chunk-GFEVTHUW.js.map +0 -1
- package/dist/init-K7EASUMM.js.map +0 -1
- package/dist/push-YFHHNITO.js +0 -174
- package/dist/push-YFHHNITO.js.map +0 -1
- package/templates/agents/b2b-sales/index.ts +0 -57
- package/templates/agents/b2b-sales/signals/deal-won.ts +0 -31
- package/templates/agents/b2b-sales/signals/hot-lead-alert.ts +0 -29
- package/templates/agents/b2b-sales/steps/qualify-prospect.ts +0 -50
- package/templates/agents/b2b-sales/steps/score-lead.ts +0 -24
- package/templates/agents/b2b-sales/tools/enrich-company.ts +0 -17
- package/templates/agents/b2b-sales/tools/send-slack-notification.ts +0 -26
- package/templates/agents/b2b-sales/webhooks/crm-inbound.ts +0 -27
- package/templates/agents/b2b-sales/webhooks/stripe-payment.ts +0 -27
- package/templates/agents/customer-support/index.ts +0 -60
- package/templates/agents/customer-support/signals/escalation-needed.ts +0 -28
- package/templates/agents/customer-support/signals/ticket-resolved.ts +0 -29
- package/templates/agents/customer-support/steps/classify-ticket.ts +0 -22
- package/templates/agents/customer-support/steps/escalate-ticket.ts +0 -53
- package/templates/agents/customer-support/tools/create-jira-issue.ts +0 -30
- package/templates/agents/customer-support/tools/search-kb.ts +0 -13
- package/templates/agents/customer-support/webhooks/slack-escalation.ts +0 -27
- package/templates/agents/customer-support/webhooks/zendesk-ticket.ts +0 -29
- package/templates/agents/financial-agent/index.ts +0 -50
- package/templates/agents/financial-agent/signals/market-alert.ts +0 -31
- package/templates/agents/financial-agent/signals/portfolio-rebalance.ts +0 -27
- package/templates/agents/financial-agent/steps/analyze-signal.ts +0 -26
- package/templates/agents/financial-agent/steps/rebalance-check.ts +0 -55
- package/templates/agents/financial-agent/tools/fetch-market-data.ts +0 -13
- package/templates/agents/financial-agent/tools/send-email-alert.ts +0 -31
- package/templates/agents/financial-agent/webhooks/exchange-webhook.ts +0 -33
- package/templates/agents/financial-agent/webhooks/tradingview-alert.ts +0 -30
- package/templates/agents/minimal/index.ts +0 -24
- package/templates/agents/minimal/signals/error-alert.ts +0 -26
- package/templates/agents/minimal/signals/task-complete.ts +0 -25
- package/templates/agents/minimal/steps/example-step.ts +0 -13
- package/templates/agents/minimal/steps/transform-data.ts +0 -32
- package/templates/agents/minimal/tools/example-tool.ts +0 -13
- package/templates/agents/minimal/tools/http-request.ts +0 -26
- package/templates/agents/minimal/webhooks/generic-inbound.ts +0 -25
- package/templates/agents/minimal/webhooks/health-check.ts +0 -23
- package/templates/project/agents/.gitkeep +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/init.ts"],"sourcesContent":["import { resolve, basename } from \"node:path\";\nimport { defineCommand } from \"citty\";\nimport * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport { scaffoldProject } from \"../scaffold.js\";\nimport { promptProjectName } from \"../utils/ui.js\";\nimport {\n ensureDirectory,\n installDeps,\n isProjectInitialized,\n} from \"../utils/fs.js\";\n\nconst LOGO = \"🦋\";\n\nexport default defineCommand({\n meta: { name: \"init\", description: \"Scaffold a new Kalp project\" },\n async run() {\n const cwd = process.cwd();\n\n p.intro(`${LOGO} ${pc.bold(\"kalp init\")}`);\n\n const projectInputName = await promptProjectName({\n message: \"What is the name of your project?\",\n placeholder: \"my-agent\",\n allowCurrentDir: true,\n });\n\n const isCurrentDir = projectInputName === \".\";\n const targetDir = isCurrentDir ? cwd : resolve(cwd, projectInputName);\n const projectName = isCurrentDir ? basename(cwd) : projectInputName;\n\n // ── Guard: already initialized ───────────────────────────────────────\n if (await isProjectInitialized(targetDir)) {\n p.log.error(\n `${pc.cyan(\"kalp.config.ts\")} already exists in this directory. Run ${pc.cyan(\"kalp create\")} to add an agent.`,\n );\n process.exit(1);\n }\n\n // ── Create target directory if needed ─────────────────────────────────\n if (!isCurrentDir) {\n await ensureDirectory(targetDir);\n }\n\n const s = p.spinner();\n\n s.start(\"Creating project structure\");\n await scaffoldProject({ projectName, targetDir });\n s.stop(\"Project structure created\");\n\n s.start(\"Installing dependencies\");\n try {\n await installDeps(targetDir);\n s.stop(\"Dependencies installed\");\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n s.stop(pc.yellow(\"Install failed\"));\n p.log.warn(\n `Run ${pc.cyan(\"npx --no-install nci\")} (or ${pc.cyan(\"npm install\")}) manually in ${isCurrentDir ? \"this directory\" : projectInputName + \"/\"}`,\n );\n p.log.info(pc.dim(msg.split(\"\\n\")[0] ?? \"Unknown error\"));\n }\n\n p.log.success(\"Project scaffolded\");\n p.log.info(`${pc.cyan(\"kalp.config.ts\")} — project config`);\n p.log.info(`${pc.cyan(\"package.json\")} — dependencies`);\n p.log.info(`${pc.cyan(\"agents/\")} — your agents live here`);\n console.log(\"\");\n p.log.info(pc.bold(\"Next\"));\n if (!isCurrentDir) {\n p.log.info(`1. ${pc.cyan(`cd ${projectInputName}`)}`);\n p.log.info(`2. ${pc.cyan(\"kalp create\")} — add your first agent`);\n } else {\n p.log.info(`1. ${pc.cyan(\"kalp create\")} — add your first agent`);\n }\n\n p.outro(pc.green(\"Kalp initialized successfully.\"));\n },\n});\n"],"mappings":";;;;;;;;;;;;;AAAA,SAAS,SAAS,gBAAgB;AAClC,SAAS,qBAAqB;AAC9B,YAAY,OAAO;AACnB,OAAO,QAAQ;AASf,IAAM,OAAO;AAEb,IAAO,eAAQ,cAAc;AAAA,EAC3B,MAAM,EAAE,MAAM,QAAQ,aAAa,8BAA8B;AAAA,EACjE,MAAM,MAAM;AACV,UAAM,MAAM,QAAQ,IAAI;AAExB,IAAE,QAAM,GAAG,IAAI,IAAI,GAAG,KAAK,WAAW,CAAC,EAAE;AAEzC,UAAM,mBAAmB,MAAM,kBAAkB;AAAA,MAC/C,SAAS;AAAA,MACT,aAAa;AAAA,MACb,iBAAiB;AAAA,IACnB,CAAC;AAED,UAAM,eAAe,qBAAqB;AAC1C,UAAM,YAAY,eAAe,MAAM,QAAQ,KAAK,gBAAgB;AACpE,UAAM,cAAc,eAAe,SAAS,GAAG,IAAI;AAGnD,QAAI,MAAM,qBAAqB,SAAS,GAAG;AACzC,MAAE,MAAI;AAAA,QACJ,GAAG,GAAG,KAAK,gBAAgB,CAAC,0CAA0C,GAAG,KAAK,aAAa,CAAC;AAAA,MAC9F;AACA,cAAQ,KAAK,CAAC;AAAA,IAChB;AAGA,QAAI,CAAC,cAAc;AACjB,YAAM,gBAAgB,SAAS;AAAA,IACjC;AAEA,UAAM,IAAM,UAAQ;AAEpB,MAAE,MAAM,4BAA4B;AACpC,UAAM,gBAAgB,EAAE,aAAa,UAAU,CAAC;AAChD,MAAE,KAAK,2BAA2B;AAElC,MAAE,MAAM,yBAAyB;AACjC,QAAI;AACF,YAAM,YAAY,SAAS;AAC3B,QAAE,KAAK,wBAAwB;AAAA,IACjC,SAAS,KAAK;AACZ,YAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,QAAE,KAAK,GAAG,OAAO,gBAAgB,CAAC;AAClC,MAAE,MAAI;AAAA,QACJ,OAAO,GAAG,KAAK,sBAAsB,CAAC,QAAQ,GAAG,KAAK,aAAa,CAAC,iBAAiB,eAAe,mBAAmB,mBAAmB,GAAG;AAAA,MAC/I;AACA,MAAE,MAAI,KAAK,GAAG,IAAI,IAAI,MAAM,IAAI,EAAE,CAAC,KAAK,eAAe,CAAC;AAAA,IAC1D;AAEA,IAAE,MAAI,QAAQ,oBAAoB;AAClC,IAAE,MAAI,KAAK,GAAG,GAAG,KAAK,gBAAgB,CAAC,wBAAmB;AAC1D,IAAE,MAAI,KAAK,GAAG,GAAG,KAAK,cAAc,CAAC,sBAAiB;AACtD,IAAE,MAAI,KAAK,GAAG,GAAG,KAAK,SAAS,CAAC,+BAA0B;AAC1D,YAAQ,IAAI,EAAE;AACd,IAAE,MAAI,KAAK,GAAG,KAAK,MAAM,CAAC;AAC1B,QAAI,CAAC,cAAc;AACjB,MAAE,MAAI,KAAK,MAAM,GAAG,KAAK,MAAM,gBAAgB,EAAE,CAAC,EAAE;AACpD,MAAE,MAAI,KAAK,MAAM,GAAG,KAAK,aAAa,CAAC,8BAAyB;AAAA,IAClE,OAAO;AACL,MAAE,MAAI,KAAK,MAAM,GAAG,KAAK,aAAa,CAAC,8BAAyB;AAAA,IAClE;AAEA,IAAE,QAAM,GAAG,MAAM,gCAAgC,CAAC;AAAA,EACpD;AACF,CAAC;","names":[]}
|
package/dist/push-YFHHNITO.js
DELETED
|
@@ -1,174 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
ensureConfig
|
|
4
|
-
} from "./chunk-Q455HC3P.js";
|
|
5
|
-
import "./chunk-2H7UOFLK.js";
|
|
6
|
-
|
|
7
|
-
// src/commands/push.ts
|
|
8
|
-
import { existsSync } from "fs";
|
|
9
|
-
import { access, mkdtemp, rm } from "fs/promises";
|
|
10
|
-
import { join, resolve } from "path";
|
|
11
|
-
import { pathToFileURL } from "url";
|
|
12
|
-
import { defineCommand } from "citty";
|
|
13
|
-
import * as p from "@clack/prompts";
|
|
14
|
-
import { build } from "esbuild";
|
|
15
|
-
import pc from "picocolors";
|
|
16
|
-
import { zodToJsonSchema } from "zod-to-json-schema";
|
|
17
|
-
var LOGO = "\u{1F98B}";
|
|
18
|
-
function toJsonSchema(schema, name) {
|
|
19
|
-
try {
|
|
20
|
-
return zodToJsonSchema(schema, name);
|
|
21
|
-
} catch {
|
|
22
|
-
return null;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
function asRecord(value) {
|
|
26
|
-
return typeof value === "object" && value !== null ? value : {};
|
|
27
|
-
}
|
|
28
|
-
function asString(value) {
|
|
29
|
-
return typeof value === "string" ? value : void 0;
|
|
30
|
-
}
|
|
31
|
-
function asArray(value) {
|
|
32
|
-
return Array.isArray(value) ? value : [];
|
|
33
|
-
}
|
|
34
|
-
function serializeSteps(steps) {
|
|
35
|
-
return steps.map((step, index) => {
|
|
36
|
-
const item = asRecord(step);
|
|
37
|
-
return {
|
|
38
|
-
id: asString(item.id) ?? `step_${index}`,
|
|
39
|
-
description: asString(item.description) ?? "",
|
|
40
|
-
inputSchema: toJsonSchema(item.input, `step_${index}_input`),
|
|
41
|
-
outputSchema: toJsonSchema(item.output, `step_${index}_output`)
|
|
42
|
-
};
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
function serializeItems(items, kind) {
|
|
46
|
-
return items.map((item, index) => {
|
|
47
|
-
const parsed = asRecord(item);
|
|
48
|
-
return {
|
|
49
|
-
id: asString(parsed.id) ?? `${kind}_${index}`,
|
|
50
|
-
description: asString(parsed.description) ?? "",
|
|
51
|
-
inputSchema: toJsonSchema(parsed.input, `${kind}_${index}_input`)
|
|
52
|
-
};
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
async function loadAgentModule(agentPath, cwd) {
|
|
56
|
-
const tempDir = await mkdtemp(join(cwd, ".kalp-push-"));
|
|
57
|
-
const outFile = join(tempDir, "agent.preview.mjs");
|
|
58
|
-
await build({
|
|
59
|
-
entryPoints: [agentPath],
|
|
60
|
-
outfile: outFile,
|
|
61
|
-
bundle: true,
|
|
62
|
-
format: "esm",
|
|
63
|
-
platform: "node",
|
|
64
|
-
target: "node18",
|
|
65
|
-
logLevel: "silent",
|
|
66
|
-
packages: "external",
|
|
67
|
-
plugins: [
|
|
68
|
-
{
|
|
69
|
-
name: "relative-js-to-ts",
|
|
70
|
-
setup(buildCtx) {
|
|
71
|
-
buildCtx.onResolve({ filter: /^\.+\/.*\.js$/ }, (args) => {
|
|
72
|
-
const resolved = resolve(args.resolveDir, args.path);
|
|
73
|
-
if (existsSync(resolved)) {
|
|
74
|
-
return { path: resolved };
|
|
75
|
-
}
|
|
76
|
-
const tsPath = resolved.replace(/\.js$/, ".ts");
|
|
77
|
-
if (existsSync(tsPath)) {
|
|
78
|
-
return { path: tsPath };
|
|
79
|
-
}
|
|
80
|
-
const tsxPath = resolved.replace(/\.js$/, ".tsx");
|
|
81
|
-
if (existsSync(tsxPath)) {
|
|
82
|
-
return { path: tsxPath };
|
|
83
|
-
}
|
|
84
|
-
return null;
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
]
|
|
89
|
-
});
|
|
90
|
-
const loaded = await import(`${pathToFileURL(outFile).href}?t=${Date.now()}`);
|
|
91
|
-
return {
|
|
92
|
-
agent: loaded.default,
|
|
93
|
-
tempDir
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
var push_default = defineCommand({
|
|
97
|
-
meta: { name: "push", description: "Push an agent to Kalp (preview mode)" },
|
|
98
|
-
args: {
|
|
99
|
-
agent: {
|
|
100
|
-
type: "string",
|
|
101
|
-
alias: "a",
|
|
102
|
-
description: "Agent name to push",
|
|
103
|
-
required: false
|
|
104
|
-
}
|
|
105
|
-
},
|
|
106
|
-
async run({ args }) {
|
|
107
|
-
const cwd = process.cwd();
|
|
108
|
-
p.intro(`${LOGO} ${pc.bold("kalp push")}`);
|
|
109
|
-
const agentName = args.agent;
|
|
110
|
-
if (!agentName) {
|
|
111
|
-
p.log.error(`Missing required flag ${pc.cyan("-a <agent-name>")}`);
|
|
112
|
-
p.outro(pc.dim(`Example: ${pc.cyan("kalp push -a my-agent")}`));
|
|
113
|
-
process.exit(1);
|
|
114
|
-
}
|
|
115
|
-
try {
|
|
116
|
-
await ensureConfig(cwd);
|
|
117
|
-
} catch {
|
|
118
|
-
p.log.error(`${pc.cyan("kalp.config.ts")} not found`);
|
|
119
|
-
p.outro(pc.dim(`Run ${pc.cyan("kalp init")} first.`));
|
|
120
|
-
process.exit(1);
|
|
121
|
-
}
|
|
122
|
-
const agentPath = join(cwd, "agents", agentName, "index.ts");
|
|
123
|
-
try {
|
|
124
|
-
await access(agentPath);
|
|
125
|
-
} catch {
|
|
126
|
-
p.log.error(
|
|
127
|
-
`Agent ${pc.cyan(agentName)} not found at ${pc.cyan(`agents/${agentName}/index.ts`)}`
|
|
128
|
-
);
|
|
129
|
-
process.exit(1);
|
|
130
|
-
}
|
|
131
|
-
const s = p.spinner();
|
|
132
|
-
s.start(`Parsing agent ${pc.cyan(agentName)}`);
|
|
133
|
-
let tempDir;
|
|
134
|
-
let agentConfig;
|
|
135
|
-
try {
|
|
136
|
-
const loaded = await loadAgentModule(agentPath, cwd);
|
|
137
|
-
tempDir = loaded.tempDir;
|
|
138
|
-
const agent = asRecord(loaded.agent);
|
|
139
|
-
agentConfig = {
|
|
140
|
-
id: asString(agent.id) ?? void 0,
|
|
141
|
-
name: asString(agent.name) ?? agentName,
|
|
142
|
-
description: asString(agent.description) ?? "",
|
|
143
|
-
source: agentPath,
|
|
144
|
-
systemPrompt: asString(agent.systemPrompt) ?? "",
|
|
145
|
-
steps: serializeSteps(asArray(agent.steps)),
|
|
146
|
-
tools: serializeItems(asArray(agent.tools), "tool"),
|
|
147
|
-
webhooks: serializeItems(asArray(agent.webhooks), "webhook"),
|
|
148
|
-
signals: serializeItems(asArray(agent.signals), "signal")
|
|
149
|
-
};
|
|
150
|
-
} catch (err) {
|
|
151
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
152
|
-
s.stop(pc.red("Could not parse agent module"));
|
|
153
|
-
p.log.info(pc.dim(msg.split("\n")[0] ?? "Unknown error"));
|
|
154
|
-
process.exit(1);
|
|
155
|
-
} finally {
|
|
156
|
-
if (tempDir) {
|
|
157
|
-
await rm(tempDir, { recursive: true, force: true });
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
s.stop("Agent parsed");
|
|
161
|
-
console.log("\n" + pc.dim("\u2500".repeat(50)));
|
|
162
|
-
console.log(pc.cyan("Agent Configuration (JSON):"));
|
|
163
|
-
console.log(pc.dim("\u2500".repeat(50)));
|
|
164
|
-
console.log(JSON.stringify(agentConfig, null, 2));
|
|
165
|
-
console.log(pc.dim("\u2500".repeat(50)) + "\n");
|
|
166
|
-
p.outro(
|
|
167
|
-
`${LOGO} ${pc.green("Preview ready")} ${pc.dim("\u2014 push to deploy coming soon")}`
|
|
168
|
-
);
|
|
169
|
-
}
|
|
170
|
-
});
|
|
171
|
-
export {
|
|
172
|
-
push_default as default
|
|
173
|
-
};
|
|
174
|
-
//# sourceMappingURL=push-YFHHNITO.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/push.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport { access, mkdtemp, rm } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { defineCommand } from \"citty\";\nimport * as p from \"@clack/prompts\";\nimport { build } from \"esbuild\";\nimport pc from \"picocolors\";\nimport type { ZodTypeAny } from \"zod\";\nimport { zodToJsonSchema } from \"zod-to-json-schema\";\nimport { ensureConfig } from \"../utils/fs.js\";\n\nconst LOGO = \"🦋\";\n\ntype JsonSchema = Record<string, unknown>;\n\ninterface AgentItemWithInput {\n id?: unknown;\n description?: unknown;\n input?: unknown;\n}\n\ninterface AgentStepItem extends AgentItemWithInput {\n output?: unknown;\n}\n\ninterface LoadedAgentModule {\n agent: unknown;\n tempDir: string;\n}\n\nfunction toJsonSchema(schema: unknown, name: string): JsonSchema | null {\n try {\n return zodToJsonSchema(schema as ZodTypeAny, name) as JsonSchema;\n } catch {\n return null;\n }\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> {\n return typeof value === \"object\" && value !== null\n ? (value as Record<string, unknown>)\n : {};\n}\n\nfunction asString(value: unknown): string | undefined {\n return typeof value === \"string\" ? value : undefined;\n}\n\nfunction asArray(value: unknown): unknown[] {\n return Array.isArray(value) ? value : [];\n}\n\nfunction serializeSteps(steps: unknown[]): Record<string, unknown>[] {\n return steps.map((step, index) => {\n const item = asRecord(step) as AgentStepItem;\n return {\n id: asString(item.id) ?? `step_${index}`,\n description: asString(item.description) ?? \"\",\n inputSchema: toJsonSchema(item.input, `step_${index}_input`),\n outputSchema: toJsonSchema(item.output, `step_${index}_output`),\n };\n });\n}\n\nfunction serializeItems(\n items: unknown[],\n kind: \"tool\" | \"webhook\" | \"signal\",\n): Record<string, unknown>[] {\n return items.map((item, index) => {\n const parsed = asRecord(item) as AgentItemWithInput;\n return {\n id: asString(parsed.id) ?? `${kind}_${index}`,\n description: asString(parsed.description) ?? \"\",\n inputSchema: toJsonSchema(parsed.input, `${kind}_${index}_input`),\n };\n });\n}\n\nasync function loadAgentModule(\n agentPath: string,\n cwd: string,\n): Promise<LoadedAgentModule> {\n const tempDir = await mkdtemp(join(cwd, \".kalp-push-\"));\n const outFile = join(tempDir, \"agent.preview.mjs\");\n\n await build({\n entryPoints: [agentPath],\n outfile: outFile,\n bundle: true,\n format: \"esm\",\n platform: \"node\",\n target: \"node18\",\n logLevel: \"silent\",\n packages: \"external\",\n plugins: [\n {\n name: \"relative-js-to-ts\",\n setup(buildCtx) {\n buildCtx.onResolve({ filter: /^\\.+\\/.*\\.js$/ }, (args) => {\n const resolved = resolve(args.resolveDir, args.path);\n if (existsSync(resolved)) {\n return { path: resolved };\n }\n\n const tsPath = resolved.replace(/\\.js$/, \".ts\");\n if (existsSync(tsPath)) {\n return { path: tsPath };\n }\n\n const tsxPath = resolved.replace(/\\.js$/, \".tsx\");\n if (existsSync(tsxPath)) {\n return { path: tsxPath };\n }\n\n return null;\n });\n },\n },\n ],\n });\n\n const loaded = (await import(\n `${pathToFileURL(outFile).href}?t=${Date.now()}`\n )) as { default?: unknown };\n\n return {\n agent: loaded.default,\n tempDir,\n };\n}\n\nexport default defineCommand({\n meta: { name: \"push\", description: \"Push an agent to Kalp (preview mode)\" },\n args: {\n agent: {\n type: \"string\",\n alias: \"a\",\n description: \"Agent name to push\",\n required: false,\n },\n },\n async run({ args }) {\n const cwd = process.cwd();\n\n p.intro(`${LOGO} ${pc.bold(\"kalp push\")}`);\n\n // ── Validate agent name ─────────────────────────────────────────────────\n const agentName = args.agent;\n if (!agentName) {\n p.log.error(`Missing required flag ${pc.cyan(\"-a <agent-name>\")}`);\n p.outro(pc.dim(`Example: ${pc.cyan(\"kalp push -a my-agent\")}`));\n process.exit(1);\n }\n\n // ── Validate kalp.config.ts exists ─────────────────────────────────────\n try {\n await ensureConfig(cwd);\n } catch {\n p.log.error(`${pc.cyan(\"kalp.config.ts\")} not found`);\n p.outro(pc.dim(`Run ${pc.cyan(\"kalp init\")} first.`));\n process.exit(1);\n }\n\n // ── Find agent ──────────────────────────────────────────────────────────\n const agentPath = join(cwd, \"agents\", agentName, \"index.ts\");\n try {\n await access(agentPath);\n } catch {\n p.log.error(\n `Agent ${pc.cyan(agentName)} not found at ${pc.cyan(`agents/${agentName}/index.ts`)}`,\n );\n process.exit(1);\n }\n\n const s = p.spinner();\n s.start(`Parsing agent ${pc.cyan(agentName)}`);\n let tempDir: string | undefined;\n let agentConfig: Record<string, unknown>;\n\n try {\n const loaded = await loadAgentModule(agentPath, cwd);\n tempDir = loaded.tempDir;\n\n const agent = asRecord(loaded.agent);\n agentConfig = {\n id: asString(agent.id) ?? undefined,\n name: asString(agent.name) ?? agentName,\n description: asString(agent.description) ?? \"\",\n source: agentPath,\n systemPrompt: asString(agent.systemPrompt) ?? \"\",\n steps: serializeSteps(asArray(agent.steps)),\n tools: serializeItems(asArray(agent.tools), \"tool\"),\n webhooks: serializeItems(asArray(agent.webhooks), \"webhook\"),\n signals: serializeItems(asArray(agent.signals), \"signal\"),\n };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n s.stop(pc.red(\"Could not parse agent module\"));\n p.log.info(pc.dim(msg.split(\"\\n\")[0] ?? \"Unknown error\"));\n process.exit(1);\n } finally {\n if (tempDir) {\n await rm(tempDir, { recursive: true, force: true });\n }\n }\n\n s.stop(\"Agent parsed\");\n\n // ── Output JSON ─────────────────────────────────────────────────────────\n console.log(\"\\n\" + pc.dim(\"─\".repeat(50)));\n console.log(pc.cyan(\"Agent Configuration (JSON):\"));\n console.log(pc.dim(\"─\".repeat(50)));\n console.log(JSON.stringify(agentConfig, null, 2));\n console.log(pc.dim(\"─\".repeat(50)) + \"\\n\");\n\n p.outro(\n `${LOGO} ${pc.green(\"Preview ready\")} ${pc.dim(\"— push to deploy coming soon\")}`,\n );\n },\n});\n"],"mappings":"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","names":[]}
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { asAgentId, defineAgent } from "@kalphq/sdk";
|
|
2
|
-
import { scoreLead } from "./steps/score-lead.js";
|
|
3
|
-
import { qualifyProspect } from "./steps/qualify-prospect.js";
|
|
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";
|
|
10
|
-
|
|
11
|
-
export default defineAgent({
|
|
12
|
-
id: asAgentId("__AGENT_NAME__"),
|
|
13
|
-
name: "__AGENT_NAME__",
|
|
14
|
-
description: "Automates B2B outreach with lead scoring and CRM enrichment.",
|
|
15
|
-
steps: [scoreLead, qualifyProspect],
|
|
16
|
-
tools: [enrichCompany, sendSlackNotification],
|
|
17
|
-
webhooks: [crmInbound, stripePayment],
|
|
18
|
-
signals: [hotLeadAlert, dealWon],
|
|
19
|
-
|
|
20
|
-
systemPrompt:
|
|
21
|
-
"You are a B2B sales assistant. Score leads, enrich company data, and draft personalized outreach messages.",
|
|
22
|
-
|
|
23
|
-
async onMessage(message, ctx) {
|
|
24
|
-
const lead = await ctx.runStep(scoreLead, { company: message.text });
|
|
25
|
-
|
|
26
|
-
if (lead.score < 50) {
|
|
27
|
-
return { text: "Lead score too low — skipping outreach." };
|
|
28
|
-
}
|
|
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
|
-
|
|
41
|
-
const enriched = await ctx.callTool(enrichCompany, { domain: lead.domain });
|
|
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
|
-
|
|
53
|
-
return {
|
|
54
|
-
text: `${enriched.companyName} (${lead.score}/100, ${qualified.priority} priority) — Ready for outreach.`,
|
|
55
|
-
};
|
|
56
|
-
},
|
|
57
|
-
});
|
|
@@ -1,31 +0,0 @@
|
|
|
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
|
-
});
|
|
@@ -1,29 +0,0 @@
|
|
|
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
|
-
});
|
|
@@ -1,50 +0,0 @@
|
|
|
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
|
-
});
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { createStep } from "@kalphq/sdk";
|
|
2
|
-
import { z } from "zod";
|
|
3
|
-
|
|
4
|
-
export const scoreLead = createStep({
|
|
5
|
-
id: "score_lead",
|
|
6
|
-
description: "Scores a B2B lead based on company signals.",
|
|
7
|
-
input: z.object({ company: z.string() }),
|
|
8
|
-
output: z.object({
|
|
9
|
-
score: z.number().min(0).max(100),
|
|
10
|
-
domain: z.string(),
|
|
11
|
-
reason: z.string(),
|
|
12
|
-
}),
|
|
13
|
-
async run({ company }, ctx) {
|
|
14
|
-
const result = await ctx.ai.generateObject({
|
|
15
|
-
prompt: `Score this B2B lead for "${company}". Provide a score 0-100, the company domain, and a brief reason.`,
|
|
16
|
-
schema: z.object({
|
|
17
|
-
score: z.number().min(0).max(100),
|
|
18
|
-
domain: z.string(),
|
|
19
|
-
reason: z.string(),
|
|
20
|
-
}),
|
|
21
|
-
});
|
|
22
|
-
return result;
|
|
23
|
-
},
|
|
24
|
-
});
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { createTool } from "@kalphq/sdk";
|
|
2
|
-
import { z } from "zod";
|
|
3
|
-
|
|
4
|
-
export const enrichCompany = createTool({
|
|
5
|
-
id: "enrich_company",
|
|
6
|
-
description: "Fetches enriched company data from the CRM.",
|
|
7
|
-
input: z.object({ domain: z.string() }),
|
|
8
|
-
async execute({ domain }, ctx) {
|
|
9
|
-
ctx.logger.info("Enriching company", { domain });
|
|
10
|
-
// Replace with actual CRM API call
|
|
11
|
-
return {
|
|
12
|
-
companyName: domain.split(".")[0] ?? domain,
|
|
13
|
-
employees: 0,
|
|
14
|
-
industry: "Unknown",
|
|
15
|
-
};
|
|
16
|
-
},
|
|
17
|
-
});
|
|
@@ -1,26 +0,0 @@
|
|
|
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
|
-
});
|
|
@@ -1,27 +0,0 @@
|
|
|
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
|
-
});
|
|
@@ -1,27 +0,0 @@
|
|
|
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,60 +0,0 @@
|
|
|
1
|
-
import { asAgentId, defineAgent } from "@kalphq/sdk";
|
|
2
|
-
import { classifyTicket } from "./steps/classify-ticket.js";
|
|
3
|
-
import { escalateTicket } from "./steps/escalate-ticket.js";
|
|
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";
|
|
10
|
-
|
|
11
|
-
export default defineAgent({
|
|
12
|
-
id: asAgentId("__AGENT_NAME__"),
|
|
13
|
-
name: "__AGENT_NAME__",
|
|
14
|
-
description: "Handles incoming support tickets with AI-powered routing.",
|
|
15
|
-
steps: [classifyTicket, escalateTicket],
|
|
16
|
-
tools: [searchKnowledgeBase, createJiraIssue],
|
|
17
|
-
webhooks: [slackEscalation, zendeskTicket],
|
|
18
|
-
signals: [escalationNeeded, ticketResolved],
|
|
19
|
-
|
|
20
|
-
systemPrompt:
|
|
21
|
-
"You are a friendly support agent. Classify tickets, search the knowledge base, and resolve issues efficiently.",
|
|
22
|
-
|
|
23
|
-
async onMessage(message, ctx) {
|
|
24
|
-
const ticket = await ctx.runStep(classifyTicket, { text: message.text });
|
|
25
|
-
|
|
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
|
-
};
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// Try knowledge base for non-escalated issues
|
|
54
|
-
const results = await ctx.callTool(searchKnowledgeBase, {
|
|
55
|
-
query: message.text,
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
return { text: results.answer ?? "Let me connect you with a specialist." };
|
|
59
|
-
},
|
|
60
|
-
});
|
|
@@ -1,28 +0,0 @@
|
|
|
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
|
-
});
|
|
@@ -1,29 +0,0 @@
|
|
|
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
|
-
});
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { createStep } from "@kalphq/sdk";
|
|
2
|
-
import { z } from "zod";
|
|
3
|
-
|
|
4
|
-
export const classifyTicket = createStep({
|
|
5
|
-
id: "classify_ticket",
|
|
6
|
-
description: "Classifies a support ticket by category and priority.",
|
|
7
|
-
input: z.object({ text: z.string() }),
|
|
8
|
-
output: z.object({
|
|
9
|
-
category: z.enum(["billing", "technical", "general"]),
|
|
10
|
-
priority: z.enum(["low", "medium", "high"]),
|
|
11
|
-
}),
|
|
12
|
-
async run({ text }, ctx) {
|
|
13
|
-
const result = await ctx.ai.generateObject({
|
|
14
|
-
prompt: `Classify this support ticket: "${text}"`,
|
|
15
|
-
schema: z.object({
|
|
16
|
-
category: z.enum(["billing", "technical", "general"]),
|
|
17
|
-
priority: z.enum(["low", "medium", "high"]),
|
|
18
|
-
}),
|
|
19
|
-
});
|
|
20
|
-
return result;
|
|
21
|
-
},
|
|
22
|
-
});
|