@amaster.ai/dsh-a2a 0.1.37 → 0.1.38

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
@@ -16,13 +16,13 @@ dsh plugin --profile my-agent add @amaster.ai/dsh-a2a
16
16
 
17
17
  `inbox.enabled: true` uses the official DSH inbox (`Agent.send`) for ordinary `next-turn` input and `next-step` steering. Tested with the unmodified npm runtime `0.2.1-rc.5`; no core patch is required. The queue and its durable projection belong to DSH. The plugin only materializes messages, attaches A2A task identities, and translates execution events.
18
18
 
19
- Standard `SendMessage` / `SendStreamingMessage`, task queries, cancellation and task subscriptions keep their official meanings. The negotiated inbox extension forwards `target` and `wakeup` to DSH. `wakeup: false` leaves an idle driver parked; it does not prevent an active driver from consuming pending input. A later real waking message releases pending input.
19
+ Standard `SendMessage` / `SendStreamingMessage`, task queries, cancellation and task subscriptions keep their official meanings. Optional inbox metadata forwards `target` and `wakeup` to DSH. `wakeup: false` leaves an idle driver parked; it does not prevent an active driver from consuming pending input. A later real waking message releases pending input.
20
20
 
21
21
  The same-process `a2aInbox` service exposes `resolve`, `content`, `enqueue`, `promote`, `cancel`, `get`, `update`, `move`, `remove`, `clearPending`, and `executePending`, plus the existing pause/wake/resume controls. Pending-only clearing preserves active work; context clearing discards all work.
22
22
 
23
23
  Pause is process-local and writes no custom required session event. After restart, restored input stays parked until a waking admission or explicit execution. Retention recovery accepts snapshots under the historical extension URI as well as the current URI, writes only the current metadata key, and clears both keys after consumption. Explicit resume durably transfers input to a fresh task before waking it; retry after an interrupted cleanup reuses the existing replacement instead of replaying its input.
24
24
 
