@ycodium-ai/plugin-api 0.2.3976 → 0.2.3990

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
@@ -61,7 +61,7 @@ import { definePlugin } from "@ycodium-ai/plugin-api";
61
61
 
62
62
  export default definePlugin({
63
63
  id: "my-plugin",
64
- apiVersion: 75,
64
+ apiVersion: 77,
65
65
  activate: (ctx) => {
66
66
  ctx.log.info("hello");
67
67
 
@@ -288,6 +288,40 @@ borrower must not kill another borrower's server. Instance disposal must stop ne
288
288
  idle timers; an externally configured server is never owned by this operation. Long-lived conversation
289
289
  sessions continue using the streaming process interface.
290
290
 
291
+ ## Executor session channel tests
292
+
293
+ Each `startSession(input)` receives its own `input.events.emit(event)` channel. Keep that
294
+ channel in the session context; the host assigns event generations. When reusing a process,
295
+ return its original `bindingGeneration` and keep emitting through its original channel.
296
+
297
+ The `@ycodium-ai/plugin-api/testing` subpath has no runtime dependencies or test framework.
298
+ Wrap your executor with `withTestChannels(instance)`, use its session methods, then call
299
+ `assertGenerationSettled(instance.recorded, generation)`. Assertion failures throw `Error`.
300
+ `recorded.accepted` contains host-stamped events; `recorded.afterClose` records attempted
301
+ delivery to a closed channel. Successful stops close channels, replacements close the old
302
+ channel, and failed starts close their candidate and the previous channel unless a stop already owns it.
303
+ Successful disposal closes all channels.
304
+
305
+ A generation must emit exactly one `session.exited`, with every `task.*` before it. A clean
306
+ stop, replacement, or successful disposal must settle each open task with a terminal status or `idle`.
307
+ Generations that already exited before the operation are checked as crashes. When a task may outlive
308
+ the process, emit `idle` with `outcomeUnknown: true`: observation for this generation ends,
309
+ while the external task's result remains unknown. Events emitted after channel closure fail
310
+ the check. Crashes must still report an exit; unconfirmed task outcomes need not be invented.
311
+
312
+ ```ts
313
+ import { withTestChannels, assertGenerationSettled } from "@ycodium-ai/plugin-api/testing";
314
+
315
+ const executor = withTestChannels(await createInstance(config, host));
316
+ try {
317
+ const session = await executor.startSession({ threadId: "test", runtimeMode: "full-access" });
318
+ await executor.stopSession("test");
319
+ assertGenerationSettled(executor.recorded, session.bindingGeneration ?? 1);
320
+ } finally {
321
+ await executor.dispose();
322
+ }
323
+ ```
324
+
291
325
  ## THERE WILL BE COMPATIBILITY-BREAKING CHANGES
292
326
 
293
327
  The definition's `apiVersion` is checked against a closed window: the host loads every version from
@@ -304,7 +338,11 @@ update against the new types and republish.
304
338
 
305
339
  <!-- plugin-api-versions:start (generated by scripts/gen-plugin-api-version.ts from packages/plugin-api/version-history.json; edit that file) -->
306
340
 
307
- The current API is **75**. This Ycodium loads plugins declaring 73 through 75.
341
+ The current API is **77**. This Ycodium loads plugins declaring 76 through 77.
342
+
343
+ API 77 adds ctx.threads.tasks.list to read persisted task activations with filtering and cursor pagination. Summary and last tool name are bounded display text with truncation flags; stored task text is unchanged.
344
+
345
+ API 76 replaces ExecutorInstance.events with a required events channel on each startSession input. Provider plugins must retain input.events for that session and emit every event there, remove originBindingGeneration from events, and return the original bindingGeneration when reusing a process. The testing subpath provides withTestChannels and assertGenerationSettled.
308
346
 
309
347
  API 75 adds the optional executor card field `keepsBackgroundServices`, the default for the instance switch that keeps an instance's background program after a session ends (off when absent), and the optional `keepBackgroundServices` on `PluginProviderInstance` and `providers.instances.list` entries, the switch's effective value.
310
348
 
@@ -3448,6 +3448,39 @@ export type ThreadsAgentsGetOutput = {
3448
3448
  readonly "errorWindow"?: Objects_56;
3449
3449
  };
3450
3450
  };
3451
+ export type ThreadsTasksListInput = {
3452
+ readonly "threadId": string;
3453
+ readonly "kind"?: "agent" | "background" | "inert";
3454
+ readonly "active"?: boolean;
3455
+ readonly "limit"?: number;
3456
+ readonly "after"?: string;
3457
+ };
3458
+ export type ThreadsTasksListOutput = {
3459
+ readonly "tasks": ReadonlyArray<{
3460
+ readonly "taskKey": string;
3461
+ readonly "activationKey": string;
3462
+ readonly "provider": string;
3463
+ readonly "taskId": string;
3464
+ readonly "activationSequence": number;
3465
+ readonly "bindingGeneration": number | null;
3466
+ readonly "kind": "agent" | "background" | "inert";
3467
+ readonly "taskType"?: string;
3468
+ readonly "ownerAgentId"?: string;
3469
+ readonly "timelineBypass"?: boolean;
3470
+ readonly "status": "pending" | "running" | "waiting" | "idle" | "completed" | "failed" | "cancelled" | "interrupted";
3471
+ readonly "statusInferred": boolean;
3472
+ readonly "title": string;
3473
+ readonly "originTurnId": string | null;
3474
+ readonly "startedAt": string;
3475
+ readonly "endedAt": string | null;
3476
+ readonly "updatedAt": string;
3477
+ readonly "lastToolName"?: string;
3478
+ readonly "lastToolNameTruncated"?: boolean;
3479
+ readonly "summary"?: string;
3480
+ readonly "summaryTruncated"?: boolean;
3481
+ }>;
3482
+ readonly "nextCursor": string | null;
3483
+ };
3451
3484
  export type ThreadsTurnChangesGetInput = {
3452
3485
  readonly "threadId": string;
3453
3486
  readonly "turnId": string;
@@ -8517,6 +8550,9 @@ export interface PluginDataPorts {
8517
8550
  readonly list: (input: ThreadsAgentsListInput) => Promise<ThreadsAgentsListOutput>;
8518
8551
  readonly get: (input: ThreadsAgentsGetInput) => Promise<ThreadsAgentsGetOutput>;
8519
8552
  };
8553
+ readonly tasks: {
8554
+ readonly list: (input: ThreadsTasksListInput) => Promise<ThreadsTasksListOutput>;
8555
+ };
8520
8556
  readonly getTurnChanges?: (input: ThreadsTurnChangesGetInput) => Promise<ThreadsTurnChangesGetOutput>;
8521
8557
  readonly toolCall: {
8522
8558
  readonly get: (input: ThreadsToolCallGetInput) => Promise<ThreadsToolCallGetOutput>;
@@ -9035,6 +9071,10 @@ export interface PluginUiDataReads {
9035
9071
  readonly input: ThreadsAgentsGetInput;
9036
9072
  readonly output: ThreadsAgentsGetOutput;
9037
9073
  };
9074
+ readonly "threads.tasks.list": {
9075
+ readonly input: ThreadsTasksListInput;
9076
+ readonly output: ThreadsTasksListOutput;
9077
+ };
9038
9078
  readonly "threads.turn.changes.get": {
9039
9079
  readonly input: ThreadsTurnChangesGetInput;
9040
9080
  readonly output: ThreadsTurnChangesGetOutput;