@photon-ai/flux 0.6.5 → 0.6.6
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 +81 -0
- package/dist/index.js +57 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -249,6 +249,37 @@ The `splitIntoMessages` helper function splits messages using `\n` and then loop
|
|
|
249
249
|
|
|
250
250
|
For example, `"Hello!\nHow are you?\nNice to meet you!"` will be sent as three separate message bubbles.
|
|
251
251
|
|
|
252
|
+
## Tapbacks
|
|
253
|
+
|
|
254
|
+
Agents can send tapback reactions (love, like, dislike, laugh, emphasize, question). When your agent receives a message, it can react to it using the `sendTapback` function.
|
|
255
|
+
|
|
256
|
+
To use `sendTapback`, you need to:
|
|
257
|
+
1. Capture `sendTapback` in `onInit` once at startup
|
|
258
|
+
2. Call it in `invoke` when processing messages
|
|
259
|
+
|
|
260
|
+
```
|
|
261
|
+
import { FluxAgent, SendTapbackFn } from '@photon-ai/flux';
|
|
262
|
+
|
|
263
|
+
let sendTapback: SendTapbackFn | undefined;
|
|
264
|
+
|
|
265
|
+
const agent: FluxAgent = {
|
|
266
|
+
onInit: async (_sendMessage, _sendTapback) => {
|
|
267
|
+
sendTapback = _sendTapback; // Save it for later
|
|
268
|
+
},
|
|
269
|
+
|
|
270
|
+
invoke: async ({ message, userPhoneNumber, messageGuid }) => {
|
|
271
|
+
// Now you can use it
|
|
272
|
+
if (sendTapback && messageGuid) {
|
|
273
|
+
await sendTapback(messageGuid, 'love', userPhoneNumber);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
return "Hello!";
|
|
277
|
+
},
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
export default agent;
|
|
281
|
+
```
|
|
282
|
+
|
|
252
283
|
## 💡 Examples
|
|
253
284
|
|
|
254
285
|
### Weather Agent
|
|
@@ -313,6 +344,56 @@ export default {
|
|
|
313
344
|
};
|
|
314
345
|
```
|
|
315
346
|
|
|
347
|
+
### Chatbot with Tapbacks
|
|
348
|
+
|
|
349
|
+
A conversational chatbot with tapback functionalities:
|
|
350
|
+
|
|
351
|
+
```
|
|
352
|
+
import "dotenv/config";
|
|
353
|
+
import OpenAI from "openai";
|
|
354
|
+
|
|
355
|
+
const openai = new OpenAI();
|
|
356
|
+
const conversations = new Map<string, Array<{ role: "user" | "assistant" | "system"; content: string }>>();
|
|
357
|
+
|
|
358
|
+
let sendTapback: ((messageGuid: string, reaction: string, userPhoneNumber: string) => Promise<boolean>) | undefined;
|
|
359
|
+
|
|
360
|
+
export default {
|
|
361
|
+
onInit: async (_sendMessage: any, _sendTapback: any) => {
|
|
362
|
+
sendTapback = _sendTapback;
|
|
363
|
+
},
|
|
364
|
+
|
|
365
|
+
invoke: async ({ message, userPhoneNumber, messageGuid }: { message: string; userPhoneNumber: string; messageGuid?: string }) => {
|
|
366
|
+
// Get or create conversation history
|
|
367
|
+
if (!conversations.has(userPhoneNumber)) {
|
|
368
|
+
conversations.set(userPhoneNumber, [{
|
|
369
|
+
role: "system",
|
|
370
|
+
content: "You are a friendly iMessage assistant. Keep responses concise. For positive messages, start with [TAPBACK:love], [TAPBACK:laugh], or [TAPBACK:like]."
|
|
371
|
+
}]);
|
|
372
|
+
}
|
|
373
|
+
const history = conversations.get(userPhoneNumber)!;
|
|
374
|
+
history.push({ role: "user", content: message });
|
|
375
|
+
|
|
376
|
+
// Call OpenAI
|
|
377
|
+
const completion = await openai.chat.completions.create({
|
|
378
|
+
model: "gpt-4o-mini",
|
|
379
|
+
messages: history,
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
let response = completion.choices[0]?.message?.content || "Hello!";
|
|
383
|
+
|
|
384
|
+
// Extract and send tapback if present
|
|
385
|
+
const tapbackMatch = response.match(/^\[TAPBACK:(love|like|laugh|emphasize)\]/i);
|
|
386
|
+
if (tapbackMatch && sendTapback && messageGuid) {
|
|
387
|
+
await sendTapback(messageGuid, tapbackMatch[1].toLowerCase(), userPhoneNumber);
|
|
388
|
+
response = response.replace(tapbackMatch[0], "").trim();
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
history.push({ role: "assistant", content: response });
|
|
392
|
+
return response;
|
|
393
|
+
},
|
|
394
|
+
};
|
|
395
|
+
```
|
|
396
|
+
|
|
316
397
|
## Why Flux?
|
|
317
398
|
|
|
318
399
|
Connecting agents to messaging platforms traditionally involves complex processes like setting up servers, configuring webhooks, and dealing with platform APIs. Most solutions rely on SMS or WhatsApp, which can be unintuitive for many users.
|
package/dist/index.js
CHANGED
|
@@ -52416,6 +52416,37 @@ async function loadAgent(agentPath) {
|
|
|
52416
52416
|
return agent;
|
|
52417
52417
|
}
|
|
52418
52418
|
|
|
52419
|
+
// src/memory.ts
|
|
52420
|
+
var Memory = class {
|
|
52421
|
+
store = /* @__PURE__ */ new Map();
|
|
52422
|
+
// Add a message to a conversation
|
|
52423
|
+
add(phoneNumber, message) {
|
|
52424
|
+
const normalized = this.normalizePhone(phoneNumber);
|
|
52425
|
+
if (!this.store.has(normalized)) {
|
|
52426
|
+
this.store.set(normalized, []);
|
|
52427
|
+
}
|
|
52428
|
+
this.store.get(normalized).push(message);
|
|
52429
|
+
}
|
|
52430
|
+
// Get all messages for a conversation
|
|
52431
|
+
get(phoneNumber) {
|
|
52432
|
+
const normalized = this.normalizePhone(phoneNumber);
|
|
52433
|
+
return this.store.get(normalized) || [];
|
|
52434
|
+
}
|
|
52435
|
+
// Clear history for a specific conversation, or all if no phone provided
|
|
52436
|
+
clear(phoneNumber) {
|
|
52437
|
+
if (phoneNumber) {
|
|
52438
|
+
this.store.delete(this.normalizePhone(phoneNumber));
|
|
52439
|
+
} else {
|
|
52440
|
+
this.store.clear();
|
|
52441
|
+
}
|
|
52442
|
+
}
|
|
52443
|
+
// Normalize phone number format
|
|
52444
|
+
normalizePhone(phone) {
|
|
52445
|
+
return phone.replace(/[\s\-\(\)]/g, "");
|
|
52446
|
+
}
|
|
52447
|
+
};
|
|
52448
|
+
var memory = new Memory();
|
|
52449
|
+
|
|
52419
52450
|
// src/index.ts
|
|
52420
52451
|
function splitIntoMessages2(response) {
|
|
52421
52452
|
if (!response.includes("\n")) {
|
|
@@ -52463,17 +52494,29 @@ async function runLocal() {
|
|
|
52463
52494
|
input: process.stdin,
|
|
52464
52495
|
output: process.stdout
|
|
52465
52496
|
});
|
|
52497
|
+
const localPhoneNumber = "+1234567890";
|
|
52466
52498
|
const askQuestion = () => {
|
|
52467
52499
|
rl.question("You: ", async (input) => {
|
|
52468
52500
|
if (!input.trim()) {
|
|
52469
52501
|
askQuestion();
|
|
52470
52502
|
return;
|
|
52471
52503
|
}
|
|
52504
|
+
memory.add(localPhoneNumber, {
|
|
52505
|
+
role: "user",
|
|
52506
|
+
content: input,
|
|
52507
|
+
timestamp: Date.now()
|
|
52508
|
+
});
|
|
52472
52509
|
console.log("[FLUX] Thinking...");
|
|
52473
52510
|
try {
|
|
52474
52511
|
const response = await agent.invoke({
|
|
52475
52512
|
message: input,
|
|
52476
|
-
userPhoneNumber:
|
|
52513
|
+
userPhoneNumber: localPhoneNumber,
|
|
52514
|
+
history: memory.get(localPhoneNumber)
|
|
52515
|
+
});
|
|
52516
|
+
memory.add(localPhoneNumber, {
|
|
52517
|
+
role: "assistant",
|
|
52518
|
+
content: response,
|
|
52519
|
+
timestamp: Date.now()
|
|
52477
52520
|
});
|
|
52478
52521
|
const messages = splitIntoMessages2(response);
|
|
52479
52522
|
for (const msg of messages) {
|
|
@@ -52517,12 +52560,24 @@ async function runProd() {
|
|
|
52517
52560
|
console.log("[FLUX] Agent loaded successfully!");
|
|
52518
52561
|
const flux = new FluxClient(phoneNumber, token, async (message) => {
|
|
52519
52562
|
console.log(`[FLUX] Processing message from ${message.userPhoneNumber}: ${message.text}`);
|
|
52563
|
+
memory.add(message.userPhoneNumber, {
|
|
52564
|
+
role: "user",
|
|
52565
|
+
content: message.text,
|
|
52566
|
+
timestamp: Date.now(),
|
|
52567
|
+
imageBase64: message.imageBase64
|
|
52568
|
+
});
|
|
52520
52569
|
try {
|
|
52521
52570
|
const response = await agent.invoke({
|
|
52522
52571
|
message: message.text,
|
|
52523
52572
|
userPhoneNumber: message.userPhoneNumber,
|
|
52524
52573
|
messageGuid: message.messageGuid,
|
|
52525
|
-
imageBase64: message.imageBase64
|
|
52574
|
+
imageBase64: message.imageBase64,
|
|
52575
|
+
history: memory.get(message.userPhoneNumber)
|
|
52576
|
+
});
|
|
52577
|
+
memory.add(message.userPhoneNumber, {
|
|
52578
|
+
role: "assistant",
|
|
52579
|
+
content: response,
|
|
52580
|
+
timestamp: Date.now()
|
|
52526
52581
|
});
|
|
52527
52582
|
console.log(`[FLUX] Agent response: ${response}`);
|
|
52528
52583
|
return response;
|