@xpert-ai/plugin-sdk 3.19.0 → 3.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/CHANGELOG.md +124 -0
  2. package/README.md +55 -0
  3. package/RESOURCE-CARDS-VALIDATION.md +51 -0
  4. package/RESOURCE-CARDS.md +361 -0
  5. package/TOOL-IMAGES.md +85 -0
  6. package/agent-results.cjs.default.js +1 -0
  7. package/agent-results.cjs.js +20 -0
  8. package/agent-results.cjs.mjs +2 -0
  9. package/agent-results.d.ts +1 -0
  10. package/agent-results.esm.js +4 -0
  11. package/index.cjs.js +494 -115
  12. package/index.esm.js +444 -114
  13. package/model-provider.cjs.js +45 -68
  14. package/model-provider.esm.js +46 -64
  15. package/package.json +8 -2
  16. package/results.cjs.js +50 -0
  17. package/results.esm.js +46 -0
  18. package/src/agent-results.d.ts +2 -0
  19. package/src/index.d.ts +3 -0
  20. package/src/lib/agent/handoff/agent-chat.contract.d.ts +10 -1
  21. package/src/lib/agent/handoff/agent-runtime-message.contract.d.ts +319 -0
  22. package/src/lib/agent/handoff/index.d.ts +1 -0
  23. package/src/lib/agent/index.d.ts +1 -0
  24. package/src/lib/agent/middleware/index.d.ts +1 -0
  25. package/src/lib/agent/middleware/model-requirements.d.ts +9 -0
  26. package/src/lib/agent/middleware/strategy.interface.d.ts +4 -0
  27. package/src/lib/agent/middleware/types.d.ts +7 -0
  28. package/src/lib/agent/resource-card.d.ts +3 -0
  29. package/src/lib/agent/runtime/activity.d.ts +6 -0
  30. package/src/lib/agent/runtime/capability.d.ts +13 -5
  31. package/src/lib/agent/runtime/cli-model-profile.d.ts +62 -0
  32. package/src/lib/agent/runtime/dispatch.d.ts +517 -0
  33. package/src/lib/agent/runtime/execution-runner.d.ts +66 -0
  34. package/src/lib/agent/runtime/index.d.ts +7 -0
  35. package/src/lib/agent/runtime/model-execution.d.ts +15 -0
  36. package/src/lib/agent/runtime/results.d.ts +335 -0
  37. package/src/lib/agent/runtime/strategy.d.ts +3 -0
  38. package/src/lib/agent/runtime/task-wait.d.ts +35 -0
  39. package/src/lib/agent/runtime/types.d.ts +35 -11
  40. package/src/lib/agent-plugin/import-default-agent-plugins.command.d.ts +6 -0
  41. package/src/lib/ai-model/ai-model-provider.interface.d.ts +2 -0
  42. package/src/lib/ai-model/ai-model.d.ts +2 -0
  43. package/src/lib/ai-model/index.d.ts +3 -0
  44. package/src/lib/ai-model/llm.d.ts +4 -2
  45. package/src/lib/ai-model/native-model.d.ts +22 -0
  46. package/src/lib/ai-model/realtime.d.ts +36 -0
  47. package/src/lib/ai-model/token-usage.d.ts +13 -0
  48. package/src/lib/core/context/request-context.d.ts +1 -0
  49. package/src/lib/mcp/app.d.ts +4 -1
  50. package/src/lib/project-task/index.d.ts +8 -1
  51. package/src/lib/project-type/index.d.ts +8 -1
  52. package/src/lib/rag/capability/index.d.ts +5 -0
  53. package/src/lib/{runtime/capabilities → rag/capability}/knowledge-document-visual-assets.d.ts +2 -2
  54. package/src/lib/rag/capability/knowledge-upload-sessions.d.ts +71 -0
  55. package/src/lib/{runtime/capabilities → rag/capability}/knowledgebase-documents.d.ts +9 -1
  56. package/src/lib/{runtime/capabilities → rag/capability}/knowledgebase.d.ts +4 -0
  57. package/src/lib/rag/index.d.ts +1 -0
  58. package/src/lib/resource-card-provider/index.d.ts +3 -0
  59. package/src/lib/resource-card-provider/provider.decorator.d.ts +4 -0
  60. package/src/lib/resource-card-provider/provider.registry.d.ts +14 -0
  61. package/src/lib/resource-card-provider/types.d.ts +36 -0
  62. package/src/lib/resource-card.d.ts +6 -0
  63. package/src/lib/runtime/capabilities/index.d.ts +1 -4
  64. package/src/lib/runtime/capabilities/project-provisioning.d.ts +10 -0
  65. package/src/lib/runtime/capabilities/tool-images.d.ts +24 -0
  66. package/src/lib/runtime/capabilities/workspace-files.d.ts +8 -2
  67. package/src/lib/sandbox/execution-environment.d.ts +2 -0
  68. package/src/lib/sandbox/execution.d.ts +10 -0
  69. package/src/lib/sandbox/managed-service.d.ts +1 -0
  70. /package/src/lib/{runtime/capabilities → rag/capability}/knowledge-graph.d.ts +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,129 @@
1
1
  # @xpert-ai/plugin-sdk
2
2
 
