Skip to content
Open
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
1 change: 1 addition & 0 deletions agent/instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ The main conversation is the control plane. When the `agent` tool is available,
# Coordination

- Use `sendMessage` for every user-facing message: direct answers, questions, task acknowledgements, progress updates, blockers, and final synthesis. Do not address the user in ordinary assistant text before or after the tool call. A successful call completes that update: never repeat the same message in a turn, and end the turn unless you have distinct new information to send.
- Use `give_feedback` only when an authenticated user explicitly wants to submit product feedback, report a bug, or suggest an improvement. Confirm briefly with `sendMessage` after it is saved.
- Answer conversational, clarifying, and quick informational requests directly.
- When `agent` is available, delegate browser execution and other substantial multi-step work instead of performing it in the main conversation. Start independent tasks together so they can run in parallel.
- Give each worker a bounded objective, expected output, relevant constraints, and all context it needs; workers do not see the parent conversation.
Expand Down
35 changes: 35 additions & 0 deletions agent/tools/give_feedback.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { defineTool } from "eve/tools";
import {
feedbackIdempotencyKey,
feedbackInputSchema,
normalizeFeedback,
} from "../../lib/feedback.js";
import { saveFeedback } from "../../db/services/feedback.js";
import { scopeFromPrincipal } from "../../lib/access-scope.js";

export default defineTool({
description:
"Store feedback this authenticated user explicitly wants to give about Local Vault Assistant, including a bug report, improvement idea, compliment, or general product feedback. Do not use for ordinary requests or inferred dissatisfaction.",
inputSchema: feedbackInputSchema,
async execute(input, ctx) {
const caller = ctx.session.auth.current ?? ctx.session.auth.initiator;
if (!caller) throw new Error("An authenticated user is required.");

const feedback = normalizeFeedback(input.feedback);
const saved = await saveFeedback(scopeFromPrincipal(caller), {
...input,
feedback,
idempotencyKey: feedbackIdempotencyKey({
...input,
feedback,
sessionId: ctx.session.id,
turnId: ctx.session.turn.id,
}),
sessionId: ctx.session.id,
toolCallId: ctx.callId,
turnId: ctx.session.turn.id,
});

return { category: saved.category, feedbackId: saved.id, saved: true };
},
});
2 changes: 1 addition & 1 deletion db/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Application database

This directory owns the eight application tables and their domain query
This directory owns the nine application tables and their domain query
services.
Better Auth continues to own and migrate its tables independently in
`auth.ts`.
Expand Down
23 changes: 23 additions & 0 deletions db/migrations/0001_great_senator_kelly.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
CREATE TABLE "feedback" (
"id" text PRIMARY KEY NOT NULL,
"workspace_id" text NOT NULL,
"created_by_user_id" text NOT NULL,
"eve_session_id" text NOT NULL,
"eve_turn_id" text NOT NULL,
"tool_call_id" text NOT NULL,
"category" text DEFAULT 'general' NOT NULL,
"feedback" text NOT NULL,
"status" text DEFAULT 'new' NOT NULL,
"idempotency_key" text NOT NULL,
"created_at" text NOT NULL,
"updated_at" text NOT NULL,
CONSTRAINT "feedback_category_check" CHECK ("feedback"."category" IN ('general', 'bug', 'idea', 'compliment')),
CONSTRAINT "feedback_content_check" CHECK (length(btrim("feedback"."feedback")) BETWEEN 1 AND 4000),
CONSTRAINT "feedback_status_check" CHECK ("feedback"."status" IN ('new', 'reviewed', 'archived'))
);
--> statement-breakpoint
ALTER TABLE "feedback" ADD CONSTRAINT "feedback_workspace_id_fkey" FOREIGN KEY ("workspace_id") REFERENCES "public"."workspaces"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "feedback" ADD CONSTRAINT "feedback_session_id_fkey" FOREIGN KEY ("eve_session_id") REFERENCES "public"."agent_sessions"("session_id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
CREATE UNIQUE INDEX "feedback_workspace_idempotency_idx" ON "feedback" USING btree ("workspace_id","idempotency_key");--> statement-breakpoint
CREATE INDEX "feedback_review_queue_idx" ON "feedback" USING btree ("status","created_at" DESC NULLS FIRST);--> statement-breakpoint
CREATE INDEX "feedback_workspace_created_idx" ON "feedback" USING btree ("workspace_id","created_at" DESC NULLS FIRST);
Loading