@salsita-ai/sdk 0.50.0-develop.c33986dc44 → 0.50.0-develop.ca5894b56c
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 +1 -1
- package/dist/application-spec/core/enhanced-json-value.d.ts +2 -31
- package/dist/application-spec/core/enhanced-json-value.js +1 -1
- package/dist/application-spec/core/index.d.ts +1 -3
- package/dist/application-spec/core/index.js +1 -1
- package/dist/application-spec/core/json-schema.d.ts +2 -52
- package/dist/application-spec/core/markers/index.d.ts +1 -1
- package/dist/application-spec/core/markers/index.js +1 -1
- package/dist/application-spec/core/markers/msg-marker.d.ts +2 -28
- package/dist/application-spec/core/markers/msg-marker.js +1 -1
- package/dist/application-spec/core/markers/raw-eval-write-marker.d.ts +1 -1
- package/dist/application-spec/core/markers/raw-eval-write-marker.js +1 -1
- package/dist/application-spec/core/markers/raw-read-write-marker.js +1 -1
- package/dist/application-spec/errors/diagnostic-codes.d.ts +1 -0
- package/dist/application-spec/errors/diagnostic-codes.js +1 -1
- package/dist/application-spec/errors/diagnostic-messages.d.ts +1 -0
- package/dist/application-spec/errors/diagnostic-messages.js +1 -1
- package/dist/application-spec/generate-application/code/project-scaffolding.js +2 -2
- package/dist/application-spec/generate-application/code/templates/index.d.ts +2 -6
- package/dist/application-spec/generate-application/code/templates/index.js +1 -1
- package/dist/application-spec/generate-application/code/templates/skills/phoenix-skill-bundle.d.ts +10 -0
- package/dist/application-spec/generate-application/code/templates/skills/phoenix-skill-bundle.js +7 -0
- package/dist/application-spec/generate-application/code/templates/skills/phoenix-skill.js +1 -1
- package/dist/application-spec/generate-application/code/templates/skills/sdk-content.d.ts +1 -1
- package/dist/application-spec/generate-application/code/templates/skills/sdk-content.js +1 -1
- package/dist/application-spec/generate-application/runtime/factory-data/factory-data-runtime.d.ts +2 -2
- package/dist/application-spec/generate-application/runtime/factory-data/recipe-defaults.d.ts +1 -1
- package/dist/application-spec/generate-application/runtime/factory-data/recipe-defaults.js +1 -1
- package/dist/application-spec/generate-application/runtime/factory-data/static-violations.d.ts +1 -1
- package/dist/application-spec/generate-application/runtime/factory-data/static-violations.js +1 -1
- package/dist/application-spec/generate-application/runtime/generate-runtime-instance.d.ts +1 -1
- package/dist/application-spec/generate-application/runtime/generate-runtime-instance.js +1 -1
- package/dist/application-spec/generate-application/runtime/sections/build-sdk-optic.js +1 -1
- package/dist/application-spec/generate-application/runtime/sections/expression-runtime.d.ts +1 -1
- package/dist/application-spec/generate-application/runtime/sections/expression-runtime.js +1 -1
- package/dist/application-spec/generate-application/runtime/sections/generate-memo-eval-plan-runtime.d.ts +1 -1
- package/dist/application-spec/generate-application/runtime/sections/generate-memo-eval-plan-runtime.js +1 -1
- package/dist/application-spec/generate-application/runtime/sections/preset-runtime.d.ts +2 -3
- package/dist/application-spec/generate-application/runtime/sections/reflection-constants-runtime.d.ts +2 -1
- package/dist/application-spec/generate-application/runtime/spec-code/resolve-spec-code.d.ts +1 -1
- package/dist/application-spec/parse-application-files/parse-application-files.js +1 -1
- package/dist/application-spec/parse-application-files/raw-spec/raw-expressions.d.ts +1 -1
- package/dist/application-spec/parse-application-files/raw-spec/raw-expressions.js +1 -1
- package/dist/application-spec/parse-application-files/spec/model/aliases.d.ts +3 -9
- package/dist/application-spec/parse-application-files/spec/model/common-types.d.ts +6 -14
- package/dist/application-spec/parse-application-files/spec/model/defaults.d.ts +6 -31
- package/dist/application-spec/parse-application-files/spec/model/entity-types.d.ts +3 -8
- package/dist/application-spec/parse-application-files/spec/model/model-version-key.d.ts +3 -3
- package/dist/application-spec/parse-application-files/spec/model/names/action-name.d.ts +3 -7
- package/dist/application-spec/parse-application-files/spec/model/names/alias-name.d.ts +3 -7
- package/dist/application-spec/parse-application-files/spec/model/names/entity-or-alias-name.d.ts +3 -8
- package/dist/application-spec/parse-application-files/spec/model/names/entity-type-name.d.ts +3 -8
- package/dist/application-spec/parse-application-files/spec/model/names/expression-name.d.ts +3 -6
- package/dist/application-spec/parse-application-files/spec/model/names/instance-name.d.ts +3 -7
- package/dist/application-spec/parse-application-files/spec/model/names/invariant-name.d.ts +3 -3
- package/dist/application-spec/parse-application-files/spec/model/names/shape-property-name.d.ts +3 -11
- package/dist/application-spec/parse-application-files/spec/model/names/violation-type-name.d.ts +3 -3
- package/dist/application-spec/parse-application-files/spec/model/presets.d.ts +6 -29
- package/dist/client/authorized-client.d.ts +3 -1
- package/dist/client/authorized-client.js +1 -1
- package/dist/client/contract.d.ts +17 -0
- package/dist/client/index.d.ts +1 -1
- package/dist/client/local-authorized-client.d.ts +3 -1
- package/dist/client/local-authorized-client.js +1 -1
- package/dist/client/memory-authorized-client.d.ts +4 -1
- package/dist/client/memory-authorized-client.js +1 -1
- package/dist/client/phoenix-api.d.ts +228 -0
- package/dist/configurator/ConfiguratorApp.js +1 -1
- package/dist/configurator/application-runtime/extensions/selectors.js +1 -1
- package/dist/configurator/application-runtime/extensions/systems/assistant-system/assistant-system.d.ts +13 -0
- package/dist/configurator/application-runtime/extensions/systems/assistant-system/assistant-system.js +1 -1
- package/dist/configurator/application-runtime/extensions/systems/assistant-system/graphql-tools.d.ts +2 -1
- package/dist/configurator/application-runtime/extensions/systems/assistant-system/graphql-tools.js +1 -1
- package/dist/configurator/application-runtime/extensions/systems/graphql-system/graphql-system.d.ts +15 -9
- package/dist/configurator/application-runtime/extensions/systems/graphql-system/graphql-system.js +1 -1
- package/dist/configurator/common/configurator-interface.d.ts +2 -2
- package/dist/configurator/common/configurator-interface.js +1 -1
- package/dist/configurator/configurator-context/ConfiguratorDataProvider.js +1 -1
- package/dist/configurator/configurator-context/PresetSelectionProvider.js +1 -1
- package/dist/configurator/configurator-context/configurator-hooks/index.d.ts +0 -1
- package/dist/configurator/configurator-context/configurator-hooks/index.js +1 -1
- package/dist/configurator/configurator-context/index.d.ts +0 -4
- package/dist/configurator/configurator-context/index.js +1 -1
- package/dist/configurator/pages/ConfiguratorNotFoundPage.js +1 -1
- package/dist/configurator/pages/LoadedConfiguratorDetailPage.js +1 -1
- package/dist/configurator/pages/error-boundaries/DevContextFallback.js +1 -1
- package/dist/configurator/pages/error-boundaries/DevLoadingFallback.js +1 -1
- package/dist/configurator/ui/assistant/screenshots/ScreenshotThumbnails.d.ts +1 -1
- package/dist/configurator/ui/assistant/screenshots/ScreenshotThumbnails.js +1 -1
- package/dist/configurator/ui/assistant/screenshots/tool-screenshots.d.ts +12 -4
- package/dist/configurator/ui/assistant/screenshots/tool-screenshots.js +1 -1
- package/dist/configurator/ui/assistant/screenshots/use-screenshot-src.d.ts +8 -0
- package/dist/configurator/ui/assistant/screenshots/use-screenshot-src.js +1 -0
- package/dist/configurator/ui/configurator-layout/slots/canvas/GPUAccelerationDisabled.js +1 -1
- package/dist/configurator/ui/configurator-layout/slots/canvas/WebGLNotSupported.js +1 -1
- package/dist/configurator/ui/configurator-layout/slots/readonly-banner/CloneToEditDialog.js +1 -1
- package/dist/configurator/ui/legacy/chat/MobileChat.js +1 -1
- package/dist/configurator/ui/legacy/layout/common/CommonTopNavigation.js +1 -1
- package/dist/configurator/ui/legacy/layout/simple/SimpleSidebar.js +1 -1
- package/dist/configurator/ui/legacy/layout/simple/SimpleTopNavigation.js +1 -1
- package/dist/configurator/ui/legacy/layout/steps/StepsNavigation.js +1 -1
- package/dist/configurator/ui/legacy/layout/steps/StepsOwnerLayout.js +1 -1
- package/dist/configurator/ui/legacy/layout/steps/StepsSideBar.js +1 -1
- package/dist/configurator/ui/legacy/layout/tabs/TabsSidebar.js +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/header/common/back-button/use-go-back-action.js +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/header/common/step-navigation/StepsNavigation.js +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/sidebar-footer/common/PreviousStepButton.js +1 -1
- package/dist/docs/3d-scene/cameras/custom.mdx +4 -2
- package/dist/docs/index.json +1 -1
- package/dist/docs/phoenix/domain-model.mdx +4 -1
- package/dist/docs/phoenix/phoenix-cli.mdx +14 -6
- package/dist/docs/phoenix/project-structure.mdx +21 -17
- package/dist/docs/phoenix/sdk-builder-workflow.mdx +2 -2
- package/dist/docs/phoenix/webhooks.mdx +5 -1
- package/dist/domain/application/assistant/build-assistant-manifest.js +1 -1
- package/dist/domain/application/assistant/generate-assistant-prompt.js +1 -1
- package/dist/domain/index.d.ts +1 -0
- package/dist/domain/index.js +1 -1
- package/dist/domain/spec/application/index.d.ts +1 -0
- package/dist/domain/spec/application/index.js +1 -0
- package/dist/{application-spec/core → domain/spec}/components/component-filter.d.ts +3 -2
- package/dist/domain/spec/enhanced-json-value.d.ts +30 -0
- package/dist/domain/spec/enhanced-json-value.js +1 -0
- package/dist/domain/spec/index.d.ts +7 -0
- package/dist/domain/spec/index.js +1 -0
- package/dist/domain/spec/json-schema.d.ts +52 -0
- package/dist/domain/spec/json-schema.js +1 -0
- package/dist/domain/spec/markers/index.d.ts +2 -0
- package/dist/domain/spec/markers/index.js +1 -0
- package/dist/domain/spec/markers/msg-marker.d.ts +28 -0
- package/dist/domain/spec/markers/msg-marker.js +1 -0
- package/dist/domain/spec/model/aliases.d.ts +9 -0
- package/dist/domain/spec/model/aliases.js +1 -0
- package/dist/domain/spec/model/common-types.d.ts +15 -0
- package/dist/domain/spec/model/common-types.js +1 -0
- package/dist/domain/spec/model/defaults.d.ts +33 -0
- package/dist/domain/spec/model/defaults.js +1 -0
- package/dist/domain/spec/model/entity-types.d.ts +8 -0
- package/dist/domain/spec/model/entity-types.js +1 -0
- package/dist/domain/spec/model/index.d.ts +7 -0
- package/dist/domain/spec/model/index.js +1 -0
- package/dist/domain/spec/model/model-version-key.d.ts +3 -0
- package/dist/domain/spec/model/model-version-key.js +1 -0
- package/dist/domain/spec/model/names/action-name.d.ts +7 -0
- package/dist/domain/spec/model/names/action-name.js +1 -0
- package/dist/domain/spec/model/names/alias-name.d.ts +7 -0
- package/dist/domain/spec/model/names/alias-name.js +1 -0
- package/dist/domain/spec/model/names/entity-or-alias-name.d.ts +8 -0
- package/dist/domain/spec/model/names/entity-or-alias-name.js +1 -0
- package/dist/domain/spec/model/names/entity-type-name.d.ts +8 -0
- package/dist/domain/spec/model/names/entity-type-name.js +1 -0
- package/dist/domain/spec/model/names/expression-name.d.ts +6 -0
- package/dist/domain/spec/model/names/expression-name.js +1 -0
- package/dist/domain/spec/model/names/index.d.ts +9 -0
- package/dist/domain/spec/model/names/index.js +1 -0
- package/dist/domain/spec/model/names/instance-name.d.ts +7 -0
- package/dist/domain/spec/model/names/instance-name.js +1 -0
- package/dist/domain/spec/model/names/invariant-name.d.ts +3 -0
- package/dist/domain/spec/model/names/invariant-name.js +1 -0
- package/dist/domain/spec/model/names/shape-property-name.d.ts +11 -0
- package/dist/domain/spec/model/names/shape-property-name.js +1 -0
- package/dist/domain/spec/model/names/violation-type-name.d.ts +3 -0
- package/dist/domain/spec/model/names/violation-type-name.js +1 -0
- package/dist/domain/spec/model/presets.d.ts +30 -0
- package/dist/domain/spec/model/presets.js +1 -0
- package/dist/phoenix/application-spec/generate-application-spec-project.d.ts +1 -0
- package/dist/phoenix/application-spec/generate-application-spec-project.js +2 -2
- package/dist/phoenix/application-spec/generate-project-files.d.ts +1 -0
- package/dist/phoenix/application-spec/index.d.ts +1 -0
- package/dist/phoenix/application-spec/index.js +1 -1
- package/dist/phoenix/application-spec/resolve-deployment-data.d.ts +11 -0
- package/dist/phoenix/application-spec/resolve-deployment-data.js +2 -2
- package/dist/phoenix/bin.js +1 -1
- package/dist/phoenix/cli.js +1 -1
- package/dist/phoenix/commands/build.js +1 -1
- package/dist/phoenix/commands/clean.js +1 -1
- package/dist/phoenix/commands/deploy.js +1 -1
- package/dist/phoenix/commands/dev.js +5 -5
- package/dist/phoenix/commands/generated-env-markers.d.ts +1 -0
- package/dist/phoenix/commands/generated-env-markers.js +1 -1
- package/dist/phoenix/commands/index.d.ts +1 -1
- package/dist/phoenix/commands/index.js +1 -1
- package/dist/phoenix/commands/sync.js +1 -1
- package/dist/phoenix/lingui/index.d.ts +1 -0
- package/dist/phoenix/lingui/index.js +1 -0
- package/dist/phoenix/{services → lingui}/lingui.d.ts +5 -2
- package/dist/phoenix/lingui/lingui.js +1 -0
- package/dist/phoenix/services/application-spec-project-watcher.d.ts +3 -1
- package/dist/phoenix/services/application-spec-project-watcher.js +2 -2
- package/dist/phoenix/services/index.d.ts +1 -0
- package/dist/phoenix/services/index.js +1 -1
- package/dist/phoenix/services/lingui-watcher.js +1 -1
- package/dist/phoenix/services/prepare-development-environment.js +1 -1
- package/dist/phoenix/services/vite-config.js +1 -1
- package/dist/react-sdk/application-runtime/domain-application-context/chat-system.d.ts +1 -1
- package/dist/{configurator/configurator-context → react-sdk}/configurator-routing/ConfiguratorRoutingProvider.d.ts +1 -1
- package/dist/react-sdk/configurator-routing/ConfiguratorRoutingProvider.js +1 -0
- package/dist/{configurator/configurator-context → react-sdk}/configurator-routing/OnGoToIndexHandler.d.ts +1 -2
- package/dist/react-sdk/configurator-routing/OnGoToIndexHandler.js +1 -0
- package/dist/react-sdk/configurator-routing/index.d.ts +3 -0
- package/dist/{configurator/configurator-context → react-sdk}/configurator-routing/index.js +1 -1
- package/dist/{configurator/configurator-context → react-sdk}/configurator-routing/use-power-routing-lifecycle.d.ts +2 -0
- package/dist/react-sdk/configurator-routing/use-power-routing-lifecycle.js +1 -0
- package/dist/react-sdk/domain-application-context/OnPresetLoadedHandler.js +1 -0
- package/dist/react-sdk/domain-application-context/chat-hooks.d.ts +4 -0
- package/dist/react-sdk/domain-application-context/chat-hooks.js +1 -0
- package/dist/react-sdk/domain-application-context/index.d.ts +2 -0
- package/dist/react-sdk/domain-application-context/index.js +1 -1
- package/dist/react-sdk/index.d.ts +3 -0
- package/dist/react-sdk/index.js +1 -1
- package/dist/react-sdk/integration/IntegrationSubscription.js +1 -0
- package/dist/react-sdk/integration/index.d.ts +1 -0
- package/dist/react-sdk/integration/index.js +1 -0
- package/dist/react-sdk/lifecycle-providers/LifecycleProviders.js +1 -0
- package/dist/react-sdk/lifecycle-providers/index.d.ts +1 -0
- package/dist/react-sdk/lifecycle-providers/index.js +1 -0
- package/package.json +3 -3
- package/dist/configurator/configurator-context/IntegrationSubscription.js +0 -1
- package/dist/configurator/configurator-context/LifecycleProviders.js +0 -1
- package/dist/configurator/configurator-context/OnPresetLoadedHandler.js +0 -1
- package/dist/configurator/configurator-context/configurator-hooks/chat-hooks.d.ts +0 -1
- package/dist/configurator/configurator-context/configurator-hooks/chat-hooks.js +0 -1
- package/dist/configurator/configurator-context/configurator-routing/ConfiguratorRoutingProvider.js +0 -1
- package/dist/configurator/configurator-context/configurator-routing/OnGoToIndexHandler.js +0 -1
- package/dist/configurator/configurator-context/configurator-routing/index.d.ts +0 -2
- package/dist/configurator/configurator-context/configurator-routing/use-power-routing-lifecycle.js +0 -1
- package/dist/phoenix/services/lingui.js +0 -1
- /package/dist/{application-spec/core → domain/spec/application}/application-instance.d.ts +0 -0
- /package/dist/{application-spec/core → domain/spec/application}/application-instance.js +0 -0
- /package/dist/{application-spec/core → domain/spec}/components/component-filter.js +0 -0
- /package/dist/{application-spec/core → domain/spec}/components/index.d.ts +0 -0
- /package/dist/{application-spec/core → domain/spec}/components/index.js +0 -0
- /package/dist/{application-spec/core → domain/spec}/components/sdk-code-ref.d.ts +0 -0
- /package/dist/{application-spec/core → domain/spec}/components/sdk-code-ref.js +0 -0
- /package/dist/{application-spec/core → domain/spec}/expressions/index.d.ts +0 -0
- /package/dist/{application-spec/core → domain/spec}/expressions/index.js +0 -0
- /package/dist/{application-spec/core → domain/spec}/expressions/relation-expression-params.d.ts +0 -0
- /package/dist/{application-spec/core → domain/spec}/expressions/relation-expression-params.js +0 -0
- /package/dist/{application-spec/core → domain/spec}/expressions/sdk-expression-implementation.d.ts +0 -0
- /package/dist/{application-spec/core → domain/spec}/expressions/sdk-expression-implementation.js +0 -0
- /package/dist/{application-spec/core → domain/spec}/markers/eval-marker.d.ts +0 -0
- /package/dist/{application-spec/core → domain/spec}/markers/eval-marker.js +0 -0
- /package/dist/{configurator/configurator-context → react-sdk/domain-application-context}/OnPresetLoadedHandler.d.ts +0 -0
- /package/dist/{configurator/configurator-context → react-sdk/integration}/IntegrationSubscription.d.ts +0 -0
- /package/dist/{configurator/configurator-context → react-sdk/lifecycle-providers}/LifecycleProviders.d.ts +0 -0
package/dist/application-spec/parse-application-files/spec/model/names/violation-type-name.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ViolationTypeName as ViolationTypeNameData } from '#package/domain';
|
|
2
2
|
import type { ParseContext } from '../../../../core/index.js';
|
|
3
|
-
/** A
|
|
4
|
-
export type ViolationTypeName =
|
|
3
|
+
/** A branded violation type name; see {@link ViolationTypeNameData | ViolationTypeName} in `domain`. */
|
|
4
|
+
export type ViolationTypeName = ViolationTypeNameData;
|
|
5
5
|
export declare const ViolationTypeName: (name: string, ctx: ParseContext) => ViolationTypeName | undefined;
|
|
@@ -1,37 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { Presets as PresetsData, SpecPreset } from '#package/domain';
|
|
2
2
|
import type { ParseContext } from '../../../core/index.js';
|
|
3
3
|
import type { MergedPresets } from '../../merge/index.js';
|
|
4
4
|
import type { RawPreset } from '../../raw-spec/index.js';
|
|
5
5
|
import type { Relations } from '../relations/index.js';
|
|
6
6
|
import type { ModelVersion } from './model-version.js';
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
*/
|
|
11
|
-
export type
|
|
12
|
-
readonly id: string;
|
|
13
|
-
readonly type: string;
|
|
14
|
-
readonly properties: Readonly<Record<string, unknown>>;
|
|
15
|
-
}>;
|
|
16
|
-
/**
|
|
17
|
-
* A single parsed preset — the root entity type, initial entities, and optional metadata.
|
|
18
|
-
* Represents one initial configuration state for a configurator deployment.
|
|
19
|
-
*/
|
|
20
|
-
export type Preset = Branded<'Preset', {
|
|
21
|
-
readonly rootEntityType: string;
|
|
22
|
-
readonly initialDomainEntities: readonly PresetEntity[];
|
|
23
|
-
readonly name?: string;
|
|
24
|
-
readonly description?: string;
|
|
25
|
-
readonly img?: string;
|
|
26
|
-
readonly imgAlt?: string;
|
|
27
|
-
readonly detailTitle?: string;
|
|
28
|
-
readonly detailDescription?: string;
|
|
29
|
-
readonly tags?: readonly string[];
|
|
30
|
-
}>;
|
|
31
|
-
/** All parsed presets for a parsed configurator or admin model. */
|
|
32
|
-
export type Presets = Branded<'Presets', {
|
|
33
|
-
readonly presets: readonly Preset[];
|
|
34
|
-
}>;
|
|
7
|
+
export type { PresetEntity } from '#package/domain';
|
|
8
|
+
/** The parsed preset; see {@link SpecPreset} in `domain`. */
|
|
9
|
+
export type Preset = SpecPreset;
|
|
10
|
+
/** The parsed presets of a domain; see {@link PresetsData | Presets} in `domain`. */
|
|
11
|
+
export type Presets = PresetsData;
|
|
35
12
|
export declare const Preset: (raw: RawPreset, latestModel: ModelVersion, relations: Relations, ctx: ParseContext) => Preset | undefined;
|
|
36
13
|
/**
|
|
37
14
|
* Parses and validates merged presets against the domain model.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AccessLevel } from '@salsita-ai/contracts/api';
|
|
2
2
|
import { type ChatStreamChunk } from '@salsita-ai/contracts/chat';
|
|
3
|
-
import { type AssistantChatConnection, type AssistantEarlierThread, type AssistantThreadCompaction, type AuthorizedPhoenixApiClient, type ChatToolCall, type ChatToolCallResult, type ConfigurationPayload, type ConfigurationSchema, type waitForFinalizationResultSettings } from './contract.js';
|
|
3
|
+
import { type AssistantChatConnection, type AssistantEarlierThread, type AssistantImageUpload, type AssistantThreadCompaction, type AuthorizedPhoenixApiClient, type ChatToolCall, type ChatToolCallResult, type ConfigurationPayload, type ConfigurationSchema, type waitForFinalizationResultSettings } from './contract.js';
|
|
4
4
|
import type { components } from './phoenix-api.js';
|
|
5
5
|
export declare class AuthorizedClient<FINALIZE_DATA extends Record<string, unknown>, FINALIZE_RESULT extends Record<string, unknown>, FRONTEND_DATA extends Record<string, unknown>> implements AuthorizedPhoenixApiClient<FINALIZE_DATA, FINALIZE_RESULT, FRONTEND_DATA> {
|
|
6
6
|
private readonly _baseUrl;
|
|
@@ -28,6 +28,8 @@ export declare class AuthorizedClient<FINALIZE_DATA extends Record<string, unkno
|
|
|
28
28
|
getAssistantChatConnection: (configurationId: string) => AssistantChatConnection;
|
|
29
29
|
compactAssistantThread: (configurationId: string) => Promise<AssistantThreadCompaction>;
|
|
30
30
|
getAssistantEarlierThread: (configurationId: string, threadId: string, limit: number) => Promise<AssistantEarlierThread>;
|
|
31
|
+
uploadAssistantImage: (configurationId: string, image: Blob) => Promise<AssistantImageUpload>;
|
|
32
|
+
getAssistantImage: (configurationId: string, imageId: string) => Promise<Blob>;
|
|
31
33
|
sendMessage: (configurationId: string, content: string, context?: Record<string, string>) => Promise<ReadableStream<ChatStreamChunk>>;
|
|
32
34
|
sendToolCallResults: (configurationId: string, calls: ChatToolCall[], results: ChatToolCallResult[], agent?: string) => Promise<ReadableStream<ChatStreamChunk>>;
|
|
33
35
|
generateShareLink: (configurationId: string, revisionId: string, expiration: number, access: AccessLevel, baseUrl: string | undefined) => Promise<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{match as t}from"ts-pattern";import{InfoError as a}from"@salsita-ai/common/utils";import{isChatError as e}from"@salsita-ai/contracts/chat";import{createApiBaseClient as r}from"./base-client.js";import{AssistantRequestError as i,InvalidAccessKeyError as
|
|
1
|
+
import{match as t}from"ts-pattern";import{InfoError as a}from"@salsita-ai/common/utils";import{isChatError as e}from"@salsita-ai/contracts/chat";import{createApiBaseClient as r}from"./base-client.js";import{AssistantRequestError as i,InvalidAccessKeyError as s}from"./contract.js";let o=()=>new TransformStream({transform(t,a){a.enqueue(t)}}),n=async(t,a)=>{for(;;){let{done:r,value:i}=await t.read();if(r){await a.close();break}for(let t of i.split("\n").filter(t=>""!==t.trim()).map(t=>JSON.parse(t))){if(e(t))return void await a.abort(Error(t.error));await a.write(t)}}},h=(e,r)=>{let i=`${r} API request failed: ${JSON.stringify(e)}`;return t(e).with({statusCode:403,invalidAccessKey:!0},()=>new s).with({statusCode:403},()=>new a(i)).otherwise(()=>Error(i))};export class AuthorizedClient{_baseUrl;_getAccessToken;_getSessionToken;_client;constructor(t,a,e){this._baseUrl=t,this._getAccessToken=a,this._getSessionToken=e,this._client=r(this._baseUrl)}_authHeaders=async()=>{let t=this._getAccessToken(),a=await this._getSessionToken();return{"X-Access-Key":t,Authorization:`Bearer ${a}`}};getConfiguration=async t=>{let a=await this._authHeaders(),e=await this._client.GET("/configurations/{configurationId}",{params:{path:{configurationId:t}},headers:a});if(e.error)throw h(e.error,"getConfiguration");return e.data};updateConfiguration=async(t,a)=>{let e=await this._authHeaders(),r=await this._client.PUT("/configurations/{configurationId}",{params:{path:{configurationId:t}},body:a,headers:e});if(r.error)throw h(r.error,"updateConfiguration");return r.data};finalize=async(t,a,e,r,i)=>{let s=await this._authHeaders(),o=await this._client.POST("/configurations/{configurationId}/{finalizationUuid}/finalize",{params:{path:{configurationId:t,finalizationUuid:a},query:{locale:r}},body:{finalizeData:e,frontendData:i},headers:s});if(o.error)throw h(o.error,"finalize")};waitForFinalizationToComplete=async(t,a,e)=>{let r=e?.pollingFrequency??500,i=Math.ceil((e?.pollingTimeout??3e4)/r);for(let e=0;e<i;e++){let e=await this._authHeaders(),i=await this._client.GET("/configurations/{configurationId}/{finalizationUuid}/state",{params:{path:{configurationId:t,finalizationUuid:a}},headers:e});if(i.error)throw h(i.error,"getFinalizeJobState");let s=i.data;if("completed"===s.state)return s.result[0];if("failed"===s.state)throw Error("finalization failed");if("unknown"===s.state)throw Error("finalization state is unknown");await new Promise(t=>setTimeout(t,r))}throw Error("finalization did not complete within the specified timeout")};getConfigurationRevision=async(t,a)=>{let e=await this._authHeaders(),r=await this._client.GET("/configurations/{configurationId}/revisions/{revisionId}",{params:{path:{configurationId:t,revisionId:a}},headers:e});if(r.error)throw h(r.error,"getConfigurationRevision");return r.data};getChatConversation=async t=>{let a=await this._authHeaders(),e=await this._client.GET("/configurations/{configurationId}/chat",{params:{path:{configurationId:t}},headers:a});if(e.error)throw h(e.error,"getChatConversation");return e.data};getSpeechToText=async(t,a)=>{let e=await this._authHeaders(),r=new FormData;r.append("voiceFile",a,"voice.wav");let i=await this._client.POST("/configurations/{configurationId}/chat/stt",{params:{path:{configurationId:t}},headers:e,body:r,bodySerializer:()=>r});if(i.error)throw h(i.error,"getSpeechToText");return i.data.text};getTextToSpeech=async(t,a)=>{let e=await this._authHeaders(),r=await this._client.POST("/configurations/{configurationId}/chat/tts",{params:{path:{configurationId:t}},body:{content:a},headers:e,parseAs:"arrayBuffer"});if(r.error)throw h(r.error,"getTextToSpeech");return new Blob([r.data],{type:"audio/mp3"})};getAssistantChatConnection=t=>({url:new URL(`configurations/${encodeURIComponent(t)}/assistant/chat`,`${this._baseUrl}/`).toString(),headers:this._authHeaders});compactAssistantThread=async t=>{let a=await this._authHeaders(),e=await this._client.POST("/configurations/{configurationId}/assistant/chat/compact",{params:{path:{configurationId:t}},headers:{...a,"Content-Type":null}});if(e.error)throw new i(`compactAssistantThread API request failed: ${JSON.stringify(e.error)}`,e.response.status);return e.data};getAssistantEarlierThread=async(t,a,e)=>{let r=await this._authHeaders(),s=await this._client.GET("/configurations/{configurationId}/assistant/chat/threads/{threadId}",{params:{path:{configurationId:t,threadId:a},query:{limit:e}},headers:r});if(s.error)throw new i(`getAssistantEarlierThread API request failed: ${JSON.stringify(s.error)}`,s.response.status);let{messages:o}=s.data;return{threadId:a,messages:Array.isArray(o)?o:[],previousThreadId:s.response.headers.get("x-assistant-previous-thread")}};uploadAssistantImage=async(t,a)=>{let e=await this._authHeaders(),r=await this._client.POST("/configurations/{configurationId}/assistant/images",{params:{path:{configurationId:t}},headers:{...e,"Content-Type":a.type},body:a.type,bodySerializer:()=>a});if(r.error)throw new i(`uploadAssistantImage API request failed: ${JSON.stringify(r.error)}`,r.response.status);return{imageId:r.data.imageId}};getAssistantImage=async(t,a)=>{let e=await this._authHeaders(),r=await this._client.GET("/configurations/{configurationId}/assistant/images/{imageId}",{params:{path:{configurationId:t,imageId:a}},headers:e,parseAs:"blob"});if(r.error)throw new i(`getAssistantImage API request failed: ${JSON.stringify(r.error)}`,r.response.status);return r.data};sendMessage=async(t,a,e)=>{let r=await this._authHeaders(),i=await this._client.POST("/configurations/{configurationId}/chat/message",{params:{path:{configurationId:t}},body:{content:a,context:e},headers:r,parseAs:"stream"});if(i.error)throw h(i.error,"sendMessage");let s=i.data?.pipeThrough(new TextDecoderStream).getReader();if(!s)throw Error("sendMessage API response did not contain a readable stream");let u=o();return n(s,u.writable.getWriter()),u.readable};sendToolCallResults=async(t,a,e,r)=>{let i=await this._authHeaders(),s=await this._client.POST("/configurations/{configurationId}/chat/tool-calls",{params:{path:{configurationId:t}},body:{agent:r,calls:a,results:e},headers:i,parseAs:"stream"});if(s.error)throw h(s.error,"sendToolCallResults");let u=s.data?.pipeThrough(new TextDecoderStream).getReader();if(!u)throw Error("sendMessage API response did not contain a readable stream");let c=o();return n(u,c.writable.getWriter()),c.readable};generateShareLink=async(t,a,e,r,i)=>{let s=await this._authHeaders(),o=await this._client.POST("/configurations/{configurationId}/share-link",{params:{path:{configurationId:t}},body:{revisionId:a,expiration:e,access:r,baseUrl:i},headers:s});if(o.error)throw h(o.error,"generateShareLink");return o.data};generateUploadLinks=async(t,a,e)=>{let r=await this._authHeaders(),i=await this._client.POST("/configurations/{configurationId}/{finalizationUuid}/image-upload-links",{params:{path:{configurationId:t,finalizationUuid:a}},body:{names:e},headers:r});if(i.error)throw h(i.error,"generateUploadLinks");return i.data.links};getConfigurationPublicUploadLink=async(t,a)=>{let e=await this._authHeaders(),r=await this._client.GET("/configurations/{configurationId}/resources/{key}/public/upload",{params:{path:{configurationId:t,key:a}},headers:e});if(r.error)throw h(r.error,"getConfigurationPublicUploadLink");return r.data};getConfigurationPrivateUploadLink=async(t,a)=>{let e=await this._authHeaders(),r=await this._client.GET("/configurations/{configurationId}/resources/{key}/private/upload",{params:{path:{configurationId:t,key:a}},headers:e});if(r.error)throw h(r.error,"getConfigurationPrivateUploadLink");return r.data};getConfigurationPrivateResourceLink=async(t,a)=>{let e=await this._authHeaders(),r=await this._client.GET("/configurations/{configurationId}/resources/{key}/private",{params:{path:{configurationId:t,key:a}},headers:e});if(r.error)throw h(r.error,"getConfigurationPrivateUploadLink");return r.data};cloneConfiguration=async(t,a)=>{let e=await this._authHeaders(),r=await this._client.POST("/configurations/{configurationId}/revisions/{revisionId}/clone",{params:{path:{configurationId:t,revisionId:a}},headers:{...e,"Content-Type":null}});if(r.error)throw h(r.error,"cloneConfiguration");return r.data}}
|
|
@@ -100,6 +100,18 @@ export interface AuthorizedPhoenixApiClient<FINALIZE_DATA extends Record<string,
|
|
|
100
100
|
* `limit` of its newest messages. Rejects with an {@link AssistantRequestError} when the server refuses.
|
|
101
101
|
*/
|
|
102
102
|
getAssistantEarlierThread: (configurationId: string, threadId: string, limit: number) => Promise<AssistantEarlierThread>;
|
|
103
|
+
/**
|
|
104
|
+
* Stores a screenshot the assistant took in the open assistant thread of the configuration, while a
|
|
105
|
+
* reply runs there, and resolves with the id its tool result references it by. The image is the
|
|
106
|
+
* rendered JPEG or PNG blob, sent with its own type. Rejects with an {@link AssistantRequestError}
|
|
107
|
+
* when the server refuses.
|
|
108
|
+
*/
|
|
109
|
+
uploadAssistantImage: (configurationId: string, image: Blob) => Promise<AssistantImageUpload>;
|
|
110
|
+
/**
|
|
111
|
+
* Reads a screenshot of an assistant thread of the configuration by the id its tool result
|
|
112
|
+
* references it by. Rejects with an {@link AssistantRequestError} when the server refuses.
|
|
113
|
+
*/
|
|
114
|
+
getAssistantImage: (configurationId: string, imageId: string) => Promise<Blob>;
|
|
103
115
|
getSpeechToText: (configurationId: string, blob: Blob) => Promise<string>;
|
|
104
116
|
getTextToSpeech: (configurationId: string, text: string) => Promise<Blob>;
|
|
105
117
|
sendMessage: (configurationId: string, message: string, state?: Record<string, string>) => Promise<ReadableStream<ChatStreamChunk>>;
|
|
@@ -137,6 +149,11 @@ export interface AssistantThreadCompaction {
|
|
|
137
149
|
/** The closed thread the new one continues. */
|
|
138
150
|
readonly previousThreadId: string;
|
|
139
151
|
}
|
|
152
|
+
/** A screenshot stored in an assistant thread. */
|
|
153
|
+
export interface AssistantImageUpload {
|
|
154
|
+
/** The id a tool result references the image by, as `assistant-image:<imageId>`. */
|
|
155
|
+
readonly imageId: string;
|
|
156
|
+
}
|
|
140
157
|
/** A closed assistant thread, as the panel paints it above the thread that continues it. */
|
|
141
158
|
export interface AssistantEarlierThread {
|
|
142
159
|
readonly threadId: string;
|
package/dist/client/index.d.ts
CHANGED
|
@@ -9,5 +9,5 @@ export { MemoryAuthorizedPhoenixApiClient } from './memory-authorized-client.js'
|
|
|
9
9
|
export { MemoryAuthenticatedClientPhoenixApiClient, memoryStorage } from './memory-authenticated-client.js';
|
|
10
10
|
export { createUnsignedJWT } from './unsigned-jwt.js';
|
|
11
11
|
export type { components as ApiTypes } from './phoenix-api.js';
|
|
12
|
-
export type { ConfigurationPayload, ConfigurationSchema, ChatConfiguration, ChatConversation, ChatEmbedding, ChatMessageParam, ChatToolCallResult, Entity, UnauthenticatedPhoenixApiClient, AuthenticatedClientPhoenixApiClient, AuthorizedPhoenixApiClient, AssistantChatConnection, AssistantEarlierThread, AssistantThreadCompaction, OAuthProvider, OAuthAccessTokenResult, GoogleOAuthConfig, ReleaseToProductionResult, SharePointSiteConfig, } from './contract.js';
|
|
12
|
+
export type { ConfigurationPayload, ConfigurationSchema, ChatConfiguration, ChatConversation, ChatEmbedding, ChatMessageParam, ChatToolCallResult, Entity, UnauthenticatedPhoenixApiClient, AuthenticatedClientPhoenixApiClient, AuthorizedPhoenixApiClient, AssistantChatConnection, AssistantEarlierThread, AssistantImageUpload, AssistantThreadCompaction, OAuthProvider, OAuthAccessTokenResult, GoogleOAuthConfig, ReleaseToProductionResult, SharePointSiteConfig, } from './contract.js';
|
|
13
13
|
export { AssistantRequestError, InvalidAccessKeyError, InvalidDeploymentError, ChunkNotFoundError, OAuthStaleConnectionError, ConfigurationSchemaMismatchError, isConfigurationSchemaMismatchError, } from './contract.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ChatMessageContentChunk, ChatToolCalls } from '@salsita-ai/contracts/chat';
|
|
2
|
-
import type { AssistantChatConnection, AssistantEarlierThread, AssistantThreadCompaction, AuthorizedPhoenixApiClient, ConfigurationPayload, ConfigurationSchema } from './contract.js';
|
|
2
|
+
import type { AssistantChatConnection, AssistantEarlierThread, AssistantImageUpload, AssistantThreadCompaction, AuthorizedPhoenixApiClient, ConfigurationPayload, ConfigurationSchema } from './contract.js';
|
|
3
3
|
import { LocalStorageAuthenticatedClientPhoenixApiClient } from './local-authenticated-client.js';
|
|
4
4
|
/**
|
|
5
5
|
* Local storage implementation for local dev, it does not check for schema changes, so you may need to create new configuration if the schema changes and
|
|
@@ -17,6 +17,8 @@ export declare class LocalStorageAuthorizedPhoenixApiClient<FINALIZE_DATA extend
|
|
|
17
17
|
getAssistantChatConnection: () => AssistantChatConnection;
|
|
18
18
|
compactAssistantThread: () => Promise<AssistantThreadCompaction>;
|
|
19
19
|
getAssistantEarlierThread: () => Promise<AssistantEarlierThread>;
|
|
20
|
+
uploadAssistantImage: () => Promise<AssistantImageUpload>;
|
|
21
|
+
getAssistantImage: () => Promise<Blob>;
|
|
20
22
|
getChatConversation: (configurationId: string) => Promise<readonly {
|
|
21
23
|
readonly augmentation?: import("./phoenix-api.js").components['schemas']['ChatMessageAugmentation'];
|
|
22
24
|
readonly content?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import*as t from"uuid";import{ChunkType as e}from"@salsita-ai/contracts/chat";import{LocalStorageAuthenticatedClientPhoenixApiClient as
|
|
1
|
+
import*as t from"uuid";import{ChunkType as e}from"@salsita-ai/contracts/chat";import{LocalStorageAuthenticatedClientPhoenixApiClient as r}from"./local-authenticated-client.js";let o=(t,r)=>{let o={role:"assistant",content:["I see","Yes","Definitely"][Math.round(2*Math.random())]};return localStorage.setItem(`${r}-chat`,JSON.stringify([...t,o])),Promise.resolve(new ReadableStream({start(t){t.enqueue({type:e.content,content:o.content??""}),t.close()}}))};export class LocalStorageAuthorizedPhoenixApiClient extends r{getConfigurationData=t=>{let e=JSON.parse(localStorage.getItem(t)??"[]");if(!e||0===e.length)throw Error("Configuration not found!");return e};getConfiguration=t=>{let e=this.getConfigurationData(t);return Promise.resolve(e[e.length-1])};updateConfiguration=(e,r)=>{let o=this.getConfigurationData(e),n=t.v4(),a={...r,configurationId:e,revisionId:n,modelVersion:this._modelVersion};return localStorage.setItem(e,JSON.stringify([...o,a])),Promise.resolve({revisionId:n})};finalize=()=>{throw Error("Not implemented!")};waitForFinalizationToComplete=()=>{throw Error("Not implemented!")};getConfigurationRevision=(t,e)=>{let r=this.getConfigurationData(t).find(t=>t.revisionId===e);if(!r)throw Error("Revision not found!");return Promise.resolve(r)};getAssistantChatConnection=()=>{throw Error("The assistant chat needs the Phoenix server. Run the configurator against a server deployment.")};compactAssistantThread=async()=>{throw Error("The assistant chat needs the Phoenix server. Run the configurator against a server deployment.")};getAssistantEarlierThread=async()=>{throw Error("The assistant chat needs the Phoenix server. Run the configurator against a server deployment.")};uploadAssistantImage=async()=>{throw Error("The assistant chat needs the Phoenix server. Run the configurator against a server deployment.")};getAssistantImage=async()=>{throw Error("The assistant chat needs the Phoenix server. Run the configurator against a server deployment.")};getChatConversation=async t=>JSON.parse(localStorage.getItem(`${t}-chat`)??"[]");sendMessage=async(t,e)=>{let r=await this.getChatConversation(t);return localStorage.setItem(`${t}-chat`,JSON.stringify([...r,e])),o(r,t)};getSpeechToText=async()=>{throw Error("Not implemented!")};getTextToSpeech=async()=>{throw Error("Not implemented!")};sendToolCallResults=async t=>o(await this.getChatConversation(t),t);generateShareLink=async()=>({link:"https://yourcompany.com/configurator/link-will-not-work-it-is-dummy-link"});generateUploadLinks=async()=>{throw Error("Not implemented!")};getConfigurationPublicUploadLink=async()=>{throw Error("Not implemented!")};getConfigurationPrivateUploadLink=async()=>{throw Error("Not implemented!")};getConfigurationPrivateResourceLink=async()=>{throw Error("Not implemented!")};cloneConfiguration=async(t,e)=>{let r=localStorage.getItem(t);if(!r)throw Error("Configuration not found");let o=JSON.parse(r).find(t=>t.revisionId===e);if(!o)throw Error("Revision not found");return this.createConfiguration(o)}}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AssistantChatConnection, AssistantEarlierThread, AssistantThreadCompaction, AuthorizedPhoenixApiClient, ConfigurationPayload, ConfigurationSchema } from './contract.js';
|
|
1
|
+
import type { AssistantChatConnection, AssistantEarlierThread, AssistantImageUpload, AssistantThreadCompaction, AuthorizedPhoenixApiClient, ConfigurationPayload, ConfigurationSchema } from './contract.js';
|
|
2
2
|
import { MemoryAuthenticatedClientPhoenixApiClient } from './memory-authenticated-client.js';
|
|
3
3
|
/**
|
|
4
4
|
* Memory implementation for local dev, it does not check for schema changes, so you may need to create new configuration if the schema changes and
|
|
@@ -17,6 +17,9 @@ export declare class MemoryAuthorizedPhoenixApiClient<FINALIZE_DATA extends Reco
|
|
|
17
17
|
getAssistantChatConnection: () => AssistantChatConnection;
|
|
18
18
|
compactAssistantThread: () => Promise<AssistantThreadCompaction>;
|
|
19
19
|
getAssistantEarlierThread: () => Promise<AssistantEarlierThread>;
|
|
20
|
+
private readonly _assistantImages;
|
|
21
|
+
uploadAssistantImage: (configurationId: string, image: Blob) => Promise<AssistantImageUpload>;
|
|
22
|
+
getAssistantImage: (configurationId: string, imageId: string) => Promise<Blob>;
|
|
20
23
|
sendMessage: () => Promise<never>;
|
|
21
24
|
getSpeechToText: () => Promise<never>;
|
|
22
25
|
getTextToSpeech: () => Promise<never>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import*as
|
|
1
|
+
import*as t from"uuid";import{MemoryAuthenticatedClientPhoenixApiClient as e,memoryStorage as r}from"./memory-authenticated-client.js";export class MemoryAuthorizedPhoenixApiClient extends e{getConfigurationData=t=>{let e=r.get(t);if(!e||!e||0===e.length)throw Error("Configuration not found!");return e};getConfiguration=t=>{let e=this.getConfigurationData(t);return Promise.resolve(e[e.length-1])};updateConfiguration=(e,o)=>{let n=this.getConfigurationData(e),i=t.v4(),a={...o,configurationId:e,revisionId:i,modelVersion:this._modelVersion};return r.set(e,[...n,a]),Promise.resolve({revisionId:i})};finalize=()=>{throw Error("Not implemented!")};waitForFinalizationToComplete=()=>{throw Error("Not implemented!")};getConfigurationRevision=(t,e)=>{let r=this.getConfigurationData(t).find(t=>t.revisionId===e);if(!r)throw Error("Revision not found!");return Promise.resolve(r)};getChatConversation=async()=>{throw Error("Not implemented!")};getAssistantChatConnection=()=>{throw Error("The assistant chat needs the Phoenix server. Run the configurator against a server deployment.")};compactAssistantThread=async()=>{throw Error("The assistant chat needs the Phoenix server. Run the configurator against a server deployment.")};getAssistantEarlierThread=async()=>{throw Error("The assistant chat needs the Phoenix server. Run the configurator against a server deployment.")};_assistantImages=new Map;uploadAssistantImage=async(e,r)=>{let o=t.v4();return this._assistantImages.set(`${e}/${o}`,r),{imageId:o}};getAssistantImage=async(t,e)=>{let r=this._assistantImages.get(`${t}/${e}`);if(!r)throw Error(`Assistant image ${e} was not uploaded for configuration ${t} through this client. Upload it before reading it.`);return r};sendMessage=async()=>{throw Error("Not implemented!")};getSpeechToText=async()=>{throw Error("Not implemented!")};getTextToSpeech=async()=>{throw Error("Not implemented!")};sendToolCallResults=async()=>{throw Error("Not implemented!")};generateShareLink=async()=>({link:"https://yourcompany.com/configurator/link-will-not-work-it-is-dummy-link"});generateUploadLinks=async()=>{throw Error("Not implemented!")};getConfigurationPublicUploadLink=async()=>{throw Error("Not implemented!")};getConfigurationPrivateUploadLink=async()=>{throw Error("Not implemented!")};getConfigurationPrivateResourceLink=async()=>{throw Error("Not implemented!")};cloneConfiguration=async(t,e)=>{let o=r.get(t);if(!o)throw Error("Configuration not found");let n=o.find(t=>t.revisionId===e);if(!n)throw Error("Revision not found");return this.createConfiguration(n)}}
|
|
@@ -379,6 +379,40 @@ export interface paths {
|
|
|
379
379
|
readonly patch?: never
|
|
380
380
|
readonly trace?: never
|
|
381
381
|
}
|
|
382
|
+
readonly '/configurations/{configurationId}/assistant/images': {
|
|
383
|
+
readonly parameters: {
|
|
384
|
+
readonly query?: never
|
|
385
|
+
readonly header?: never
|
|
386
|
+
readonly path?: never
|
|
387
|
+
readonly cookie?: never
|
|
388
|
+
}
|
|
389
|
+
readonly get?: never
|
|
390
|
+
readonly put?: never
|
|
391
|
+
/** @description Store a screenshot the browser took for the assistant in the caller's open thread on the configuration, while a run of the assistant answers there. The body is the raw JPEG or PNG image, with its type as the content type. The answer carries the id that tool results reference the image by, as `assistant-image:<imageId>`. Answers 409 when the caller has no open thread on the configuration or the thread is not in the middle of a reply (no run running and no client tool call waiting), and 415 for any other content type. */
|
|
392
|
+
readonly post: operations['uploadAssistantImage']
|
|
393
|
+
readonly delete?: never
|
|
394
|
+
readonly options?: never
|
|
395
|
+
readonly head?: never
|
|
396
|
+
readonly patch?: never
|
|
397
|
+
readonly trace?: never
|
|
398
|
+
}
|
|
399
|
+
readonly '/configurations/{configurationId}/assistant/images/{imageId}': {
|
|
400
|
+
readonly parameters: {
|
|
401
|
+
readonly query?: never
|
|
402
|
+
readonly header?: never
|
|
403
|
+
readonly path?: never
|
|
404
|
+
readonly cookie?: never
|
|
405
|
+
}
|
|
406
|
+
/** @description Load a screenshot of one of the caller's assistant threads on the configuration, the earlier threads of the chain included. The bytes never change, so the answer may be cached for good. Answers 404 for an image that is not in one of the caller's threads on this configuration. */
|
|
407
|
+
readonly get: operations['getAssistantImage']
|
|
408
|
+
readonly put?: never
|
|
409
|
+
readonly post?: never
|
|
410
|
+
readonly delete?: never
|
|
411
|
+
readonly options?: never
|
|
412
|
+
readonly head?: never
|
|
413
|
+
readonly patch?: never
|
|
414
|
+
readonly trace?: never
|
|
415
|
+
}
|
|
382
416
|
readonly '/configurations/{configurationId}/chat': {
|
|
383
417
|
readonly parameters: {
|
|
384
418
|
readonly query?: never
|
|
@@ -1503,6 +1537,13 @@ export interface components {
|
|
|
1503
1537
|
/** @enum {number} */
|
|
1504
1538
|
readonly statusCode: 401
|
|
1505
1539
|
}
|
|
1540
|
+
/** @description Unsupported Media Type: The request body is of a content type the route does not accept. */
|
|
1541
|
+
readonly UnsupportedMediaTypeError: {
|
|
1542
|
+
/** @example Unsupported Media Type! */
|
|
1543
|
+
readonly message: string
|
|
1544
|
+
/** @enum {number} */
|
|
1545
|
+
readonly statusCode: 415
|
|
1546
|
+
}
|
|
1506
1547
|
/** @description A webhook resource to which the deployment can send requests. */
|
|
1507
1548
|
readonly Webhook: {
|
|
1508
1549
|
/**
|
|
@@ -3397,6 +3438,193 @@ export interface operations {
|
|
|
3397
3438
|
}
|
|
3398
3439
|
}
|
|
3399
3440
|
}
|
|
3441
|
+
readonly uploadAssistantImage: {
|
|
3442
|
+
readonly parameters: {
|
|
3443
|
+
readonly query?: never
|
|
3444
|
+
readonly header?: never
|
|
3445
|
+
readonly path: {
|
|
3446
|
+
/** @description The configuration on which the caller's assistant thread is used. */
|
|
3447
|
+
readonly configurationId: components['schemas']['ConfigurationUuid']
|
|
3448
|
+
}
|
|
3449
|
+
readonly cookie?: never
|
|
3450
|
+
}
|
|
3451
|
+
/** @description The JPEG or PNG image. */
|
|
3452
|
+
readonly requestBody: {
|
|
3453
|
+
readonly content: {
|
|
3454
|
+
readonly 'image/jpeg': string
|
|
3455
|
+
readonly 'image/png': string
|
|
3456
|
+
}
|
|
3457
|
+
}
|
|
3458
|
+
readonly responses: {
|
|
3459
|
+
/** @description The image was stored in the thread. */
|
|
3460
|
+
readonly 200: {
|
|
3461
|
+
headers: {
|
|
3462
|
+
readonly [name: string]: unknown
|
|
3463
|
+
}
|
|
3464
|
+
content: {
|
|
3465
|
+
readonly 'application/json': {
|
|
3466
|
+
/**
|
|
3467
|
+
* Format: uuid
|
|
3468
|
+
* @description The id tool results reference the image by.
|
|
3469
|
+
*/
|
|
3470
|
+
readonly imageId: string
|
|
3471
|
+
}
|
|
3472
|
+
}
|
|
3473
|
+
}
|
|
3474
|
+
/** @description Bad Request! */
|
|
3475
|
+
readonly 400: {
|
|
3476
|
+
headers: {
|
|
3477
|
+
readonly [name: string]: unknown
|
|
3478
|
+
}
|
|
3479
|
+
content: {
|
|
3480
|
+
readonly 'application/json': components['schemas']['BadRequestError']
|
|
3481
|
+
}
|
|
3482
|
+
}
|
|
3483
|
+
/** @description Unauthorized! */
|
|
3484
|
+
readonly 401: {
|
|
3485
|
+
headers: {
|
|
3486
|
+
readonly [name: string]: unknown
|
|
3487
|
+
}
|
|
3488
|
+
content: {
|
|
3489
|
+
readonly 'application/json': components['schemas']['UnauthorizedError']
|
|
3490
|
+
}
|
|
3491
|
+
}
|
|
3492
|
+
/** @description Forbidden! */
|
|
3493
|
+
readonly 403: {
|
|
3494
|
+
headers: {
|
|
3495
|
+
readonly [name: string]: unknown
|
|
3496
|
+
}
|
|
3497
|
+
content: {
|
|
3498
|
+
readonly 'application/json': components['schemas']['ForbiddenError']
|
|
3499
|
+
}
|
|
3500
|
+
}
|
|
3501
|
+
/** @description Not Found! */
|
|
3502
|
+
readonly 404: {
|
|
3503
|
+
headers: {
|
|
3504
|
+
readonly [name: string]: unknown
|
|
3505
|
+
}
|
|
3506
|
+
content: {
|
|
3507
|
+
readonly 'application/json': components['schemas']['NotFoundError']
|
|
3508
|
+
}
|
|
3509
|
+
}
|
|
3510
|
+
/** @description Conflict! */
|
|
3511
|
+
readonly 409: {
|
|
3512
|
+
headers: {
|
|
3513
|
+
readonly [name: string]: unknown
|
|
3514
|
+
}
|
|
3515
|
+
content: {
|
|
3516
|
+
readonly 'application/json': components['schemas']['ConflictError']
|
|
3517
|
+
}
|
|
3518
|
+
}
|
|
3519
|
+
/** @description Unsupported Media Type! */
|
|
3520
|
+
readonly 415: {
|
|
3521
|
+
headers: {
|
|
3522
|
+
readonly [name: string]: unknown
|
|
3523
|
+
}
|
|
3524
|
+
content: {
|
|
3525
|
+
readonly 'application/json': components['schemas']['UnsupportedMediaTypeError']
|
|
3526
|
+
}
|
|
3527
|
+
}
|
|
3528
|
+
/** @description Bad Gateway! */
|
|
3529
|
+
readonly 502: {
|
|
3530
|
+
headers: {
|
|
3531
|
+
readonly [name: string]: unknown
|
|
3532
|
+
}
|
|
3533
|
+
content: {
|
|
3534
|
+
readonly 'application/json': components['schemas']['BadGatewayError']
|
|
3535
|
+
}
|
|
3536
|
+
}
|
|
3537
|
+
/** @description An unexpected error occurred! */
|
|
3538
|
+
readonly default: {
|
|
3539
|
+
headers: {
|
|
3540
|
+
readonly [name: string]: unknown
|
|
3541
|
+
}
|
|
3542
|
+
content: {
|
|
3543
|
+
readonly 'application/json': components['schemas']['DefaultResponse']
|
|
3544
|
+
}
|
|
3545
|
+
}
|
|
3546
|
+
}
|
|
3547
|
+
}
|
|
3548
|
+
readonly getAssistantImage: {
|
|
3549
|
+
readonly parameters: {
|
|
3550
|
+
readonly query?: never
|
|
3551
|
+
readonly header?: never
|
|
3552
|
+
readonly path: {
|
|
3553
|
+
/** @description The configuration on which the caller's assistant thread is used. */
|
|
3554
|
+
readonly configurationId: components['schemas']['ConfigurationUuid']
|
|
3555
|
+
/** @description The image, as a tool result references it. */
|
|
3556
|
+
readonly imageId: string
|
|
3557
|
+
}
|
|
3558
|
+
readonly cookie?: never
|
|
3559
|
+
}
|
|
3560
|
+
readonly requestBody?: never
|
|
3561
|
+
readonly responses: {
|
|
3562
|
+
/** @description The image. */
|
|
3563
|
+
readonly 200: {
|
|
3564
|
+
headers: {
|
|
3565
|
+
readonly [name: string]: unknown
|
|
3566
|
+
}
|
|
3567
|
+
content: {
|
|
3568
|
+
readonly 'image/jpeg': unknown
|
|
3569
|
+
readonly 'image/png': unknown
|
|
3570
|
+
}
|
|
3571
|
+
}
|
|
3572
|
+
/** @description Bad Request! */
|
|
3573
|
+
readonly 400: {
|
|
3574
|
+
headers: {
|
|
3575
|
+
readonly [name: string]: unknown
|
|
3576
|
+
}
|
|
3577
|
+
content: {
|
|
3578
|
+
readonly 'application/json': components['schemas']['BadRequestError']
|
|
3579
|
+
}
|
|
3580
|
+
}
|
|
3581
|
+
/** @description Unauthorized! */
|
|
3582
|
+
readonly 401: {
|
|
3583
|
+
headers: {
|
|
3584
|
+
readonly [name: string]: unknown
|
|
3585
|
+
}
|
|
3586
|
+
content: {
|
|
3587
|
+
readonly 'application/json': components['schemas']['UnauthorizedError']
|
|
3588
|
+
}
|
|
3589
|
+
}
|
|
3590
|
+
/** @description Forbidden! */
|
|
3591
|
+
readonly 403: {
|
|
3592
|
+
headers: {
|
|
3593
|
+
readonly [name: string]: unknown
|
|
3594
|
+
}
|
|
3595
|
+
content: {
|
|
3596
|
+
readonly 'application/json': components['schemas']['ForbiddenError']
|
|
3597
|
+
}
|
|
3598
|
+
}
|
|
3599
|
+
/** @description Not Found! */
|
|
3600
|
+
readonly 404: {
|
|
3601
|
+
headers: {
|
|
3602
|
+
readonly [name: string]: unknown
|
|
3603
|
+
}
|
|
3604
|
+
content: {
|
|
3605
|
+
readonly 'application/json': components['schemas']['NotFoundError']
|
|
3606
|
+
}
|
|
3607
|
+
}
|
|
3608
|
+
/** @description Bad Gateway! */
|
|
3609
|
+
readonly 502: {
|
|
3610
|
+
headers: {
|
|
3611
|
+
readonly [name: string]: unknown
|
|
3612
|
+
}
|
|
3613
|
+
content: {
|
|
3614
|
+
readonly 'application/json': components['schemas']['BadGatewayError']
|
|
3615
|
+
}
|
|
3616
|
+
}
|
|
3617
|
+
/** @description An unexpected error occurred! */
|
|
3618
|
+
readonly default: {
|
|
3619
|
+
headers: {
|
|
3620
|
+
readonly [name: string]: unknown
|
|
3621
|
+
}
|
|
3622
|
+
content: {
|
|
3623
|
+
readonly 'application/json': components['schemas']['DefaultResponse']
|
|
3624
|
+
}
|
|
3625
|
+
}
|
|
3626
|
+
}
|
|
3627
|
+
}
|
|
3400
3628
|
readonly getChatConversation: {
|
|
3401
3629
|
readonly parameters: {
|
|
3402
3630
|
readonly query?: never
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as r,jsxs as e}from"react/jsx-runtime";import{I18nProvider as o}from"@lingui/react";import{QueryClientProvider as i}from"@tanstack/react-query";import n from"mui-modal-provider";import{useEffect as t}from"react";import{standardWebComponentProperties as c}from"#package/domain";import{getAvailableLocales as a,resolveLocale as m}from"#package/i18n";import{ApplicationType as l,ApplicationTypeProvider as d,
|
|
1
|
+
import{jsx as r,jsxs as e}from"react/jsx-runtime";import{I18nProvider as o}from"@lingui/react";import{QueryClientProvider as i}from"@tanstack/react-query";import n from"mui-modal-provider";import{useEffect as t}from"react";import{standardWebComponentProperties as c}from"#package/domain";import{getAvailableLocales as a,resolveLocale as m}from"#package/i18n";import{ApplicationType as l,ApplicationTypeProvider as d,ConfiguratorRoutingProvider as p,InvalidDeploymentReload as s,LoaderHost as f,OnApplicationStartProvider as u,OnRoutingReadyProvider as h,OnSessionReadyProvider as x,SessionServiceProvider as g,useApplicationQueryClient as j,useI18n as k,usePowerRoutingLifecycle as v,useSpecAlwaysExpand as b,useSpecAppLoader as y,useSpecPrefetchTextureUrls as C,useSpecPreview as w,useWebComponentProperty$ as E,useWebComponentPropertySetter as I,useWebComponentPropertyValue as L}from"#package/react-sdk";import{SnackbarProvider as P}from"#package/ui-sdk";import{ConfiguratorDataProvider as Z}from"./configurator-context/ConfiguratorDataProvider.js";import{ConfiguratorResponsiveProvider as q}from"./configurator-context/ConfiguratorResponsiveProvider.js";import{PresetSelectionProvider as A,PreviewApplicationProvider as B}from"./configurator-context/index.js";import{LoadingErrorBoundary as D}from"./pages/error-boundaries/LoadingErrorBoundary.js";import{GeneralErrorFallback as F,RootPage as R}from"./pages/index.js";import{SceneResourcesProvider as S}from"./scene/index.js";import{EncapsulatedConfiguratorTheme as T}from"./ui/index.js";import{AppLoader as U}from"./ui/phoenix-layout-elements/index.js";export const ConfiguratorApp=()=>{let z=j(),G=k(),H=y(),J=w(),K=b(),M=C(),N=I(c.locale),O=E(c.locale);t(()=>{let r=O.subscribe(r=>{let e=m(r,a(G));G.activate(e)}),e=()=>{N(G.locale)};return G.on("change",e),()=>{r.unsubscribe(),G.removeListener("change",e)}},[O,G,N]);let Q=L(c.containerZIndex),V=L(c.power);return(v(),"off"===V)?null:r(d,{type:l.Configurator,children:r(i,{client:z,children:r(T,{children:r(f,{children:r(q,{containerZIndex:Q,children:r(U,{mode:H,children:r(B,{alwaysExpand:K,preview:J,children:r(o,{i18n:G,children:r(P,{maxSnack:5,children:r(D,{FallbackComponent:F,children:r(S,{prefetchTextureUrls:M,children:r(u,{children:r(g,{children:r(x,{children:"on"===V&&r(p,{children:r(Z,{children:r(A,{children:r(h,{children:e(n,{children:[r(s,{}),r(R,{})]})})})})})})})})})})})})})})})})})})})};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createSelector as e}from"@salsita-ai/common/utils";import{createSessionAssistant as t,isAssistantSetupHandler as n}from"#package/domain";import{AnimationSystem as s,AssistantSystem as o,CameraControlSystem as r,CameraSystem as a,CanvasSystem as i,DragAndDropSystem as g,ExportSystem as m,GraphQLSystem as
|
|
1
|
+
import{createSelector as e}from"@salsita-ai/common/utils";import{createSessionAssistant as t,isAssistantSetupHandler as n}from"#package/domain";import{AnimationSystem as s,AssistantSystem as o,CameraControlSystem as r,CameraSystem as a,CanvasSystem as i,DragAndDropSystem as g,ExportSystem as m,GraphQLSystem as l,ImageRenderingSystem as c,LayoutSystem as S,SketchingSystem as d}from"./systems/index.js";export const createConfiguratorExtensionSelectors=u=>{let{getState:y,domainContextSelectors:C,specSelectors:p,domainServicesSelectors:w,accessSelectors:f,commonServicesSelectors:h}=u,A=e.withTypes()([p.selectConfiguratorSpec,C.selectInitializationContext],(e,s)=>t({resolved:e.assistant,handler:e.handlers.find(n),inputs:s&&s.access?{role:s.role,sessionData:s.sessionData,access:s.access}:null})),I={getConfigurationId:()=>f.getConfiguratorConfigurationId(),getAuthorizedClient:()=>h.getConfiguratorAuthorizedClient(),getAssistantSetup:()=>A(y()),domainContextSelectors:C,domainServicesSelectors:w,specSelectors:p},x={getSystems:()=>Q,getCanvasSystem:()=>z,getCameraControlSystem:()=>D,getAnimationSystem:()=>b,getDragAndDropSystem:()=>v,getImageRenderingSystem:()=>G,getLayoutSystem:()=>T,getSketchingSystem:()=>j,getExportSystem:()=>k,getCameraSystem:()=>F,getGraphQLSystem:()=>L,getAssistantSystem:()=>R},E={...I,configuratorExtensionSelectors:x},z=new i(I),D=new r({configuratorExtensionSelectors:x}),v=new g(E),b=new s(I),k=new m(E),L=new l({...I,renderScreenshot:async(e,t)=>{let[n]=await x.getImageRenderingSystem().generateImagesFromComponents([e],t,{},{awaitSettledState:!0});if(!n)throw Error("The canvas rendered no image.");return n.blob},uploadScreenshot:e=>I.getAuthorizedClient().uploadAssistantImage(I.getConfigurationId(),e)}),R=new o(E),T=new S(I),j=new d(E),F=new a(E),G=new c(E),Q={cameraControlSystem:D,layoutSystem:T,sketchingSystem:j,dragAndDropSystem:v,canvasSystem:z,cameraSystem:F,exportSystem:k,imageRenderingSystem:G,animationSystem:b,graphQLSystem:L,assistantSystem:R};return x};
|
|
@@ -136,6 +136,11 @@ export declare class AssistantSystem implements InitializableSystem {
|
|
|
136
136
|
*/
|
|
137
137
|
private readonly _applyToolCallIds;
|
|
138
138
|
private readonly _undoTipToolCallId;
|
|
139
|
+
/**
|
|
140
|
+
* Object URLs of the screenshots read so far, by image id. An uploaded image never changes, so
|
|
141
|
+
* each is read once and kept while the configuration stays loaded.
|
|
142
|
+
*/
|
|
143
|
+
private _screenshotUrls;
|
|
139
144
|
constructor(_context: AssistantSystemContext);
|
|
140
145
|
/** The conversation. It never completes, and holds the empty chat whenever no chat is active. */
|
|
141
146
|
readonly chat$: ObservableWithLastValue<AssistantChatSnapshot>;
|
|
@@ -231,6 +236,12 @@ export declare class AssistantSystem implements InitializableSystem {
|
|
|
231
236
|
* refuses with a conflict is not a failure: the thread is read again and `false` is returned.
|
|
232
237
|
*/
|
|
233
238
|
resume: () => Promise<boolean>;
|
|
239
|
+
/**
|
|
240
|
+
* An object URL of a screenshot of the conversation, by the id its tool result references it by.
|
|
241
|
+
* It is read from the server through the client of the current chat, once per image; a read that
|
|
242
|
+
* failed is forgotten, so it can be asked for again. Rejects without a chat or when the read fails.
|
|
243
|
+
*/
|
|
244
|
+
loadScreenshotUrl: (imageId: string) => Promise<string>;
|
|
234
245
|
/**
|
|
235
246
|
* Loads the thread before the oldest painted one and paints it above. Does nothing when there is
|
|
236
247
|
* none or one is being loaded. A load that fails is logged and can be asked for again.
|
|
@@ -300,6 +311,8 @@ export declare class AssistantSystem implements InitializableSystem {
|
|
|
300
311
|
* it is: whether it finishes its reply or is cut off is the caller's decision.
|
|
301
312
|
*/
|
|
302
313
|
private _retireChat;
|
|
314
|
+
/** Revokes the object URLs of the screenshots read for the configuration that was loaded, also those still being read. */
|
|
315
|
+
private _releaseScreenshotUrls;
|
|
303
316
|
/** Ends the current chat without cutting its reply off. */
|
|
304
317
|
private _endChat;
|
|
305
318
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ChatClient as e,fetchServerSentEvents as t}from"@tanstack/ai-client";import{BehaviorSubject as i}from"rxjs";import{skip as s}from"rxjs/operators";import{isShallowEqual as a}from"@salsita-ai/common/utils";import{AssistantRequestError as r}from"#package/client";import{createBrowserDetailsClientTool as n}from"./browser-details.js";import{ChangeRecorder as o}from"./change-recorder.js";import{createApplyClientTool as l,createQueryClientTool as h,toToolResult as d}from"./graphql-tools.js";let c=Object.freeze({messages:Object.freeze([]),isLoading:!1,error:void 0,failedStatus:void 0,isContinuable:!0,isLoaded:!1,isResuming:!1,earlierThreads:Object.freeze([]),hasEarlierThread:!1,isLoadingEarlierThread:!1}),u=Object.freeze({open:!1,hasUnreadReply:!1,isInputFocused:!1}),_=Object.freeze({}),g=d({results:[],committed:!1,sideEffects:[],screenshots:new Map,message:"Nothing was run, because the user closed the configurator while this reply was being written. Do not call any more tools in this reply and end it now. The tools work again as soon as the user writes the next message."}),m=e=>{if(e.getError())return!0;let t=e.getMessages().at(-1)?.parts.at(-1);return t?.type!=="tool-call"&&t?.type!=="tool-result"};export class AssistantSystem{_context;_tools;_chat=new i(c);_panel=new i(u);_activation=null;_current=null;_finishing=new Set;_olderThreadId=null;_resuming=null;_refused=null;_firstAttempt=null;_chain={};_loadingThreadId=null;_recorder;_recording=null;_applyToolCallIds=new WeakMap;_undoTipToolCallId=new i(void 0);constructor(e){this._context=e;let{configuratorExtensionSelectors:t,domainContextSelectors:i,domainServicesSelectors:s,getAssistantSetup:a}=e;this._recorder=new o({maxEntities:30},{readers:{selectedEntityId:e=>i.getNavigationSystem().getActiveSelectionState(e),navigationState:e=>i.getNavigationSystem().getActiveNavigationState(e),viewState:e=>i.getNavigationSystem().getActiveViewState(e),toolState:e=>i.getNavigationSystem().getActiveToolState(e)},getExposedFields:()=>a().manifest?.fields??_,resolveLocalizable:e=>s.getResolveLocalizable()(e)});let r={getGraphQLSystem:()=>t.getGraphQLSystem(),getStoreSystem:()=>i.getStoreSystem(),getActiveMode:()=>i.getActiveMode(),getIsViewMode:()=>i.getIsViewMode(),clearChanges:()=>this._recorder.clear(this._committedState()),rememberCommit:(e,t)=>{this._applyToolCallIds.set(t,e),this._refreshUndoTip()}};this._tools=[n(),h(r),l(r)],i.getUndoSystem().tip$.subscribe(this._refreshUndoTip)}chat$=this._chat;panel$=this._panel;undoTipToolCallId$=this._undoTipToolCallId;getSessionManifest=()=>this._context.getAssistantSetup().manifest;initialize=()=>{let{committed:e}=this._context.domainContextSelectors.getStoreSystem().stateSlices;this._recording??=e.pipe(s(1)).subscribe(this._recorder.record),this._recorder.reset(e.value.state),this._endChat(),this._patchPanel(u),this._activation&&this._startClient()};activate=()=>{this._endChat();let e={};return this._activation=e,this._startClient(),()=>{this._activation===e&&(this._activation=null,this._endChat())}};send=async e=>{if(!this._chat.value.isContinuable&&!await this.resume())return;let t=this._current;if(!t)return;let i={changes:this._recorder.take(this._committedState())};this._firstAttempt=t;try{await this._sendOn(t,e,i);let s=this._findRefusedMessageIndex(t);if(-1===s)return;this._refused={chat:t,index:s}}finally{this._firstAttempt===t&&(this._firstAttempt=null)}if(!await this.resume())return;let s=this._current;s&&await this._sendOn(s,e,i)};resume=async()=>{let e=this._current;if(!e)return!1;if(this._chat.value.isContinuable)return!0;if(this._resuming)return this._resuming;let t=this._resume(e).finally(()=>{this._resuming===t&&(this._resuming=null)});return this._resuming=t,t};loadEarlierThread=async()=>{let e=this._current,t=this._olderThreadId;if(!e||null===t||this._loadingThreadId===t)return;let i=this._chain;this._loadingThreadId=t,this._chat.next({...this._chat.value,isLoadingEarlierThread:!0});try{let s=await e.authorizedClient.getAssistantEarlierThread(e.configurationId,t,50);if(this._chain!==i||this._olderThreadId!==t)return;this._olderThreadId=s.previousThreadId,this._chat.next({...this._chat.value,earlierThreads:[{threadId:t,messages:s.messages},...this._chat.value.earlierThreads],hasEarlierThread:null!==s.previousThreadId})}catch(e){this._context.domainServicesSelectors.getLogger().warn("Could not load the earlier assistant conversation",{error:e})}finally{this._chain===i&&this._loadingThreadId===t&&(this._loadingThreadId=null,this._chat.next({...this._chat.value,isLoadingEarlierThread:!1}))}};stop=async()=>{let e=this._current;if(!e)return;let t=e.client.getCurrentRunId();if(e.client.stop(),null!=t)try{let i=e.getConnection();await fetch(`${i.url}/runs/${encodeURIComponent(t)}/cancel`,{method:"POST",headers:await i.headers()})}catch(e){this._context.domainServicesSelectors.getLogger().warn("Could not cancel the assistant run on the server",{error:e})}};reloadThread=()=>{if(!this._activation)return;let e=this._retireChat();e?.client.stop(),e?.dispose(),this._recorder.reset(this._committedState()),this._startClient()};undoToolCalls=e=>{let t=this._context.domainContextSelectors.getUndoSystem(),i=()=>{let t=this._findTipToolCallId();return void 0!==t&&e.has(t)};for(;i();)t.undo()};setOpen=e=>{this._patchPanel(e?{open:e,hasUnreadReply:!1}:{open:e,isInputFocused:!1})};setInputFocused=e=>{this._patchPanel({isInputFocused:e})};_findRefusedMessageIndex=e=>{var t;let i,{failedStatus:s,isContinuable:a}=this._chat.value;return this._firstAttempt===e&&e.generation.active&&409===s&&!a?(i=(t=e.client.getMessages()).map(e=>e.role).lastIndexOf("user"),t.slice(i+1).every(e=>0===e.parts.length)?i:-1):-1};_sendOn=async(e,t,i)=>{let{client:s}=e;s.getIsLoading()||null===s.getResumeState()||s.stop();try{await s.sendMessage({content:t,metadata:i})}catch(i){let t=i instanceof Error?i:Error(String(i));e.generation.active&&this._chat.next({...this._chat.value,error:t}),this._context.domainServicesSelectors.getLogger().error("The assistant message could not be sent",{},t)}};_resume=async e=>{this._chat.next({...this._chat.value,isResuming:!0,error:void 0,failedStatus:void 0});try{let{previousThreadId:t}=await e.authorizedClient.compactAssistantThread(e.configurationId);if(!e.generation.active)return!1;let{messages:i,earlierThreads:s,hasEarlierThread:a}=this._chat.value,r=this._refused?.chat===e?i.slice(0,this._refused.index):i;return e.generation.active=!1,this._current=null,e.client.stop(),e.dispose(),this._chat.next({...c,earlierThreads:[...s,{threadId:t,messages:r}],hasEarlierThread:a,isLoadingEarlierThread:null!==this._loadingThreadId}),this._startClient(),!0}catch(i){let t=i instanceof Error?i:Error(String(i));if(t instanceof r&&409===t.status)return e.generation.active&&this.reloadThread(),!1;return e.generation.active&&this._chat.next({...this._chat.value,isResuming:!1,error:t,failedStatus:t instanceof r?t.status:void 0}),this._context.domainServicesSelectors.getLogger().error("The assistant thread could not be resumed",{},t),!1}};_findTipToolCallId=()=>{let e=this._context.domainContextSelectors.getUndoSystem(),t=e.tip$.value?.committedState;return void 0!==t&&e.canUndo()?this._applyToolCallIds.get(t):void 0};_refreshUndoTip=()=>{let e=this._findTipToolCallId();e!==this._undoTipToolCallId.value&&this._undoTipToolCallId.next(e)};_committedState=()=>this._context.domainContextSelectors.getStoreSystem().stateSlices.committed.value.state;_patchPanel=e=>{let t={...this._panel.value,...e};a(t,this._panel.value)||this._panel.next(t)};_takeOverThread=e=>{for(let t of this._finishing)t.configurationId===e&&(t.client.stop(),t.dispose())};_startClient=()=>{let i={active:!0},s=this._context.getConfigurationId();this._takeOverThread(s);let r=this._context.getAuthorizedClient(),n=()=>{if(i.active){let{manifest:e,error:t}=this._context.getAssistantSetup();if(t)throw t;if(!e)throw Error("The assistant is disabled for this session.")}return r.getAssistantChatConnection(s)},o=e=>{if(!i.active)return;let t={...this._chat.value,...e};a(t,this._chat.value)||this._chat.next(t)},l=async(e,t)=>{let s=await fetch(e,t).finally(()=>o({isLoaded:!0})),a=s.headers.get("x-assistant-thread-continuable");return null!=a&&s.ok&&i.active&&0===this._chat.value.earlierThreads.length&&(this._olderThreadId=s.headers.get("x-assistant-previous-thread")),o({failedStatus:s.ok?void 0:s.status,...null!=a&&{isContinuable:"false"!==a,hasEarlierThread:null!==this._olderThreadId}}),s},h=async()=>({headers:await n().headers(),fetchClient:l}),d=t(()=>n().url,h),c=t(()=>`${n().url}/runs`,h),u=this._tools.map(e=>({...e,execute:(t,s)=>{if(!i.active)return g;let{manifest:a,error:r}=this._context.getAssistantSetup();return r||!a?{error:r?.message??"The assistant is disabled for this session."}:e.execute?.(t,s)}})),_=new e({threadId:`assistant:${s}`,connection:{...d,joinRun:c.joinRun},persistence:!0,history:{pageSize:50},tools:u,onMessagesChange:e=>o({messages:e}),onLoadingChange:e=>{let t=i.active&&this._chat.value.isLoading;o({isLoading:e}),!e&&m(_)&&(i.active?t&&!this._panel.value.open&&this._patchPanel({hasUnreadReply:!0}):p())},onErrorChange:e=>{i.active&&e!==this._chat.value.error&&(!e||-1===this._findRefusedMessageIndex(v))&&(o({error:e}),e&&this._context.domainServicesSelectors.getLogger().error("The assistant request failed",{status:this._chat.value.failedStatus},e))}}),f=!1,p=()=>{f||(f=!0,this._finishing.delete(v),_.dispose())},v={client:_,configurationId:s,generation:i,authorizedClient:r,getConnection:n,dispose:p};this._current=v,_.attach()};_retireChat=()=>{let e=this._current;return this._current=null,e&&(e.generation.active=!1),this._chain={},this._olderThreadId=null,this._resuming=null,this._refused=null,this._loadingThreadId=null,this._chat.value!==c&&this._chat.next(c),e};_endChat=()=>{let e=this._retireChat();if(e){if(!e.client.getIsLoading()&&m(e.client))return void e.dispose();this._finishing.add(e)}}}
|
|
1
|
+
import{ChatClient as e,fetchServerSentEvents as t}from"@tanstack/ai-client";import{BehaviorSubject as s}from"rxjs";import{skip as i}from"rxjs/operators";import{isShallowEqual as a}from"@salsita-ai/common/utils";import{AssistantRequestError as r}from"#package/client";import{createBrowserDetailsClientTool as n}from"./browser-details.js";import{ChangeRecorder as o}from"./change-recorder.js";import{createApplyClientTool as l,createQueryClientTool as h,toToolResult as d}from"./graphql-tools.js";let c=Object.freeze({messages:Object.freeze([]),isLoading:!1,error:void 0,failedStatus:void 0,isContinuable:!0,isLoaded:!1,isResuming:!1,earlierThreads:Object.freeze([]),hasEarlierThread:!1,isLoadingEarlierThread:!1}),u=Object.freeze({open:!1,hasUnreadReply:!1,isInputFocused:!1}),_=Object.freeze({}),g=d({results:[],committed:!1,sideEffects:[],screenshots:new Map,message:"Nothing was run, because the user closed the configurator while this reply was being written. Do not call any more tools in this reply and end it now. The tools work again as soon as the user writes the next message."}),f=e=>{if(e.getError())return!0;let t=e.getMessages().at(-1)?.parts.at(-1);return t?.type!=="tool-call"&&t?.type!=="tool-result"};export class AssistantSystem{_context;_tools;_chat=new s(c);_panel=new s(u);_activation=null;_current=null;_finishing=new Set;_olderThreadId=null;_resuming=null;_refused=null;_firstAttempt=null;_chain={};_loadingThreadId=null;_recorder;_recording=null;_applyToolCallIds=new WeakMap;_undoTipToolCallId=new s(void 0);_screenshotUrls=new Map;constructor(e){this._context=e;let{configuratorExtensionSelectors:t,domainContextSelectors:s,domainServicesSelectors:i,getAssistantSetup:a}=e;this._recorder=new o({maxEntities:30},{readers:{selectedEntityId:e=>s.getNavigationSystem().getActiveSelectionState(e),navigationState:e=>s.getNavigationSystem().getActiveNavigationState(e),viewState:e=>s.getNavigationSystem().getActiveViewState(e),toolState:e=>s.getNavigationSystem().getActiveToolState(e)},getExposedFields:()=>a().manifest?.fields??_,resolveLocalizable:e=>i.getResolveLocalizable()(e)});let r={getGraphQLSystem:()=>t.getGraphQLSystem(),getStoreSystem:()=>s.getStoreSystem(),getActiveMode:()=>s.getActiveMode(),getIsViewMode:()=>s.getIsViewMode(),clearChanges:()=>this._recorder.clear(this._committedState()),rememberCommit:(e,t)=>{this._applyToolCallIds.set(t,e),this._refreshUndoTip()}};this._tools=[n(),h(r),l(r)],s.getUndoSystem().tip$.subscribe(this._refreshUndoTip)}chat$=this._chat;panel$=this._panel;undoTipToolCallId$=this._undoTipToolCallId;getSessionManifest=()=>this._context.getAssistantSetup().manifest;initialize=()=>{let{committed:e}=this._context.domainContextSelectors.getStoreSystem().stateSlices;this._recording??=e.pipe(i(1)).subscribe(this._recorder.record),this._recorder.reset(e.value.state),this._endChat(),this._patchPanel(u),this._releaseScreenshotUrls(),this._activation&&this._startClient()};activate=()=>{this._endChat();let e={};return this._activation=e,this._startClient(),()=>{this._activation===e&&(this._activation=null,this._endChat())}};send=async e=>{if(!this._chat.value.isContinuable&&!await this.resume())return;let t=this._current;if(!t)return;let s={changes:this._recorder.take(this._committedState())};this._firstAttempt=t;try{await this._sendOn(t,e,s);let i=this._findRefusedMessageIndex(t);if(-1===i)return;this._refused={chat:t,index:i}}finally{this._firstAttempt===t&&(this._firstAttempt=null)}if(!await this.resume())return;let i=this._current;i&&await this._sendOn(i,e,s)};resume=async()=>{let e=this._current;if(!e)return!1;if(this._chat.value.isContinuable)return!0;if(this._resuming)return this._resuming;let t=this._resume(e).finally(()=>{this._resuming===t&&(this._resuming=null)});return this._resuming=t,t};loadScreenshotUrl=e=>{let t=this._screenshotUrls.get(e);if(t)return t;let s=this._current;if(!s)return Promise.reject(Error(`The screenshot ${e} cannot be read, because the assistant chat is not active. Open the assistant panel of the configuration first.`));let i=this._screenshotUrls,a=s.authorizedClient.getAssistantImage(s.configurationId,e).then(e=>URL.createObjectURL(e));return i.set(e,a),a.catch(()=>{i.get(e)===a&&i.delete(e)}),a};loadEarlierThread=async()=>{let e=this._current,t=this._olderThreadId;if(!e||null===t||this._loadingThreadId===t)return;let s=this._chain;this._loadingThreadId=t,this._chat.next({...this._chat.value,isLoadingEarlierThread:!0});try{let i=await e.authorizedClient.getAssistantEarlierThread(e.configurationId,t,50);if(this._chain!==s||this._olderThreadId!==t)return;this._olderThreadId=i.previousThreadId,this._chat.next({...this._chat.value,earlierThreads:[{threadId:t,messages:i.messages},...this._chat.value.earlierThreads],hasEarlierThread:null!==i.previousThreadId})}catch(e){this._context.domainServicesSelectors.getLogger().warn("Could not load the earlier assistant conversation",{error:e})}finally{this._chain===s&&this._loadingThreadId===t&&(this._loadingThreadId=null,this._chat.next({...this._chat.value,isLoadingEarlierThread:!1}))}};stop=async()=>{let e=this._current;if(!e)return;let t=e.client.getCurrentRunId();if(e.client.stop(),null!=t)try{let s=e.getConnection();await fetch(`${s.url}/runs/${encodeURIComponent(t)}/cancel`,{method:"POST",headers:await s.headers()})}catch(e){this._context.domainServicesSelectors.getLogger().warn("Could not cancel the assistant run on the server",{error:e})}};reloadThread=()=>{if(!this._activation)return;let e=this._retireChat();e?.client.stop(),e?.dispose(),this._recorder.reset(this._committedState()),this._startClient()};undoToolCalls=e=>{let t=this._context.domainContextSelectors.getUndoSystem(),s=()=>{let t=this._findTipToolCallId();return void 0!==t&&e.has(t)};for(;s();)t.undo()};setOpen=e=>{this._patchPanel(e?{open:e,hasUnreadReply:!1}:{open:e,isInputFocused:!1})};setInputFocused=e=>{this._patchPanel({isInputFocused:e})};_findRefusedMessageIndex=e=>{var t;let s,{failedStatus:i,isContinuable:a}=this._chat.value;return this._firstAttempt===e&&e.generation.active&&409===i&&!a?(s=(t=e.client.getMessages()).map(e=>e.role).lastIndexOf("user"),t.slice(s+1).every(e=>0===e.parts.length)?s:-1):-1};_sendOn=async(e,t,s)=>{let{client:i}=e;i.getIsLoading()||null===i.getResumeState()||i.stop();try{await i.sendMessage({content:t,metadata:s})}catch(s){let t=s instanceof Error?s:Error(String(s));e.generation.active&&this._chat.next({...this._chat.value,error:t}),this._context.domainServicesSelectors.getLogger().error("The assistant message could not be sent",{},t)}};_resume=async e=>{this._chat.next({...this._chat.value,isResuming:!0,error:void 0,failedStatus:void 0});try{let{previousThreadId:t}=await e.authorizedClient.compactAssistantThread(e.configurationId);if(!e.generation.active)return!1;let{messages:s,earlierThreads:i,hasEarlierThread:a}=this._chat.value,r=this._refused?.chat===e?s.slice(0,this._refused.index):s;return e.generation.active=!1,this._current=null,e.client.stop(),e.dispose(),this._chat.next({...c,earlierThreads:[...i,{threadId:t,messages:r}],hasEarlierThread:a,isLoadingEarlierThread:null!==this._loadingThreadId}),this._startClient(),!0}catch(s){let t=s instanceof Error?s:Error(String(s));if(t instanceof r&&409===t.status)return e.generation.active&&this.reloadThread(),!1;return e.generation.active&&this._chat.next({...this._chat.value,isResuming:!1,error:t,failedStatus:t instanceof r?t.status:void 0}),this._context.domainServicesSelectors.getLogger().error("The assistant thread could not be resumed",{},t),!1}};_findTipToolCallId=()=>{let e=this._context.domainContextSelectors.getUndoSystem(),t=e.tip$.value?.committedState;return void 0!==t&&e.canUndo()?this._applyToolCallIds.get(t):void 0};_refreshUndoTip=()=>{let e=this._findTipToolCallId();e!==this._undoTipToolCallId.value&&this._undoTipToolCallId.next(e)};_committedState=()=>this._context.domainContextSelectors.getStoreSystem().stateSlices.committed.value.state;_patchPanel=e=>{let t={...this._panel.value,...e};a(t,this._panel.value)||this._panel.next(t)};_takeOverThread=e=>{for(let t of this._finishing)t.configurationId===e&&(t.client.stop(),t.dispose())};_startClient=()=>{let s={active:!0},i=this._context.getConfigurationId();this._takeOverThread(i);let r=this._context.getAuthorizedClient(),n=()=>{if(s.active){let{manifest:e,error:t}=this._context.getAssistantSetup();if(t)throw t;if(!e)throw Error("The assistant is disabled for this session.")}return r.getAssistantChatConnection(i)},o=e=>{if(!s.active)return;let t={...this._chat.value,...e};a(t,this._chat.value)||this._chat.next(t)},l=async(e,t)=>{let i=await fetch(e,t).finally(()=>o({isLoaded:!0})),a=i.headers.get("x-assistant-thread-continuable");return null!=a&&i.ok&&s.active&&0===this._chat.value.earlierThreads.length&&(this._olderThreadId=i.headers.get("x-assistant-previous-thread")),o({failedStatus:i.ok?void 0:i.status,...null!=a&&{isContinuable:"false"!==a,hasEarlierThread:null!==this._olderThreadId}}),i},h=async()=>({headers:await n().headers(),fetchClient:l}),d=t(()=>n().url,h),c=t(()=>`${n().url}/runs`,h),u=this._tools.map(e=>({...e,execute:(t,i)=>{if(!s.active)return g;let{manifest:a,error:r}=this._context.getAssistantSetup();return r||!a?{error:r?.message??"The assistant is disabled for this session."}:e.execute?.(t,i)}})),_=new e({threadId:`assistant:${i}`,connection:{...d,joinRun:c.joinRun},persistence:!0,history:{pageSize:50},tools:u,onMessagesChange:e=>o({messages:e}),onLoadingChange:e=>{let t=s.active&&this._chat.value.isLoading;o({isLoading:e}),!e&&f(_)&&(s.active?t&&!this._panel.value.open&&this._patchPanel({hasUnreadReply:!0}):p())},onErrorChange:e=>{s.active&&e!==this._chat.value.error&&(!e||-1===this._findRefusedMessageIndex(v))&&(o({error:e}),e&&this._context.domainServicesSelectors.getLogger().error("The assistant request failed",{status:this._chat.value.failedStatus},e))}}),m=!1,p=()=>{m||(m=!0,this._finishing.delete(v),_.dispose())},v={client:_,configurationId:i,generation:s,authorizedClient:r,getConnection:n,dispose:p};this._current=v,_.attach()};_retireChat=()=>{let e=this._current;return this._current=null,e&&(e.generation.active=!1),this._chain={},this._olderThreadId=null,this._resuming=null,this._refused=null,this._loadingThreadId=null,this._chat.value!==c&&this._chat.next(c),e};_releaseScreenshotUrls=()=>{for(let e of this._screenshotUrls.values())e.then(URL.revokeObjectURL,()=>void 0);this._screenshotUrls=new Map};_endChat=()=>{let e=this._retireChat();if(e){if(!e.client.getIsLoading()&&f(e.client))return void e.dispose();this._finishing.add(e)}}}
|
package/dist/configurator/application-runtime/extensions/systems/assistant-system/graphql-tools.d.ts
CHANGED
|
@@ -35,7 +35,8 @@ export interface AssistantToolDependencies {
|
|
|
35
35
|
/**
|
|
36
36
|
* A tool result as the chat client accepts it: content parts, the execution's JSON as a text part
|
|
37
37
|
* followed, per screenshot, by its label as a text part and its picture as an image part, so the
|
|
38
|
-
* model reads each picture under the label its `image` field returned
|
|
38
|
+
* model reads each picture under the label its `image` field returned; the image part references the picture the browser uploaded, which the server
|
|
39
|
+
* inlines only for the model. The client deep-clones a
|
|
39
40
|
* result and rejects anything that is not plain JSON, so the `GraphQLError` instances of a result
|
|
40
41
|
* are formatted through their `toJSON` and `undefined` members are dropped. The prepared state stays
|
|
41
42
|
* in the browser.
|
package/dist/configurator/application-runtime/extensions/systems/assistant-system/graphql-tools.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{AssistantGraphQLToolInput as e,applyTool as t,queryTool as
|
|
1
|
+
import{AssistantGraphQLToolInput as e,applyTool as t,assistantImageReference as o,queryTool as i}from"@salsita-ai/contracts/assistant";let a=e=>({results:[],committed:!1,message:e,sideEffects:[],screenshots:new Map});export const toToolResult=({preparedState:e,screenshots:t,...i})=>[{type:"text",content:JSON.stringify(i)},...[...t].flatMap(([e,{imageId:t}])=>[{type:"text",content:e},{type:"image",source:{type:"url",value:o(t)}}])];let s=t=>{let o=e.safeParse(t);if(!o.success){let e=o.error.issues.map(e=>`${e.path.join(".")}: ${e.message}`).join("; ");return{ok:!1,refusal:a(`Nothing was run, because the tool input is not a list of operations (${e}). Send { "operations": [{ "query": "<one GraphQL operation>" }] } with at least one item.`)}}return{ok:!0,operations:o.data.operations.map(({query:e,variables:t,operationName:o})=>({document:e,variables:t??void 0,operationName:o??void 0}))}};export const createQueryClientTool=e=>i.client(async t=>{let o=s(t);if(!o.ok)return toToolResult(o.refusal);let i=e.getStoreSystem();if(!i.isInitialized)return toToolResult(a("Nothing was run, because the configuration is not loaded yet, so there is no state to query. Call the tool again once the configurator has finished loading."));let n=e.getGraphQLSystem(),r=await n.prepare(i.stateSlices.committed.value.state,o.operations);return toToolResult({results:r.map(({result:e})=>e),committed:!1,sideEffects:n.readSideEffects(r),screenshots:n.readScreenshots(r)})});export const createApplyClientTool=e=>t.client(async(t,o)=>{if("finalize"===e.getActiveMode())return toToolResult(a("Nothing was run, because changes cannot be applied in this session: the user may view this configuration but not change it. The query tool still works here, including mutations, to show what a change would do without keeping it."));if(e.getIsViewMode())return toToolResult(a("Nothing was run, because the configuration is read-only right now: the user may view it but not change it. The query tool still works here, including mutations, to show what a change would do without keeping it. Call apply again only once the configuration is editable."));let i=s(t);if(!i.ok)return toToolResult(i.refusal);let n=await e.getGraphQLSystem().execute(i.operations),r=o?.toolCallId;return void 0!==r&&void 0!==n.preparedState&&e.rememberCommit(r,n.preparedState),n.committed&&e.clearChanges(),toToolResult(n)});
|