@genesislcap/ai-assistant 14.494.0 → 14.496.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.
- package/dist/ai-assistant.api.json +588 -214
- package/dist/ai-assistant.d.ts +157 -6
- package/dist/chat-driver.cjs +5608 -0
- package/dist/chat-driver.cjs.map +7 -0
- package/dist/chat-driver.mjs +5566 -0
- package/dist/chat-driver.mjs.map +7 -0
- package/dist/custom-elements.json +713 -333
- package/dist/dts/channel/ai-activity-bus.d.ts +36 -0
- package/dist/dts/channel/ai-activity-bus.d.ts.map +1 -1
- package/dist/dts/channel/ai-activity-channel.d.ts +10 -1
- package/dist/dts/channel/ai-activity-channel.d.ts.map +1 -1
- package/dist/dts/chat-driver-node.d.ts +28 -0
- package/dist/dts/chat-driver-node.d.ts.map +1 -0
- package/dist/dts/components/chat-driver/chat-driver.d.ts +66 -5
- package/dist/dts/components/chat-driver/chat-driver.d.ts.map +1 -1
- package/dist/dts/components/chat-driver/chat-driver.test.d.ts.map +1 -1
- package/dist/dts/components/orchestrating-driver/orchestrating-driver.d.ts +3 -0
- package/dist/dts/components/orchestrating-driver/orchestrating-driver.d.ts.map +1 -1
- package/dist/dts/config/config.d.ts +37 -2
- package/dist/dts/config/config.d.ts.map +1 -1
- package/dist/dts/index.d.ts +1 -0
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/dts/main/main.d.ts.map +1 -1
- package/dist/dts/state/debug-event-log.d.ts +8 -12
- package/dist/dts/state/debug-event-log.d.ts.map +1 -1
- package/dist/esm/channel/ai-activity-bus.js +48 -12
- package/dist/esm/chat-driver-node.js +33 -0
- package/dist/esm/components/chat-driver/chat-driver.js +77 -25
- package/dist/esm/components/chat-driver/chat-driver.test.js +160 -36
- package/dist/esm/components/orchestrating-driver/orchestrating-driver.js +7 -1
- package/dist/esm/main/main.js +8 -1
- package/dist/esm/main/popout-interaction-gate.test.js +6 -10
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +29 -19
- package/scripts/build-chat-driver-node.mjs +42 -0
- package/src/channel/ai-activity-bus.ts +64 -10
- package/src/channel/ai-activity-channel.ts +9 -1
- package/src/chat-driver-node.ts +54 -0
- package/src/components/chat-driver/chat-driver.test.ts +237 -50
- package/src/components/chat-driver/chat-driver.ts +151 -39
- package/src/components/orchestrating-driver/orchestrating-driver.ts +10 -11
- package/src/config/config.ts +40 -1
- package/src/index.ts +1 -0
- package/src/main/main.ts +8 -11
- package/src/main/popout-interaction-gate.test.ts +6 -11
- package/src/state/debug-event-log.ts +9 -18
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["../src/index.ts","../src/channel/ai-activity-bus.ts","../src/channel/ai-activity-channel.ts","../src/components/flowing-waves-indicator.ts","../src/components/halo-overlay.ts","../src/components/plasma-orb-indicator.ts","../src/components/waves-indicator.ts","../src/components/activity-halo/activity-halo.ts","../src/components/agent-picker/agent-picker.constants.ts","../src/components/agent-picker/agent-picker.styles.ts","../src/components/agent-picker/agent-picker.template.ts","../src/components/agent-picker/agent-picker.ts","../src/components/agent-picker/index.ts","../src/components/ai-driver/ai-driver.ts","../src/components/ai-driver/index.ts","../src/components/chat-bubble/chat-bubble.styles.ts","../src/components/chat-bubble/chat-bubble.template.ts","../src/components/chat-bubble/chat-bubble.ts","../src/components/chat-bubble/index.ts","../src/components/chat-driver/align-event-globals.ts","../src/components/chat-driver/chat-driver.compact.test.ts","../src/components/chat-driver/chat-driver.test.ts","../src/components/chat-driver/chat-driver.ts","../src/components/chat-driver/index.ts","../src/components/chat-interaction-wrapper/chat-interaction-wrapper.styles.ts","../src/components/chat-interaction-wrapper/chat-interaction-wrapper.template.ts","../src/components/chat-interaction-wrapper/chat-interaction-wrapper.test.ts","../src/components/chat-interaction-wrapper/chat-interaction-wrapper.ts","../src/components/chat-interaction-wrapper/index.ts","../src/components/chat-markdown/chat-markdown.ts","../src/components/chat-markdown/index.ts","../src/components/orchestrating-driver/index.ts","../src/components/orchestrating-driver/orchestrating-driver.pin.test.ts","../src/components/orchestrating-driver/orchestrating-driver.ts","../src/components/popout-manager/index.ts","../src/components/popout-manager/popout-manager.ts","../src/components/settings-modal/index.ts","../src/components/settings-modal/settings-modal.styles.ts","../src/components/settings-modal/settings-modal.template.ts","../src/config/config.ts","../src/config/define-stateful-agent.test.ts","../src/config/define-stateful-agent.ts","../src/config/fallback-agents.ts","../src/config/index.ts","../src/config/validate-providers.test.ts","../src/config/validate-providers.ts","../src/main/index.ts","../src/main/main.styles.ts","../src/main/main.template.ts","../src/main/main.ts","../src/main/main.types.ts","../src/main/popout-interaction-gate.test.ts","../src/provider/ai-provider-switcher.ts","../src/provider/assistant-app-settings.ts","../src/state/ai-assistant-slice.test.ts","../src/state/ai-assistant-slice.ts","../src/state/debug-event-log.test.ts","../src/state/debug-event-log.ts","../src/state/driver-registry.test.ts","../src/state/driver-registry.ts","../src/state/interaction-context.test.ts","../src/state/interaction-context.ts","../src/state/session-store.ts","../src/state/persistence/diagnostics-cursors.test.ts","../src/state/persistence/diagnostics-cursors.ts","../src/state/persistence/diagnostics.test.ts","../src/state/persistence/diagnostics.ts","../src/state/persistence/index.ts","../src/state/persistence/persister-registry.ts","../src/state/persistence/session-persistence-provider.test.ts","../src/state/persistence/session-persistence-provider.ts","../src/state/persistence/session-persistence.integration.test.ts","../src/state/persistence/session-persister.test.ts","../src/state/persistence/session-persister.ts","../src/state/persistence/session-snapshot.test.ts","../src/state/persistence/session-snapshot.ts","../src/state/persistence/stateful-restore.e2e.test.ts","../src/styles/ai-colours.ts","../src/suggestions/chat-suggestions.ts","../src/tags/index.ts","../src/types/ai-chat-widget.ts","../src/types/interaction-context.ts","../src/utils/animated-panel-toggle.ts","../src/utils/animation-exclusivity.test.ts","../src/utils/animation-exclusivity.ts","../src/utils/collect-session-models.test.ts","../src/utils/collect-session-models.ts","../src/utils/condense-history.test.ts","../src/utils/condense-history.ts","../src/utils/cost-session-history.test.ts","../src/utils/cost-session-history.ts","../src/utils/derive-cost-session-title.test.ts","../src/utils/derive-cost-session-title.ts","../src/utils/flatten-sub-agent-messages.test.ts","../src/utils/flatten-sub-agent-messages.ts","../src/utils/history-transform.test.ts","../src/utils/history-transform.ts","../src/utils/index.ts","../src/utils/logger.ts","../src/utils/message-partition.test.ts","../src/utils/message-partition.ts","../src/utils/resolve-cost-history-config.test.ts","../src/utils/resolve-cost-history-config.ts","../src/utils/resolve-preference-baseline.test.ts","../src/utils/resolve-preference-baseline.ts","../src/utils/strip-agent-handlers.test.ts","../src/utils/strip-agent-handlers.ts","../src/utils/sum-costs.test.ts","../src/utils/sum-costs.ts","../src/utils/sum-tokens.test.ts","../src/utils/sum-tokens.ts","../src/utils/tool-fold.ts","../src/utils/with-timeout.ts"],"version":"5.9.2"}
|
|
1
|
+
{"root":["../src/chat-driver-node.ts","../src/index.ts","../src/channel/ai-activity-bus.ts","../src/channel/ai-activity-channel.ts","../src/components/flowing-waves-indicator.ts","../src/components/halo-overlay.ts","../src/components/plasma-orb-indicator.ts","../src/components/waves-indicator.ts","../src/components/activity-halo/activity-halo.ts","../src/components/agent-picker/agent-picker.constants.ts","../src/components/agent-picker/agent-picker.styles.ts","../src/components/agent-picker/agent-picker.template.ts","../src/components/agent-picker/agent-picker.ts","../src/components/agent-picker/index.ts","../src/components/ai-driver/ai-driver.ts","../src/components/ai-driver/index.ts","../src/components/chat-bubble/chat-bubble.styles.ts","../src/components/chat-bubble/chat-bubble.template.ts","../src/components/chat-bubble/chat-bubble.ts","../src/components/chat-bubble/index.ts","../src/components/chat-driver/align-event-globals.ts","../src/components/chat-driver/chat-driver.compact.test.ts","../src/components/chat-driver/chat-driver.test.ts","../src/components/chat-driver/chat-driver.ts","../src/components/chat-driver/index.ts","../src/components/chat-interaction-wrapper/chat-interaction-wrapper.styles.ts","../src/components/chat-interaction-wrapper/chat-interaction-wrapper.template.ts","../src/components/chat-interaction-wrapper/chat-interaction-wrapper.test.ts","../src/components/chat-interaction-wrapper/chat-interaction-wrapper.ts","../src/components/chat-interaction-wrapper/index.ts","../src/components/chat-markdown/chat-markdown.ts","../src/components/chat-markdown/index.ts","../src/components/orchestrating-driver/index.ts","../src/components/orchestrating-driver/orchestrating-driver.pin.test.ts","../src/components/orchestrating-driver/orchestrating-driver.ts","../src/components/popout-manager/index.ts","../src/components/popout-manager/popout-manager.ts","../src/components/settings-modal/index.ts","../src/components/settings-modal/settings-modal.styles.ts","../src/components/settings-modal/settings-modal.template.ts","../src/config/config.ts","../src/config/define-stateful-agent.test.ts","../src/config/define-stateful-agent.ts","../src/config/fallback-agents.ts","../src/config/index.ts","../src/config/validate-providers.test.ts","../src/config/validate-providers.ts","../src/main/index.ts","../src/main/main.styles.ts","../src/main/main.template.ts","../src/main/main.ts","../src/main/main.types.ts","../src/main/popout-interaction-gate.test.ts","../src/provider/ai-provider-switcher.ts","../src/provider/assistant-app-settings.ts","../src/state/ai-assistant-slice.test.ts","../src/state/ai-assistant-slice.ts","../src/state/debug-event-log.test.ts","../src/state/debug-event-log.ts","../src/state/driver-registry.test.ts","../src/state/driver-registry.ts","../src/state/interaction-context.test.ts","../src/state/interaction-context.ts","../src/state/session-store.ts","../src/state/persistence/diagnostics-cursors.test.ts","../src/state/persistence/diagnostics-cursors.ts","../src/state/persistence/diagnostics.test.ts","../src/state/persistence/diagnostics.ts","../src/state/persistence/index.ts","../src/state/persistence/persister-registry.ts","../src/state/persistence/session-persistence-provider.test.ts","../src/state/persistence/session-persistence-provider.ts","../src/state/persistence/session-persistence.integration.test.ts","../src/state/persistence/session-persister.test.ts","../src/state/persistence/session-persister.ts","../src/state/persistence/session-snapshot.test.ts","../src/state/persistence/session-snapshot.ts","../src/state/persistence/stateful-restore.e2e.test.ts","../src/styles/ai-colours.ts","../src/suggestions/chat-suggestions.ts","../src/tags/index.ts","../src/types/ai-chat-widget.ts","../src/types/interaction-context.ts","../src/utils/animated-panel-toggle.ts","../src/utils/animation-exclusivity.test.ts","../src/utils/animation-exclusivity.ts","../src/utils/collect-session-models.test.ts","../src/utils/collect-session-models.ts","../src/utils/condense-history.test.ts","../src/utils/condense-history.ts","../src/utils/cost-session-history.test.ts","../src/utils/cost-session-history.ts","../src/utils/derive-cost-session-title.test.ts","../src/utils/derive-cost-session-title.ts","../src/utils/flatten-sub-agent-messages.test.ts","../src/utils/flatten-sub-agent-messages.ts","../src/utils/history-transform.test.ts","../src/utils/history-transform.ts","../src/utils/index.ts","../src/utils/logger.ts","../src/utils/message-partition.test.ts","../src/utils/message-partition.ts","../src/utils/resolve-cost-history-config.test.ts","../src/utils/resolve-cost-history-config.ts","../src/utils/resolve-preference-baseline.test.ts","../src/utils/resolve-preference-baseline.ts","../src/utils/strip-agent-handlers.test.ts","../src/utils/strip-agent-handlers.ts","../src/utils/sum-costs.test.ts","../src/utils/sum-costs.ts","../src/utils/sum-tokens.test.ts","../src/utils/sum-tokens.ts","../src/utils/tool-fold.ts","../src/utils/with-timeout.ts"],"version":"5.9.2"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@genesislcap/ai-assistant",
|
|
3
3
|
"description": "Genesis AI Assistant micro-frontend",
|
|
4
|
-
"version": "14.
|
|
4
|
+
"version": "14.496.0",
|
|
5
5
|
"license": "SEE LICENSE IN license.txt",
|
|
6
6
|
"main": "dist/esm/index.js",
|
|
7
7
|
"types": "dist/ai-assistant.d.ts",
|
|
@@ -27,6 +27,11 @@
|
|
|
27
27
|
"types": "./dist/dts/config/index.d.ts",
|
|
28
28
|
"default": "./dist/esm/config/index.js"
|
|
29
29
|
},
|
|
30
|
+
"./chat-driver": {
|
|
31
|
+
"types": "./dist/dts/chat-driver-node.d.ts",
|
|
32
|
+
"import": "./dist/chat-driver.mjs",
|
|
33
|
+
"require": "./dist/chat-driver.cjs"
|
|
34
|
+
},
|
|
30
35
|
"./package.json": "./package.json",
|
|
31
36
|
"./react": {
|
|
32
37
|
"types": "./dist/dts/react.d.ts",
|
|
@@ -38,11 +43,15 @@
|
|
|
38
43
|
"*": {
|
|
39
44
|
"config": [
|
|
40
45
|
"./dist/dts/config/index.d.ts"
|
|
46
|
+
],
|
|
47
|
+
"chat-driver": [
|
|
48
|
+
"./dist/dts/chat-driver-node.d.ts"
|
|
41
49
|
]
|
|
42
50
|
}
|
|
43
51
|
},
|
|
44
52
|
"scripts": {
|
|
45
|
-
"build": "genx build -b ts",
|
|
53
|
+
"build": "genx build -b ts && node ./scripts/build-chat-driver-node.mjs",
|
|
54
|
+
"build:chat-driver": "node ./scripts/build-chat-driver-node.mjs",
|
|
46
55
|
"build:webpack": "genx build",
|
|
47
56
|
"build:webpack:stats": "genx analyze",
|
|
48
57
|
"circular": "npx -y madge --extensions ts --circular ./src",
|
|
@@ -64,25 +73,26 @@
|
|
|
64
73
|
}
|
|
65
74
|
},
|
|
66
75
|
"devDependencies": {
|
|
67
|
-
"@genesislcap/foundation-testing": "14.
|
|
68
|
-
"@genesislcap/genx": "14.
|
|
69
|
-
"@genesislcap/rollup-builder": "14.
|
|
70
|
-
"@genesislcap/ts-builder": "14.
|
|
71
|
-
"@genesislcap/uvu-playwright-builder": "14.
|
|
72
|
-
"@genesislcap/vite-builder": "14.
|
|
73
|
-
"@genesislcap/webpack-builder": "14.
|
|
76
|
+
"@genesislcap/foundation-testing": "14.496.0",
|
|
77
|
+
"@genesislcap/genx": "14.496.0",
|
|
78
|
+
"@genesislcap/rollup-builder": "14.496.0",
|
|
79
|
+
"@genesislcap/ts-builder": "14.496.0",
|
|
80
|
+
"@genesislcap/uvu-playwright-builder": "14.496.0",
|
|
81
|
+
"@genesislcap/vite-builder": "14.496.0",
|
|
82
|
+
"@genesislcap/webpack-builder": "14.496.0",
|
|
74
83
|
"@types/dompurify": "^3.0.5",
|
|
75
|
-
"@types/marked": "^5.0.2"
|
|
84
|
+
"@types/marked": "^5.0.2",
|
|
85
|
+
"esbuild": "0.25.12"
|
|
76
86
|
},
|
|
77
87
|
"dependencies": {
|
|
78
|
-
"@genesislcap/foundation-ai": "14.
|
|
79
|
-
"@genesislcap/foundation-logger": "14.
|
|
80
|
-
"@genesislcap/foundation-notifications": "14.
|
|
81
|
-
"@genesislcap/foundation-redux": "14.
|
|
82
|
-
"@genesislcap/foundation-ui": "14.
|
|
83
|
-
"@genesislcap/foundation-utils": "14.
|
|
84
|
-
"@genesislcap/rapid-design-system": "14.
|
|
85
|
-
"@genesislcap/web-core": "14.
|
|
88
|
+
"@genesislcap/foundation-ai": "14.496.0",
|
|
89
|
+
"@genesislcap/foundation-logger": "14.496.0",
|
|
90
|
+
"@genesislcap/foundation-notifications": "14.496.0",
|
|
91
|
+
"@genesislcap/foundation-redux": "14.496.0",
|
|
92
|
+
"@genesislcap/foundation-ui": "14.496.0",
|
|
93
|
+
"@genesislcap/foundation-utils": "14.496.0",
|
|
94
|
+
"@genesislcap/rapid-design-system": "14.496.0",
|
|
95
|
+
"@genesislcap/web-core": "14.496.0",
|
|
86
96
|
"dompurify": "^3.3.1",
|
|
87
97
|
"marked": "^17.0.3"
|
|
88
98
|
},
|
|
@@ -95,5 +105,5 @@
|
|
|
95
105
|
"access": "public"
|
|
96
106
|
},
|
|
97
107
|
"customElements": "dist/custom-elements.json",
|
|
98
|
-
"gitHead": "
|
|
108
|
+
"gitHead": "2ae3ec60cab8440c6beb1da84e2d47239b11e9b5"
|
|
99
109
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bundles the Node-safe `./chat-driver` subpath into self-contained, Node-loadable dual output
|
|
3
|
+
* (`dist/chat-driver.mjs` + `dist/chat-driver.cjs`).
|
|
4
|
+
*
|
|
5
|
+
* Why a bundler and not just tsc: `genx build -b ts` emits bundler-target ESM (extensionless
|
|
6
|
+
* relative imports + a bare `tslib` import) that Node's own loader can't resolve. This step bundles
|
|
7
|
+
* `src/chat-driver-node.ts` and its closure (including `@genesislcap/foundation-ai`, `tslib`, and
|
|
8
|
+
* the logger) inline, so a plain Node/CommonJS host can `require`/`import` the driver stack with no
|
|
9
|
+
* bundler and no jsdom. The FAST/DOM layer is never in this entry's closure, and `foundation-ai`'s
|
|
10
|
+
* DI module (its only `@microsoft/fast-foundation` importer) tree-shakes out.
|
|
11
|
+
*
|
|
12
|
+
* Runs after `genx build -b ts` (which produces the matching `dist/dts/chat-driver-node.d.ts`).
|
|
13
|
+
*/
|
|
14
|
+
import { dirname, resolve } from 'node:path';
|
|
15
|
+
import { fileURLToPath } from 'node:url';
|
|
16
|
+
import * as esbuild from 'esbuild';
|
|
17
|
+
|
|
18
|
+
const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
|
19
|
+
const entry = resolve(packageRoot, 'src/chat-driver-node.ts');
|
|
20
|
+
|
|
21
|
+
/** @type {import('esbuild').BuildOptions} */
|
|
22
|
+
const shared = {
|
|
23
|
+
entryPoints: [entry],
|
|
24
|
+
bundle: true,
|
|
25
|
+
platform: 'node',
|
|
26
|
+
target: 'node22',
|
|
27
|
+
// Self-contained: bundle third-party deps (foundation-ai, tslib, logger) inline so the artifact
|
|
28
|
+
// is Node-loadable standalone. Node built-ins are external automatically under platform: 'node'.
|
|
29
|
+
sourcemap: 'linked',
|
|
30
|
+
logLevel: 'info',
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
await esbuild.build({
|
|
34
|
+
...shared,
|
|
35
|
+
format: 'esm',
|
|
36
|
+
outfile: resolve(packageRoot, 'dist/chat-driver.mjs'),
|
|
37
|
+
});
|
|
38
|
+
await esbuild.build({
|
|
39
|
+
...shared,
|
|
40
|
+
format: 'cjs',
|
|
41
|
+
outfile: resolve(packageRoot, 'dist/chat-driver.cjs'),
|
|
42
|
+
});
|
|
@@ -10,10 +10,37 @@ export interface AgenticActivityBusConfig {
|
|
|
10
10
|
crossTabEvents?: (keyof AgenticActivityEvents)[];
|
|
11
11
|
/** BroadcastChannel name. Only used when crossTabEvents is non-empty. */
|
|
12
12
|
channelName?: string;
|
|
13
|
+
/**
|
|
14
|
+
* Lazy alternative to {@link AgenticActivityBusConfig.channelName}: called the first
|
|
15
|
+
* time a cross-tab channel is actually needed, in a browser only. Deferring the name
|
|
16
|
+
* computation keeps side effects (e.g. `sessionStorage` reads) out of module-eval and
|
|
17
|
+
* off the non-browser path. Ignored if `channelName` is also set.
|
|
18
|
+
*/
|
|
19
|
+
channelNameFactory?: () => string;
|
|
13
20
|
}
|
|
14
21
|
|
|
15
22
|
type AnyHandler = (detail: any) => void;
|
|
16
23
|
|
|
24
|
+
/**
|
|
25
|
+
* Minimal activity-bus surface the drivers depend on. `ChatDriver`/`OrchestratingDriver`
|
|
26
|
+
* only ever *publish* — accepting this narrow interface (rather than importing the module
|
|
27
|
+
* singleton) lets a headless/server or unit-test host omit the bus entirely, so no live
|
|
28
|
+
* `BroadcastChannel` is ever opened on that path. See {@link NOOP_ACTIVITY_BUS}.
|
|
29
|
+
*
|
|
30
|
+
* @beta
|
|
31
|
+
*/
|
|
32
|
+
export interface ActivityBus {
|
|
33
|
+
publish<K extends keyof AgenticActivityEvents>(type: K, detail: AgenticActivityEvents[K]): void;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* No-op {@link ActivityBus}. The default when no bus is injected (Node, tests, headless
|
|
38
|
+
* server use) — publishing goes nowhere and nothing is left open to tear down.
|
|
39
|
+
*
|
|
40
|
+
* @beta
|
|
41
|
+
*/
|
|
42
|
+
export const NOOP_ACTIVITY_BUS: ActivityBus = { publish: () => {} };
|
|
43
|
+
|
|
17
44
|
/**
|
|
18
45
|
* Typed in-process event bus for AI assistant activity events.
|
|
19
46
|
*
|
|
@@ -31,7 +58,9 @@ type AnyHandler = (detail: any) => void;
|
|
|
31
58
|
export class AgenticActivityBus {
|
|
32
59
|
private readonly subscribers = new Map<string, Set<AnyHandler>>();
|
|
33
60
|
private readonly crossTabEvents: Set<string>;
|
|
61
|
+
private readonly channelNameFactory?: () => string;
|
|
34
62
|
private channel?: BroadcastChannel;
|
|
63
|
+
private channelInitialised = false;
|
|
35
64
|
|
|
36
65
|
/**
|
|
37
66
|
* @param config - Optional configuration. Omit to create an in-memory-only bus.
|
|
@@ -39,13 +68,28 @@ export class AgenticActivityBus {
|
|
|
39
68
|
*/
|
|
40
69
|
constructor(config?: AgenticActivityBusConfig) {
|
|
41
70
|
this.crossTabEvents = new Set(config?.crossTabEvents ?? []);
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
71
|
+
this.channelNameFactory =
|
|
72
|
+
config?.channelName != null ? () => config.channelName! : config?.channelNameFactory;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Lazily open the cross-tab `BroadcastChannel` on first use. Deferred (rather than
|
|
77
|
+
* created in the constructor) so that importing this module, or constructing the bus
|
|
78
|
+
* off-browser (Node, tests, headless server), never opens a live channel or reads
|
|
79
|
+
* `sessionStorage` — both would keep a Node event loop alive and hang the process.
|
|
80
|
+
* Cross-tab forwarding is inherently browser-only, so channel creation is gated on a
|
|
81
|
+
* browser environment; elsewhere the bus stays purely in-process.
|
|
82
|
+
*/
|
|
83
|
+
private ensureChannel(): void {
|
|
84
|
+
if (this.channelInitialised) return;
|
|
85
|
+
this.channelInitialised = true;
|
|
86
|
+
const inBrowser = typeof window !== 'undefined' && typeof BroadcastChannel !== 'undefined';
|
|
87
|
+
if (this.crossTabEvents.size === 0 || !this.channelNameFactory || !inBrowser) return;
|
|
88
|
+
this.channel = new BroadcastChannel(this.channelNameFactory());
|
|
89
|
+
this.channel.onmessage = (ev) => {
|
|
90
|
+
const { type, detail } = (ev.data ?? {}) as { type?: string; detail?: unknown };
|
|
91
|
+
if (type) this.notifyLocal(type, detail);
|
|
92
|
+
};
|
|
49
93
|
}
|
|
50
94
|
|
|
51
95
|
/**
|
|
@@ -58,6 +102,9 @@ export class AgenticActivityBus {
|
|
|
58
102
|
type: K,
|
|
59
103
|
handler: (detail: AgenticActivityEvents[K]) => void,
|
|
60
104
|
): () => void {
|
|
105
|
+
// Open the cross-tab channel (browser only) so this subscriber receives events
|
|
106
|
+
// forwarded from other tabs; no-op off-browser.
|
|
107
|
+
this.ensureChannel();
|
|
61
108
|
let handlers = this.subscribers.get(type as string);
|
|
62
109
|
if (!handlers) {
|
|
63
110
|
handlers = new Set();
|
|
@@ -76,8 +123,9 @@ export class AgenticActivityBus {
|
|
|
76
123
|
*/
|
|
77
124
|
publish<K extends keyof AgenticActivityEvents>(type: K, detail: AgenticActivityEvents[K]): void {
|
|
78
125
|
this.notifyLocal(type as string, detail);
|
|
79
|
-
if (this.crossTabEvents.has(type as string)
|
|
80
|
-
this.
|
|
126
|
+
if (this.crossTabEvents.has(type as string)) {
|
|
127
|
+
this.ensureChannel();
|
|
128
|
+
this.channel?.postMessage({ type, detail });
|
|
81
129
|
}
|
|
82
130
|
}
|
|
83
131
|
|
|
@@ -124,6 +172,9 @@ export class AgenticActivityBus {
|
|
|
124
172
|
* instances on the same origin.
|
|
125
173
|
*/
|
|
126
174
|
function getTabScopedChannelName(base: string): string {
|
|
175
|
+
// Belt-and-braces: this only runs in a browser (see `ensureChannel`), but guard anyway
|
|
176
|
+
// so a direct call off-browser never throws a `sessionStorage is not defined` ReferenceError.
|
|
177
|
+
if (typeof sessionStorage === 'undefined') return `${base}-nostorage`;
|
|
127
178
|
const key = `${base}-tab-id`;
|
|
128
179
|
let id = sessionStorage.getItem(key);
|
|
129
180
|
if (!id) {
|
|
@@ -151,5 +202,8 @@ function getTabScopedChannelName(base: string): string {
|
|
|
151
202
|
*/
|
|
152
203
|
export const agenticActivityBus = new AgenticActivityBus({
|
|
153
204
|
crossTabEvents: ['halo-start', 'halo-stop', 'tool-loop-start', 'tool-loop-end'],
|
|
154
|
-
|
|
205
|
+
// Lazy: the tab-scoped name (and its `sessionStorage` read) is computed on first
|
|
206
|
+
// cross-tab use in a browser, not at module-eval — so importing this module is
|
|
207
|
+
// side-effect-free and Node/test-safe.
|
|
208
|
+
channelNameFactory: () => getTabScopedChannelName('foundation-ai-activity'),
|
|
155
209
|
});
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { TurnFailureReason } from '@genesislcap/foundation-ai';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Event map for the AI activity bus.
|
|
3
5
|
*
|
|
@@ -59,8 +61,14 @@ export interface AgenticActivityEvents {
|
|
|
59
61
|
* spinner animation lifecycle (which can flap mid-turn as tool calls resolve), whereas
|
|
60
62
|
* this event is a one-shot per turn boundary. Use this for hooks tied to a turn ending
|
|
61
63
|
* (telemetry flushes, post-turn workspace transitions, deferred state recomputation).
|
|
64
|
+
*
|
|
65
|
+
* The detail carries the turn's outcome (PTC-0): on a failure it is `{ failureReason }`
|
|
66
|
+
* with the typed `TurnFailureReason`; on a clean completion, a user cancel, a
|
|
67
|
+
* driver dispose, and an agent handoff the detail is `undefined` — the historical shape,
|
|
68
|
+
* kept byte-identical so subscribers that only care about the boundary can keep ignoring
|
|
69
|
+
* it. Structured-cloneable so it survives the cross-tab BroadcastChannel hop.
|
|
62
70
|
*/
|
|
63
|
-
'tool-loop-end': undefined;
|
|
71
|
+
'tool-loop-end': { failureReason?: TurnFailureReason } | undefined;
|
|
64
72
|
/**
|
|
65
73
|
* Fired when a tool handler hands a widget to the user mid-loop and parks awaiting it
|
|
66
74
|
* (`requestInteraction`) — the turn is suspended between provider calls, with no request
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node-safe headless entry point for the AI assistant driver stack (`@genesislcap/ai-assistant/chat-driver`).
|
|
3
|
+
*
|
|
4
|
+
* Re-exports ONLY the framework-agnostic pieces — {@link ChatDriver}, `OrchestratingDriver`, the
|
|
5
|
+
* agent-config surface (`defineAgent`, `defineStatefulAgent`, and the config/input types), and the
|
|
6
|
+
* activity-bus types/`NOOP_ACTIVITY_BUS` — WITHOUT the DOM/FAST component layer that the package's
|
|
7
|
+
* main entry (`.`) pulls in via `main/main`. This lets a Node / CommonJS host (server, unit tests,
|
|
8
|
+
* benches) construct and drive `ChatDriver` over `foundation-ai` providers with no jsdom and no
|
|
9
|
+
* custom-element registration.
|
|
10
|
+
*
|
|
11
|
+
* Every module re-exported here is DOM-clean at import time (no `window`/`document`/`sessionStorage`
|
|
12
|
+
* eval-time access, no `@genesislcap/web-core`). The activity bus is imported for its types and the
|
|
13
|
+
* no-op default; its cross-tab `BroadcastChannel` is created lazily and only in a browser, so
|
|
14
|
+
* pulling this entry into Node opens nothing.
|
|
15
|
+
*
|
|
16
|
+
* @packageDocumentation
|
|
17
|
+
* @beta
|
|
18
|
+
*/
|
|
19
|
+
export * from './components/chat-driver';
|
|
20
|
+
export * from './components/orchestrating-driver';
|
|
21
|
+
export * from './channel/ai-activity-channel';
|
|
22
|
+
export * from './channel/ai-activity-bus';
|
|
23
|
+
export * from './config/config';
|
|
24
|
+
export * from './config/define-stateful-agent';
|
|
25
|
+
export * from './config/fallback-agents';
|
|
26
|
+
|
|
27
|
+
// Provider-construction surface, re-exported from `@genesislcap/foundation-ai` so a headless
|
|
28
|
+
// consumer builds its registry from the SAME bundled foundation-ai instance the driver uses. That
|
|
29
|
+
// shared identity matters: `ChatDriver`'s malformed/truncated handling does `instanceof` on the
|
|
30
|
+
// transports' error classes, so a second foundation-ai copy (a separate dep) would silently break
|
|
31
|
+
// those checks. NAMED re-exports only — `export *` would drag in the FAST-DI module
|
|
32
|
+
// (`@microsoft/fast-foundation` → `fast-element` → `document` at eval); by naming just these,
|
|
33
|
+
// esbuild tree-shakes the DI module out and the bundle stays Node-loadable.
|
|
34
|
+
export {
|
|
35
|
+
AnthropicProvider,
|
|
36
|
+
AnthropicTransport,
|
|
37
|
+
GeminiProvider,
|
|
38
|
+
GeminiTransport,
|
|
39
|
+
MutableAIProviderRegistry,
|
|
40
|
+
isObservableAIProviderRegistry,
|
|
41
|
+
} from '@genesislcap/foundation-ai';
|
|
42
|
+
export type {
|
|
43
|
+
AIProvider,
|
|
44
|
+
AIProviderRegistry,
|
|
45
|
+
AnthropicModelId,
|
|
46
|
+
CachePolicy,
|
|
47
|
+
ChatFallback,
|
|
48
|
+
ChatMessage,
|
|
49
|
+
ChatRequestOptions,
|
|
50
|
+
ChatToolChoice,
|
|
51
|
+
ChatToolDefinition,
|
|
52
|
+
ChatToolHandlers,
|
|
53
|
+
GeminiModelId,
|
|
54
|
+
} from '@genesislcap/foundation-ai';
|