pinokiod 7.0.4 → 7.0.5

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pinokiod",
3
- "version": "7.0.4",
3
+ "version": "7.0.5",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -52,6 +52,7 @@ Follow these sections in order:
52
52
  2. Only use Registry Fallback if Search App found no suitable installed app and the user approved it.
53
53
  3. Then use Run App.
54
54
  4. Then use API Call Strategy if the app exposes an automatable API.
55
+ 5. Only use Parallel Mode when the user explicitly asks to use multiple apps or multiple machines in parallel.
55
56
 
56
57
  ### 1. Search App
57
58
 
@@ -173,6 +174,27 @@ Follow these sections in order:
173
174
  - Do not execute the app's internal Python/Node/bundled CLI as a fallback when `pterm` has already selected a launcher-managed app.
174
175
  - If no automatable API exists after the app is running, report that clearly instead of bypassing the launcher with an internal CLI.
175
176
 
177
+ ### 5. Parallel Mode (explicit only)
178
+
179
+ - Use this section only when the user explicitly asks to:
180
+ - run on multiple machines
181
+ - use multiple apps in parallel
182
+ - compare multiple relevant apps side by side
183
+ - generate multiple outputs concurrently
184
+ - Do not use this mode by default.
185
+ - Keep each selected app as a separate target, including remote results like `<app_id>@<source.host>`.
186
+ - Selection rules:
187
+ - if the user asks for all relevant apps, use all relevant search results that can perform the task
188
+ - if the user asks for a specific count, use the top N relevant search results after normal search ranking
189
+ - if the user asks for parallel use but does not specify how many apps or machines to use, ask once
190
+ - Ranking still applies in this mode:
191
+ - prefer `ready` apps first
192
+ - then `running` apps
193
+ - then offline apps if more targets are still needed
194
+ - Run and monitor each selected target independently.
195
+ - Keep outputs labeled by target `app_id`.
196
+ - For remote path-based tasks, run `pterm upload <app_id> <file...>` separately for each remote target and use that target's returned remote `path` values.
197
+
176
198
  ## Behavior Rules
177
199
 
178
200
  - Do not add app-specific hardcoding when user gave only capability (for example "tts").
@@ -577,7 +577,45 @@ module.exports = function registerAppRoutes(app, { registry, preferences, appSea
577
577
  }))
578
578
 
579
579
  router.get('/apps/logs/:app_id', asyncHandler(async (req, res) => {
580
- const appId = registry.normalizeAppId(req.params.app_id)
580
+ const parsedAppId = parseQualifiedAppId(req.params.app_id)
581
+ const requestedAppId = parsedAppId.app_id || req.params.app_id
582
+ const remoteHost = parsedAppId.qualified ? parsedAppId.host : null
583
+ if (remoteHost && remoteHost !== currentPeerHost()) {
584
+ try {
585
+ const params = {}
586
+ if (typeof req.query.script === 'string' && req.query.script.trim()) {
587
+ params.script = req.query.script
588
+ }
589
+ const tail = registry.parseTailCount(req.query.tail, 200)
590
+ if (Number.isFinite(tail) && tail > 0) {
591
+ params.tail = String(tail)
592
+ }
593
+ const response = await axios.get(`http://${remoteHost}:${peerPort()}/apps/logs/${encodeURIComponent(requestedAppId)}`, {
594
+ timeout: DEFAULT_PEER_TIMEOUT_MS,
595
+ headers: peerRequestHeaders(req),
596
+ params
597
+ })
598
+ const payload = response && response.data && typeof response.data === 'object'
599
+ ? { ...response.data }
600
+ : {}
601
+ payload.app_id = qualifyAppId(requestedAppId, remoteHost)
602
+ payload.source = buildSource(remoteHost, false)
603
+ res.json(payload)
604
+ return
605
+ } catch (error) {
606
+ if (error && error.response) {
607
+ res.status(error.response.status).json(error.response.data)
608
+ return
609
+ }
610
+ res.status(502).json({
611
+ error: 'Peer logs unavailable',
612
+ app_id: qualifyAppId(requestedAppId, remoteHost),
613
+ source: buildSource(remoteHost, false)
614
+ })
615
+ return
616
+ }
617
+ }
618
+ const appId = registry.normalizeAppId(requestedAppId)
581
619
  if (!appId) {
582
620
  res.status(400).json({ error: 'Invalid app_id' })
583
621
  return