@oh-my-pi/pi-coding-agent 16.1.13 → 16.1.15

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 (153) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/dist/cli.js +5615 -2833
  3. package/dist/types/advisor/runtime.d.ts +3 -0
  4. package/dist/types/config/settings-schema.d.ts +64 -14
  5. package/dist/types/eval/__tests__/julia-prelude.test.d.ts +1 -0
  6. package/dist/types/eval/backend-helpers.d.ts +23 -0
  7. package/dist/types/eval/executor-base.d.ts +118 -0
  8. package/dist/types/eval/index.d.ts +2 -0
  9. package/dist/types/eval/jl/executor.d.ts +44 -0
  10. package/dist/types/eval/jl/index.d.ts +11 -0
  11. package/dist/types/eval/jl/kernel.d.ts +28 -0
  12. package/dist/types/eval/jl/prelude.d.ts +1 -0
  13. package/dist/types/eval/jl/runtime.d.ts +22 -0
  14. package/dist/types/eval/kernel-base.d.ts +105 -0
  15. package/dist/types/eval/py/kernel.d.ts +3 -61
  16. package/dist/types/eval/rb/executor.d.ts +77 -0
  17. package/dist/types/eval/rb/index.d.ts +11 -0
  18. package/dist/types/eval/rb/kernel.d.ts +31 -0
  19. package/dist/types/eval/rb/prelude.d.ts +1 -0
  20. package/dist/types/eval/rb/runtime.d.ts +23 -0
  21. package/dist/types/eval/runtime-env.d.ts +24 -0
  22. package/dist/types/eval/types.d.ts +3 -3
  23. package/dist/types/export/share.d.ts +8 -1
  24. package/dist/types/extensibility/extensions/runner.d.ts +2 -15
  25. package/dist/types/extensibility/hooks/loader.d.ts +1 -25
  26. package/dist/types/extensibility/session-handler-types.d.ts +23 -0
  27. package/dist/types/jsonrpc/message-framing.d.ts +35 -0
  28. package/dist/types/mcp/transports/stdio.d.ts +12 -1
  29. package/dist/types/mnemopi/embed-client.d.ts +7 -24
  30. package/dist/types/modes/components/chat-transcript-builder.d.ts +1 -1
  31. package/dist/types/modes/components/custom-editor.d.ts +11 -0
  32. package/dist/types/modes/components/selector-helpers.d.ts +53 -0
  33. package/dist/types/modes/components/status-line/context-thresholds.d.ts +4 -3
  34. package/dist/types/modes/components/status-line/types.d.ts +1 -0
  35. package/dist/types/modes/interactive-mode.d.ts +0 -2
  36. package/dist/types/modes/theme/theme.d.ts +8 -1
  37. package/dist/types/modes/types.d.ts +0 -2
  38. package/dist/types/modes/utils/copy-targets.d.ts +1 -1
  39. package/dist/types/modes/utils/interactive-context-helpers.d.ts +14 -0
  40. package/dist/types/modes/utils/transcript-render-helpers.d.ts +54 -0
  41. package/dist/types/sdk.d.ts +1 -1
  42. package/dist/types/secrets/obfuscator.d.ts +3 -3
  43. package/dist/types/session/agent-session.d.ts +2 -2
  44. package/dist/types/stt/asr-client.d.ts +3 -29
  45. package/dist/types/subprocess/worker-client.d.ts +149 -0
  46. package/dist/types/subprocess/worker-runtime.d.ts +107 -0
  47. package/dist/types/tiny/title-client.d.ts +14 -34
  48. package/dist/types/tools/eval-backends.d.ts +6 -3
  49. package/dist/types/tools/eval-render.d.ts +6 -5
  50. package/dist/types/tools/eval.d.ts +13 -15
  51. package/dist/types/tools/index.d.ts +3 -3
  52. package/dist/types/tts/tts-client.d.ts +3 -28
  53. package/dist/types/tui/code-cell.d.ts +7 -0
  54. package/dist/types/utils/file-display-mode.d.ts +1 -1
  55. package/dist/types/utils/shell-snapshot.d.ts +10 -0
  56. package/dist/types/web/parallel.d.ts +6 -0
  57. package/dist/types/web/search/providers/perplexity.d.ts +17 -3
  58. package/package.json +12 -12
  59. package/src/advisor/__tests__/advisor.test.ts +114 -0
  60. package/src/advisor/runtime.ts +129 -1
  61. package/src/config/model-registry.ts +12 -4
  62. package/src/config/settings-schema.ts +74 -18
  63. package/src/config/settings.ts +5 -0
  64. package/src/dap/client.ts +13 -107
  65. package/src/eval/__tests__/julia-prelude.test.ts +77 -0
  66. package/src/eval/backend-helpers.ts +48 -0
  67. package/src/eval/executor-base.ts +425 -0
  68. package/src/eval/index.ts +2 -0
  69. package/src/eval/jl/executor.ts +540 -0
  70. package/src/eval/jl/index.ts +54 -0
  71. package/src/eval/jl/kernel.ts +235 -0
  72. package/src/eval/jl/prelude.jl +930 -0
  73. package/src/eval/jl/prelude.ts +3 -0
  74. package/src/eval/jl/runner.jl +634 -0
  75. package/src/eval/jl/runtime.ts +118 -0
  76. package/src/eval/js/index.ts +3 -14
  77. package/src/eval/kernel-base.ts +569 -0
  78. package/src/eval/py/executor.ts +43 -252
  79. package/src/eval/py/index.ts +9 -20
  80. package/src/eval/py/kernel.ts +29 -544
  81. package/src/eval/rb/executor.ts +504 -0
  82. package/src/eval/rb/index.ts +54 -0
  83. package/src/eval/rb/kernel.ts +230 -0
  84. package/src/eval/rb/prelude.rb +721 -0
  85. package/src/eval/rb/prelude.ts +3 -0
  86. package/src/eval/rb/runner.rb +474 -0
  87. package/src/eval/rb/runtime.ts +132 -0
  88. package/src/eval/runtime-env.ts +104 -0
  89. package/src/eval/types.ts +3 -3
  90. package/src/exec/bash-executor.ts +44 -0
  91. package/src/export/share.ts +51 -28
  92. package/src/extensibility/extensions/runner.ts +4 -11
  93. package/src/extensibility/hooks/loader.ts +3 -21
  94. package/src/extensibility/session-handler-types.ts +21 -0
  95. package/src/internal-urls/docs-index.generated.txt +1 -1
  96. package/src/jsonrpc/message-framing.ts +142 -0
  97. package/src/lsp/client.ts +13 -109
  98. package/src/mcp/transports/stdio.ts +20 -4
  99. package/src/mnemopi/embed-client.ts +43 -198
  100. package/src/modes/components/agent-dashboard.ts +17 -40
  101. package/src/modes/components/chat-transcript-builder.ts +18 -102
  102. package/src/modes/components/custom-editor.test.ts +22 -0
  103. package/src/modes/components/custom-editor.ts +29 -1
  104. package/src/modes/components/extensions/extension-dashboard.ts +4 -13
  105. package/src/modes/components/extensions/extension-list.ts +16 -44
  106. package/src/modes/components/footer.ts +4 -3
  107. package/src/modes/components/history-search.ts +4 -16
  108. package/src/modes/components/selector-helpers.ts +129 -0
  109. package/src/modes/components/settings-selector.ts +7 -5
  110. package/src/modes/components/status-line/component.ts +5 -1
  111. package/src/modes/components/status-line/context-thresholds.ts +11 -3
  112. package/src/modes/components/status-line/segments.ts +1 -1
  113. package/src/modes/components/status-line/types.ts +1 -0
  114. package/src/modes/components/tree-selector.ts +13 -18
  115. package/src/modes/controllers/command-controller.ts +1 -0
  116. package/src/modes/controllers/event-controller.ts +3 -9
  117. package/src/modes/controllers/input-controller.ts +32 -54
  118. package/src/modes/interactive-mode.ts +5 -7
  119. package/src/modes/theme/theme.ts +35 -0
  120. package/src/modes/types.ts +0 -2
  121. package/src/modes/utils/copy-targets.ts +3 -2
  122. package/src/modes/utils/interactive-context-helpers.ts +27 -0
  123. package/src/modes/utils/transcript-render-helpers.ts +157 -0
  124. package/src/modes/utils/ui-helpers.ts +21 -126
  125. package/src/prompts/system/system-prompt.md +5 -5
  126. package/src/prompts/tools/bash.md +2 -3
  127. package/src/prompts/tools/eval.md +6 -4
  128. package/src/prompts/tools/find.md +0 -4
  129. package/src/prompts/tools/read.md +1 -2
  130. package/src/prompts/tools/replace.md +1 -1
  131. package/src/sdk.ts +13 -7
  132. package/src/secrets/obfuscator.ts +3 -9
  133. package/src/session/agent-session.ts +42 -9
  134. package/src/slash-commands/builtin-registry.ts +2 -1
  135. package/src/stt/asr-client.ts +35 -215
  136. package/src/stt/asr-worker.ts +29 -181
  137. package/src/subprocess/worker-client.ts +297 -0
  138. package/src/subprocess/worker-runtime.ts +277 -0
  139. package/src/task/executor.ts +4 -4
  140. package/src/tiny/title-client.ts +53 -219
  141. package/src/tiny/worker.ts +29 -180
  142. package/src/tools/eval-backends.ts +10 -3
  143. package/src/tools/eval-render.ts +17 -8
  144. package/src/tools/eval.ts +187 -22
  145. package/src/tools/index.ts +51 -28
  146. package/src/tts/tts-client.ts +38 -206
  147. package/src/tts/tts-worker.ts +23 -97
  148. package/src/tui/code-cell.ts +12 -1
  149. package/src/utils/file-display-mode.ts +2 -3
  150. package/src/utils/shell-snapshot.ts +63 -1
  151. package/src/web/parallel.ts +43 -42
  152. package/src/web/search/providers/parallel.ts +10 -99
  153. package/src/web/search/providers/perplexity.ts +18 -6
