@omercnet/paseo-omp 5.1.0 → 5.1.1-next.335.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -54,7 +54,7 @@ Profile selection is request-local: concurrent clients cannot change each other'
54
54
 
55
55
  ## Paseo provider SDK coverage
56
56
 
57
- The capability inventory is pinned to `@getpaseo/plugin` 0.14.0-beta.1, with nightly compatibility checks
57
+ The capability inventory is pinned to `@getpaseo/plugin` 0.14.0, with nightly compatibility checks
58
58
  against the latest and beta channels. Provider capability scoring covers
59
59
  all 18 entries in the SDK's `PROVIDER_CAPABILITIES`; the separate provider/client SDK table below
60
60
  also tracks the registration, screen, and sidebar APIs introduced in 0.11. This measures strict SDK surface
@@ -126,7 +126,7 @@ Existing agents whose provider is `omp` remain owned by the bundled provider. Ne
126
126
 
127
127
  OMP `18.1.15` is the oldest version tested end to end. The direct provider's hard compatibility gate is `rpc-ui` protocol v2: metadata-free legacy ready frames and v1-only runtimes are rejected before a provider session opens because they cannot support the advertised persistence and conversation-rewind capabilities. Typed tool approvals remain capability-gated and fall back as described above. For terminal completion, a matching `agent_end.requestId` is authoritative and mismatches are ignored before state changes. Released OMP 18.2.x builds that omit that field use an ordered fallback requiring a fresh correlated native user entry followed by current-turn assistant activity, an idle non-compacting runtime, and no conflicting permission, tool, steer, or child-session work. Ambiguous events while OMP is active are ignored; unresolved ambiguity after confirmed idle fails only the Paseo turn. This trades a bounded residual same-agent stale-event risk for compatibility with released OMP instead of terminating and lazily restarting the runtime after every later prompt. Paseo clients, including mobile clients inside reconnect grace, do not own or terminate the daemon-managed OMP session.
128
128
 
129
- Paseo 0.14 is the minimum supported release. The controlled Docker canary is pinned to official 0.14.0-beta.1; nightly SDK checks cover the latest and beta channels. The canary preserves nested provider-subagent ancestry and spawning-tool links, and validates npm-managed plugin sources, platform-owned external URL opening, and whole-item timeline transforms before Overview grouping.
129
+ Paseo 0.14 is the minimum supported release. The controlled Docker canary is pinned to official 0.14.0; nightly SDK checks cover the latest and beta channels. The canary preserves nested provider-subagent ancestry and spawning-tool links, and validates npm-managed plugin sources, platform-owned external URL opening, and whole-item timeline transforms before Overview grouping.
130
130
 
