@datalayer/agent-runtimes 1.5.45 → 1.5.47

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 (54) hide show
  1. package/dist-embed/datalayer-app-main.js +4 -4
  2. package/lib/portable/conversation.d.ts +6 -0
  3. package/lib/portable/conversation.js +29 -1
  4. package/lib/portable/hosts/__tests__/fixtures/lock-with-jupyter.json +40 -0
  5. package/lib/portable/hosts/__tests__/fixtures/npm-ls-with-jupyter.json +21 -0
  6. package/lib/portable/hosts/agentClient.d.ts +167 -0
  7. package/lib/portable/hosts/agentClient.js +346 -0
  8. package/lib/portable/hosts/approvalRenderers.d.ts +43 -0
  9. package/lib/portable/hosts/approvalRenderers.js +180 -0
  10. package/lib/portable/hosts/client.d.ts +95 -0
  11. package/lib/portable/hosts/client.js +174 -0
  12. package/lib/portable/hosts/contracts.d.ts +199 -0
  13. package/lib/portable/hosts/contracts.js +235 -0
  14. package/lib/portable/hosts/contracts.json +381 -0
  15. package/lib/portable/hosts/deadLetters.d.ts +41 -0
  16. package/lib/portable/hosts/deadLetters.js +124 -0
  17. package/lib/portable/hosts/deliveries.d.ts +76 -0
  18. package/lib/portable/hosts/deliveries.js +147 -0
  19. package/lib/portable/hosts/forbiddenGraph.d.ts +77 -0
  20. package/lib/portable/hosts/forbiddenGraph.js +174 -0
  21. package/lib/portable/hosts/health.d.ts +35 -0
  22. package/lib/portable/hosts/health.js +92 -0
  23. package/lib/portable/hosts/index.d.ts +40 -0
  24. package/lib/portable/hosts/index.js +45 -0
  25. package/lib/portable/hosts/observability.d.ts +67 -0
  26. package/lib/portable/hosts/observability.js +171 -0
  27. package/lib/portable/hosts/postgresQueue.d.ts +55 -0
  28. package/lib/portable/hosts/postgresQueue.js +217 -0
  29. package/lib/portable/hosts/queue.d.ts +47 -0
  30. package/lib/portable/hosts/queue.js +63 -0
  31. package/lib/portable/hosts/quotas.d.ts +81 -0
  32. package/lib/portable/hosts/quotas.js +147 -0
  33. package/lib/portable/hosts/rateLimit.d.ts +13 -0
  34. package/lib/portable/hosts/rateLimit.js +8 -0
  35. package/lib/portable/hosts/resolution.d.ts +54 -0
  36. package/lib/portable/hosts/resolution.js +46 -0
  37. package/lib/portable/hosts/schema.d.ts +19 -0
  38. package/lib/portable/hosts/schema.js +81 -0
  39. package/lib/portable/hosts/secretCipher.d.ts +23 -0
  40. package/lib/portable/hosts/secretCipher.js +45 -0
  41. package/lib/portable/hosts/sessionUid.d.ts +7 -0
  42. package/lib/portable/hosts/sessionUid.js +28 -0
  43. package/lib/portable/hosts/turnState.d.ts +45 -0
  44. package/lib/portable/hosts/turnState.js +113 -0
  45. package/lib/portable/index.d.ts +2 -0
  46. package/lib/portable/index.js +3 -0
  47. package/lib/portable/semantic-events.json +480 -0
  48. package/lib/portable/semantic.d.ts +78 -0
  49. package/lib/portable/semantic.js +100 -0
  50. package/lib/portable/semanticOfAgUi.d.ts +41 -0
  51. package/lib/portable/semanticOfAgUi.js +108 -0
  52. package/lib/protocols/A2AAdapter.js +19 -0
  53. package/lib/test-setup.js +17 -14
  54. package/package.json +1 -1
