Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ Read the latest item and the owner's requested change. Preserve manual title,
priority, due-time, owner, snooze, and dismissal choices unless the owner asked
to change them or a supported policy explicitly authorizes the update.

Use the actual item ID. A thread ID, message ID, or chat todo ID is not a Work item
ID. If several items could match, use their source and intended outcome to resolve
Use the actual item ID. A thread ID or message ID is not a Work item ID. If several items could match, use their source and intended outcome to resolve
them; ask only when a mistaken update would affect a different task.

## Apply only supported changes
Expand Down Expand Up @@ -42,8 +41,7 @@ ambiguous failure, read the current item through an available tool before retryi
Do not create a replacement item because an update response was delayed.

Do not promise undo from a history ID alone. Undo requires an available working
tool and a successful result. Chat `TodoWrite` tracks the agent's execution plan;
it does not create or update the owner's persistent Work items.
tool and a successful result.

## Report what happened

Expand Down
33 changes: 19 additions & 14 deletions src/prerna/collaboration/BrainAttachments.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
import prerna.auth.User;
import prerna.sablecc2.om.execptions.SemossPixelException;
import prerna.util.Utility;
import prerna.io.connector.mail.AttachmentText;

// One email attachment for the owner: read live, only while today's rules still show its email,
// and written into the caller's folder. That is an insight folder, which is the room folder once
Expand Down Expand Up @@ -109,14 +110,15 @@ static Map<String, Object> stage(User user, String ownerId, String ownerType, St
static Map<String, Object> stage(User user, String ownerId, String ownerType, String folder, String threadId,
String messageId, String attachmentId, String attachmentName, String fileName, boolean includeText,
BrainMessageSource messages, long maxBytes) {
Map<String, Object> reused = reuse(user, ownerId, ownerType, folder, threadId, attachmentId, attachmentName,
includeText, messages);
if (reused != null) {
return reused;
}
// the email first: a copy staged from an older email on the thread is not a revised file of the same name
if ((attachmentId == null || attachmentId.isBlank()) && attachmentName != null && !attachmentName.isBlank()) {
messageId = emailWithFile(user, ownerId, ownerType, threadId, messageId, attachmentName, messages);
}
Map<String, Object> reused = reuse(user, ownerId, ownerType, folder, threadId, messageId, attachmentId,
attachmentName, includeText, messages);
if (reused != null) {
return reused;
}
BrainThreadMessages.Readable email = BrainThreadMessages.readable(user, ownerId, ownerType, threadId,
messageId, messages);
if (email == null) {
Expand Down Expand Up @@ -195,7 +197,7 @@ static Map<String, Object> stage(User user, String ownerId, String ownerType, St
}
result.put("size", size);
result.put("filePath", target);
if (includeText && BrainAttachmentText.supports(name)) {
if (includeText && AttachmentText.supports(name)) {
addText(result, path, name, email);
}
record(dir, result);
Expand All @@ -217,10 +219,10 @@ static Map<String, Object> stage(User user, String ownerId, String ownerType, St
// the attachment this chat already downloaded, so asking again reuses the file instead of Graph;
// the email must still pass today's rules, as for a fresh download
private static Map<String, Object> reuse(User user, String ownerId, String ownerType, String folder,
String threadId, String attachmentId, String attachmentName, boolean includeText,
String threadId, String messageId, String attachmentId, String attachmentName, boolean includeText,
BrainMessageSource messages) {
Path dir = Path.of(folder).toAbsolutePath().normalize();
Map<String, Object> entry = staged(dir, threadId, attachmentId, attachmentName);
Map<String, Object> entry = staged(dir, threadId, messageId, attachmentId, attachmentName);
if (entry == null) {
return null;
}
Expand All @@ -242,7 +244,7 @@ private static Map<String, Object> reuse(User user, String ownerId, String owner
}
result.put("alreadyInChat", true);
String name = String.valueOf(entry.get("name"));
if (includeText && BrainAttachmentText.supports(name)) {
if (includeText && AttachmentText.supports(name)) {
Path text = path.resolveSibling(path.getFileName() + ".txt");
if (Files.isRegularFile(text)) {
result.put("textPath", text.getFileName().toString());
Expand All @@ -253,9 +255,11 @@ private static Map<String, Object> reuse(User user, String ownerId, String owner
return result;
}

// by attachment id when one is passed, else by the file name the assistant sees on the thread
// by attachment id when one is passed, else by the file name the assistant sees on the thread, from the same email
// when it is known
@SuppressWarnings("unchecked")
private static Map<String, Object> staged(Path dir, String threadId, String attachmentId, String attachmentName) {
private static Map<String, Object> staged(Path dir, String threadId, String messageId, String attachmentId,
String attachmentName) {
boolean byId = attachmentId != null && !attachmentId.isBlank();
if (!byId && (attachmentName == null || attachmentName.isBlank())) {
return null;
Expand All @@ -267,7 +271,8 @@ private static Map<String, Object> staged(Path dir, String threadId, String atta
continue;
}
if (byId ? attachmentId.equals(entry.get("attachmentId"))
: looseName(attachmentName).equals(looseName(String.valueOf(entry.get("name"))))) {
: looseName(attachmentName).equals(looseName(String.valueOf(entry.get("name"))))
&& (messageId == null || messageId.equalsIgnoreCase(String.valueOf(entry.get("messageId"))))) {
return entry;
}
}
Expand Down Expand Up @@ -405,8 +410,8 @@ private static String looseName(String name) {
private static void addText(Map<String, Object> result, Path file, String name,
BrainThreadMessages.Readable email) {
try {
BrainAttachmentText.Extracted text = BrainAttachmentText.extract(file, name, header(name, email),
BrainAttachmentText.MAX_CHARS);
AttachmentText.Extracted text = AttachmentText.extract(file, name, header(name, email),
AttachmentText.MAX_CHARS);
if (text == null) {
return;
}
Expand Down
13 changes: 13 additions & 0 deletions src/prerna/collaboration/BrainConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,24 @@ public static Map<String, Object> status(User user) {
result.put("sources", CollaborationSourceUtils.getSourceStatuses(owner.getValue0(), owner.getValue1()));
// a finished import, so turning mail off reads as paused rather than never set up
result.put("imported", BrainSync.lastRun(owner.getValue0(), owner.getValue1()) != null);
// until the owner opens Work at the end of setup or skips it, Today sends them back to setup
result.put("setupDone", CollaborationDbUtils.exists("SELECT 1 FROM BRAIN_SETTINGS WHERE OWNER_ID = ? "
+ "AND OWNER_TYPE = ? AND SETUP_DONE_AT IS NOT NULL", owner.getValue0(), owner.getValue1()));
// which Outlook folders mail is read from, and how many topics stand for one
result.put("folders", BrainMailFolders.summary(owner.getValue0(), owner.getValue1()));
return result;
}

/** Records that the owner opened Work at the end of setup or skipped the rest of it; Reset clears it. */
public static Map<String, Object> finishSetup(User user) {
Pair<String, String> owner = CollaborationDbUtils.ownerOf(user);
// creates the settings row a new owner does not have yet
BrainProfileUtils.getSettings(owner.getValue0(), owner.getValue1());
CollaborationDbUtils.update("UPDATE BRAIN_SETTINGS SET SETUP_DONE_AT = ? WHERE OWNER_ID = ? AND OWNER_TYPE = ?",
CollaborationDbUtils.now(), owner.getValue0(), owner.getValue1());
return status(user);
}

/** Keeps this session's renewable Microsoft sign-in so routines and refresh work without the page open. */
public static Map<String, Object> saveBackground(User user) {
Pair<String, String> owner = CollaborationDbUtils.ownerOf(user);
Expand Down
5 changes: 3 additions & 2 deletions src/prerna/collaboration/BrainDraftFormat.java
Original file line number Diff line number Diff line change
Expand Up @@ -282,8 +282,9 @@ public static Map<String, Object> learn(User user) {
int read = 0;
for (BrainMessageSource.Fetched fetched : BrainMessageSource.current().fetchAll(user, "email", null, ids)) {
Map<String, Object> message = fetched.message();
// a forward carries someone else's signature
if (message == null || FORWARD.matcher(String.valueOf(message.get("subject"))).find()) {
// a forward carries someone else's signature; a routine's styled result mailed to the owner carries none
if (message == null || FORWARD.matcher(String.valueOf(message.get("subject"))).find()
|| BrainStyleLearning.toThemselves(message)) {
continue;
}
// only what the owner wrote, never the quoted mail below it
Expand Down
Loading
Loading