@askalf/deepdive 0.14.0 → 0.16.0

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.
Files changed (59) hide show
  1. package/README.md +22 -1
  2. package/dist/agent.d.ts +2 -1
  3. package/dist/agent.d.ts.map +1 -1
  4. package/dist/agent.js +12 -0
  5. package/dist/agent.js.map +1 -1
  6. package/dist/cli.d.ts.map +1 -1
  7. package/dist/cli.js +168 -15
  8. package/dist/cli.js.map +1 -1
  9. package/dist/config-file.d.ts.map +1 -1
  10. package/dist/config-file.js +1 -0
  11. package/dist/config-file.js.map +1 -1
  12. package/dist/config.d.ts +3 -0
  13. package/dist/config.d.ts.map +1 -1
  14. package/dist/config.js +5 -0
  15. package/dist/config.js.map +1 -1
  16. package/dist/dates.d.ts +1 -0
  17. package/dist/dates.d.ts.map +1 -1
  18. package/dist/dates.js +23 -0
  19. package/dist/dates.js.map +1 -1
  20. package/dist/index.d.ts +4 -2
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +4 -2
  23. package/dist/index.js.map +1 -1
  24. package/dist/open.d.ts +6 -0
  25. package/dist/open.d.ts.map +1 -0
  26. package/dist/open.js +25 -0
  27. package/dist/open.js.map +1 -0
  28. package/dist/search/hackernews.d.ts +16 -0
  29. package/dist/search/hackernews.d.ts.map +1 -0
  30. package/dist/search/hackernews.js +47 -0
  31. package/dist/search/hackernews.js.map +1 -0
  32. package/dist/search/openalex.d.ts +24 -0
  33. package/dist/search/openalex.d.ts.map +1 -0
  34. package/dist/search/openalex.js +71 -0
  35. package/dist/search/openalex.js.map +1 -0
  36. package/dist/search/pubmed.d.ts +7 -0
  37. package/dist/search/pubmed.d.ts.map +1 -0
  38. package/dist/search/pubmed.js +75 -0
  39. package/dist/search/pubmed.js.map +1 -0
  40. package/dist/search/semanticscholar.d.ts +21 -0
  41. package/dist/search/semanticscholar.d.ts.map +1 -0
  42. package/dist/search/semanticscholar.js +58 -0
  43. package/dist/search/semanticscholar.js.map +1 -0
  44. package/dist/search/stackexchange.d.ts +17 -0
  45. package/dist/search/stackexchange.d.ts.map +1 -0
  46. package/dist/search/stackexchange.js +70 -0
  47. package/dist/search/stackexchange.js.map +1 -0
  48. package/dist/search.d.ts.map +1 -1
  49. package/dist/search.js +26 -0
  50. package/dist/search.js.map +1 -1
  51. package/dist/sessions.d.ts +4 -0
  52. package/dist/sessions.d.ts.map +1 -1
  53. package/dist/sessions.js +32 -0
  54. package/dist/sessions.js.map +1 -1
  55. package/dist/stats.d.ts +20 -0
  56. package/dist/stats.d.ts.map +1 -0
  57. package/dist/stats.js +73 -0
  58. package/dist/stats.js.map +1 -0
  59. package/package.json +1 -1
package/dist/stats.js ADDED
@@ -0,0 +1,73 @@
1
+ // Aggregate insights across saved sessions — what have I researched, how much
2
+ // has it cost, which models did the work. Pure over a list of SessionRecords
3
+ // (the CLI reads them); rendering is separate so it's unit-testable.
4
+ export function aggregateSessionStats(records) {
5
+ const byModel = new Map();
6
+ let totalCostUsd = 0;
7
+ let totalSources = 0;
8
+ let totalRounds = 0;
9
+ let deepRuns = 0;
10
+ let oldest;
11
+ let newest;
12
+ for (const r of records) {
13
+ const cost = typeof r.cost?.amountUsd === "number" ? r.cost.amountUsd : 0;
14
+ totalCostUsd += cost;
15
+ totalSources += r.sources?.length ?? 0;
16
+ const rounds = r.rounds?.length ?? 0;
17
+ totalRounds += rounds;
18
+ if (rounds > 1)
19
+ deepRuns++;
20
+ const model = r.llm?.model ?? "(unknown)";
21
+ let bucket = byModel.get(model);
22
+ if (!bucket) {
23
+ bucket = { model, count: 0, costUsd: 0 };
24
+ byModel.set(model, bucket);
25
+ }
26
+ bucket.count++;
27
+ bucket.costUsd += cost;
28
+ if (typeof r.createdAt === "number") {
29
+ if (oldest === undefined || r.createdAt < oldest)
30
+ oldest = r.createdAt;
31
+ if (newest === undefined || r.createdAt > newest)
32
+ newest = r.createdAt;
33
+ }
34
+ }
35
+ const models = Array.from(byModel.values()).sort((a, b) => b.count - a.count || b.costUsd - a.costUsd);
36
+ return {
37
+ count: records.length,
38
+ totalCostUsd,
39
+ totalSources,
40
+ totalRounds,
41
+ deepRuns,
42
+ avgSourcesPerSession: records.length > 0 ? totalSources / records.length : 0,
43
+ byModel: models,
44
+ oldest,
45
+ newest,
46
+ };
47
+ }
48
+ // Exported for unit tests. Human-readable summary block.
49
+ export function renderStats(stats) {
50
+ if (stats.count === 0) {
51
+ return "(no sessions yet — run `deepdive \"<question>\"` to create one)";
52
+ }
53
+ const lines = [];
54
+ lines.push(`sessions ${stats.count}`);
55
+ lines.push(`cost ~$${stats.totalCostUsd.toFixed(stats.totalCostUsd < 0.01 ? 4 : 2)} total (calculated at list price)`);
56
+ lines.push(`sources ${stats.totalSources} fetched · ${stats.avgSourcesPerSession.toFixed(1)} avg/session`);
57
+ lines.push(`rounds ${stats.totalRounds} total · ${stats.deepRuns} deep run${stats.deepRuns === 1 ? "" : "s"}`);
58
+ if (stats.oldest !== undefined && stats.newest !== undefined) {
59
+ lines.push(`span ${isoDay(stats.oldest)} → ${isoDay(stats.newest)}`);
60
+ }
61
+ if (stats.byModel.length > 0) {
62
+ lines.push("models");
63
+ for (const m of stats.byModel) {
64
+ lines.push(` ${m.model.padEnd(22)} ${String(m.count).padStart(4)} run${m.count === 1 ? " " : "s"} · ~$${m.costUsd.toFixed(m.costUsd < 0.01 ? 4 : 2)}`);
65
+ }
66
+ }
67
+ return lines.join("\n");
68
+ }
69
+ function isoDay(ms) {
70
+ const d = new Date(ms);
71
+ return Number.isNaN(d.getTime()) ? "?" : d.toISOString().slice(0, 10);
72
+ }
73
+ //# sourceMappingURL=stats.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stats.js","sourceRoot":"","sources":["../src/stats.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@askalf/deepdive",
3
- "version": "0.14.0",
3
+ "version": "0.16.0",
4
4
  "description": "A local research agent. One command, cited answer. Routes every LLM call through your own proxy (dario, Anthropic-compat, OpenAI-compat). Headless browser + pluggable search + multi-provider LLM — zero hosted dependencies.",
5
5
  "type": "module",
6
6
  "bin": {