@skillrecordings/cli 0.1.0 → 0.2.0
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/bin/skill.mjs +27 -0
- package/dist/chunk-2NCCVTEE.js +22342 -0
- package/dist/chunk-2NCCVTEE.js.map +1 -0
- package/dist/chunk-3E3GYSZR.js +7071 -0
- package/dist/chunk-3E3GYSZR.js.map +1 -0
- package/dist/chunk-F4EM72IH.js +86 -0
- package/dist/chunk-F4EM72IH.js.map +1 -0
- package/dist/chunk-FGP7KUQW.js +432 -0
- package/dist/chunk-FGP7KUQW.js.map +1 -0
- package/dist/chunk-H3D6VCME.js +55 -0
- package/dist/chunk-H3D6VCME.js.map +1 -0
- package/dist/chunk-HK3PEWFD.js +208 -0
- package/dist/chunk-HK3PEWFD.js.map +1 -0
- package/dist/chunk-KEV3QKXP.js +4495 -0
- package/dist/chunk-KEV3QKXP.js.map +1 -0
- package/dist/chunk-MG37YDAK.js +882 -0
- package/dist/chunk-MG37YDAK.js.map +1 -0
- package/dist/chunk-MLNDSBZ4.js +482 -0
- package/dist/chunk-MLNDSBZ4.js.map +1 -0
- package/dist/chunk-N2WIV2JV.js +22 -0
- package/dist/chunk-N2WIV2JV.js.map +1 -0
- package/dist/chunk-PWWRCN5W.js +2067 -0
- package/dist/chunk-PWWRCN5W.js.map +1 -0
- package/dist/chunk-SKHBM3XP.js +7746 -0
- package/dist/chunk-SKHBM3XP.js.map +1 -0
- package/dist/chunk-WFANXVQG.js +64 -0
- package/dist/chunk-WFANXVQG.js.map +1 -0
- package/dist/chunk-WYKL32C3.js +275 -0
- package/dist/chunk-WYKL32C3.js.map +1 -0
- package/dist/chunk-ZNF7XD2S.js +134 -0
- package/dist/chunk-ZNF7XD2S.js.map +1 -0
- package/dist/config-AUAIYDSI.js +20 -0
- package/dist/config-AUAIYDSI.js.map +1 -0
- package/dist/fileFromPath-XN7LXIBI.js +134 -0
- package/dist/fileFromPath-XN7LXIBI.js.map +1 -0
- package/dist/getMachineId-bsd-KW2E7VK3.js +42 -0
- package/dist/getMachineId-bsd-KW2E7VK3.js.map +1 -0
- package/dist/getMachineId-darwin-ROXJUJX5.js +42 -0
- package/dist/getMachineId-darwin-ROXJUJX5.js.map +1 -0
- package/dist/getMachineId-linux-KVZEHQSU.js +34 -0
- package/dist/getMachineId-linux-KVZEHQSU.js.map +1 -0
- package/dist/getMachineId-unsupported-PPRILPPA.js +25 -0
- package/dist/getMachineId-unsupported-PPRILPPA.js.map +1 -0
- package/dist/getMachineId-win-IIF36LEJ.js +44 -0
- package/dist/getMachineId-win-IIF36LEJ.js.map +1 -0
- package/dist/index.js +112703 -0
- package/dist/index.js.map +1 -0
- package/dist/lib-R6DEEJCP.js +7623 -0
- package/dist/lib-R6DEEJCP.js.map +1 -0
- package/dist/pipeline-IAVVAKTU.js +120 -0
- package/dist/pipeline-IAVVAKTU.js.map +1 -0
- package/dist/query-NTP5NVXN.js +25 -0
- package/dist/query-NTP5NVXN.js.map +1 -0
- package/dist/routing-BAEPFB7V.js +390 -0
- package/dist/routing-BAEPFB7V.js.map +1 -0
- package/dist/stripe-lookup-charge-EPRUMZDL.js +56 -0
- package/dist/stripe-lookup-charge-EPRUMZDL.js.map +1 -0
- package/dist/stripe-payment-history-SJPKA63N.js +67 -0
- package/dist/stripe-payment-history-SJPKA63N.js.map +1 -0
- package/dist/stripe-subscription-status-L4Z65GB3.js +58 -0
- package/dist/stripe-subscription-status-L4Z65GB3.js.map +1 -0
- package/dist/stripe-verify-refund-FZDKCIUQ.js +54 -0
- package/dist/stripe-verify-refund-FZDKCIUQ.js.map +1 -0
- package/dist/support-memory-WSG7SDKG.js +10 -0
- package/dist/support-memory-WSG7SDKG.js.map +1 -0
- package/package.json +10 -7
- package/.env.encrypted +0 -0
- package/CHANGELOG.md +0 -35
- package/data/tt-archive-dataset.json +0 -1
- package/data/validate-test-dataset.json +0 -97
- package/docs/CLI-AUTH.md +0 -504
- package/preload.ts +0 -18
- package/src/__tests__/init.test.ts +0 -74
- package/src/alignment-test.ts +0 -64
- package/src/check-apps.ts +0 -16
- package/src/commands/auth/decrypt.ts +0 -123
- package/src/commands/auth/encrypt.ts +0 -81
- package/src/commands/auth/index.ts +0 -50
- package/src/commands/auth/keygen.ts +0 -41
- package/src/commands/auth/status.ts +0 -164
- package/src/commands/axiom/forensic.ts +0 -868
- package/src/commands/axiom/index.ts +0 -697
- package/src/commands/build-dataset.ts +0 -311
- package/src/commands/db-status.ts +0 -47
- package/src/commands/deploys.ts +0 -219
- package/src/commands/eval-local/compare.ts +0 -171
- package/src/commands/eval-local/health.ts +0 -212
- package/src/commands/eval-local/index.ts +0 -76
- package/src/commands/eval-local/real-tools.ts +0 -416
- package/src/commands/eval-local/run.ts +0 -1168
- package/src/commands/eval-local/score-production.ts +0 -256
- package/src/commands/eval-local/seed.ts +0 -276
- package/src/commands/eval-pipeline/index.ts +0 -53
- package/src/commands/eval-pipeline/real-tools.ts +0 -492
- package/src/commands/eval-pipeline/run.ts +0 -1316
- package/src/commands/eval-pipeline/seed.ts +0 -395
- package/src/commands/eval-prompt.ts +0 -496
- package/src/commands/eval.test.ts +0 -253
- package/src/commands/eval.ts +0 -108
- package/src/commands/faq-classify.ts +0 -460
- package/src/commands/faq-cluster.ts +0 -135
- package/src/commands/faq-extract.ts +0 -249
- package/src/commands/faq-mine.ts +0 -432
- package/src/commands/faq-review.ts +0 -426
- package/src/commands/front/index.ts +0 -351
- package/src/commands/front/pull-conversations.ts +0 -275
- package/src/commands/front/tags.ts +0 -825
- package/src/commands/front-cache.ts +0 -1277
- package/src/commands/front-stats.ts +0 -75
- package/src/commands/health.test.ts +0 -82
- package/src/commands/health.ts +0 -362
- package/src/commands/init.test.ts +0 -89
- package/src/commands/init.ts +0 -106
- package/src/commands/inngest/client.ts +0 -294
- package/src/commands/inngest/events.ts +0 -296
- package/src/commands/inngest/investigate.ts +0 -382
- package/src/commands/inngest/runs.ts +0 -149
- package/src/commands/inngest/signal.ts +0 -143
- package/src/commands/kb-sync.ts +0 -498
- package/src/commands/memory/find.ts +0 -135
- package/src/commands/memory/get.ts +0 -87
- package/src/commands/memory/index.ts +0 -97
- package/src/commands/memory/stats.ts +0 -163
- package/src/commands/memory/store.ts +0 -49
- package/src/commands/memory/vote.ts +0 -159
- package/src/commands/pipeline.ts +0 -127
- package/src/commands/responses.ts +0 -856
- package/src/commands/tools.ts +0 -293
- package/src/commands/wizard.ts +0 -319
- package/src/index.ts +0 -172
- package/src/lib/crypto.ts +0 -56
- package/src/lib/env-loader.ts +0 -206
- package/src/lib/onepassword.ts +0 -137
- package/src/test-agent-local.ts +0 -115
- package/tsconfig.json +0 -11
- package/vitest.config.ts +0 -10
|
@@ -1,492 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Real tool implementations for eval-pipeline CLI
|
|
3
|
-
*
|
|
4
|
-
* Unlike mock tools, these actually hit Docker MySQL and Qdrant
|
|
5
|
-
* for production-like eval behavior.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import {
|
|
9
|
-
type OllamaClient,
|
|
10
|
-
createOllamaClient,
|
|
11
|
-
} from '@skillrecordings/core/adapters/ollama'
|
|
12
|
-
import {
|
|
13
|
-
type QdrantClient,
|
|
14
|
-
createQdrantClient,
|
|
15
|
-
} from '@skillrecordings/core/adapters/qdrant'
|
|
16
|
-
import { tool } from 'ai'
|
|
17
|
-
import type { Pool } from 'mysql2/promise'
|
|
18
|
-
import { createPool } from 'mysql2/promise'
|
|
19
|
-
import { z } from 'zod'
|
|
20
|
-
|
|
21
|
-
let mysqlPool: Pool | null = null
|
|
22
|
-
let qdrantClient: QdrantClient | null = null
|
|
23
|
-
let ollamaClient: OllamaClient | null = null
|
|
24
|
-
|
|
25
|
-
export interface RealToolsConfig {
|
|
26
|
-
mysql?: {
|
|
27
|
-
host: string
|
|
28
|
-
port: number
|
|
29
|
-
user: string
|
|
30
|
-
password: string
|
|
31
|
-
database: string
|
|
32
|
-
}
|
|
33
|
-
qdrant?: {
|
|
34
|
-
url: string
|
|
35
|
-
collection: string
|
|
36
|
-
}
|
|
37
|
-
ollama?: {
|
|
38
|
-
url: string
|
|
39
|
-
model: string
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const DEFAULT_CONFIG: RealToolsConfig = {
|
|
44
|
-
mysql: {
|
|
45
|
-
host: process.env.MYSQL_HOST || 'localhost',
|
|
46
|
-
port: parseInt(process.env.MYSQL_PORT || '3306', 10),
|
|
47
|
-
user: process.env.MYSQL_USER || 'eval_user',
|
|
48
|
-
password: process.env.MYSQL_PASSWORD || 'eval_pass',
|
|
49
|
-
database: process.env.MYSQL_DATABASE || 'support_eval',
|
|
50
|
-
},
|
|
51
|
-
qdrant: {
|
|
52
|
-
url: process.env.QDRANT_URL || 'http://localhost:6333',
|
|
53
|
-
collection: process.env.QDRANT_COLLECTION || 'support_eval',
|
|
54
|
-
},
|
|
55
|
-
ollama: {
|
|
56
|
-
url: process.env.OLLAMA_BASE_URL || 'http://localhost:11434',
|
|
57
|
-
model: process.env.EMBEDDING_MODEL || 'nomic-embed-text',
|
|
58
|
-
},
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Initialize connections to Docker services
|
|
63
|
-
*/
|
|
64
|
-
export async function initRealTools(
|
|
65
|
-
config: RealToolsConfig = DEFAULT_CONFIG,
|
|
66
|
-
verbose = false
|
|
67
|
-
): Promise<{ mysql: boolean; qdrant: boolean; ollama: boolean }> {
|
|
68
|
-
const status = { mysql: false, qdrant: false, ollama: false }
|
|
69
|
-
|
|
70
|
-
// MySQL
|
|
71
|
-
if (config.mysql) {
|
|
72
|
-
try {
|
|
73
|
-
mysqlPool = createPool({
|
|
74
|
-
...config.mysql,
|
|
75
|
-
waitForConnections: true,
|
|
76
|
-
connectionLimit: 5,
|
|
77
|
-
})
|
|
78
|
-
const conn = await mysqlPool.getConnection()
|
|
79
|
-
await conn.ping()
|
|
80
|
-
conn.release()
|
|
81
|
-
status.mysql = true
|
|
82
|
-
if (verbose) console.log(' ✅ MySQL connected')
|
|
83
|
-
} catch (error) {
|
|
84
|
-
if (verbose)
|
|
85
|
-
console.log(
|
|
86
|
-
` ❌ MySQL: ${error instanceof Error ? error.message : 'failed'}`
|
|
87
|
-
)
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// Qdrant
|
|
92
|
-
if (config.qdrant) {
|
|
93
|
-
try {
|
|
94
|
-
qdrantClient = createQdrantClient()
|
|
95
|
-
const info = await qdrantClient.getCollectionInfo()
|
|
96
|
-
status.qdrant = info.status !== 'not_found'
|
|
97
|
-
if (verbose)
|
|
98
|
-
console.log(` ✅ Qdrant connected (${info.pointsCount} points)`)
|
|
99
|
-
} catch (error) {
|
|
100
|
-
if (verbose)
|
|
101
|
-
console.log(
|
|
102
|
-
` ❌ Qdrant: ${error instanceof Error ? error.message : 'failed'}`
|
|
103
|
-
)
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// Ollama (for embeddings)
|
|
108
|
-
if (config.ollama) {
|
|
109
|
-
try {
|
|
110
|
-
ollamaClient = createOllamaClient()
|
|
111
|
-
const healthy = await ollamaClient.healthCheck()
|
|
112
|
-
if (healthy) {
|
|
113
|
-
const available = await ollamaClient.isModelAvailable()
|
|
114
|
-
if (available) {
|
|
115
|
-
status.ollama = true
|
|
116
|
-
if (verbose) console.log(' ✅ Ollama connected')
|
|
117
|
-
} else {
|
|
118
|
-
if (verbose) console.log(' ⚠️ Ollama healthy but model not available')
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
} catch (error) {
|
|
122
|
-
if (verbose)
|
|
123
|
-
console.log(
|
|
124
|
-
` ❌ Ollama: ${error instanceof Error ? error.message : 'failed'}`
|
|
125
|
-
)
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
return status
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Clean up connections
|
|
134
|
-
*/
|
|
135
|
-
export async function cleanupRealTools(): Promise<void> {
|
|
136
|
-
if (mysqlPool) {
|
|
137
|
-
await mysqlPool.end()
|
|
138
|
-
mysqlPool = null
|
|
139
|
-
}
|
|
140
|
-
qdrantClient = null
|
|
141
|
-
ollamaClient = null
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Get embedding for text using Ollama
|
|
146
|
-
*/
|
|
147
|
-
async function embed(text: string): Promise<number[]> {
|
|
148
|
-
if (!ollamaClient) {
|
|
149
|
-
throw new Error('Ollama client not initialized')
|
|
150
|
-
}
|
|
151
|
-
return ollamaClient.embed(text)
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* Create real tools that query Docker services
|
|
156
|
-
*/
|
|
157
|
-
export function createRealTools(scenario: {
|
|
158
|
-
appId?: string
|
|
159
|
-
customerEmail?: string
|
|
160
|
-
}) {
|
|
161
|
-
const appId = scenario.appId || 'total-typescript'
|
|
162
|
-
const customerEmail = scenario.customerEmail || '[EMAIL]'
|
|
163
|
-
|
|
164
|
-
return {
|
|
165
|
-
lookupUser: tool({
|
|
166
|
-
description: 'Look up user by email in the product database',
|
|
167
|
-
inputSchema: z.object({
|
|
168
|
-
email: z.string().describe('Customer email address'),
|
|
169
|
-
appId: z.string().describe('App/product identifier'),
|
|
170
|
-
}),
|
|
171
|
-
execute: async ({ email, appId: queryAppId }) => {
|
|
172
|
-
if (!mysqlPool) {
|
|
173
|
-
return { found: false, error: 'MySQL not connected' }
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
try {
|
|
177
|
-
// Look up customer in conversations table
|
|
178
|
-
const [convRows] = (await mysqlPool.query(
|
|
179
|
-
`SELECT DISTINCT customer_email, customer_name
|
|
180
|
-
FROM SUPPORT_conversations
|
|
181
|
-
WHERE customer_email = ? AND (app_id = ? OR app_id IS NULL)
|
|
182
|
-
LIMIT 1`,
|
|
183
|
-
[email, queryAppId]
|
|
184
|
-
)) as any[]
|
|
185
|
-
|
|
186
|
-
if (convRows.length > 0) {
|
|
187
|
-
return {
|
|
188
|
-
found: true,
|
|
189
|
-
user: {
|
|
190
|
-
id: `user_${email.split('@')[0]}`,
|
|
191
|
-
email: convRows[0].customer_email,
|
|
192
|
-
name: convRows[0].customer_name || 'Customer',
|
|
193
|
-
},
|
|
194
|
-
purchases: [
|
|
195
|
-
{
|
|
196
|
-
id: `purch_${Date.now()}`,
|
|
197
|
-
product:
|
|
198
|
-
queryAppId === 'ai-hero'
|
|
199
|
-
? 'AI Hero Workshop'
|
|
200
|
-
: 'Total TypeScript',
|
|
201
|
-
date: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000)
|
|
202
|
-
.toISOString()
|
|
203
|
-
.split('T')[0],
|
|
204
|
-
status: 'active',
|
|
205
|
-
},
|
|
206
|
-
],
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
return {
|
|
211
|
-
found: false,
|
|
212
|
-
user: null,
|
|
213
|
-
purchases: [],
|
|
214
|
-
}
|
|
215
|
-
} catch (error) {
|
|
216
|
-
console.error('lookupUser error:', error)
|
|
217
|
-
return { found: false, error: String(error) }
|
|
218
|
-
}
|
|
219
|
-
},
|
|
220
|
-
}),
|
|
221
|
-
|
|
222
|
-
searchKnowledge: tool({
|
|
223
|
-
description: 'Search the knowledge base for relevant information',
|
|
224
|
-
inputSchema: z.object({
|
|
225
|
-
query: z.string().describe('Search query'),
|
|
226
|
-
appId: z.string().describe('App/product identifier'),
|
|
227
|
-
}),
|
|
228
|
-
execute: async ({ query, appId: queryAppId }) => {
|
|
229
|
-
if (!qdrantClient || !ollamaClient) {
|
|
230
|
-
return { similarTickets: [], knowledge: [], goodResponses: [] }
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
try {
|
|
234
|
-
const queryVector = await embed(query)
|
|
235
|
-
|
|
236
|
-
// Search with app filter
|
|
237
|
-
const results = await qdrantClient.search(queryVector, 5, {
|
|
238
|
-
should: [
|
|
239
|
-
{ key: 'app', match: { value: queryAppId } },
|
|
240
|
-
{ key: 'app', match: { value: 'general' } },
|
|
241
|
-
],
|
|
242
|
-
})
|
|
243
|
-
|
|
244
|
-
return {
|
|
245
|
-
similarTickets: results
|
|
246
|
-
.filter((r) => r.payload?.type === 'ticket')
|
|
247
|
-
.map((r) => ({
|
|
248
|
-
data: r.payload?.content as string,
|
|
249
|
-
score: r.score,
|
|
250
|
-
})),
|
|
251
|
-
knowledge: results
|
|
252
|
-
.filter(
|
|
253
|
-
(r) =>
|
|
254
|
-
r.payload?.type === 'knowledge' ||
|
|
255
|
-
r.payload?.type === 'general' ||
|
|
256
|
-
r.payload?.type === 'faq'
|
|
257
|
-
)
|
|
258
|
-
.map((r) => ({
|
|
259
|
-
data: r.payload?.content as string,
|
|
260
|
-
score: r.score,
|
|
261
|
-
})),
|
|
262
|
-
goodResponses: results
|
|
263
|
-
.filter((r) => r.payload?.type === 'response')
|
|
264
|
-
.map((r) => ({
|
|
265
|
-
data: r.payload?.content as string,
|
|
266
|
-
score: r.score,
|
|
267
|
-
})),
|
|
268
|
-
}
|
|
269
|
-
} catch (error) {
|
|
270
|
-
console.error('searchKnowledge error:', error)
|
|
271
|
-
return { similarTickets: [], knowledge: [], goodResponses: [] }
|
|
272
|
-
}
|
|
273
|
-
},
|
|
274
|
-
}),
|
|
275
|
-
|
|
276
|
-
searchProductContent: tool({
|
|
277
|
-
description: 'Search product content (courses, tutorials, etc)',
|
|
278
|
-
inputSchema: z.object({
|
|
279
|
-
query: z.string().describe('Search query'),
|
|
280
|
-
}),
|
|
281
|
-
execute: async ({ query }) => {
|
|
282
|
-
if (!qdrantClient || !ollamaClient) {
|
|
283
|
-
return { results: [] }
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
try {
|
|
287
|
-
const queryVector = await embed(query)
|
|
288
|
-
const results = await qdrantClient.search(queryVector, 3)
|
|
289
|
-
|
|
290
|
-
return {
|
|
291
|
-
results: results
|
|
292
|
-
.filter((r) => r.payload?.type === 'content')
|
|
293
|
-
.map((r) => ({
|
|
294
|
-
title: r.payload?.title as string,
|
|
295
|
-
type: (r.payload?.content_type as string) || 'course',
|
|
296
|
-
url: r.payload?.url as string,
|
|
297
|
-
})),
|
|
298
|
-
}
|
|
299
|
-
} catch {
|
|
300
|
-
return { results: [] }
|
|
301
|
-
}
|
|
302
|
-
},
|
|
303
|
-
}),
|
|
304
|
-
|
|
305
|
-
draftResponse: tool({
|
|
306
|
-
description: 'Draft a response to send to the customer',
|
|
307
|
-
inputSchema: z.object({
|
|
308
|
-
body: z.string().describe('The response body to draft'),
|
|
309
|
-
}),
|
|
310
|
-
execute: async ({ body }) => {
|
|
311
|
-
return { drafted: true, body }
|
|
312
|
-
},
|
|
313
|
-
}),
|
|
314
|
-
|
|
315
|
-
escalateToHuman: tool({
|
|
316
|
-
description: 'Escalate the conversation to human support',
|
|
317
|
-
inputSchema: z.object({
|
|
318
|
-
reason: z.string().describe('Reason for escalation'),
|
|
319
|
-
urgency: z.enum(['low', 'medium', 'high']).describe('Urgency level'),
|
|
320
|
-
}),
|
|
321
|
-
execute: async ({ reason, urgency }) => {
|
|
322
|
-
return { escalated: true, reason, urgency }
|
|
323
|
-
},
|
|
324
|
-
}),
|
|
325
|
-
|
|
326
|
-
assignToInstructor: tool({
|
|
327
|
-
description:
|
|
328
|
-
'Assign conversation to instructor for personal correspondence',
|
|
329
|
-
inputSchema: z.object({
|
|
330
|
-
conversationId: z.string(),
|
|
331
|
-
reason: z.string(),
|
|
332
|
-
}),
|
|
333
|
-
execute: async ({ conversationId, reason }) => ({
|
|
334
|
-
status: 'pending_approval',
|
|
335
|
-
conversationId,
|
|
336
|
-
reason,
|
|
337
|
-
message: 'Instructor assignment submitted for approval',
|
|
338
|
-
}),
|
|
339
|
-
}),
|
|
340
|
-
|
|
341
|
-
processRefund: tool({
|
|
342
|
-
description: 'Process a refund for a purchase',
|
|
343
|
-
inputSchema: z.object({
|
|
344
|
-
purchaseId: z.string(),
|
|
345
|
-
appId: z.string(),
|
|
346
|
-
reason: z.string(),
|
|
347
|
-
}),
|
|
348
|
-
execute: async ({ purchaseId, reason }) => ({
|
|
349
|
-
status: 'pending_approval',
|
|
350
|
-
purchaseId,
|
|
351
|
-
reason,
|
|
352
|
-
message: 'Refund submitted for approval',
|
|
353
|
-
}),
|
|
354
|
-
}),
|
|
355
|
-
|
|
356
|
-
transferPurchase: tool({
|
|
357
|
-
description: 'Transfer purchase to another email',
|
|
358
|
-
inputSchema: z.object({
|
|
359
|
-
purchaseId: z.string(),
|
|
360
|
-
appId: z.string(),
|
|
361
|
-
fromUserId: z.string(),
|
|
362
|
-
toEmail: z.string(),
|
|
363
|
-
reason: z.string(),
|
|
364
|
-
}),
|
|
365
|
-
execute: async () => ({
|
|
366
|
-
status: 'pending_approval',
|
|
367
|
-
message: 'Transfer submitted for approval',
|
|
368
|
-
}),
|
|
369
|
-
}),
|
|
370
|
-
|
|
371
|
-
getPaymentHistory: tool({
|
|
372
|
-
description: 'Get payment history from Stripe',
|
|
373
|
-
inputSchema: z.object({
|
|
374
|
-
customerEmail: z.string(),
|
|
375
|
-
limit: z.number().optional(),
|
|
376
|
-
}),
|
|
377
|
-
execute: async ({ customerEmail: email }) => {
|
|
378
|
-
if (!mysqlPool) {
|
|
379
|
-
return { charges: [] }
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
try {
|
|
383
|
-
const [rows] = (await mysqlPool.query(
|
|
384
|
-
`SELECT 1 FROM SUPPORT_conversations WHERE customer_email = ? LIMIT 1`,
|
|
385
|
-
[email]
|
|
386
|
-
)) as any[]
|
|
387
|
-
|
|
388
|
-
if (rows.length > 0) {
|
|
389
|
-
return {
|
|
390
|
-
charges: [
|
|
391
|
-
{
|
|
392
|
-
id: `ch_eval_${Date.now()}`,
|
|
393
|
-
amount: 24900,
|
|
394
|
-
status: 'succeeded',
|
|
395
|
-
created: Date.now() - 7 * 24 * 60 * 60 * 1000,
|
|
396
|
-
},
|
|
397
|
-
],
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
return { charges: [] }
|
|
402
|
-
} catch {
|
|
403
|
-
return { charges: [] }
|
|
404
|
-
}
|
|
405
|
-
},
|
|
406
|
-
}),
|
|
407
|
-
|
|
408
|
-
check_product_availability: tool({
|
|
409
|
-
description: 'Check if product is available or sold out',
|
|
410
|
-
inputSchema: z.object({
|
|
411
|
-
productId: z.string().optional(),
|
|
412
|
-
appId: z.string(),
|
|
413
|
-
}),
|
|
414
|
-
execute: async () => ({
|
|
415
|
-
soldOut: false,
|
|
416
|
-
quantityRemaining: -1,
|
|
417
|
-
enrollmentOpen: true,
|
|
418
|
-
}),
|
|
419
|
-
}),
|
|
420
|
-
|
|
421
|
-
memory_search: tool({
|
|
422
|
-
description: 'Search semantic memory',
|
|
423
|
-
inputSchema: z.object({ query: z.string() }),
|
|
424
|
-
execute: async () => ({ results: [], total: 0 }),
|
|
425
|
-
}),
|
|
426
|
-
|
|
427
|
-
memory_store: tool({
|
|
428
|
-
description: 'Store learning in memory',
|
|
429
|
-
inputSchema: z.object({
|
|
430
|
-
content: z.string(),
|
|
431
|
-
tags: z.array(z.string()).optional(),
|
|
432
|
-
}),
|
|
433
|
-
execute: async () => ({ stored: true, id: 'mem_eval_1' }),
|
|
434
|
-
}),
|
|
435
|
-
|
|
436
|
-
memory_vote: tool({
|
|
437
|
-
description: 'Vote on memory usefulness',
|
|
438
|
-
inputSchema: z.object({
|
|
439
|
-
memoryId: z.string(),
|
|
440
|
-
vote: z.enum(['up', 'down']),
|
|
441
|
-
}),
|
|
442
|
-
execute: async () => ({ success: true }),
|
|
443
|
-
}),
|
|
444
|
-
|
|
445
|
-
memory_cite: tool({
|
|
446
|
-
description: 'Cite a memory as used',
|
|
447
|
-
inputSchema: z.object({ memoryId: z.string() }),
|
|
448
|
-
execute: async () => ({ cited: true }),
|
|
449
|
-
}),
|
|
450
|
-
|
|
451
|
-
getSubscriptionStatus: tool({
|
|
452
|
-
description: 'Get subscription status',
|
|
453
|
-
inputSchema: z.object({
|
|
454
|
-
customerId: z.string(),
|
|
455
|
-
stripeAccountId: z.string(),
|
|
456
|
-
}),
|
|
457
|
-
execute: async () => ({ subscription: null }),
|
|
458
|
-
}),
|
|
459
|
-
|
|
460
|
-
lookupCharge: tool({
|
|
461
|
-
description: 'Look up specific charge',
|
|
462
|
-
inputSchema: z.object({ chargeId: z.string() }),
|
|
463
|
-
execute: async ({ chargeId }) => ({
|
|
464
|
-
charge: {
|
|
465
|
-
id: chargeId,
|
|
466
|
-
amount: 24900,
|
|
467
|
-
status: 'succeeded',
|
|
468
|
-
refunded: false,
|
|
469
|
-
},
|
|
470
|
-
}),
|
|
471
|
-
}),
|
|
472
|
-
|
|
473
|
-
verifyRefund: tool({
|
|
474
|
-
description: 'Verify refund status',
|
|
475
|
-
inputSchema: z.object({ refundId: z.string() }),
|
|
476
|
-
execute: async ({ refundId }) => ({
|
|
477
|
-
refund: {
|
|
478
|
-
id: refundId,
|
|
479
|
-
status: 'succeeded',
|
|
480
|
-
amount: 24900,
|
|
481
|
-
},
|
|
482
|
-
}),
|
|
483
|
-
}),
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
/**
|
|
488
|
-
* Check if real tools are available
|
|
489
|
-
*/
|
|
490
|
-
export function isRealToolsAvailable(): boolean {
|
|
491
|
-
return mysqlPool !== null && qdrantClient !== null
|
|
492
|
-
}
|