@agimon-ai/po-codemode 0.0.1-alpha.1 → 0.0.1-alpha.2

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.
@@ -1,4 +1,5 @@
1
1
  import { assertCodemodeNamespaceName } from "@agimon-ai/po-core/codemode";
2
+ import { invalidImageReason } from "@agimon-ai/po-core/headless";
2
3
  import { Type } from "typebox";
3
4
  //#region src/services/codemodeRegistry/index.ts
4
5
  /** The session's namespaces and script folders, in registration order. One name per session. */
@@ -64,8 +65,12 @@ const MAX_TIMEOUT_MS = 12e4;
64
65
  const MIN_TIMEOUT_MS = 1e3;
65
66
  const MAX_LOG_CHARS = 1e4;
66
67
  const MAX_VALUE_CHARS = 65536;
67
- const MAX_DECLARATION_CHARS = 12e3;
68
+ const MAX_DECLARATION_CHARS = 24e3;
68
69
  const MAX_QUERY_LINES = 40;
70
+ const MAX_CONCURRENT_RUNS = 8;
71
+ const MAX_RECORDED_CALLS = 50;
72
+ const MAX_RECORDED_TEXT = 8e3;
73
+ const MAX_RECORDED_JSON = 16e3;
69
74
  const MAX_LISTED_SCRIPTS = 20;
70
75
  const MAX_IMAGES = 4;
71
76
  const MAX_IMAGE_BYTES = 5242880;
@@ -95,7 +100,8 @@ function format(value) {
95
100
  }
