opencandle 0.11.0 → 0.11.1

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 (162) hide show
  1. package/README.md +5 -4
  2. package/dist/analysts/orchestrator.d.ts +2 -0
  3. package/dist/analysts/orchestrator.js +19 -0
  4. package/dist/analysts/orchestrator.js.map +1 -1
  5. package/dist/doctor/report.js +1 -1
  6. package/dist/doctor/report.js.map +1 -1
  7. package/dist/infra/cache.d.ts +6 -0
  8. package/dist/infra/cache.js +16 -6
  9. package/dist/infra/cache.js.map +1 -1
  10. package/dist/infra/freshness.d.ts +21 -0
  11. package/dist/infra/freshness.js +119 -0
  12. package/dist/infra/freshness.js.map +1 -0
  13. package/dist/infra/market-calendar.d.ts +14 -0
  14. package/dist/infra/market-calendar.js +137 -0
  15. package/dist/infra/market-calendar.js.map +1 -0
  16. package/dist/infra/rate-limiter.js +1 -0
  17. package/dist/infra/rate-limiter.js.map +1 -1
  18. package/dist/market-state/summaries.d.ts +8 -0
  19. package/dist/market-state/summaries.js +70 -0
  20. package/dist/market-state/summaries.js.map +1 -0
  21. package/dist/onboarding/providers.d.ts +25 -1
  22. package/dist/onboarding/providers.js +26 -0
  23. package/dist/onboarding/providers.js.map +1 -1
  24. package/dist/pi/opencandle-extension.js +44 -5
  25. package/dist/pi/opencandle-extension.js.map +1 -1
  26. package/dist/providers/alpha-vantage.js +6 -0
  27. package/dist/providers/alpha-vantage.js.map +1 -1
  28. package/dist/providers/coingecko.js +1 -0
  29. package/dist/providers/coingecko.js.map +1 -1
  30. package/dist/providers/polymarket.d.ts +2 -0
  31. package/dist/providers/polymarket.js +163 -0
  32. package/dist/providers/polymarket.js.map +1 -0
  33. package/dist/providers/wrap-provider.js +5 -3
  34. package/dist/providers/wrap-provider.js.map +1 -1
  35. package/dist/providers/yahoo-finance.d.ts +3 -0
  36. package/dist/providers/yahoo-finance.js +206 -10
  37. package/dist/providers/yahoo-finance.js.map +1 -1
  38. package/dist/routing/entity-extractor.js +16 -0
  39. package/dist/routing/entity-extractor.js.map +1 -1
  40. package/dist/routing/route-manifest.js +1 -1
  41. package/dist/routing/route-manifest.js.map +1 -1
  42. package/dist/routing/router-llm-client.js +18 -3
  43. package/dist/routing/router-llm-client.js.map +1 -1
  44. package/dist/routing/router.d.ts +1 -1
  45. package/dist/routing/router.js +274 -5
  46. package/dist/routing/router.js.map +1 -1
  47. package/dist/routing/slot-resolver.d.ts +1 -0
  48. package/dist/routing/slot-resolver.js +1 -1
  49. package/dist/routing/slot-resolver.js.map +1 -1
  50. package/dist/runtime/evidence.d.ts +1 -0
  51. package/dist/runtime/evidence.js.map +1 -1
  52. package/dist/runtime/numeric-claims.d.ts +23 -0
  53. package/dist/runtime/numeric-claims.js +100 -0
  54. package/dist/runtime/numeric-claims.js.map +1 -0
  55. package/dist/runtime/planning-evidence.js +1 -76
  56. package/dist/runtime/planning-evidence.js.map +1 -1
  57. package/dist/runtime/prompt-step.d.ts +10 -1
  58. package/dist/runtime/prompt-step.js +116 -2
  59. package/dist/runtime/prompt-step.js.map +1 -1
  60. package/dist/runtime/session-coordinator.d.ts +11 -1
  61. package/dist/runtime/session-coordinator.js +352 -49
  62. package/dist/runtime/session-coordinator.js.map +1 -1
  63. package/dist/runtime/validation.d.ts +3 -1
  64. package/dist/runtime/workflow-events.d.ts +1 -1
  65. package/dist/runtime/workflow-events.js.map +1 -1
  66. package/dist/runtime/workflow-types.d.ts +3 -0
  67. package/dist/runtime/workflow-types.js.map +1 -1
  68. package/dist/tools/fundamentals/comps.d.ts +1 -0
  69. package/dist/tools/fundamentals/comps.js +20 -9
  70. package/dist/tools/fundamentals/comps.js.map +1 -1
  71. package/dist/tools/fundamentals/dcf.js +183 -112
  72. package/dist/tools/fundamentals/dcf.js.map +1 -1
  73. package/dist/tools/index.d.ts +1 -0
  74. package/dist/tools/index.js +3 -0
  75. package/dist/tools/index.js.map +1 -1
  76. package/dist/tools/macro/event-probabilities.d.ts +8 -0
  77. package/dist/tools/macro/event-probabilities.js +121 -0
  78. package/dist/tools/macro/event-probabilities.js.map +1 -0
  79. package/dist/tools/market/crypto-price.d.ts +4 -1
  80. package/dist/tools/market/crypto-price.js +10 -1
  81. package/dist/tools/market/crypto-price.js.map +1 -1
  82. package/dist/tools/market/screen-stocks.js +14 -3
  83. package/dist/tools/market/screen-stocks.js.map +1 -1
  84. package/dist/tools/market/stock-quote.d.ts +4 -1
  85. package/dist/tools/market/stock-quote.js +9 -4
  86. package/dist/tools/market/stock-quote.js.map +1 -1
  87. package/dist/tools/options/option-chain.d.ts +4 -1
  88. package/dist/tools/options/option-chain.js +12 -1
  89. package/dist/tools/options/option-chain.js.map +1 -1
  90. package/dist/tools/portfolio/risk-analysis.js +1 -1
  91. package/dist/tools/portfolio/risk-analysis.js.map +1 -1
  92. package/dist/tools/technical/indicators.js +1 -1
  93. package/dist/tools/technical/indicators.js.map +1 -1
  94. package/dist/types/fundamentals.d.ts +1 -0
  95. package/dist/types/index.d.ts +1 -0
  96. package/dist/types/market.d.ts +2 -0
  97. package/dist/types/options.d.ts +1 -0
  98. package/dist/types/prediction-markets.d.ts +13 -0
  99. package/dist/types/prediction-markets.js +2 -0
  100. package/dist/types/prediction-markets.js.map +1 -0
  101. package/gui/server/chat-event-adapter.ts +89 -5
  102. package/gui/server/http-routes.ts +285 -37
  103. package/gui/server/invoke-tool.ts +14 -13
  104. package/gui/server/live-chat-event-adapter.ts +37 -2
  105. package/gui/server/market-state-api.ts +63 -5
  106. package/gui/server/projector.ts +132 -3
  107. package/gui/server/session-actions.ts +32 -40
  108. package/gui/server/session-entry-wait.ts +22 -3
  109. package/gui/server/ws-hub.ts +16 -4
  110. package/gui/shared/chat-events.ts +10 -1
  111. package/gui/shared/event-reducer.ts +1 -0
  112. package/gui/web/dist/assets/CatalogOverlay-DZ1niyQm.js +1 -0
  113. package/gui/web/dist/assets/index-D4F9AJnn.css +2 -0
  114. package/gui/web/dist/assets/index-DtqMMBTr.js +65 -0
  115. package/gui/web/dist/index.html +2 -2
  116. package/package.json +8 -13
  117. package/src/analysts/orchestrator.ts +20 -0
  118. package/src/doctor/report.ts +1 -1
  119. package/src/infra/cache.ts +24 -11
  120. package/src/infra/freshness.ts +165 -0
  121. package/src/infra/market-calendar.ts +193 -0
  122. package/src/infra/rate-limiter.ts +1 -0
  123. package/src/market-state/summaries.ts +75 -0
  124. package/src/onboarding/providers.ts +29 -1
  125. package/src/pi/opencandle-extension.ts +55 -5
  126. package/src/providers/alpha-vantage.ts +6 -0
  127. package/src/providers/coingecko.ts +2 -0
  128. package/src/providers/polymarket.ts +214 -0
  129. package/src/providers/wrap-provider.ts +5 -3
  130. package/src/providers/yahoo-finance.ts +339 -27
  131. package/src/routing/entity-extractor.ts +17 -0
  132. package/src/routing/route-manifest.ts +1 -1
  133. package/src/routing/router-llm-client.ts +31 -19
  134. package/src/routing/router.ts +340 -5
  135. package/src/routing/slot-resolver.ts +1 -1
  136. package/src/runtime/evidence.ts +1 -0
  137. package/src/runtime/numeric-claims.ts +108 -0
  138. package/src/runtime/planning-evidence.ts +6 -91
  139. package/src/runtime/prompt-step.ts +127 -2
  140. package/src/runtime/session-coordinator.ts +462 -57
  141. package/src/runtime/validation.ts +1 -1
  142. package/src/runtime/workflow-events.ts +2 -0
  143. package/src/runtime/workflow-types.ts +3 -0
  144. package/src/tools/fundamentals/comps.ts +25 -14
  145. package/src/tools/fundamentals/dcf.ts +204 -124
  146. package/src/tools/index.ts +3 -0
  147. package/src/tools/macro/event-probabilities.ts +141 -0
  148. package/src/tools/market/crypto-price.ts +14 -2
  149. package/src/tools/market/screen-stocks.ts +14 -3
  150. package/src/tools/market/stock-quote.ts +49 -43
  151. package/src/tools/options/option-chain.ts +16 -2
  152. package/src/tools/portfolio/risk-analysis.ts +1 -1
  153. package/src/tools/technical/indicators.ts +1 -1
  154. package/src/types/fundamentals.ts +1 -0
  155. package/src/types/index.ts +1 -0
  156. package/src/types/market.ts +2 -0
  157. package/src/types/options.ts +1 -0
  158. package/src/types/prediction-markets.ts +13 -0
  159. package/gui/server/chat-run-session.ts +0 -16
  160. package/gui/web/dist/assets/CatalogOverlay-ChRTKNlf.js +0 -1
  161. package/gui/web/dist/assets/index-BzyqyVnd.css +0 -2
  162. package/gui/web/dist/assets/index-DvMjkOP9.js +0 -65