@@ -1,4 +1,3 @@
1
- import { createRequire } from "node:module";
2
1
  import * as path from "node:path";
3
2
  import type {
4
3
  ProgressInfo,
@@ -6,16 +5,18 @@ import type {
6
5
  TextGenerationStringOutput,
7
6
  StoppingCriteria as TransformersStoppingCriteria,
8
7
  } from "@huggingface/transformers";
9
- import {
10
- ensureRuntimeInstalled,
11
- getTinyModelsCacheDir,
12
- installRuntimeModuleResolver,
13
- isCompiledBinary,
14
- prompt,
15
- resolveRuntimeModule,
16
- } from "@oh-my-pi/pi-utils";
17
- import packageJson from "../../package.json" with { type: "json" };
8
+ import { getTinyModelsCacheDir, prompt } from "@oh-my-pi/pi-utils";
18
9
  import tinyTitleSystemPrompt from "../prompts/system/tiny-title-system.md" with { type: "text" };
10
+ import {
11
+ errorMessage,
12
+ errorText,
13
+ getTransformersVersionSpec,
14
+ loadTransformersRuntime,
15
+ MemoizedRuntime,
16
+ replayCachedReady,
17
+ sendLog,
18
+ sendProgress,
19
+ } from "../subprocess/worker-runtime";
19
20
  import { resolveTinyModelDevicePreference, type TinyModelDevice, tinyModelDeviceLoadOrder } from "./device";
20
21
  import { resolveTinyModelDtypeOverride, type TinyModelDtype } from "./dtype";
21
22
  import {
@@ -25,7 +26,7 @@ import {
25
26
  type TinyTitleLocalModelSpec,
26
27
  } from "./models";
27
28
  import { formatTitleUserMessage, normalizeGeneratedTitle } from "./text";
28
- import type { TinyTitleProgressEvent, TinyTitleTransport, TinyTitleWorkerInbound } from "./title-protocol";
29
+ import type { TinyTitleTransport, TinyTitleWorkerInbound } from "./title-protocol";
29
30
 
30
31
  const TITLE_PREFILL = "<title>";
31
32
  const TITLE_CLOSE = "</title>";
@@ -34,9 +35,6 @@ const STOP_DECODE_WINDOW_TOKENS = 32;
34
35
  const MEMORY_COMPLETION_DEFAULT_MAX_NEW_TOKENS = 256;
35
36
  const COMPLETION_MAX_NEW_TOKENS = 1024;
36
37
  const TINY_TITLE_SYSTEM_PROMPT = prompt.render(tinyTitleSystemPrompt);
37
- const TRANSFORMERS_PACKAGE = "@huggingface/transformers";
38
- const COMPILED_TRANSFORMERS_VERSION = process.env.PI_TINY_TRANSFORMERS_VERSION;
39
- const sourceRequire = createRequire(import.meta.url);
40
38
 
41
39
  const tinyModelDevicePreference = resolveTinyModelDevicePreference();
42
40
  const tinyModelDtypeOverride = resolveTinyModelDtypeOverride();
@@ -64,51 +62,11 @@ interface TransformersRuntime {
64
62
 
65
63
  const pipelines = new Map<TinyLocalModelKey, Promise<TextGenerationPipeline>>();
66
64
 
67
- function resolveTransformersVersionSpec(): string {
68
- const manifest = packageJson as {
69
- optionalDependencies?: Record<string, string>;
70
- dependencies?: Record<string, string>;
71
- };
72
- const versionSpec =
73
- manifest.optionalDependencies?.[TRANSFORMERS_PACKAGE] ?? manifest.dependencies?.[TRANSFORMERS_PACKAGE];
74
- if (!versionSpec) throw new Error(`${TRANSFORMERS_PACKAGE} is missing from package.json optionalDependencies`);
75
- if (!versionSpec.startsWith("catalog:")) return versionSpec;
76
- if (COMPILED_TRANSFORMERS_VERSION) return COMPILED_TRANSFORMERS_VERSION;
77
- const installed = sourceRequire(`${TRANSFORMERS_PACKAGE}/package.json`) as { version: string };
78
- return installed.version;
79
- }
80
- let cachedTransformersVersionSpec: string | undefined;
81
- /**
82
- * Lazily resolve (and memoize) the transformers version spec. In the
83
- * `catalog:` case {@link resolveTransformersVersionSpec} `require`s the
84
- * installed `@huggingface/transformers/package.json`, so touching it forces
85
- * the dependency to exist. Defer it to the compiled-binary runtime-install
86
- * path — which only runs when a local title model is actually generated or
87
- * downloaded — so loading this worker (smoke-test ping, online title path)
88
- * never triggers the transformers resolve/install dance.
89
- */
90
- function getTransformersVersionSpec(): string {
91
- cachedTransformersVersionSpec ??= resolveTransformersVersionSpec();
92
- return cachedTransformersVersionSpec;
93
- }
94
65
  function getTransformersRuntimeKey(): string {
95
66
  return getTransformersVersionSpec().replace(/[^A-Za-z0-9._-]/g, "_");
96
67
  }
97
68
  let generateQueue = Promise.resolve();
98
- let transformersRuntime: Promise<TransformersRuntime> | null = null;
99
-
100
- function errorText(error: unknown): string {
101
- return error instanceof Error ? (error.stack ?? error.message) : String(error);
102
- }
103
-
104
- function sendLog(
105
- transport: TinyTitleTransport,
106
- level: "debug" | "warn" | "error",
107
- msg: string,
108
- meta?: Record<string, unknown>,
109
- ): void {
110
- transport.send({ type: "log", level, msg, meta });
111
- }
69
+ const transformersRuntime = new MemoizedRuntime<TransformersRuntime>();
112
70
 
113
71
  function getTinyTitleRuntimeDir(): string {
114
72
  return path.join(
@@ -118,74 +76,6 @@ function getTinyTitleRuntimeDir(): string {
118
76
  );
119
77
  }
120
78
 
121
- function sendRuntimeInstallProgress(
122
- transport: TinyTitleTransport,
123
- requestId: string,
124
- modelKey: TinyLocalModelKey,
125
- status: "initiate" | "download" | "done",
126
- ): void {
127
- transport.send({
128
- type: "progress",
129
- id: requestId,
130
- event: {
131
- modelKey,
132
- status,
133
- name: `${TRANSFORMERS_PACKAGE}@${getTransformersVersionSpec()}`,
134
- },
135
- });
136
- }
137
-
138
- /**
139
- * Prepare the freshly-installed compiled runtime for loading: stub `sharp`
140
- * (the tiny models are text-generation only, so the native image pipeline is
141
- * dead weight) and patch the module resolver so Transformers.js's bare requires
142
- * (`onnxruntime-node`, `onnxruntime-common`) resolve against the cache. Returns
143
- * the absolute Transformers.js entrypoint to `require`.
144
- */
145
- async function prepareCompiledRuntime(runtimeDir: string): Promise<string> {
146
- const nodeModules = path.join(runtimeDir, "node_modules");
147
- const sharpStub = path.join(runtimeDir, "omp-sharp-stub.cjs");
148
- await Bun.write(sharpStub, "module.exports = {};\n");
149
- installRuntimeModuleResolver({ runtimeNodeModules: nodeModules, stubs: { sharp: sharpStub } });
150
- const entry = resolveRuntimeModule(nodeModules, TRANSFORMERS_PACKAGE);
151
- if (!entry) throw new Error(`Unable to resolve ${TRANSFORMERS_PACKAGE} in compiled runtime at ${nodeModules}`);
152
- return entry;
153
- }
154
-
155
- function configureTransformers(transformers: TransformersRuntime): TransformersRuntime {
156
- transformers.env.cacheDir = getTinyModelsCacheDir();
157
- transformers.env.allowLocalModels = false;
158
- transformers.env.logLevel = transformers.LogLevel.ERROR;
159
- return transformers;
160
- }
161
-
162
- async function loadTransformers(
163
- transport: TinyTitleTransport,
164
- requestId: string,
165
- modelKey: TinyLocalModelKey,
166
- ): Promise<TransformersRuntime> {
167
- if (transformersRuntime) return transformersRuntime;
168
- transformersRuntime = (async () => {
169
- if (!isCompiledBinary()) return configureTransformers(sourceRequire(TRANSFORMERS_PACKAGE) as TransformersRuntime);
170
- const runtimeDir = await ensureRuntimeInstalled({
171
- runtimeDir: getTinyTitleRuntimeDir(),
172
- install: {
173
- dependencies: { [TRANSFORMERS_PACKAGE]: getTransformersVersionSpec() },
174
- trustedDependencies: ["onnxruntime-node"],
175
- },
176
- probePackage: TRANSFORMERS_PACKAGE,
177
- onPhase: phase => sendRuntimeInstallProgress(transport, requestId, modelKey, phase),
178
- });
179
- const entry = await prepareCompiledRuntime(runtimeDir);
180
- const require_ = createRequire(entry);
181
- return configureTransformers(require_(entry) as TransformersRuntime);
182
- })().catch(error => {
183
- transformersRuntime = null;
184
- throw error;
185
- });
186
- return transformersRuntime;
187
- }
188
-
189
79
  function createStopOnTextCriteria(
190
80
  transformers: TransformersRuntime,
191
81
  tokenizer: TextGenerationPipeline["tokenizer"],
@@ -215,48 +105,6 @@ function createStopOnTextCriteria(
215
105
  return new StopOnTextCriteria();
216
106
  }
217
107
 
218
- function toProgressEvent(modelKey: TinyLocalModelKey, info: ProgressInfo): TinyTitleProgressEvent {
219
- if (info.status === "ready") {
220
- return { modelKey, status: info.status, task: info.task, model: info.model };
221
- }
222
- if (info.status === "progress_total") {
223
- return {
224
- modelKey,
225
- status: info.status,
226
- name: info.name,
227
- progress: info.progress,
228
- loaded: info.loaded,
229
- total: info.total,
230
- files: info.files,
231
- };
232
- }
233
- if (info.status === "progress") {
234
- return {
235
- modelKey,
236
- status: info.status,
237
- name: info.name,
238
- file: info.file,
239
- progress: info.progress,
240
- loaded: info.loaded,
241
- total: info.total,
242
- };
243
- }
244
- return { modelKey, status: info.status, name: info.name, file: info.file };
245
- }
246
-
247
- function sendProgress(
248
- transport: TinyTitleTransport,
249
- id: string,
250
- modelKey: TinyLocalModelKey,
251
- info: ProgressInfo,
252
- ): void {
253
- transport.send({ type: "progress", id, event: toProgressEvent(modelKey, info) });
254
- }
255
-
256
- function errorMessage(error: unknown): string {
257
- return error instanceof Error ? error.message : String(error);
258
- }
259
-
260
108
  async function loadPipelineOnDevice(
261
109
  transformers: TransformersRuntime,
262
110
  spec: TinyTitleLocalModelSpec,
@@ -318,21 +166,16 @@ async function loadPipeline(
318
166
  const spec = getTinyLocalModelSpec(modelKey);
319
167
  if (!spec) throw new Error(`Unknown tiny local model: ${modelKey}`);
320
168
  if (spec.unsupportedReason) throw new Error(`${modelKey} is unavailable: ${spec.unsupportedReason}`);
321
- const cached = pipelines.get(modelKey);
322
- if (cached) {
323
- void cached
324
- .then(() => {
325
- transport.send({
326
- type: "progress",
327
- id: requestId,
328
- event: { modelKey, status: "ready", task: "text-generation", model: spec.repo },
329
- });
330
- })
331
- .catch(() => undefined);
332
- return cached;
333
- }
169
+ const cached = replayCachedReady(pipelines, modelKey, transport, requestId, "text-generation", spec.repo);
170
+ if (cached) return cached;
334
171
 
335
- const transformers = await loadTransformers(transport, requestId, modelKey);
172
+ const transformers = await loadTransformersRuntime(
173
+ transformersRuntime,
174
+ transport,
175
+ requestId,
176
+ modelKey,
177
+ getTinyTitleRuntimeDir,
178
+ );
336
179
  const startedAt = performance.now();
337
180
  const loaded = loadPipelineWithDeviceFallback(transformers, spec, modelKey, transport, requestId).then(
338
181
  ({ generator, device }) => {
@@ -393,7 +236,13 @@ async function generateTitle(
393
236
  ): Promise<string | null> {
394
237
  const generator = await loadPipeline(modelKey, transport, requestId);
395
238
  const promptText = buildPrompt(generator, message, systemPrompt);
396
- const transformers = await loadTransformers(transport, requestId, modelKey);
239
+ const transformers = await loadTransformersRuntime(
240
+ transformersRuntime,
241
+ transport,
242
+ requestId,
243
+ modelKey,
244
+ getTinyTitleRuntimeDir,
245
+ );
397
246
  const output = (await generator(promptText, {
398
247
  max_new_tokens: TITLE_MAX_NEW_TOKENS,
399
248
  do_sample: false,
@@ -4,24 +4,31 @@ import type { ToolSession } from ".";
4
4
  export interface EvalBackendsAllowance {
5
5
  python: boolean;
6
6
  js: boolean;
7
+ ruby: boolean;
8
+ julia: boolean;
7
9
  }
8
10
 
9
- /** Read per-backend allowance from settings (defaults true). */
11
+ /** Read per-backend allowance from settings (py/js default on; rb/jl opt-in, default off). */
10
12
  export function readEvalBackendsAllowance(session: ToolSession): EvalBackendsAllowance {
11
13
  return {
12
14
  python: session.settings.get("eval.py") ?? true,
13
15
  js: session.settings.get("eval.js") ?? true,
16
+ ruby: session.settings.get("eval.rb") ?? false,
17
+ julia: session.settings.get("eval.jl") ?? false,
14
18
  };
15
19
  }
16
20
 
17
21
  /**
18
- * Materialize the active eval backend allowance: PI_PY / PI_JS env flags
19
- * override the per-key settings; otherwise settings (defaults true) win.
22
+ * Materialize the active eval backend allowance: PI_PY / PI_JS / PI_RB / PI_JL
23
+ * env flags override the per-key settings; otherwise settings win (py/js default
24
+ * on, rb/jl default off).
20
25
  */
21
26
  export function resolveEvalBackends(session: ToolSession): EvalBackendsAllowance {
22
27
  const settings = readEvalBackendsAllowance(session);
23
28
  return {
24
29
  python: $flag("PI_PY", settings.python),
25
30
  js: $flag("PI_JS", settings.js),
31
+ ruby: $flag("PI_RB", settings.ruby),
32
+ julia: $flag("PI_JL", settings.julia),
26
33
  };
27
34
  }
@@ -2,11 +2,12 @@
2
2
  * TUI rendering for the eval tool.
3
3
  *
4
4
  * Split out from `eval.ts` so the renderer can be imported by `renderers.ts`
5
- * without dragging the eval *runtime* (JS/Python backends -> agent bridge ->
6
- * task executor -> sdk -> extension loader -> root barrel) into the renderer
7
- * module graph. That transitive chain re-enters `renderers.ts` while `eval.ts`
8
- * is still initializing, which previously crashed module load with a TDZ
9
- * `Cannot access 'evalToolRenderer' before initialization`.
5
+ * without dragging the eval *runtime* (JS/Python/Ruby/Julia backends ->
6
+ * agent bridge -> task executor -> sdk -> extension loader -> root barrel)
7
+ * into the renderer module graph. That transitive chain re-enters
8
+ * `renderers.ts` while `eval.ts` is still initializing, which previously
9
+ * crashed module load with a TDZ `Cannot access 'evalToolRenderer' before
10
+ * initialization`.
10
11
  */
11
12
  import type { Component } from "@oh-my-pi/pi-tui";
12
13
  import { Markdown, Text } from "@oh-my-pi/pi-tui";
@@ -41,8 +42,11 @@ import {
41
42
  } from "./render-utils";
42
43
  export const EVAL_DEFAULT_PREVIEW_LINES = 10;
43
44
 
44
- function languageForHighlighter(language: EvalLanguage | undefined): "python" | "javascript" {
45
- return language === "js" ? "javascript" : "python";
45
+ function languageForHighlighter(language: EvalLanguage | undefined): "python" | "javascript" | "ruby" | "julia" {
46
+ if (language === "js") return "javascript";
47
+ if (language === "ruby") return "ruby";
48
+ if (language === "julia") return "julia";
49
+ return "python";
46
50
  }
47
51
 
48
52
  interface EvalRenderCellArg {
@@ -70,7 +74,10 @@ interface EvalRenderCell {
70
74
  }
71
75
 
72
76
  function normalizeRenderLanguage(value: string | undefined): EvalLanguage {
73
- return value === "js" ? "js" : "python";
77
+ if (value === "js") return "js";
78
+ if (value === "rb" || value === "ruby") return "ruby";
79
+ if (value === "jl" || value === "julia") return "julia";
80
+ return "python";
74
81
  }
75
82
 
76
83
  function getRenderCells(args: EvalRenderArgs | undefined): EvalRenderCell[] {
@@ -506,6 +513,7 @@ export const evalToolRenderer = {
506
513
  {
507
514
  code: cell.code,
508
515
  language: languageForHighlighter(cell.language),
516
+ showLanguage: true,
509
517
  index: i,
510
518
  total: cells.length,
511
519
  title: cell.title,
@@ -608,6 +616,7 @@ export const evalToolRenderer = {
608
616
  {
609
617
  code: cell.code,
610
618
  language: languageForHighlighter(cell.language ?? details?.language),
619
+ showLanguage: true,
611
620
  index: i,
612
621
  total: cellResults.length,
613
622
  title: cell.title,