@pie-players/pie-assessment-toolkit 0.3.74 → 0.3.75
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 +349 -313
- package/dist/attempt/TestSession.d.ts +1 -20
- package/dist/attempt/TestSession.js +8 -99
- package/dist/components/ItemScope.custom-element.d.ts +1 -0
- package/dist/components/ItemScope.custom-element.js +1 -0
- package/dist/components/ItemToolBar.custom-element.js +1 -1
- package/dist/components/PieAssessmentToolkit.custom-element.js +14 -14
- package/dist/components/SectionToolBar.custom-element.js +1 -1
- package/dist/components/chunks/ItemToolBar-7tt7v2xp.js +4 -0
- package/dist/components/chunks/{ItemToolBar-gmrryv2v.js → ItemToolBar-97hx60z4.js} +1 -1
- package/dist/components/chunks/ItemToolBar-bxwyhr5p.js +2 -0
- package/dist/components/chunks/ItemToolBar-jx38w99s.js +2 -0
- package/dist/components/chunks/ItemToolBar-rd2bb4p6.js +40 -0
- package/dist/components/chunks/ItemToolBar-vdkyn9f3.js +2 -0
- package/dist/components/chunks/sre-engine-jd8cc08x.js +1 -0
- package/dist/components/item-scope-element.d.ts +2 -0
- package/dist/components/item-scope-element.js +2 -0
- package/dist/context/assessment-toolkit-context.d.ts +27 -6
- package/dist/index.d.ts +22 -47
- package/dist/index.js +12 -36
- package/dist/policy/core/PolicySource.d.ts +1 -1
- package/dist/policy/core/ToolPolicyEngine.d.ts +77 -32
- package/dist/policy/core/ToolPolicyEngine.js +136 -46
- package/dist/policy/core/compose-decision.d.ts +28 -7
- package/dist/policy/core/compose-decision.js +75 -54
- package/dist/policy/core/decision-types.d.ts +65 -34
- package/dist/policy/core/feature-decision.d.ts +16 -9
- package/dist/policy/core/feature-decision.js +14 -8
- package/dist/policy/core/pnp-policy-inputs.d.ts +24 -33
- package/dist/policy/core/pnp-policy-inputs.js +28 -56
- package/dist/policy/core/provenance.d.ts +9 -4
- package/dist/policy/core/provenance.js +1 -1
- package/dist/policy/engine.d.ts +7 -23
- package/dist/policy/engine.js +5 -20
- package/dist/policy/sources/PnpPolicySource.d.ts +44 -61
- package/dist/policy/sources/PnpPolicySource.js +117 -118
- package/dist/runtime/SectionControllerBinding.d.ts +279 -0
- package/dist/runtime/SectionControllerBinding.js +450 -0
- package/dist/runtime/SectionRuntimeEngine.d.ts +26 -289
- package/dist/runtime/SectionRuntimeEngine.js +30 -372
- package/dist/runtime/adapter/SectionEngineAdapter.d.ts +19 -80
- package/dist/runtime/adapter/SectionEngineAdapter.js +19 -92
- package/dist/runtime/adapter/dom-event-bridge.d.ts +15 -30
- package/dist/runtime/adapter/dom-event-bridge.js +17 -44
- package/dist/runtime/adapter/subscriber-fanout.d.ts +1 -2
- package/dist/runtime/adapter/subscriber-fanout.js +1 -2
- package/dist/runtime/catalog-context.d.ts +19 -0
- package/dist/runtime/catalog-context.js +28 -0
- package/dist/runtime/composition-emit-scheduler.d.ts +9 -15
- package/dist/runtime/composition-emit-scheduler.js +9 -15
- package/dist/runtime/content-language.d.ts +32 -0
- package/dist/runtime/content-language.js +46 -0
- package/dist/runtime/content-region.d.ts +17 -0
- package/dist/runtime/content-region.js +29 -0
- package/dist/runtime/content-registration.d.ts +13 -0
- package/dist/runtime/content-registration.js +25 -0
- package/dist/runtime/core/SectionEngineCore.d.ts +2 -2
- package/dist/runtime/core/SectionEngineCore.js +2 -2
- package/dist/runtime/core/cohort.d.ts +1 -1
- package/dist/runtime/core/cohort.js +1 -1
- package/dist/runtime/core/engine-input.d.ts +18 -30
- package/dist/runtime/core/engine-input.js +11 -12
- package/dist/runtime/core/engine-output.d.ts +16 -40
- package/dist/runtime/core/engine-output.js +9 -21
- package/dist/runtime/core/engine-readiness.d.ts +5 -37
- package/dist/runtime/core/engine-readiness.js +8 -41
- package/dist/runtime/core/engine-resolver.d.ts +46 -74
- package/dist/runtime/core/engine-resolver.js +18 -43
- package/dist/runtime/core/engine-state.d.ts +28 -36
- package/dist/runtime/core/engine-state.js +18 -21
- package/dist/runtime/core/engine-transition.d.ts +14 -19
- package/dist/runtime/core/engine-transition.js +71 -51
- package/dist/runtime/engine.d.ts +16 -19
- package/dist/runtime/engine.js +12 -19
- package/dist/runtime/page-warnings.d.ts +13 -0
- package/dist/runtime/page-warnings.js +22 -0
- package/dist/runtime/policy-input-forwarding.d.ts +25 -0
- package/dist/runtime/policy-input-forwarding.js +25 -0
- package/dist/runtime/registration-events.d.ts +11 -0
- package/dist/runtime/runtime-event-claim.d.ts +8 -0
- package/dist/runtime/runtime-event-claim.js +15 -0
- package/dist/runtime/shell-event-bridge.d.ts +45 -0
- package/dist/runtime/shell-event-bridge.js +127 -0
- package/dist/runtime/shell-registration.d.ts +73 -0
- package/dist/runtime/shell-registration.js +95 -0
- package/dist/runtime/shell-scope.d.ts +68 -0
- package/dist/runtime/shell-scope.js +188 -0
- package/dist/runtime/tool-host-contract.d.ts +8 -10
- package/dist/runtime/tool-host-contract.js +11 -11
- package/dist/runtime/unclaimed-registration-watch.d.ts +7 -0
- package/dist/runtime/unclaimed-registration-watch.js +23 -0
- package/dist/services/ElementToolStateStore.d.ts +14 -10
- package/dist/services/ElementToolStateStore.js +37 -13
- package/dist/services/HighlightCoordinator.d.ts +21 -21
- package/dist/services/HighlightCoordinator.js +431 -325
- package/dist/services/RangeSerializer.d.ts +10 -1
- package/dist/services/RangeSerializer.js +87 -14
- package/dist/services/TTSService.d.ts +117 -70
- package/dist/services/TTSService.js +668 -578
- package/dist/services/ToolCoordinator.d.ts +43 -60
- package/dist/services/ToolCoordinator.js +164 -206
- package/dist/services/ToolRegistry.d.ts +74 -57
- package/dist/services/ToolRegistry.js +104 -114
- package/dist/services/ToolkitCoordinator.d.ts +183 -189
- package/dist/services/ToolkitCoordinator.js +477 -431
- package/dist/services/audio-handoff.d.ts +6 -7
- package/dist/services/audio-handoff.js +20 -14
- package/dist/services/catalog-owner.d.ts +0 -1
- package/dist/services/framework-error-bus.d.ts +3 -6
- package/dist/services/framework-error-bus.js +3 -6
- package/dist/services/framework-error.d.ts +22 -7
- package/dist/services/framework-error.js +9 -7
- package/dist/services/interfaces.d.ts +158 -129
- package/dist/services/section-session-assignment.d.ts +21 -0
- package/dist/services/section-session-assignment.js +82 -0
- package/dist/services/spoken-audio-cards.d.ts +0 -2
- package/dist/services/spoken-audio-cards.js +0 -2
- package/dist/services/tool-config-defaults.d.ts +3 -3
- package/dist/services/tool-config-defaults.js +3 -3
- package/dist/services/tool-config-validation.d.ts +4 -5
- package/dist/services/tool-config-validation.js +36 -61
- package/dist/services/tool-context.d.ts +0 -8
- package/dist/services/tool-context.js +0 -12
- package/dist/services/tool-icons.d.ts +4 -3
- package/dist/services/tool-icons.js +4 -3
- package/dist/services/tool-instance-id.d.ts +0 -1
- package/dist/services/tool-instance-id.js +0 -6
- package/dist/services/tool-providers/TTSToolProvider.d.ts +18 -19
- package/dist/services/tool-providers/TTSToolProvider.js +37 -34
- package/dist/services/tool-providers/ToolProviderApi.d.ts +10 -4
- package/dist/services/tool-providers/ToolProviderRegistry.d.ts +30 -26
- package/dist/services/tool-providers/ToolProviderRegistry.js +119 -93
- package/dist/services/tool-request.d.ts +27 -12
- package/dist/services/tool-request.js +24 -14
- package/dist/services/toolbar-decided-tools.d.ts +15 -0
- package/dist/services/toolbar-decided-tools.js +28 -0
- package/dist/services/tools-config-normalizer.d.ts +17 -22
- package/dist/services/tools-config-normalizer.js +2 -10
- package/dist/services/tts/browser-provider.d.ts +38 -2
- package/dist/services/tts/browser-provider.js +276 -140
- package/dist/services/tts/flat-tree.d.ts +71 -0
- package/dist/services/tts/flat-tree.js +269 -0
- package/dist/services/tts/generated-speech/assemble-plan.d.ts +3 -1
- package/dist/services/tts/generated-speech/assemble-plan.js +3 -1
- package/dist/services/tts/generated-speech/dom/build-dom-plan.d.ts +2 -0
- package/dist/services/tts/generated-speech/dom/build-dom-plan.js +1 -1
- package/dist/services/tts/generated-speech/math-speech-cache.d.ts +3 -1
- package/dist/services/tts/generated-speech/math-speech-cache.js +5 -1
- package/dist/services/tts/highlight-pipeline/create-highlight-plan.js +12 -4
- package/dist/services/tts/highlight-pipeline/prose-boundary-resolver.js +6 -4
- package/dist/services/tts/highlight-pipeline/readable-region.js +3 -2
- package/dist/services/tts/highlight-pipeline/types.d.ts +5 -0
- package/dist/services/tts/highlight-pipeline/visible-map-range.d.ts +12 -0
- package/dist/services/tts/highlight-pipeline/visible-map-range.js +73 -7
- package/dist/services/tts/math-aware-text-processing.d.ts +5 -1
- package/dist/services/tts/math-aware-text-processing.js +32 -18
- package/dist/services/tts/math-control-names.d.ts +21 -0
- package/dist/services/tts/math-control-names.js +142 -0
- package/dist/services/tts/math-speech.d.ts +11 -0
- package/dist/services/tts/math-speech.js +51 -18
- package/dist/services/tts/provider-options.d.ts +41 -0
- package/dist/services/tts/provider-options.js +1 -0
- package/dist/services/tts/ssml/spoken-text.d.ts +2 -26
- package/dist/services/tts/ssml/spoken-text.js +29 -0
- package/dist/services/tts/start-failure.d.ts +11 -0
- package/dist/services/tts/start-failure.js +19 -0
- package/dist/services/tts/text-processing.d.ts +9 -0
- package/dist/services/tts/text-processing.js +46 -33
- package/dist/services/tts/text-segmentation.d.ts +7 -0
- package/dist/services/tts/text-segmentation.js +47 -0
- package/dist/services/tts-runtime-config.d.ts +25 -17
- package/dist/services/tts-runtime-config.js +16 -95
- package/dist/tools/content-capability-resolution.d.ts +7 -9
- package/dist/tools/content-capability-resolution.js +8 -45
- package/dist/tools/registration.d.ts +58 -0
- package/dist/tools/registration.js +54 -0
- package/dist/tools/registrations/toolbar-registration-helpers.js +2 -2
- package/dist/tools/tool-surface-host.d.ts +6 -10
- package/dist/tools/tool-surface-host.js +44 -42
- package/dist/tools/tool-tag-map.d.ts +5 -15
- package/dist/tools/tool-tag-map.js +6 -20
- package/dist/utils/structural-equality.d.ts +11 -0
- package/dist/utils/structural-equality.js +47 -0
- package/package.json +13 -29
- package/dist/attempt/adapters/activity-to-test-attempt-session.d.ts +0 -49
- package/dist/attempt/adapters/activity-to-test-attempt-session.js +0 -138
- package/dist/components/chunks/ItemToolBar-b9dz5jvd.js +0 -40
- package/dist/components/chunks/ItemToolBar-h4xap0t0.js +0 -4
- package/dist/components/chunks/ItemToolBar-wr2myaah.js +0 -2
- package/dist/components/chunks/sre-engine-wf9s43gg.js +0 -1
- package/dist/context/runtime-context-consumer.d.ts +0 -13
- package/dist/context/runtime-context-consumer.js +0 -18
- package/dist/item-loader.d.ts +0 -44
- package/dist/item-loader.js +0 -61
- package/dist/policy/core/engine-context.d.ts +0 -29
- package/dist/policy/core/engine-context.js +0 -27
- package/dist/policy/core/policy-source-tag.d.ts +0 -31
- package/dist/policy/core/policy-source-tag.js +0 -28
- package/dist/policy/internal.d.ts +0 -25
- package/dist/policy/internal.js +0 -25
- package/dist/runtime/adapter/coordinator-bridge.d.ts +0 -92
- package/dist/runtime/adapter/coordinator-bridge.js +0 -126
- package/dist/runtime/adapter/framework-error-bridge.d.ts +0 -36
- package/dist/runtime/adapter/framework-error-bridge.js +0 -46
- package/dist/runtime/adapter/instrumentation-bridge.d.ts +0 -31
- package/dist/runtime/adapter/instrumentation-bridge.js +0 -38
- package/dist/runtime/core/engine-stage-derivation.d.ts +0 -18
- package/dist/runtime/core/engine-stage-derivation.js +0 -29
- package/dist/runtime/engine-context.d.ts +0 -39
- package/dist/runtime/engine-context.js +0 -31
- package/dist/runtime/internal.d.ts +0 -43
- package/dist/runtime/internal.js +0 -45
- package/dist/runtime/section-runtime-engine-host-context.d.ts +0 -74
- package/dist/runtime/section-runtime-engine-host-context.js +0 -57
- package/dist/runtime/stage-emit-gate.d.ts +0 -92
- package/dist/runtime/stage-emit-gate.js +0 -82
- package/dist/services/I18nService.d.ts +0 -47
- package/dist/services/I18nService.js +0 -84
- package/dist/services/ThemeProvider.d.ts +0 -95
- package/dist/services/ThemeProvider.js +0 -334
- package/dist/services/defaultPersonalNeedsProfile.d.ts +0 -21
- package/dist/services/defaultPersonalNeedsProfile.js +0 -26
- package/dist/services/pnp-standard-features.d.ts +0 -238
- package/dist/services/pnp-standard-features.js +0 -338
- package/dist/tools/client.d.ts +0 -10
- package/dist/tools/client.js +0 -10
- package/dist/tools/internal.d.ts +0 -44
- package/dist/tools/internal.js +0 -39
|
@@ -8,13 +8,13 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import type { ToolProviderApi, ToolCategory } from "./ToolProviderApi.js";
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
11
|
+
* What `register` takes: the provider, its config, and how it starts.
|
|
12
12
|
*/
|
|
13
|
-
export interface
|
|
13
|
+
export interface ToolProviderRegistration<TConfig = any> {
|
|
14
14
|
/**
|
|
15
15
|
* Provider instance to register
|
|
16
16
|
*/
|
|
17
|
-
provider: ToolProviderApi
|
|
17
|
+
provider: ToolProviderApi;
|
|
18
18
|
/**
|
|
19
19
|
* Configuration for this provider
|
|
20
20
|
* (may include auth credentials, endpoints, etc.)
|
|
@@ -54,14 +54,16 @@ export interface ToolProviderConfig<TConfig = any> {
|
|
|
54
54
|
* - Registration
|
|
55
55
|
* - Lazy initialization
|
|
56
56
|
* - Auth credential fetching
|
|
57
|
-
* - Provider lookup by
|
|
57
|
+
* - Provider lookup by tool id or category
|
|
58
|
+
*
|
|
59
|
+
* The toolkit coordinator registers each provider under its tool's id.
|
|
58
60
|
*
|
|
59
61
|
* @example
|
|
60
62
|
* ```typescript
|
|
61
63
|
* const registry = new ToolProviderRegistry();
|
|
62
64
|
*
|
|
63
65
|
* // Register a provider with auth fetcher
|
|
64
|
-
* registry.register('
|
|
66
|
+
* registry.register('calculator', {
|
|
65
67
|
* provider: new ExampleToolProvider(),
|
|
66
68
|
* config: {},
|
|
67
69
|
* lazy: true,
|
|
@@ -72,7 +74,7 @@ export interface ToolProviderConfig<TConfig = any> {
|
|
|
72
74
|
* });
|
|
73
75
|
*
|
|
74
76
|
* // Get provider (auto-initializes if lazy)
|
|
75
|
-
* const provider = await registry.getProvider('
|
|
77
|
+
* const provider = await registry.getProvider('calculator');
|
|
76
78
|
* ```
|
|
77
79
|
*/
|
|
78
80
|
export declare class ToolProviderRegistry {
|
|
@@ -85,23 +87,28 @@ export declare class ToolProviderRegistry {
|
|
|
85
87
|
* Register a tool provider
|
|
86
88
|
*
|
|
87
89
|
* Adds a provider to the registry. If lazy is false, initializes immediately.
|
|
90
|
+
* A registration under an id already registered replaces it: the replaced
|
|
91
|
+
* provider is destroyed once a start in progress settles, and a caller
|
|
92
|
+
* waiting on that start gets the replacement.
|
|
88
93
|
*
|
|
89
|
-
* @param
|
|
94
|
+
* @param toolId Id of the tool the provider serves
|
|
90
95
|
* @param config Provider configuration
|
|
91
|
-
* @throws Error if provider with same ID already registered
|
|
92
96
|
*/
|
|
93
|
-
register(
|
|
97
|
+
register(toolId: string, config: ToolProviderRegistration): void;
|
|
94
98
|
/**
|
|
95
99
|
* Initialize a provider
|
|
96
100
|
*
|
|
97
101
|
* Fetches auth if needed and initializes the provider.
|
|
98
102
|
* Safe to call multiple times - subsequent calls wait for first initialization.
|
|
99
103
|
*
|
|
100
|
-
* @param
|
|
104
|
+
* @param toolId Tool whose provider to initialize
|
|
101
105
|
* @returns Promise that resolves when initialization complete
|
|
102
106
|
* @throws Error if provider not registered or initialization fails
|
|
103
107
|
*/
|
|
104
|
-
initialize(
|
|
108
|
+
initialize(toolId: string): Promise<void>;
|
|
109
|
+
/** Whether a registration replaced `provider` under `toolId`. */
|
|
110
|
+
private isReplaced;
|
|
111
|
+
private destroyProvider;
|
|
105
112
|
/**
|
|
106
113
|
* Internal initialization logic
|
|
107
114
|
*/
|
|
@@ -112,54 +119,51 @@ export declare class ToolProviderRegistry {
|
|
|
112
119
|
* Retrieves a registered provider. If autoInitialize is true and provider
|
|
113
120
|
* is not initialized, initializes it first.
|
|
114
121
|
*
|
|
115
|
-
* @param
|
|
122
|
+
* @param toolId Id of the tool the provider serves
|
|
116
123
|
* @param autoInitialize Auto-initialize if not ready (default: true)
|
|
117
124
|
* @returns Provider instance
|
|
118
125
|
* @throws Error if provider not registered
|
|
119
126
|
*/
|
|
120
|
-
getProvider<T extends ToolProviderApi = ToolProviderApi>(
|
|
127
|
+
getProvider<T extends ToolProviderApi = ToolProviderApi>(toolId: string, autoInitialize?: boolean): Promise<T>;
|
|
121
128
|
/**
|
|
122
|
-
*
|
|
129
|
+
* The ids of the tools whose provider is in `category`.
|
|
123
130
|
*
|
|
124
131
|
* @param category Tool category to filter by
|
|
125
|
-
* @returns Array of provider IDs in the category
|
|
126
132
|
*/
|
|
127
133
|
getProvidersByCategory(category: ToolCategory): string[];
|
|
128
134
|
/**
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
* @returns Array of all provider IDs
|
|
135
|
+
* The ids of the tools with a registered provider.
|
|
132
136
|
*/
|
|
133
137
|
getProviderIds(): string[];
|
|
134
138
|
/**
|
|
135
139
|
* Check if provider is registered
|
|
136
140
|
*
|
|
137
|
-
* @param
|
|
141
|
+
* @param toolId Id of the tool the provider serves
|
|
138
142
|
* @returns true if provider is registered
|
|
139
143
|
*/
|
|
140
|
-
has(
|
|
144
|
+
has(toolId: string): boolean;
|
|
141
145
|
/**
|
|
142
146
|
* Check if provider is initialized
|
|
143
147
|
*
|
|
144
|
-
* @param
|
|
148
|
+
* @param toolId Id of the tool the provider serves
|
|
145
149
|
* @returns true if provider is initialized
|
|
146
150
|
*/
|
|
147
|
-
isInitialized(
|
|
151
|
+
isInitialized(toolId: string): boolean;
|
|
148
152
|
/**
|
|
149
153
|
* Check if provider is currently initializing
|
|
150
154
|
*
|
|
151
|
-
* @param
|
|
155
|
+
* @param toolId Id of the tool the provider serves
|
|
152
156
|
* @returns true if initialization in progress
|
|
153
157
|
*/
|
|
154
|
-
isInitializing(
|
|
158
|
+
isInitializing(toolId: string): boolean;
|
|
155
159
|
/**
|
|
156
160
|
* Unregister and destroy a provider
|
|
157
161
|
*
|
|
158
162
|
* Removes the provider from the registry and calls its destroy method.
|
|
159
163
|
*
|
|
160
|
-
* @param
|
|
164
|
+
* @param toolId Tool whose provider to unregister
|
|
161
165
|
*/
|
|
162
|
-
unregister(
|
|
166
|
+
unregister(toolId: string): Promise<void>;
|
|
163
167
|
/**
|
|
164
168
|
* Clean up all providers
|
|
165
169
|
*
|
|
@@ -6,6 +6,9 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Part of PIE Assessment Toolkit.
|
|
8
8
|
*/
|
|
9
|
+
import { createPieLogger, isGlobalDebugEnabled, } from "@pie-players/pie-players-shared/pie";
|
|
10
|
+
// Lifecycle lines need `window.PIE_DEBUG = true`, read on each line.
|
|
11
|
+
const logger = createPieLogger("ToolProviderRegistry", isGlobalDebugEnabled);
|
|
9
12
|
/**
|
|
10
13
|
* Tool Provider Registry
|
|
11
14
|
*
|
|
@@ -13,14 +16,16 @@
|
|
|
13
16
|
* - Registration
|
|
14
17
|
* - Lazy initialization
|
|
15
18
|
* - Auth credential fetching
|
|
16
|
-
* - Provider lookup by
|
|
19
|
+
* - Provider lookup by tool id or category
|
|
20
|
+
*
|
|
21
|
+
* The toolkit coordinator registers each provider under its tool's id.
|
|
17
22
|
*
|
|
18
23
|
* @example
|
|
19
24
|
* ```typescript
|
|
20
25
|
* const registry = new ToolProviderRegistry();
|
|
21
26
|
*
|
|
22
27
|
* // Register a provider with auth fetcher
|
|
23
|
-
* registry.register('
|
|
28
|
+
* registry.register('calculator', {
|
|
24
29
|
* provider: new ExampleToolProvider(),
|
|
25
30
|
* config: {},
|
|
26
31
|
* lazy: true,
|
|
@@ -31,7 +36,7 @@
|
|
|
31
36
|
* });
|
|
32
37
|
*
|
|
33
38
|
* // Get provider (auto-initializes if lazy)
|
|
34
|
-
* const provider = await registry.getProvider('
|
|
39
|
+
* const provider = await registry.getProvider('calculator');
|
|
35
40
|
* ```
|
|
36
41
|
*/
|
|
37
42
|
export class ToolProviderRegistry {
|
|
@@ -51,24 +56,35 @@ export class ToolProviderRegistry {
|
|
|
51
56
|
* Register a tool provider
|
|
52
57
|
*
|
|
53
58
|
* Adds a provider to the registry. If lazy is false, initializes immediately.
|
|
59
|
+
* A registration under an id already registered replaces it: the replaced
|
|
60
|
+
* provider is destroyed once a start in progress settles, and a caller
|
|
61
|
+
* waiting on that start gets the replacement.
|
|
54
62
|
*
|
|
55
|
-
* @param
|
|
63
|
+
* @param toolId Id of the tool the provider serves
|
|
56
64
|
* @param config Provider configuration
|
|
57
|
-
* @throws Error if provider with same ID already registered
|
|
58
65
|
*/
|
|
59
|
-
register(
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
66
|
+
register(toolId, config) {
|
|
67
|
+
const replaced = this.providers.get(toolId);
|
|
68
|
+
const replacedStart = this.initializationPromises.get(toolId);
|
|
69
|
+
this.providers.set(toolId, config.provider);
|
|
70
|
+
this.configs.set(toolId, config);
|
|
71
|
+
this.initialized.set(toolId, false);
|
|
72
|
+
this.initializationPromises.delete(toolId);
|
|
73
|
+
if (replaced) {
|
|
74
|
+
if (replacedStart) {
|
|
75
|
+
void replacedStart
|
|
76
|
+
.catch(() => { })
|
|
77
|
+
.then(() => this.destroyProvider(toolId, replaced));
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
this.destroyProvider(toolId, replaced);
|
|
81
|
+
}
|
|
63
82
|
}
|
|
64
|
-
|
|
65
|
-
this.configs.set(providerId, config);
|
|
66
|
-
this.initialized.set(providerId, false);
|
|
67
|
-
console.log(`[ToolProviderRegistry] Registered provider "${providerId}" (${config.provider.providerName})`);
|
|
83
|
+
logger.debug(`${replaced ? "Replaced" : "Registered"} provider "${toolId}" (${config.provider.providerName})`);
|
|
68
84
|
// Initialize immediately if not lazy
|
|
69
85
|
if (config.lazy === false) {
|
|
70
|
-
this.initialize(
|
|
71
|
-
console.error(`[ToolProviderRegistry] Failed to initialize provider "${
|
|
86
|
+
this.initialize(toolId).catch((error) => {
|
|
87
|
+
console.error(`[ToolProviderRegistry] Failed to initialize provider "${toolId}":`, error);
|
|
72
88
|
});
|
|
73
89
|
}
|
|
74
90
|
}
|
|
@@ -78,60 +94,73 @@ export class ToolProviderRegistry {
|
|
|
78
94
|
* Fetches auth if needed and initializes the provider.
|
|
79
95
|
* Safe to call multiple times - subsequent calls wait for first initialization.
|
|
80
96
|
*
|
|
81
|
-
* @param
|
|
97
|
+
* @param toolId Tool whose provider to initialize
|
|
82
98
|
* @returns Promise that resolves when initialization complete
|
|
83
99
|
* @throws Error if provider not registered or initialization fails
|
|
84
100
|
*/
|
|
85
|
-
async initialize(
|
|
101
|
+
async initialize(toolId) {
|
|
86
102
|
// Already initialized
|
|
87
|
-
if (this.initialized.get(
|
|
103
|
+
if (this.initialized.get(toolId)) {
|
|
88
104
|
return;
|
|
89
105
|
}
|
|
90
106
|
// Initialization in progress - wait for it
|
|
91
|
-
const existingPromise = this.initializationPromises.get(
|
|
107
|
+
const existingPromise = this.initializationPromises.get(toolId);
|
|
92
108
|
if (existingPromise) {
|
|
93
109
|
return existingPromise;
|
|
94
110
|
}
|
|
95
111
|
// Start new initialization
|
|
96
|
-
const
|
|
97
|
-
this.
|
|
112
|
+
const provider = this.providers.get(toolId);
|
|
113
|
+
const initPromise = this._doInitialize(toolId);
|
|
114
|
+
this.initializationPromises.set(toolId, initPromise);
|
|
98
115
|
try {
|
|
99
116
|
await initPromise;
|
|
100
117
|
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
if (!this.isReplaced(toolId, provider))
|
|
120
|
+
throw error;
|
|
121
|
+
}
|
|
101
122
|
finally {
|
|
102
|
-
this.initializationPromises.
|
|
123
|
+
if (this.initializationPromises.get(toolId) === initPromise) {
|
|
124
|
+
this.initializationPromises.delete(toolId);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (this.isReplaced(toolId, provider)) {
|
|
128
|
+
return this.initialize(toolId);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/** Whether a registration replaced `provider` under `toolId`. */
|
|
132
|
+
isReplaced(toolId, provider) {
|
|
133
|
+
const current = this.providers.get(toolId);
|
|
134
|
+
return current !== undefined && current !== provider;
|
|
135
|
+
}
|
|
136
|
+
destroyProvider(toolId, provider) {
|
|
137
|
+
try {
|
|
138
|
+
provider.destroy();
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
console.warn(`[ToolProviderRegistry] Failed to destroy provider "${toolId}":`, error);
|
|
103
142
|
}
|
|
104
143
|
}
|
|
105
144
|
/**
|
|
106
145
|
* Internal initialization logic
|
|
107
146
|
*/
|
|
108
|
-
async _doInitialize(
|
|
109
|
-
const provider = this.providers.get(
|
|
110
|
-
const config = this.configs.get(
|
|
147
|
+
async _doInitialize(toolId) {
|
|
148
|
+
const provider = this.providers.get(toolId);
|
|
149
|
+
const config = this.configs.get(toolId);
|
|
111
150
|
if (!provider || !config) {
|
|
112
|
-
throw new Error(`[ToolProviderRegistry] Provider "${
|
|
151
|
+
throw new Error(`[ToolProviderRegistry] Provider "${toolId}" not registered`);
|
|
113
152
|
}
|
|
114
153
|
// Start with base config
|
|
115
154
|
let providerConfig = { ...config.config };
|
|
116
155
|
const deriveBackend = (value) => {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
? typed.backend
|
|
122
|
-
: typeof typed.provider === "string"
|
|
123
|
-
? typed.provider
|
|
124
|
-
: typeof typed.serverProvider === "string"
|
|
125
|
-
? typed.serverProvider
|
|
126
|
-
: typeof typed.providerId === "string"
|
|
127
|
-
? typed.providerId
|
|
128
|
-
: "";
|
|
129
|
-
return direct || "unknown";
|
|
156
|
+
const backend = value && typeof value === "object"
|
|
157
|
+
? value.backend
|
|
158
|
+
: undefined;
|
|
159
|
+
return typeof backend === "string" && backend ? backend : "unknown";
|
|
130
160
|
};
|
|
131
161
|
const providerInitStartedAt = Date.now();
|
|
132
162
|
await this.emitTelemetry(config, "pie-tool-init-start", {
|
|
133
|
-
toolId
|
|
134
|
-
providerId,
|
|
163
|
+
toolId,
|
|
135
164
|
backend: deriveBackend(providerConfig),
|
|
136
165
|
operation: "provider-initialize",
|
|
137
166
|
});
|
|
@@ -139,18 +168,16 @@ export class ToolProviderRegistry {
|
|
|
139
168
|
if (provider.requiresAuth && config.authFetcher) {
|
|
140
169
|
const authFetchStartedAt = Date.now();
|
|
141
170
|
await this.emitTelemetry(config, "pie-tool-backend-call-start", {
|
|
142
|
-
toolId
|
|
143
|
-
providerId,
|
|
171
|
+
toolId,
|
|
144
172
|
backend: deriveBackend(providerConfig),
|
|
145
173
|
operation: "auth-fetch",
|
|
146
174
|
});
|
|
147
|
-
|
|
175
|
+
logger.debug(`Fetching auth for "${toolId}"...`);
|
|
148
176
|
try {
|
|
149
177
|
const authData = await config.authFetcher();
|
|
150
178
|
providerConfig = { ...providerConfig, ...authData };
|
|
151
179
|
await this.emitTelemetry(config, "pie-tool-backend-call-success", {
|
|
152
|
-
toolId
|
|
153
|
-
providerId,
|
|
180
|
+
toolId,
|
|
154
181
|
backend: deriveBackend(providerConfig),
|
|
155
182
|
operation: "auth-fetch",
|
|
156
183
|
duration: Date.now() - authFetchStartedAt,
|
|
@@ -158,42 +185,41 @@ export class ToolProviderRegistry {
|
|
|
158
185
|
}
|
|
159
186
|
catch (error) {
|
|
160
187
|
await this.emitTelemetry(config, "pie-tool-backend-call-error", {
|
|
161
|
-
toolId
|
|
162
|
-
providerId,
|
|
188
|
+
toolId,
|
|
163
189
|
backend: deriveBackend(providerConfig),
|
|
164
190
|
operation: "auth-fetch",
|
|
165
191
|
duration: Date.now() - authFetchStartedAt,
|
|
166
192
|
errorType: "ProviderAuthFetchError",
|
|
167
193
|
message: error instanceof Error ? error.message : String(error),
|
|
168
194
|
});
|
|
169
|
-
console.error(`[ToolProviderRegistry] Auth fetch failed for "${
|
|
170
|
-
throw new Error(`Failed to fetch auth credentials for provider "${
|
|
195
|
+
console.error(`[ToolProviderRegistry] Auth fetch failed for "${toolId}":`, error);
|
|
196
|
+
throw new Error(`Failed to fetch auth credentials for provider "${toolId}"`);
|
|
171
197
|
}
|
|
172
198
|
}
|
|
173
199
|
// Initialize provider
|
|
174
200
|
try {
|
|
175
201
|
await provider.initialize(providerConfig);
|
|
176
|
-
this.
|
|
202
|
+
if (this.providers.get(toolId) === provider) {
|
|
203
|
+
this.initialized.set(toolId, true);
|
|
204
|
+
}
|
|
177
205
|
await this.emitTelemetry(config, "pie-tool-init-success", {
|
|
178
|
-
toolId
|
|
179
|
-
providerId,
|
|
206
|
+
toolId,
|
|
180
207
|
backend: deriveBackend(providerConfig),
|
|
181
208
|
operation: "provider-initialize",
|
|
182
209
|
duration: Date.now() - providerInitStartedAt,
|
|
183
210
|
});
|
|
184
|
-
|
|
211
|
+
logger.debug(`Provider "${toolId}" initialized`);
|
|
185
212
|
}
|
|
186
213
|
catch (error) {
|
|
187
214
|
await this.emitTelemetry(config, "pie-tool-init-error", {
|
|
188
|
-
toolId
|
|
189
|
-
providerId,
|
|
215
|
+
toolId,
|
|
190
216
|
backend: deriveBackend(providerConfig),
|
|
191
217
|
operation: "provider-initialize",
|
|
192
218
|
duration: Date.now() - providerInitStartedAt,
|
|
193
219
|
errorType: "ProviderInitializationError",
|
|
194
220
|
message: error instanceof Error ? error.message : String(error),
|
|
195
221
|
});
|
|
196
|
-
console.error(`[ToolProviderRegistry] Initialization failed for "${
|
|
222
|
+
console.error(`[ToolProviderRegistry] Initialization failed for "${toolId}":`, error);
|
|
197
223
|
throw error;
|
|
198
224
|
}
|
|
199
225
|
}
|
|
@@ -203,32 +229,31 @@ export class ToolProviderRegistry {
|
|
|
203
229
|
* Retrieves a registered provider. If autoInitialize is true and provider
|
|
204
230
|
* is not initialized, initializes it first.
|
|
205
231
|
*
|
|
206
|
-
* @param
|
|
232
|
+
* @param toolId Id of the tool the provider serves
|
|
207
233
|
* @param autoInitialize Auto-initialize if not ready (default: true)
|
|
208
234
|
* @returns Provider instance
|
|
209
235
|
* @throws Error if provider not registered
|
|
210
236
|
*/
|
|
211
|
-
async getProvider(
|
|
212
|
-
const provider = this.providers.get(
|
|
237
|
+
async getProvider(toolId, autoInitialize = true) {
|
|
238
|
+
const provider = this.providers.get(toolId);
|
|
213
239
|
if (!provider) {
|
|
214
240
|
console.error("[ToolProviderRegistry] Provider not found:", {
|
|
215
|
-
requestedId:
|
|
241
|
+
requestedId: toolId,
|
|
216
242
|
availableProviders: Array.from(this.providers.keys()),
|
|
217
243
|
});
|
|
218
|
-
throw new Error(`[ToolProviderRegistry] Provider "${
|
|
244
|
+
throw new Error(`[ToolProviderRegistry] Provider "${toolId}" not registered`);
|
|
219
245
|
}
|
|
220
246
|
// Auto-initialize if needed
|
|
221
|
-
if (autoInitialize && !this.initialized.get(
|
|
222
|
-
|
|
223
|
-
await this.initialize(
|
|
247
|
+
if (autoInitialize && !this.initialized.get(toolId)) {
|
|
248
|
+
logger.debug("Auto-initializing provider:", toolId);
|
|
249
|
+
await this.initialize(toolId);
|
|
224
250
|
}
|
|
225
251
|
return provider;
|
|
226
252
|
}
|
|
227
253
|
/**
|
|
228
|
-
*
|
|
254
|
+
* The ids of the tools whose provider is in `category`.
|
|
229
255
|
*
|
|
230
256
|
* @param category Tool category to filter by
|
|
231
|
-
* @returns Array of provider IDs in the category
|
|
232
257
|
*/
|
|
233
258
|
getProvidersByCategory(category) {
|
|
234
259
|
return Array.from(this.providers.entries())
|
|
@@ -236,9 +261,7 @@ export class ToolProviderRegistry {
|
|
|
236
261
|
.map(([id]) => id);
|
|
237
262
|
}
|
|
238
263
|
/**
|
|
239
|
-
*
|
|
240
|
-
*
|
|
241
|
-
* @returns Array of all provider IDs
|
|
264
|
+
* The ids of the tools with a registered provider.
|
|
242
265
|
*/
|
|
243
266
|
getProviderIds() {
|
|
244
267
|
return Array.from(this.providers.keys());
|
|
@@ -246,42 +269,42 @@ export class ToolProviderRegistry {
|
|
|
246
269
|
/**
|
|
247
270
|
* Check if provider is registered
|
|
248
271
|
*
|
|
249
|
-
* @param
|
|
272
|
+
* @param toolId Id of the tool the provider serves
|
|
250
273
|
* @returns true if provider is registered
|
|
251
274
|
*/
|
|
252
|
-
has(
|
|
253
|
-
return this.providers.has(
|
|
275
|
+
has(toolId) {
|
|
276
|
+
return this.providers.has(toolId);
|
|
254
277
|
}
|
|
255
278
|
/**
|
|
256
279
|
* Check if provider is initialized
|
|
257
280
|
*
|
|
258
|
-
* @param
|
|
281
|
+
* @param toolId Id of the tool the provider serves
|
|
259
282
|
* @returns true if provider is initialized
|
|
260
283
|
*/
|
|
261
|
-
isInitialized(
|
|
262
|
-
return this.initialized.get(
|
|
284
|
+
isInitialized(toolId) {
|
|
285
|
+
return this.initialized.get(toolId) === true;
|
|
263
286
|
}
|
|
264
287
|
/**
|
|
265
288
|
* Check if provider is currently initializing
|
|
266
289
|
*
|
|
267
|
-
* @param
|
|
290
|
+
* @param toolId Id of the tool the provider serves
|
|
268
291
|
* @returns true if initialization in progress
|
|
269
292
|
*/
|
|
270
|
-
isInitializing(
|
|
271
|
-
return this.initializationPromises.has(
|
|
293
|
+
isInitializing(toolId) {
|
|
294
|
+
return this.initializationPromises.has(toolId);
|
|
272
295
|
}
|
|
273
296
|
/**
|
|
274
297
|
* Unregister and destroy a provider
|
|
275
298
|
*
|
|
276
299
|
* Removes the provider from the registry and calls its destroy method.
|
|
277
300
|
*
|
|
278
|
-
* @param
|
|
301
|
+
* @param toolId Tool whose provider to unregister
|
|
279
302
|
*/
|
|
280
|
-
async unregister(
|
|
281
|
-
const provider = this.providers.get(
|
|
303
|
+
async unregister(toolId) {
|
|
304
|
+
const provider = this.providers.get(toolId);
|
|
282
305
|
if (provider) {
|
|
283
306
|
// Wait for any pending initialization
|
|
284
|
-
const initPromise = this.initializationPromises.get(
|
|
307
|
+
const initPromise = this.initializationPromises.get(toolId);
|
|
285
308
|
if (initPromise) {
|
|
286
309
|
try {
|
|
287
310
|
await initPromise;
|
|
@@ -289,15 +312,18 @@ export class ToolProviderRegistry {
|
|
|
289
312
|
catch {
|
|
290
313
|
// Ignore initialization errors during unregister
|
|
291
314
|
}
|
|
315
|
+
// A provider registered meanwhile owns the slot, and register()
|
|
316
|
+
// already destroys this one once its start settles.
|
|
317
|
+
if (this.providers.get(toolId) !== provider)
|
|
318
|
+
return;
|
|
292
319
|
}
|
|
293
|
-
|
|
294
|
-
provider.destroy();
|
|
320
|
+
this.destroyProvider(toolId, provider);
|
|
295
321
|
// Remove from registry
|
|
296
|
-
this.providers.delete(
|
|
297
|
-
this.configs.delete(
|
|
298
|
-
this.initialized.delete(
|
|
299
|
-
this.initializationPromises.delete(
|
|
300
|
-
|
|
322
|
+
this.providers.delete(toolId);
|
|
323
|
+
this.configs.delete(toolId);
|
|
324
|
+
this.initialized.delete(toolId);
|
|
325
|
+
this.initializationPromises.delete(toolId);
|
|
326
|
+
logger.debug(`Unregistered provider "${toolId}"`);
|
|
301
327
|
}
|
|
302
328
|
}
|
|
303
329
|
/**
|
|
@@ -306,8 +332,8 @@ export class ToolProviderRegistry {
|
|
|
306
332
|
* Unregisters and destroys all providers in the registry.
|
|
307
333
|
*/
|
|
308
334
|
async destroy() {
|
|
309
|
-
const
|
|
310
|
-
await Promise.all(
|
|
311
|
-
|
|
335
|
+
const toolIds = Array.from(this.providers.keys());
|
|
336
|
+
await Promise.all(toolIds.map((id) => this.unregister(id)));
|
|
337
|
+
logger.debug("Registry destroyed");
|
|
312
338
|
}
|
|
313
339
|
}
|
|
@@ -42,17 +42,26 @@ export interface ToolOpenRequest {
|
|
|
42
42
|
* to match a placement made elsewhere is a step it has no reason to expect.
|
|
43
43
|
*
|
|
44
44
|
* At `"item"` and `"passage"` a section holds one target per card, and the first
|
|
45
|
-
* registered one that hosts the tool claims the request
|
|
46
|
-
*
|
|
47
|
-
* does not need to: the strip is a section-scoped singleton acting on passage
|
|
48
|
-
* selections, so the selection belongs to no card, and what opens is a floating
|
|
49
|
-
* shell rather than anything rendered inside one.
|
|
45
|
+
* registered one that hosts the tool claims the request unless `scopeId` names
|
|
46
|
+
* the card.
|
|
50
47
|
*/
|
|
51
48
|
level?: ToolPlacementLevel;
|
|
49
|
+
/**
|
|
50
|
+
* Scope of the toolbar that should open the tool: the item's canonical id for
|
|
51
|
+
* an item toolbar, the section id for a section toolbar. A constraint like
|
|
52
|
+
* `level`, for a requester that belongs to one card, as an inline control in an
|
|
53
|
+
* item does. Only a target registered with the same `scopeId` claims it.
|
|
54
|
+
*/
|
|
55
|
+
scopeId?: string;
|
|
52
56
|
}
|
|
53
57
|
export interface ToolRequestTarget {
|
|
54
58
|
/** The placement level this toolbar renders. */
|
|
55
59
|
level: ToolPlacementLevel;
|
|
60
|
+
/**
|
|
61
|
+
* The scope this toolbar renders for, matched against a request's `scopeId`.
|
|
62
|
+
* A target without one claims only requests that name no scope.
|
|
63
|
+
*/
|
|
64
|
+
readonly scopeId?: string;
|
|
56
65
|
/** Whether this toolbar currently renders the tool, per its own policy pass. */
|
|
57
66
|
hostsTool: (toolId: string) => boolean;
|
|
58
67
|
/**
|
|
@@ -80,16 +89,17 @@ export declare class ToolRequestRegistry {
|
|
|
80
89
|
* nothing is worse than an absent one, and availability moves with policy —
|
|
81
90
|
* hence {@link onTargetsChange}.
|
|
82
91
|
*/
|
|
83
|
-
canRequest(toolId: string, level?: ToolPlacementLevel): boolean;
|
|
92
|
+
canRequest(toolId: string, level?: ToolPlacementLevel, scopeId?: string): boolean;
|
|
84
93
|
/** Returns whether a target claimed the request. */
|
|
85
94
|
request(request: ToolOpenRequest): boolean;
|
|
86
95
|
/**
|
|
87
|
-
* Fires when a toolbar registers or unregisters
|
|
96
|
+
* Fires when a toolbar registers or unregisters, and on
|
|
97
|
+
* {@link notifyTargetsChange}.
|
|
88
98
|
*
|
|
89
|
-
* Not when a registered toolbar's
|
|
90
|
-
* live, so a caller re-asking `canRequest` gets the current answer. A
|
|
91
|
-
* that needs to notice a policy change should also follow the policy
|
|
92
|
-
* already has.
|
|
99
|
+
* Not when a policy change moves a registered toolbar's visible set: `hostsTool`
|
|
100
|
+
* is read live, so a caller re-asking `canRequest` gets the current answer. A
|
|
101
|
+
* surface that needs to notice a policy change should also follow the policy
|
|
102
|
+
* signal it already has.
|
|
93
103
|
*/
|
|
94
104
|
onTargetsChange(listener: () => void): () => void;
|
|
95
105
|
/**
|
|
@@ -102,6 +112,11 @@ export declare class ToolRequestRegistry {
|
|
|
102
112
|
private findTarget;
|
|
103
113
|
private findTargetAtLevel;
|
|
104
114
|
private hostsTool;
|
|
105
|
-
|
|
115
|
+
/**
|
|
116
|
+
* Tell change listeners that what the targets can claim changed. Registration
|
|
117
|
+
* calls it, and so does the coordinator when a target stops hosting a tool
|
|
118
|
+
* outside a policy change, as when the tool's module fails to load.
|
|
119
|
+
*/
|
|
120
|
+
notifyTargetsChange(): void;
|
|
106
121
|
dispose(): void;
|
|
107
122
|
}
|