pi-advisor-flow 0.6.0 → 0.8.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 (93) hide show
  1. package/CHANGELOG.md +34 -17
  2. package/README.md +10 -8
  3. package/dist/index.js +2852 -868
  4. package/extensions/index.ts +2 -1
  5. package/package.json +55 -40
  6. package/src/attachments.ts +11 -10
  7. package/src/commands/activation-preparation.ts +1 -0
  8. package/src/commands/activation.ts +2 -0
  9. package/src/commands/lifecycle.ts +1 -0
  10. package/src/commands/manual-command.ts +7 -1
  11. package/src/commands/manual-consultation.ts +103 -79
  12. package/src/commands/manual-progress.ts +7 -5
  13. package/src/commands/model-commands.ts +1 -1
  14. package/src/commands/model-options.ts +14 -3
  15. package/src/commands/model-picker.ts +1 -0
  16. package/src/commands/registration.ts +1 -0
  17. package/src/commands/renderers.ts +67 -55
  18. package/src/commands/runtime.ts +16 -14
  19. package/src/commands/settings-commands.ts +10 -4
  20. package/src/commands/settings-persistence.ts +64 -2
  21. package/src/commands/types.ts +2 -0
  22. package/src/commands.ts +0 -1
  23. package/src/config/args.ts +1 -1
  24. package/src/config/defaults.ts +83 -1
  25. package/src/config/schema.ts +152 -15
  26. package/src/config/state.ts +80 -2
  27. package/src/config/storage.ts +38 -22
  28. package/src/config/types.ts +45 -3
  29. package/src/config/validation.ts +33 -21
  30. package/src/config.ts +3 -0
  31. package/src/content-utils.ts +24 -4
  32. package/src/conversation.ts +16 -15
  33. package/src/git.ts +10 -3
  34. package/src/herdr-block.ts +83 -0
  35. package/src/herdr-shared.ts +108 -0
  36. package/src/herdr.ts +30 -192
  37. package/src/jev/client.ts +338 -0
  38. package/src/jev/failure.ts +19 -0
  39. package/src/jev/key-store.ts +267 -0
  40. package/src/jev/ledger.ts +228 -0
  41. package/src/jev/questions.ts +122 -0
  42. package/src/jev/state.ts +50 -0
  43. package/src/jev/transport.ts +63 -0
  44. package/src/model-stream.ts +35 -37
  45. package/src/outcomes.ts +20 -12
  46. package/src/pi-settings.ts +4 -9
  47. package/src/preferences.ts +4 -2
  48. package/src/redaction.ts +10 -12
  49. package/src/scout-context.ts +59 -60
  50. package/src/scout-curation.ts +4 -13
  51. package/src/scout-groups.ts +178 -175
  52. package/src/scout-protocol.ts +74 -70
  53. package/src/scout-reconstruct.ts +1 -1
  54. package/src/scout.ts +115 -73
  55. package/src/session-state.ts +148 -39
  56. package/src/tool-result-cap.ts +18 -17
  57. package/src/tools/consult-context.ts +7 -15
  58. package/src/tools/consultation.ts +14 -4
  59. package/src/tools/gate-policy.ts +1 -0
  60. package/src/tools/gate-protocol.ts +36 -23
  61. package/src/tools/jev-filter.ts +204 -0
  62. package/src/tools/jev-turn-gate.ts +203 -0
  63. package/src/tools/loop-gate.ts +32 -20
  64. package/src/tools/model-access.ts +46 -0
  65. package/src/tools/outage-notifier.ts +30 -0
  66. package/src/tools/prompts.ts +20 -25
  67. package/src/tools/register-ask-advisor.ts +73 -17
  68. package/src/tools/register-lifecycle.ts +22 -0
  69. package/src/tools/register-outcome.ts +2 -0
  70. package/src/tools/register-renderers.ts +149 -73
  71. package/src/tools/registration.ts +15 -0
  72. package/src/tools/render-advisor-result.ts +77 -35
  73. package/src/tools/render-common.ts +16 -19
  74. package/src/tools/scout-status.ts +42 -27
  75. package/src/tools/types.ts +11 -0
  76. package/src/tools.ts +0 -1
  77. package/src/ui/jev-setup-submenu.ts +350 -0
  78. package/src/ui/manual-dialog-render.ts +1 -0
  79. package/src/ui/manual-dialog.ts +39 -43
  80. package/src/ui/masked-input.ts +62 -0
  81. package/src/ui/model-multi-selector.ts +9 -0
  82. package/src/ui/model-selector-adapter.ts +31 -0
  83. package/src/ui/model-selector.ts +14 -161
  84. package/src/ui/searchable-model-list.ts +230 -0
  85. package/src/ui/settings-formatting.ts +24 -14
  86. package/src/ui/settings-items.ts +200 -2
  87. package/src/ui/settings-list-adapter.ts +15 -12
  88. package/src/ui/settings-mutations.ts +169 -47
  89. package/src/ui/settings-selector.ts +18 -9
  90. package/src/ui/text-setting-submenu.ts +3 -6
  91. package/src/ui/types.ts +25 -0
  92. package/src/ui.ts +0 -1
  93. package/src/usage.ts +29 -20