131
131
  Paseo releases idle resumable agent runtimes after one hour; the agent stays listed as `closed` and the next prompt resumes the same OMP session. The plugin vetoes that release while the session has a running turn, a pending permission, an active subagent, or OMP background async work, and while OMP does not report a settled state (the plugin needs the `hasPendingAsyncWork` and `isSettled` fields in OMP's `get_state`; builds without them are never released). Set `agents.idleRuntimeCleanup: false` in the Paseo config to disable idle release for every provider.
132
132
 
@@ -1,22 +1,22 @@
1
1
  {
2
2
  "name": "@omercnet/paseo-omp",
3
- "version": "5.1.0",
3
+ "version": "5.1.1",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@omercnet/paseo-omp",
9
- "version": "5.1.0",
9
+ "version": "5.1.1",
10
10
  "dependencies": {
11
- "@getpaseo/protocol": "0.14.0-beta.1",
11
+ "@getpaseo/protocol": "0.14.0",
12
12
  "@modelcontextprotocol/sdk": "1.30.0",
13
13
  "yaml": "^2.9.0"
14
14
  }
15
15
  },
16
16
  "node_modules/@getpaseo/protocol": {
17
- "version": "0.14.0-beta.1",
18
- "resolved": "https://registry.npmjs.org/@getpaseo/protocol/-/protocol-0.14.0-beta.1.tgz",
19
- "integrity": "sha512-qkZCmLlL5EQ1PkN0Jy8JLIfyqoj34UC2HdJIicERQ/OdrYGQ3krpOfIpYJ3c3BU27GcDL/E4aoA0GbuEVR4qUw==",
17
+ "version": "0.14.0",
18
+ "resolved": "https://registry.npmjs.org/@getpaseo/protocol/-/protocol-0.14.0.tgz",
19
+ "integrity": "sha512-fF0na1u91sKKgk6R0EKtXQMTJKbqLx8jZ8IuiUcm3jLVOnGruAvPggAQVAzm4MX2mrikesj3immqztHjPNxjTQ==",
20
20
  "dependencies": {
21
21
  "semver": "^7.8.5",
22
22
  "zod": "^4.4.3"
@@ -313,12 +313,16 @@
313
313
  "license": "MIT"
314
314
  },
315
315
  "node_modules/encodeurl": {
316
- "version": "2.0.0",
317
- "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
318
- "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
316
+ "version": "2.0.1",
317
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.1.tgz",
318
+ "integrity": "sha512-Ev/hIyePLZtpL98x562lvPtenrUfGr0lfaf44HFZ+hDEwso7ccV9QAZrEVLg0hxNAzygaAFxy2dYaAKKM0G06A==",
319
319
  "license": "MIT",
320
320
  "engines": {
321
321
  "node": ">= 0.8"
322
+ },
323
+ "funding": {
324
+ "type": "opencollective",
325
+ "url": "https://opencollective.com/express"
322
326
  }
323
327
  },
324
328
  "node_modules/es-define-property": {
@@ -687,9 +691,9 @@
687
691
  "license": "ISC"
688
692
  },
689
693
  "node_modules/jose": {
690
- "version": "6.2.13",
691
- "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.13.tgz",
692
- "integrity": "sha512-7TIg10ZE1x82YediN+lcrPNvGMKge9yFHQD+Qho/b8y2adfugU3AsvvHfxV0fzyFllT6l9xCjf4RWY9g/Z9PJQ==",
694
+ "version": "6.2.14",
695
+ "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.14.tgz",
696
+ "integrity": "sha512-3JasLuki1NRLQvY4wCoC37KZk4qxoBx2k2aFqLxT84IezqW0bkJKnNtxnZj/Fu1xsQivoc/lytxaRHJoGLjJ1A==",
693
697
  "license": "MIT",
694
698
  "funding": {
695
699
  "url": "https://github.com/sponsors/panva"
@@ -902,9 +906,9 @@
902
906
  }
903
907
  },
904
908
  "node_modules/qs": {
905
- "version": "6.17.0",
906
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.17.0.tgz",
907
- "integrity": "sha512-5LK5BZ2XDHMvcUJaf0CQ5HL3aVgKbpklvByC7qLSxYkfE8COEEbJg5xCHWCTqzqi0Gs4Jn5Mv5v3R38W6edscA==",
909
+ "version": "6.17.1",
910
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.17.1.tgz",
911
+ "integrity": "sha512-jd3COkaKVgGUW+ZHyEHCG9bH7RoaaiWuMgzsIBjUMVjLAaWGWpoUAVwljVvBHxRu/2qEHnadLGZrkutYUBPQJA==",
908
912
  "license": "BSD-3-Clause",
909
913
  "dependencies": {
910
914
  "es-define-property": "^1.0.1",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@omercnet/paseo-omp",
3
- "version": "5.1.0",
3
+ "version": "5.1.1-next.335.1",
4
4
  "type": "module",
5
5
  "description": "Paseo integration for OMP, including its direct provider and workspace tooling.",
6
6
  "license": "MIT",
@@ -54,16 +54,16 @@
54
54
  "typecheck": "tsc --noEmit -p tsconfig.client.json && tsc --noEmit -p tsconfig.server.json && tsc --noEmit -p tsconfig.tests.json"
55
55
  },
56
56
  "dependencies": {
57
- "@getpaseo/protocol": "0.14.0-beta.1",
57
+ "@getpaseo/protocol": "0.14.0",
58
58
  "@modelcontextprotocol/sdk": "1.30.0",
59
59
  "yaml": "^2.9.0"
60
60
  },
61
61
  "devDependencies": {
62
62
  "@biomejs/biome": "^2.5.10",
63
- "@getpaseo/cli": "0.14.0-beta.1",
64
- "@getpaseo/client": "0.14.0-beta.1",
65
- "@getpaseo/plugin": "0.14.0-beta.1",
66
- "@getpaseo/server": "0.14.0-beta.1",
63
+ "@getpaseo/cli": "0.14.0",
64
+ "@getpaseo/client": "0.14.0",
65
+ "@getpaseo/plugin": "0.14.0",
66
+ "@getpaseo/server": "0.14.0",
67
67
  "@oh-my-pi/pi-agent-core": "18.12.6",
68
68
  "@oh-my-pi/pi-coding-agent": "18.12.6",
69
69
  "@tanstack/react-query": "^5.102.3",
@@ -71,9 +71,9 @@
71
71
  "@types/react": "^19.2.18",
72
72
  "@vitest/coverage-v8": "^5.0.0",
73
73
  "esbuild": "0.28.2",
74
+ "pino": "10.3.1",
74
75
  "react": "19.1.0",
75
76
  "react-native": "0.81.5",
76
- "pino": "10.3.1",
77
77
  "tsx": "^4.20.6",
78
78
  "typescript": "^7.0.2",
79
79
  "vitest": "^5.0.0",
@@ -1,2 +1,2 @@
1
1
  /** Release Please keeps this bundle-safe constant aligned with package.json. */
2
- export const PASEO_OMP_PACKAGE_VERSION = "5.1.0"; // x-release-please-version
2
+ export const PASEO_OMP_PACKAGE_VERSION = "5.1.1-next.335.1"; // x-release-please-version
@@ -1003,7 +1003,12 @@ export class OmpRpcProcess {
1003
1003
  4_096,
1004
1004
  ) !== Number.POSITIVE_INFINITY;
1005
1005
  if (onlyUnsafePayload && payloadIsSafe) return false;
1006
- if (envelope.data.isTerminal === false) {
1006
+ // Nonterminal messages are never read, so an over-budget list is dropped like a terminal one.
1007
+ if (
1008
+ envelope.data.isTerminal === false &&
1009
+ frame.messages !== undefined &&
1010
+ !Array.isArray(frame.messages)
1011
+ ) {
1007
1012
  this.fail(new Error("OMP emitted an invalid nonterminal agent_end payload"));
1008
1013
  return true;
1009
1014
  }
@@ -1351,6 +1356,7 @@ export class OmpRpcProcess {
1351
1356
  }
1352
1357
  }
1353
1358
 
1359
+ // The session shows this message to the user. Pass only plugin-authored text, never OMP output.
1354
1360
  private fail(error: Error): void {
1355
1361
  if (this.fatalError || this.closed) return;
1356
1362
  this.fatalError = error;
@@ -2359,7 +2359,7 @@ export class OmpProviderSession implements OmpOpenedSession {
2359
2359
  return;
2360
2360
  }
2361
2361
  if (event.type === "process_exit") {
2362
- this.handleRuntimeFailure();
2362
+ this.handleRuntimeFailure(`OMP runtime failed: ${event.error}`);
2363
2363
  return;
2364
2364
  }
2365
2365
  if (event.type === "retry_fallback_applied" || event.type === "retry_fallback_succeeded") {
@@ -372,8 +372,8 @@ export class OmpTimelineProjector {
372
372
  private flushTimer: unknown;
373
373
  private currentTurnId: string | null = null;
374
374
  private assistantSequence = 0;
375
+ // Least recently used first, so a long turn evicts its oldest identities.
375
376
  private readonly turnNativeMessageIds = new Map<string, string>();
376
- private nativeIdentitySaturated = false;
377
377
  private assistantIdentitySequence = 0;
378
378
  private noticeSequence = 0;
379
379
  private toolSequence = 0;
@@ -901,7 +901,6 @@ export class OmpTimelineProjector {
901
901
  this.currentTurnId = null;
902
902
  this.assistantSequence = 0;
903
903
  this.turnNativeMessageIds.clear();
904
- this.nativeIdentitySaturated = false;
905
904
  this.assistantIdentitySequence = 0;
906
905
  this.toolSequence = 0;
907
906
  this.userSequence = 0;
@@ -1174,7 +1173,6 @@ export class OmpTimelineProjector {
1174
1173
  this.currentTurnId = null;
1175
1174
  this.assistantSequence = 0;
1176
1175
  this.turnNativeMessageIds.clear();
1177
- this.nativeIdentitySaturated = false;
1178
1176
  }
1179
1177
 
1180
1178
  close(): void {
@@ -1242,13 +1240,12 @@ export class OmpTimelineProjector {
1242
1240
  this.commandPublishedText = "";
1243
1241
  }
1244
1242
 
1245
- private beginStream(message: OmpAssistantMessage, turnId: string): StreamSnapshot | null {
1243
+ private beginStream(message: OmpAssistantMessage, turnId: string): StreamSnapshot {
1246
1244
  this.assistantSequence += 1;
1247
1245
  const nativeIdentity = assistantIdentity(message);
1248
1246
  const messageId = nativeIdentity
1249
1247
  ? this.messageIdForNativeIdentity(nativeIdentity)
1250
1248
  : this.nextAssistantMessageId(`turn:${turnId}:${this.assistantSequence}`);
1251
- if (!messageId) return null;
1252
1249
  this.stream = {
1253
1250
  messageId,
1254
1251
  ...(nativeIdentity ? { nativeIdentity } : {}),
@@ -1261,15 +1258,16 @@ export class OmpTimelineProjector {
1261
1258
  };
1262
1259
  return this.stream;
1263
1260
  }
1264
- private messageIdForNativeIdentity(nativeIdentity: string): string | undefined {
1261
+ private messageIdForNativeIdentity(nativeIdentity: string): string {
1265
1262
  const existing = this.turnNativeMessageIds.get(nativeIdentity);
1266
- if (existing) return existing;
1267
- if (
1268
- this.nativeIdentitySaturated ||
1269
- this.turnNativeMessageIds.size >= MAX_TURN_NATIVE_IDENTITIES
1270
- ) {
1271
- this.nativeIdentitySaturated = true;
1272
- return undefined;
1263
+ if (existing) {
1264
+ this.turnNativeMessageIds.delete(nativeIdentity);
1265
+ this.turnNativeMessageIds.set(nativeIdentity, existing);
1266
+ return existing;
1267
+ }
1268
+ if (this.turnNativeMessageIds.size >= MAX_TURN_NATIVE_IDENTITIES) {
1269
+ const oldest = this.turnNativeMessageIds.keys().next().value;
1270
+ if (oldest !== undefined) this.turnNativeMessageIds.delete(oldest);
1273
1271
  }
1274
1272
  const messageId = this.nextAssistantMessageId(nativeIdentity);
1275
1273
  this.turnNativeMessageIds.set(nativeIdentity, messageId);
@@ -1290,12 +1288,7 @@ export class OmpTimelineProjector {
1290
1288
  const nativeIdentity = assistantIdentity(message);
1291
1289
  if (this.stream && nativeIdentity && this.stream.nativeIdentity !== nativeIdentity) {
1292
1290
  if (!this.stream.nativeIdentity && !this.stream.published) {
1293
- const messageId = this.messageIdForNativeIdentity(nativeIdentity);
1294
- if (!messageId) {
1295
- this.stream = null;
1296
- return;
1297
- }
1298
- this.stream.messageId = messageId;
1291
+ this.stream.messageId = this.messageIdForNativeIdentity(nativeIdentity);
1299
1292
  this.stream.nativeIdentity = nativeIdentity;
1300
1293
  } else {
1301
1294
  this.flush();
@@ -1303,7 +1296,6 @@ export class OmpTimelineProjector {
1303
1296
  }
1304
1297
  }
1305
1298
  const stream = this.stream ?? this.beginStream(message, turnId);
1306
- if (!stream) return;
1307
1299
  if (update?.contentIndex !== undefined) {
1308
1300
  this.updateBlock(stream, message, update.contentIndex, update);
1309
1301
  return;