@@ -1,3 +1,6 @@
1
+ import type { SessionEntry } from "@earendil-works/pi-coding-agent";
2
+ import type { FreshnessStamp } from "../infra/freshness.js";
3
+ import type { EvidenceRecord } from "./evidence.js";
1
4
  import type { StepOutput, WorkflowStep } from "./workflow-types.js";
2
5
 
3
6
  /**
@@ -43,14 +46,98 @@ export function promptStep(
43
46
  * Create a StepOutput for a prompt-based step (no structured evidence yet).
44
47
  * Evidence will be captured separately via tool call hooks.
45
48
  */
46
- export function promptStepOutput(stepIndex: number, stepType: string): StepOutput {
49
+ export function promptStepOutput(
50
+ stepIndex: number,
51
+ stepType: string,
52
+ options: { evidence?: EvidenceRecord[]; rawText?: string } = {},
53
+ ): StepOutput {
47
54
  return {
48
55
  stepIndex,
49
56
  stepType,
50
- evidence: [],
57
+ evidence: options.evidence ?? [],
58
+ ...(options.rawText ? { rawText: options.rawText } : {}),
51
59
  };
52
60
  }
53
61
 
62
+ /** Capture compact evidence records from session entries produced by one step. */
63
+ export function captureToolEvidence(entries: SessionEntry[]): EvidenceRecord[] {
64
+ const calls = new Map<string, { tool: string; args: unknown; startedAt: string }>();
65
+ const evidence: EvidenceRecord[] = [];
66
+
67
+ for (const entry of entries) {
68
+ if (entry.type !== "message") continue;
69
+ const message = entry.message as unknown as Record<string, unknown>;
70
+
71
+ if (message.role === "assistant") {
72
+ for (const part of Array.isArray(message.content) ? message.content : []) {
73
+ const record = asRecord(part);
74
+ if (record.type !== "toolCall") continue;
75
+ const id = stringValue(record.id);
76
+ const tool = stringValue(record.name);
77
+ if (!id || !tool) continue;
78
+ calls.set(id, {
79
+ tool,
80
+ args: record.arguments ?? record.args ?? {},
81
+ startedAt: entry.timestamp,
82
+ });
83
+ }
84
+ continue;
85
+ }
86
+
87
+ if (message.role !== "toolResult") continue;
88
+ const toolCallId = stringValue(message.toolCallId);
89
+ const pending = toolCallId ? calls.get(toolCallId) : undefined;
90
+ const tool = pending?.tool ?? stringValue(message.toolName);
91
+ if (!tool) continue;
92
+ const resultValue = message.details ?? message.content ?? "";
93
+ const freshness = extractFreshness(resultValue);
94
+ const serializedResult = serialize(resultValue);
95
+ evidence.push({
96
+ label: `tool:${tool}`,
97
+ value: {
98
+ tool,
99
+ args: truncate(serialize(pending?.args ?? {}), 500),
100
+ ...(freshness ? { freshness } : {}),
101
+ resultDigest: {
102
+ preview: truncate(serializedResult, 500),
103
+ totalLength: serializedResult.length,
104
+ },
105
+ startedAt: pending?.startedAt ?? entry.timestamp,
106
+ completedAt: entry.timestamp,
107
+ },
108
+ provenance: {
109
+ source: "computed",
110
+ timestamp: freshness?.providerDataAt ?? freshness?.fetchedAt ?? entry.timestamp,
111
+ provider: tool,
112
+ confidence: message.isError === true ? 0.5 : undefined,
113
+ },
114
+ });
115
+ }
116
+
117
+ return evidence;
118
+ }
119
+
120
+ /** Extract assistant text emitted during a step, preserving final response order. */
121
+ export function extractAssistantText(entries: SessionEntry[]): string {
122
+ return entries
123
+ .filter((entry) => entry.type === "message")
124
+ .flatMap((entry) => {
125
+ const message = (entry as Extract<SessionEntry, { type: "message" }>)
126
+ .message as unknown as Record<string, unknown>;
127
+ if (message.role !== "assistant") return [];
128
+ const content = message.content;
129
+ if (typeof content === "string") return [content];
130
+ if (!Array.isArray(content)) return [];
131
+ return content
132
+ .map((part) => asRecord(part))
133
+ .filter((part) => part.type === "text")
134
+ .map((part) => stringValue(part.text) ?? "")
135
+ .filter(Boolean);
136
+ })
137
+ .join("\n")
138
+ .trim();
139
+ }
140
+
54
141
  /**
55
142
  * Extract just the WorkflowStep metadata from PromptStep definitions
56
143
  * (dropping the prompt field) for passing to WorkflowRunner.
@@ -58,3 +145,41 @@ export function promptStepOutput(stepIndex: number, stepType: string): StepOutpu
58
145
  export function toStepDefinitions(steps: PromptStep[]): Omit<WorkflowStep, "status">[] {
59
146
  return steps.map(({ prompt: _prompt, ...step }) => step);
60
147
  }
148
+
149
+ function serialize(value: unknown): string {
150
+ if (typeof value === "string") return value;
151
+ try {
152
+ return JSON.stringify(value);
153
+ } catch {
154
+ return String(value);
155
+ }
156
+ }
157
+
158
+ function truncate(value: string, maxLength: number): string {
159
+ return value.length > maxLength ? value.slice(0, maxLength) : value;
160
+ }
161
+
162
+ function asRecord(value: unknown): Record<string, unknown> {
163
+ return typeof value === "object" && value !== null && !Array.isArray(value)
164
+ ? (value as Record<string, unknown>)
165
+ : {};
166
+ }
167
+
168
+ function stringValue(value: unknown): string | undefined {
169
+ return typeof value === "string" && value.length > 0 ? value : undefined;
170
+ }
171
+
172
+ function extractFreshness(value: unknown): FreshnessStamp | undefined {
173
+ const record = asRecord(value);
174
+ return isFreshnessStamp(record.freshness) ? record.freshness : undefined;
175
+ }
176
+
177
+ function isFreshnessStamp(value: unknown): value is FreshnessStamp {
178
+ const record = asRecord(value);
179
+ return (
180
+ typeof record.fetchedAt === "string" &&
181
+ typeof record.cacheStatus === "string" &&
182
+ typeof record.marketSession === "string" &&
183
+ typeof record.isStaleForSession === "boolean"
184
+ );
185
+ }