plasalid 0.7.1 → 0.7.3
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 +15 -15
- package/dist/accounts/taxonomy.d.ts +1 -1
- package/dist/accounts/taxonomy.js +1 -1
- package/dist/ai/agent.d.ts +9 -10
- package/dist/ai/agent.js +31 -15
- package/dist/ai/personas.d.ts +1 -1
- package/dist/ai/personas.js +57 -55
- package/dist/ai/prompt-sections.d.ts +4 -4
- package/dist/ai/prompt-sections.js +1 -1
- package/dist/ai/system-prompt.d.ts +2 -2
- package/dist/ai/system-prompt.js +5 -5
- package/dist/ai/tools/account-mutex.d.ts +1 -0
- package/dist/ai/tools/account-mutex.js +16 -0
- package/dist/ai/tools/clarify.d.ts +2 -0
- package/dist/ai/tools/clarify.js +169 -0
- package/dist/ai/tools/index.js +10 -18
- package/dist/ai/tools/ingest.d.ts +2 -2
- package/dist/ai/tools/ingest.js +284 -244
- package/dist/ai/tools/merchants.js +1 -28
- package/dist/ai/tools/read.js +8 -8
- package/dist/ai/tools/record.js +7 -40
- package/dist/ai/tools/resolve.js +25 -22
- package/dist/ai/tools/scan.js +0 -1
- package/dist/ai/tools/types.d.ts +14 -21
- package/dist/cli/commands/clarify.d.ts +5 -0
- package/dist/cli/commands/clarify.js +44 -0
- package/dist/cli/commands/record.js +1 -82
- package/dist/cli/commands/resolve.d.ts +5 -2
- package/dist/cli/commands/resolve.js +36 -5
- package/dist/cli/commands/revert.js +4 -2
- package/dist/cli/commands/rules.js +2 -2
- package/dist/cli/commands/scan.js +199 -128
- package/dist/cli/commands/status.js +6 -6
- package/dist/cli/index.js +8 -29
- package/dist/cli/ink/ScanDashboard.d.ts +49 -0
- package/dist/cli/ink/ScanDashboard.js +214 -0
- package/dist/cli/ink/scan_dashboard.d.ts +40 -25
- package/dist/cli/ink/scan_dashboard.js +139 -44
- package/dist/cli/setup.js +1 -1
- package/dist/cli/ux.js +1 -1
- package/dist/db/queries/account-balance.d.ts +1 -1
- package/dist/db/queries/questions.d.ts +62 -0
- package/dist/db/queries/questions.js +110 -0
- package/dist/db/queries/transactions.d.ts +1 -1
- package/dist/db/queries/unknowns.d.ts +17 -15
- package/dist/db/queries/unknowns.js +35 -39
- package/dist/db/schema.js +6 -28
- package/dist/scanner/audit/auditor.d.ts +31 -0
- package/dist/scanner/audit/auditor.js +72 -0
- package/dist/scanner/audit/engine.d.ts +10 -0
- package/dist/scanner/audit/engine.js +98 -0
- package/dist/scanner/audit/eventBus.d.ts +60 -0
- package/dist/scanner/audit/eventBus.js +35 -0
- package/dist/scanner/audit/passes/index.d.ts +11 -0
- package/dist/scanner/audit/passes/index.js +9 -0
- package/dist/scanner/audit/passes/types.d.ts +23 -0
- package/dist/scanner/audit/passes/types.js +1 -0
- package/dist/scanner/audit/types.d.ts +27 -0
- package/dist/scanner/audit/types.js +1 -0
- package/dist/scanner/auditor.d.ts +51 -0
- package/dist/scanner/auditor.js +80 -0
- package/dist/scanner/buffer/engine.d.ts +9 -0
- package/dist/scanner/buffer/engine.js +110 -0
- package/dist/scanner/buffer/sharedBuffer.d.ts +78 -0
- package/dist/scanner/buffer/sharedBuffer.js +130 -0
- package/dist/scanner/buffer/types.d.ts +67 -0
- package/dist/scanner/buffer/types.js +1 -0
- package/dist/scanner/buffer.d.ts +45 -38
- package/dist/scanner/buffer.js +93 -61
- package/dist/scanner/bus/engine.d.ts +11 -0
- package/dist/scanner/bus/engine.js +42 -0
- package/dist/scanner/bus/types.d.ts +53 -0
- package/dist/scanner/bus/types.js +1 -0
- package/dist/scanner/bus.d.ts +38 -0
- package/dist/scanner/bus.js +37 -0
- package/dist/scanner/chunk-worker.d.ts +19 -0
- package/dist/scanner/chunk-worker.js +67 -0
- package/dist/scanner/chunkWorker.d.ts +20 -0
- package/dist/scanner/chunkWorker.js +59 -0
- package/dist/scanner/chunker/chunker.d.ts +7 -0
- package/dist/scanner/chunker/chunker.js +60 -0
- package/dist/scanner/chunker.d.ts +7 -0
- package/dist/scanner/chunker.js +60 -0
- package/dist/scanner/clarifier-memory.d.ts +8 -0
- package/dist/scanner/clarifier-memory.js +24 -0
- package/dist/scanner/clarifier.d.ts +39 -0
- package/dist/scanner/clarifier.js +196 -0
- package/dist/scanner/converge.d.ts +29 -0
- package/dist/scanner/converge.js +15 -0
- package/dist/scanner/decrypt.d.ts +10 -0
- package/dist/scanner/decrypt.js +80 -0
- package/dist/scanner/engine/scanEngine.d.ts +24 -0
- package/dist/scanner/engine/scanEngine.js +87 -0
- package/dist/scanner/engine/types.d.ts +90 -0
- package/dist/scanner/engine/types.js +1 -0
- package/dist/scanner/engine.d.ts +90 -0
- package/dist/scanner/engine.js +84 -0
- package/dist/scanner/file-worker.d.ts +33 -0
- package/dist/scanner/file-worker.js +28 -0
- package/dist/scanner/fileWorker.d.ts +33 -0
- package/dist/scanner/fileWorker.js +22 -0
- package/dist/scanner/hooks/types.d.ts +25 -0
- package/dist/scanner/hooks/types.js +1 -0
- package/dist/scanner/hooks.d.ts +23 -0
- package/dist/scanner/hooks.js +1 -0
- package/dist/scanner/parse.d.ts +10 -0
- package/dist/scanner/parse.js +47 -0
- package/dist/scanner/passes/index.d.ts +8 -0
- package/dist/scanner/passes/index.js +6 -0
- package/dist/scanner/passes/types.d.ts +22 -0
- package/dist/scanner/passes/types.js +1 -0
- package/dist/scanner/pdf/chunker.d.ts +7 -0
- package/dist/scanner/pdf/chunker.js +60 -0
- package/dist/scanner/pdf/password-store.d.ts +34 -0
- package/dist/scanner/pdf/password-store.js +83 -0
- package/dist/scanner/pdf/pdf-unlock.d.ts +17 -0
- package/dist/scanner/pdf/pdf-unlock.js +50 -0
- package/dist/scanner/pdf/pdf.d.ts +17 -0
- package/dist/scanner/pdf/pdf.js +36 -0
- package/dist/scanner/pdf/state-machine.d.ts +60 -0
- package/dist/scanner/pdf/state-machine.js +64 -0
- package/dist/scanner/pdf/unlock.d.ts +22 -0
- package/dist/scanner/pdf/unlock.js +121 -0
- package/dist/scanner/phase-decrypt.d.ts +10 -0
- package/dist/scanner/phase-decrypt.js +80 -0
- package/dist/scanner/phase-parse.d.ts +10 -0
- package/dist/scanner/phase-parse.js +46 -0
- package/dist/scanner/phases/chunk.d.ts +8 -0
- package/dist/scanner/phases/chunk.js +13 -0
- package/dist/scanner/phases/commit.d.ts +12 -0
- package/dist/scanner/phases/commit.js +140 -0
- package/dist/scanner/phases/decrypt.d.ts +10 -0
- package/dist/scanner/phases/decrypt.js +80 -0
- package/dist/scanner/phases/parse.d.ts +10 -0
- package/dist/scanner/phases/parse.js +46 -0
- package/dist/scanner/phases/resolve.d.ts +10 -0
- package/dist/scanner/phases/resolve.js +17 -0
- package/dist/scanner/phases/review.d.ts +10 -0
- package/dist/scanner/phases/review.js +12 -0
- package/dist/scanner/progress.d.ts +14 -0
- package/dist/scanner/progress.js +21 -0
- package/dist/scanner/resolver-memory.d.ts +8 -0
- package/dist/scanner/resolver-memory.js +24 -0
- package/dist/scanner/resolver.d.ts +39 -0
- package/dist/scanner/resolver.js +196 -0
- package/dist/scanner/result.d.ts +17 -0
- package/dist/scanner/result.js +19 -0
- package/dist/scanner/run-passes.d.ts +30 -0
- package/dist/scanner/run-passes.js +15 -0
- package/dist/scanner/unlock.js +1 -1
- package/dist/scanner/worker.d.ts +19 -0
- package/dist/scanner/worker.js +67 -0
- package/dist/scanner/workers/chunkWorker.d.ts +20 -0
- package/dist/scanner/workers/chunkWorker.js +65 -0
- package/dist/scanner/workers/fileWorker.d.ts +32 -0
- package/dist/scanner/workers/fileWorker.js +22 -0
- package/package.json +1 -1
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process-wide serialization for write operations that race when multiple scan
|
|
3
|
+
* agents run in parallel. Each in-flight `create_account` / `update_account_metadata`
|
|
4
|
+
* is held inside `runExclusive` so the SQLite write + the subsequent read-back
|
|
5
|
+
* by another agent's `list_accounts` are consistent.
|
|
6
|
+
*
|
|
7
|
+
* Single tail-promise queue: cheap, deterministic, no extra deps.
|
|
8
|
+
*/
|
|
9
|
+
let tail = Promise.resolve();
|
|
10
|
+
export function runExclusive(fn) {
|
|
11
|
+
const next = tail.then(() => fn());
|
|
12
|
+
// Swallow rejection so a thrown callback doesn't poison the queue for the
|
|
13
|
+
// next caller. The caller still sees the rejection through `next`.
|
|
14
|
+
tail = next.catch(() => undefined);
|
|
15
|
+
return next;
|
|
16
|
+
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { deleteTransaction, updateTransaction, updatePosting, } from "../../db/queries/transactions.js";
|
|
2
|
+
import { mergeAccounts } from "../../db/queries/account-balance.js";
|
|
3
|
+
import { linkTransactionToRecurrence, recordRecurrence, } from "../../db/queries/recurrences.js";
|
|
4
|
+
import { sanitizeForPrompt } from "../sanitize.js";
|
|
5
|
+
const DEFS = [
|
|
6
|
+
{
|
|
7
|
+
name: "update_transaction",
|
|
8
|
+
description: "Header-only update: date, description, or source_page. To change amounts, delete the transaction and record a new one.",
|
|
9
|
+
input_schema: {
|
|
10
|
+
type: "object",
|
|
11
|
+
properties: {
|
|
12
|
+
transaction_id: { type: "string" },
|
|
13
|
+
date: { type: "string" },
|
|
14
|
+
description: { type: "string" },
|
|
15
|
+
source_page: { type: "number" },
|
|
16
|
+
},
|
|
17
|
+
required: ["transaction_id"],
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: "update_posting",
|
|
22
|
+
description: "Safe single-posting edit: re-categorize (account_id) or update memo. Refuses changes to debit/credit/currency — delete and re-record the transaction for those.",
|
|
23
|
+
input_schema: {
|
|
24
|
+
type: "object",
|
|
25
|
+
properties: {
|
|
26
|
+
posting_id: { type: "string" },
|
|
27
|
+
account_id: { type: "string" },
|
|
28
|
+
memo: { type: "string" },
|
|
29
|
+
},
|
|
30
|
+
required: ["posting_id"],
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
name: "delete_transaction",
|
|
35
|
+
description: "Delete a transaction and (via cascade) all its postings. The primitive for removing duplicates.",
|
|
36
|
+
input_schema: {
|
|
37
|
+
type: "object",
|
|
38
|
+
properties: { transaction_id: { type: "string" } },
|
|
39
|
+
required: ["transaction_id"],
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: "record_recurrence",
|
|
44
|
+
description: "Create a recurrences row and link every supplied transaction to it. Computes first_seen_date, last_seen_date, and next_expected_date from the member transactions. Use this after the user confirms a recurrence_candidate question.",
|
|
45
|
+
input_schema: {
|
|
46
|
+
type: "object",
|
|
47
|
+
properties: {
|
|
48
|
+
account_id: {
|
|
49
|
+
type: "string",
|
|
50
|
+
description: "The account this recurs on.",
|
|
51
|
+
},
|
|
52
|
+
description: {
|
|
53
|
+
type: "string",
|
|
54
|
+
description: "Human label, e.g. 'Spotify subscription', 'Salary', 'Rent'.",
|
|
55
|
+
},
|
|
56
|
+
frequency: {
|
|
57
|
+
type: "string",
|
|
58
|
+
enum: ["weekly", "biweekly", "monthly", "annually"],
|
|
59
|
+
},
|
|
60
|
+
amount_typical: {
|
|
61
|
+
type: "number",
|
|
62
|
+
description: "Representative amount (typically the matching amount of the member transactions).",
|
|
63
|
+
},
|
|
64
|
+
currency: { type: "string", default: "THB" },
|
|
65
|
+
transaction_ids: {
|
|
66
|
+
type: "array",
|
|
67
|
+
items: { type: "string" },
|
|
68
|
+
description: "Transaction ids to link to this recurrence.",
|
|
69
|
+
},
|
|
70
|
+
notes: {
|
|
71
|
+
type: "string",
|
|
72
|
+
description: "Optional context the chat agent can read later.",
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
required: ["account_id", "description", "frequency", "transaction_ids"],
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
name: "link_transaction_to_recurrence",
|
|
80
|
+
description: "Attach a single newly-seen transaction to an existing recurrence. Recomputes last_seen_date and next_expected_date on the recurrence.",
|
|
81
|
+
input_schema: {
|
|
82
|
+
type: "object",
|
|
83
|
+
properties: {
|
|
84
|
+
transaction_id: { type: "string" },
|
|
85
|
+
recurrence_id: { type: "string" },
|
|
86
|
+
},
|
|
87
|
+
required: ["transaction_id", "recurrence_id"],
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
name: "merge_accounts",
|
|
92
|
+
description: "Move every posting on `from_id` over to `to_id`, then delete the source account. Use to apply a similar_accounts question's 'Merge A into B' resolution. Refuses if the source still has child accounts.",
|
|
93
|
+
input_schema: {
|
|
94
|
+
type: "object",
|
|
95
|
+
properties: { from_id: { type: "string" }, to_id: { type: "string" } },
|
|
96
|
+
required: ["from_id", "to_id"],
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
];
|
|
100
|
+
const LABELS = {
|
|
101
|
+
update_transaction: "Updating transaction",
|
|
102
|
+
update_posting: "Updating posting",
|
|
103
|
+
delete_transaction: "Deleting transaction",
|
|
104
|
+
record_recurrence: "Recording recurrence",
|
|
105
|
+
link_transaction_to_recurrence: "Linking transaction to recurrence",
|
|
106
|
+
merge_accounts: "Merging accounts",
|
|
107
|
+
};
|
|
108
|
+
async function execute(db, name, input, _ctx) {
|
|
109
|
+
switch (name) {
|
|
110
|
+
case "update_transaction": {
|
|
111
|
+
const changed = updateTransaction(db, input.transaction_id, {
|
|
112
|
+
date: input.date,
|
|
113
|
+
description: input.description,
|
|
114
|
+
source_page: input.source_page,
|
|
115
|
+
});
|
|
116
|
+
return changed === 0
|
|
117
|
+
? `Transaction ${input.transaction_id} not found or no fields to update.`
|
|
118
|
+
: `Updated transaction ${input.transaction_id}.`;
|
|
119
|
+
}
|
|
120
|
+
case "update_posting": {
|
|
121
|
+
const changed = updatePosting(db, input.posting_id, {
|
|
122
|
+
account_id: input.account_id,
|
|
123
|
+
memo: input.memo,
|
|
124
|
+
});
|
|
125
|
+
return changed === 0
|
|
126
|
+
? `Posting ${input.posting_id} not found or no fields to update.`
|
|
127
|
+
: `Updated posting ${input.posting_id}.`;
|
|
128
|
+
}
|
|
129
|
+
case "delete_transaction": {
|
|
130
|
+
const changed = deleteTransaction(db, input.transaction_id);
|
|
131
|
+
return changed === 0
|
|
132
|
+
? `Transaction ${input.transaction_id} not found.`
|
|
133
|
+
: `Deleted transaction ${input.transaction_id} and its postings.`;
|
|
134
|
+
}
|
|
135
|
+
case "record_recurrence": {
|
|
136
|
+
try {
|
|
137
|
+
const id = recordRecurrence(db, {
|
|
138
|
+
account_id: input.account_id,
|
|
139
|
+
description: input.description,
|
|
140
|
+
frequency: input.frequency,
|
|
141
|
+
amount_typical: input.amount_typical ?? null,
|
|
142
|
+
currency: input.currency,
|
|
143
|
+
transaction_ids: input.transaction_ids || [],
|
|
144
|
+
notes: input.notes ?? null,
|
|
145
|
+
});
|
|
146
|
+
return `Recorded recurrence ${id} ("${sanitizeForPrompt(input.description)}", ${input.frequency}); linked ${(input.transaction_ids || []).length} transaction(s).`;
|
|
147
|
+
}
|
|
148
|
+
catch (err) {
|
|
149
|
+
return `Could not record recurrence: ${err.message}`;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
case "link_transaction_to_recurrence": {
|
|
153
|
+
try {
|
|
154
|
+
linkTransactionToRecurrence(db, input.transaction_id, input.recurrence_id);
|
|
155
|
+
return `Linked transaction ${input.transaction_id} → recurrence ${input.recurrence_id}.`;
|
|
156
|
+
}
|
|
157
|
+
catch (err) {
|
|
158
|
+
return `Could not link: ${err.message}`;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
case "merge_accounts": {
|
|
162
|
+
const moved = mergeAccounts(db, input.from_id, input.to_id);
|
|
163
|
+
return `Merged ${input.from_id} → ${input.to_id}; moved ${moved} posting(s).`;
|
|
164
|
+
}
|
|
165
|
+
default:
|
|
166
|
+
return undefined;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
export const clarifyTools = { DEFS, LABELS, execute };
|
package/dist/ai/tools/index.js
CHANGED
|
@@ -1,27 +1,19 @@
|
|
|
1
1
|
import { commonTools } from "./common.js";
|
|
2
2
|
import { readTools } from "./read.js";
|
|
3
|
-
import { accountIngestTools,
|
|
3
|
+
import { accountIngestTools, scanQuestionTools, clarifyIngestTools } from "./ingest.js";
|
|
4
4
|
import { scanTools } from "./scan.js";
|
|
5
|
-
import {
|
|
5
|
+
import { clarifyTools } from "./clarify.js";
|
|
6
6
|
import { recordTools } from "./record.js";
|
|
7
7
|
import { merchantTools } from "./merchants.js";
|
|
8
8
|
/**
|
|
9
9
|
* Profile composition. Each profile is the union of one or more tool modules;
|
|
10
10
|
* the dispatcher iterates every module on each tool call so we never need a
|
|
11
11
|
* central switch.
|
|
12
|
-
*
|
|
13
|
-
* `accountIngestTools` (create_account / update_account_metadata /
|
|
14
|
-
* record_transaction) ships with scan, resolve, and record — they're the
|
|
15
|
-
* shared write primitives. `scanUnknownTools` (note_unknown) is scan-only;
|
|
16
|
-
* record uses `clarify` from `recordTools` for transient prompts, resolve uses
|
|
17
|
-
* `ask_user` from `resolveIngestTools` for resolve-in-place clarifications.
|
|
18
|
-
* `merchantTools` ships with scan, resolve, and record so any write profile can
|
|
19
|
-
* upsert / look up / re-cache merchants alongside the posting flow.
|
|
20
12
|
*/
|
|
21
13
|
const PROFILES = {
|
|
22
|
-
scan: [commonTools, accountIngestTools,
|
|
14
|
+
scan: [commonTools, accountIngestTools, scanQuestionTools, scanTools, merchantTools],
|
|
23
15
|
chat: [commonTools, readTools],
|
|
24
|
-
|
|
16
|
+
clarify: [commonTools, readTools, accountIngestTools, clarifyIngestTools, clarifyTools, merchantTools],
|
|
25
17
|
record: [commonTools, readTools, accountIngestTools, recordTools, merchantTools],
|
|
26
18
|
};
|
|
27
19
|
export function getToolDefinitions(profile) {
|
|
@@ -31,10 +23,10 @@ const MODULES = [
|
|
|
31
23
|
commonTools,
|
|
32
24
|
readTools,
|
|
33
25
|
accountIngestTools,
|
|
34
|
-
|
|
35
|
-
|
|
26
|
+
scanQuestionTools,
|
|
27
|
+
clarifyIngestTools,
|
|
36
28
|
scanTools,
|
|
37
|
-
|
|
29
|
+
clarifyTools,
|
|
38
30
|
recordTools,
|
|
39
31
|
merchantTools,
|
|
40
32
|
];
|
|
@@ -56,10 +48,10 @@ export const TOOL_LABELS = {
|
|
|
56
48
|
...commonTools.LABELS,
|
|
57
49
|
...readTools.LABELS,
|
|
58
50
|
...accountIngestTools.LABELS,
|
|
59
|
-
...
|
|
60
|
-
...
|
|
51
|
+
...scanQuestionTools.LABELS,
|
|
52
|
+
...clarifyIngestTools.LABELS,
|
|
61
53
|
...scanTools.LABELS,
|
|
62
|
-
...
|
|
54
|
+
...clarifyTools.LABELS,
|
|
63
55
|
...recordTools.LABELS,
|
|
64
56
|
...merchantTools.LABELS,
|
|
65
57
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { ToolModule } from "./types.js";
|
|
2
2
|
export declare const accountIngestTools: ToolModule;
|
|
3
|
-
export declare const
|
|
4
|
-
export declare const
|
|
3
|
+
export declare const scanQuestionTools: ToolModule;
|
|
4
|
+
export declare const clarifyIngestTools: ToolModule;
|