@oh-my-pi/pi-coding-agent 14.5.12 → 14.5.14

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 (112) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/package.json +18 -10
  3. package/src/cli/jupyter-cli.ts +1 -1
  4. package/src/commit/pipeline.ts +4 -3
  5. package/src/config/model-equivalence.ts +49 -16
  6. package/src/config/model-registry.ts +100 -25
  7. package/src/config/model-resolver.ts +29 -15
  8. package/src/config/settings-schema.ts +20 -6
  9. package/src/config/settings.ts +9 -8
  10. package/src/config.ts +18 -6
  11. package/src/eval/backend.ts +43 -0
  12. package/src/eval/eval.lark +43 -0
  13. package/src/eval/index.ts +5 -0
  14. package/src/eval/js/context-manager.ts +717 -0
  15. package/src/eval/js/executor.ts +131 -0
  16. package/src/eval/js/index.ts +46 -0
  17. package/src/eval/js/prelude.ts +2 -0
  18. package/src/eval/js/prelude.txt +84 -0
  19. package/src/eval/js/tool-bridge.ts +124 -0
  20. package/src/eval/parse.ts +337 -0
  21. package/src/{ipy → eval/py}/executor.ts +2 -180
  22. package/src/{ipy → eval/py}/gateway-coordinator.ts +2 -2
  23. package/src/eval/py/index.ts +58 -0
  24. package/src/{ipy → eval/py}/kernel.ts +9 -45
  25. package/src/{ipy → eval/py}/prelude.py +39 -227
  26. package/src/eval/types.ts +48 -0
  27. package/src/export/html/template.generated.ts +1 -1
  28. package/src/export/html/template.js +8 -10
  29. package/src/extensibility/extensions/types.ts +2 -3
  30. package/src/internal-urls/docs-index.generated.ts +5 -5
  31. package/src/lsp/client.ts +9 -0
  32. package/src/lsp/index.ts +395 -0
  33. package/src/lsp/types.ts +15 -4
  34. package/src/main.ts +35 -14
  35. package/src/mcp/manager.ts +22 -0
  36. package/src/mcp/oauth-flow.ts +1 -1
  37. package/src/memories/index.ts +1 -1
  38. package/src/modes/acp/acp-event-mapper.ts +1 -1
  39. package/src/modes/components/{python-execution.ts → eval-execution.ts} +11 -4
  40. package/src/modes/components/login-dialog.ts +1 -1
  41. package/src/modes/components/oauth-selector.ts +2 -1
  42. package/src/modes/components/tool-execution.ts +3 -4
  43. package/src/modes/controllers/command-controller.ts +28 -8
  44. package/src/modes/controllers/input-controller.ts +4 -4
  45. package/src/modes/controllers/selector-controller.ts +2 -1
  46. package/src/modes/interactive-mode.ts +4 -5
  47. package/src/modes/rpc/rpc-client.ts +9 -0
  48. package/src/modes/rpc/rpc-mode.ts +6 -0
  49. package/src/modes/rpc/rpc-types.ts +9 -0
  50. package/src/modes/types.ts +3 -3
  51. package/src/modes/utils/ui-helpers.ts +2 -2
  52. package/src/prompts/system/system-prompt.md +3 -3
  53. package/src/prompts/tools/eval.md +92 -0
  54. package/src/prompts/tools/lsp.md +7 -3
  55. package/src/sdk.ts +64 -35
  56. package/src/session/agent-session.ts +152 -46
  57. package/src/session/messages.ts +1 -1
  58. package/src/slash-commands/builtin-registry.ts +1 -1
  59. package/src/system-prompt.ts +34 -66
  60. package/src/task/agents.ts +4 -5
  61. package/src/task/executor.ts +5 -9
  62. package/src/tools/archive-reader.ts +9 -3
  63. package/src/tools/browser/launch.ts +22 -0
  64. package/src/tools/browser/readable.ts +11 -6
  65. package/src/tools/browser/registry.ts +25 -244
  66. package/src/tools/browser/render.ts +1 -1
  67. package/src/tools/browser/tab-protocol.ts +101 -0
  68. package/src/tools/browser/tab-supervisor.ts +429 -0
  69. package/src/tools/browser/tab-worker-entry.ts +21 -0
  70. package/src/tools/browser/tab-worker.ts +1006 -0
  71. package/src/tools/browser.ts +17 -32
  72. package/src/tools/checkpoint.ts +2 -2
  73. package/src/tools/{python.ts → eval.ts} +324 -315
  74. package/src/tools/exit-plan-mode.ts +1 -1
  75. package/src/tools/image-gen.ts +2 -2
  76. package/src/tools/index.ts +62 -100
  77. package/src/tools/read.ts +0 -6
  78. package/src/tools/recipe/runners/pkg.ts +34 -32
  79. package/src/tools/renderers.ts +2 -2
  80. package/src/tools/resolve.ts +7 -2
  81. package/src/tools/todo-write.ts +0 -1
  82. package/src/tools/tool-timeouts.ts +2 -2
  83. package/src/tools/write.ts +8 -1
  84. package/src/utils/markit.ts +15 -7
  85. package/src/utils/tools-manager.ts +5 -5
  86. package/src/web/scrapers/crossref.ts +3 -3
  87. package/src/web/scrapers/devto.ts +1 -1
  88. package/src/web/scrapers/discourse.ts +5 -5
  89. package/src/web/scrapers/firefox-addons.ts +1 -1
  90. package/src/web/scrapers/flathub.ts +2 -2
  91. package/src/web/scrapers/gitlab.ts +1 -1
  92. package/src/web/scrapers/go-pkg.ts +2 -2
  93. package/src/web/scrapers/jetbrains-marketplace.ts +1 -1
  94. package/src/web/scrapers/mastodon.ts +9 -9
  95. package/src/web/scrapers/mdn.ts +11 -7
  96. package/src/web/scrapers/pub-dev.ts +1 -1
  97. package/src/web/scrapers/rawg.ts +3 -3
  98. package/src/web/scrapers/readthedocs.ts +1 -1
  99. package/src/web/scrapers/spdx.ts +1 -1
  100. package/src/web/scrapers/stackoverflow.ts +2 -2
  101. package/src/web/scrapers/types.ts +53 -39
  102. package/src/web/scrapers/w3c.ts +1 -1
  103. package/src/web/search/index.ts +5 -5
  104. package/src/web/search/provider.ts +121 -39
  105. package/src/web/search/providers/gemini.ts +4 -4
  106. package/src/web/search/render.ts +2 -2
  107. package/src/ipy/modules.ts +0 -144
  108. package/src/prompts/tools/python.md +0 -57
  109. package/src/tools/browser/vm.ts +0 -792
  110. /package/src/{ipy → eval/py}/cancellation.ts +0 -0
  111. /package/src/{ipy → eval/py}/prelude.ts +0 -0
  112. /package/src/{ipy → eval/py}/runtime.ts +0 -0