package/src/usage.ts CHANGED
@@ -1,5 +1,8 @@
1
1
  import type { Usage } from "@earendil-works/pi-ai/compat";
2
2
 
3
+ import { isNumber, isRecordOf } from "./content-utils.ts";
4
+ import type { JsonValue } from "./content-utils.ts";
5
+
3
6
  /** Normalized usage returned by an Advisor or Scout provider response. */
4
7
  export interface AdvisorUsageSnapshot {
5
8
  cacheRead?: number;
@@ -22,26 +25,22 @@ export interface AdvisorUsageTotals {
22
25
  totalTokens?: number;
23
26
  }
24
27
 
25
- const finite = (value: unknown) =>
26
- typeof value === "number" && Number.isFinite(value) && value >= 0
27
- ? value
28
- : undefined;
28
+ const finite = (value: JsonValue | undefined): number | undefined =>
29
+ isNumber(value) && Number.isFinite(value) && value >= 0 ? value : undefined;
29
30
 
30
31
  const add = (left: number | undefined, right: number | undefined) =>
31
32
  left === undefined || right === undefined ? (left ?? right) : left + right;
32
33
 
33
- import { isRecord } from "./content-utils.ts";
34
-
35
34
  const costFields = ["input", "output", "cacheRead", "cacheWrite", "total"];
36
35
 
37
36
  /** Extracts provider-agnostic usage fields without trusting provider metadata. */
38
- export const snapshotAdvisorUsage = (
39
- usage: unknown
37
+ export const snapshotAdvisorUsage = <Input>(
38
+ usage: Input
40
39
  ): AdvisorUsageSnapshot | undefined => {
41
- if (!isRecord(usage)) {
40
+ if (!isRecordOf(usage)) {
42
41
  return undefined;
43
42
  }
44
- const cost = isRecord(usage.cost) ? usage.cost : undefined;
43
+ const cost = isRecordOf(usage.cost) ? usage.cost : undefined;
45
44
  const snapshot = {
46
45
  cacheRead: finite(usage.cacheRead),
47
46
  cacheWrite: finite(usage.cacheWrite),
@@ -60,7 +59,7 @@ export const snapshotAdvisorUsage = (
60
59
  };
61
60
 
62
61
  /** Returns the reported provider cost, when the response includes one. */
63
- export const advisorUsageCost = (usage: unknown): number | undefined =>
62
+ export const advisorUsageCost = <Input>(usage: Input): number | undefined =>
64
63
  snapshotAdvisorUsage(usage)?.cost;
65
64
 
66
65
  /**
@@ -68,23 +67,21 @@ export const advisorUsageCost = (usage: unknown): number | undefined =>
68
67
  * Missing fields become zero only at this Pi API boundary; absent usage remains
69
68
  * undefined so an unavailable request is never presented as a zero-cost call.
70
69
  */
71
- export const advisorUsageForPi = (usage: unknown): Usage | undefined => {
70
+ export const advisorUsageForPi = <Input>(usage: Input): Usage | undefined => {
72
71
  const snapshot = snapshotAdvisorUsage(usage);
73
- if (!(snapshot && isRecord(usage))) {
72
+ if (!(snapshot && isRecordOf(usage))) {
74
73
  return undefined;
75
74
  }
76
- const cost = isRecord(usage.cost) ? usage.cost : undefined;
75
+ const cost = isRecordOf(usage.cost) ? usage.cost : undefined;
77
76
  const input = snapshot.input ?? 0;
78
77
  const output = snapshot.output ?? 0;
79
78
  const cacheRead = snapshot.cacheRead ?? 0;
80
79
  const cacheWrite = snapshot.cacheWrite ?? 0;
81
80
  const cacheWrite1h = finite(usage.cacheWrite1h);
82
81
  const reasoning = finite(usage.reasoning);
83
- return {
82
+ const piUsage: Usage = {
84
83
  cacheRead,
85
84
  cacheWrite,
86
- ...(cacheWrite1h === undefined ? {} : { cacheWrite1h }),
87
- ...(reasoning === undefined ? {} : { reasoning }),
88
85
  cost: {
89
86
  cacheRead: finite(cost?.cacheRead) ?? 0,
90
87
  cacheWrite: finite(cost?.cacheWrite) ?? 0,
@@ -97,6 +94,13 @@ export const advisorUsageForPi = (usage: unknown): Usage | undefined => {
97
94
  totalTokens:
98
95
  snapshot.totalTokens ?? input + output + cacheRead + cacheWrite,
99
96
  };
97
+ if (cacheWrite1h !== undefined) {
98
+ piUsage.cacheWrite1h = cacheWrite1h;
99
+ }
100
+ if (reasoning !== undefined) {
101
+ piUsage.reasoning = reasoning;
102
+ }
103
+ return piUsage;
100
104
  };
101
105
 
102
106
  /** Creates empty totals without treating absent usage as zero usage. */
@@ -107,7 +111,10 @@ export const emptyAdvisorUsageTotals = (): AdvisorUsageTotals => ({
107
111
  });
108
112
 
109
113
  /** Adds one direct Advisor response to session-local usage totals. */
110
- export const addAdvisorUsage = (totals: AdvisorUsageTotals, usage: unknown) => {
114
+ export const addAdvisorUsage = <Input>(
115
+ totals: AdvisorUsageTotals,
116
+ usage: Input
117
+ ) => {
111
118
  totals.calls += 1;
112
119
  const snapshot = snapshotAdvisorUsage(usage);
113
120
  if (!snapshot) {
@@ -125,7 +132,7 @@ export const addAdvisorUsage = (totals: AdvisorUsageTotals, usage: unknown) => {
125
132
  }
126
133
  };
127
134
 
128
- const formatTokens = (value: number) => {
135
+ export const formatTokenCount = (value: number) => {
129
136
  if (value < 1000) {
130
137
  return String(value);
131
138
  }
@@ -141,6 +148,8 @@ const formatTokens = (value: number) => {
141
148
  return `${Math.round(value / 1_000_000)}M`;
142
149
  };
143
150
 
151
+ const formatTokens = formatTokenCount;
152
+
144
153
  const formatCost = (value: number) => `$${value.toFixed(4)}`;
145
154
 
146
155
  const formatUsageFields = (usage: AdvisorUsageSnapshot): string | undefined => {
@@ -163,7 +172,7 @@ const formatUsageFields = (usage: AdvisorUsageSnapshot): string | undefined => {
163
172
  return tokens.join(" · ") || undefined;
164
173
  };
165
174
 
166
- export const formatAdvisorUsage = (usage: unknown): string | undefined => {
175
+ export const formatAdvisorUsage = <Input>(usage: Input): string | undefined => {
167
176
  const snapshot = snapshotAdvisorUsage(usage);
168
177
  return snapshot ? formatUsageFields(snapshot) : undefined;
169
178
  };