3
+ ## 3.21.0
4
+
5
+ ### Minor Changes
6
+
7
+ - c9f9379: Group Knowledge capabilities under `rag/capability` and expose resumable upload sessions through `Documents.uploads`. Support idempotent document imports without automatic processing, plus filename and folder-path search with MIME type filters so unprocessed images remain discoverable.
8
+
9
+ Allow organizations to read public tenant libraries while requiring super administrators to explicitly select tenant scope before managing them. Keep document processing behind write-access checks without switching the caller's request scope. Release the SDK and host implementation together for the new upload API.
10
+
11
+ ### Patch Changes
12
+
13
+ - f76a9c9: Let organization administrators import the official Agent plugins from one Git snapshot with a single button. Reuse existing package versions, isolate package failures, and display import results without granting workspace access. Expose the shared import command for system setup.
14
+ - 82b8db4: Preserve the ENOENT error code when scoped workspace file operations encounter missing files or an uninitialized root. Document the in-process runtime file contract so plugins can distinguish missing files from other failures without interpreting localized messages. Keep path boundaries and HTTP error responses unchanged.
15
+ - Updated dependencies [eecb9fa]
16
+ - Updated dependencies [f76a9c9]
17
+ - Updated dependencies [eecb9fa]
18
+ - Updated dependencies [c5e19d5]
19
+ - Updated dependencies [4b7a346]
20
+ - Updated dependencies [4fff330]
21
+ - @xpert-ai/contracts@3.21.0
22
+
23
+ ## 3.20.0
24
+
25
+ ### Minor Changes
26
+
27
+ - a01cd48: Add the realtime voice model capability, model protocol adapter contract, and Bosi voice sessions. Assistant creation and settings can select an independently authorized realtime model and voice. The host relays bounded PCM audio over an authenticated, single-use-ticket WebSocket and dispatches durable Assistant tasks independently of call lifetime. Create the voice tables and timing columns through the platform's existing TypeORM entity synchronization (the schema-sync job in externally managed deployments), and configure allowed renderer origins before enabling calls. No separate realtime voice SQL migration is required.
28
+
29
+ Introduce host-owned message envelopes with explicit source, target, correlation, and presentation for voice and future Assistant/Agent messages. Persist them in a dedicated typed `ChatMessage.messageEnvelope` JSONB column. Retain runtime execution, retry and branch history while applying consistent public-history filtering and protecting provenance from client edits. Apply the message-envelope migration before deployment.
30
+
31
+ - bf33018: Expose optional version-pinned CLI background transports and V2 execution receipts that separate business cwd from managed execution records. Preserve V1 receipts and support bounded runtime reads.
32
+ - f5add6a: Remove the ModelExecution per-request input cap and the byte/token comparison from
33
+ Chat, native and bridged CLI requests. Read and discard legacy maxInputTokens in
34
+ persisted policies and grants. Reserve estimated request tokens plus output against
35
+ cumulative budgets; settle using provider usage facts as before.
36
+
37
+ Expose the selected model's catalog context window to CLI profiles instead of deriving
38
+ it from tenant input limits. Custom CLI profiles must migrate from limits.maxInputTokens
39
+ to optional model.contextWindow. Upgrade the host and profiles together and start a new
40
+ execution to regenerate CLI configuration.
41
+
42
+ Remove the extra output cap and fixed Qwen/CodeBuddy turn caps. Use optional catalog
43
+ output metadata for CLI configuration, make execution token budgets explicit opt-ins,
44
+ and distinguish rate/concurrency errors from budget exhaustion. Honor active response
45
+ streams using an inactivity timer, and do not recover live grants as lost workers solely
46
+ because their calls are old. Republished Assistant versions no longer invalidate an
47
+ otherwise authorized execution.
48
+
49
+ - c941907: Define versioned Project Task execution specifications, implementation/review purposes, evidence references and distinct invocation receipts. Add host-validated Runtime message provenance, reply metadata, progress observations and shared event/consumption identities.
50
+
51
+ This is the contract stage only. Durable Project Task dispatch, outbox/inbox consumers and automatic result delivery are not enabled by these declarations. Deploy compatible contracts, SDK and host before producing the new Runtime envelopes.
52
+
53
+ Use the published `@xpert-ai/chatkit-types` 0.11.1 package and declare the contracts package's Zod peer dependency. Host UI package upgrades follow with the live conversation integration.
54
+
55
+ - 00b626e: Separate Project Task creation from execution and add authorized Runtime discovery, explicit idempotent task dispatch, specification snapshots and task details. Persist attempts and pinned dispatch intents before launching through the existing Invocation runtime; serialize Project execution admission and preserve native handoff behavior.
56
+
57
+ Support the built-in Project general agent as an explicit caller/reply identity. Computer invocations from this caller require a binding with an explicit `modelSource` referring to an accessible Assistant in the Project workspace; that Assistant supplies model policy, not caller identity or task ownership.
58
+
59
+ Apply `20261006-project-task-runtime.sql` before deploying the host. This stage supports durable dispatch identity and explicit retry/inspection, but does not enable autonomous recovery scanning, reliable result messages, automatic continuation or acceptance workflows.
60
+
61
+ Replace the legacy ProjectToolset and its creation command with the built-in `project-tasks` Middleware Plugin. Project general agents load it from the registry; Assistants can configure it through ordinary Plugin nodes and tool preferences. Preserve the six tool names while validating host-owned project/caller scope, localizing tool display metadata, and retaining Invocation status ownership.
62
+
63
+ - 00db21e: Add optional ResourceCardProvider registration and batched, read-only card resolution to the plugin SDK. Dispatch live conversation card updates through a single host handler with scoped provider lookup, resource identity validation and isolated deadlines. Migrate project task cards to this provider path while keeping unregistered types as saved snapshots. Keep initial project card construction and refreshed presentation together in ProjectTaskCardProvider.
64
+
65
+ ### Patch Changes
66
+
67
+ - 1df94f0: Add version-qualified background CLI profiles for Claude Code 2.1.63, CodeBuddy
68
+ 2.161.1 and Kimi Code 2.1.1. Support an optional literal argv prompt argument in
69
+ the SDK JSONL transport contract. Configure isolated settings and explicit
70
+ permission modes; Kimi advertises only allow because its prompt mode forces
71
+ automatic approval. Keep revisions unchanged for unrelated tools.
72
+
73
+ Execution still requires a matching host transport and Agent Runtime adapter.
74
+
75
+ - bf33018: Make managed background Coding CLI permissions configurable through the existing
76
+ tenant model execution policy, defaulting to allow with per-tool restricted
77
+ overrides. Pin the selected mode in runner receipts and keep evidence-only review
78
+ restrictions. Advertise supported modes in CLI profiles; leave interactive and
79
+ managed shell sessions unchanged.
80
+ - d4dba33: Add the Conversation Map data and action services with authorized Assistant-family pagination, visible message search, branch-aware summaries, and typed branch titles. Reuse existing conversation creation, rename, branch, and navigation services, and return the existing side chat on request retries even after its source starts another run.
81
+ - 01fd502: Add the on-demand Conversation Map Workbench View with shared shadcn controls, React Flow layouts, searchable conversation and branch navigation, and host-backed display preferences. Include compact directory rows, content-sized cards, accessible action tooltips, and reproducible source builds.
82
+
83
+ Use `agent.workbench` as the canonical Assistant Workbench slot. Normalize legacy `agent.workbench.fixed` and `agent.workbench.main` requests and plugin declarations at the host boundary, preserving authorization and opening preferences without duplicate views.
84
+
85
+ - deff039: Add persisted conversation Resource Cards, the public emitResourceCard helper and optional transactional Project creation receipts. Cards use typed Workbench navigation without changing file Artifacts. Scheduler creation now emits a receipt and offers an on-demand, authorized detail/edit/history View. ChatKit and Xpert SDK companion releases are required for the UI; publish public contracts/SDK before consuming plugins.
86
+
87
+ Opening an Assistant Project target with a View now opens a separately scoped host tab, retaining the current conversation, composer and ChatKit mount. The target Project is authorized independently, and its View scope survives refresh and browser history. Explicit Project selection without a View retains its existing workspace-switch behavior.
88
+
89
+ - b66bdcc: Add optional invocation activity capture and an independent Coding Execution View. Persist scoped, resumable public CLI activity and private bounded output archives; unify direct runtime cards and project execution navigation without coupling collection to task acceptance.
90
+ - b86bba1: Add execution-scoped model grants, protocol bridges, CLI launchers, budget enforcement, attributed usage settlement and audited reconciliation. Expose the native model SDK and scoped host runner capability, and accept CLI prompt-cache hints without forwarding provider credentials to execution environments.
91
+
92
+ Add typed Agent execution results, authorized file delivery and bounded task observation. Preserve background execution during logout, centralize conversation file access, retain explicit Assistant middleware configuration, and allow validated text-only receipts from image-capable tools. Include the API and Web releases required by these shared contracts and runtime changes.
93
+
94
+ - c0dd14c: Add provider-registered business task types with localized labels and controlled Lucide icon tokens. Persist taskType in the existing type column, preserve legacy values, and resolve presentation independently of hierarchy, status and assignee. Project Tasks list, tree, Gantt, board and detail views share one icon renderer. No database migration is required.
95
+ - 3142346: Support explicit file/archive delivery in project task delegation, pin selections in durable dispatch intents and reject changed selections on replay. Share the delivery schema through contracts while preserving SDK exports. Reject wildcard paths before delegation and retain evidence-only review confinement.
96
+ - 3185f56: Add explicit, revision-bound Project Task acceptance and rework decisions. Bind decisions to the current implementation, specification, and result or Artifact versions; keep retries idempotent and reject completion through generic task updates. Once independent review is requested, acceptance requires the latest valid passing review for that implementation.
97
+
98
+ Expose runtime progress, delivery and consumption, review reports, decision history, and authorized human controls in Tasks & Timeline. OS provides the shared review protocol and validation; the current review dispatch gate requires the Computer OpenCode executor supplied by Pro. This batch does not include Computer execution, live conversation streams, or message cards.
99
+
100
+ Apply `20261006-project-task-decisions.sql` after the task association and reliable reply migrations. Validation covers local tests and isolated PostgreSQL; it does not represent live model or CLI acceptance.
101
+
102
+ - 55ec356: Add typed ModelRequest.requirements and mergeModelRequirements for per-call capability requirements, initially supporting ModelFeature.VISION. The host validates and snapshots middleware contributions, unions requirements across the call chain, and checks each invoked model including fallbacks. Required capabilities cannot silently degrade or substitute a static response. Calls without requirements retain existing behavior. Generic multimodal ToolNode support remains deferred.
103
+ - fffb0f4: Add the scoped `ToolImagesRuntimeCapability` for immutable tool image references and temporary verified model input. Bind storage and Artifact access to the current host conversation, enforce complete tool rounds and checksum validation, and keep image bytes out of tool messages and checkpoints. Legacy image-tool history is sanitized only in outbound request copies.
104
+ - d81dbe2: Allow Workbench Views to opt into conversation context updates while staying mounted, and connect exact branch and message navigation to ChatKit.
105
+ - a131790: Add optional message anchors and originating-view preservation to Workbench conversation navigation contracts. The navigation resolver accepts an exact thread and message, validates thread ownership and visible user/assistant message membership, and retains the default thread behavior for older requests. Validate optional anchors at the HTTP boundary before resolving access.
106
+ - Updated dependencies [d18aa7f]
107
+ - Updated dependencies [b86bba1]
108
+ - Updated dependencies [a01cd48]
109
+ - Updated dependencies [bf33018]
110
+ - Updated dependencies [aa33949]
111
+ - Updated dependencies [d4dba33]
112
+ - Updated dependencies [01fd502]
113
+ - Updated dependencies [deff039]
114
+ - Updated dependencies [b66bdcc]
115
+ - Updated dependencies [b86bba1]
116
+ - Updated dependencies [f5add6a]
117
+ - Updated dependencies [c941907]
118
+ - Updated dependencies [c0dd14c]
119
+ - Updated dependencies [00b626e]
120
+ - Updated dependencies [3142346]
121
+ - Updated dependencies [3185f56]
122
+ - Updated dependencies [98a7367]
123
+ - Updated dependencies [d81dbe2]
124
+ - Updated dependencies [a131790]
125
+ - @xpert-ai/contracts@3.20.0
126
+
3
127
  ## 3.19.0
