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
3 changes: 2 additions & 1 deletion apps/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"db:push": "drizzle-kit push",
"db:studio": "drizzle-kit studio",
"eval": "evalite",
"eval:dev": "evalite watch"
"eval:dev": "evalite watch",
"test:cron": "curl 'http://localhost:8787/cdn-cgi/handler/scheduled'"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Single quotes around the URL make this npm script fail on Windows shells; use double quotes (escaped) for cross-platform compatibility.

Prompt for AI agents
Address the following comment on apps/server/package.json at line 16:

<comment>Single quotes around the URL make this npm script fail on Windows shells; use double quotes (escaped) for cross-platform compatibility.</comment>

<file context>
@@ -12,7 +12,8 @@
     &quot;db:push&quot;: &quot;drizzle-kit push&quot;,
     &quot;db:studio&quot;: &quot;drizzle-kit studio&quot;,
     &quot;eval&quot;: &quot;evalite&quot;,
-    &quot;eval:dev&quot;: &quot;evalite watch&quot;
+    &quot;eval:dev&quot;: &quot;evalite watch&quot;,
+    &quot;test:cron&quot;: &quot;curl &#39;http://localhost:8787/cdn-cgi/handler/scheduled&#39;&quot;
   },
   &quot;exports&quot;: {
</file context>
Suggested change
"test:cron": "curl 'http://localhost:8787/cdn-cgi/handler/scheduled'"
"test:cron": "curl \"http://localhost:8787/cdn-cgi/handler/scheduled\""

},
"exports": {
"./trpc": "./src/trpc/index.ts",
Expand Down
1 change: 1 addition & 0 deletions apps/server/src/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ export type ZeroEnv = {
thread_queue: Queue;
VECTORIZE: VectorizeIndex;
VECTORIZE_MESSAGE: VectorizeIndex;
DEV_PROXY: string;
};

const env = _env as ZeroEnv;
Expand Down
4 changes: 3 additions & 1 deletion apps/server/src/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ export const c = {
} as unknown as AppContext;

export const getNotificationsUrl = (provider: EProviders) => {
return env.VITE_PUBLIC_BACKEND_URL + '/a8n/notify/' + provider;
return env.DEV_PROXY
? `${env.DEV_PROXY}/a8n/notify/${provider}`
: env.VITE_PUBLIC_BACKEND_URL + '/a8n/notify/' + provider;
};

export async function setSubscribedState(
Expand Down
6 changes: 4 additions & 2 deletions apps/server/src/pipelines.ts
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ export class WorkflowRunner extends DurableObject<ZeroEnv> {
// Extract thread IDs from messages
historyItem.messagesAdded?.forEach((msg) => {
if (msg.message?.labelIds?.includes('DRAFT')) return;
if (msg.message?.labelIds?.includes('SPAM')) return;
// if (msg.message?.labelIds?.includes('SPAM')) return;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Strategic spam processing relocation!

Moving spam filtering downstream to the workflow level is a brilliant architectural decision - like moving engine gimbal control from the booster to the flight computer where it belongs. However, let's clean up this commented code rather than leaving space debris in our codebase.

Consider removing the commented line entirely since spam filtering is now handled at the workflow level:

-            // if (msg.message?.labelIds?.includes('SPAM')) return;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// if (msg.message?.labelIds?.includes('SPAM')) return;
🤖 Prompt for AI Agents
In apps/server/src/pipelines.ts at line 357, remove the commented-out line that
checks for 'SPAM' label filtering since spam processing has been moved
downstream to the workflow level. This cleanup will keep the codebase tidy and
avoid confusion from obsolete commented code.

if (msg.message?.threadId) {
threadsAdded.add(msg.message.threadId);
}
Expand Down Expand Up @@ -465,6 +465,8 @@ export class WorkflowRunner extends DurableObject<ZeroEnv> {
);
}
}
} else {
yield* Console.log('[ZERO_WORKFLOW] No new threads to process');
}

// Process label changes for threads
Expand Down Expand Up @@ -1070,7 +1072,7 @@ export class WorkflowRunner extends DurableObject<ZeroEnv> {
history.forEach((historyItem) => {
historyItem.messagesAdded?.forEach((msg) => {
if (msg.message?.labelIds?.includes('DRAFT')) return;
if (msg.message?.labelIds?.includes('SPAM')) return;
// if (msg.message?.labelIds?.includes('SPAM')) return;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Consistent architectural alignment!

Good to see the same spam filtering removal in the non-Effect version for consistency. However, same recommendation as before - let's remove this commented code entirely rather than leaving it as technical debt.

Remove the commented line to keep the codebase clean:

-            // if (msg.message?.labelIds?.includes('SPAM')) return;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// if (msg.message?.labelIds?.includes('SPAM')) return;
🤖 Prompt for AI Agents
In apps/server/src/pipelines.ts at line 1075, remove the commented-out line that
checks for 'SPAM' in message labelIds to keep the codebase clean and avoid
technical debt, as the spam filtering removal is already handled consistently
elsewhere.

if (msg.message?.threadId) {
threadsAdded.add(msg.message.threadId);
}
Expand Down
13 changes: 1 addition & 12 deletions apps/server/src/routes/agent/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -941,6 +941,7 @@ export class ZeroDriver extends DurableObject<ZeroEnv> {
Effect.tap(() =>
Effect.sync(() => console.log(`[syncThread] Updated database for ${threadId}`)),
),
Effect.tap(() => Effect.sync(() => this.reloadFolder('inbox'))),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The folder to reload is hard-coded to "inbox", so threads that are synchronised to other folders (e.g., spam, trash, sent) will not trigger a refresh for the correct folder and may leave the UI stale. Use the labels on the freshly-synced thread to decide which folder(s) need to be reloaded instead. (Based on your team's feedback about avoiding hard-coded folder names that break multi-folder workflows.)

Prompt for AI agents
Address the following comment on apps/server/src/routes/agent/index.ts at line 944:

<comment>The folder to reload is hard-coded to &quot;inbox&quot;, so threads that are synchronised to other folders (e.g., spam, trash, sent) will not trigger a refresh for the correct folder and may leave the UI stale. Use the labels on the freshly-synced thread to decide which folder(s) need to be reloaded instead. (Based on your team&#39;s feedback about avoiding hard-coded folder names that break multi-folder workflows.)</comment>

<file context>
@@ -941,6 +941,7 @@ export class ZeroDriver extends DurableObject&lt;ZeroEnv&gt; {
           Effect.tap(() =&gt;
             Effect.sync(() =&gt; console.log(`[syncThread] Updated database for ${threadId}`)),
           ),
+          Effect.tap(() =&gt; Effect.sync(() =&gt; this.reloadFolder(&#39;inbox&#39;))),
           Effect.catchAll((error) =&gt; {
             console.error(`[syncThread] Failed to update database for ${threadId}:`, error);
</file context>
Suggested change
Effect.tap(() => Effect.sync(() => this.reloadFolder('inbox'))),
Effect.tap(() => Effect.sync(() => latest.tags.forEach((tag) => this.reloadFolder(tag.id.toLowerCase())))),

Effect.catchAll((error) => {
console.error(`[syncThread] Failed to update database for ${threadId}:`, error);
return Effect.succeed(undefined);
Expand All @@ -966,18 +967,6 @@ export class ZeroDriver extends DurableObject<ZeroEnv> {
return Effect.succeed(undefined);
}),
);
// yield* Effect.tryPromise(() => sendDoState(this.name)).pipe(
// Effect.tap(() =>
// Effect.sync(() => {
// result.broadcastSent = true;
// console.log(`[syncThread] Broadcasted do state for ${threadId}`);
// }),
// ),
// Effect.catchAll((error) => {
// console.warn(`[syncThread] Failed to broadcast do state for ${threadId}:`, error);
// return Effect.succeed(undefined);
// }),
// );
} else {
console.log(`[syncThread] No agent available for broadcasting ${threadId}`);
}
Expand Down
25 changes: 16 additions & 9 deletions apps/server/src/thread-workflow-utils/workflow-engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -280,24 +280,31 @@ export const createDefaultWorkflows = (): WorkflowEngine => {
{
id: 'get-user-labels',
name: 'Get User Labels',
description: 'Retrieves user-defined labels',
description: 'Retrieves existing labels from user account',
enabled: true,
action: workflowFunctions.getUserLabels,
},
{
id: 'generate-labels',
name: 'Generate Labels',
description: 'Generates appropriate labels for the thread',
id: 'get-user-topics',
name: 'Get User Topics',
description: 'Retrieves user-defined topics for potential new labels',
enabled: true,
action: workflowFunctions.generateLabels,
action: workflowFunctions.getUserTopics,
},
{
id: 'generate-label-suggestions',
name: 'Generate Label Suggestions',
description: 'Generates appropriate label suggestions for the thread',
enabled: true,
action: workflowFunctions.generateLabelSuggestions,
errorHandling: 'continue',
},
{
id: 'apply-labels',
name: 'Apply Labels',
description: 'Applies generated labels to the thread',
id: 'sync-labels',
name: 'Sync Labels',
description: 'Creates missing labels and applies them to the thread',
enabled: true,
action: workflowFunctions.applyLabels,
action: workflowFunctions.syncLabels,
errorHandling: 'continue',
},
{
Expand Down
Loading