feat: add guarded savings agent tools
This commit is contained in:
@@ -24,6 +24,51 @@ const chatCitation = v.object({
|
||||
marker: v.string(),
|
||||
sourceId: v.string(),
|
||||
});
|
||||
const agentActionPlanStatus = v.union(
|
||||
v.literal("pending"),
|
||||
v.literal("applied"),
|
||||
v.literal("dismissed"),
|
||||
v.literal("expired"),
|
||||
);
|
||||
const agentActionPlanKind = v.union(
|
||||
v.literal("bulk_recategory"),
|
||||
v.literal("category_changes"),
|
||||
);
|
||||
const agentActionPlanOperation = v.union(
|
||||
v.object({
|
||||
type: v.literal("set_transaction_category"),
|
||||
transactionId: v.id("transactions"),
|
||||
fromCategoryId: v.optional(v.id("categories")),
|
||||
toCategoryId: v.id("categories"),
|
||||
}),
|
||||
v.object({
|
||||
type: v.literal("create_category"),
|
||||
name: v.string(),
|
||||
kind: categoryKind,
|
||||
block: v.optional(expenseBlock),
|
||||
color: v.string(),
|
||||
icon: v.optional(v.string()),
|
||||
sortOrder: v.number(),
|
||||
}),
|
||||
v.object({
|
||||
type: v.literal("update_category"),
|
||||
categoryId: v.id("categories"),
|
||||
name: v.optional(v.string()),
|
||||
kind: v.optional(categoryKind),
|
||||
block: v.optional(expenseBlock),
|
||||
color: v.optional(v.string()),
|
||||
icon: v.optional(v.string()),
|
||||
sortOrder: v.optional(v.number()),
|
||||
}),
|
||||
);
|
||||
const agentActionPlanPreviewRow = v.object({
|
||||
date: v.optional(v.string()),
|
||||
description: v.string(),
|
||||
amount: v.optional(v.number()),
|
||||
currentCategoryName: v.optional(v.string()),
|
||||
targetCategoryName: v.optional(v.string()),
|
||||
action: v.optional(v.string()),
|
||||
});
|
||||
|
||||
export default defineSchema({
|
||||
...authTables,
|
||||
@@ -41,6 +86,22 @@ export default defineSchema({
|
||||
.index("by_user", ["userId"])
|
||||
.index("by_user_external", ["userId", "externalId"]),
|
||||
|
||||
accountBalances: defineTable({
|
||||
userId: v.id("users"),
|
||||
accountId: v.id("accounts"),
|
||||
externalId: v.string(),
|
||||
provider: v.union(v.literal("comdirect"), v.literal("fints")),
|
||||
balance: v.number(),
|
||||
currency: v.string(),
|
||||
asOf: v.optional(v.string()),
|
||||
fetchedAt: v.number(),
|
||||
status: v.union(v.literal("fresh"), v.literal("stale"), v.literal("error")),
|
||||
errorMessage: v.optional(v.string()),
|
||||
})
|
||||
.index("by_user", ["userId"])
|
||||
.index("by_user_account", ["userId", "accountId"])
|
||||
.index("by_user_provider_fetched", ["userId", "provider", "fetchedAt"]),
|
||||
|
||||
categories: defineTable({
|
||||
userId: v.id("users"),
|
||||
name: v.string(),
|
||||
@@ -214,4 +275,20 @@ export default defineSchema({
|
||||
sources: v.optional(v.array(chatSource)),
|
||||
citations: v.optional(v.array(chatCitation)),
|
||||
}).index("by_user_session_created", ["userId", "sessionId", "createdAt"]),
|
||||
|
||||
agentActionPlans: defineTable({
|
||||
userId: v.id("users"),
|
||||
sessionId: v.id("chatSessions"),
|
||||
kind: agentActionPlanKind,
|
||||
status: agentActionPlanStatus,
|
||||
summary: v.string(),
|
||||
affectedCount: v.number(),
|
||||
createdAt: v.number(),
|
||||
expiresAt: v.number(),
|
||||
operations: v.array(agentActionPlanOperation),
|
||||
previewRows: v.array(agentActionPlanPreviewRow),
|
||||
resultSummary: v.optional(v.string()),
|
||||
})
|
||||
.index("by_user_session_status_created", ["userId", "sessionId", "status", "createdAt"])
|
||||
.index("by_user_status_expires", ["userId", "status", "expiresAt"]),
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user