96
101
  function memberNames(namespace) {
97
102
  const names = /* @__PURE__ */ new Set();
98
- for (const line of namespace.declarations.split("\n")) {
103
+ const declaration = new RegExp(`^declare const ${namespace.name}: \\{([\\s\\S]*?)^\\};`, "mu").exec(namespace.declarations)?.[1] ?? "";
104
+ for (const line of declaration.split("\n")) {
99
105
  const name = MEMBER_LINE.exec(line)?.[1];
100
106
  if (name) names.add(name);
101
107
  }
@@ -132,6 +138,8 @@ function createOutput() {
132
138
  if (images.length >= MAX_IMAGES) throw new RangeError(`An exec run returns at most ${MAX_IMAGES} images.`);
133
139
  imageBytes += Math.ceil(data.length * 3 / 4);
134
140
  if (imageBytes > MAX_IMAGE_BYTES) throw new RangeError("Images from one exec run exceed 5 MB.");
141
+ const invalid = invalidImageReason(data, mime);
142
+ if (invalid !== void 0) throw new TypeError(`image() rejected an undecodable image: ${invalid}.`);
135
143
  images.push({
136
144
  data,
137
145
  mimeType: mime
@@ -155,7 +163,39 @@ function createOutput() {
155
163
  function activeDomains(execution) {
156
164
  return execution?.selection?.domains;
157
165
  }
158
- function toResult(result, output, saved) {
166
+ /** A JSON copy of `value`, or undefined when it does not serialise or is larger than `limit` characters. */
167
+ function bounded(value, limit) {
168
+ try {
169
+ const json = JSON.stringify(value);
170
+ return json !== void 0 && json.length <= limit ? JSON.parse(json) : void 0;
171
+ } catch {
172
+ return;
173
+ }
174
+ }
175
+ /** The call as it is kept in the transcript: text blocks only, clipped, with args and details dropped when large. */
176
+ function recordedCall(call) {
177
+ const content = (call.result?.content ?? []).flatMap((block) => {
178
+ const { type, text } = block ?? {};
179
+ return type === "text" && typeof text === "string" ? [{
180
+ type: "text",
181
+ text: truncate(text, MAX_RECORDED_TEXT)
182
+ }] : [];
183
+ });
184
+ const details = bounded(call.result?.details, MAX_RECORDED_JSON);
185
+ return {
186
+ name: call.name,
187
+ tool: call.tool,
188
+ args: bounded(call.args, MAX_RECORDED_JSON) ?? {},
189
+ ok: call.ok,
190
+ ms: Math.max(0, Math.round(call.ms)),
191
+ ...call.error === void 0 ? {} : { error: truncate(call.error, MAX_RECORDED_TEXT) },
192
+ ...call.result === void 0 ? {} : { result: {
193
+ content,
194
+ ...details === void 0 ? {} : { details }
195
+ } }
196
+ };
197
+ }
198
+ function toResult(result, output, saved, calls) {
159
199
  const content = [];
160
200
  if (output.lines.length > 0) content.push({
161
201
  type: "text",
@@ -193,6 +233,7 @@ function toResult(result, output, saved) {
193
233
  });
194
234
  return {
195
235
  content,
236
+ ...calls.length > 0 ? { details: { calls } } : {},
196
237
  ...result.ok ? {} : { isError: true }
197
238
  };
198
239
  }
@@ -208,7 +249,7 @@ function sleep(ms, signal) {
208
249
  }
209
250
  /** `discover` and `exec` for one session, over the namespaces its packages contributed. */
210
251
  function createCodemodeTools({ registry, isolate, scripts }) {
211
- let busy = false;
252
+ let running = 0;
212
253
  const visible = (service) => registry.list().filter((namespace) => service.liveObjects || namespace.portable === true);
213
254
  return {
214
255
  discover: {
@@ -282,16 +323,20 @@ function createCodemodeTools({ registry, isolate, scripts }) {
282
323
  async execute(_toolCallId, parameters, signal, _onUpdate, execution) {
283
324
  const service = isolate();
284
325
  if (!service) return text("Code mode is not available on this host.", true);
285
- if (busy) return text("Another exec run is still active in this session. Wait for it to finish.", true);
286
- busy = true;
326
+ if (running >= MAX_CONCURRENT_RUNS) return text(`This session already has ${MAX_CONCURRENT_RUNS} exec runs active. Wait for one to finish.`, true);
327
+ running += 1;
287
328
  const controller = new AbortController();
288
329
  const runSignal = signal ? AbortSignal.any([signal, controller.signal]) : controller.signal;
289
330
  const cleanups = [];
331
+ const calls = [];
290
332
  const output = createOutput();
291
333
  const run = {
292
334
  sessionId: execution.sessionId,
293
335
  signal: runSignal,
294
- onDispose: (cleanup) => void cleanups.push(cleanup)
336
+ onDispose: (cleanup) => void cleanups.push(cleanup),
337
+ record: (call) => {
338
+ if (calls.length < MAX_RECORDED_CALLS) calls.push(recordedCall(call));
339
+ }
295
340
  };
296
341
  try {
297
342
  let saved;
@@ -320,13 +365,13 @@ function createCodemodeTools({ registry, isolate, scripts }) {
320
365
  deny: [...deny],
321
366
  onDiagnostic: output.note,
322
367
  ...scripts ? { resolveImport: (specifier) => scripts.resolve(specifier, activeDomains(execution)) } : {}
323
- }), output, saved);
368
+ }), output, saved, calls);
324
369
  } catch (error) {
325
370
  return text(`Code mode could not run the script: ${error instanceof Error ? error.message : String(error)}`, true);
326
371
  } finally {
327
372
  controller.abort();
328
373
  for (const cleanup of cleanups.reverse()) await Promise.resolve().then(cleanup).catch((error) => output.note(`cleanup failed: ${String(error)}`));
329
- busy = false;
374
+ running -= 1;
330
375
  }
331
376
  }
332
377
  }
@@ -335,4 +380,4 @@ function createCodemodeTools({ registry, isolate, scripts }) {
335
380
  //#endregion
336
381
  export { createCodemodeRegistry as n, createCodemodeTools as t };
337
382
 
338
- //# sourceMappingURL=codemodeTools-CSYUxIeA.mjs.map
383
+ //# sourceMappingURL=codemodeTools-BdwOARH8.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codemodeTools-BdwOARH8.mjs","names":[],"sources":["../src/services/codemodeRegistry/index.ts","../src/schemas/codemodeTools.ts","../src/services/codemodeTools/index.ts"],"sourcesContent":["import {\n assertCodemodeNamespaceName,\n type PoCodemodeNamespace,\n type PoCodemodeRegistration,\n type PoCodemodeScriptSource,\n type PoCodemodeService,\n} from '@agimon-ai/po-core/codemode';\n\n/** The session's namespaces and script folders, in registration order. One name per session. */\nexport function createCodemodeRegistry(): PoCodemodeService {\n const entries = new Map<string, { source: string; namespace: PoCodemodeNamespace }>();\n const scripts = new Set<PoCodemodeScriptSource>();\n const listeners = new Set<() => void>();\n const notify = (): void => {\n for (const listener of listeners) listener();\n };\n return {\n register(source: string, namespace: PoCodemodeNamespace): PoCodemodeRegistration {\n assertCodemodeNamespaceName(namespace.name);\n const taken = entries.get(namespace.name);\n if (taken) {\n throw new Error(\n `Code-mode namespace \"${namespace.name}\" from ${source} is already registered by ${taken.source}.`,\n );\n }\n const entry = { source, namespace };\n entries.set(namespace.name, entry);\n notify();\n return {\n dispose: () => {\n if (entries.get(namespace.name) !== entry) return;\n entries.delete(namespace.name);\n notify();\n },\n };\n },\n list: () => [...entries.values()].map((entry) => entry.namespace),\n registerScripts(_source: string, entry: PoCodemodeScriptSource): PoCodemodeRegistration {\n const owned = { domain: entry.domain, directory: entry.directory };\n scripts.add(owned);\n notify();\n return { dispose: () => void (scripts.delete(owned) && notify()) };\n },\n listScripts: () => [...scripts],\n subscribe(listener: () => void): () => void {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n };\n}\n","import { Type, type Static } from 'typebox';\n\nexport const DiscoverToolSchema = Type.Object({\n namespace: Type.Optional(Type.String({ description: 'Show the full TypeScript declarations of one namespace.' })),\n query: Type.Optional(Type.String({ description: 'Find matching members across every namespace.' })),\n});\nexport type DiscoverToolParams = Static<typeof DiscoverToolSchema>;\n\nexport const ExecToolSchema = Type.Object({\n code: Type.String({\n description:\n 'TypeScript body of an async function. Top-level await and return work. The returned value, console output and image() calls come back.',\n }),\n timeoutMs: Type.Optional(\n Type.Integer({ minimum: 1_000, maximum: 120_000, description: 'Deadline in milliseconds. Default 30000.' }),\n ),\n});\nexport type ExecToolParams = Static<typeof ExecToolSchema>;\n","import type {\n PoCodemodeCall,\n PoCodemodeNamespace,\n PoCodemodeRun,\n PoCodemodeService,\n} from '@agimon-ai/po-core/codemode';\nimport {\n invalidImageReason,\n type PoHeadlessContent,\n type PoHeadlessExecutionContext,\n type PoHeadlessTool,\n type PoHeadlessToolResult,\n} from '@agimon-ai/po-core/headless';\nimport type { PoIsolateResult, PoIsolateService } from '@agimon-ai/po-core/platform';\n\nimport {\n DiscoverToolSchema,\n ExecToolSchema,\n type DiscoverToolParams,\n type ExecToolParams,\n} from '../../schemas/codemodeTools';\nimport type { CodemodeScriptsPort } from '../codemodeScripts/type';\n\nconst DEFAULT_TIMEOUT_MS = 30_000;\nconst MAX_TIMEOUT_MS = 120_000;\nconst MIN_TIMEOUT_MS = 1_000;\nconst MAX_LOG_CHARS = 10_000;\nconst MAX_VALUE_CHARS = 64 * 1024;\nconst MAX_DECLARATION_CHARS = 24_000;\nconst MAX_QUERY_LINES = 40;\n// The main agent and its subagents share one exec tool, so several runs can overlap.\nconst MAX_CONCURRENT_RUNS = 8;\n// Recorded calls ride the result's details into the transcript, so they are few and small.\nconst MAX_RECORDED_CALLS = 50;\nconst MAX_RECORDED_TEXT = 8_000;\nconst MAX_RECORDED_JSON = 16_000;\nconst MAX_LISTED_SCRIPTS = 20;\nconst MAX_IMAGES = 4;\nconst MAX_IMAGE_BYTES = 5 * 1024 * 1024;\nconst DEFAULT_IMAGE_MIME = 'image/png';\nconst MEMBER_LINE = /^\\s{2}(?:readonly\\s+)?(\\w+)\\s*[(?:<]/u;\n\nconst GLOBALS_HELP =\n 'Globals: console.log/info/warn/error, image(data, mimeType?) to return a screenshot, sleep(ms). ' +\n 'Return a value with `return`.';\nconst SCRIPTS_HELP =\n 'Every exec run is saved. Call a saved script with `await (await import(specifier))(args)`; ' +\n 'inside it, `args` is the argument and its `return` is the result.';\n\nexport interface CodemodeToolsOptions {\n readonly registry: PoCodemodeService;\n /** Resolved per call, so a host that binds the isolate late still works. */\n readonly isolate: () => PoIsolateService | undefined;\n /** Saves every exec body and backs `import()`; without it nothing is saved or importable. */\n readonly scripts?: CodemodeScriptsPort;\n}\n\nexport interface CodemodeTools {\n readonly discover: PoHeadlessTool<typeof DiscoverToolSchema>;\n readonly exec: PoHeadlessTool<typeof ExecToolSchema>;\n}\n\nfunction text(value: string, isError = false): PoHeadlessToolResult {\n return { content: [{ type: 'text', text: value }], ...(isError ? { isError: true } : {}) };\n}\n\nfunction truncate(value: string, limit: number): string {\n return value.length <= limit ? value : `${value.slice(0, limit)}\\n[truncated ${value.length - limit} chars]`;\n}\n\nfunction format(value: unknown): string {\n if (typeof value === 'string') return value;\n try {\n const json = JSON.stringify(value, null, 2);\n if (json !== undefined) return json;\n } catch {\n // Cyclic or exotic values fall back to their string form.\n }\n return String(value);\n}\n\nfunction memberNames(namespace: PoCodemodeNamespace): string[] {\n const names = new Set<string>();\n const declaration =\n new RegExp(`^declare const ${namespace.name}: \\\\{([\\\\s\\\\S]*?)^\\\\};`, 'mu').exec(namespace.declarations)?.[1] ?? '';\n for (const line of declaration.split('\\n')) {\n const name = MEMBER_LINE.exec(line)?.[1];\n if (name) names.add(name);\n }\n return [...names];\n}\n\nfunction bytesToBase64(bytes: Uint8Array): string {\n let binary = '';\n for (let index = 0; index < bytes.length; index += 0x8000) {\n binary += String.fromCharCode(...bytes.subarray(index, index + 0x8000));\n }\n return btoa(binary);\n}\n\n/** Collects what a script prints and the images it returns, within the output caps. */\nfunction createOutput() {\n const lines: string[] = [];\n const images: { data: string; mimeType: string }[] = [];\n let imageBytes = 0;\n const log =\n (level: string) =>\n (...args: unknown[]) => {\n const line = args.map(format).join(' ');\n lines.push(level === 'log' || level === 'info' ? line : `[${level}] ${line}`);\n };\n const note = (message: string): void => void lines.push(`[note] ${message}`);\n const addImage = (input: unknown, mimeType?: unknown): void => {\n if (typeof input === 'object' && input !== null && 'images' in input && Array.isArray(input.images)) {\n for (const image of input.images) addImage(image);\n return;\n }\n let data: string;\n let mime = typeof mimeType === 'string' ? mimeType : DEFAULT_IMAGE_MIME;\n if (typeof input === 'string')\n data = input.replace(/^data:([^;]+);base64,/u, (_match, type: string) => ((mime = type), ''));\n else if (ArrayBuffer.isView(input))\n data = bytesToBase64(new Uint8Array(input.buffer, input.byteOffset, input.byteLength));\n else if (typeof input === 'object' && input !== null && 'data' in input && typeof input.data === 'string') {\n data = input.data;\n if ('mimeType' in input && typeof input.mimeType === 'string') mime = input.mimeType;\n } else throw new TypeError('image() takes base64 text, bytes, or { data, mimeType }.');\n if (images.length >= MAX_IMAGES) throw new RangeError(`An exec run returns at most ${MAX_IMAGES} images.`);\n imageBytes += Math.ceil((data.length * 3) / 4);\n if (imageBytes > MAX_IMAGE_BYTES) throw new RangeError('Images from one exec run exceed 5 MB.');\n const invalid = invalidImageReason(data, mime);\n if (invalid !== undefined) throw new TypeError(`image() rejected an undecodable image: ${invalid}.`);\n images.push({ data, mimeType: mime });\n };\n const console = { log: log('log'), info: log('info'), warn: log('warn'), error: log('error'), debug: log('debug') };\n return { console, note, addImage, lines, images };\n}\n\n/** The session's active domains; every registered domain when the host reports none. */\nfunction activeDomains(execution: PoHeadlessExecutionContext | undefined): readonly string[] | undefined {\n return execution?.selection?.domains;\n}\n\n/** A JSON copy of `value`, or undefined when it does not serialise or is larger than `limit` characters. */\nfunction bounded<T>(value: T, limit: number): T | undefined {\n try {\n const json = JSON.stringify(value);\n return json !== undefined && json.length <= limit ? (JSON.parse(json) as T) : undefined;\n } catch {\n return undefined;\n }\n}\n\n/** The call as it is kept in the transcript: text blocks only, clipped, with args and details dropped when large. */\nfunction recordedCall(call: PoCodemodeCall): PoCodemodeCall {\n const content = (call.result?.content ?? []).flatMap((block) => {\n const { type, text } = (block ?? {}) as { type?: unknown; text?: unknown };\n return type === 'text' && typeof text === 'string'\n ? [{ type: 'text', text: truncate(text, MAX_RECORDED_TEXT) }]\n : [];\n });\n const details = bounded(call.result?.details, MAX_RECORDED_JSON);\n return {\n name: call.name,\n tool: call.tool,\n args: bounded(call.args, MAX_RECORDED_JSON) ?? {},\n ok: call.ok,\n ms: Math.max(0, Math.round(call.ms)),\n ...(call.error === undefined ? {} : { error: truncate(call.error, MAX_RECORDED_TEXT) }),\n ...(call.result === undefined ? {} : { result: { content, ...(details === undefined ? {} : { details }) } }),\n };\n}\n\nfunction toResult(\n result: PoIsolateResult,\n output: ReturnType<typeof createOutput>,\n saved: string | undefined,\n calls: readonly PoCodemodeCall[],\n): PoHeadlessToolResult {\n const content: PoHeadlessContent[] = [];\n if (output.lines.length > 0) content.push({ type: 'text', text: truncate(output.lines.join('\\n'), MAX_LOG_CHARS) });\n if (result.ok) {\n if (ArrayBuffer.isView(result.value)) {\n content.push({ type: 'text', text: 'The script returned bytes. Pass them to image(data, mimeType) instead.' });\n } else if (result.value !== undefined) {\n content.push({ type: 'text', text: truncate(format(result.value), MAX_VALUE_CHARS) });\n }\n } else {\n const { kind, name, message } = result.error;\n const hint = kind === 'timeout' ? ' Raise timeoutMs or split the work into smaller exec calls.' : '';\n content.push({ type: 'text', text: `${name}: ${message}${hint}` });\n }\n if (content.length === 0) content.push({ type: 'text', text: '(no return value)' });\n if (saved !== undefined) content.push({ type: 'text', text: saved });\n for (const image of output.images) content.push({ type: 'image', data: image.data, mimeType: image.mimeType });\n return {\n content,\n ...(calls.length > 0 ? { details: { calls } } : {}),\n ...(result.ok ? {} : { isError: true }),\n };\n}\n\nfunction sleep(ms: number, signal: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal.aborted) return reject(new Error('Run ended.'));\n const timer = setTimeout(resolve, Math.max(0, ms));\n signal.addEventListener(\n 'abort',\n () => {\n clearTimeout(timer);\n reject(new Error('Run ended.'));\n },\n { once: true },\n );\n });\n}\n\n/** `discover` and `exec` for one session, over the namespaces its packages contributed. */\nexport function createCodemodeTools({ registry, isolate, scripts }: CodemodeToolsOptions): CodemodeTools {\n let running = 0;\n\n const visible = (service: PoIsolateService): PoCodemodeNamespace[] =>\n registry.list().filter((namespace) => service.liveObjects || namespace.portable === true);\n\n // ponytail: the cockpit's generic tool item renders both for now; add a poWeb renderer for exec code and images when it earns one.\n // web-plugin-tool-renderers: ignore discover, plain text result\n const discover: CodemodeTools['discover'] = {\n name: 'discover',\n label: 'Discover',\n description:\n 'List the code-mode namespaces and reusable scripts you can use from `exec`, show one namespace in full, ' +\n 'or search members and scripts. ' +\n 'Not required before exec: its description already names the namespaces.',\n parameters: DiscoverToolSchema,\n promptSnippet: 'List code-mode namespaces and their TypeScript declarations',\n executionMode: 'parallel',\n async execute(_toolCallId, parameters: DiscoverToolParams, _signal, _onUpdate, execution) {\n const service = isolate();\n if (!service) return text('Code mode is not available on this host.', true);\n const namespaces = visible(service);\n // Imports need a host with live objects; the edge saves scripts but cannot chain them.\n const listed = scripts && service.liveObjects ? await scripts.list(activeDomains(execution)) : [];\n if (parameters.namespace !== undefined) {\n const found = namespaces.find((namespace) => namespace.name === parameters.namespace);\n if (!found) {\n const names = namespaces.map((namespace) => namespace.name).join(', ') || 'none';\n return text(`Unknown namespace \"${parameters.namespace}\". Registered: ${names}.`, true);\n }\n return text(truncate(found.declarations, MAX_DECLARATION_CHARS));\n }\n if (parameters.query !== undefined) {\n const needle = parameters.query.toLowerCase();\n const hits: string[] = [];\n for (const namespace of namespaces) {\n const lines = namespace.declarations.split('\\n');\n lines.forEach((line, index) => {\n if (!line.toLowerCase().includes(needle) || hits.length >= MAX_QUERY_LINES) return;\n const doc = lines[index - 1]?.trim().startsWith('/**') ? `${lines[index - 1]?.trim()} ` : '';\n hits.push(`${namespace.name}: ${doc}${line.trim()}`);\n });\n }\n for (const script of listed) {\n if (hits.length >= MAX_QUERY_LINES) break;\n if (`${script.specifier} ${script.description}`.toLowerCase().includes(needle)) {\n hits.push(`script ${script.specifier}: ${script.description}`);\n }\n }\n return text(hits.length > 0 ? hits.join('\\n') : `No members or scripts match \"${parameters.query}\".`);\n }\n const sections: string[] = [];\n if (namespaces.length === 0) sections.push('No namespaces are registered in this session.');\n for (const namespace of namespaces) {\n sections.push(`- ${namespace.name}: ${namespace.summary}\\n members: ${memberNames(namespace).join(', ')}`);\n }\n sections.push(GLOBALS_HELP);\n if (!service.liveObjects) sections.push('This host runs plain JavaScript with JSON-only functions.');\n if (listed.length > 0) {\n sections.push(`Scripts. ${SCRIPTS_HELP}`);\n for (const script of listed.slice(0, MAX_LISTED_SCRIPTS)) {\n sections.push(`- ${script.specifier}${script.description ? `: ${script.description}` : ''}`);\n }\n if (listed.length > MAX_LISTED_SCRIPTS) {\n sections.push(`...and ${listed.length - MAX_LISTED_SCRIPTS} more; use discover({ query }) to search.`);\n }\n }\n if (namespaces.length > 0) sections.push('Call discover({ namespace }) for full types.');\n return text(sections.join('\\n'));\n },\n };\n\n // web-plugin-tool-renderers: ignore exec, generic item until a code and image renderer exists\n const exec: CodemodeTools['exec'] = {\n name: 'exec',\n label: 'Exec',\n get description(): string {\n const service = isolate();\n const namespaces = service ? visible(service) : [];\n const listed = namespaces.map((namespace) => `- ${namespace.name}: ${namespace.summary}`).join('\\n');\n return [\n 'Run a TypeScript script inside the Po server with live objects from the namespaces below in scope.',\n 'It runs with full server trust, like bash. Keep each call to one logical step.',\n listed || '(no namespaces registered yet; call discover to check)',\n GLOBALS_HELP,\n ...(scripts && service?.liveObjects ? [`${SCRIPTS_HELP} discover lists saved and domain scripts.`] : []),\n 'Use discover({ namespace }) for full signatures when needed.',\n ].join('\\n');\n },\n parameters: ExecToolSchema,\n promptSnippet: 'Run a TypeScript script against live Po objects (browser and other namespaces)',\n executionMode: 'serial',\n async execute(_toolCallId, parameters: ExecToolParams, signal, _onUpdate, execution) {\n const service = isolate();\n if (!service) return text('Code mode is not available on this host.', true);\n if (running >= MAX_CONCURRENT_RUNS)\n return text(`This session already has ${MAX_CONCURRENT_RUNS} exec runs active. Wait for one to finish.`, true);\n running += 1;\n const controller = new AbortController();\n const runSignal = signal ? AbortSignal.any([signal, controller.signal]) : controller.signal;\n const cleanups: (() => void | Promise<void>)[] = [];\n const calls: PoCodemodeCall[] = [];\n const output = createOutput();\n const run: PoCodemodeRun = {\n sessionId: execution.sessionId,\n signal: runSignal,\n onDispose: (cleanup) => void cleanups.push(cleanup),\n record: (call) => {\n if (calls.length < MAX_RECORDED_CALLS) calls.push(recordedCall(call));\n },\n };\n try {\n let saved: string | undefined;\n try {\n const file = await scripts?.save(parameters.code);\n if (file) saved = `Saved as ${file.specifier} (${file.path})`;\n } catch (error) {\n output.note(`Could not save the script: ${error instanceof Error ? error.message : String(error)}`);\n }\n const globals: Record<string, unknown> = {\n console: output.console,\n image: output.addImage,\n sleep: (ms: number) => sleep(ms, runSignal),\n };\n const deny = new Set<string>();\n for (const namespace of visible(service)) {\n globals[namespace.name] = namespace.bind(run);\n for (const member of namespace.deny ?? []) deny.add(member);\n }\n const deadlineMs = Math.min(\n MAX_TIMEOUT_MS,\n Math.max(MIN_TIMEOUT_MS, parameters.timeoutMs ?? DEFAULT_TIMEOUT_MS),\n );\n const result = await service.run({\n source: parameters.code,\n globals,\n deadlineMs,\n signal: runSignal,\n deny: [...deny],\n onDiagnostic: output.note,\n ...(scripts ? { resolveImport: (specifier) => scripts.resolve(specifier, activeDomains(execution)) } : {}),\n });\n return toResult(result, output, saved, calls);\n } catch (error) {\n return text(\n `Code mode could not run the script: ${error instanceof Error ? error.message : String(error)}`,\n true,\n );\n } finally {\n controller.abort();\n for (const cleanup of cleanups.reverse()) {\n await Promise.resolve()\n .then(cleanup)\n .catch((error: unknown) => output.note(`cleanup failed: ${String(error)}`));\n }\n running -= 1;\n }\n },\n };\n\n return { discover, exec };\n}\n"],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  let _agimon_ai_po_core_codemode = require("@agimon-ai/po-core/codemode");
2
+ let _agimon_ai_po_core_headless = require("@agimon-ai/po-core/headless");
2
3
  let typebox = require("typebox");
3
4
  //#region src/services/codemodeRegistry/index.ts
4
5
  /** The session's namespaces and script folders, in registration order. One name per session. */
@@ -64,8 +65,12 @@ const MAX_TIMEOUT_MS = 12e4;
64
65
  const MIN_TIMEOUT_MS = 1e3;
65
66
  const MAX_LOG_CHARS = 1e4;
66
67
  const MAX_VALUE_CHARS = 65536;
67
- const MAX_DECLARATION_CHARS = 12e3;
68
+ const MAX_DECLARATION_CHARS = 24e3;
68
69
  const MAX_QUERY_LINES = 40;
70
+ const MAX_CONCURRENT_RUNS = 8;
71
+ const MAX_RECORDED_CALLS = 50;
72
+ const MAX_RECORDED_TEXT = 8e3;
73
+ const MAX_RECORDED_JSON = 16e3;
69
74
  const MAX_LISTED_SCRIPTS = 20;
70
75
  const MAX_IMAGES = 4;
71
76
  const MAX_IMAGE_BYTES = 5242880;
@@ -95,7 +100,8 @@ function format(value) {
95
100
  }
96
101
  function memberNames(namespace) {
97
102
  const names = /* @__PURE__ */ new Set();
98
- for (const line of namespace.declarations.split("\n")) {
103
+ const declaration = new RegExp(`^declare const ${namespace.name}: \\{([\\s\\S]*?)^\\};`, "mu").exec(namespace.declarations)?.[1] ?? "";
104
+ for (const line of declaration.split("\n")) {
99
105
  const name = MEMBER_LINE.exec(line)?.[1];
100
106
  if (name) names.add(name);
101
107
  }
@@ -132,6 +138,8 @@ function createOutput() {
132
138
  if (images.length >= MAX_IMAGES) throw new RangeError(`An exec run returns at most ${MAX_IMAGES} images.`);
133
139
  imageBytes += Math.ceil(data.length * 3 / 4);
134
140
  if (imageBytes > MAX_IMAGE_BYTES) throw new RangeError("Images from one exec run exceed 5 MB.");
141
+ const invalid = (0, _agimon_ai_po_core_headless.invalidImageReason)(data, mime);
142
+ if (invalid !== void 0) throw new TypeError(`image() rejected an undecodable image: ${invalid}.`);
135
143
  images.push({
136
144
  data,
137
145
  mimeType: mime
@@ -155,7 +163,39 @@ function createOutput() {
155
163
  function activeDomains(execution) {
156
164
  return execution?.selection?.domains;
157
165
  }
158
- function toResult(result, output, saved) {
166
+ /** A JSON copy of `value`, or undefined when it does not serialise or is larger than `limit` characters. */
167
+ function bounded(value, limit) {
168
+ try {
169
+ const json = JSON.stringify(value);
170
+ return json !== void 0 && json.length <= limit ? JSON.parse(json) : void 0;
171
+ } catch {
172
+ return;
173
+ }
174
+ }
175
+ /** The call as it is kept in the transcript: text blocks only, clipped, with args and details dropped when large. */
176
+ function recordedCall(call) {
177
+ const content = (call.result?.content ?? []).flatMap((block) => {
178
+ const { type, text } = block ?? {};
179
+ return type === "text" && typeof text === "string" ? [{
180
+ type: "text",
181
+ text: truncate(text, MAX_RECORDED_TEXT)
182
+ }] : [];
183
+ });
184
+ const details = bounded(call.result?.details, MAX_RECORDED_JSON);
185
+ return {
186
+ name: call.name,
187
+ tool: call.tool,
188
+ args: bounded(call.args, MAX_RECORDED_JSON) ?? {},
189
+ ok: call.ok,
190
+ ms: Math.max(0, Math.round(call.ms)),
191
+ ...call.error === void 0 ? {} : { error: truncate(call.error, MAX_RECORDED_TEXT) },
192
+ ...call.result === void 0 ? {} : { result: {
193
+ content,
194
+ ...details === void 0 ? {} : { details }
195
+ } }
196
+ };
197
+ }
198
+ function toResult(result, output, saved, calls) {
159
199
  const content = [];
160
200
  if (output.lines.length > 0) content.push({
161
201
  type: "text",
@@ -193,6 +233,7 @@ function toResult(result, output, saved) {
193
233
  });
194
234
  return {
195
235
  content,
236
+ ...calls.length > 0 ? { details: { calls } } : {},
196
237
  ...result.ok ? {} : { isError: true }
197
238
  };
198
239
  }
@@ -208,7 +249,7 @@ function sleep(ms, signal) {
208
249
  }
209
250
  /** `discover` and `exec` for one session, over the namespaces its packages contributed. */
210
251
  function createCodemodeTools({ registry, isolate, scripts }) {
211
- let busy = false;
252
+ let running = 0;
212
253
  const visible = (service) => registry.list().filter((namespace) => service.liveObjects || namespace.portable === true);
213
254
  return {
214
255
  discover: {
@@ -282,16 +323,20 @@ function createCodemodeTools({ registry, isolate, scripts }) {
282
323
  async execute(_toolCallId, parameters, signal, _onUpdate, execution) {
283
324
  const service = isolate();
284
325
  if (!service) return text("Code mode is not available on this host.", true);
285
- if (busy) return text("Another exec run is still active in this session. Wait for it to finish.", true);
286
- busy = true;
326
+ if (running >= MAX_CONCURRENT_RUNS) return text(`This session already has ${MAX_CONCURRENT_RUNS} exec runs active. Wait for one to finish.`, true);
327
+ running += 1;
287
328
  const controller = new AbortController();
288
329
  const runSignal = signal ? AbortSignal.any([signal, controller.signal]) : controller.signal;
289
330
  const cleanups = [];
331
+ const calls = [];
290
332
  const output = createOutput();
291
333
  const run = {
292
334
  sessionId: execution.sessionId,
293
335
  signal: runSignal,
294
- onDispose: (cleanup) => void cleanups.push(cleanup)
336
+ onDispose: (cleanup) => void cleanups.push(cleanup),
337
+ record: (call) => {
338
+ if (calls.length < MAX_RECORDED_CALLS) calls.push(recordedCall(call));
339
+ }
295
340
  };
296
341
  try {
297
342
  let saved;
@@ -320,13 +365,13 @@ function createCodemodeTools({ registry, isolate, scripts }) {
320
365
  deny: [...deny],
321
366
  onDiagnostic: output.note,
322
367
  ...scripts ? { resolveImport: (specifier) => scripts.resolve(specifier, activeDomains(execution)) } : {}
323
- }), output, saved);
368
+ }), output, saved, calls);
324
369
  } catch (error) {
325
370
  return text(`Code mode could not run the script: ${error instanceof Error ? error.message : String(error)}`, true);
326
371
  } finally {
327
372
  controller.abort();
328
373
  for (const cleanup of cleanups.reverse()) await Promise.resolve().then(cleanup).catch((error) => output.note(`cleanup failed: ${String(error)}`));
329
- busy = false;
374
+ running -= 1;
330
375
  }
331
376
  }
332
377
  }
@@ -346,4 +391,4 @@ Object.defineProperty(exports, "createCodemodeTools", {
346
391
  }
347
392
  });
348
393
 
349
- //# sourceMappingURL=codemodeTools-BX2qieCR.cjs.map
394
+ //# sourceMappingURL=codemodeTools-CLgSDqfU.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codemodeTools-CLgSDqfU.cjs","names":["Type","invalidImageReason"],"sources":["../src/services/codemodeRegistry/index.ts","../src/schemas/codemodeTools.ts","../src/services/codemodeTools/index.ts"],"sourcesContent":["import {\n assertCodemodeNamespaceName,\n type PoCodemodeNamespace,\n type PoCodemodeRegistration,\n type PoCodemodeScriptSource,\n type PoCodemodeService,\n} from '@agimon-ai/po-core/codemode';\n\n/** The session's namespaces and script folders, in registration order. One name per session. */\nexport function createCodemodeRegistry(): PoCodemodeService {\n const entries = new Map<string, { source: string; namespace: PoCodemodeNamespace }>();\n const scripts = new Set<PoCodemodeScriptSource>();\n const listeners = new Set<() => void>();\n const notify = (): void => {\n for (const listener of listeners) listener();\n };\n return {\n register(source: string, namespace: PoCodemodeNamespace): PoCodemodeRegistration {\n assertCodemodeNamespaceName(namespace.name);\n const taken = entries.get(namespace.name);\n if (taken) {\n throw new Error(\n `Code-mode namespace \"${namespace.name}\" from ${source} is already registered by ${taken.source}.`,\n );\n }\n const entry = { source, namespace };\n entries.set(namespace.name, entry);\n notify();\n return {\n dispose: () => {\n if (entries.get(namespace.name) !== entry) return;\n entries.delete(namespace.name);\n notify();\n },\n };\n },\n list: () => [...entries.values()].map((entry) => entry.namespace),\n registerScripts(_source: string, entry: PoCodemodeScriptSource): PoCodemodeRegistration {\n const owned = { domain: entry.domain, directory: entry.directory };\n scripts.add(owned);\n notify();\n return { dispose: () => void (scripts.delete(owned) && notify()) };\n },\n listScripts: () => [...scripts],\n subscribe(listener: () => void): () => void {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n };\n}\n","import { Type, type Static } from 'typebox';\n\nexport const DiscoverToolSchema = Type.Object({\n namespace: Type.Optional(Type.String({ description: 'Show the full TypeScript declarations of one namespace.' })),\n query: Type.Optional(Type.String({ description: 'Find matching members across every namespace.' })),\n});\nexport type DiscoverToolParams = Static<typeof DiscoverToolSchema>;\n\nexport const ExecToolSchema = Type.Object({\n code: Type.String({\n description:\n 'TypeScript body of an async function. Top-level await and return work. The returned value, console output and image() calls come back.',\n }),\n timeoutMs: Type.Optional(\n Type.Integer({ minimum: 1_000, maximum: 120_000, description: 'Deadline in milliseconds. Default 30000.' }),\n ),\n});\nexport type ExecToolParams = Static<typeof ExecToolSchema>;\n","import type {\n PoCodemodeCall,\n PoCodemodeNamespace,\n PoCodemodeRun,\n PoCodemodeService,\n} from '@agimon-ai/po-core/codemode';\nimport {\n invalidImageReason,\n type PoHeadlessContent,\n type PoHeadlessExecutionContext,\n type PoHeadlessTool,\n type PoHeadlessToolResult,\n} from '@agimon-ai/po-core/headless';\nimport type { PoIsolateResult, PoIsolateService } from '@agimon-ai/po-core/platform';\n\nimport {\n DiscoverToolSchema,\n ExecToolSchema,\n type DiscoverToolParams,\n type ExecToolParams,\n} from '../../schemas/codemodeTools';\nimport type { CodemodeScriptsPort } from '../codemodeScripts/type';\n\nconst DEFAULT_TIMEOUT_MS = 30_000;\nconst MAX_TIMEOUT_MS = 120_000;\nconst MIN_TIMEOUT_MS = 1_000;\nconst MAX_LOG_CHARS = 10_000;\nconst MAX_VALUE_CHARS = 64 * 1024;\nconst MAX_DECLARATION_CHARS = 24_000;\nconst MAX_QUERY_LINES = 40;\n// The main agent and its subagents share one exec tool, so several runs can overlap.\nconst MAX_CONCURRENT_RUNS = 8;\n// Recorded calls ride the result's details into the transcript, so they are few and small.\nconst MAX_RECORDED_CALLS = 50;\nconst MAX_RECORDED_TEXT = 8_000;\nconst MAX_RECORDED_JSON = 16_000;\nconst MAX_LISTED_SCRIPTS = 20;\nconst MAX_IMAGES = 4;\nconst MAX_IMAGE_BYTES = 5 * 1024 * 1024;\nconst DEFAULT_IMAGE_MIME = 'image/png';\nconst MEMBER_LINE = /^\\s{2}(?:readonly\\s+)?(\\w+)\\s*[(?:<]/u;\n\nconst GLOBALS_HELP =\n 'Globals: console.log/info/warn/error, image(data, mimeType?) to return a screenshot, sleep(ms). ' +\n 'Return a value with `return`.';\nconst SCRIPTS_HELP =\n 'Every exec run is saved. Call a saved script with `await (await import(specifier))(args)`; ' +\n 'inside it, `args` is the argument and its `return` is the result.';\n\nexport interface CodemodeToolsOptions {\n readonly registry: PoCodemodeService;\n /** Resolved per call, so a host that binds the isolate late still works. */\n readonly isolate: () => PoIsolateService | undefined;\n /** Saves every exec body and backs `import()`; without it nothing is saved or importable. */\n readonly scripts?: CodemodeScriptsPort;\n}\n\nexport interface CodemodeTools {\n readonly discover: PoHeadlessTool<typeof DiscoverToolSchema>;\n readonly exec: PoHeadlessTool<typeof ExecToolSchema>;\n}\n\nfunction text(value: string, isError = false): PoHeadlessToolResult {\n return { content: [{ type: 'text', text: value }], ...(isError ? { isError: true } : {}) };\n}\n\nfunction truncate(value: string, limit: number): string {\n return value.length <= limit ? value : `${value.slice(0, limit)}\\n[truncated ${value.length - limit} chars]`;\n}\n\nfunction format(value: unknown): string {\n if (typeof value === 'string') return value;\n try {\n const json = JSON.stringify(value, null, 2);\n if (json !== undefined) return json;\n } catch {\n // Cyclic or exotic values fall back to their string form.\n }\n return String(value);\n}\n\nfunction memberNames(namespace: PoCodemodeNamespace): string[] {\n const names = new Set<string>();\n const declaration =\n new RegExp(`^declare const ${namespace.name}: \\\\{([\\\\s\\\\S]*?)^\\\\};`, 'mu').exec(namespace.declarations)?.[1] ?? '';\n for (const line of declaration.split('\\n')) {\n const name = MEMBER_LINE.exec(line)?.[1];\n if (name) names.add(name);\n }\n return [...names];\n}\n\nfunction bytesToBase64(bytes: Uint8Array): string {\n let binary = '';\n for (let index = 0; index < bytes.length; index += 0x8000) {\n binary += String.fromCharCode(...bytes.subarray(index, index + 0x8000));\n }\n return btoa(binary);\n}\n\n/** Collects what a script prints and the images it returns, within the output caps. */\nfunction createOutput() {\n const lines: string[] = [];\n const images: { data: string; mimeType: string }[] = [];\n let imageBytes = 0;\n const log =\n (level: string) =>\n (...args: unknown[]) => {\n const line = args.map(format).join(' ');\n lines.push(level === 'log' || level === 'info' ? line : `[${level}] ${line}`);\n };\n const note = (message: string): void => void lines.push(`[note] ${message}`);\n const addImage = (input: unknown, mimeType?: unknown): void => {\n if (typeof input === 'object' && input !== null && 'images' in input && Array.isArray(input.images)) {\n for (const image of input.images) addImage(image);\n return;\n }\n let data: string;\n let mime = typeof mimeType === 'string' ? mimeType : DEFAULT_IMAGE_MIME;\n if (typeof input === 'string')\n data = input.replace(/^data:([^;]+);base64,/u, (_match, type: string) => ((mime = type), ''));\n else if (ArrayBuffer.isView(input))\n data = bytesToBase64(new Uint8Array(input.buffer, input.byteOffset, input.byteLength));\n else if (typeof input === 'object' && input !== null && 'data' in input && typeof input.data === 'string') {\n data = input.data;\n if ('mimeType' in input && typeof input.mimeType === 'string') mime = input.mimeType;\n } else throw new TypeError('image() takes base64 text, bytes, or { data, mimeType }.');\n if (images.length >= MAX_IMAGES) throw new RangeError(`An exec run returns at most ${MAX_IMAGES} images.`);\n imageBytes += Math.ceil((data.length * 3) / 4);\n if (imageBytes > MAX_IMAGE_BYTES) throw new RangeError('Images from one exec run exceed 5 MB.');\n const invalid = invalidImageReason(data, mime);\n if (invalid !== undefined) throw new TypeError(`image() rejected an undecodable image: ${invalid}.`);\n images.push({ data, mimeType: mime });\n };\n const console = { log: log('log'), info: log('info'), warn: log('warn'), error: log('error'), debug: log('debug') };\n return { console, note, addImage, lines, images };\n}\n\n/** The session's active domains; every registered domain when the host reports none. */\nfunction activeDomains(execution: PoHeadlessExecutionContext | undefined): readonly string[] | undefined {\n return execution?.selection?.domains;\n}\n\n/** A JSON copy of `value`, or undefined when it does not serialise or is larger than `limit` characters. */\nfunction bounded<T>(value: T, limit: number): T | undefined {\n try {\n const json = JSON.stringify(value);\n return json !== undefined && json.length <= limit ? (JSON.parse(json) as T) : undefined;\n } catch {\n return undefined;\n }\n}\n\n/** The call as it is kept in the transcript: text blocks only, clipped, with args and details dropped when large. */\nfunction recordedCall(call: PoCodemodeCall): PoCodemodeCall {\n const content = (call.result?.content ?? []).flatMap((block) => {\n const { type, text } = (block ?? {}) as { type?: unknown; text?: unknown };\n return type === 'text' && typeof text === 'string'\n ? [{ type: 'text', text: truncate(text, MAX_RECORDED_TEXT) }]\n : [];\n });\n const details = bounded(call.result?.details, MAX_RECORDED_JSON);\n return {\n name: call.name,\n tool: call.tool,\n args: bounded(call.args, MAX_RECORDED_JSON) ?? {},\n ok: call.ok,\n ms: Math.max(0, Math.round(call.ms)),\n ...(call.error === undefined ? {} : { error: truncate(call.error, MAX_RECORDED_TEXT) }),\n ...(call.result === undefined ? {} : { result: { content, ...(details === undefined ? {} : { details }) } }),\n };\n}\n\nfunction toResult(\n result: PoIsolateResult,\n output: ReturnType<typeof createOutput>,\n saved: string | undefined,\n calls: readonly PoCodemodeCall[],\n): PoHeadlessToolResult {\n const content: PoHeadlessContent[] = [];\n if (output.lines.length > 0) content.push({ type: 'text', text: truncate(output.lines.join('\\n'), MAX_LOG_CHARS) });\n if (result.ok) {\n if (ArrayBuffer.isView(result.value)) {\n content.push({ type: 'text', text: 'The script returned bytes. Pass them to image(data, mimeType) instead.' });\n } else if (result.value !== undefined) {\n content.push({ type: 'text', text: truncate(format(result.value), MAX_VALUE_CHARS) });\n }\n } else {\n const { kind, name, message } = result.error;\n const hint = kind === 'timeout' ? ' Raise timeoutMs or split the work into smaller exec calls.' : '';\n content.push({ type: 'text', text: `${name}: ${message}${hint}` });\n }\n if (content.length === 0) content.push({ type: 'text', text: '(no return value)' });\n if (saved !== undefined) content.push({ type: 'text', text: saved });\n for (const image of output.images) content.push({ type: 'image', data: image.data, mimeType: image.mimeType });\n return {\n content,\n ...(calls.length > 0 ? { details: { calls } } : {}),\n ...(result.ok ? {} : { isError: true }),\n };\n}\n\nfunction sleep(ms: number, signal: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal.aborted) return reject(new Error('Run ended.'));\n const timer = setTimeout(resolve, Math.max(0, ms));\n signal.addEventListener(\n 'abort',\n () => {\n clearTimeout(timer);\n reject(new Error('Run ended.'));\n },\n { once: true },\n );\n });\n}\n\n/** `discover` and `exec` for one session, over the namespaces its packages contributed. */\nexport function createCodemodeTools({ registry, isolate, scripts }: CodemodeToolsOptions): CodemodeTools {\n let running = 0;\n\n const visible = (service: PoIsolateService): PoCodemodeNamespace[] =>\n registry.list().filter((namespace) => service.liveObjects || namespace.portable === true);\n\n // ponytail: the cockpit's generic tool item renders both for now; add a poWeb renderer for exec code and images when it earns one.\n // web-plugin-tool-renderers: ignore discover, plain text result\n const discover: CodemodeTools['discover'] = {\n name: 'discover',\n label: 'Discover',\n description:\n 'List the code-mode namespaces and reusable scripts you can use from `exec`, show one namespace in full, ' +\n 'or search members and scripts. ' +\n 'Not required before exec: its description already names the namespaces.',\n parameters: DiscoverToolSchema,\n promptSnippet: 'List code-mode namespaces and their TypeScript declarations',\n executionMode: 'parallel',\n async execute(_toolCallId, parameters: DiscoverToolParams, _signal, _onUpdate, execution) {\n const service = isolate();\n if (!service) return text('Code mode is not available on this host.', true);\n const namespaces = visible(service);\n // Imports need a host with live objects; the edge saves scripts but cannot chain them.\n const listed = scripts && service.liveObjects ? await scripts.list(activeDomains(execution)) : [];\n if (parameters.namespace !== undefined) {\n const found = namespaces.find((namespace) => namespace.name === parameters.namespace);\n if (!found) {\n const names = namespaces.map((namespace) => namespace.name).join(', ') || 'none';\n return text(`Unknown namespace \"${parameters.namespace}\". Registered: ${names}.`, true);\n }\n return text(truncate(found.declarations, MAX_DECLARATION_CHARS));\n }\n if (parameters.query !== undefined) {\n const needle = parameters.query.toLowerCase();\n const hits: string[] = [];\n for (const namespace of namespaces) {\n const lines = namespace.declarations.split('\\n');\n lines.forEach((line, index) => {\n if (!line.toLowerCase().includes(needle) || hits.length >= MAX_QUERY_LINES) return;\n const doc = lines[index - 1]?.trim().startsWith('/**') ? `${lines[index - 1]?.trim()} ` : '';\n hits.push(`${namespace.name}: ${doc}${line.trim()}`);\n });\n }\n for (const script of listed) {\n if (hits.length >= MAX_QUERY_LINES) break;\n if (`${script.specifier} ${script.description}`.toLowerCase().includes(needle)) {\n hits.push(`script ${script.specifier}: ${script.description}`);\n }\n }\n return text(hits.length > 0 ? hits.join('\\n') : `No members or scripts match \"${parameters.query}\".`);\n }\n const sections: string[] = [];\n if (namespaces.length === 0) sections.push('No namespaces are registered in this session.');\n for (const namespace of namespaces) {\n sections.push(`- ${namespace.name}: ${namespace.summary}\\n members: ${memberNames(namespace).join(', ')}`);\n }\n sections.push(GLOBALS_HELP);\n if (!service.liveObjects) sections.push('This host runs plain JavaScript with JSON-only functions.');\n if (listed.length > 0) {\n sections.push(`Scripts. ${SCRIPTS_HELP}`);\n for (const script of listed.slice(0, MAX_LISTED_SCRIPTS)) {\n sections.push(`- ${script.specifier}${script.description ? `: ${script.description}` : ''}`);\n }\n if (listed.length > MAX_LISTED_SCRIPTS) {\n sections.push(`...and ${listed.length - MAX_LISTED_SCRIPTS} more; use discover({ query }) to search.`);\n }\n }\n if (namespaces.length > 0) sections.push('Call discover({ namespace }) for full types.');\n return text(sections.join('\\n'));\n },\n };\n\n // web-plugin-tool-renderers: ignore exec, generic item until a code and image renderer exists\n const exec: CodemodeTools['exec'] = {\n name: 'exec',\n label: 'Exec',\n get description(): string {\n const service = isolate();\n const namespaces = service ? visible(service) : [];\n const listed = namespaces.map((namespace) => `- ${namespace.name}: ${namespace.summary}`).join('\\n');\n return [\n 'Run a TypeScript script inside the Po server with live objects from the namespaces below in scope.',\n 'It runs with full server trust, like bash. Keep each call to one logical step.',\n listed || '(no namespaces registered yet; call discover to check)',\n GLOBALS_HELP,\n ...(scripts && service?.liveObjects ? [`${SCRIPTS_HELP} discover lists saved and domain scripts.`] : []),\n 'Use discover({ namespace }) for full signatures when needed.',\n ].join('\\n');\n },\n parameters: ExecToolSchema,\n promptSnippet: 'Run a TypeScript script against live Po objects (browser and other namespaces)',\n executionMode: 'serial',\n async execute(_toolCallId, parameters: ExecToolParams, signal, _onUpdate, execution) {\n const service = isolate();\n if (!service) return text('Code mode is not available on this host.', true);\n if (running >= MAX_CONCURRENT_RUNS)\n return text(`This session already has ${MAX_CONCURRENT_RUNS} exec runs active. Wait for one to finish.`, true);\n running += 1;\n const controller = new AbortController();\n const runSignal = signal ? AbortSignal.any([signal, controller.signal]) : controller.signal;\n const cleanups: (() => void | Promise<void>)[] = [];\n const calls: PoCodemodeCall[] = [];\n const output = createOutput();\n const run: PoCodemodeRun = {\n sessionId: execution.sessionId,\n signal: runSignal,\n onDispose: (cleanup) => void cleanups.push(cleanup),\n record: (call) => {\n if (calls.length < MAX_RECORDED_CALLS) calls.push(recordedCall(call));\n },\n };\n try {\n let saved: string | undefined;\n try {\n const file = await scripts?.save(parameters.code);\n if (file) saved = `Saved as ${file.specifier} (${file.path})`;\n } catch (error) {\n output.note(`Could not save the script: ${error instanceof Error ? error.message : String(error)}`);\n }\n const globals: Record<string, unknown> = {\n console: output.console,\n image: output.addImage,\n sleep: (ms: number) => sleep(ms, runSignal),\n };\n const deny = new Set<string>();\n for (const namespace of visible(service)) {\n globals[namespace.name] = namespace.bind(run);\n for (const member of namespace.deny ?? []) deny.add(member);\n }\n const deadlineMs = Math.min(\n MAX_TIMEOUT_MS,\n Math.max(MIN_TIMEOUT_MS, parameters.timeoutMs ?? DEFAULT_TIMEOUT_MS),\n );\n const result = await service.run({\n source: parameters.code,\n globals,\n deadlineMs,\n signal: runSignal,\n deny: [...deny],\n onDiagnostic: output.note,\n ...(scripts ? { resolveImport: (specifier) => scripts.resolve(specifier, activeDomains(execution)) } : {}),\n });\n return toResult(result, output, saved, calls);\n } catch (error) {\n return text(\n `Code mode could not run the script: ${error instanceof Error ? error.message : String(error)}`,\n true,\n );\n } finally {\n controller.abort();\n for (const cleanup of cleanups.reverse()) {\n await Promise.resolve()\n .then(cleanup)\n .catch((error: unknown) => output.note(`cleanup failed: ${String(error)}`));\n }\n running -= 1;\n }\n },\n };\n\n return { discover, exec };\n}\n"],"mappings":";;;;;AASA,SAAgB,yBAA4C;CAC1D,MAAM,0BAAU,IAAI,IAAgE;CACpF,MAAM,0BAAU,IAAI,IAA4B;CAChD,MAAM,4BAAY,IAAI,IAAgB;CACtC,MAAM,eAAqB;EACzB,KAAK,MAAM,YAAY,WAAW,SAAS;CAC7C;CACA,OAAO;EACL,SAAS,QAAgB,WAAwD;GAC/E,CAAA,GAAA,4BAAA,4BAAA,CAA4B,UAAU,IAAI;GAC1C,MAAM,QAAQ,QAAQ,IAAI,UAAU,IAAI;GACxC,IAAI,OACF,MAAM,IAAI,MACR,wBAAwB,UAAU,KAAK,SAAS,OAAO,4BAA4B,MAAM,OAAO,EAClG;GAEF,MAAM,QAAQ;IAAE;IAAQ;GAAU;GAClC,QAAQ,IAAI,UAAU,MAAM,KAAK;GACjC,OAAO;GACP,OAAO,EACL,eAAe;IACb,IAAI,QAAQ,IAAI,UAAU,IAAI,MAAM,OAAO;IAC3C,QAAQ,OAAO,UAAU,IAAI;IAC7B,OAAO;GACT,EACF;EACF;EACA,YAAY,CAAC,GAAG,QAAQ,OAAO,CAAC,CAAC,CAAC,KAAK,UAAU,MAAM,SAAS;EAChE,gBAAgB,SAAiB,OAAuD;GACtF,MAAM,QAAQ;IAAE,QAAQ,MAAM;IAAQ,WAAW,MAAM;GAAU;GACjE,QAAQ,IAAI,KAAK;GACjB,OAAO;GACP,OAAO,EAAE,eAAe,MAAM,QAAQ,OAAO,KAAK,KAAK,OAAO,GAAG;EACnE;EACA,mBAAmB,CAAC,GAAG,OAAO;EAC9B,UAAU,UAAkC;GAC1C,UAAU,IAAI,QAAQ;GACtB,aAAa,UAAU,OAAO,QAAQ;EACxC;CACF;AACF;;;AC/CA,MAAa,qBAAqBA,QAAAA,KAAK,OAAO;CAC5C,WAAWA,QAAAA,KAAK,SAASA,QAAAA,KAAK,OAAO,EAAE,aAAa,0DAA0D,CAAC,CAAC;CAChH,OAAOA,QAAAA,KAAK,SAASA,QAAAA,KAAK,OAAO,EAAE,aAAa,gDAAgD,CAAC,CAAC;AACpG,CAAC;AAGD,MAAa,iBAAiBA,QAAAA,KAAK,OAAO;CACxC,MAAMA,QAAAA,KAAK,OAAO,EAChB,aACE,yIACJ,CAAC;CACD,WAAWA,QAAAA,KAAK,SACdA,QAAAA,KAAK,QAAQ;EAAE,SAAS;EAAO,SAAS;EAAS,aAAa;CAA2C,CAAC,CAC5G;AACF,CAAC;;;ACOD,MAAM,qBAAqB;AAC3B,MAAM,iBAAiB;AACvB,MAAM,iBAAiB;AACvB,MAAM,gBAAgB;AACtB,MAAM,kBAAkB;AACxB,MAAM,wBAAwB;AAC9B,MAAM,kBAAkB;AAExB,MAAM,sBAAsB;AAE5B,MAAM,qBAAqB;AAC3B,MAAM,oBAAoB;AAC1B,MAAM,oBAAoB;AAC1B,MAAM,qBAAqB;AAC3B,MAAM,aAAa;AACnB,MAAM,kBAAkB;AACxB,MAAM,qBAAqB;AAC3B,MAAM,cAAc;AAEpB,MAAM,eACJ;AAEF,MAAM,eACJ;AAgBF,SAAS,KAAK,OAAe,UAAU,OAA6B;CAClE,OAAO;EAAE,SAAS,CAAC;GAAE,MAAM;GAAQ,MAAM;EAAM,CAAC;EAAG,GAAI,UAAU,EAAE,SAAS,KAAK,IAAI,CAAC;CAAG;AAC3F;AAEA,SAAS,SAAS,OAAe,OAAuB;CACtD,OAAO,MAAM,UAAU,QAAQ,QAAQ,GAAG,MAAM,MAAM,GAAG,KAAK,EAAE,eAAe,MAAM,SAAS,MAAM;AACtG;AAEA,SAAS,OAAO,OAAwB;CACtC,IAAI,OAAO,UAAU,UAAU,OAAO;CACtC,IAAI;EACF,MAAM,OAAO,KAAK,UAAU,OAAO,MAAM,CAAC;EAC1C,IAAI,SAAS,KAAA,GAAW,OAAO;CACjC,QAAQ,CAER;CACA,OAAO,OAAO,KAAK;AACrB;AAEA,SAAS,YAAY,WAA0C;CAC7D,MAAM,wBAAQ,IAAI,IAAY;CAC9B,MAAM,cACJ,IAAI,OAAO,kBAAkB,UAAU,KAAK,yBAAyB,IAAI,CAAC,CAAC,KAAK,UAAU,YAAY,CAAC,GAAG,MAAM;CAClH,KAAK,MAAM,QAAQ,YAAY,MAAM,IAAI,GAAG;EAC1C,MAAM,OAAO,YAAY,KAAK,IAAI,CAAC,GAAG;EACtC,IAAI,MAAM,MAAM,IAAI,IAAI;CAC1B;CACA,OAAO,CAAC,GAAG,KAAK;AAClB;AAEA,SAAS,cAAc,OAA2B;CAChD,IAAI,SAAS;CACb,KAAK,IAAI,QAAQ,GAAG,QAAQ,MAAM,QAAQ,SAAS,OACjD,UAAU,OAAO,aAAa,GAAG,MAAM,SAAS,OAAO,QAAQ,KAAM,CAAC;CAExE,OAAO,KAAK,MAAM;AACpB;;AAGA,SAAS,eAAe;CACtB,MAAM,QAAkB,CAAC;CACzB,MAAM,SAA+C,CAAC;CACtD,IAAI,aAAa;CACjB,MAAM,OACH,WACA,GAAG,SAAoB;EACtB,MAAM,OAAO,KAAK,IAAI,MAAM,CAAC,CAAC,KAAK,GAAG;EACtC,MAAM,KAAK,UAAU,SAAS,UAAU,SAAS,OAAO,IAAI,MAAM,IAAI,MAAM;CAC9E;CACF,MAAM,QAAQ,YAA0B,KAAK,MAAM,KAAK,UAAU,SAAS;CAC3E,MAAM,YAAY,OAAgB,aAA6B;EAC7D,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,YAAY,SAAS,MAAM,QAAQ,MAAM,MAAM,GAAG;GACnG,KAAK,MAAM,SAAS,MAAM,QAAQ,SAAS,KAAK;GAChD;EACF;EACA,IAAI;EACJ,IAAI,OAAO,OAAO,aAAa,WAAW,WAAW;EACrD,IAAI,OAAO,UAAU,UACnB,OAAO,MAAM,QAAQ,2BAA2B,QAAQ,UAAmB,OAAO,MAAO,GAAG;OACzF,IAAI,YAAY,OAAO,KAAK,GAC/B,OAAO,cAAc,IAAI,WAAW,MAAM,QAAQ,MAAM,YAAY,MAAM,UAAU,CAAC;OAClF,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,UAAU,SAAS,OAAO,MAAM,SAAS,UAAU;GACzG,OAAO,MAAM;GACb,IAAI,cAAc,SAAS,OAAO,MAAM,aAAa,UAAU,OAAO,MAAM;EAC9E,OAAO,MAAM,IAAI,UAAU,0DAA0D;EACrF,IAAI,OAAO,UAAU,YAAY,MAAM,IAAI,WAAW,+BAA+B,WAAW,SAAS;EACzG,cAAc,KAAK,KAAM,KAAK,SAAS,IAAK,CAAC;EAC7C,IAAI,aAAa,iBAAiB,MAAM,IAAI,WAAW,uCAAuC;EAC9F,MAAM,WAAA,GAAUC,4BAAAA,mBAAAA,CAAmB,MAAM,IAAI;EAC7C,IAAI,YAAY,KAAA,GAAW,MAAM,IAAI,UAAU,0CAA0C,QAAQ,EAAE;EACnG,OAAO,KAAK;GAAE;GAAM,UAAU;EAAK,CAAC;CACtC;CAEA,OAAO;EAAE,SAAA;GADS,KAAK,IAAI,KAAK;GAAG,MAAM,IAAI,MAAM;GAAG,MAAM,IAAI,MAAM;GAAG,OAAO,IAAI,OAAO;GAAG,OAAO,IAAI,OAAO;EACjG;EAAG;EAAM;EAAU;EAAO;CAAO;AAClD;;AAGA,SAAS,cAAc,WAAkF;CACvG,OAAO,WAAW,WAAW;AAC/B;;AAGA,SAAS,QAAW,OAAU,OAA8B;CAC1D,IAAI;EACF,MAAM,OAAO,KAAK,UAAU,KAAK;EACjC,OAAO,SAAS,KAAA,KAAa,KAAK,UAAU,QAAS,KAAK,MAAM,IAAI,IAAU,KAAA;CAChF,QAAQ;EACN;CACF;AACF;;AAGA,SAAS,aAAa,MAAsC;CAC1D,MAAM,WAAW,KAAK,QAAQ,WAAW,CAAC,EAAA,CAAG,SAAS,UAAU;EAC9D,MAAM,EAAE,MAAM,SAAU,SAAS,CAAC;EAClC,OAAO,SAAS,UAAU,OAAO,SAAS,WACtC,CAAC;GAAE,MAAM;GAAQ,MAAM,SAAS,MAAM,iBAAiB;EAAE,CAAC,IAC1D,CAAC;CACP,CAAC;CACD,MAAM,UAAU,QAAQ,KAAK,QAAQ,SAAS,iBAAiB;CAC/D,OAAO;EACL,MAAM,KAAK;EACX,MAAM,KAAK;EACX,MAAM,QAAQ,KAAK,MAAM,iBAAiB,KAAK,CAAC;EAChD,IAAI,KAAK;EACT,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,EAAE,CAAC;EACnC,GAAI,KAAK,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,SAAS,KAAK,OAAO,iBAAiB,EAAE;EACrF,GAAI,KAAK,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ;GAAE;GAAS,GAAI,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ;EAAG,EAAE;CAC5G;AACF;AAEA,SAAS,SACP,QACA,QACA,OACA,OACsB;CACtB,MAAM,UAA+B,CAAC;CACtC,IAAI,OAAO,MAAM,SAAS,GAAG,QAAQ,KAAK;EAAE,MAAM;EAAQ,MAAM,SAAS,OAAO,MAAM,KAAK,IAAI,GAAG,aAAa;CAAE,CAAC;CAClH,IAAI,OAAO,IAAI;EACb,IAAI,YAAY,OAAO,OAAO,KAAK,GACjC,QAAQ,KAAK;GAAE,MAAM;GAAQ,MAAM;EAAyE,CAAC;OACxG,IAAI,OAAO,UAAU,KAAA,GAC1B,QAAQ,KAAK;GAAE,MAAM;GAAQ,MAAM,SAAS,OAAO,OAAO,KAAK,GAAG,eAAe;EAAE,CAAC;CAExF,OAAO;EACL,MAAM,EAAE,MAAM,MAAM,YAAY,OAAO;EACvC,MAAM,OAAO,SAAS,YAAY,gEAAgE;EAClG,QAAQ,KAAK;GAAE,MAAM;GAAQ,MAAM,GAAG,KAAK,IAAI,UAAU;EAAO,CAAC;CACnE;CACA,IAAI,QAAQ,WAAW,GAAG,QAAQ,KAAK;EAAE,MAAM;EAAQ,MAAM;CAAoB,CAAC;CAClF,IAAI,UAAU,KAAA,GAAW,QAAQ,KAAK;EAAE,MAAM;EAAQ,MAAM;CAAM,CAAC;CACnE,KAAK,MAAM,SAAS,OAAO,QAAQ,QAAQ,KAAK;EAAE,MAAM;EAAS,MAAM,MAAM;EAAM,UAAU,MAAM;CAAS,CAAC;CAC7G,OAAO;EACL;EACA,GAAI,MAAM,SAAS,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC;EACjD,GAAI,OAAO,KAAK,CAAC,IAAI,EAAE,SAAS,KAAK;CACvC;AACF;AAEA,SAAS,MAAM,IAAY,QAAoC;CAC7D,OAAO,IAAI,SAAS,SAAS,WAAW;EACtC,IAAI,OAAO,SAAS,OAAO,uBAAO,IAAI,MAAM,YAAY,CAAC;EACzD,MAAM,QAAQ,WAAW,SAAS,KAAK,IAAI,GAAG,EAAE,CAAC;EACjD,OAAO,iBACL,eACM;GACJ,aAAa,KAAK;GAClB,uBAAO,IAAI,MAAM,YAAY,CAAC;EAChC,GACA,EAAE,MAAM,KAAK,CACf;CACF,CAAC;AACH;;AAGA,SAAgB,oBAAoB,EAAE,UAAU,SAAS,WAAgD;CACvG,IAAI,UAAU;CAEd,MAAM,WAAW,YACf,SAAS,KAAK,CAAC,CAAC,QAAQ,cAAc,QAAQ,eAAe,UAAU,aAAa,IAAI;CA4J1F,OAAO;EAAE,UAAA;GAvJP,MAAM;GACN,OAAO;GACP,aACE;GAGF,YAAY;GACZ,eAAe;GACf,eAAe;GACf,MAAM,QAAQ,aAAa,YAAgC,SAAS,WAAW,WAAW;IACxF,MAAM,UAAU,QAAQ;IACxB,IAAI,CAAC,SAAS,OAAO,KAAK,4CAA4C,IAAI;IAC1E,MAAM,aAAa,QAAQ,OAAO;IAElC,MAAM,SAAS,WAAW,QAAQ,cAAc,MAAM,QAAQ,KAAK,cAAc,SAAS,CAAC,IAAI,CAAC;IAChG,IAAI,WAAW,cAAc,KAAA,GAAW;KACtC,MAAM,QAAQ,WAAW,MAAM,cAAc,UAAU,SAAS,WAAW,SAAS;KACpF,IAAI,CAAC,OAAO;MACV,MAAM,QAAQ,WAAW,KAAK,cAAc,UAAU,IAAI,CAAC,CAAC,KAAK,IAAI,KAAK;MAC1E,OAAO,KAAK,sBAAsB,WAAW,UAAU,iBAAiB,MAAM,IAAI,IAAI;KACxF;KACA,OAAO,KAAK,SAAS,MAAM,cAAc,qBAAqB,CAAC;IACjE;IACA,IAAI,WAAW,UAAU,KAAA,GAAW;KAClC,MAAM,SAAS,WAAW,MAAM,YAAY;KAC5C,MAAM,OAAiB,CAAC;KACxB,KAAK,MAAM,aAAa,YAAY;MAClC,MAAM,QAAQ,UAAU,aAAa,MAAM,IAAI;MAC/C,MAAM,SAAS,MAAM,UAAU;OAC7B,IAAI,CAAC,KAAK,YAAY,CAAC,CAAC,SAAS,MAAM,KAAK,KAAK,UAAU,iBAAiB;OAC5E,MAAM,MAAM,MAAM,QAAQ,EAAE,EAAE,KAAK,CAAC,CAAC,WAAW,KAAK,IAAI,GAAG,MAAM,QAAQ,EAAE,EAAE,KAAK,EAAE,KAAK;OAC1F,KAAK,KAAK,GAAG,UAAU,KAAK,IAAI,MAAM,KAAK,KAAK,GAAG;MACrD,CAAC;KACH;KACA,KAAK,MAAM,UAAU,QAAQ;MAC3B,IAAI,KAAK,UAAU,iBAAiB;MACpC,IAAI,GAAG,OAAO,UAAU,GAAG,OAAO,cAAc,YAAY,CAAC,CAAC,SAAS,MAAM,GAC3E,KAAK,KAAK,UAAU,OAAO,UAAU,IAAI,OAAO,aAAa;KAEjE;KACA,OAAO,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,gCAAgC,WAAW,MAAM,GAAG;IACtG;IACA,MAAM,WAAqB,CAAC;IAC5B,IAAI,WAAW,WAAW,GAAG,SAAS,KAAK,+CAA+C;IAC1F,KAAK,MAAM,aAAa,YACtB,SAAS,KAAK,KAAK,UAAU,KAAK,IAAI,UAAU,QAAQ,eAAe,YAAY,SAAS,CAAC,CAAC,KAAK,IAAI,GAAG;IAE5G,SAAS,KAAK,YAAY;IAC1B,IAAI,CAAC,QAAQ,aAAa,SAAS,KAAK,2DAA2D;IACnG,IAAI,OAAO,SAAS,GAAG;KACrB,SAAS,KAAK,YAAY,cAAc;KACxC,KAAK,MAAM,UAAU,OAAO,MAAM,GAAG,kBAAkB,GACrD,SAAS,KAAK,KAAK,OAAO,YAAY,OAAO,cAAc,KAAK,OAAO,gBAAgB,IAAI;KAE7F,IAAI,OAAO,SAAS,oBAClB,SAAS,KAAK,UAAU,OAAO,SAAS,mBAAmB,0CAA0C;IAEzG;IACA,IAAI,WAAW,SAAS,GAAG,SAAS,KAAK,8CAA8C;IACvF,OAAO,KAAK,SAAS,KAAK,IAAI,CAAC;GACjC;EA2Fc;EAAG,MAAA;GAtFjB,MAAM;GACN,OAAO;GACP,IAAI,cAAsB;IACxB,MAAM,UAAU,QAAQ;IAGxB,OAAO;KACL;KACA;MAJiB,UAAU,QAAQ,OAAO,IAAI,CAAC,EAAA,CACvB,KAAK,cAAc,KAAK,UAAU,KAAK,IAAI,UAAU,SAAS,CAAC,CAAC,KAAK,IAIxF,KAAK;KACV;KACA,GAAI,WAAW,SAAS,cAAc,CAAC,GAAG,aAAa,0CAA0C,IAAI,CAAC;KACtG;IACF,CAAC,CAAC,KAAK,IAAI;GACb;GACA,YAAY;GACZ,eAAe;GACf,eAAe;GACf,MAAM,QAAQ,aAAa,YAA4B,QAAQ,WAAW,WAAW;IACnF,MAAM,UAAU,QAAQ;IACxB,IAAI,CAAC,SAAS,OAAO,KAAK,4CAA4C,IAAI;IAC1E,IAAI,WAAW,qBACb,OAAO,KAAK,4BAA4B,oBAAoB,6CAA6C,IAAI;IAC/G,WAAW;IACX,MAAM,aAAa,IAAI,gBAAgB;IACvC,MAAM,YAAY,SAAS,YAAY,IAAI,CAAC,QAAQ,WAAW,MAAM,CAAC,IAAI,WAAW;IACrF,MAAM,WAA2C,CAAC;IAClD,MAAM,QAA0B,CAAC;IACjC,MAAM,SAAS,aAAa;IAC5B,MAAM,MAAqB;KACzB,WAAW,UAAU;KACrB,QAAQ;KACR,YAAY,YAAY,KAAK,SAAS,KAAK,OAAO;KAClD,SAAS,SAAS;MAChB,IAAI,MAAM,SAAS,oBAAoB,MAAM,KAAK,aAAa,IAAI,CAAC;KACtE;IACF;IACA,IAAI;KACF,IAAI;KACJ,IAAI;MACF,MAAM,OAAO,MAAM,SAAS,KAAK,WAAW,IAAI;MAChD,IAAI,MAAM,QAAQ,YAAY,KAAK,UAAU,IAAI,KAAK,KAAK;KAC7D,SAAS,OAAO;MACd,OAAO,KAAK,8BAA8B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,GAAG;KACpG;KACA,MAAM,UAAmC;MACvC,SAAS,OAAO;MAChB,OAAO,OAAO;MACd,QAAQ,OAAe,MAAM,IAAI,SAAS;KAC5C;KACA,MAAM,uBAAO,IAAI,IAAY;KAC7B,KAAK,MAAM,aAAa,QAAQ,OAAO,GAAG;MACxC,QAAQ,UAAU,QAAQ,UAAU,KAAK,GAAG;MAC5C,KAAK,MAAM,UAAU,UAAU,QAAQ,CAAC,GAAG,KAAK,IAAI,MAAM;KAC5D;KACA,MAAM,aAAa,KAAK,IACtB,gBACA,KAAK,IAAI,gBAAgB,WAAW,aAAa,kBAAkB,CACrE;KAUA,OAAO,SAAS,MATK,QAAQ,IAAI;MAC/B,QAAQ,WAAW;MACnB;MACA;MACA,QAAQ;MACR,MAAM,CAAC,GAAG,IAAI;MACd,cAAc,OAAO;MACrB,GAAI,UAAU,EAAE,gBAAgB,cAAc,QAAQ,QAAQ,WAAW,cAAc,SAAS,CAAC,EAAE,IAAI,CAAC;KAC1G,CAAC,GACuB,QAAQ,OAAO,KAAK;IAC9C,SAAS,OAAO;KACd,OAAO,KACL,uCAAuC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,KAC5F,IACF;IACF,UAAU;KACR,WAAW,MAAM;KACjB,KAAK,MAAM,WAAW,SAAS,QAAQ,GACrC,MAAM,QAAQ,QAAQ,CAAC,CACpB,KAAK,OAAO,CAAC,CACb,OAAO,UAAmB,OAAO,KAAK,mBAAmB,OAAO,KAAK,GAAG,CAAC;KAE9E,WAAW;IACb;GACF;EAGoB;CAAE;AAC1B"}
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_codemodeTools = require("../codemodeTools-BX2qieCR.cjs");
5
+ const require_codemodeTools = require("../codemodeTools-CLgSDqfU.cjs");
6
6
  let _agimon_ai_po_core_codemode = require("@agimon-ai/po-core/codemode");
7
7
  let _agimon_ai_po_core_serverPlugin = require("@agimon-ai/po-core/serverPlugin");
8
8
  let _agimon_ai_po_core_extensionFile = require("@agimon-ai/po-core/extensionFile");
@@ -1,4 +1,4 @@
1
- import { n as createCodemodeRegistry, t as createCodemodeTools } from "../codemodeTools-CSYUxIeA.mjs";
1
+ import { n as createCodemodeRegistry, t as createCodemodeTools } from "../codemodeTools-BdwOARH8.mjs";
2
2
  import { PO_CODEMODE_CONTRACT, PO_CODEMODE_SERVICE } from "@agimon-ai/po-core/codemode";
3
3
  import { PO_SERVER_SCOPE_SERVICE, composeServerProviderOverrides, defineServerPlugin, packageResourcePath, readPackageResource, requirePoServerScope } from "@agimon-ai/po-core/serverPlugin";
4
4
  import { composeRootHooks, composeRootInjects, defineResource, defineRoot, defineServerTool, defineServiceContract } from "@agimon-ai/po-core/extensionFile";
@@ -0,0 +1,295 @@
1
+ import { defineToolRenderer, defineWebPlugin, toolResultTextLines } from "@agimon-ai/po-core/web";
2
+ import { CodeBlock, MessageItem, MessageItemBody, MessageItemHeader, MessageItemStatus, toolTone } from "@agimon-ai/po-web-components";
3
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
+ //#region src/extensions/workspaces/sessions/(frontend)/tool/_lib/execToolView.ts
5
+ /** Tool names this package registers (registerTool's `name`). */
6
+ const execToolName = "exec";
7
+ const discoverToolName = "discover";
8
+ const SUMMARY_MAX = 120;
9
+ const ARGS_MAX = 160;
10
+ const CALLS_MAX = 50;
11
+ const IMAGE_TYPES = /^image\/(?:png|jpeg|webp|gif)$/u;
12
+ const SAVED_LINE = /^Saved as (\S+) \((.+)\)$/u;
13
+ function record(value) {
14
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
15
+ }
16
+ function clip(text, max) {
17
+ return text.length <= max ? text : `${text.slice(0, max - 1)}…`;
18
+ }
19
+ /** The script the call ran, exactly as the agent wrote it. */
20
+ function execCode(args) {
21
+ return typeof args.code === "string" ? args.code : "";
22
+ }
23
+ /** The header line: the script's first line, with a leading `//` comment marker dropped. */
24
+ function execSummary(args) {
25
+ const first = execCode(args).split("\n").map((line) => line.trim()).find((line) => line !== "");
26
+ if (first === void 0) return "script";
27
+ return clip(first.replace(/^\/\/+\s*/u, ""), SUMMARY_MAX);
28
+ }
29
+ function callOf(value) {
30
+ const call = record(value);
31
+ if (call === void 0 || typeof call.name !== "string" || call.name === "") return void 0;
32
+ const result = record(call.result);
33
+ return {
34
+ name: call.name,
35
+ args: record(call.args) ?? {},
36
+ ok: call.ok !== false,
37
+ ms: typeof call.ms === "number" && Number.isFinite(call.ms) && call.ms >= 0 ? Math.round(call.ms) : 0,
38
+ ...typeof call.tool === "string" && call.tool !== "" ? { tool: call.tool } : {},
39
+ ...typeof call.error === "string" && call.error !== "" ? { error: call.error } : {},
40
+ ...result !== void 0 && Array.isArray(result.content) ? { result: {
41
+ content: result.content,
42
+ details: result.details
43
+ } } : {}
44
+ };
45
+ }
46
+ /** The nested calls recorded in a result's details; anything malformed is skipped. */
47
+ function execCalls(details) {
48
+ const calls = record(details)?.calls;
49
+ if (!Array.isArray(calls)) return [];
50
+ return calls.slice(0, CALLS_MAX).map(callOf).filter((call) => call !== void 0);
51
+ }
52
+ /** A call's arguments on one line, for a row that has no card of its own. */
53
+ function callArgsSummary(args) {
54
+ return Object.keys(args).length === 0 ? "" : clip(JSON.stringify(args), ARGS_MAX);
55
+ }
56
+ /** What a result holds, with the saved-script footer and the pictures taken out of the text. */
57
+ function execResultView(result) {
58
+ if (result === null) return {
59
+ lines: [],
60
+ images: []
61
+ };
62
+ let saved;
63
+ const content = [];
64
+ for (const block of result.content) {
65
+ const text = record(block)?.type === "text" ? record(block)?.text : void 0;
66
+ const match = typeof text === "string" ? SAVED_LINE.exec(text.trim()) : null;
67
+ if (match?.[1] !== void 0 && match[2] !== void 0) saved = {
68
+ id: match[1],
69
+ path: match[2]
70
+ };
71
+ else content.push(block);
72
+ }
73
+ const images = content.flatMap((block) => {
74
+ const image = record(block);
75
+ return image?.type === "image" && typeof image.data === "string" && typeof image.mimeType === "string" && IMAGE_TYPES.test(image.mimeType) ? [{
76
+ mimeType: image.mimeType,
77
+ data: image.data
78
+ }] : [];
79
+ });
80
+ return {
81
+ lines: toolResultTextLines(content),
82
+ ...saved === void 0 ? {} : { saved },
83
+ images
84
+ };
85
+ }
86
+ /** The header line for discover: what was asked for. */
87
+ function discoverSummary(args) {
88
+ if (typeof args.namespace === "string" && args.namespace !== "") return args.namespace;
89
+ if (typeof args.query === "string" && args.query !== "") return `find "${clip(args.query, SUMMARY_MAX)}"`;
90
+ return "namespaces and scripts";
91
+ }
92
+ //#endregion
93
+ //#region src/extensions/workspaces/sessions/(frontend)/tool/_components/DiscoverToolCard.tsx
94
+ /** The discover tool's timeline item: folded to what was asked for, open to what came back. */
95
+ function DiscoverToolCard({ args, output, running, isError, defaultExpanded = false }) {
96
+ const declarations = typeof args.namespace === "string" && args.namespace !== "" && !isError;
97
+ return /* @__PURE__ */ jsx(MessageItem, {
98
+ tone: toolTone({
99
+ running,
100
+ isError
101
+ }),
102
+ expandable: true,
103
+ defaultExpanded,
104
+ children: ({ expanded }) => /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(MessageItemHeader, {
105
+ title: discoverToolName,
106
+ children: /* @__PURE__ */ jsx("span", {
107
+ "data-testid": `tool-call-${discoverToolName}`,
108
+ className: "min-w-0 flex-1 truncate text-po-text",
109
+ children: discoverSummary(args)
110
+ })
111
+ }), expanded ? /* @__PURE__ */ jsxs(MessageItemBody, {
112
+ "data-testid": `tool-result-${discoverToolName}`,
113
+ className: "flex flex-col gap-2",
114
+ children: [running && output === "" ? /* @__PURE__ */ jsx(MessageItemStatus, {
115
+ tone: "running",
116
+ children: "running"
117
+ }) : null, output === "" ? null : declarations ? /* @__PURE__ */ jsx("div", {
118
+ className: "max-h-96 overflow-auto",
119
+ children: /* @__PURE__ */ jsx(CodeBlock, {
120
+ text: output,
121
+ className: "language-ts"
122
+ })
123
+ }) : /* @__PURE__ */ jsx("pre", {
124
+ "data-testid": "tool-output",
125
+ className: `max-h-96 overflow-auto font-mono text-sm break-words whitespace-pre-wrap ${isError ? "text-po-red" : "text-po-text"}`,
126
+ children: output
127
+ })]
128
+ }) : null] })
129
+ });
130
+ }
131
+ //#endregion
132
+ //#region src/extensions/workspaces/sessions/(frontend)/tool/discover.web.tsx
133
+ var discover_web_default = defineToolRenderer({ message: DiscoverToolCard });
134
+ //#endregion
135
+ //#region src/extensions/workspaces/sessions/(frontend)/tool/_components/ToolSection.tsx
136
+ /** A labelled part of an expanded card body. */
137
+ function ToolSection({ label, children }) {
138
+ return /* @__PURE__ */ jsxs("section", {
139
+ className: "flex flex-col gap-1.5",
140
+ children: [/* @__PURE__ */ jsx("h4", {
141
+ className: "text-sm font-medium text-po-dim",
142
+ children: label
143
+ }), children]
144
+ });
145
+ }
146
+ //#endregion
147
+ //#region src/extensions/workspaces/sessions/(frontend)/tool/_components/ExecToolCard.tsx
148
+ function CallRow({ call }) {
149
+ const args = callArgsSummary(call.args);
150
+ return /* @__PURE__ */ jsxs("div", {
151
+ "data-testid": "exec-call",
152
+ className: "flex flex-col gap-0.5",
153
+ children: [/* @__PURE__ */ jsxs("div", {
154
+ className: "flex items-center gap-2 text-sm",
155
+ children: [
156
+ /* @__PURE__ */ jsx("span", {
157
+ className: "shrink-0 font-mono text-po-text",
158
+ children: call.name
159
+ }),
160
+ /* @__PURE__ */ jsx("span", {
161
+ className: "min-w-0 flex-1 truncate font-mono text-po-dim",
162
+ children: args
163
+ }),
164
+ /* @__PURE__ */ jsx("span", {
165
+ "aria-hidden": true,
166
+ className: `w-3 shrink-0 text-center ${call.ok ? "text-po-green" : "text-po-red"}`,
167
+ children: call.ok ? "✓" : "✗"
168
+ }),
169
+ /* @__PURE__ */ jsxs("span", {
170
+ className: "w-16 shrink-0 text-right tabular-nums text-po-dim",
171
+ children: [call.ms, " ms"]
172
+ })
173
+ ]
174
+ }), call.error === void 0 ? null : /* @__PURE__ */ jsx("p", {
175
+ className: "pl-5 text-sm break-words text-po-red",
176
+ children: call.error
177
+ })]
178
+ });
179
+ }
180
+ function Calls({ calls, renderTool }) {
181
+ return /* @__PURE__ */ jsx("ul", {
182
+ className: "flex flex-col gap-2",
183
+ children: calls.map((call, index) => {
184
+ const card = call.tool === void 0 || renderTool === void 0 ? null : renderTool({
185
+ toolName: call.tool,
186
+ args: call.args,
187
+ result: call.result ?? null,
188
+ isError: !call.ok
189
+ });
190
+ return /* @__PURE__ */ jsx("li", { children: card ?? /* @__PURE__ */ jsx(CallRow, { call }) }, `${String(index)}-${call.name}`);
191
+ })
192
+ });
193
+ }
194
+ /**
195
+ * The exec tool's timeline item. It stays folded until opened: the script is the
196
+ * point of the call, so opening shows the code, every namespace call it made
197
+ * (as the owning tool's card when one exists), then what it returned.
198
+ */
199
+ function ExecToolCard({ args, result, running, isError, defaultExpanded = false, renderTool }) {
200
+ const code = execCode(args);
201
+ const view = execResultView(result);
202
+ const calls = execCalls(result?.details);
203
+ return /* @__PURE__ */ jsx(MessageItem, {
204
+ tone: toolTone({
205
+ running,
206
+ isError
207
+ }),
208
+ expandable: true,
209
+ defaultExpanded,
210
+ children: ({ expanded }) => /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs(MessageItemHeader, {
211
+ title: execToolName,
212
+ children: [/* @__PURE__ */ jsx("span", {
213
+ "data-testid": `tool-call-${execToolName}`,
214
+ className: "min-w-0 flex-1 truncate text-po-text",
215
+ children: execSummary(args)
216
+ }), calls.length > 0 ? /* @__PURE__ */ jsxs("span", {
217
+ className: "shrink-0 text-sm text-po-dim",
218
+ children: [
219
+ calls.length,
220
+ " ",
221
+ calls.length === 1 ? "call" : "calls"
222
+ ]
223
+ }) : null]
224
+ }), expanded ? /* @__PURE__ */ jsxs(MessageItemBody, {
225
+ "data-testid": `tool-result-${execToolName}`,
226
+ className: "flex flex-col gap-4",
227
+ children: [
228
+ code === "" ? null : /* @__PURE__ */ jsx(ToolSection, {
229
+ label: "Code",
230
+ children: /* @__PURE__ */ jsx(CodeBlock, {
231
+ text: code,
232
+ className: "language-ts"
233
+ })
234
+ }),
235
+ calls.length === 0 ? null : /* @__PURE__ */ jsx(ToolSection, {
236
+ label: "Calls",
237
+ children: /* @__PURE__ */ jsx(Calls, {
238
+ calls,
239
+ renderTool
240
+ })
241
+ }),
242
+ running && view.lines.length === 0 ? /* @__PURE__ */ jsx(MessageItemStatus, {
243
+ tone: "running",
244
+ children: "running"
245
+ }) : /* @__PURE__ */ jsxs(ToolSection, {
246
+ label: isError ? "Error" : "Result",
247
+ children: [
248
+ view.lines.length === 0 && view.images.length === 0 ? /* @__PURE__ */ jsx("p", {
249
+ className: "text-sm text-po-dim",
250
+ children: "No output."
251
+ }) : null,
252
+ view.lines.length === 0 ? null : /* @__PURE__ */ jsx("pre", {
253
+ "data-testid": "tool-output",
254
+ className: `max-h-72 overflow-auto font-mono text-sm break-words whitespace-pre-wrap ${isError ? "text-po-red" : "text-po-text"}`,
255
+ children: view.lines.join("\n")
256
+ }),
257
+ view.images.map((image, index) => /* @__PURE__ */ jsx("img", {
258
+ src: `data:${image.mimeType};base64,${image.data}`,
259
+ alt: `Script image ${String(index + 1)}`,
260
+ "data-testid": "tool-output-image",
261
+ className: "max-h-96 max-w-full self-start rounded-md border border-po-border-soft"
262
+ }, `${image.mimeType}-${String(index)}`))
263
+ ]
264
+ }),
265
+ view.saved === void 0 ? null : /* @__PURE__ */ jsxs("p", {
266
+ className: "text-sm text-po-dim",
267
+ title: view.saved.path,
268
+ children: ["Saved as ", /* @__PURE__ */ jsx("span", {
269
+ className: "font-mono text-po-text",
270
+ children: view.saved.id
271
+ })]
272
+ })
273
+ ]
274
+ }) : null] })
275
+ });
276
+ }
277
+ //#endregion
278
+ //#region src/extensions/workspaces/sessions/(frontend)/tool/exec.web.tsx
279
+ var exec_web_default = defineToolRenderer({ message: ExecToolCard });
280
+ //#endregion
281
+ //#region generated/web.ts
282
+ const via = (identity, value) => value === void 0 ? void 0 : {
283
+ ...identity,
284
+ ...value
285
+ };
286
+ const webPlugin = defineWebPlugin({
287
+ id: "codemode",
288
+ session: { get toolRenderers() {
289
+ return [via({ tools: ["discover"] }, discover_web_default), via({ tools: ["exec"] }, exec_web_default)];
290
+ } }
291
+ });
292
+ //#endregion
293
+ export { webPlugin };
294
+
295
+ //# sourceMappingURL=web.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web.mjs","names":["toolDiscover","toolExec"],"sources":["../../src/extensions/workspaces/sessions/(frontend)/tool/_lib/execToolView.ts","../../src/extensions/workspaces/sessions/(frontend)/tool/_components/DiscoverToolCard.tsx","../../src/extensions/workspaces/sessions/(frontend)/tool/discover.web.tsx","../../src/extensions/workspaces/sessions/(frontend)/tool/_components/ToolSection.tsx","../../src/extensions/workspaces/sessions/(frontend)/tool/_components/ExecToolCard.tsx","../../src/extensions/workspaces/sessions/(frontend)/tool/exec.web.tsx","../../generated/web.ts"],"sourcesContent":["import { type ToolResultView, toolResultTextLines } from '@agimon-ai/po-core/web';\n\n/** Tool names this package registers (registerTool's `name`). */\nexport const execToolName = 'exec' as const;\nexport const discoverToolName = 'discover' as const;\n\nconst SUMMARY_MAX = 120;\nconst ARGS_MAX = 160;\nconst CALLS_MAX = 50;\nconst IMAGE_TYPES = /^image\\/(?:png|jpeg|webp|gif)$/u;\nconst SAVED_LINE = /^Saved as (\\S+) \\((.+)\\)$/u;\n\nfunction record(value: unknown): Record<string, unknown> | undefined {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined;\n}\n\nfunction clip(text: string, max: number): string {\n return text.length <= max ? text : `${text.slice(0, max - 1)}…`;\n}\n\n/** The script the call ran, exactly as the agent wrote it. */\nexport function execCode(args: Readonly<Record<string, unknown>>): string {\n return typeof args.code === 'string' ? args.code : '';\n}\n\n/** The header line: the script's first line, with a leading `//` comment marker dropped. */\nexport function execSummary(args: Readonly<Record<string, unknown>>): string {\n const first = execCode(args)\n .split('\\n')\n .map((line) => line.trim())\n .find((line) => line !== '');\n if (first === undefined) return 'script';\n return clip(first.replace(/^\\/\\/+\\s*/u, ''), SUMMARY_MAX);\n}\n\n/** One namespace call the script made, as exec reports it in the result's details. */\nexport interface ExecCall {\n /** The member called, such as `browser.click` or `mcp.github.search_issues`. */\n name: string;\n args: Record<string, unknown>;\n ok: boolean;\n ms: number;\n /** The tool name whose own card shows this call, when another package has one. */\n tool?: string;\n error?: string;\n result?: ToolResultView;\n}\n\nfunction callOf(value: unknown): ExecCall | undefined {\n const call = record(value);\n if (call === undefined || typeof call.name !== 'string' || call.name === '') return undefined;\n const result = record(call.result);\n return {\n name: call.name,\n args: record(call.args) ?? {},\n ok: call.ok !== false,\n ms: typeof call.ms === 'number' && Number.isFinite(call.ms) && call.ms >= 0 ? Math.round(call.ms) : 0,\n ...(typeof call.tool === 'string' && call.tool !== '' ? { tool: call.tool } : {}),\n ...(typeof call.error === 'string' && call.error !== '' ? { error: call.error } : {}),\n ...(result !== undefined && Array.isArray(result.content)\n ? { result: { content: result.content, details: result.details } }\n : {}),\n };\n}\n\n/** The nested calls recorded in a result's details; anything malformed is skipped. */\nexport function execCalls(details: unknown): ExecCall[] {\n const calls = record(details)?.calls;\n if (!Array.isArray(calls)) return [];\n return calls\n .slice(0, CALLS_MAX)\n .map(callOf)\n .filter((call): call is ExecCall => call !== undefined);\n}\n\n/** A call's arguments on one line, for a row that has no card of its own. */\nexport function callArgsSummary(args: Readonly<Record<string, unknown>>): string {\n return Object.keys(args).length === 0 ? '' : clip(JSON.stringify(args), ARGS_MAX);\n}\n\nexport interface ExecImage {\n mimeType: string;\n data: string;\n}\n\nexport interface ExecResultView {\n lines: string[];\n /** The saved-script footer exec appends: the id to import it by, and where it lives. */\n saved?: { id: string; path: string };\n images: ExecImage[];\n}\n\n/** What a result holds, with the saved-script footer and the pictures taken out of the text. */\nexport function execResultView(result: ToolResultView | null): ExecResultView {\n if (result === null) return { lines: [], images: [] };\n let saved: ExecResultView['saved'];\n const content: unknown[] = [];\n for (const block of result.content) {\n const text = record(block)?.type === 'text' ? record(block)?.text : undefined;\n const match = typeof text === 'string' ? SAVED_LINE.exec(text.trim()) : null;\n if (match?.[1] !== undefined && match[2] !== undefined) saved = { id: match[1], path: match[2] };\n else content.push(block);\n }\n const images = content.flatMap((block): ExecImage[] => {\n const image = record(block);\n return image?.type === 'image' &&\n typeof image.data === 'string' &&\n typeof image.mimeType === 'string' &&\n IMAGE_TYPES.test(image.mimeType)\n ? [{ mimeType: image.mimeType, data: image.data }]\n : [];\n });\n return { lines: toolResultTextLines(content), ...(saved === undefined ? {} : { saved }), images };\n}\n\n/** The header line for discover: what was asked for. */\nexport function discoverSummary(args: Readonly<Record<string, unknown>>): string {\n if (typeof args.namespace === 'string' && args.namespace !== '') return args.namespace;\n if (typeof args.query === 'string' && args.query !== '') return `find \"${clip(args.query, SUMMARY_MAX)}\"`;\n return 'namespaces and scripts';\n}\n","import type { ToolMessageRenderProps } from '@agimon-ai/po-core/web';\nimport {\n CodeBlock,\n MessageItem,\n MessageItemBody,\n MessageItemHeader,\n MessageItemStatus,\n toolTone,\n} from '@agimon-ai/po-web-components';\n\nimport { discoverSummary, discoverToolName } from '../_lib/execToolView';\n\nexport type DiscoverToolCardProps = ToolMessageRenderProps & { defaultExpanded?: boolean };\n\n/** The discover tool's timeline item: folded to what was asked for, open to what came back. */\nexport function DiscoverToolCard({ args, output, running, isError, defaultExpanded = false }: DiscoverToolCardProps) {\n const declarations = typeof args.namespace === 'string' && args.namespace !== '' && !isError;\n return (\n <MessageItem tone={toolTone({ running, isError })} expandable defaultExpanded={defaultExpanded}>\n {({ expanded }) => (\n <>\n <MessageItemHeader title={discoverToolName}>\n <span data-testid={`tool-call-${discoverToolName}`} className=\"min-w-0 flex-1 truncate text-po-text\">\n {discoverSummary(args)}\n </span>\n </MessageItemHeader>\n {expanded ? (\n <MessageItemBody data-testid={`tool-result-${discoverToolName}`} className=\"flex flex-col gap-2\">\n {running && output === '' ? <MessageItemStatus tone=\"running\">running</MessageItemStatus> : null}\n {output === '' ? null : declarations ? (\n <div className=\"max-h-96 overflow-auto\">\n <CodeBlock text={output} className=\"language-ts\" />\n </div>\n ) : (\n <pre\n data-testid=\"tool-output\"\n className={`max-h-96 overflow-auto font-mono text-sm break-words whitespace-pre-wrap ${isError ? 'text-po-red' : 'text-po-text'}`}\n >\n {output}\n </pre>\n )}\n </MessageItemBody>\n ) : null}\n </>\n )}\n </MessageItem>\n );\n}\n","import { defineToolRenderer } from '@agimon-ai/po-core/web';\n\nimport { DiscoverToolCard } from './_components/DiscoverToolCard';\n\nexport default defineToolRenderer({ message: DiscoverToolCard });\n","import type { ReactNode } from 'react';\n\n/** A labelled part of an expanded card body. */\nexport function ToolSection({ label, children }: { label: string; children: ReactNode }) {\n return (\n <section className=\"flex flex-col gap-1.5\">\n <h4 className=\"text-sm font-medium text-po-dim\">{label}</h4>\n {children}\n </section>\n );\n}\n","import type { ToolMessageRenderProps } from '@agimon-ai/po-core/web';\nimport {\n CodeBlock,\n MessageItem,\n MessageItemBody,\n MessageItemHeader,\n MessageItemStatus,\n toolTone,\n} from '@agimon-ai/po-web-components';\n\nimport {\n callArgsSummary,\n execCalls,\n execCode,\n execResultView,\n execSummary,\n execToolName,\n type ExecCall,\n} from '../_lib/execToolView';\nimport { ToolSection } from './ToolSection';\n\n/** Draws another tool's own card for a nested call, or nothing when no package owns one. */\nexport type RenderNestedTool = NonNullable<ToolMessageRenderProps['renderTool']>;\n\nexport type ExecToolCardProps = ToolMessageRenderProps & { defaultExpanded?: boolean };\n\nfunction CallRow({ call }: { call: ExecCall }) {\n const args = callArgsSummary(call.args);\n return (\n <div data-testid=\"exec-call\" className=\"flex flex-col gap-0.5\">\n <div className=\"flex items-center gap-2 text-sm\">\n <span className=\"shrink-0 font-mono text-po-text\">{call.name}</span>\n <span className=\"min-w-0 flex-1 truncate font-mono text-po-dim\">{args}</span>\n <span aria-hidden className={`w-3 shrink-0 text-center ${call.ok ? 'text-po-green' : 'text-po-red'}`}>\n {call.ok ? '✓' : '✗'}\n </span>\n <span className=\"w-16 shrink-0 text-right tabular-nums text-po-dim\">{call.ms} ms</span>\n </div>\n {call.error === undefined ? null : <p className=\"pl-5 text-sm break-words text-po-red\">{call.error}</p>}\n </div>\n );\n}\n\nfunction Calls({ calls, renderTool }: { calls: readonly ExecCall[]; renderTool: RenderNestedTool | undefined }) {\n return (\n <ul className=\"flex flex-col gap-2\">\n {calls.map((call, index) => {\n const card =\n call.tool === undefined || renderTool === undefined\n ? null\n : renderTool({\n toolName: call.tool,\n args: call.args,\n result: call.result ?? null,\n isError: !call.ok,\n });\n return <li key={`${String(index)}-${call.name}`}>{card ?? <CallRow call={call} />}</li>;\n })}\n </ul>\n );\n}\n\n/**\n * The exec tool's timeline item. It stays folded until opened: the script is the\n * point of the call, so opening shows the code, every namespace call it made\n * (as the owning tool's card when one exists), then what it returned.\n */\nexport function ExecToolCard({\n args,\n result,\n running,\n isError,\n defaultExpanded = false,\n renderTool,\n}: ExecToolCardProps) {\n const code = execCode(args);\n const view = execResultView(result);\n const calls = execCalls(result?.details);\n return (\n <MessageItem tone={toolTone({ running, isError })} expandable defaultExpanded={defaultExpanded}>\n {({ expanded }) => (\n <>\n <MessageItemHeader title={execToolName}>\n <span data-testid={`tool-call-${execToolName}`} className=\"min-w-0 flex-1 truncate text-po-text\">\n {execSummary(args)}\n </span>\n {calls.length > 0 ? (\n <span className=\"shrink-0 text-sm text-po-dim\">\n {calls.length} {calls.length === 1 ? 'call' : 'calls'}\n </span>\n ) : null}\n </MessageItemHeader>\n {expanded ? (\n <MessageItemBody data-testid={`tool-result-${execToolName}`} className=\"flex flex-col gap-4\">\n {code === '' ? null : (\n <ToolSection label=\"Code\">\n <CodeBlock text={code} className=\"language-ts\" />\n </ToolSection>\n )}\n {calls.length === 0 ? null : (\n <ToolSection label=\"Calls\">\n <Calls calls={calls} renderTool={renderTool} />\n </ToolSection>\n )}\n {running && view.lines.length === 0 ? (\n <MessageItemStatus tone=\"running\">running</MessageItemStatus>\n ) : (\n <ToolSection label={isError ? 'Error' : 'Result'}>\n {view.lines.length === 0 && view.images.length === 0 ? (\n <p className=\"text-sm text-po-dim\">No output.</p>\n ) : null}\n {view.lines.length === 0 ? null : (\n <pre\n data-testid=\"tool-output\"\n className={`max-h-72 overflow-auto font-mono text-sm break-words whitespace-pre-wrap ${isError ? 'text-po-red' : 'text-po-text'}`}\n >\n {view.lines.join('\\n')}\n </pre>\n )}\n {view.images.map((image, index) => (\n <img\n key={`${image.mimeType}-${String(index)}`}\n src={`data:${image.mimeType};base64,${image.data}`}\n alt={`Script image ${String(index + 1)}`}\n data-testid=\"tool-output-image\"\n className=\"max-h-96 max-w-full self-start rounded-md border border-po-border-soft\"\n />\n ))}\n </ToolSection>\n )}\n {view.saved === undefined ? null : (\n <p className=\"text-sm text-po-dim\" title={view.saved.path}>\n Saved as <span className=\"font-mono text-po-text\">{view.saved.id}</span>\n </p>\n )}\n </MessageItemBody>\n ) : null}\n </>\n )}\n </MessageItem>\n );\n}\n","import { defineToolRenderer } from '@agimon-ai/po-core/web';\n\nimport { ExecToolCard } from './_components/ExecToolCard';\n\nexport default defineToolRenderer({ message: ExecToolCard });\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineWebPlugin, type WebPluginContributions } from '@agimon-ai/po-core/web';\n\nimport toolDiscover from '../src/extensions/workspaces/sessions/(frontend)/tool/discover.web';\nimport toolExec from '../src/extensions/workspaces/sessions/(frontend)/tool/exec.web';\n\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const webPlugin = defineWebPlugin({\n id: 'codemode',\n session: {\n get toolRenderers(): WebPluginContributions['toolRenderers'] { return [via({ tools: ['discover'] }, toolDiscover), via({ tools: ['exec'] }, toolExec)]; },\n },\n});\n"],"mappings":"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"}
package/dist/index.cjs CHANGED
@@ -1,4 +1,4 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_codemodeTools = require("./codemodeTools-BX2qieCR.cjs");
2
+ const require_codemodeTools = require("./codemodeTools-CLgSDqfU.cjs");
3
3
  exports.createCodemodeRegistry = require_codemodeTools.createCodemodeRegistry;
4
4
  exports.createCodemodeTools = require_codemodeTools.createCodemodeTools;
package/dist/index.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { PoCodemodeService } from "@agimon-ai/po-core/codemode";
2
+ import { PoHeadlessTool } from "@agimon-ai/po-core/headless";
2
3
  import { Type } from "typebox";
3
4
  import { PoIsolateService } from "@agimon-ai/po-core/platform";
4
- import { PoHeadlessTool } from "@agimon-ai/po-core/headless";
5
5
  //#region src/services/codemodeRegistry/index.d.ts
6
6
  /** The session's namespaces and script folders, in registration order. One name per session. */
7
7
  export declare function createCodemodeRegistry(): PoCodemodeService;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/services/codemodeRegistry/index.ts","../src/schemas/codemodeTools.ts","../src/services/codemodeScripts/type.ts","../src/services/codemodeTools/index.ts"],"mappings":";;;;;;wBASgB,0BAA0B;;;cCP7B,oBAAkB,KAAA;;;;cAMlB,gBAAc,KAAA;;;;;;;UCPV;;WAEN;WACA;;WAEA;;;UAIM;;EAEf,KAAK,eAAe;aAAmB;aAA4B;;;EAEnE,QAAQ,mBAAmB,8BAA8B;aAAmB;aAAqB;;;EAEjG,KAAK,6BAA6B,iBAAiB,QAAQ;;;;UCqB5C;WACN,UAAU;;WAEV,eAAe;;WAEf,UAAU;;UAGJ;WACN,UAAU,sBAAsB;WAChC,MAAM,sBAAsB;;;wBAwHvB,sBAAsB,UAAU,SAAS,WAAW,uBAAuB"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/services/codemodeRegistry/index.ts","../src/schemas/codemodeTools.ts","../src/services/codemodeScripts/type.ts","../src/services/codemodeTools/index.ts"],"mappings":";;;;;;wBASgB,0BAA0B;;;cCP7B,oBAAkB,KAAA;;;;cAMlB,gBAAc,KAAA;;;;;;;UCPV;;WAEN;WACA;;WAEA;;;UAIM;;EAEf,KAAK,eAAe;aAAmB;aAA4B;;;EAEnE,QAAQ,mBAAmB,8BAA8B;aAAmB;aAAqB;;;EAEjG,KAAK,6BAA6B,iBAAiB,QAAQ;;;;UCiC5C;WACN,UAAU;;WAEV,eAAe;;WAEf,UAAU;;UAGJ;WACN,UAAU,sBAAsB;WAChC,MAAM,sBAAsB;;;wBA+JvB,sBAAsB,UAAU,SAAS,WAAW,uBAAuB"}
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- export { n as createCodemodeRegistry, t as createCodemodeTools } from "./codemodeTools-CSYUxIeA.mjs";
1
+ export { n as createCodemodeRegistry, t as createCodemodeTools } from "./codemodeTools-BdwOARH8.mjs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agimon-ai/po-codemode",
3
- "version": "0.0.1-alpha.1",
3
+ "version": "0.0.1-alpha.2",
4
4
  "description": "Code mode for Po sessions: discover and exec over namespaces other packages contribute",
5
5
  "keywords": [
6
6
  "ai",
@@ -43,22 +43,31 @@
43
43
  "import": "./dist/extensions/server.mjs",
44
44
  "require": "./dist/extensions/server.cjs"
45
45
  },
46
+ "./extensions/web": {
47
+ "import": "./dist/extensions/web.mjs"
48
+ },
46
49
  "./package.json": "./package.json"
47
50
  },
48
51
  "publishConfig": {
49
52
  "access": "public"
50
53
  },
51
54
  "dependencies": {
52
- "@agimon-ai/po-core": "0.0.0-alpha.28",
55
+ "@agimon-ai/po-core": "0.0.0-alpha.29",
56
+ "@agimon-ai/po-web-components": "0.0.0-alpha.29",
53
57
  "@deepseek-ai/cordis": "4.0.5",
58
+ "react": "19.3.0",
54
59
  "typebox": "1.3.37"
55
60
  },
56
61
  "devDependencies": {
57
- "@agimon-ai/po-build": "0.0.0-alpha.28",
58
- "@agimon-ai/vibe-lint-plugin-po-extension": "0.0.0-alpha.28",
62
+ "@agimon-ai/po-build": "0.0.0-alpha.29",
63
+ "@agimon-ai/vibe-lint-plugin-po-extension": "0.0.0-alpha.29",
64
+ "@agimon-ai/vibe-lint-plugin-po-web": "0.0.0-alpha.29",
59
65
  "@earendil-works/pi-coding-agent": "1.3.0",
60
66
  "@types/node": "26.6.5",
67
+ "@types/react": "19.3.0",
68
+ "@types/react-dom": "19.3.0",
61
69
  "@vitest/coverage-v8": "5.0.4",
70
+ "react-dom": "19.3.0",
62
71
  "tsdown": "0.23.1",
63
72
  "typescript": "7.0.2",
64
73
  "vitest": "5.0.4"
@@ -90,10 +99,18 @@
90
99
  ]
91
100
  }
92
101
  },
102
+ "poWeb": {
103
+ "pluginId": "codemode",
104
+ "channels": [],
105
+ "client": "./dist/extensions/web.mjs",
106
+ "scopes": [
107
+ "session"
108
+ ]
109
+ },
93
110
  "scripts": {
94
111
  "build": "tsdown",
95
112
  "test": "vitest --run",
96
- "typecheck": "tsc --noEmit",
113
+ "typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.web.json",
97
114
  "lint": "oxlint . && oxfmt . --check",
98
115
  "fixcode": "oxlint . --fix && oxfmt ."
99
116
  }
@@ -9,6 +9,7 @@ Code mode gives you two tools.
9
9
 
10
10
  - `discover`: with no arguments, lists the namespaces this session has (for example `browser`) and their members, plus reusable scripts from the active domains and this session's saved scripts (capped, newest first). `discover({ namespace })` shows full TypeScript declarations; `discover({ query })` finds members, script names and script descriptions.
11
11
  - `exec`: runs a TypeScript async function body. Namespaces are in scope as globals. `return` a value, use `console.log` for notes, `image(data, mimeType)` to send back a screenshot, and `sleep(ms)` to wait.
12
+ - Read the return type before relying on a result. `Promise<string>` is text, not an object. A doc such as `JSON text: Browser.ExpectResult` means `JSON.parse(text) as Browser.ExpectResult`, and its fields tell you what a success looks like (for example `success` only says the check ran, `passed` is the outcome). A failed call rejects with the tool's message. An MCP tool that declares an output schema returns it typed in `structuredContent`.
12
13
 
13
14
  ```ts
14
15
  // exec({ code })
@@ -42,3 +43,4 @@ To keep a useful script, copy the saved file with normal file tools to `plugins/
42
43
  - Objects you get from a namespace are live. Listeners you add and the objects themselves stop working when the run ends; keep state in the namespace, not in script variables.
43
44
  - `exec` runs inside the Po server with full trust, like `bash`. Do not use it to bypass a blocked tool.
44
45
  - There is no `eval`, `Function`, `setTimeout`, `fetch`, `require` or `process` inside a script.
46
+ - Subagents have `exec` too, and up to 8 runs can overlap across you and them. Namespaces are shared, so a run sees the pages and tasks another agent made.
@@ -1 +0,0 @@
1
- {"version":3,"file":"codemodeTools-BX2qieCR.cjs","names":["Type"],"sources":["../src/services/codemodeRegistry/index.ts","../src/schemas/codemodeTools.ts","../src/services/codemodeTools/index.ts"],"sourcesContent":["import {\n assertCodemodeNamespaceName,\n type PoCodemodeNamespace,\n type PoCodemodeRegistration,\n type PoCodemodeScriptSource,\n type PoCodemodeService,\n} from '@agimon-ai/po-core/codemode';\n\n/** The session's namespaces and script folders, in registration order. One name per session. */\nexport function createCodemodeRegistry(): PoCodemodeService {\n const entries = new Map<string, { source: string; namespace: PoCodemodeNamespace }>();\n const scripts = new Set<PoCodemodeScriptSource>();\n const listeners = new Set<() => void>();\n const notify = (): void => {\n for (const listener of listeners) listener();\n };\n return {\n register(source: string, namespace: PoCodemodeNamespace): PoCodemodeRegistration {\n assertCodemodeNamespaceName(namespace.name);\n const taken = entries.get(namespace.name);\n if (taken) {\n throw new Error(\n `Code-mode namespace \"${namespace.name}\" from ${source} is already registered by ${taken.source}.`,\n );\n }\n const entry = { source, namespace };\n entries.set(namespace.name, entry);\n notify();\n return {\n dispose: () => {\n if (entries.get(namespace.name) !== entry) return;\n entries.delete(namespace.name);\n notify();\n },\n };\n },\n list: () => [...entries.values()].map((entry) => entry.namespace),\n registerScripts(_source: string, entry: PoCodemodeScriptSource): PoCodemodeRegistration {\n const owned = { domain: entry.domain, directory: entry.directory };\n scripts.add(owned);\n notify();\n return { dispose: () => void (scripts.delete(owned) && notify()) };\n },\n listScripts: () => [...scripts],\n subscribe(listener: () => void): () => void {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n };\n}\n","import { Type, type Static } from 'typebox';\n\nexport const DiscoverToolSchema = Type.Object({\n namespace: Type.Optional(Type.String({ description: 'Show the full TypeScript declarations of one namespace.' })),\n query: Type.Optional(Type.String({ description: 'Find matching members across every namespace.' })),\n});\nexport type DiscoverToolParams = Static<typeof DiscoverToolSchema>;\n\nexport const ExecToolSchema = Type.Object({\n code: Type.String({\n description:\n 'TypeScript body of an async function. Top-level await and return work. The returned value, console output and image() calls come back.',\n }),\n timeoutMs: Type.Optional(\n Type.Integer({ minimum: 1_000, maximum: 120_000, description: 'Deadline in milliseconds. Default 30000.' }),\n ),\n});\nexport type ExecToolParams = Static<typeof ExecToolSchema>;\n","import type { PoCodemodeNamespace, PoCodemodeRun, PoCodemodeService } from '@agimon-ai/po-core/codemode';\nimport type {\n PoHeadlessContent,\n PoHeadlessExecutionContext,\n PoHeadlessTool,\n PoHeadlessToolResult,\n} from '@agimon-ai/po-core/headless';\nimport type { PoIsolateResult, PoIsolateService } from '@agimon-ai/po-core/platform';\n\nimport {\n DiscoverToolSchema,\n ExecToolSchema,\n type DiscoverToolParams,\n type ExecToolParams,\n} from '../../schemas/codemodeTools';\nimport type { CodemodeScriptsPort } from '../codemodeScripts/type';\n\nconst DEFAULT_TIMEOUT_MS = 30_000;\nconst MAX_TIMEOUT_MS = 120_000;\nconst MIN_TIMEOUT_MS = 1_000;\nconst MAX_LOG_CHARS = 10_000;\nconst MAX_VALUE_CHARS = 64 * 1024;\nconst MAX_DECLARATION_CHARS = 12_000;\nconst MAX_QUERY_LINES = 40;\nconst MAX_LISTED_SCRIPTS = 20;\nconst MAX_IMAGES = 4;\nconst MAX_IMAGE_BYTES = 5 * 1024 * 1024;\nconst DEFAULT_IMAGE_MIME = 'image/png';\nconst MEMBER_LINE = /^\\s{2}(?:readonly\\s+)?(\\w+)\\s*[(?:<]/u;\n\nconst GLOBALS_HELP =\n 'Globals: console.log/info/warn/error, image(data, mimeType?) to return a screenshot, sleep(ms). ' +\n 'Return a value with `return`.';\nconst SCRIPTS_HELP =\n 'Every exec run is saved. Call a saved script with `await (await import(specifier))(args)`; ' +\n 'inside it, `args` is the argument and its `return` is the result.';\n\nexport interface CodemodeToolsOptions {\n readonly registry: PoCodemodeService;\n /** Resolved per call, so a host that binds the isolate late still works. */\n readonly isolate: () => PoIsolateService | undefined;\n /** Saves every exec body and backs `import()`; without it nothing is saved or importable. */\n readonly scripts?: CodemodeScriptsPort;\n}\n\nexport interface CodemodeTools {\n readonly discover: PoHeadlessTool<typeof DiscoverToolSchema>;\n readonly exec: PoHeadlessTool<typeof ExecToolSchema>;\n}\n\nfunction text(value: string, isError = false): PoHeadlessToolResult {\n return { content: [{ type: 'text', text: value }], ...(isError ? { isError: true } : {}) };\n}\n\nfunction truncate(value: string, limit: number): string {\n return value.length <= limit ? value : `${value.slice(0, limit)}\\n[truncated ${value.length - limit} chars]`;\n}\n\nfunction format(value: unknown): string {\n if (typeof value === 'string') return value;\n try {\n const json = JSON.stringify(value, null, 2);\n if (json !== undefined) return json;\n } catch {\n // Cyclic or exotic values fall back to their string form.\n }\n return String(value);\n}\n\nfunction memberNames(namespace: PoCodemodeNamespace): string[] {\n const names = new Set<string>();\n for (const line of namespace.declarations.split('\\n')) {\n const name = MEMBER_LINE.exec(line)?.[1];\n if (name) names.add(name);\n }\n return [...names];\n}\n\nfunction bytesToBase64(bytes: Uint8Array): string {\n let binary = '';\n for (let index = 0; index < bytes.length; index += 0x8000) {\n binary += String.fromCharCode(...bytes.subarray(index, index + 0x8000));\n }\n return btoa(binary);\n}\n\n/** Collects what a script prints and the images it returns, within the output caps. */\nfunction createOutput() {\n const lines: string[] = [];\n const images: { data: string; mimeType: string }[] = [];\n let imageBytes = 0;\n const log =\n (level: string) =>\n (...args: unknown[]) => {\n const line = args.map(format).join(' ');\n lines.push(level === 'log' || level === 'info' ? line : `[${level}] ${line}`);\n };\n const note = (message: string): void => void lines.push(`[note] ${message}`);\n const addImage = (input: unknown, mimeType?: unknown): void => {\n if (typeof input === 'object' && input !== null && 'images' in input && Array.isArray(input.images)) {\n for (const image of input.images) addImage(image);\n return;\n }\n let data: string;\n let mime = typeof mimeType === 'string' ? mimeType : DEFAULT_IMAGE_MIME;\n if (typeof input === 'string')\n data = input.replace(/^data:([^;]+);base64,/u, (_match, type: string) => ((mime = type), ''));\n else if (ArrayBuffer.isView(input))\n data = bytesToBase64(new Uint8Array(input.buffer, input.byteOffset, input.byteLength));\n else if (typeof input === 'object' && input !== null && 'data' in input && typeof input.data === 'string') {\n data = input.data;\n if ('mimeType' in input && typeof input.mimeType === 'string') mime = input.mimeType;\n } else throw new TypeError('image() takes base64 text, bytes, or { data, mimeType }.');\n if (images.length >= MAX_IMAGES) throw new RangeError(`An exec run returns at most ${MAX_IMAGES} images.`);\n imageBytes += Math.ceil((data.length * 3) / 4);\n if (imageBytes > MAX_IMAGE_BYTES) throw new RangeError('Images from one exec run exceed 5 MB.');\n images.push({ data, mimeType: mime });\n };\n const console = { log: log('log'), info: log('info'), warn: log('warn'), error: log('error'), debug: log('debug') };\n return { console, note, addImage, lines, images };\n}\n\n/** The session's active domains; every registered domain when the host reports none. */\nfunction activeDomains(execution: PoHeadlessExecutionContext | undefined): readonly string[] | undefined {\n return execution?.selection?.domains;\n}\n\nfunction toResult(\n result: PoIsolateResult,\n output: ReturnType<typeof createOutput>,\n saved: string | undefined,\n): PoHeadlessToolResult {\n const content: PoHeadlessContent[] = [];\n if (output.lines.length > 0) content.push({ type: 'text', text: truncate(output.lines.join('\\n'), MAX_LOG_CHARS) });\n if (result.ok) {\n if (ArrayBuffer.isView(result.value)) {\n content.push({ type: 'text', text: 'The script returned bytes. Pass them to image(data, mimeType) instead.' });\n } else if (result.value !== undefined) {\n content.push({ type: 'text', text: truncate(format(result.value), MAX_VALUE_CHARS) });\n }\n } else {\n const { kind, name, message } = result.error;\n const hint = kind === 'timeout' ? ' Raise timeoutMs or split the work into smaller exec calls.' : '';\n content.push({ type: 'text', text: `${name}: ${message}${hint}` });\n }\n if (content.length === 0) content.push({ type: 'text', text: '(no return value)' });\n if (saved !== undefined) content.push({ type: 'text', text: saved });\n for (const image of output.images) content.push({ type: 'image', data: image.data, mimeType: image.mimeType });\n return { content, ...(result.ok ? {} : { isError: true }) };\n}\n\nfunction sleep(ms: number, signal: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal.aborted) return reject(new Error('Run ended.'));\n const timer = setTimeout(resolve, Math.max(0, ms));\n signal.addEventListener(\n 'abort',\n () => {\n clearTimeout(timer);\n reject(new Error('Run ended.'));\n },\n { once: true },\n );\n });\n}\n\n/** `discover` and `exec` for one session, over the namespaces its packages contributed. */\nexport function createCodemodeTools({ registry, isolate, scripts }: CodemodeToolsOptions): CodemodeTools {\n let busy = false;\n\n const visible = (service: PoIsolateService): PoCodemodeNamespace[] =>\n registry.list().filter((namespace) => service.liveObjects || namespace.portable === true);\n\n // ponytail: the cockpit's generic tool item renders both for now; add a poWeb renderer for exec code and images when it earns one.\n // web-plugin-tool-renderers: ignore discover, plain text result\n const discover: CodemodeTools['discover'] = {\n name: 'discover',\n label: 'Discover',\n description:\n 'List the code-mode namespaces and reusable scripts you can use from `exec`, show one namespace in full, ' +\n 'or search members and scripts. ' +\n 'Not required before exec: its description already names the namespaces.',\n parameters: DiscoverToolSchema,\n promptSnippet: 'List code-mode namespaces and their TypeScript declarations',\n executionMode: 'parallel',\n async execute(_toolCallId, parameters: DiscoverToolParams, _signal, _onUpdate, execution) {\n const service = isolate();\n if (!service) return text('Code mode is not available on this host.', true);\n const namespaces = visible(service);\n // Imports need a host with live objects; the edge saves scripts but cannot chain them.\n const listed = scripts && service.liveObjects ? await scripts.list(activeDomains(execution)) : [];\n if (parameters.namespace !== undefined) {\n const found = namespaces.find((namespace) => namespace.name === parameters.namespace);\n if (!found) {\n const names = namespaces.map((namespace) => namespace.name).join(', ') || 'none';\n return text(`Unknown namespace \"${parameters.namespace}\". Registered: ${names}.`, true);\n }\n return text(truncate(found.declarations, MAX_DECLARATION_CHARS));\n }\n if (parameters.query !== undefined) {\n const needle = parameters.query.toLowerCase();\n const hits: string[] = [];\n for (const namespace of namespaces) {\n const lines = namespace.declarations.split('\\n');\n lines.forEach((line, index) => {\n if (!line.toLowerCase().includes(needle) || hits.length >= MAX_QUERY_LINES) return;\n const doc = lines[index - 1]?.trim().startsWith('/**') ? `${lines[index - 1]?.trim()} ` : '';\n hits.push(`${namespace.name}: ${doc}${line.trim()}`);\n });\n }\n for (const script of listed) {\n if (hits.length >= MAX_QUERY_LINES) break;\n if (`${script.specifier} ${script.description}`.toLowerCase().includes(needle)) {\n hits.push(`script ${script.specifier}: ${script.description}`);\n }\n }\n return text(hits.length > 0 ? hits.join('\\n') : `No members or scripts match \"${parameters.query}\".`);\n }\n const sections: string[] = [];\n if (namespaces.length === 0) sections.push('No namespaces are registered in this session.');\n for (const namespace of namespaces) {\n sections.push(`- ${namespace.name}: ${namespace.summary}\\n members: ${memberNames(namespace).join(', ')}`);\n }\n sections.push(GLOBALS_HELP);\n if (!service.liveObjects) sections.push('This host runs plain JavaScript with JSON-only functions.');\n if (listed.length > 0) {\n sections.push(`Scripts. ${SCRIPTS_HELP}`);\n for (const script of listed.slice(0, MAX_LISTED_SCRIPTS)) {\n sections.push(`- ${script.specifier}${script.description ? `: ${script.description}` : ''}`);\n }\n if (listed.length > MAX_LISTED_SCRIPTS) {\n sections.push(`...and ${listed.length - MAX_LISTED_SCRIPTS} more; use discover({ query }) to search.`);\n }\n }\n if (namespaces.length > 0) sections.push('Call discover({ namespace }) for full types.');\n return text(sections.join('\\n'));\n },\n };\n\n // web-plugin-tool-renderers: ignore exec, generic item until a code and image renderer exists\n const exec: CodemodeTools['exec'] = {\n name: 'exec',\n label: 'Exec',\n get description(): string {\n const service = isolate();\n const namespaces = service ? visible(service) : [];\n const listed = namespaces.map((namespace) => `- ${namespace.name}: ${namespace.summary}`).join('\\n');\n return [\n 'Run a TypeScript script inside the Po server with live objects from the namespaces below in scope.',\n 'It runs with full server trust, like bash. Keep each call to one logical step.',\n listed || '(no namespaces registered yet; call discover to check)',\n GLOBALS_HELP,\n ...(scripts && service?.liveObjects ? [`${SCRIPTS_HELP} discover lists saved and domain scripts.`] : []),\n 'Use discover({ namespace }) for full signatures when needed.',\n ].join('\\n');\n },\n parameters: ExecToolSchema,\n promptSnippet: 'Run a TypeScript script against live Po objects (browser and other namespaces)',\n executionMode: 'serial',\n async execute(_toolCallId, parameters: ExecToolParams, signal, _onUpdate, execution) {\n const service = isolate();\n if (!service) return text('Code mode is not available on this host.', true);\n if (busy) return text('Another exec run is still active in this session. Wait for it to finish.', true);\n busy = true;\n const controller = new AbortController();\n const runSignal = signal ? AbortSignal.any([signal, controller.signal]) : controller.signal;\n const cleanups: (() => void | Promise<void>)[] = [];\n const output = createOutput();\n const run: PoCodemodeRun = {\n sessionId: execution.sessionId,\n signal: runSignal,\n onDispose: (cleanup) => void cleanups.push(cleanup),\n };\n try {\n let saved: string | undefined;\n try {\n const file = await scripts?.save(parameters.code);\n if (file) saved = `Saved as ${file.specifier} (${file.path})`;\n } catch (error) {\n output.note(`Could not save the script: ${error instanceof Error ? error.message : String(error)}`);\n }\n const globals: Record<string, unknown> = {\n console: output.console,\n image: output.addImage,\n sleep: (ms: number) => sleep(ms, runSignal),\n };\n const deny = new Set<string>();\n for (const namespace of visible(service)) {\n globals[namespace.name] = namespace.bind(run);\n for (const member of namespace.deny ?? []) deny.add(member);\n }\n const deadlineMs = Math.min(\n MAX_TIMEOUT_MS,\n Math.max(MIN_TIMEOUT_MS, parameters.timeoutMs ?? DEFAULT_TIMEOUT_MS),\n );\n const result = await service.run({\n source: parameters.code,\n globals,\n deadlineMs,\n signal: runSignal,\n deny: [...deny],\n onDiagnostic: output.note,\n ...(scripts ? { resolveImport: (specifier) => scripts.resolve(specifier, activeDomains(execution)) } : {}),\n });\n return toResult(result, output, saved);\n } catch (error) {\n return text(\n `Code mode could not run the script: ${error instanceof Error ? error.message : String(error)}`,\n true,\n );\n } finally {\n controller.abort();\n for (const cleanup of cleanups.reverse()) {\n await Promise.resolve()\n .then(cleanup)\n .catch((error: unknown) => output.note(`cleanup failed: ${String(error)}`));\n }\n busy = false;\n }\n },\n };\n\n return { discover, exec };\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"codemodeTools-CSYUxIeA.mjs","names":[],"sources":["../src/services/codemodeRegistry/index.ts","../src/schemas/codemodeTools.ts","../src/services/codemodeTools/index.ts"],"sourcesContent":["import {\n assertCodemodeNamespaceName,\n type PoCodemodeNamespace,\n type PoCodemodeRegistration,\n type PoCodemodeScriptSource,\n type PoCodemodeService,\n} from '@agimon-ai/po-core/codemode';\n\n/** The session's namespaces and script folders, in registration order. One name per session. */\nexport function createCodemodeRegistry(): PoCodemodeService {\n const entries = new Map<string, { source: string; namespace: PoCodemodeNamespace }>();\n const scripts = new Set<PoCodemodeScriptSource>();\n const listeners = new Set<() => void>();\n const notify = (): void => {\n for (const listener of listeners) listener();\n };\n return {\n register(source: string, namespace: PoCodemodeNamespace): PoCodemodeRegistration {\n assertCodemodeNamespaceName(namespace.name);\n const taken = entries.get(namespace.name);\n if (taken) {\n throw new Error(\n `Code-mode namespace \"${namespace.name}\" from ${source} is already registered by ${taken.source}.`,\n );\n }\n const entry = { source, namespace };\n entries.set(namespace.name, entry);\n notify();\n return {\n dispose: () => {\n if (entries.get(namespace.name) !== entry) return;\n entries.delete(namespace.name);\n notify();\n },\n };\n },\n list: () => [...entries.values()].map((entry) => entry.namespace),\n registerScripts(_source: string, entry: PoCodemodeScriptSource): PoCodemodeRegistration {\n const owned = { domain: entry.domain, directory: entry.directory };\n scripts.add(owned);\n notify();\n return { dispose: () => void (scripts.delete(owned) && notify()) };\n },\n listScripts: () => [...scripts],\n subscribe(listener: () => void): () => void {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n };\n}\n","import { Type, type Static } from 'typebox';\n\nexport const DiscoverToolSchema = Type.Object({\n namespace: Type.Optional(Type.String({ description: 'Show the full TypeScript declarations of one namespace.' })),\n query: Type.Optional(Type.String({ description: 'Find matching members across every namespace.' })),\n});\nexport type DiscoverToolParams = Static<typeof DiscoverToolSchema>;\n\nexport const ExecToolSchema = Type.Object({\n code: Type.String({\n description:\n 'TypeScript body of an async function. Top-level await and return work. The returned value, console output and image() calls come back.',\n }),\n timeoutMs: Type.Optional(\n Type.Integer({ minimum: 1_000, maximum: 120_000, description: 'Deadline in milliseconds. Default 30000.' }),\n ),\n});\nexport type ExecToolParams = Static<typeof ExecToolSchema>;\n","import type { PoCodemodeNamespace, PoCodemodeRun, PoCodemodeService } from '@agimon-ai/po-core/codemode';\nimport type {\n PoHeadlessContent,\n PoHeadlessExecutionContext,\n PoHeadlessTool,\n PoHeadlessToolResult,\n} from '@agimon-ai/po-core/headless';\nimport type { PoIsolateResult, PoIsolateService } from '@agimon-ai/po-core/platform';\n\nimport {\n DiscoverToolSchema,\n ExecToolSchema,\n type DiscoverToolParams,\n type ExecToolParams,\n} from '../../schemas/codemodeTools';\nimport type { CodemodeScriptsPort } from '../codemodeScripts/type';\n\nconst DEFAULT_TIMEOUT_MS = 30_000;\nconst MAX_TIMEOUT_MS = 120_000;\nconst MIN_TIMEOUT_MS = 1_000;\nconst MAX_LOG_CHARS = 10_000;\nconst MAX_VALUE_CHARS = 64 * 1024;\nconst MAX_DECLARATION_CHARS = 12_000;\nconst MAX_QUERY_LINES = 40;\nconst MAX_LISTED_SCRIPTS = 20;\nconst MAX_IMAGES = 4;\nconst MAX_IMAGE_BYTES = 5 * 1024 * 1024;\nconst DEFAULT_IMAGE_MIME = 'image/png';\nconst MEMBER_LINE = /^\\s{2}(?:readonly\\s+)?(\\w+)\\s*[(?:<]/u;\n\nconst GLOBALS_HELP =\n 'Globals: console.log/info/warn/error, image(data, mimeType?) to return a screenshot, sleep(ms). ' +\n 'Return a value with `return`.';\nconst SCRIPTS_HELP =\n 'Every exec run is saved. Call a saved script with `await (await import(specifier))(args)`; ' +\n 'inside it, `args` is the argument and its `return` is the result.';\n\nexport interface CodemodeToolsOptions {\n readonly registry: PoCodemodeService;\n /** Resolved per call, so a host that binds the isolate late still works. */\n readonly isolate: () => PoIsolateService | undefined;\n /** Saves every exec body and backs `import()`; without it nothing is saved or importable. */\n readonly scripts?: CodemodeScriptsPort;\n}\n\nexport interface CodemodeTools {\n readonly discover: PoHeadlessTool<typeof DiscoverToolSchema>;\n readonly exec: PoHeadlessTool<typeof ExecToolSchema>;\n}\n\nfunction text(value: string, isError = false): PoHeadlessToolResult {\n return { content: [{ type: 'text', text: value }], ...(isError ? { isError: true } : {}) };\n}\n\nfunction truncate(value: string, limit: number): string {\n return value.length <= limit ? value : `${value.slice(0, limit)}\\n[truncated ${value.length - limit} chars]`;\n}\n\nfunction format(value: unknown): string {\n if (typeof value === 'string') return value;\n try {\n const json = JSON.stringify(value, null, 2);\n if (json !== undefined) return json;\n } catch {\n // Cyclic or exotic values fall back to their string form.\n }\n return String(value);\n}\n\nfunction memberNames(namespace: PoCodemodeNamespace): string[] {\n const names = new Set<string>();\n for (const line of namespace.declarations.split('\\n')) {\n const name = MEMBER_LINE.exec(line)?.[1];\n if (name) names.add(name);\n }\n return [...names];\n}\n\nfunction bytesToBase64(bytes: Uint8Array): string {\n let binary = '';\n for (let index = 0; index < bytes.length; index += 0x8000) {\n binary += String.fromCharCode(...bytes.subarray(index, index + 0x8000));\n }\n return btoa(binary);\n}\n\n/** Collects what a script prints and the images it returns, within the output caps. */\nfunction createOutput() {\n const lines: string[] = [];\n const images: { data: string; mimeType: string }[] = [];\n let imageBytes = 0;\n const log =\n (level: string) =>\n (...args: unknown[]) => {\n const line = args.map(format).join(' ');\n lines.push(level === 'log' || level === 'info' ? line : `[${level}] ${line}`);\n };\n const note = (message: string): void => void lines.push(`[note] ${message}`);\n const addImage = (input: unknown, mimeType?: unknown): void => {\n if (typeof input === 'object' && input !== null && 'images' in input && Array.isArray(input.images)) {\n for (const image of input.images) addImage(image);\n return;\n }\n let data: string;\n let mime = typeof mimeType === 'string' ? mimeType : DEFAULT_IMAGE_MIME;\n if (typeof input === 'string')\n data = input.replace(/^data:([^;]+);base64,/u, (_match, type: string) => ((mime = type), ''));\n else if (ArrayBuffer.isView(input))\n data = bytesToBase64(new Uint8Array(input.buffer, input.byteOffset, input.byteLength));\n else if (typeof input === 'object' && input !== null && 'data' in input && typeof input.data === 'string') {\n data = input.data;\n if ('mimeType' in input && typeof input.mimeType === 'string') mime = input.mimeType;\n } else throw new TypeError('image() takes base64 text, bytes, or { data, mimeType }.');\n if (images.length >= MAX_IMAGES) throw new RangeError(`An exec run returns at most ${MAX_IMAGES} images.`);\n imageBytes += Math.ceil((data.length * 3) / 4);\n if (imageBytes > MAX_IMAGE_BYTES) throw new RangeError('Images from one exec run exceed 5 MB.');\n images.push({ data, mimeType: mime });\n };\n const console = { log: log('log'), info: log('info'), warn: log('warn'), error: log('error'), debug: log('debug') };\n return { console, note, addImage, lines, images };\n}\n\n/** The session's active domains; every registered domain when the host reports none. */\nfunction activeDomains(execution: PoHeadlessExecutionContext | undefined): readonly string[] | undefined {\n return execution?.selection?.domains;\n}\n\nfunction toResult(\n result: PoIsolateResult,\n output: ReturnType<typeof createOutput>,\n saved: string | undefined,\n): PoHeadlessToolResult {\n const content: PoHeadlessContent[] = [];\n if (output.lines.length > 0) content.push({ type: 'text', text: truncate(output.lines.join('\\n'), MAX_LOG_CHARS) });\n if (result.ok) {\n if (ArrayBuffer.isView(result.value)) {\n content.push({ type: 'text', text: 'The script returned bytes. Pass them to image(data, mimeType) instead.' });\n } else if (result.value !== undefined) {\n content.push({ type: 'text', text: truncate(format(result.value), MAX_VALUE_CHARS) });\n }\n } else {\n const { kind, name, message } = result.error;\n const hint = kind === 'timeout' ? ' Raise timeoutMs or split the work into smaller exec calls.' : '';\n content.push({ type: 'text', text: `${name}: ${message}${hint}` });\n }\n if (content.length === 0) content.push({ type: 'text', text: '(no return value)' });\n if (saved !== undefined) content.push({ type: 'text', text: saved });\n for (const image of output.images) content.push({ type: 'image', data: image.data, mimeType: image.mimeType });\n return { content, ...(result.ok ? {} : { isError: true }) };\n}\n\nfunction sleep(ms: number, signal: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal.aborted) return reject(new Error('Run ended.'));\n const timer = setTimeout(resolve, Math.max(0, ms));\n signal.addEventListener(\n 'abort',\n () => {\n clearTimeout(timer);\n reject(new Error('Run ended.'));\n },\n { once: true },\n );\n });\n}\n\n/** `discover` and `exec` for one session, over the namespaces its packages contributed. */\nexport function createCodemodeTools({ registry, isolate, scripts }: CodemodeToolsOptions): CodemodeTools {\n let busy = false;\n\n const visible = (service: PoIsolateService): PoCodemodeNamespace[] =>\n registry.list().filter((namespace) => service.liveObjects || namespace.portable === true);\n\n // ponytail: the cockpit's generic tool item renders both for now; add a poWeb renderer for exec code and images when it earns one.\n // web-plugin-tool-renderers: ignore discover, plain text result\n const discover: CodemodeTools['discover'] = {\n name: 'discover',\n label: 'Discover',\n description:\n 'List the code-mode namespaces and reusable scripts you can use from `exec`, show one namespace in full, ' +\n 'or search members and scripts. ' +\n 'Not required before exec: its description already names the namespaces.',\n parameters: DiscoverToolSchema,\n promptSnippet: 'List code-mode namespaces and their TypeScript declarations',\n executionMode: 'parallel',\n async execute(_toolCallId, parameters: DiscoverToolParams, _signal, _onUpdate, execution) {\n const service = isolate();\n if (!service) return text('Code mode is not available on this host.', true);\n const namespaces = visible(service);\n // Imports need a host with live objects; the edge saves scripts but cannot chain them.\n const listed = scripts && service.liveObjects ? await scripts.list(activeDomains(execution)) : [];\n if (parameters.namespace !== undefined) {\n const found = namespaces.find((namespace) => namespace.name === parameters.namespace);\n if (!found) {\n const names = namespaces.map((namespace) => namespace.name).join(', ') || 'none';\n return text(`Unknown namespace \"${parameters.namespace}\". Registered: ${names}.`, true);\n }\n return text(truncate(found.declarations, MAX_DECLARATION_CHARS));\n }\n if (parameters.query !== undefined) {\n const needle = parameters.query.toLowerCase();\n const hits: string[] = [];\n for (const namespace of namespaces) {\n const lines = namespace.declarations.split('\\n');\n lines.forEach((line, index) => {\n if (!line.toLowerCase().includes(needle) || hits.length >= MAX_QUERY_LINES) return;\n const doc = lines[index - 1]?.trim().startsWith('/**') ? `${lines[index - 1]?.trim()} ` : '';\n hits.push(`${namespace.name}: ${doc}${line.trim()}`);\n });\n }\n for (const script of listed) {\n if (hits.length >= MAX_QUERY_LINES) break;\n if (`${script.specifier} ${script.description}`.toLowerCase().includes(needle)) {\n hits.push(`script ${script.specifier}: ${script.description}`);\n }\n }\n return text(hits.length > 0 ? hits.join('\\n') : `No members or scripts match \"${parameters.query}\".`);\n }\n const sections: string[] = [];\n if (namespaces.length === 0) sections.push('No namespaces are registered in this session.');\n for (const namespace of namespaces) {\n sections.push(`- ${namespace.name}: ${namespace.summary}\\n members: ${memberNames(namespace).join(', ')}`);\n }\n sections.push(GLOBALS_HELP);\n if (!service.liveObjects) sections.push('This host runs plain JavaScript with JSON-only functions.');\n if (listed.length > 0) {\n sections.push(`Scripts. ${SCRIPTS_HELP}`);\n for (const script of listed.slice(0, MAX_LISTED_SCRIPTS)) {\n sections.push(`- ${script.specifier}${script.description ? `: ${script.description}` : ''}`);\n }\n if (listed.length > MAX_LISTED_SCRIPTS) {\n sections.push(`...and ${listed.length - MAX_LISTED_SCRIPTS} more; use discover({ query }) to search.`);\n }\n }\n if (namespaces.length > 0) sections.push('Call discover({ namespace }) for full types.');\n return text(sections.join('\\n'));\n },\n };\n\n // web-plugin-tool-renderers: ignore exec, generic item until a code and image renderer exists\n const exec: CodemodeTools['exec'] = {\n name: 'exec',\n label: 'Exec',\n get description(): string {\n const service = isolate();\n const namespaces = service ? visible(service) : [];\n const listed = namespaces.map((namespace) => `- ${namespace.name}: ${namespace.summary}`).join('\\n');\n return [\n 'Run a TypeScript script inside the Po server with live objects from the namespaces below in scope.',\n 'It runs with full server trust, like bash. Keep each call to one logical step.',\n listed || '(no namespaces registered yet; call discover to check)',\n GLOBALS_HELP,\n ...(scripts && service?.liveObjects ? [`${SCRIPTS_HELP} discover lists saved and domain scripts.`] : []),\n 'Use discover({ namespace }) for full signatures when needed.',\n ].join('\\n');\n },\n parameters: ExecToolSchema,\n promptSnippet: 'Run a TypeScript script against live Po objects (browser and other namespaces)',\n executionMode: 'serial',\n async execute(_toolCallId, parameters: ExecToolParams, signal, _onUpdate, execution) {\n const service = isolate();\n if (!service) return text('Code mode is not available on this host.', true);\n if (busy) return text('Another exec run is still active in this session. Wait for it to finish.', true);\n busy = true;\n const controller = new AbortController();\n const runSignal = signal ? AbortSignal.any([signal, controller.signal]) : controller.signal;\n const cleanups: (() => void | Promise<void>)[] = [];\n const output = createOutput();\n const run: PoCodemodeRun = {\n sessionId: execution.sessionId,\n signal: runSignal,\n onDispose: (cleanup) => void cleanups.push(cleanup),\n };\n try {\n let saved: string | undefined;\n try {\n const file = await scripts?.save(parameters.code);\n if (file) saved = `Saved as ${file.specifier} (${file.path})`;\n } catch (error) {\n output.note(`Could not save the script: ${error instanceof Error ? error.message : String(error)}`);\n }\n const globals: Record<string, unknown> = {\n console: output.console,\n image: output.addImage,\n sleep: (ms: number) => sleep(ms, runSignal),\n };\n const deny = new Set<string>();\n for (const namespace of visible(service)) {\n globals[namespace.name] = namespace.bind(run);\n for (const member of namespace.deny ?? []) deny.add(member);\n }\n const deadlineMs = Math.min(\n MAX_TIMEOUT_MS,\n Math.max(MIN_TIMEOUT_MS, parameters.timeoutMs ?? DEFAULT_TIMEOUT_MS),\n );\n const result = await service.run({\n source: parameters.code,\n globals,\n deadlineMs,\n signal: runSignal,\n deny: [...deny],\n onDiagnostic: output.note,\n ...(scripts ? { resolveImport: (specifier) => scripts.resolve(specifier, activeDomains(execution)) } : {}),\n });\n return toResult(result, output, saved);\n } catch (error) {\n return text(\n `Code mode could not run the script: ${error instanceof Error ? error.message : String(error)}`,\n true,\n );\n } finally {\n controller.abort();\n for (const cleanup of cleanups.reverse()) {\n await Promise.resolve()\n .then(cleanup)\n .catch((error: unknown) => output.note(`cleanup failed: ${String(error)}`));\n }\n busy = false;\n }\n },\n };\n\n return { discover, exec };\n}\n"],"mappings":"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"}