@trikhub/cli 0.17.0 → 0.17.1-dev.1
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/README.md +1 -0
- package/dist/cli.js +1 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/create-agent.d.ts.map +1 -1
- package/dist/commands/create-agent.js +30 -3
- package/dist/commands/create-agent.js.map +1 -1
- package/dist/commands/install.d.ts +1 -0
- package/dist/commands/install.d.ts.map +1 -1
- package/dist/commands/install.js +155 -1
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/publish.js +1 -1
- package/dist/commands/publish.js.map +1 -1
- package/dist/lib/registry.d.ts.map +1 -1
- package/dist/lib/registry.js +1 -0
- package/dist/lib/registry.js.map +1 -1
- package/dist/lib/validator.d.ts +13 -0
- package/dist/lib/validator.d.ts.map +1 -0
- package/dist/lib/validator.js +12 -0
- package/dist/lib/validator.js.map +1 -0
- package/dist/templates/agent-python.d.ts.map +1 -1
- package/dist/templates/agent-python.js +219 -26
- package/dist/templates/agent-python.js.map +1 -1
- package/dist/templates/agent-typescript.d.ts +1 -0
- package/dist/templates/agent-typescript.d.ts.map +1 -1
- package/dist/templates/agent-typescript.js +220 -36
- package/dist/templates/agent-typescript.js.map +1 -1
- package/dist/templates/typescript.d.ts.map +1 -1
- package/dist/templates/typescript.js +5 -8
- package/dist/templates/typescript.js.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +12 -12
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @deprecated Use @trikhub/linter instead.
|
|
3
|
+
*
|
|
4
|
+
* v1 validator removed in P1. All validation now through @trikhub/linter.
|
|
5
|
+
*/
|
|
6
|
+
export interface ValidationResult {
|
|
7
|
+
valid: boolean;
|
|
8
|
+
errors: string[];
|
|
9
|
+
warnings: string[];
|
|
10
|
+
}
|
|
11
|
+
export declare function validateTrik(_trikPath: string): ValidationResult;
|
|
12
|
+
export declare function formatValidationResult(result: ValidationResult): string;
|
|
13
|
+
//# sourceMappingURL=validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/lib/validator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB,CAEhE;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAEvE"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @deprecated Use @trikhub/linter instead.
|
|
3
|
+
*
|
|
4
|
+
* v1 validator removed in P1. All validation now through @trikhub/linter.
|
|
5
|
+
*/
|
|
6
|
+
export function validateTrik(_trikPath) {
|
|
7
|
+
return { valid: true, errors: [], warnings: [] };
|
|
8
|
+
}
|
|
9
|
+
export function formatValidationResult(result) {
|
|
10
|
+
return result.valid ? 'Validation passed' : 'Validation failed';
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/lib/validator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,MAAM,UAAU,YAAY,CAAC,SAAiB;IAC5C,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,MAAwB;IAC7D,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,mBAAmB,CAAC;AAClE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-python.d.ts","sourceRoot":"","sources":["../../src/templates/agent-python.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"agent-python.d.ts","sourceRoot":"","sources":["../../src/templates/agent-python.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AA+X/D;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAgB5F"}
|
|
@@ -47,13 +47,17 @@ dependencies = [
|
|
|
47
47
|
"langchain-core>=0.3.0",
|
|
48
48
|
"langgraph>=0.2.0",
|
|
49
49
|
"trikhub>=0.6.0",
|
|
50
|
-
"python-dotenv>=1.0.0"
|
|
50
|
+
"python-dotenv>=1.0.0",${config.channels === 'cli+telegram' ? `\n "python-telegram-bot>=21.0",` : ''}
|
|
51
51
|
]
|
|
52
52
|
`;
|
|
53
53
|
}
|
|
54
54
|
function generateEnvExample(config) {
|
|
55
55
|
const provider = PROVIDERS[config.provider];
|
|
56
|
-
|
|
56
|
+
let env = `${provider.envVar}=your-api-key-here\n`;
|
|
57
|
+
if (config.channels === 'cli+telegram') {
|
|
58
|
+
env += `TELEGRAM_BOT_TOKEN=your-token-from-botfather\n`;
|
|
59
|
+
}
|
|
60
|
+
return env;
|
|
57
61
|
}
|
|
58
62
|
function generateGitignore() {
|
|
59
63
|
return `__pycache__/
|
|
@@ -77,32 +81,35 @@ from __future__ import annotations
|
|
|
77
81
|
from ${provider.importPath} import ${provider.className}
|
|
78
82
|
from langgraph.prebuilt import create_react_agent
|
|
79
83
|
|
|
80
|
-
from trikhub.
|
|
81
|
-
|
|
84
|
+
from trikhub.langchain import enhance, EnhanceOptions
|
|
85
|
+
|
|
86
|
+
SYSTEM_PROMPT = """You are a helpful agent spawned by Trikhub. A user has installed you and you are ready to install Triks to help them with various tasks. You can call any tools provided by the installed Triks to assist the user.
|
|
87
|
+
Feel free to propose a few starting Triks that the user should use to test out your capabilitites:
|
|
88
|
+
- @molefas/trikster: The first Trik anyone should have. This allows you to install other Triks, which will expand your capabilities with new tools and handoffs.
|
|
89
|
+
- @molefas/site-builder: A Demo Trik for building websites. It's meant to showcase how Triks can generate files and execute commands in a safe environment (docker container). With this Trik, you can build a static website by describing it to the agent, which will generate the necessary HTML/CSS/JS files and even run a local server for you to preview it.
|
|
90
|
+
- @molefas/trik-hash: A Demo Trik to showcase basic Tool-like triks, with no conversational skill. It provides a simple hashing tool that can hash any input with various algorithms (md5, sha256, etc). It's a great starting point to understand how to call tools from your agent.
|
|
91
|
+
- @molefas/ghost-writer: A Demo Trik to showcase persistent storage capabilitites and how a full-fledged Trik can be. It also exposes a web interface for users to interact with their data.
|
|
92
|
+
|
|
93
|
+
Other useful tips:
|
|
94
|
+
- Users can do trik list to see installed triks and trik search <query> to find new ones.
|
|
95
|
+
- Users can refer to the Trikhub documentation at https://docs.trikhub.com for more details on how to use and create triks.
|
|
96
|
+
- If you've chosen the Telegram installation, check the readme for instructions on how to interact with your agent via Telegram.
|
|
82
97
|
|
|
83
|
-
SYSTEM_PROMPT = """You are a helpful assistant.
|
|
84
98
|
When a trik can handle the user's request, use the appropriate tool."""
|
|
85
99
|
|
|
86
100
|
|
|
87
101
|
async def initialize_agent():
|
|
88
102
|
model = ${provider.className}(model="${provider.defaultModel}")
|
|
89
103
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
agent = create_react_agent(
|
|
98
|
-
model=model,
|
|
99
|
-
tools=[*handoff_tools, *exposed_tools],
|
|
100
|
-
prompt=SYSTEM_PROMPT,
|
|
101
|
-
)
|
|
102
|
-
|
|
103
|
-
app = await enhance(agent, gateway_instance=gateway)
|
|
104
|
+
app = await enhance(None, EnhanceOptions(
|
|
105
|
+
create_agent=lambda trik_tools: create_react_agent(
|
|
106
|
+
model=model,
|
|
107
|
+
tools=list(trik_tools),
|
|
108
|
+
prompt=SYSTEM_PROMPT,
|
|
109
|
+
),
|
|
110
|
+
))
|
|
104
111
|
|
|
105
|
-
return app
|
|
112
|
+
return app
|
|
106
113
|
`;
|
|
107
114
|
}
|
|
108
115
|
function generateCliPy() {
|
|
@@ -123,13 +130,13 @@ from agent import initialize_agent
|
|
|
123
130
|
async def main() -> None:
|
|
124
131
|
print("Loading agent...\\n")
|
|
125
132
|
|
|
126
|
-
app
|
|
133
|
+
app = await initialize_agent()
|
|
127
134
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
print('
|
|
135
|
+
loaded_triks = app.get_loaded_triks()
|
|
136
|
+
if loaded_triks:
|
|
137
|
+
print(f"Loaded triks: {', '.join(loaded_triks)}")
|
|
138
|
+
print('Type "/back" to return from a trik handoff, "exit" to quit.')
|
|
139
|
+
print('Tip: Ask the Agent what to do next\\n')
|
|
133
140
|
|
|
134
141
|
session_id = f"cli-{id(app)}"
|
|
135
142
|
|
|
@@ -164,6 +171,188 @@ if __name__ == "__main__":
|
|
|
164
171
|
asyncio.run(main())
|
|
165
172
|
`;
|
|
166
173
|
}
|
|
174
|
+
function generateTelegramPy() {
|
|
175
|
+
return `#!/usr/bin/env python3
|
|
176
|
+
"""Telegram bot for the TrikHub-powered agent."""
|
|
177
|
+
|
|
178
|
+
from __future__ import annotations
|
|
179
|
+
|
|
180
|
+
import asyncio
|
|
181
|
+
import logging
|
|
182
|
+
import os
|
|
183
|
+
import time
|
|
184
|
+
|
|
185
|
+
from dotenv import load_dotenv
|
|
186
|
+
|
|
187
|
+
load_dotenv()
|
|
188
|
+
|
|
189
|
+
from telegram import Update
|
|
190
|
+
from telegram.ext import Application, MessageHandler, filters, ContextTypes
|
|
191
|
+
|
|
192
|
+
from agent import initialize_agent
|
|
193
|
+
|
|
194
|
+
logging.basicConfig(level=logging.INFO)
|
|
195
|
+
logger = logging.getLogger(__name__)
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
async def main() -> None:
|
|
199
|
+
print("Loading agent...\\n")
|
|
200
|
+
|
|
201
|
+
app = await initialize_agent()
|
|
202
|
+
|
|
203
|
+
loaded_triks = app.get_loaded_triks()
|
|
204
|
+
if loaded_triks:
|
|
205
|
+
print(f"Loaded triks: {', '.join(loaded_triks)}")
|
|
206
|
+
|
|
207
|
+
token = os.environ.get("TELEGRAM_BOT_TOKEN")
|
|
208
|
+
if not token:
|
|
209
|
+
print("TELEGRAM_BOT_TOKEN is not set in .env")
|
|
210
|
+
raise SystemExit(1)
|
|
211
|
+
|
|
212
|
+
session_id = f"telegram-{int(time.time())}"
|
|
213
|
+
|
|
214
|
+
async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
|
215
|
+
if not update.message or not update.message.text:
|
|
216
|
+
return
|
|
217
|
+
try:
|
|
218
|
+
result = await app.process_message(update.message.text, session_id)
|
|
219
|
+
await update.message.reply_text(result.message)
|
|
220
|
+
except Exception as e:
|
|
221
|
+
logger.error("Error processing message: %s", e)
|
|
222
|
+
await update.message.reply_text("Something went wrong. Please try again.")
|
|
223
|
+
|
|
224
|
+
application = Application.builder().token(token).build()
|
|
225
|
+
application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_message))
|
|
226
|
+
|
|
227
|
+
print("\\nTelegram bot started! Send a message to your bot.\\n")
|
|
228
|
+
await application.run_polling()
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
if __name__ == "__main__":
|
|
232
|
+
asyncio.run(main())
|
|
233
|
+
`;
|
|
234
|
+
}
|
|
235
|
+
function generateReadme(config) {
|
|
236
|
+
const provider = PROVIDERS[config.provider];
|
|
237
|
+
const hasTelegram = config.channels === 'cli+telegram';
|
|
238
|
+
let readme = `# ${config.name}
|
|
239
|
+
|
|
240
|
+
An AI agent powered by [TrikHub](https://trikhub.com). This agent uses **${provider.className}** and can be extended with triks — composable capabilities that plug into your agent.
|
|
241
|
+
|
|
242
|
+
## What can this agent do?
|
|
243
|
+
|
|
244
|
+
Out of the box, your agent is a general-purpose assistant. Its real power comes from **triks** — install them to give your agent new capabilities:
|
|
245
|
+
|
|
246
|
+
\`\`\`bash
|
|
247
|
+
# Browse and search available triks
|
|
248
|
+
trik search <query>
|
|
249
|
+
|
|
250
|
+
# Install a trik
|
|
251
|
+
trik install @scope/trik-name
|
|
252
|
+
\`\`\`
|
|
253
|
+
|
|
254
|
+
Triks come in two flavors:
|
|
255
|
+
- **Handoff triks** — take over the conversation for a specialized task (e.g. a coding assistant, a travel planner). Use \`/back\` to return.
|
|
256
|
+
- **Tool triks** — appear as native tools the agent can call (e.g. web search, calculator).
|
|
257
|
+
|
|
258
|
+
## Setup
|
|
259
|
+
|
|
260
|
+
\`\`\`bash
|
|
261
|
+
python -m venv .venv
|
|
262
|
+
source .venv/bin/activate # Windows: .venv\\Scripts\\activate
|
|
263
|
+
pip install -e .
|
|
264
|
+
cp .env.example .env
|
|
265
|
+
\`\`\`
|
|
266
|
+
|
|
267
|
+
Add your **${provider.envVar}** to \`.env\`.
|
|
268
|
+
`;
|
|
269
|
+
if (hasTelegram) {
|
|
270
|
+
readme += `
|
|
271
|
+
### Telegram Bot Token
|
|
272
|
+
|
|
273
|
+
To run the Telegram bot, you need a bot token:
|
|
274
|
+
|
|
275
|
+
1. Open Telegram and message [@BotFather](https://t.me/BotFather)
|
|
276
|
+
2. Send \`/newbot\`
|
|
277
|
+
3. Choose a display name (e.g. "${config.name}")
|
|
278
|
+
4. Choose a username (must end in \`bot\`, e.g. \`${config.name.replace(/-/g, '_')}_bot\`)
|
|
279
|
+
5. Copy the token into \`.env\` as \`TELEGRAM_BOT_TOKEN\`
|
|
280
|
+
`;
|
|
281
|
+
}
|
|
282
|
+
readme += `
|
|
283
|
+
## Running
|
|
284
|
+
|
|
285
|
+
### CLI mode
|
|
286
|
+
|
|
287
|
+
\`\`\`bash
|
|
288
|
+
python cli.py
|
|
289
|
+
\`\`\`
|
|
290
|
+
|
|
291
|
+
Chat with your agent in the terminal. Type \`/back\` to return from a trik handoff, \`exit\` to quit.
|
|
292
|
+
`;
|
|
293
|
+
if (hasTelegram) {
|
|
294
|
+
readme += `
|
|
295
|
+
### Telegram mode
|
|
296
|
+
|
|
297
|
+
\`\`\`bash
|
|
298
|
+
python telegram_bot.py
|
|
299
|
+
\`\`\`
|
|
300
|
+
|
|
301
|
+
Your agent runs as a Telegram bot. Open Telegram, find your bot by username, and start chatting.
|
|
302
|
+
|
|
303
|
+
## Keeping your bot running
|
|
304
|
+
|
|
305
|
+
The Telegram bot needs to stay running to receive messages. Here are a few options:
|
|
306
|
+
|
|
307
|
+
### pm2 (Recommended)
|
|
308
|
+
|
|
309
|
+
\`\`\`bash
|
|
310
|
+
npm install -g pm2
|
|
311
|
+
pm2 start python --name "${config.name}" -- telegram_bot.py
|
|
312
|
+
pm2 save
|
|
313
|
+
pm2 startup # auto-start on boot
|
|
314
|
+
\`\`\`
|
|
315
|
+
|
|
316
|
+
### Docker
|
|
317
|
+
|
|
318
|
+
\`\`\`dockerfile
|
|
319
|
+
FROM python:3.12-slim
|
|
320
|
+
WORKDIR /app
|
|
321
|
+
COPY pyproject.toml .
|
|
322
|
+
COPY *.py .
|
|
323
|
+
RUN pip install .
|
|
324
|
+
CMD ["python", "telegram_bot.py"]
|
|
325
|
+
\`\`\`
|
|
326
|
+
|
|
327
|
+
### systemd (Linux VPS)
|
|
328
|
+
|
|
329
|
+
\`\`\`ini
|
|
330
|
+
[Unit]
|
|
331
|
+
Description=${config.name} Telegram bot
|
|
332
|
+
After=network.target
|
|
333
|
+
|
|
334
|
+
[Service]
|
|
335
|
+
ExecStart=/home/user/${config.name}/.venv/bin/python /home/user/${config.name}/telegram_bot.py
|
|
336
|
+
WorkingDirectory=/home/user/${config.name}
|
|
337
|
+
Restart=always
|
|
338
|
+
EnvironmentFile=/home/user/${config.name}/.env
|
|
339
|
+
|
|
340
|
+
[Install]
|
|
341
|
+
WantedBy=multi-user.target
|
|
342
|
+
\`\`\`
|
|
343
|
+
`;
|
|
344
|
+
}
|
|
345
|
+
readme += `
|
|
346
|
+
## Installing triks
|
|
347
|
+
|
|
348
|
+
\`\`\`bash
|
|
349
|
+
trik install @scope/trik-name
|
|
350
|
+
\`\`\`
|
|
351
|
+
|
|
352
|
+
Installed triks are saved to \`.trikhub/config.json\` and loaded automatically when your agent starts.
|
|
353
|
+
`;
|
|
354
|
+
return readme;
|
|
355
|
+
}
|
|
167
356
|
// ============================================================================
|
|
168
357
|
// Public API
|
|
169
358
|
// ============================================================================
|
|
@@ -178,8 +367,12 @@ export function generateAgentPythonProject(config) {
|
|
|
178
367
|
files['.env.example'] = generateEnvExample(config);
|
|
179
368
|
files['.gitignore'] = generateGitignore();
|
|
180
369
|
files['.trikhub/config.json'] = generateTrikhubConfig();
|
|
370
|
+
files['README.md'] = generateReadme(config);
|
|
181
371
|
files['agent.py'] = generateAgentPy(config);
|
|
182
372
|
files['cli.py'] = generateCliPy();
|
|
373
|
+
if (config.channels === 'cli+telegram') {
|
|
374
|
+
files['telegram_bot.py'] = generateTelegramPy();
|
|
375
|
+
}
|
|
183
376
|
return files;
|
|
184
377
|
}
|
|
185
378
|
//# sourceMappingURL=agent-python.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-python.js","sourceRoot":"","sources":["../../src/templates/agent-python.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAgBH,MAAM,SAAS,GAAiC;IAC9C,MAAM,EAAE;QACN,UAAU,EAAE,kBAAkB;QAC9B,SAAS,EAAE,YAAY;QACvB,UAAU,EAAE,kBAAkB;QAC9B,YAAY,EAAE,aAAa;QAC3B,MAAM,EAAE,gBAAgB;KACzB;IACD,SAAS,EAAE;QACT,UAAU,EAAE,qBAAqB;QACjC,SAAS,EAAE,eAAe;QAC1B,UAAU,EAAE,qBAAqB;QACjC,YAAY,EAAE,0BAA0B;QACxC,MAAM,EAAE,mBAAmB;KAC5B;IACD,MAAM,EAAE;QACN,UAAU,EAAE,wBAAwB;QACpC,SAAS,EAAE,wBAAwB;QACnC,UAAU,EAAE,wBAAwB;QACpC,YAAY,EAAE,kBAAkB;QAChC,MAAM,EAAE,gBAAgB;KACzB;CACF,CAAC;AAEF,+EAA+E;AAC/E,kBAAkB;AAClB,+EAA+E;AAE/E,SAAS,qBAAqB,CAAC,MAAyB;IACtD,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC5C,OAAO;;;;;UAKC,MAAM,CAAC,IAAI;;;;;;OAMd,QAAQ,CAAC,UAAU
|
|
1
|
+
{"version":3,"file":"agent-python.js","sourceRoot":"","sources":["../../src/templates/agent-python.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-typescript.d.ts","sourceRoot":"","sources":["../../src/templates/agent-typescript.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,QAAQ,GAAG,WAAW,GAAG,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"agent-typescript.d.ts","sourceRoot":"","sources":["../../src/templates/agent-typescript.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,QAAQ,GAAG,WAAW,GAAG,QAAQ,CAAC;IAC5C,QAAQ,CAAC,EAAE,KAAK,GAAG,cAAc,CAAC;CACnC;AA8YD;;;;GAIG;AACH,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAiBhG"}
|
|
@@ -33,22 +33,31 @@ const PROVIDERS = {
|
|
|
33
33
|
// ============================================================================
|
|
34
34
|
function generatePackageJson(config) {
|
|
35
35
|
const provider = PROVIDERS[config.provider];
|
|
36
|
+
const hasTelegram = config.channels === 'cli+telegram';
|
|
37
|
+
const scripts = {
|
|
38
|
+
dev: 'node --import tsx src/cli.ts',
|
|
39
|
+
build: 'tsc',
|
|
40
|
+
};
|
|
41
|
+
if (hasTelegram) {
|
|
42
|
+
scripts.telegram = 'node --import tsx src/telegram.ts';
|
|
43
|
+
}
|
|
44
|
+
const dependencies = {
|
|
45
|
+
[provider.npmPackage]: '^1.0.0',
|
|
46
|
+
'@langchain/core': '^1.0.0',
|
|
47
|
+
'@langchain/langgraph': '^1.0.0',
|
|
48
|
+
'@trikhub/gateway': 'latest',
|
|
49
|
+
dotenv: '^16.4.0',
|
|
50
|
+
};
|
|
51
|
+
if (hasTelegram) {
|
|
52
|
+
dependencies.grammy = '^1.0.0';
|
|
53
|
+
}
|
|
36
54
|
const pkg = {
|
|
37
55
|
name: config.name,
|
|
38
56
|
version: '0.1.0',
|
|
39
57
|
description: 'AI agent powered by TrikHub',
|
|
40
58
|
type: 'module',
|
|
41
|
-
scripts
|
|
42
|
-
|
|
43
|
-
build: 'tsc',
|
|
44
|
-
},
|
|
45
|
-
dependencies: {
|
|
46
|
-
[provider.npmPackage]: '^1.0.0',
|
|
47
|
-
'@langchain/core': '^1.0.0',
|
|
48
|
-
'@langchain/langgraph': '^1.0.0',
|
|
49
|
-
'@trikhub/gateway': 'latest',
|
|
50
|
-
dotenv: '^16.4.0',
|
|
51
|
-
},
|
|
59
|
+
scripts,
|
|
60
|
+
dependencies,
|
|
52
61
|
devDependencies: {
|
|
53
62
|
tsx: '^4.19.0',
|
|
54
63
|
typescript: '^5.7.0',
|
|
@@ -76,7 +85,11 @@ function generateTsConfig() {
|
|
|
76
85
|
}
|
|
77
86
|
function generateEnvExample(config) {
|
|
78
87
|
const provider = PROVIDERS[config.provider];
|
|
79
|
-
|
|
88
|
+
let env = `${provider.envVar}=your-api-key-here\n`;
|
|
89
|
+
if (config.channels === 'cli+telegram') {
|
|
90
|
+
env += `TELEGRAM_BOT_TOKEN=your-token-from-botfather\n`;
|
|
91
|
+
}
|
|
92
|
+
return env;
|
|
80
93
|
}
|
|
81
94
|
function generateGitignore() {
|
|
82
95
|
return `node_modules/
|
|
@@ -94,31 +107,35 @@ function generateAgentTs(config) {
|
|
|
94
107
|
const modelParam = config.provider === 'anthropic' ? 'modelName' : 'model';
|
|
95
108
|
return `import { ${provider.className} } from '${provider.importPath}';
|
|
96
109
|
import { createReactAgent } from '@langchain/langgraph/prebuilt';
|
|
97
|
-
import {
|
|
98
|
-
|
|
110
|
+
import { enhance } from '@trikhub/gateway/langchain';
|
|
111
|
+
|
|
112
|
+
const SYSTEM_PROMPT = \`You are a helpful agent spawned by Trikhub. A user has installed you and you are ready to install Triks to help them with various tasks. You can call any tools provided by the installed Triks to assist the user.
|
|
113
|
+
Feel free to propose a few starting Triks that the user should use to test out your capabilitites:
|
|
114
|
+
- @molefas/trikster: The first Trik anyone should have. This allows you to install other Triks, which will expand your capabilities with new tools and handoffs.
|
|
115
|
+
- @molefas/site-builder: A Demo Trik for building websites. It's meant to showcase how Triks can generate files and execute commands in a safe environment (docker container). With this Trik, you can build a static website by describing it to the agent, which will generate the necessary HTML/CSS/JS files and even run a local server for you to preview it.
|
|
116
|
+
- @molefas/trik-hash: A Demo Trik to showcase basic Tool-like triks, with no conversational skill. It provides a simple hashing tool that can hash any input with various algorithms (md5, sha256, etc). It's a great starting point to understand how to call tools from your agent.
|
|
117
|
+
- @molefas/ghost-writer: A Demo Trik to showcase persistent storage capabilitites and how a full-fledged Trik can be. It also exposes a web interface for users to interact with their data.
|
|
118
|
+
|
|
119
|
+
Other useful tips:
|
|
120
|
+
- Users can do trik list to see installed triks and trik search <query> to find new ones.
|
|
121
|
+
- Users can refer to the Trikhub documentation at https://docs.trikhub.com for more details on how to use and create triks.
|
|
122
|
+
- If you've chosen the Telegram installation, check the readme for instructions on how to interact with your agent via Telegram.
|
|
99
123
|
|
|
100
|
-
const SYSTEM_PROMPT = \`You are a helpful assistant.
|
|
101
124
|
When a trik can handle the user's request, use the appropriate tool.\`;
|
|
102
125
|
|
|
103
126
|
export async function initializeAgent() {
|
|
104
127
|
const model = new ${provider.className}({ ${modelParam}: '${provider.defaultModel}' });
|
|
105
128
|
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
const agent = createReactAgent({
|
|
114
|
-
llm: model,
|
|
115
|
-
tools: [...handoffTools, ...exposedTools] as any,
|
|
116
|
-
messageModifier: SYSTEM_PROMPT,
|
|
129
|
+
const app = await enhance(null, {
|
|
130
|
+
createAgent: (trikTools) =>
|
|
131
|
+
createReactAgent({
|
|
132
|
+
llm: model,
|
|
133
|
+
tools: [...trikTools] as any,
|
|
134
|
+
messageModifier: SYSTEM_PROMPT,
|
|
135
|
+
}),
|
|
117
136
|
});
|
|
118
137
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
return { app, handoffTools, exposedTools };
|
|
138
|
+
return app;
|
|
122
139
|
}
|
|
123
140
|
`;
|
|
124
141
|
}
|
|
@@ -141,15 +158,14 @@ function prompt(question: string): Promise<string> {
|
|
|
141
158
|
async function main() {
|
|
142
159
|
console.log('Loading agent...\\n');
|
|
143
160
|
|
|
144
|
-
const
|
|
161
|
+
const app = await initializeAgent();
|
|
145
162
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
if (exposedTools.length > 0) {
|
|
150
|
-
console.log(\`Tool-mode triks: \${exposedTools.map((t) => t.name).join(', ')}\`);
|
|
163
|
+
const loadedTriks = app.getLoadedTriks();
|
|
164
|
+
if (loadedTriks.length > 0) {
|
|
165
|
+
console.log(\`Loaded triks: \${loadedTriks.join(', ')}\`);
|
|
151
166
|
}
|
|
152
|
-
console.log('Type "/back" to return from a trik handoff, "exit" to quit
|
|
167
|
+
console.log('Type "/back" to return from a trik handoff, "exit" to quit.');
|
|
168
|
+
console.log('Tip: Ask the Agent what to do next\\n');
|
|
153
169
|
|
|
154
170
|
const sessionId = \`cli-\${Date.now()}\`;
|
|
155
171
|
|
|
@@ -187,6 +203,170 @@ main().catch((error) => {
|
|
|
187
203
|
});
|
|
188
204
|
`;
|
|
189
205
|
}
|
|
206
|
+
function generateTelegramTs() {
|
|
207
|
+
return `import 'dotenv/config';
|
|
208
|
+
import { Bot } from 'grammy';
|
|
209
|
+
import { initializeAgent } from './agent.js';
|
|
210
|
+
|
|
211
|
+
async function main() {
|
|
212
|
+
console.log('Loading agent...\\n');
|
|
213
|
+
|
|
214
|
+
const app = await initializeAgent();
|
|
215
|
+
|
|
216
|
+
const loadedTriks = app.getLoadedTriks();
|
|
217
|
+
if (loadedTriks.length > 0) {
|
|
218
|
+
console.log(\`Loaded triks: \${loadedTriks.join(', ')}\`);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const token = process.env.TELEGRAM_BOT_TOKEN;
|
|
222
|
+
if (!token) {
|
|
223
|
+
console.error('TELEGRAM_BOT_TOKEN is not set in .env');
|
|
224
|
+
process.exit(1);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
const bot = new Bot(token);
|
|
228
|
+
const sessionId = \`telegram-\${Date.now()}\`;
|
|
229
|
+
|
|
230
|
+
bot.on('message:text', async (ctx) => {
|
|
231
|
+
try {
|
|
232
|
+
const result = await app.processMessage(ctx.message.text, sessionId);
|
|
233
|
+
await ctx.reply(result.message);
|
|
234
|
+
} catch (error) {
|
|
235
|
+
console.error('Error processing message:', error);
|
|
236
|
+
await ctx.reply('Something went wrong. Please try again.');
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
bot.catch((err) => {
|
|
241
|
+
console.error('Bot error:', err);
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
console.log('\\nTelegram bot started! Send a message to your bot.\\n');
|
|
245
|
+
bot.start();
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
main().catch(console.error);
|
|
249
|
+
`;
|
|
250
|
+
}
|
|
251
|
+
function generateReadme(config) {
|
|
252
|
+
const provider = PROVIDERS[config.provider];
|
|
253
|
+
const hasTelegram = config.channels === 'cli+telegram';
|
|
254
|
+
let readme = `# ${config.name}
|
|
255
|
+
|
|
256
|
+
An AI agent powered by [TrikHub](https://trikhub.com). This agent uses **${provider.className}** and can be extended with triks — composable capabilities that plug into your agent.
|
|
257
|
+
|
|
258
|
+
## What can this agent do?
|
|
259
|
+
|
|
260
|
+
Out of the box, your agent is a general-purpose assistant. Its real power comes from **triks** — install them to give your agent new capabilities:
|
|
261
|
+
|
|
262
|
+
\`\`\`bash
|
|
263
|
+
# Browse and search available triks
|
|
264
|
+
trik search <query>
|
|
265
|
+
|
|
266
|
+
# Install a trik
|
|
267
|
+
trik install @scope/trik-name
|
|
268
|
+
\`\`\`
|
|
269
|
+
|
|
270
|
+
Triks come in two flavors:
|
|
271
|
+
- **Handoff triks** — take over the conversation for a specialized task (e.g. a coding assistant, a travel planner). Use \`/back\` to return.
|
|
272
|
+
- **Tool triks** — appear as native tools the agent can call (e.g. web search, calculator).
|
|
273
|
+
|
|
274
|
+
## Setup
|
|
275
|
+
|
|
276
|
+
\`\`\`bash
|
|
277
|
+
cp .env.example .env
|
|
278
|
+
\`\`\`
|
|
279
|
+
|
|
280
|
+
Add your **${provider.envVar}** to \`.env\`.
|
|
281
|
+
`;
|
|
282
|
+
if (hasTelegram) {
|
|
283
|
+
readme += `
|
|
284
|
+
### Telegram Bot Token
|
|
285
|
+
|
|
286
|
+
To run the Telegram bot, you need a bot token:
|
|
287
|
+
|
|
288
|
+
1. Open Telegram and message [@BotFather](https://t.me/BotFather)
|
|
289
|
+
2. Send \`/newbot\`
|
|
290
|
+
3. Choose a display name (e.g. "${config.name}")
|
|
291
|
+
4. Choose a username (must end in \`bot\`, e.g. \`${config.name.replace(/-/g, '_')}_bot\`)
|
|
292
|
+
5. Copy the token into \`.env\` as \`TELEGRAM_BOT_TOKEN\`
|
|
293
|
+
`;
|
|
294
|
+
}
|
|
295
|
+
readme += `
|
|
296
|
+
## Running
|
|
297
|
+
|
|
298
|
+
### CLI mode
|
|
299
|
+
|
|
300
|
+
\`\`\`bash
|
|
301
|
+
npm run dev
|
|
302
|
+
\`\`\`
|
|
303
|
+
|
|
304
|
+
Chat with your agent in the terminal. Type \`/back\` to return from a trik handoff, \`exit\` to quit.
|
|
305
|
+
`;
|
|
306
|
+
if (hasTelegram) {
|
|
307
|
+
readme += `
|
|
308
|
+
### Telegram mode
|
|
309
|
+
|
|
310
|
+
\`\`\`bash
|
|
311
|
+
npm run telegram
|
|
312
|
+
\`\`\`
|
|
313
|
+
|
|
314
|
+
Your agent runs as a Telegram bot. Open Telegram, find your bot by username, and start chatting.
|
|
315
|
+
|
|
316
|
+
## Keeping your bot running
|
|
317
|
+
|
|
318
|
+
The Telegram bot needs to stay running to receive messages. Here are a few options:
|
|
319
|
+
|
|
320
|
+
### pm2 (Recommended)
|
|
321
|
+
|
|
322
|
+
\`\`\`bash
|
|
323
|
+
npm install -g pm2
|
|
324
|
+
pm2 start npm --name "${config.name}" -- run telegram
|
|
325
|
+
pm2 save
|
|
326
|
+
pm2 startup # auto-start on boot
|
|
327
|
+
\`\`\`
|
|
328
|
+
|
|
329
|
+
### Docker
|
|
330
|
+
|
|
331
|
+
\`\`\`dockerfile
|
|
332
|
+
FROM node:22-slim
|
|
333
|
+
WORKDIR /app
|
|
334
|
+
COPY package.json package-lock.json ./
|
|
335
|
+
RUN npm install --production
|
|
336
|
+
COPY . .
|
|
337
|
+
RUN npm run build
|
|
338
|
+
CMD ["node", "dist/telegram.js"]
|
|
339
|
+
\`\`\`
|
|
340
|
+
|
|
341
|
+
### systemd (Linux VPS)
|
|
342
|
+
|
|
343
|
+
\`\`\`ini
|
|
344
|
+
[Unit]
|
|
345
|
+
Description=${config.name} Telegram bot
|
|
346
|
+
After=network.target
|
|
347
|
+
|
|
348
|
+
[Service]
|
|
349
|
+
ExecStart=/usr/bin/node /home/user/${config.name}/dist/telegram.js
|
|
350
|
+
WorkingDirectory=/home/user/${config.name}
|
|
351
|
+
Restart=always
|
|
352
|
+
EnvironmentFile=/home/user/${config.name}/.env
|
|
353
|
+
|
|
354
|
+
[Install]
|
|
355
|
+
WantedBy=multi-user.target
|
|
356
|
+
\`\`\`
|
|
357
|
+
`;
|
|
358
|
+
}
|
|
359
|
+
readme += `
|
|
360
|
+
## Installing triks
|
|
361
|
+
|
|
362
|
+
\`\`\`bash
|
|
363
|
+
trik install @scope/trik-name
|
|
364
|
+
\`\`\`
|
|
365
|
+
|
|
366
|
+
Installed triks are saved to \`.trikhub/config.json\` and loaded automatically when your agent starts.
|
|
367
|
+
`;
|
|
368
|
+
return readme;
|
|
369
|
+
}
|
|
190
370
|
// ============================================================================
|
|
191
371
|
// Public API
|
|
192
372
|
// ============================================================================
|
|
@@ -202,8 +382,12 @@ export function generateAgentTypescriptProject(config) {
|
|
|
202
382
|
files['.env.example'] = generateEnvExample(config);
|
|
203
383
|
files['.gitignore'] = generateGitignore();
|
|
204
384
|
files['.trikhub/config.json'] = generateTrikhubConfig();
|
|
385
|
+
files['README.md'] = generateReadme(config);
|
|
205
386
|
files['src/agent.ts'] = generateAgentTs(config);
|
|
206
387
|
files['src/cli.ts'] = generateCliTs();
|
|
388
|
+
if (config.channels === 'cli+telegram') {
|
|
389
|
+
files['src/telegram.ts'] = generateTelegramTs();
|
|
390
|
+
}
|
|
207
391
|
return files;
|
|
208
392
|
}
|
|
209
393
|
//# sourceMappingURL=agent-typescript.js.map
|