@@ -0,0 +1,108 @@
1
+ /*
2
+ * Copyright (c) 2025-2026 Datalayer, Inc.
3
+ * Distributed under the terms of the Modified BSD License.
4
+ */
5
+ /** A string field of an event, or the fallback: never an object stringified. */
6
+ const stringOf = (value, fallback = '') => typeof value === 'string' ? value : fallback;
7
+ const isRecord = (value) => Boolean(value) && typeof value === 'object' && !Array.isArray(value);
8
+ /** The turn a `loop.turn` event names, or `undefined` for any other event. */
9
+ export function turnOf(event) {
10
+ if (event.type !== 'CUSTOM' || event.name !== 'loop.turn') {
11
+ return undefined;
12
+ }
13
+ const value = isRecord(event.value) ? event.value : {};
14
+ return {
15
+ replayed: value.replayed === true,
16
+ session: stringOf(value.session),
17
+ state: stringOf(value.state),
18
+ turn: stringOf(value.turn),
19
+ };
20
+ }
21
+ /** What a tool's result says of itself: JSON when it is JSON, else nothing. */
22
+ function resultRecord(content) {
23
+ if (isRecord(content)) {
24
+ return content;
25
+ }
26
+ if (typeof content !== 'string') {
27
+ return undefined;
28
+ }
29
+ try {
30
+ const parsed = JSON.parse(content);
31
+ return isRecord(parsed) ? parsed : undefined;
32
+ }
33
+ catch {
34
+ return undefined;
35
+ }
36
+ }
37
+ /**
38
+ * The question a turn ends on (`RUN_FINISHED.result.asking`), as
39
+ * a host asks it, or `undefined` when the value is not a question. A kind a
40
+ * host does not know is answered in Datalayer, as a form (SLACK S-307):
41
+ * never guessed to be text. (`conversation.ts`'s `questionOf`, for a native
42
+ * client, throws on such a kind instead.)
43
+ */
44
+ export function askQuestionOf(value) {
45
+ if (!isRecord(value) || typeof value.prompt !== 'string') {
46
+ return undefined;
47
+ }
48
+ const kind = value.kind === 'text' ||
49
+ value.kind === 'choice' ||
50
+ value.kind === 'file' ||
51
+ value.kind === 'form'
52
+ ? value.kind
53
+ : 'form';
54
+ const options = Array.isArray(value.options)
55
+ ? value.options.filter((one) => typeof one === 'string')
56
+ : undefined;
57
+ return kind === 'choice'
58
+ ? { kind, prompt: value.prompt, options: options ?? [] }
59
+ : { kind, prompt: value.prompt };
60
+ }
61
+ /**
62
+ * The semantic events (version 1) one AG-UI event means: none for an event a
63
+ * host does not show. `tools` keeps each running call's name by its id, for
64
+ * its result.
65
+ */
66
+ export function semanticOf(event, tools) {
67
+ switch (event.type) {
68
+ case 'TEXT_MESSAGE_CONTENT':
69
+ case 'TEXT_MESSAGE_CHUNK':
70
+ return typeof event.delta === 'string' && event.delta
71
+ ? [{ kind: 'text', text: event.delta }]
72
+ : [];
73
+ case 'TOOL_CALL_START': {
74
+ const id = stringOf(event.toolCallId);
75
+ const name = stringOf(event.toolCallName, 'a tool');
76
+ tools.set(id, name);
77
+ return [{ kind: 'tool', id, name, status: 'running' }];
78
+ }
79
+ case 'TOOL_CALL_RESULT': {
80
+ const id = stringOf(event.toolCallId);
81
+ const name = tools.get(id) ?? 'a tool';
82
+ const result = resultRecord(event.content);
83
+ if (result?.pending_approval === true) {
84
+ return [{ kind: 'approval', toolCallId: id, toolName: name }];
85
+ }
86
+ const failed = result?.success === false || result?.isError === true;
87
+ return [
88
+ { kind: 'tool', id, name, status: failed ? 'failed' : 'complete' },
89
+ ];
90
+ }
91
+ case 'STEP_STARTED':
92
+ return typeof event.stepName === 'string' && event.stepName
93
+ ? [{ kind: 'progress', label: event.stepName }]
94
+ : [];
95
+ case 'RUN_FINISHED': {
96
+ const asking = askQuestionOf(isRecord(event.result) ? event.result.asking : undefined);
97
+ return asking
98
+ ? [{ kind: 'ask', question: asking }]
99
+ : [{ kind: 'completion' }];
100
+ }
101
+ case 'RUN_ERROR':
102
+ return [
103
+ { kind: 'error', message: stringOf(event.message, 'The run failed.') },
104
+ ];
105
+ default:
106
+ return [];
107
+ }
108
+ }
@@ -10,6 +10,7 @@
10
10
  import { ORCHESTRATION_EXTENSION_URI, ENVELOPE_KEY as DATALAYER_META_KEY, readUsageMeta, } from '@datalayer/agent-teams';
