@mongrov/analytics 0.1.0-alpha.7 → 0.1.0-alpha.9

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 (161) hide show
  1. package/dist/rules/__fakes__/fakeClock.d.ts +7 -0
  2. package/dist/rules/__fakes__/fakeClock.d.ts.map +1 -0
  3. package/dist/rules/__fakes__/fakeClock.js +13 -0
  4. package/dist/rules/__fakes__/fakeClock.js.map +1 -0
  5. package/dist/rules/__fakes__/fakeEngine.d.ts +12 -0
  6. package/dist/rules/__fakes__/fakeEngine.d.ts.map +1 -0
  7. package/dist/rules/__fakes__/fakeEngine.js +33 -0
  8. package/dist/rules/__fakes__/fakeEngine.js.map +1 -0
  9. package/dist/rules/__fakes__/fakeStorage.d.ts +7 -0
  10. package/dist/rules/__fakes__/fakeStorage.d.ts.map +1 -0
  11. package/dist/rules/__fakes__/fakeStorage.js +22 -0
  12. package/dist/rules/__fakes__/fakeStorage.js.map +1 -0
  13. package/dist/rules/compiler-cache.d.ts +16 -0
  14. package/dist/rules/compiler-cache.d.ts.map +1 -0
  15. package/dist/rules/compiler-cache.js +29 -0
  16. package/dist/rules/compiler-cache.js.map +1 -0
  17. package/dist/rules/compiler.d.ts +27 -0
  18. package/dist/rules/compiler.d.ts.map +1 -0
  19. package/dist/rules/compiler.js +210 -0
  20. package/dist/rules/compiler.js.map +1 -0
  21. package/dist/rules/defaults/index.d.ts +13 -0
  22. package/dist/rules/defaults/index.d.ts.map +1 -0
  23. package/dist/rules/defaults/index.js +13 -0
  24. package/dist/rules/defaults/index.js.map +1 -0
  25. package/dist/rules/defaults/loader.d.ts +18 -0
  26. package/dist/rules/defaults/loader.d.ts.map +1 -0
  27. package/dist/rules/defaults/loader.js +37 -0
  28. package/dist/rules/defaults/loader.js.map +1 -0
  29. package/dist/rules/defaults/luminx.d.ts +6 -0
  30. package/dist/rules/defaults/luminx.d.ts.map +1 -0
  31. package/dist/rules/defaults/luminx.js +64 -0
  32. package/dist/rules/defaults/luminx.js.map +1 -0
  33. package/dist/rules/defaults/viva.d.ts +6 -0
  34. package/dist/rules/defaults/viva.d.ts.map +1 -0
  35. package/dist/rules/defaults/viva.js +45 -0
  36. package/dist/rules/defaults/viva.js.map +1 -0
  37. package/dist/rules/defaults/yogaring.d.ts +6 -0
  38. package/dist/rules/defaults/yogaring.d.ts.map +1 -0
  39. package/dist/rules/defaults/yogaring.js +45 -0
  40. package/dist/rules/defaults/yogaring.js.map +1 -0
  41. package/dist/rules/defaults/ziva.d.ts +10 -0
  42. package/dist/rules/defaults/ziva.d.ts.map +1 -0
  43. package/dist/rules/defaults/ziva.js +87 -0
  44. package/dist/rules/defaults/ziva.js.map +1 -0
  45. package/dist/rules/emitter.d.ts +20 -0
  46. package/dist/rules/emitter.d.ts.map +1 -0
  47. package/dist/rules/emitter.js +32 -0
  48. package/dist/rules/emitter.js.map +1 -0
  49. package/dist/rules/evaluator.d.ts +44 -0
  50. package/dist/rules/evaluator.d.ts.map +1 -0
  51. package/dist/rules/evaluator.js +127 -0
  52. package/dist/rules/evaluator.js.map +1 -0
  53. package/dist/rules/factory.d.ts +13 -0
  54. package/dist/rules/factory.d.ts.map +1 -0
  55. package/dist/rules/factory.js +56 -0
  56. package/dist/rules/factory.js.map +1 -0
  57. package/dist/rules/hooks/useRuleRegistry.d.ts +16 -0
  58. package/dist/rules/hooks/useRuleRegistry.d.ts.map +1 -0
  59. package/dist/rules/hooks/useRuleRegistry.js +26 -0
  60. package/dist/rules/hooks/useRuleRegistry.js.map +1 -0
  61. package/dist/rules/hooks/useRuleViolations.d.ts +21 -0
  62. package/dist/rules/hooks/useRuleViolations.d.ts.map +1 -0
  63. package/dist/rules/hooks/useRuleViolations.js +32 -0
  64. package/dist/rules/hooks/useRuleViolations.js.map +1 -0
  65. package/dist/rules/index.d.ts +30 -1
  66. package/dist/rules/index.d.ts.map +1 -1
  67. package/dist/rules/index.js +36 -1
  68. package/dist/rules/index.js.map +1 -1
  69. package/dist/rules/registry.d.ts +32 -0
  70. package/dist/rules/registry.d.ts.map +1 -0
  71. package/dist/rules/registry.js +98 -0
  72. package/dist/rules/registry.js.map +1 -0
  73. package/dist/rules/schema.d.ts +221 -0
  74. package/dist/rules/schema.d.ts.map +1 -0
  75. package/dist/rules/schema.js +80 -0
  76. package/dist/rules/schema.js.map +1 -0
  77. package/dist/rules/throttle.d.ts +27 -0
  78. package/dist/rules/throttle.d.ts.map +1 -0
  79. package/dist/rules/throttle.js +76 -0
  80. package/dist/rules/throttle.js.map +1 -0
  81. package/dist/rules/types.d.ts +88 -0
  82. package/dist/rules/types.d.ts.map +1 -0
  83. package/dist/rules/types.js +9 -0
  84. package/dist/rules/types.js.map +1 -0
  85. package/dist/rules/validator.d.ts +27 -0
  86. package/dist/rules/validator.d.ts.map +1 -0
  87. package/dist/rules/validator.js +97 -0
  88. package/dist/rules/validator.js.map +1 -0
  89. package/dist/sync/factory.d.ts +8 -0
  90. package/dist/sync/factory.d.ts.map +1 -1
  91. package/dist/sync/factory.js +31 -1
  92. package/dist/sync/factory.js.map +1 -1
  93. package/dist/sync/flusher.d.ts +6 -0
  94. package/dist/sync/flusher.d.ts.map +1 -1
  95. package/dist/sync/flusher.js +13 -1
  96. package/dist/sync/flusher.js.map +1 -1
  97. package/dist/tools/__fakes__/engine.d.ts +25 -0
  98. package/dist/tools/__fakes__/engine.d.ts.map +1 -0
  99. package/dist/tools/__fakes__/engine.js +37 -0
  100. package/dist/tools/__fakes__/engine.js.map +1 -0
  101. package/dist/tools/audit.d.ts +31 -0
  102. package/dist/tools/audit.d.ts.map +1 -0
  103. package/dist/tools/audit.js +157 -0
  104. package/dist/tools/audit.js.map +1 -0
  105. package/dist/tools/authorize.d.ts +36 -0
  106. package/dist/tools/authorize.d.ts.map +1 -0
  107. package/dist/tools/authorize.js +87 -0
  108. package/dist/tools/authorize.js.map +1 -0
  109. package/dist/tools/budget.d.ts +15 -0
  110. package/dist/tools/budget.d.ts.map +1 -0
  111. package/dist/tools/budget.js +64 -0
  112. package/dist/tools/budget.js.map +1 -0
  113. package/dist/tools/factory.d.ts +43 -0
  114. package/dist/tools/factory.d.ts.map +1 -0
  115. package/dist/tools/factory.js +137 -0
  116. package/dist/tools/factory.js.map +1 -0
  117. package/dist/tools/formatters.d.ts +17 -0
  118. package/dist/tools/formatters.d.ts.map +1 -0
  119. package/dist/tools/formatters.js +30 -0
  120. package/dist/tools/formatters.js.map +1 -0
  121. package/dist/tools/impls/activity.d.ts +15 -0
  122. package/dist/tools/impls/activity.d.ts.map +1 -0
  123. package/dist/tools/impls/activity.js +61 -0
  124. package/dist/tools/impls/activity.js.map +1 -0
  125. package/dist/tools/impls/anomaly.d.ts +21 -0
  126. package/dist/tools/impls/anomaly.d.ts.map +1 -0
  127. package/dist/tools/impls/anomaly.js +70 -0
  128. package/dist/tools/impls/anomaly.js.map +1 -0
  129. package/dist/tools/impls/compare.d.ts +21 -0
  130. package/dist/tools/impls/compare.d.ts.map +1 -0
  131. package/dist/tools/impls/compare.js +68 -0
  132. package/dist/tools/impls/compare.js.map +1 -0
  133. package/dist/tools/impls/hrv.d.ts +15 -0
  134. package/dist/tools/impls/hrv.d.ts.map +1 -0
  135. package/dist/tools/impls/hrv.js +36 -0
  136. package/dist/tools/impls/hrv.js.map +1 -0
  137. package/dist/tools/impls/insights.d.ts +18 -0
  138. package/dist/tools/impls/insights.d.ts.map +1 -0
  139. package/dist/tools/impls/insights.js +41 -0
  140. package/dist/tools/impls/insights.js.map +1 -0
  141. package/dist/tools/impls/sleep.d.ts +15 -0
  142. package/dist/tools/impls/sleep.d.ts.map +1 -0
  143. package/dist/tools/impls/sleep.js +43 -0
  144. package/dist/tools/impls/sleep.js.map +1 -0
  145. package/dist/tools/index.d.ts +13 -1
  146. package/dist/tools/index.d.ts.map +1 -1
  147. package/dist/tools/index.js +21 -1
  148. package/dist/tools/index.js.map +1 -1
  149. package/dist/tools/rate-limit.d.ts +26 -0
  150. package/dist/tools/rate-limit.d.ts.map +1 -0
  151. package/dist/tools/rate-limit.js +67 -0
  152. package/dist/tools/rate-limit.js.map +1 -0
  153. package/dist/tools/types.d.ts +121 -0
  154. package/dist/tools/types.d.ts.map +1 -0
  155. package/dist/tools/types.js +16 -0
  156. package/dist/tools/types.js.map +1 -0
  157. package/dist/tools/wrap.d.ts +53 -0
  158. package/dist/tools/wrap.d.ts.map +1 -0
  159. package/dist/tools/wrap.js +135 -0
  160. package/dist/tools/wrap.js.map +1 -0
  161. package/package.json +5 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit.js","sourceRoot":"","sources":["../../src/tools/rate-limit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,kBAAkB,EAAwB,MAAM,SAAS,CAAA;AAmBlE,MAAM,aAAa,GAAG,KAAM,CAAA;AAC5B,MAAM,WAAW,GAAG,OAAS,CAAA;AAE7B,MAAM,UAAU,iBAAiB,CAC/B,MAA+B,EAAE;IAEjC,MAAM,EAAE,GAAoB,GAAG,CAAC,MAAM,IAAI,kBAAkB,CAAA;IAC5D,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,CAAA;IAEnC,MAAM,aAAa,GAAG,IAAI,GAAG,EAAuB,CAAA;IACpD,MAAM,WAAW,GAAG,IAAI,GAAG,EAAuB,CAAA;IAClD,MAAM,aAAa,GAAG,IAAI,GAAG,EAAuB,CAAA;IAEpD,SAAS,WAAW,CAClB,GAA6B,EAC7B,GAAW,EACX,QAAgB,EAChB,QAAgB,EAChB,GAAW;QAEX,IAAI,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QACpB,IAAI,CAAC,CAAC,EAAE,CAAC;YACP,CAAC,GAAG;gBACF,MAAM,EAAE,QAAQ;gBAChB,YAAY,EAAE,GAAG;gBACjB,QAAQ;gBACR,WAAW,EAAE,QAAQ,GAAG,QAAQ;aACjC,CAAA;YACD,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;QACjB,CAAC;QACD,OAAO,CAAC,CAAA;IACV,CAAC;IAED,SAAS,MAAM,CAAC,CAAc,EAAE,GAAW;QACzC,MAAM,OAAO,GAAG,GAAG,GAAG,CAAC,CAAC,YAAY,CAAA;QACpC,IAAI,OAAO,IAAI,CAAC;YAAE,OAAM;QACxB,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,MAAM,GAAG,OAAO,GAAG,CAAC,CAAC,WAAW,CAAC,CAAA;QACnE,CAAC,CAAC,YAAY,GAAG,GAAG,CAAA;IACtB,CAAC;IAED,OAAO;QACL,KAAK,CAAC,QAAQ,EAAE,MAAM;YACpB,MAAM,GAAG,GAAG,KAAK,EAAE,CAAA;YACnB,MAAM,OAAO,GAAG,GAAG,QAAQ,IAAI,MAAM,EAAE,CAAA;YACvC,MAAM,OAAO,GAAG,MAAM,CAAA;YAEtB,MAAM,EAAE,GAAG,WAAW,CACpB,aAAa,EACb,OAAO,EACP,EAAE,CAAC,gBAAgB,EACnB,aAAa,EACb,GAAG,CACJ,CAAA;YACD,MAAM,EAAE,GAAG,WAAW,CACpB,WAAW,EACX,OAAO,EACP,EAAE,CAAC,cAAc,EACjB,WAAW,EACX,GAAG,CACJ,CAAA;YACD,MAAM,EAAE,GAAG,WAAW,CACpB,aAAa,EACb,OAAO,EACP,EAAE,CAAC,gBAAgB,EACnB,aAAa,EACb,GAAG,CACJ,CAAA;YAED,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC,CAAA;YACf,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC,CAAA;YACf,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC,CAAA;YAEf,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACpD,OAAO,KAAK,CAAA;YACd,CAAC;YAED,EAAE,CAAC,MAAM,IAAI,CAAC,CAAA;YACd,EAAE,CAAC,MAAM,IAAI,CAAC,CAAA;YACd,EAAE,CAAC,MAAM,IAAI,CAAC,CAAA;YACd,OAAO,IAAI,CAAA;QACb,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Public type surface for @mongrov/analytics/tools.