package/src/config.ts CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  } from "@oh-my-pi/pi-utils";
12
12
  import type { TSchema } from "@sinclair/typebox";
13
13
  import { Value } from "@sinclair/typebox/value";
14
- import { Ajv, type ErrorObject, type ValidateFunction } from "ajv";
14
+ import type { ErrorObject } from "ajv";
15
15
  import { JSONC, YAML } from "bun";
16
16
  import { expandTilde } from "./tools/path-utils";
17
17
 
@@ -143,7 +143,6 @@ export type LoadResult<T> =
143
143
  | { value: T; error?: undefined; status: "ok" }
144
144
  | { value?: null; error?: unknown; status: "not-found" };
145
145
 
146
- const ajv = new Ajv();
147
146
  export class ConfigFile<T> implements IConfigFile<T> {
148
147
  readonly #basePath: string;
149
148
  #cache?: LoadResult<T>;
@@ -175,6 +174,15 @@ export class ConfigFile<T> implements IConfigFile<T> {
175
174
  return result;
176
175
  }
177
176
 
177
+ getMtimeMs(): number | null {
178
+ try {
179
+ return fs.statSync(this.path()).mtimeMs;
180
+ } catch (err) {
181
+ if (isEnoent(err)) return null;
182
+ throw err;
183
+ }
184
+ }
185
+
178
186
  withValidation(name: string, validate: (value: T) => void): this {
179
187
  const prev = this.#auxValidate;
180
188
  this.#auxValidate = (value: T) => {
@@ -212,13 +220,17 @@ export class ConfigFile<T> implements IConfigFile<T> {
212
220
  throw new Error(`Invalid config file path: ${this.#basePath}`);
213
221
  }
214
222
 
215
- const validate = ajv.compile(this.schema) as ValidateFunction<T>;
216
- if (!validate(parsed)) {
217
- const error = new ConfigError(this.id, validate.errors);
223
+ if (!Value.Check(this.schema, parsed)) {
224
+ const schemaErrors: ErrorObject[] = [];
225
+ for (const err of Value.Errors(this.schema, parsed)) {
226
+ schemaErrors.push({ instancePath: err.path, message: err.message } as ErrorObject);
227
+ if (schemaErrors.length >= 50) break;
228
+ }
229
+ const error = new ConfigError(this.id, schemaErrors);
218
230
  logger.warn("Failed to parse config file", { path: this.path(), error });
219
231
  return this.#storeCache({ error, status: "error" });
220
232
  }
221
- return this.#storeCache({ value: parsed, status: "ok" });
233
+ return this.#storeCache({ value: parsed as T, status: "ok" });
222
234
  } catch (error) {
223
235
  if (isEnoent(error)) {
224
236
  return this.#storeCache({ status: "not-found" });
@@ -0,0 +1,43 @@
1
+ import type { ToolSession } from "../tools";
2
+ import type { EvalDisplayOutput, EvalLanguage } from "./types";
3
+
4
+ /** Per-cell execute() options. */
5
+ export interface ExecutorBackendExecOptions {
6
+ cwd: string;
7
+ sessionId: string;
8
+ sessionFile: string | undefined;
9
+ kernelOwnerId: string | undefined;
10
+ signal?: AbortSignal;
11
+ session: ToolSession;
12
+ deadlineMs: number;
13
+ reset: boolean;
14
+ artifactPath: string | undefined;
15
+ artifactId: string | undefined;
16
+ onChunk: (chunk: string) => void;
17
+ }
18
+
19
+ /** Result returned by a backend's execute(). */
20
+ export interface ExecutorBackendResult {
21
+ output: string;
22
+ exitCode: number | undefined;
23
+ cancelled: boolean;
24
+ truncated: boolean;
25
+ artifactId: string | undefined;
26
+ totalLines: number;
27
+ totalBytes: number;
28
+ outputLines: number;
29
+ outputBytes: number;
30
+ displayOutputs: EvalDisplayOutput[];
31
+ }
32
+
33
+ /** Pluggable language backend for the eval tool. */
34
+ export interface ExecutorBackend {
35
+ readonly id: EvalLanguage;
36
+ readonly label: string;
37
+ /** Source language identifier passed to the syntax highlighter (e.g. "python", "javascript"). */
38
+ readonly highlightLang: string;
39
+ /** Cheap availability check. Used by fallback resolution. */
40
+ isAvailable(session: ToolSession): Promise<boolean>;
41
+ /** Execute one cell. Caller invokes once per cell and aggregates results. */
42
+ execute(code: string, opts: ExecutorBackendExecOptions): Promise<ExecutorBackendResult>;
43
+ }
@@ -0,0 +1,43 @@
1
+ %import common.LF
2
+ %import common.WS_INLINE
3
+
4
+ // Strict canonical surface for the eval tool. Callers MUST emit exactly this
5
+ // form. The runtime parser accepts additional lenient shapes (positional
6
+ // title/duration, alias keys, long-form lang tokens, mixed casing, fence
7
+ // runs of any length ≥ 3, etc.) but those are fallback only and MUST NOT
8
+ // be relied on.
9
+ //
10
+ // Each cell is a fenced code block opened and closed by exactly three
11
+ // (or exactly five) backticks or tildes — five lets callers nest a 3-char
12
+ // fence inside a cell verbatim. The opening fence carries an optional info
13
+ // string with up to four parts, IN THIS ORDER:
14
+ //
15
+ // lang? id_attr? t_attr? rst_attr?
16
+ //
17
+ // where:
18
+ // lang = "py" | "js" | "ts"
19
+ // id_attr = id="..." (double-quoted cell id)
20
+ // t_attr = t=<duration> (bare integer with optional ms/s/m unit)
21
+ // rst_attr= rst=0|1 (per-language kernel reset for this cell)
22
+
23
+ start: cell+
24
+
25
+ cell: backtick_cell | tilde_cell
26
+
27
+ backtick_cell: BACKTICKS info? LF code_line* BACKTICKS LF
28
+ tilde_cell: TILDES info? LF code_line* TILDES LF
29
+
30
+ info: lang (WS_INLINE id_attr)? (WS_INLINE t_attr)? (WS_INLINE rst_attr)?
31
+ | id_attr (WS_INLINE t_attr)? (WS_INLINE rst_attr)?
32
+ | t_attr (WS_INLINE rst_attr)?
33
+ | rst_attr
34
+
35
+ lang: "py" | "js" | "ts"
36
+ id_attr: "id=" /"[^"\r\n]*"/
37
+ t_attr: "t=" /\d+(ms|s|m)?/
38
+ rst_attr: "rst=" /[01]/
39
+
40
+ code_line: /[^\r\n]*/ LF
41
+
42
+ BACKTICKS: "```" | "`````"
43
+ TILDES: "~~~" | "~~~~~"
@@ -0,0 +1,5 @@
1
+ export * from "./backend";
2
+ export { default as jsBackend } from "./js";
3
+ export * from "./parse";
4
+ export { default as pythonBackend } from "./py";
5
+ export * from "./types";