11
11
  import { generateMessageId, createAssistantMessage } from '../types/messages';
12
12
  import { BaseProtocolAdapter } from './BaseProtocolAdapter';
13
+ import { VOICE_SAY_EVENT, VOICE_SETTINGS_EVENT } from '../voice/sayAloud';
13
14
  /**
14
15
  * The header fasta2a-based workers (`agent-runtimes`'s own, and any other
15
16
  * built on it) actually read to activate an extension for one request —
@@ -432,6 +433,24 @@ export class A2AAdapter extends BaseProtocolAdapter {
432
433
  if (eventKind === 'status-update') {
433
434
  const state = task.status?.state;
434
435
  console.log('[A2AAdapter] Status update:', state, 'final:', task.final);
436
+ // The agent's voice and the lines it says aloud, in a working status
437
+ // message's metadata (VOICE.md VO-36): activities the chat says and
438
+ // captions, as AG-UI's `voice.settings` and `voice.say` custom events.
439
+ const voice = task.status?.message?.metadata?.voice;
440
+ if (voice?.settings) {
441
+ this.emit({
442
+ type: 'activity',
443
+ activity: { type: VOICE_SETTINGS_EVENT, data: voice.settings },
444
+ timestamp: new Date(),
445
+ });
446
+ }
447
+ if (voice?.say) {
448
+ this.emit({
449
+ type: 'activity',
450
+ activity: { type: VOICE_SAY_EVENT, data: voice.say },
451
+ timestamp: new Date(),
452
+ });
453
+ }
435
454
  if (task.final &&
436
455
  (state === 'completed' || state === 'failed' || state === 'canceled')) {
437
456
  // Only read the envelope once the worker actually named the
package/lib/test-setup.js CHANGED
@@ -68,20 +68,23 @@ class MockDataTransfer {
68
68
  // Add missing DOM APIs to global scope
69
69
  global.DragEvent = MockDragEvent;
70
70
  global.DataTransfer = MockDataTransfer;
71
- // Mock window.matchMedia
72
- Object.defineProperty(window, 'matchMedia', {
73
- writable: true,
74
- value: (query) => ({
75
- matches: false,
76
- media: query,
77
- onchange: null,
78
- addListener: () => { }, // deprecated
79
- removeListener: () => { }, // deprecated
80
- addEventListener: () => { },
81
- removeEventListener: () => { },
82
- dispatchEvent: () => { },
83
- }),
84
- });
71
+ // Mock window.matchMedia. A test that runs in node (`@vitest-environment
72
+ // node`, the portable host code: plans/DISCORD.md §4.2) has no window.
73
+ if (typeof window !== 'undefined') {
74
+ Object.defineProperty(window, 'matchMedia', {
75
+ writable: true,
76
+ value: (query) => ({
77
+ matches: false,
78
+ media: query,
79
+ onchange: null,
80
+ addListener: () => { }, // deprecated
81
+ removeListener: () => { }, // deprecated
82
+ addEventListener: () => { },
83
+ removeEventListener: () => { },
84
+ dispatchEvent: () => { },
85
+ }),
86
+ });
87
+ }
85
88
  // Mock Simple-related modules to prevent import errors
86
89
  import { vi } from 'vitest';
87
90
  vi.mock('@datalayer/jupyter-react', () => ({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datalayer/agent-runtimes",
3
- "version": "1.5.45",
3
+ "version": "1.5.47",
4
4
  "type": "module",
5
5
  "workspaces": [
6
6
  ".",