3
+ *
4
+ * Types shared across tool impls, rate limiter, authorize hooks,
5
+ * audit writer, wrapper, and the top-level factory.
6
+ */
7
+ import type { AnalyticsEngine, FamilyMembersProvider } from '../core/types';
8
+ /** Runtime context threaded through every tool impl and authorize hook. */
9
+ export interface ToolContext {
10
+ readonly requesterUserId: string;
11
+ readonly brand: string;
12
+ readonly familyId: string;
13
+ readonly now?: () => Date;
14
+ }
15
+ /** Bounded text summary returned by every tool impl. */
16
+ export interface ToolResult {
17
+ readonly text: string;
18
+ readonly rowCount: number;
19
+ readonly bytes: number;
20
+ }
21
+ /**
22
+ * Authorization hook — invoked before every tool execute. `false`
23
+ * rejects the call before SQL runs. Toolname passes through so hooks
24
+ * can gate by tool identity in addition to args + ctx.
25
+ */
26
+ export type AuthorizeFn = (toolName: string, args: Record<string, unknown>, ctx: ToolContext) => Promise<boolean>;
27
+ /**
28
+ * Token-bucket rate-limit ceilings. Defaults come from
29
+ * `analytics-ai-tools/spec.md` §Rate limiting.
30
+ */
31
+ export interface RateLimitConfig {
32
+ perToolPerMinute: number;
33
+ perToolPerHour: number;
34
+ perUserPerMinute: number;
35
+ }
36
+ export declare const DEFAULT_RATE_LIMIT: RateLimitConfig;
37
+ export interface ToolsLogger {
38
+ debug: (message: string, meta?: Record<string, unknown>) => void;
39
+ info: (message: string, meta?: Record<string, unknown>) => void;
40
+ warn: (message: string, meta?: Record<string, unknown>) => void;
41
+ error: (message: string, meta?: Record<string, unknown>) => void;
42
+ }
43
+ /**
44
+ * A tool impl. Takes a Zod-parsed input and the runtime context
45
+ * (augmented with the analytics engine), returns a bounded text
46
+ * result. `makeTool` (T-10) wraps this with rate → auth → execute →
47
+ * budget → audit chain to produce an AI SDK `tool()` handle.
48
+ */
49
+ export type ToolImpl<Input> = (input: Input, ctx: ToolContext & {
50
+ analytics: AnalyticsEngine;
51
+ }) => Promise<ToolResult>;
52
+ /**
53
+ * Outcome recorded in `tool_call_audit.outcome`. Enum discipline —
54
+ * every wrapper code path resolves to exactly one of these.
55
+ */
56
+ export type ToolOutcome = 'success' | 'rate_limited' | 'authorized_reject' | 'error';
57
+ /**
58
+ * A single row destined for `tool_call_audit`. Column mapping (see
59
+ * `core/schemas.ts` line 189):
60
+ * ts, brand, family_id, requester_user_id, tool_name, args,
61
+ * result_bytes, result_row_count, latency_ms, outcome, error_message
62
+ */
63
+ export interface AuditEntry {
64
+ readonly ts: Date;
65
+ readonly brand: string;
66
+ readonly familyId: string;
67
+ readonly requesterUserId: string;
68
+ readonly toolName: string;
69
+ readonly args: Record<string, unknown>;
70
+ readonly resultBytes: number | null;
71
+ readonly resultRowCount: number | null;
72
+ readonly latencyMs: number | null;
73
+ readonly outcome: ToolOutcome;
74
+ readonly errorMessage: string | null;
75
+ }
76
+ /**
77
+ * Batched writer for `tool_call_audit`. `record` is non-blocking —
78
+ * entries flush on batch-size or timer. `flush` and `close` are test
79
+ * hooks / graceful-shutdown hooks respectively.
80
+ */
81
+ export interface AuditWriter {
82
+ record: (entry: AuditEntry) => void;
83
+ flush: () => Promise<void>;
84
+ close: () => Promise<void>;
85
+ }
86
+ /**
87
+ * Per-tool output ceiling enforced by `applyOutputBudget`. Text
88
+ * exceeding `maxBytes` is UTF-8-safely truncated with a
89
+ * `\n[truncated]` suffix. `maxRows` is informational — impls limit
90
+ * row count via SQL.
91
+ */
92
+ export interface OutputBudget {
93
+ maxBytes: number;
94
+ maxRows: number;
95
+ }
96
+ export declare const DEFAULT_OUTPUT_BUDGET: OutputBudget;
97
+ /**
98
+ * Config for `createAnalyticsTools` factory. All fields except
99
+ * `analytics` are optional with sane defaults from `spec.md`.
100
+ *
101
+ * - `rateLimit: false` disables the limiter entirely (tests only).
102
+ * - `authorize: undefined` defaults to `familyScopeAuthorize` wired
103
+ * with `familyMembersProvider` if supplied.
104
+ * - `audit.enabled: false` makes `record` a no-op.
105
+ */
106
+ export interface AnalyticsToolsConfig {
107
+ analytics: AnalyticsEngine;
108
+ authorize?: AuthorizeFn;
109
+ rateLimit?: RateLimitConfig | false;
110
+ audit?: {
111
+ enabled?: boolean;
112
+ batchSize?: number;
113
+ flushIntervalMs?: number;
114
+ retentionDays?: number;
115
+ };
116
+ outputBudget?: Partial<OutputBudget>;
117
+ logger?: ToolsLogger;
118
+ familyMembersProvider?: FamilyMembersProvider;
119
+ clock?: () => number;
120
+ }
121
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/tools/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Public type surface for @mongrov/analytics/tools.
3
+ *
4
+ * Types shared across tool impls, rate limiter, authorize hooks,
5
+ * audit writer, wrapper, and the top-level factory.
6
+ */
7
+ export const DEFAULT_RATE_LIMIT = {
8
+ perToolPerMinute: 20,
9
+ perToolPerHour: 200,
10
+ perUserPerMinute: 60,
11
+ };
12
+ export const DEFAULT_OUTPUT_BUDGET = {
13
+ maxBytes: 4096,
14
+ maxRows: 100,
15
+ };
16
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/tools/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAwCH,MAAM,CAAC,MAAM,kBAAkB,GAAoB;IACjD,gBAAgB,EAAE,EAAE;IACpB,cAAc,EAAE,GAAG;IACnB,gBAAgB,EAAE,EAAE;CACrB,CAAA;AAwED,MAAM,CAAC,MAAM,qBAAqB,GAAiB;IACjD,QAAQ,EAAE,IAAI;IACd,OAAO,EAAE,GAAG;CACb,CAAA"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * `makeTool` — compose an AI SDK `tool()` from a raw impl plus the
3
+ * rate → auth → execute → budget → audit chain.
4
+ *
5
+ * The chain order is load-bearing:
6
+ * 1. Rate limit → cheap, no I/O; short-circuits abusive callers.
7
+ * 2. Authorize → may hit SQL/provider; runs after rate cap.
8
+ * 3. Execute → real tool work.
9
+ * 4. Budget → truncate oversized text before returning.
10
+ * 5. Audit → record every terminal state (success / reject
11
+ * / rate-limited / error).
12
+ *
13
+ * Every branch records exactly one audit entry. The wrapper never
14
+ * throws — errors resolve to a short LLM-friendly string. Because
15
+ * the AI SDK `execute(input)` signature has no per-call context arg,
16
+ * the caller supplies a `ctxProvider()` closure that returns the
17
+ * current `ToolContext` at invocation time (the factory backs this
18
+ * with a mutable container updated per request).
19
+ */
20
+ import type { ZodTypeAny } from 'zod';
21
+ import type { AnalyticsEngine } from '../core/types';
22
+ import type { RateLimiter } from './rate-limit';
23
+ import type { AuditWriter, AuthorizeFn, OutputBudget, ToolContext, ToolImpl, ToolsLogger } from './types';
24
+ export interface MakeToolConfig<Input> {
25
+ name: string;
26
+ description: string;
27
+ /**
28
+ * Accepts any Zod schema whose parsed output is assignable to
29
+ * `Input`. Widened to `ZodTypeAny` so schemas with `.default()` /
30
+ * `.optional()` fields (whose input types include `undefined`)
31
+ * still fit — the AI SDK's own `tool()` uses the same shape.
32
+ */
33
+ inputSchema: ZodTypeAny;
34
+ impl: ToolImpl<Input>;
35
+ analytics: AnalyticsEngine;
36
+ authorize?: AuthorizeFn;
37
+ rateLimiter?: RateLimiter | null;
38
+ audit: AuditWriter;
39
+ budget: OutputBudget;
40
+ logger?: ToolsLogger;
41
+ /**
42
+ * Returns the current `ToolContext` at execute-time. The factory
43
+ * backs this with a mutable container so a single tool handle
44
+ * threads per-request scope. Returning `null` triggers a clean
45
+ * error branch (no ctx → audit `error` outcome).
46
+ */
47
+ ctxProvider: () => ToolContext | null;
48
+ clock?: () => number;
49
+ }
50
+ export declare function makeTool<Input>(cfg: MakeToolConfig<Input>): import("ai").Tool<ZodTypeAny, string> & {
51
+ execute: (args: any, options: import("ai").ToolExecutionOptions) => PromiseLike<string>;
52
+ };
53
+ //# sourceMappingURL=wrap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrap.d.ts","sourceRoot":"","sources":["../../src/tools/wrap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AACrC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAEpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,KAAK,EACV,WAAW,EACX,WAAW,EACX,YAAY,EACZ,WAAW,EACX,QAAQ,EACR,WAAW,EACZ,MAAM,SAAS,CAAA;AAOhB,MAAM,WAAW,cAAc,CAAC,KAAK;IACnC,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB;;;;;OAKG;IACH,WAAW,EAAE,UAAU,CAAA;IACvB,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAA;IACrB,SAAS,EAAE,eAAe,CAAA;IAC1B,SAAS,CAAC,EAAE,WAAW,CAAA;IACvB,WAAW,CAAC,EAAE,WAAW,GAAG,IAAI,CAAA;IAChC,KAAK,EAAE,WAAW,CAAA;IAClB,MAAM,EAAE,YAAY,CAAA;IACpB,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB;;;;;OAKG;IACH,WAAW,EAAE,MAAM,WAAW,GAAG,IAAI,CAAA;IACrC,KAAK,CAAC,EAAE,MAAM,MAAM,CAAA;CACrB;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,GAAG,EAAE,cAAc,CAAC,KAAK,CAAC;;EAqHzD"}
@@ -0,0 +1,135 @@
1
+ /**
2
+ * `makeTool` — compose an AI SDK `tool()` from a raw impl plus the
3
+ * rate → auth → execute → budget → audit chain.
4
+ *
5
+ * The chain order is load-bearing:
6
+ * 1. Rate limit → cheap, no I/O; short-circuits abusive callers.
7
+ * 2. Authorize → may hit SQL/provider; runs after rate cap.
8
+ * 3. Execute → real tool work.
9
+ * 4. Budget → truncate oversized text before returning.
10
+ * 5. Audit → record every terminal state (success / reject
11
+ * / rate-limited / error).
12
+ *
13
+ * Every branch records exactly one audit entry. The wrapper never
14
+ * throws — errors resolve to a short LLM-friendly string. Because
15
+ * the AI SDK `execute(input)` signature has no per-call context arg,
16
+ * the caller supplies a `ctxProvider()` closure that returns the
17
+ * current `ToolContext` at invocation time (the factory backs this
18
+ * with a mutable container updated per request).
19
+ */
20
+ import { tool } from 'ai';
21
+ import { applyOutputBudget } from './budget';
22
+ const RATE_LIMIT_MESSAGE = 'Rate limit exceeded. Try again shortly.';
23
+ const AUTHZ_MESSAGE = 'Not authorized to access that user\'s data.';
24
+ const ERROR_MESSAGE = 'Tool call failed.';
25
+ const NO_CONTEXT_MESSAGE = 'Tool call failed: request context not set.';
26
+ export function makeTool(cfg) {
27
+ const clock = cfg.clock ?? Date.now;
28
+ return tool({
29
+ description: cfg.description,
30
+ parameters: cfg.inputSchema,
31
+ execute: async (input) => {
32
+ const startMs = clock();
33
+ const ctx = cfg.ctxProvider();
34
+ // 0. Ctx guard — audit as error, no rate/auth/execute performed.
35
+ if (!ctx) {
36
+ cfg.audit.record({
37
+ ts: new Date(clock()),
38
+ brand: '',
39
+ familyId: '',
40
+ requesterUserId: '',
41
+ toolName: cfg.name,
42
+ args: input,
43
+ resultBytes: null,
44
+ resultRowCount: null,
45
+ latencyMs: clock() - startMs,
46
+ outcome: 'error',
47
+ errorMessage: 'context not set',
48
+ });
49
+ cfg.logger?.warn('tool invoked without context', { toolName: cfg.name });
50
+ return NO_CONTEXT_MESSAGE;
51
+ }
52
+ // 1. Rate limit.
53
+ if (cfg.rateLimiter && !cfg.rateLimiter.check(cfg.name, ctx.requesterUserId)) {
54
+ cfg.audit.record({
55
+ ts: new Date(clock()),
56
+ brand: ctx.brand,
57
+ familyId: ctx.familyId,
58
+ requesterUserId: ctx.requesterUserId,
59
+ toolName: cfg.name,
60
+ args: input,
61
+ resultBytes: null,
62
+ resultRowCount: null,
63
+ latencyMs: clock() - startMs,
64
+ outcome: 'rate_limited',
65
+ errorMessage: null,
66
+ });
67
+ return RATE_LIMIT_MESSAGE;
68
+ }
69
+ // 2. Authorize.
70
+ if (cfg.authorize) {
71
+ const ok = await cfg.authorize(cfg.name, input, ctx);
72
+ if (!ok) {
73
+ cfg.audit.record({
74
+ ts: new Date(clock()),
75
+ brand: ctx.brand,
76
+ familyId: ctx.familyId,
77
+ requesterUserId: ctx.requesterUserId,
78
+ toolName: cfg.name,
79
+ args: input,
80
+ resultBytes: null,
81
+ resultRowCount: null,
82
+ latencyMs: clock() - startMs,
83
+ outcome: 'authorized_reject',
84
+ errorMessage: null,
85
+ });
86
+ return AUTHZ_MESSAGE;
87
+ }
88
+ }
89
+ // 3. Execute + 4. Budget + 5. Audit success/error.
90
+ try {
91
+ const raw = await cfg.impl(input, {
92
+ ...ctx,
93
+ analytics: cfg.analytics,
94
+ });
95
+ const capped = applyOutputBudget(raw, cfg.budget);
96
+ cfg.audit.record({
97
+ ts: new Date(clock()),
98
+ brand: ctx.brand,
99
+ familyId: ctx.familyId,
100
+ requesterUserId: ctx.requesterUserId,
101
+ toolName: cfg.name,
102
+ args: input,
103
+ resultBytes: capped.bytes,
104
+ resultRowCount: capped.rowCount,
105
+ latencyMs: clock() - startMs,
106
+ outcome: 'success',
107
+ errorMessage: null,
108
+ });
109
+ return capped.text;
110
+ }
111
+ catch (err) {
112
+ const errorMessage = err instanceof Error ? err.message : String(err);
113
+ cfg.audit.record({
114
+ ts: new Date(clock()),
115
+ brand: ctx.brand,
116
+ familyId: ctx.familyId,
117
+ requesterUserId: ctx.requesterUserId,
118
+ toolName: cfg.name,
119
+ args: input,
120
+ resultBytes: null,
121
+ resultRowCount: null,
122
+ latencyMs: clock() - startMs,
123
+ outcome: 'error',
124
+ errorMessage,
125
+ });
126
+ cfg.logger?.warn('tool execution failed', {
127
+ toolName: cfg.name,
128
+ err: errorMessage,
129
+ });
130
+ return ERROR_MESSAGE;
131
+ }
132
+ },
133
+ });
134
+ }
135
+ //# sourceMappingURL=wrap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrap.js","sourceRoot":"","sources":["../../src/tools/wrap.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mongrov/analytics",
3
- "version": "0.1.0-alpha.7",
3
+ "version": "0.1.0-alpha.9",
4
4
  "description": "DuckDB + R2 Iceberg local analytics for @mongrov apps",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -64,6 +64,7 @@
64
64
  "peerDependencies": {
65
65
  "@mongrov/db": "workspace:*",
66
66
  "@mongrov/types": "^0.4.0",
67
+ "ai": ">=4",
67
68
  "react": ">=19",
68
69
  "react-native": ">=0.81",
69
70
  "react-native-duckdb": ">=1.0.0"
@@ -80,6 +81,7 @@
80
81
  }
81
82
  },
82
83
  "dependencies": {
84
+ "@iarna/toml": "^2.2.5",
83
85
  "date-fns-tz": "^3.2.0",
84
86
  "p-queue": "^8.0.1",
85
87
  "xstate": "^5.30.0"
@@ -90,6 +92,8 @@
90
92
  "@testing-library/react": "^14.3.1",
91
93
  "@types/react": "^18.3.12",
92
94
  "@types/react-dom": "^18.3.1",
95
+ "ai": "^4.3.0",
96
+ "fast-check": "^4.9.0",
93
97
  "jsdom": "^25.0.1",
94
98
  "react": "^18.3.1",
95
99
  "react-dom": "^18.3.1",