25
- For external clients, the [native inbox extension specification](#native-inbox-extension-v1) defines `inbox/get`, `update`, `move`, `remove`, `clear`, `execute`, `steer`, and `subscribe` at the advertised JSONRPC endpoint. Activate it with the `A2A-Extensions` header set to the extension URI. Updates use standard A2A 1.0 user Messages; operations address native inbox IDs. REST/gRPC clients use the advertised JSONRPC endpoint for these extension methods. No extra queue or consumer is created.
25
+ For external clients, the [native inbox extension specification](#native-inbox-extension-v1) defines `inbox/get`, `update`, `move`, `remove`, `clear`, `execute`, `steer`, and `subscribe` at the advertised JSONRPC endpoint. No `A2A-Extensions` header or extension activation is required. Updates use standard A2A 1.0 user Messages; operations address native inbox IDs. REST/gRPC clients use the advertised JSONRPC endpoint for these extension methods. No extra queue or consumer is created.
26
26
 
27
27
  `inbox/subscribe` streams checkpointed invalidations `{contextId, version}` over SSE, including native consumption and edits. It registers before its initial checkpoint and sends only after owner-scoped `ctx.sessions.flush()` returns true. A false/rejected checkpoint sends no success notification. Re-read the live inbox on invalidation and reconnect; there is no replay or durable outbox. Slow clients disconnect instead of accumulating notifications. To publish the same invalidations to host listeners on `a2a/inbox-checkpointed` without an SSE subscriber, enable `inbox.notifications: true` (default false). Hosts retain authentication, authorization and product-specific fan-out.
28
28
 
@@ -81,14 +81,15 @@ DSH_NATIVE_OWNERSHIP_LANGFUSE_LIVE=true node .github/scripts/check-inbox.mjs -t
81
81
 
82
82
  Protocol identifier: `https://github.com/TGYD-helige/dsh-plugins/blob/main/packages/dsh-a2a/README.md`
83
83
 
84
- This README contains the extension specification. The URI identifies the
85
- extension during negotiation; no additional documentation parameter is advertised.
84
+ This README contains the extension specification. The URI remains a metadata
85
+ namespace and discovery identifier for compatibility; callers do not need to send it.
86
86
 
87
87
  This is a project extension, not an official A2A extension. It follows the
88
88
  [A2A extension mechanism](https://a2a-protocol.org/v1.0.1/topics/extensions/).
89
- The Agent Card advertises it when `inbox.enabled` is true. Activate it with the
90
- `A2A-Extensions` HTTP header. Responses echo that header. Standard task methods,
91
- states, subscriptions and Push configurations keep their official meanings.
89
+ The Agent Card advertises it when `inbox.enabled` is true. Inbox methods and
90
+ optional admission controls do not require an `A2A-Extensions` header or an
91
+ activation handshake. Standard task methods, states, subscriptions and Push
92
+ configurations keep their official meanings.
92
93
 
93
94
  ### Methods
94
95
 
@@ -177,7 +178,7 @@ Closing the plugin unregisters observers/subscriptions and suppresses late sends
177
178
 
178
179
  Standard SendMessage/SendStreamingMessage continues to accept
179
180
  `metadata[URI] = {target: 'next-turn' | 'next-step', wakeup: boolean}` on its
180
- Message, negotiated as before. Prefer those standard methods for new input.
181
+ Message, without extension negotiation. Prefer those standard methods for new input.
181
182
  The operations above control already queued input; they do not add another
182
183
  queue, consumer, task-state machine or webhook configuration store.
183
184
 
package/lib/inbox-api.js CHANGED
@@ -1,8 +1,8 @@
1
1
  /** JSON-RPC method extension; standard task methods stay with the official SDK. */
2
- import { A2A_PROTOCOL_VERSION, A2A_VERSION_HEADER, Extensions, HTTP_EXTENSION_HEADER, Message, } from '@a2a-js/sdk';
3
- import { ExtensionSupportRequiredError, RequestMalformedError, toJsonRpcError, } from '@a2a-js/sdk/errors';
2
+ import { A2A_PROTOCOL_VERSION, A2A_VERSION_HEADER, Message } from '@a2a-js/sdk';
3
+ import { RequestMalformedError, toJsonRpcError } from '@a2a-js/sdk/errors';
4
4
  import { validateVersion } from '@a2a-js/sdk/server';
5
- import { INBOX_EXTENSION, validateInboxPage } from './inbox.js';
5
+ import { validateInboxPage } from './inbox.js';
6
6
  export function inboxRpcHandler(inbox, card) {
7
7
  return async (req, res, next) => {
8
8
  const body = req.body;
@@ -12,9 +12,6 @@ export function inboxRpcHandler(inbox, card) {
12
12
  if (body.jsonrpc !== '2.0' || !['string', 'number'].includes(typeof body.id))
13
13
  throw new RequestMalformedError('A JSON-RPC 2.0 request id is required.');
14
14
  validateVersion(req.get(A2A_VERSION_HEADER) || A2A_PROTOCOL_VERSION, card, 'JSONRPC');
15
- if (!Extensions.parseServiceParameter(req.get(HTTP_EXTENSION_HEADER)).includes(INBOX_EXTENSION))
16
- throw new ExtensionSupportRequiredError('Activate the native inbox extension.');
17
- res.setHeader(HTTP_EXTENSION_HEADER, INBOX_EXTENSION);
18
15
  const params = body.params;
19
16
  if (!params ||
20
17
  typeof params !== 'object' ||
package/lib/inbox.js CHANGED
@@ -951,12 +951,10 @@ export class NativeInbox {
951
951
  context: new ServerCallContext({ tenant: context.tenant, user: context.user }),
952
952
  };
953
953
  }
954
- controls(message, context) {
954
+ controls(message) {
955
955
  const value = message.metadata?.[INBOX_EXTENSION];
956
956
  if (value === undefined)
957
957
  return { target: 'next-turn', wakeup: true };
958
- if (!context.requestedExtensions?.includes(INBOX_EXTENSION))
959
- throw new Error('Inbox controls require A2A-Extensions negotiation.');
960
958
  if (!value ||
961
959
  typeof value !== 'object' ||
962
960
  Array.isArray(value) ||
@@ -966,7 +964,6 @@ export class NativeInbox {
966
964
  throw new Error('Invalid inbox target.');
967
965
  if (value.wakeup !== undefined && typeof value.wakeup !== 'boolean')
968
966
  throw new Error('Invalid inbox wakeup.');
969
- context.addActivatedExtension(INBOX_EXTENSION);
970
967
  return {
971
968
  target: value.target === 'next-step' ? 'next-step' : 'next-turn',
972
969
  wakeup: value.wakeup !== false,
@@ -976,7 +973,7 @@ export class NativeInbox {
976
973
  async beforeMessage(message, context) {
977
974
  if (!message.messageId)
978
975
  throw new Error('message.messageId is required.');
979
- const controls = this.controls(message, context);
976
+ const controls = this.controls(message);
980
977
  if (!message.taskId) {
981
978
  if (controls.target === 'next-step')
982
979
  throw new Error('Steering must address an active task.');
@@ -1149,7 +1146,7 @@ export class NativeInbox {
1149
1146
  let task;
1150
1147
  let ownsTask = false;
1151
1148
  try {
1152
- const controls = this.controls(userMessage, context);
1149
+ const controls = this.controls(userMessage);
1153
1150
  const run = await this.context(contextId, context);
1154
1151
  task = run.tasks.get(taskId);
1155
1152
  if (!task) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amaster.ai/dsh-a2a",
3
- "version": "0.1.37",
3
+ "version": "0.1.38",
4
4
  "description": "A2A protocol (JSON-RPC + SSE) server plugin for DeepSeek Harness: expose dsh agents as A2A agents.",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",