4
128
 
5
129
  ### Minor Changes
package/README.md CHANGED
@@ -156,3 +156,58 @@ their behavior; user identity and Artifact scope checks still apply.
156
156
 
157
157
  These additions require matching host contracts/runtime support and an SDK build
158
158
  containing these interfaces. They are not part of the published SDK 3.18.3 baseline.
159
+
160
+ ## Conversation resource receipts
161
+
162
+ See [RESOURCE-CARDS.md](./RESOURCE-CARDS.md) for the public protocol, tool/middleware emitter, transactional Project provider example, and coordinated release order.
163
+
164
+ ## Project task business types
165
+
166
+ Task providers can register business types without changing task hierarchy, status or ownership:
167
+
168
+ ```ts
169
+ import { ProjectTaskProvider, type IProjectTaskProvider, type ProjectTaskTypeDefinition } from '@xpert-ai/plugin-sdk'
170
+
171
+ @ProjectTaskProvider('example.tasks')
172
+ export class ExampleTasks implements IProjectTaskProvider {
173
+ readonly key = 'example.tasks'
174
+ readonly taskTypes = [
175
+ {
176
+ key: 'example.tasks.illustration',
177
+ presentation: {
178
+ label: { en_US: 'Construction images', zh_Hans: '施工配图' },
179
+ icon: 'Images'
180
+ }
181
+ }
182
+ ] satisfies ProjectTaskTypeDefinition[]
183
+
184
+ async snapshot() {
185
+ return {
186
+ revision: '1',
187
+ tasks: [
188
+ {
189
+ key: 'chapter-images',
190
+ title: 'Prepare construction images',
191
+ kind: 'task' as const,
192
+ taskType: 'example.tasks.illustration',
193
+ status: 'todo' as const,
194
+ predecessorKeys: [],
195
+ executions: []
196
+ }
197
+ ]
198
+ }
199
+ }
200
+ }
201
+ ```
202
+
203
+ Each `taskType` must reference a unique registration prefixed by the owning provider key and a dot. Presentation accepts an `I18nObject` label and a `ProjectTaskIconName` token. Supported icons are `FileText`, `FileScan`, `FileSearch`, `ListChecks`, `ListTree`, `ShieldCheck`, `FilePenLine`, `Workflow`, `Images`, `FolderInput` and `FileOutput`; providers cannot register SVG, HTML, scripts or remote icon URLs.
204
+
205
+ The host persists this key in the existing task `type` column and resolves presentation from the same provider on graph reads. Omit `taskType` to retain legacy persisted values, or pass `null` to clear it. Existing unknown types retain their identity and receive a structural fallback icon. New projections referencing unregistered types are rejected with a provider diagnostic. Registration changes are reflected on the next graph read without rewriting history.
206
+
207
+ `kind` still means `task`, `summary` or `milestone`. A task with children keeps its business icon; the separate expand/collapse control represents hierarchy. List, tree, Gantt, board and detail views share the same icon renderer, while status indicators and Assistant avatars retain their own meanings. Titles and execution prompts never determine a task's business type.
208
+
209
+ Deploy matching contracts, SDK and host support before a plugin starts emitting `taskType`. This is an additive public contract and requires no database migration or historical task rewrite.
210
+
211
+ ## Tool image references
212
+
213
+ See [TOOL-IMAGES.md](./TOOL-IMAGES.md) for `ToolImagesRuntimeCapability`, reference-only tool results, temporary visual model inputs, execution scope, and recovery rules. Never persist the messages returned by `prepareModelInput`.
@@ -0,0 +1,51 @@
1
+ # Resource Card validation — 2026-09-30
2
+
3
+ ## Implemented behavior
4
+
5
+ - Additive Resource Card protocol, allowlisted targets, stable per-reply deduplication, server-bound identities, streaming/history content, separate reply-bottom rendering and click-only Workbench navigation.
6
+ - Immediate best-effort scheduler receipt persistence; display errors are logged without changing an already successful creation result.
7
+ - Feature-gated scheduler detail View: authorized data/actions, edit/save, pause/resume, execution history and navigation. The View uses existing task services and built Remote Component assets.
8
+ - Optional public Project provider receipts, transactional pending metadata and atomic first-reply delivery. Bid uses platform Project IDs and keeps manual creation/business navigation independent.
9
+
10
+ ## Checks completed
11
+
12
+ - ChatKit UI: the full suite passed (131 files / 1,240 tests). After navigation restoration and stream tests were added, the focused protocol/card/Workbench/navigation suites passed (57 tests) and the stream/replay suite passed (3 tests).
13
+ - Backend: 20 resource-card/scheduler/delivery tests passed. Existing chat handler plus Project creation/provider suites passed (83 tests), including new receipt assertions. Cloud navigation authorization tests passed (8 tests).
14
+ - Bid: Project provider/creation tests passed (12 tests), plugin build passed, `verify:dist` passed, backend typecheck passed. These consume the sibling built public contracts and plugin-sdk through the existing workspace overrides.
15
+ - Xpert SDK: package build and View Host client tests passed (9 tests).
16
+ - Type checks: ChatKit UI, platform server-ai, Cloud and scheduler Remote Component passed. The broader server regression also passed against the newly built local ChatKit declarations; TypeORM's recursive JSON update boundary was narrowed without weakening the public method contract.
17
+ - Builds: ChatKit types/UI app and library, Xpert SDK, contracts, plugin-sdk and Bid passed. Scheduler and existing project-task Remote Component generated assets passed byte-for-byte freshness checks using `build.mjs --check`.
18
+ - Platform's temporary parser copy and ChatKit parser produce identical normalized JavaScript.
19
+ - All four repositories passed `git diff --check`.
20
+
21
+ ## Browser evidence
22
+
23
+ `chatkit-js/packages/chatkit-ui/resource-card-preview` builds the actual card renderer, command executor, Xpert SDK client and iframe bridge. It loads verified production scheduler/project-task assets. **The API data and Project session in this fixture are simulated.**
24
+
25
+ Playwright verified explicit click and keyboard Enter; scheduler edit/save, pause/resume, execution navigation; successive task selections and retained per-task unsaved drafts; browser Back/Forward and refresh; platform Project target opening the existing task timeline. Screenshots were visually inspected for Chinese/light, English/dark, a 430px panel and long titles:
26
+
27
+ - `chatkit-js/output/playwright/resource-card-zh-light.png`
28
+ - `chatkit-js/output/playwright/resource-card-en-dark.png`
29
+ - `chatkit-js/output/playwright/resource-card-narrow.png`
30
+ - `chatkit-js/output/playwright/resource-card-project.png`
31
+
32
+ ## Runtime/release boundary
33
+
34
+ The selected local Xpert source environment passed the environment inspector: API readiness at port 3000, Cloud at port 4200, correct checkout provenance, Bid workspace allowlisted. This proves environment health only.
35
+
36
+ No npm release or production deployment occurred. The platform's installed ChatKit catalog remains 0.7.0; a packaged release must upgrade it to the release containing these companion changes. Bid declares the upcoming contracts/plugin-sdk 3.19.0 baseline and uses local workspace overrides for validation.
37
+
38
+ On 2026-09-30, at the user's request, Bid 0.4.97 was rebuilt, packed and refreshed in the local Default tenant. The API was restarted from the current Xpert source, and authenticated checks confirmed the plugin was loaded, the Bid View manifest/data and Remote Component entry were available, and the Project middleware tool schemas resolved. The 12 Project tests, `verify:dist`, contracts/plugin-sdk builds and local environment inspector passed. Cloud on port 4200 serves the new card navigation code and uses the existing ChatKit source server on port 5173, where the new card renderer and public parser helpers are available. This is a source development deployment; the host SDK metadata remains 3.18.7 and therefore emits a compatibility warning against Bid's forthcoming 3.19.0 release baseline.
39
+
40
+ The package and secret-free deployment/runtime receipts are under `/Users/lilinhao/tiwen/.xpert-local-environment/bid-resource-cards-20260930/`. The user test entry is `http://localhost:4200/chat/x/bid-studio-5cb148df/c`.
41
+
42
+ A real authenticated Agent creating resources through the running platform and PostgreSQL, then navigating in that same deployed Cloud build, has **not** been accepted end to end; the user will perform that acceptance. Transaction/concurrency/rollback tests use repository doubles; the browser evidence above uses fixture APIs. The authenticated deployment smoke checks prove availability of the loaded plugin and its endpoints, not acceptance of the full conversation flow.
43
+
44
+ ## Project card navigation regression — 2026-09-30
45
+
46
+ The original host path treated an `assistant.project` card with a View as a workspace switch. That cleared the active conversation and first-send Project adoption, dropped the thread from the route, and changed the ChatKit mount binding. Project Views now own an independently authorized `projectScope` on their host tabs. The `viewProject` query parameter restores the View without changing the conversation route; card authorization resolves manifests in the persisted card's target Project scope.
47
+
48
+ - Seven focused Cloud suites passed: 178 tests covering card authorization, independent Project tabs, first-send adoption, retained conversation/control/mount, runtime scope propagation, stale requests, URL recovery and Back/Forward. Cloud application typecheck and `git diff --check` passed.
49
+ - Actual source environment: authenticated Cloud 4200 + ChatKit 5173 + API 3000 loaded an existing Bid conversation and restored its scoped `platform.project-tasks__timeline` View with the original thread and history present. The real Remote Component loaded the target Project's task panel. Screenshot: `/Users/lilinhao/tiwen/.xpert-local-environment/bid-resource-cards-20260930/project-view-conversation-retained.png`.
50
+ - Browser automation could not reliably activate controls inside the ChatKit iframe (`Click target is no longer available` / unavailable keyboard focus root). The real card-click-and-draft-retention path is therefore **not claimed as browser-verified**; it is covered by the host regression tests and remains a manual acceptance check. No new Agent request or business object was created during this verification.
51
+ - This fix is in Cloud host navigation and is loaded by the local source development server. Bid does not require repacking for this change. No npm publication or production deployment occurred.
@@ -0,0 +1,361 @@
1
+ # Conversation Resource Cards
2
+
3
+ A Resource Card is a persisted receipt for a business resource. File Artifacts remain the content/version/sharing model. Creating a scheduler or Project does not create an empty Artifact. A card may include `resource.artifactId` when it represents an existing file Artifact.
4
+
5
+ ## Ownership and lifecycle
6
+
7
+ | Layer | Responsibility |
8
+ | ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
9
+ | Domain service / Runtime | Commit business changes and execution facts; own authorization, decisions and revisions. |
10
+ | Plugin ResourceCard Provider | Construct the initial card and resolve its current, authorized presentation using the same formatter. |
11
+ | Tool / middleware | Emit the card after the business commit, using the active RunnableConfig. |
12
+ | Host | Persist and bind the card to the actual reply; discover providers, batch refreshes, validate identities and isolate failures. |
13
+ | ChatKit / Workbench | Render and reconcile generic cards; authorize navigation through the registered View. |
14
+
15
+ `createCard()` is a plugin-owned typed method, not an additional SDK interface or
16
+ registry operation. Only `resolveMany()` is standardized, and registering a
17
+ Provider remains optional. A static card does not need a Provider. Providers
18
+ format and read facts; they do not become the owner of business state.
19
+
20
+ ```mermaid
21
+ flowchart LR
22
+ D[Committed domain result] --> P[Provider.createCard]
23
+ P --> E[emitResourceCard]
24
+ E --> M[Host binds and persists message card]
25
+ M --> C[ChatKit generic card]
26
+ A[Thread activity subscription] --> H[Host refresh command / registry]
27
+ H --> R[Provider.resolveMany]
28
+ R -. reuses formatter .-> P
29
+ R --> S[Host validates read projection]
30
+ S --> C
31
+ ```
32
+
33
+ ## Emit after a successful tool mutation
34
+
35
+ ```ts
36
+ import { emitResourceCard } from '@xpert-ai/plugin-sdk'
37
+
38
+ const task = await tasks.create(input)
39
+ try {
40
+ await emitResourceCard(
41
+ {
42
+ resource: { namespace: 'platform', type: 'scheduled-task', id: task.id },
43
+ title: task.name,
44
+ description: `${task.scheduleDescription} · ${task.timeZone || 'UTC'}`,
45
+ icon: { type: 'emoji', value: '◷' },
46
+ open: {
47
+ target: 'workbench.view',
48
+ viewKey: 'platform.scheduler__detail',
49
+ selectionId: task.id
50
+ }
51
+ },
52
+ runnableConfig
53
+ )
54
+ } catch (error) {
55
+ logger.warn('Task created; resource receipt delivery failed', error)
56
+ }
57
+ return task
58
+ ```
59
+
60
+ Tools, middleware and plugin code can use the same helper inside an active Agent run. Pass its RunnableConfig to preserve callback context. The helper dispatches `ON_CHAT_EVENT`; the host binds the actual reply and execution, normalizes to a `MESSAGE` event and persists `type: 'resource_card'` content before forwarding. Emitters cannot choose message ownership. A presentation failure must not report a committed business mutation as failed or trigger another creation.
61
+
62
+ `resource.namespace + resource.type + resource.id` identifies the receipt **within a single reply**. Re-emitting replaces its snapshot at the same position. Other replies keep their own snapshots. The canonical part ID is produced by `resourceCardId`; callers should not concatenate an ID themselves. Text extraction and model history exclude these parts. Branches retain the content with their owning messages, and history loading never triggers navigation.
63
+
64
+ Targets are an allowlisted JSON protocol:
65
+
66
+ - `workbench.view`: required `viewKey`, optional `selectionId`, optional `parameters` containing scalars or scalar arrays.
67
+ - `assistant.project`: additionally requires the **platform Project ID** in `projectId`, and a `viewKey`.
68
+ - `workbench.file`: required `viewKey`, `fileKey` and `targetId`; opens a file preview with an original-file download action. Optional `previewFile` supplies a separate preview reference.
69
+
70
+ Targets cannot contain URLs, scripts or arbitrary client commands. Icons use the existing sanitized SVG, emoji or font renderer. Navigation and resource queries still pass through the host's View availability and access checks. An unavailable Workbench, missing View or denied/deleted resource produces feedback instead of an automatic fallback.
71
+
72
+ By default the card title/description is a snapshot. Opening loads current business state. Types that register the optional ResourceCard Provider below opt in to live refresh while a conversation is observed. Explicit scheduler-card navigation remembers the selected task per conversation and supports browser refresh/back/forward.
73
+
74
+ ## Optional live resource state
75
+
76
+ Plugins can opt exact resource types into live refresh with `ResourceCardProvider`
77
+ and `IResourceCardProvider`. Existing emitters need no change. Register the class
78
+ in the plugin module's `providers`; the host discovers it through the existing
79
+ StrategyBus lifecycle. Do not register a CQRS handler or a registry in the plugin.
80
+
81
+ ```ts
82
+ import { Injectable } from '@nestjs/common'
83
+ import type { ConversationResourceCard } from '@xpert-ai/contracts'
84
+ import {
85
+ ResourceCardProvider,
86
+ type IResourceCardProvider,
87
+ type ResourceCardContext,
88
+ type ResourceCardReadRequest,
89
+ type ResourceCardResolution
90
+ } from '@xpert-ai/plugin-sdk'
91
+
92
+ @Injectable()
93
+ @ResourceCardProvider({ namespace: 'my-plugin', type: 'report' })
94
+ export class ReportCardProvider implements IResourceCardProvider {
95
+ constructor(private readonly reports: ReportsService) {}
96
+
97
+ createCard(report: { id: string; title: string; description: string }): ConversationResourceCard {
98
+ return {
99
+ resource: { namespace: 'my-plugin', type: 'report', id: report.id },
100
+ title: report.title,
101
+ description: report.description,
102
+ open: { target: 'workbench.view', viewKey: 'my-plugin__reports', selectionId: report.id }
103
+ }
104
+ }
105
+
106
+ async resolveMany(
107
+ context: ResourceCardContext,
108
+ requests: readonly ResourceCardReadRequest[]
109
+ ): Promise<ResourceCardResolution[]> {
110
+ // ReportsService is the plugin's domain service. This read must enforce
111
+ // tenant, organization, user and resource access and honor context.signal.
112
+ const summaries = await this.reports.readAuthorizedSummaries(context, [
113
+ ...new Set(requests.map(({ card }) => card.resource.id))
114
+ ])
115
+ return requests.map(({ key, card }) => {
116
+ const summary = summaries.get(card.resource.id)
117
+ return summary === undefined
118
+ ? { key, status: 'unavailable', reason: 'forbidden' }
119
+ : {
120
+ key,
121
+ status: 'resolved',
122
+ card: this.createCard({ id: card.resource.id, title: card.title, description: summary })
123
+ }
124
+ })
125
+ }
126
+ }
127
+ ```
128
+
129
+ The decorator accepts multiple `{ namespace, type }` arguments. Each pair belongs
130
+ to one provider owner across installation scopes; another plugin cannot shadow
131
+ it. Same-plugin instances follow the existing organization, tenant, system and
132
+ builtin scope resolution. Refresh/uninstall removes that installation's routes.
133
+
134
+ Keep initial card construction in the same provider (for example, a typed
135
+ `createCard()` method), and reuse it from both tool receipts and `resolveMany()`.
136
+ Creation inputs belong to the plugin; the SDK only standardizes the optional
137
+ refresh contract. Tools remain responsible for emitting the returned card with
138
+ `emitResourceCard(provider.createCard(committedResult), runnableConfig)` after
139
+ the business commit, and isolating emission failures as in the first example.
140
+
141
+ The host calls `resolveMany` once per matched provider per snapshot, only for
142
+ cards already present in the authorized conversation. Context identity comes
143
+ from the host; `projectId` is optional. Requests include persisted message and
144
+ execution bindings for resources that require those association checks. Echo
145
+ `key` unchanged and return one result per request, including repeated resources
146
+ in different messages. Missing resources return `not_found`; denied resources
147
+ return `forbidden`. Do not return private diagnostics in presentation data.
148
+
149
+ Providers only read durable business state. Do not start jobs, decide acceptance,
150
+ write message history or poll a Computer CLI for each viewer. Use batched reads.
151
+ The host applies a two-second deadline and abort signal per provider, validates
152
+ returned card/resource identities, and supplies the original message bindings.
153
+ Invalid, missing, duplicated or failed responses receive a generic refresh
154
+ failure description; unavailable results receive a localized unavailable
155
+ message. Other providers and run discovery continue. Ignore late results and
156
+ honor the abort signal in cancellable I/O; the host cannot forcibly stop plugin
157
+ code or an uncancellable database call.
158
+
159
+ Live projections are viewer-specific and do not rewrite stored receipts or
160
+ create new cards. Removing the provider falls back to the saved receipt; clicking
161
+ still uses the View's access checks. Card navigation and result payloads keep the
162
+ existing ChatKit protocol. The updated ChatKit UI displays all committed cards
163
+ during streaming, without business-namespace-specific presentation branches.
164
+
165
+ The host has one `RefreshConversationResourceCardsCommand` handler in the message
166
+ module. `ThreadActivityService` supplies references; the handler dispatches
167
+ through `ResourceCardProviderRegistry`. The built-in Project Task Provider uses
168
+ this same path and retains its task, invocation and pinned-review checks.
169
+
170
+ ## Implemented scope and release boundary
171
+
172
+ The optional Provider path covers creation, persisted message binding, scoped
173
+ registration/replacement/removal, authorized batched refresh, failure isolation
174
+ and generic ChatKit display/navigation. `ProjectTaskCardProvider` is the built-in
175
+ implementation: delegation and refresh both call its `createCard()`; task
176
+ creation emits only a tool step, and each implementation/review attempt emits
177
+ its own execution card. Runtime success is distinct from business acceptance.
178
+
179
+ This is not a custom React/component extension API. A plugin supplies the shared
180
+ card data and a registered View target. Independent execution viewers remain
181
+ separate features. Activity currently polls full snapshots; there is no generic
182
+ card outbox, pagination or reconstruction of missing historical receipts.
183
+ Transactional first-conversation Project receipts below have their own durable
184
+ attachment mechanism; ordinary `emitResourceCard` does not inherit it.
185
+
186
+ Deploy the updated host/plugin SDK and matching ChatKit app assets together.
187
+ Local builds or copied app assets do not publish npm packages. After deployment,
188
+ reload the host once, then test a fresh delegation without refreshing during
189
+ execution: one card appears, its status updates, and the resumed Agent reply
190
+ streams automatically. Test Provider registration/refresh/removal with a
191
+ non-project fixture separately; a Project Task run alone does not prove an
192
+ external plugin's installation lifecycle.
193
+
194
+ ## Composable content and image groups
195
+
196
+ Use the optional `content` array to compose ordered presentation blocks inside one resource card. Each block can have a `title`:
197
+
198
+ | Kind | Items | Presentation |
199
+ | --------------- | ----------------------------- | ------------------------------------------------------------------- |
200
+ | `image-gallery` | `images: ResourceCardImage[]` | One responsive row initially; More expands the remaining images. |
201
+ | `file-list` | `files: ResourceCardFile[]` | File titles, optional descriptions and authorized download actions. |
202
+ | `fields` | `fields: ResourceCardField[]` | Read-only label/value pairs. |
203
+
204
+ For example, add this `content` property to the card passed to `emitResourceCard`:
205
+
206
+ ```ts
207
+ content: [
208
+ { kind: 'fields', fields: [{ label: '状态', value: '已完成' }] },
209
+ {
210
+ kind: 'image-gallery',
211
+ title: '施工配图',
212
+ images: [
213
+ {
214
+ id: 'site-layout',
215
+ title: '施工现场平面布置图',
216
+ alt: '施工分区、出入口和运输路线',
217
+ file: {
218
+ viewKey: 'bid.view-provider__bid.studio',
219
+ fileKey: 'bid-project-image',
220
+ targetId: `${projectId}:${assetVersionId}`
221
+ }
222
+ }
223
+ ]
224
+ }
225
+ ]
226
+ ```
227
+
228
+ New producers emit `content`, not top-level `images`. The reader converts historical top-level `images` only when `content` is absent. Image and file IDs must be unique within their block. The parser accepts up to 32 blocks and 100 items per block; these are transport bounds, not business image quotas. Invalid or unknown blocks are skipped independently.
229
+
230
+ Reference committed, immutable file versions. The View must declare the file key and implement its authorized resolver. Image previews require the `preview` purpose; download actions require `download`. Do not store signed URLs, private file paths, credentials or base64 pixels in a card.
231
+
232
+ ChatKit resolves visible thumbnails through the SDK View file-access session/grant API, reads authorized bytes and releases the session. Collapsed images are loaded only after expansion. Clicking an image opens a file preview with its own URL lifetime and an original-file download action. Failed previews can be retried without rerunning the business tool.
233
+
234
+ Committed cards appear as soon as their events arrive, including while the Assistant reply is streaming. Later events upsert the same card instead of adding duplicates. Cards render independently of text message bubbles and remain available in history.
235
+
236
+ The stream mapper binds an external Assistant's actual execution from runtime metadata; the root reply owns persistence. External Assistant transcripts retain cards for that execution and its descendants without counting them as tools or process steps. Plugins cannot supply either owner identity in the card payload.
237
+
238
+ For Bid, `bid_submit_role_task` emits one group only after the illustration task is accepted, including native writing and queued post-writing tasks. Repeated submissions upsert the same group in the current reply. Unaccepted candidates and omitted needs are excluded. An emission failure never changes the accepted submission result.
239
+
240
+ This extension requires coordinated ChatKit types/UI and host contracts/SDK/server updates before deploying a consuming plugin. Source tests do not upgrade installed packages.
241
+
242
+ ## File preview and original download
243
+
244
+ Use `workbench.file` for an exported document's Open action. It opens the file preview rather than the business View:
245
+
246
+ ```ts
247
+ open: {
248
+ target: 'workbench.file',
249
+ viewKey: 'bid.view-provider__bid.studio',
250
+ fileKey: 'bid-export-docx',
251
+ targetId: exportVersionId,
252
+ previewFile: {
253
+ viewKey: 'bid.view-provider__bid.studio',
254
+ fileKey: 'bid-export-preview-pdf',
255
+ targetId: exportVersionId
256
+ }
257
+ }
258
+ ```
259
+
260
+ `previewFile` is optional and uses the same `{ viewKey, fileKey, targetId }` reference shape. It can point to a derived PDF for a DOCX original. The preview and original download are authorized independently; Download always resolves the original reference. An unavailable preview can be retried without disabling Download. A resource card itself never grants file access.
261
+
262
+ Workbench navigation and file access are separate capabilities. If tabs are unavailable, a host can still provide authorized inline images and downloads. Leaving the runtime scope cancels pending file access and closes scoped file previews.
263
+
264
+ ## Transactional first-conversation Project receipts
265
+
266
+ Implement the public `IProjectTypeProvider.createForConversation` interface and return optional `resourceCards` along with the managed state:
267
+
268
+ ```ts
269
+ async createForConversation(context, input) {
270
+ const bid = await input.transaction.save(makeBid({
271
+ platformProjectId: input.projectId,
272
+ title: input.name
273
+ }))
274
+ return {
275
+ name: bid.title,
276
+ status: 'active',
277
+ viewKey: 'bid__projects', // Existing business entry remains independent.
278
+ selectionId: bid.id,
279
+ resourceCards: [{
280
+ resource: { namespace: 'platform', type: 'project', id: input.projectId },
281
+ title: bid.title,
282
+ open: {
283
+ target: 'assistant.project',
284
+ projectId: input.projectId,
285
+ viewKey: 'platform.project-tasks__timeline'
286
+ }
287
+ }]
288
+ }
289
+ }
290
+ ```
291
+
292
+ The host validates the target against `input.projectId`. It stores pending receipts in `Project.settings.conversationBootstrap` in the same transaction as the business write and conversation binding. `ProjectResourceCardService` locks the Project, then atomically updates the first Assistant message and `resourceCardMessageId`. Streaming begins after commit. A failed attachment leaves a pending receipt; competing first sends claim it once. Manual Project creation has no conversation receipt.
293
+
294
+ Do not emit directly inside the creation transaction: an event would escape a rollback. Plugins returning no receipts keep existing behavior.
295
+
296
+ ## Scheduler example
297
+
298
+ `SchedulerAgentMiddleware` declares the `scheduler` Feature. `SchedulerDetailViewProvider` contributes the on-demand `platform.scheduler__detail` View using the built Remote Component assets. Its selection is the stable task ID. Data/actions call existing task access, update, pause and resume services; execution navigation verifies the conversation belongs to that task. Existing cron parsing and other scheduler tools are unchanged.
299
+
300
+ While the detail View stays open, switching tasks retains each unsaved form draft in memory. Saving commits through the existing service; drafts are not background-saved or polled.
301
+
302
+ Build assets with:
303
+
304
+ ```sh
305
+ corepack pnpm exec tsc -p packages/server-ai/src/xpert-task/remote-components/scheduler-detail/tsconfig.json --noEmit
306
+ node packages/server-ai/src/xpert-task/remote-components/scheduler-detail/build.mjs
307
+ node packages/server-ai/src/xpert-task/remote-components/scheduler-detail/build.mjs --check
308
+ corepack pnpm remote-view:preview --config packages/server-ai/src/xpert-task/remote-components/scheduler-detail/preview.config.mjs --port 4325
309
+ ```
310
+
311
+ The preview explicitly uses fixture data, not a live scheduler.
312
+
313
+ ## Coordinated dependency rollout
314
+
315
+ 1. Build/release ChatKit types and Xpert SDK message contracts.
316
+ 2. Build/release ChatKit UI and wrappers together. Verify the iframe assets contain `resource_card` handling.
317
+ 3. Update the platform's single ChatKit catalog and relevant dependency lockfiles to those published versions, then build/release platform contracts and plugin-sdk against them.
318
+ 4. Build Bid against that public plugin-sdk (no local decorator/interface shim), run `verify:dist`, then deploy the matching host and plugin.
319
+
320
+ This change prepares changesets; it does not publish packages or deploy production. Platform contracts re-export the protocol from `@xpert-ai/chatkit-types`; plugin-sdk re-exports those contracts. Building local source does not publish packages or update the platform's pinned dependencies. Verify the installed release supports `content` blocks and `workbench.file` before deploying consumers. Local Bid workspace overrides may resolve sibling builds; do not describe a source alias or preview as a deployed package upgrade.
321
+
322
+ Existing message JSON is additive and needs no migration, new Artifact table or historical backfill.
323
+
324
+ ## Agent task results
325
+
326
+ Browser views import result schemas and types from `@xpert-ai/plugin-sdk/agent-results`.
327
+ This public entry only exports portable result contracts and Zod validation; the SDK root also exports server dependencies.
328
+ Do not reach into another package's `src` directory or import the server SDK root from a browser bundle.
329
+
330
+ `emitResourceCard(card, runnableConfig)` emits the existing ChatKit `resource_card` contract. It does not create an Artifact or grant access to one. Emit after the referenced business object has been committed.
331
+
332
+ ```ts
333
+ await emitResourceCard(
334
+ {
335
+ resource: { namespace: 'my-plugin', type: 'report', id: report.id },
336
+ title: report.title,
337
+ open: { target: 'workbench.view', viewKey: 'my-plugin__reports', selectionId: report.id }
338
+ },
339
+ config
340
+ )
341
+ ```
342
+
343
+ Use stable namespace/type/id values. Repeated observations update the same card in the current reply. The host supplies `messageId` and `executionId`, persists the card, and excludes it from model/transcript text. Callers cannot choose another reply. The registered View must recheck authorization on every read and file download. Do not put credentials, arbitrary URLs, commands, or private paths in navigation parameters.
344
+
345
+ Task results use the provider-neutral `AgentResultItem` union: analysis, changes, tests, and explicitly declared file deliverables. File delivery defaults to `none`; `files` exports only the declared files and `archive` packages only an explicit selection. Export failure is recorded separately from task execution. A card for an exported artifact refers to the committed artifact and opens the authorized task results View.
346
+
347
+ New artifact references must include the committed `versionId`. The task-results View will not download older references without a pinned version: falling back to the current artifact version could deliver unrelated later content. Such task results remain readable.
348
+
349
+ Middleware using the host task-results View declares `AGENT_TASK_RESULTS_FEATURE` in `meta.features`. The View uses `AGENT_WORKBENCH_SLOT`, opens on demand, and declares support for selection and parameter queries. Other plugins should register their own governed View and feature; emitting a card alone does not activate a View.
350
+
351
+ Local rollout requires the matching ChatKit types/UI with resource-card support, then host contracts/SDK/server, then consuming plugins. Building a local SDK does not publish a new registry package.
352
+
353
+ `api:build` builds the task-results browser bundle before copying its assets. For a source-run API, first run `corepack pnpm nx run api:build-agent-results`. Generated `app.js` and `app.css` are ignored; commit the source and build configuration only.
354
+
355
+ ## Coding invocation cards and activity
356
+
357
+ The built-in `platform.agent-invocation/execution` provider owns direct Coding invocation card creation and refresh. Runtime middleware requests the card through the optional `AgentInvocationApi.getResourceCard()` after start. Project dispatch keeps its existing `platform.project-tasks/execution` identity and does not emit a second generic card.
358
+
359
+ The card opens `platform.coding-execution__execution` with the exact invocation ID. Public CLI activity is written through the optional Runtime `context.activity` recorder and queried by the View provider. Resource-card refresh contains only presentation/state/target updates; it does not transport command output or invoke a CLI. Final summary cards are suppressed only when a Coding execution card already covers the run; independently delivered files retain their own cards.
360
+
361
+ See [Coding Execution View](../server-ai/src/agent-invocation/execution-view/README.md) for the capability, authorization, storage, retention and navigation contract.