@salsita-ai/sdk 0.50.0-develop.b7caacb493 → 0.50.0-develop.b956e273cc

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/dist/application/index.d.ts +1 -0
  2. package/dist/application/index.js +1 -1
  3. package/dist/application/mount-application.d.ts +1 -1
  4. package/dist/application/mount-application.js +1 -1
  5. package/dist/application/mount-configurator.d.ts +19 -0
  6. package/dist/application/mount-configurator.js +1 -0
  7. package/dist/application/mounted-application-runtime.d.ts +4 -0
  8. package/dist/application/mounted-application-runtime.js +1 -0
  9. package/dist/application/register-web-component.d.ts +2 -0
  10. package/dist/application/register-web-component.js +1 -0
  11. package/dist/application-spec/generate-application/code/templates/skills/phoenix-skill.js +1 -1
  12. package/dist/application-spec/generate-application/index.d.ts +1 -0
  13. package/dist/application-spec/generate-application/index.js +1 -1
  14. package/dist/application-spec/generate-application/runtime/admin-runtime/admin-runtime.d.ts +2 -0
  15. package/dist/application-spec/generate-application/runtime/admin-runtime/admin-runtime.js +1 -1
  16. package/dist/application-spec/generate-application/runtime/application-runtime.d.ts +5 -0
  17. package/dist/application-spec/generate-application/runtime/application-runtime.js +1 -1
  18. package/dist/application-spec/generate-application/runtime/application-spec-slice.d.ts +2 -1
  19. package/dist/application-spec/generate-application/runtime/configurator-runtime/configurator-runtime.d.ts +2 -0
  20. package/dist/application-spec/generate-application/runtime/configurator-runtime/configurator-runtime.js +1 -1
  21. package/dist/application-spec/generate-application/runtime/create-application.d.ts +57 -0
  22. package/dist/application-spec/generate-application/runtime/create-application.js +1 -0
  23. package/dist/client/authorized-client.d.ts +3 -1
  24. package/dist/client/authorized-client.js +1 -1
  25. package/dist/client/contract.d.ts +17 -0
  26. package/dist/client/index.d.ts +1 -1
  27. package/dist/client/local-authorized-client.d.ts +3 -1
  28. package/dist/client/local-authorized-client.js +1 -1
  29. package/dist/client/memory-authorized-client.d.ts +4 -1
  30. package/dist/client/memory-authorized-client.js +1 -1
  31. package/dist/client/phoenix-api.d.ts +228 -0
  32. package/dist/configurator/application-runtime/extensions/selectors.js +1 -1
  33. package/dist/configurator/application-runtime/extensions/systems/assistant-system/assistant-system.d.ts +13 -0
  34. package/dist/configurator/application-runtime/extensions/systems/assistant-system/assistant-system.js +1 -1
  35. package/dist/configurator/application-runtime/extensions/systems/assistant-system/graphql-tools.d.ts +2 -1
  36. package/dist/configurator/application-runtime/extensions/systems/assistant-system/graphql-tools.js +1 -1
  37. package/dist/configurator/application-runtime/extensions/systems/graphql-system/graphql-system.d.ts +15 -9
  38. package/dist/configurator/application-runtime/extensions/systems/graphql-system/graphql-system.js +1 -1
  39. package/dist/configurator/ui/assistant/screenshots/ScreenshotThumbnails.d.ts +1 -1
  40. package/dist/configurator/ui/assistant/screenshots/ScreenshotThumbnails.js +1 -1
  41. package/dist/configurator/ui/assistant/screenshots/tool-screenshots.d.ts +12 -4
  42. package/dist/configurator/ui/assistant/screenshots/tool-screenshots.js +1 -1
  43. package/dist/configurator/ui/assistant/screenshots/use-screenshot-src.d.ts +8 -0
  44. package/dist/configurator/ui/assistant/screenshots/use-screenshot-src.js +1 -0
  45. package/dist/docs/index.json +1 -1
  46. package/dist/docs/phoenix/domain-model.mdx +4 -1
  47. package/dist/docs/phoenix/phoenix-cli.mdx +8 -2
  48. package/dist/docs/phoenix/sdk-builder-workflow.mdx +4 -2
  49. package/dist/domain/application/assistant/build-assistant-manifest.js +1 -1
  50. package/dist/domain/application/assistant/generate-assistant-prompt.js +1 -1
  51. package/dist/domain/application/configurator-builder.d.ts +7 -1
  52. package/dist/domain/application/configurator-builder.js +1 -1
  53. package/dist/domain/application/index.d.ts +1 -1
  54. package/dist/domain/application/index.js +1 -1
  55. package/dist/domain/domain-runtime/application.d.ts +39 -0
  56. package/dist/domain/domain-runtime/application.js +1 -0
  57. package/dist/domain/domain-runtime/domain-runtime.d.ts +18 -4
  58. package/dist/domain/domain-runtime/domain-runtime.js +1 -1
  59. package/dist/domain/domain-runtime/environment/initialize.d.ts +1 -1
  60. package/dist/domain/domain-runtime/index.d.ts +1 -0
  61. package/dist/domain/domain-runtime/index.js +1 -1
  62. package/dist/phoenix/application-spec/resolve-deployment-data.d.ts +11 -0
  63. package/dist/phoenix/application-spec/resolve-deployment-data.js +2 -2
  64. package/dist/phoenix/cli.js +1 -1
  65. package/dist/phoenix/commands/dev.js +5 -5
  66. package/dist/phoenix/commands/generated-env-markers.d.ts +1 -0
  67. package/dist/phoenix/commands/generated-env-markers.js +1 -1
  68. package/dist/phoenix/services/application-spec-project-watcher.d.ts +3 -1
  69. package/dist/phoenix/services/application-spec-project-watcher.js +2 -2
  70. package/dist/phoenix/services/prepare-development-environment.js +1 -1
  71. package/dist/react-sdk/application-runtime/common-services/analytics/analytics-service.d.ts +1 -1
  72. package/dist/react-sdk/application-runtime/common-services/initialize.d.ts +2 -2
  73. package/dist/react-sdk/application-runtime/runtime/create-application-runtime.d.ts +17 -6
  74. package/dist/react-sdk/application-runtime/runtime/create-application-runtime.js +1 -1
  75. package/package.json +3 -3
@@ -1,3 +1,4 @@
1
1
  export { mountApplication,
2
2
  /** @deprecated Use embedded admin in Editor instead */
3
3
  mountStandaloneAdminApplication, mountConfiguratorApplication, mountEmbeddedAdminApplication, mountEmbeddedConfiguratorApplication, embeddedModuleSchema, } from './mount-application.js';
4
+ export { mountConfigurator } from './mount-configurator.js';
@@ -1 +1 @@
1
- export{mountApplication,mountStandaloneAdminApplication,mountConfiguratorApplication,mountEmbeddedAdminApplication,mountEmbeddedConfiguratorApplication,embeddedModuleSchema}from"./mount-application.js";
1
+ export{mountApplication,mountStandaloneAdminApplication,mountConfiguratorApplication,mountEmbeddedAdminApplication,mountEmbeddedConfiguratorApplication,embeddedModuleSchema}from"./mount-application.js";export{mountConfigurator}from"./mount-configurator.js";
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import type { $DomainEntity, ApplicationConfig, DomainEntity } from '#package/domain';
2
+ import { type $DomainEntity, type ApplicationConfig, type DomainEntity } from '#package/domain';
3
3
  export declare const embeddedModuleSchema: z.ZodObject<{
4
4
  default: z.ZodObject<{
5
5
  mount: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodString>;
@@ -1 +1 @@
1
- import{jsx as o}from"react/jsx-runtime";import{z as t}from"zod";import{Application as n,EmbeddedAdmin as e,StandaloneAdmin as i}from"#package/admin";import{ConfiguratorApp as p,createConfiguratorExtensions as a}from"#package/configurator";import{createApplicationRuntime as m,createWebComponent as r}from"#package/react-sdk";export const embeddedModuleSchema=t.object({default:t.object({mount:t.function().returns(t.string()),config:t.unknown()})});let c=(o,t)=>{customElements.get(o)?console.error(`Web component with tag name "${o}" is already registered.`):customElements.define(o,t)};export const mountApplication=t=>{let e=t.mount.Application?t.mount.Application(t):()=>o(n,{});c(t.mount.tag,r({RootComponent:e,webComponentOptions:t.mount.options,embeddedIntegration:!1,applicationRuntimeFactory:o=>m(t,o,a)}))};export const mountConfiguratorApplication=t=>{let n=t.mount.Application?t.mount.Application(t):()=>o(p,{});c(t.mount.tag,r({RootComponent:n,webComponentOptions:t.mount.options,embeddedIntegration:!1,applicationRuntimeFactory:o=>m(t,o,a)}))};export const mountStandaloneAdminApplication=t=>{c("salsita-admin",r({RootComponent:()=>o(i,{}),webComponentOptions:{},embeddedIntegration:!1,applicationRuntimeFactory:o=>m(t,o,a)}))};export const mountEmbeddedAdminApplication=(t,n,i)=>{c(`salsita-admin-${n}-${i}`,r({RootComponent:()=>o(e,{}),webComponentOptions:{},embeddedIntegration:!0,applicationRuntimeFactory:o=>m(t,o,a)}))};export const mountEmbeddedConfiguratorApplication=(t,n,e)=>{c(`salsita-configurator-${n}-${e}`,r({RootComponent:t.mount.Application?t.mount.Application(t):()=>o(p,{}),webComponentOptions:t.mount.options,embeddedIntegration:!0,applicationRuntimeFactory:o=>m(t,o,a)}))};
1
+ import{jsx as o}from"react/jsx-runtime";import{z as t}from"zod";import{Application as n,EmbeddedAdmin as i,StandaloneAdmin as e}from"#package/admin";import{ConfiguratorApp as p}from"#package/configurator";import{applicationFromConfig as m}from"#package/domain";import{createWebComponent as a}from"#package/react-sdk";import{createMountedApplicationRuntime as r}from"./mounted-application-runtime.js";import{registerWebComponent as c}from"./register-web-component.js";export const embeddedModuleSchema=t.object({default:t.object({mount:t.function().returns(t.string()),config:t.unknown()})});export const mountApplication=t=>{let i=t.mount.Application?t.mount.Application(t):()=>o(n,{});c(t.mount.tag,a({RootComponent:i,webComponentOptions:t.mount.options,embeddedIntegration:!1,applicationRuntimeFactory:o=>r(m(t),o)}))};export const mountConfiguratorApplication=t=>{let n=t.mount.Application?t.mount.Application(t):()=>o(p,{});c(t.mount.tag,a({RootComponent:n,webComponentOptions:t.mount.options,embeddedIntegration:!1,applicationRuntimeFactory:o=>r(m(t),o)}))};export const mountStandaloneAdminApplication=t=>{c("salsita-admin",a({RootComponent:()=>o(e,{}),webComponentOptions:{},embeddedIntegration:!1,applicationRuntimeFactory:o=>r(m(t),o)}))};export const mountEmbeddedAdminApplication=(t,n,e)=>{c(`salsita-admin-${n}-${e}`,a({RootComponent:()=>o(i,{}),webComponentOptions:{},embeddedIntegration:!0,applicationRuntimeFactory:o=>r(m(t),o)}))};export const mountEmbeddedConfiguratorApplication=(t,n,i)=>{c(`salsita-configurator-${n}-${i}`,a({RootComponent:t.mount.Application?t.mount.Application(t):()=>o(p,{}),webComponentOptions:t.mount.options,embeddedIntegration:!0,applicationRuntimeFactory:o=>r(m(t),o)}))};
@@ -0,0 +1,19 @@
1
+ import { type Application } from '#package/domain';
2
+ /**
3
+ * Declares the web component of a configurator application built from its runtime spec
4
+ * (`createApplication` of `@salsita-ai/sdk/application-spec`), with no `ApplicationConfig`.
5
+ *
6
+ * It registers `application.tag`; every `<tag></tag>` element in the DOM renders the configurator
7
+ * in a closed shadow DOM. The web component's properties and events and the wrapper of the
8
+ * application come from the project's `GetWebComponentOptions` and `GetApplicationWrapper` handlers.
9
+ * With `embedded`, the configurator integrates with the page that embeds it, as
10
+ * `mountEmbeddedConfiguratorApplication` does; the embedding host looks for the tag
11
+ * `salsita-configurator-<project slug>-<environment slug>`, which the caller passes to
12
+ * `createApplication` as `tag`.
13
+ *
14
+ * It runs the same runtime as `mountConfiguratorApplication`, which converts its config to an
15
+ * application first.
16
+ */
17
+ export declare const mountConfigurator: <TYPES>(application: Application<TYPES>, options?: {
18
+ readonly embedded?: boolean;
19
+ }) => void;
@@ -0,0 +1 @@
1
+ import{jsx as o}from"react/jsx-runtime";import{ConfiguratorApp as r}from"#package/configurator";import{isGetApplicationWrapperHandler as t,isGetWebComponentOptionsHandler as e}from"#package/domain";import{createWebComponent as n}from"#package/react-sdk";import{createMountedApplicationRuntime as a}from"./mounted-application-runtime.js";import{registerWebComponent as i}from"./register-web-component.js";export const mountConfigurator=(m,p={})=>{let{handlers:d}=m.spec.configurator,c=d.find(t)?.handler().handler,f=d.find(e)?.handler().handler(void 0),s=c?c(m):()=>o(r,{});i(m.tag,n({RootComponent:s,webComponentOptions:f??{},embeddedIntegration:p.embedded??!1,applicationRuntimeFactory:o=>a(m,o)}))};
@@ -0,0 +1,4 @@
1
+ import { type AnyConfiguratorExtensionSystems } from '#package/configurator';
2
+ import type { Application } from '#package/domain';
3
+ import { type ApplicationRuntime, type ApplicationRuntimeBootConfig } from '#package/react-sdk';
4
+ export declare const createMountedApplicationRuntime: (application: Application, bootConfig: ApplicationRuntimeBootConfig) => ApplicationRuntime<AnyConfiguratorExtensionSystems>;
@@ -0,0 +1 @@
1
+ import{createConfiguratorExtensions as o}from"#package/configurator";import{createApplicationRuntime as t}from"#package/react-sdk";export const createMountedApplicationRuntime=(r,a)=>t(r,a,o);
@@ -0,0 +1,2 @@
1
+ /** Defines the custom element of a mounted application, unless its tag is taken. */
2
+ export declare const registerWebComponent: (tag: string, element: CustomElementConstructor) => void;
@@ -0,0 +1 @@
1
+ export const registerWebComponent=(e,t)=>{customElements.get(e)?console.error(`Web component with tag name "${e}" is already registered.`):customElements.define(e,t)};
@@ -1 +1 @@
1
- import{renderAgentSkill as e}from"./agent-skill.js";import{sdkGuidanceSections as t}from"./sdk-content.js";export const followsCanaryBuilds=e=>!e.useWorkspace&&e.sdkVersion.includes("-develop.");export const generatePhoenixSkill=({checkLatestCanary:n})=>e({name:"phoenix",description:`Phoenix SDK project conventions, covering project structure, architecture principles, key patterns, file and export rules, webhook membership, versioning the domain model once it is deployed, showing the user the dev preview and the build of a deploy, the run evaluation that follows a live deploy, inspecting the rendered result, and how to search the SDK documentation${n?", and the internal-beta check for the latest canary SDK build":""}. Use before writing or changing specs or source code, or deploying this Phoenix configurator project.`,sections:[t.packageManager,...n?["## Stay on the Latest Canary\nDuring the internal beta this project uses the `canary` build of the SDK, which is published from every change to the platform. Once per conversation, before you change anything, compare the installed version, the `version` in `node_modules/@salsita-ai/sdk/package.json`, with the newest canary:\n```bash\nnpm view @salsita-ai/sdk@canary version\n```\nWhen they differ, tell the user which version you are moving to, then update the SDK, bring the packages it needs next to it in line, and regenerate the project's files:\n```bash\npnpm add @salsita-ai/sdk@canary && pnpm phoenix deps && pnpm install && pnpm phoenix sync\n```\n`sync` rewrites the Phoenix skills, so read the ones you use again after it. When the user runs a globally installed `phoenix`, update that too with `npm install -g @salsita-ai/sdk@canary`. If the project no longer builds after the update, stop and tell the user; the `phoenix-feedback` skill covers reporting it."]:[],t.projectStructure,t.architecturePrinciples,t.keyPatterns,t.fileConventions,t.exportRules,t.webhookMembership,t.doNotEdit,t.modelVersioning,"## Show the Preview While You Work\nThe user should see the configurator change as you build it. Before your first change in a conversation, make sure `pnpm phoenix dev` is running (start it in the background when it is not) and open the address it prints as `Preview: <url>` (also written to `.phoenix/phoenix-dev.log`) in the user's browser: `open '<url>'` on macOS, `xdg-open '<url>'` on Linux, `Start-Process '<url>'` in PowerShell, `start \"\" \"<url>\"` in cmd. Keep the quotes, the shell would otherwise read a `?` in the address as a pattern. The log keeps the lines of earlier runs, so when you have just started dev, wait for the `Preview:` line written after your start and use the last one. Open it once; the preview reloads on every change, so tell the user to keep that tab open instead of opening it again.",t.visualInspection,"## Show the Build After a Deploy\nImmediately before invoking `pnpm phoenix deploy`, refresh `conversation.log` in the project root with the current conversation. Prefer the agent application's native session export when available; do not invent an export command or scan unrelated sessions. Otherwise write the messages still available in context and label the log `reconstructed; incomplete`. Never present a compaction summary as verbatim earlier messages.\n\nUse UTF-8 text with a header naming the agent, export time, source (native export or reconstructed), covered session and known omissions. Preserve user and assistant messages in chronological order, plus tool names, arguments and results when available. Keep each tool result to at most 16 KiB of text, marking truncation explicitly; describe image attachments by reference rather than embedding binary/base64 data, and mark references whose files are not uploaded. Exclude internal instructions, hidden reasoning, credentials and unrelated sensitive content; mark redactions without repeating the removed content. Refresh the current session's log rather than appending duplicate copies or silently carrying over a previous session.\n\nShow the user the exact file to review or redact and obtain approval to include it before deploying; do not ask again when they have already approved that file. If they decline, move it out of the project root before deployment so it cannot be collected. Deploy includes the file in the build's private source archive, downloadable by those authorized to download that build's sources, and leaves it out when extracting build inputs. A missing log warns but does not block deployment. The CLI does not export, redact or validate the transcript's completeness for you.\n\n`pnpm phoenix deploy` starts a build on the server and waits for it to go live. Right after `Build <id> started` it prints `Follow the build in Studio: <url>`. Run the deploy so that you can read its output while it runs, and open that link in the user's browser, quoted as above, as soon as it appears, so they can follow the build they just triggered. When the line is missing, the sign-in is older than the link: tell the user the build is listed under Deployments in Studio, and that `pnpm phoenix login <workspace>` brings the link back.\n\nWhen the deploy reports the configurator live, load the `phoenix-feedback` skill before you write your final message and follow its \"Evaluate the Run\" section, so the user is asked about the run while they are still there. It is asked once per conversation, and only once the user has nothing more to build.","## Code Review\nUse the `phoenix-review` skill to review code changes before committing.",t.sdkDocumentation]});
1
+ import{renderAgentSkill as e}from"./agent-skill.js";import{sdkGuidanceSections as t}from"./sdk-content.js";export const followsCanaryBuilds=e=>!e.useWorkspace&&e.sdkVersion.includes("-develop.");export const generatePhoenixSkill=({checkLatestCanary:n})=>e({name:"phoenix",description:`Phoenix SDK project conventions, covering project structure, architecture principles, key patterns, file and export rules, webhook membership, versioning the domain model once it is deployed, showing the user the dev preview and the build of a deploy, the run evaluation that follows a live deploy, inspecting the rendered result, and how to search the SDK documentation${n?", and the internal-beta check for the latest canary SDK build":""}. Use before writing or changing specs or source code, or deploying this Phoenix configurator project.`,sections:[t.packageManager,...n?["## Stay on the Latest Canary\nDuring the internal beta this project uses the `canary` build of the SDK, which is published from every change to the platform. Once per conversation, before you change anything, compare the installed version, the `version` in `node_modules/@salsita-ai/sdk/package.json`, with the newest canary:\n```bash\nnpm view @salsita-ai/sdk@canary version\n```\nWhen they differ, tell the user which version you are moving to, then update the SDK, bring the packages it needs next to it in line, and regenerate the project's files:\n```bash\npnpm add @salsita-ai/sdk@canary && pnpm phoenix deps && pnpm install && pnpm phoenix sync\n```\n`sync` rewrites the Phoenix skills, so read the ones you use again after it. When the user runs a globally installed `phoenix`, update that too with `npm install -g @salsita-ai/sdk@canary`. If the project no longer builds after the update, stop and tell the user; the `phoenix-feedback` skill covers reporting it."]:[],t.projectStructure,t.architecturePrinciples,t.keyPatterns,t.fileConventions,t.exportRules,t.webhookMembership,t.doNotEdit,t.modelVersioning,"## Show the Preview While You Work\nThe user should see the configurator change as you build it. Before your first change in a conversation, make sure `pnpm phoenix dev` is running (start it in the background when it is not) and open the address it prints as `Preview: <url>` (also written to `.phoenix/phoenix-dev.log`) in the user's browser: `open '<url>'` on macOS, `xdg-open '<url>'` on Linux, `Start-Process '<url>'` in PowerShell, `start \"\" \"<url>\"` in cmd. Keep the quotes, the shell would otherwise read a `?` in the address as a pattern. The log keeps the lines of earlier runs, so when you have just started dev, wait for the `Preview:` line written after your start and use the last one. Open it once; the preview reloads on every change, so tell the user to keep that tab open instead of opening it again. A domain model change is the exception: `pnpm phoenix dev` registers the model with the server only when it starts, and after the change it logs an error that asks for a restart. Restart it, wait for the new `Preview:` line and open that address in place of the old tab, whose address carries the `?cid=` of a configuration saved with the earlier model, which the new model rejects.",t.visualInspection,"## Show the Build After a Deploy\nImmediately before invoking `pnpm phoenix deploy`, refresh `conversation.log` in the project root with the current conversation. Prefer the agent application's native session export when available; do not invent an export command or scan unrelated sessions. Otherwise write the messages still available in context and label the log `reconstructed; incomplete`. Never present a compaction summary as verbatim earlier messages.\n\nUse UTF-8 text with a header naming the agent, export time, source (native export or reconstructed), covered session and known omissions. Preserve user and assistant messages in chronological order, plus tool names, arguments and results when available. Keep each tool result to at most 16 KiB of text, marking truncation explicitly; describe image attachments by reference rather than embedding binary/base64 data, and mark references whose files are not uploaded. Exclude internal instructions, hidden reasoning, credentials and unrelated sensitive content; mark redactions without repeating the removed content. Refresh the current session's log rather than appending duplicate copies or silently carrying over a previous session.\n\nShow the user the exact file to review or redact and obtain approval to include it before deploying; do not ask again when they have already approved that file. If they decline, move it out of the project root before deployment so it cannot be collected. Deploy includes the file in the build's private source archive, downloadable by those authorized to download that build's sources, and leaves it out when extracting build inputs. A missing log warns but does not block deployment. The CLI does not export, redact or validate the transcript's completeness for you.\n\n`pnpm phoenix deploy` starts a build on the server and waits for it to go live. Right after `Build <id> started` it prints `Follow the build in Studio: <url>`. Run the deploy so that you can read its output while it runs, and open that link in the user's browser, quoted as above, as soon as it appears, so they can follow the build they just triggered. When the line is missing, the sign-in is older than the link: tell the user the build is listed under Deployments in Studio, and that `pnpm phoenix login <workspace>` brings the link back.\n\nWhen the deploy reports the configurator live, load the `phoenix-feedback` skill before you write your final message and follow its \"Evaluate the Run\" section, so the user is asked about the run while they are still there. It is asked once per conversation, and only once the user has nothing more to build.","## Code Review\nUse the `phoenix-review` skill to review code changes before committing.",t.sdkDocumentation]});
@@ -1,6 +1,7 @@
1
1
  export * from './runtime/sections/index.js';
2
2
  export * from './runtime/application-runtime.js';
3
3
  export { applicationSpecSlice, type ApplicationSpecSliceModules } from './runtime/application-spec-slice.js';
4
+ export { type ApplicationModules, createApplication } from './runtime/create-application.js';
4
5
  export * from './runtime/factory-data/index.js';
5
6
  export * from './runtime/migrations/index.js';
6
7
  export { isConfiguratorModelSchemaCompatible } from './runtime/configurator-runtime/configurator-model-runtime.js';
@@ -1 +1 @@
1
- export*from"./runtime/sections/index.js";export*from"./runtime/application-runtime.js";export{applicationSpecSlice}from"./runtime/application-spec-slice.js";export*from"./runtime/factory-data/index.js";export*from"./runtime/migrations/index.js";export{isConfiguratorModelSchemaCompatible}from"./runtime/configurator-runtime/configurator-model-runtime.js";export*from"./code/index.js";export{generateRuntimeInstance}from"./runtime/generate-runtime-instance.js";
1
+ export*from"./runtime/sections/index.js";export*from"./runtime/application-runtime.js";export{applicationSpecSlice}from"./runtime/application-spec-slice.js";export{createApplication}from"./runtime/create-application.js";export*from"./runtime/factory-data/index.js";export*from"./runtime/migrations/index.js";export{isConfiguratorModelSchemaCompatible}from"./runtime/configurator-runtime/configurator-model-runtime.js";export*from"./code/index.js";export{generateRuntimeInstance}from"./runtime/generate-runtime-instance.js";
@@ -25,5 +25,7 @@ export type AdminRuntimeResult = {
25
25
  } | {
26
26
  readonly ok: false;
27
27
  readonly missingExpressions: readonly MissingExpression[];
28
+ /** The migrations the migration modules do not export, as `migrationRuntime.missingMigrations` lists them. */
29
+ readonly missingMigrations: readonly string[];
28
30
  };
29
31
  export declare const AdminRuntime: (spec: RuntimeSpec, referenceStore: RuntimeReferenceStore, expressionModules: readonly ProjectModule[], invariantImplementations: InvariantImplementations, migrationModules: MigrationModules, code: SpecCodeMap | undefined, errors: ImplementationErrorCollector) => AdminRuntimeResult;
@@ -1 +1 @@
1
- import{Branded as e}from"@salsita-ai/common/utils";import{Preset as t,PresetCategory as i,commonAdminCustomExpressions as n,commonAdminViolationExpressions as r}from"#package/domain";import{MigrationRuntime as s}from"../migrations/index.js";import{ComponentOptics as o}from"../sections/component-optic.js";import{ExpressionRuntime as m}from"../sections/expression-runtime.js";import{PresetRuntime as a}from"../sections/preset-runtime.js";import{AdminSpecRuntime as p}from"./admin-spec-runtime.js";import{AdminStatesRuntime as u}from"./states-runtime.js";let c={Preset:[{evaluate:(e,i,n)=>{let s=n.domain.get$Entity(e,i);return t.assert(s),r.Preset.nameNotEmpty(s)}}]},f={PresetCategory:{$isDraft:{origin:{name:"$isDraft",typeOrAlias:"PresetCategory"},evaluate:(e,t,r)=>{let s=r.domain.get$Entity(e,t);return i.assert(s),n.PresetCategory.$isDraft(s)},meta:{}}}},l=new WeakMap;export const AdminRuntime=(t,i,n,r,d,g,R)=>{let{modelRuntime:j,factoryDataRuntime:y}=p(t,i,g),k=m(t.admin,i,n,"adminExpressionRuntime",((e,t)=>{if(0===Object.keys(e).length)return c;let i=l.get(t)??new WeakMap;l.set(t,i);let n=i.get(e);if(n)return n;let r={};for(let i of[c,e])for(let[e,n]of Object.entries(i))for(let i of t[e]??[e])r[i]=[...r[i]??[],...n];return i.set(e,r),r})(r,j.aliases),g,R,f);return k.ok?{ok:!0,runtime:e({modelRuntime:j,componentOptics:o(i,{components:t.admin.components,referenceScope:"adminRuntime/componentOptics",modelRuntime:j,code:g}),expressionRuntime:k.runtime,presetRuntime:a(i,{referenceScope:"adminRuntime/presetRuntime",presets:t.admin.presets.presets}),statesRuntime:u(t,i),migrationRuntime:s(i,{referenceScope:"adminRuntime/migrationRuntime",resolvedVersions:t.admin.resolvedVersions,latestEntities:j.entities,migrationModules:d}),factoryDataRuntime:y})}:{ok:!1,missingExpressions:k.missing}};
1
+ import{Branded as e}from"@salsita-ai/common/utils";import{Preset as t,PresetCategory as i,commonAdminCustomExpressions as s,commonAdminViolationExpressions as n}from"#package/domain";import{MigrationRuntime as r}from"../migrations/index.js";import{ComponentOptics as o}from"../sections/component-optic.js";import{ExpressionRuntime as m}from"../sections/expression-runtime.js";import{PresetRuntime as a}from"../sections/preset-runtime.js";import{AdminSpecRuntime as p}from"./admin-spec-runtime.js";import{AdminStatesRuntime as u}from"./states-runtime.js";let c={Preset:[{evaluate:(e,i,s)=>{let r=s.domain.get$Entity(e,i);return t.assert(r),n.Preset.nameNotEmpty(r)}}]},f={PresetCategory:{$isDraft:{origin:{name:"$isDraft",typeOrAlias:"PresetCategory"},evaluate:(e,t,n)=>{let r=n.domain.get$Entity(e,t);return i.assert(r),s.PresetCategory.$isDraft(r)},meta:{}}}},l=new WeakMap;export const AdminRuntime=(t,i,s,n,g,d,R)=>{let{modelRuntime:j,factoryDataRuntime:y}=p(t,i,d),k=m(t.admin,i,s,"adminExpressionRuntime",((e,t)=>{if(0===Object.keys(e).length)return c;let i=l.get(t)??new WeakMap;l.set(t,i);let s=i.get(e);if(s)return s;let n={};for(let i of[c,e])for(let[e,s]of Object.entries(i))for(let i of t[e]??[e])n[i]=[...n[i]??[],...s];return i.set(e,n),n})(n,j.aliases),d,R,f),x=r(i,{referenceScope:"adminRuntime/migrationRuntime",resolvedVersions:t.admin.resolvedVersions,latestEntities:j.entities,migrationModules:g});return k.ok?{ok:!0,runtime:e({modelRuntime:j,componentOptics:o(i,{components:t.admin.components,referenceScope:"adminRuntime/componentOptics",modelRuntime:j,code:d}),expressionRuntime:k.runtime,presetRuntime:a(i,{referenceScope:"adminRuntime/presetRuntime",presets:t.admin.presets.presets}),statesRuntime:u(t,i),migrationRuntime:x,factoryDataRuntime:y})}:{ok:!1,missingExpressions:k.missing,missingMigrations:x.missingMigrations}};
@@ -23,6 +23,11 @@ export type ApplicationRuntimeResult = {
23
23
  } | {
24
24
  readonly ok: false;
25
25
  readonly missingExpressions: readonly MissingExpression[];
26
+ /**
27
+ * The migrations of both domains the migration modules do not export, which a built
28
+ * runtime lists in `migrationRuntime.missingMigrations` of each domain.
29
+ */
30
+ readonly missingMigrations: readonly string[];
26
31
  };
27
32
  /**
28
33
  * Builds an ApplicationRuntime from a RuntimeSpec: the part of the parsed spec the runtime reads, which a
@@ -1 +1 @@
1
- import{Branded as i}from"@salsita-ai/common/utils";import{createImplementationErrorCollector as o}from"#package/domain";import{AdminRuntime as r}from"./admin-runtime/admin-runtime.js";import{ConfiguratorRuntime as n}from"./configurator-runtime/configurator-runtime.js";import{DataRuntime as m}from"./sections/data-runtime.js";export const ApplicationRuntime=(t,s,a,e,u,p=[],f={},c={},d,g)=>{let k=g??o(),l=n(t,s,a,e,u,c,d?.configurator,k),x=r(t,s,p,f,c,d?.admin,k);return(void 0===g&&k.throwIfAny(),l.ok&&x.ok)?{ok:!0,runtime:i({configurator:l.runtime,admin:x.runtime,data:m(t,s)})}:{ok:!1,missingExpressions:[...l.ok?[]:l.missingExpressions,...x.ok?[]:x.missingExpressions]}};
1
+ import{Branded as i}from"@salsita-ai/common/utils";import{createImplementationErrorCollector as n}from"#package/domain";import{AdminRuntime as o}from"./admin-runtime/admin-runtime.js";import{ConfiguratorRuntime as r}from"./configurator-runtime/configurator-runtime.js";import{DataRuntime as m}from"./sections/data-runtime.js";export const ApplicationRuntime=(t,s,a,e,g,u=[],p={},f={},c,k)=>{let d=k??n(),M=r(t,s,a,e,g,f,c?.configurator,d),l=o(t,s,u,p,f,c?.admin,d);return(void 0===k&&d.throwIfAny(),M.ok&&l.ok)?{ok:!0,runtime:i({configurator:M.runtime,admin:l.runtime,data:m(t,s)})}:{ok:!1,missingExpressions:[...M.ok?[]:M.missingExpressions,...l.ok?[]:l.missingExpressions],missingMigrations:[...M.ok?M.runtime.migrationRuntime.missingMigrations:M.missingMigrations,...l.ok?l.runtime.migrationRuntime.missingMigrations:l.missingMigrations]}};
@@ -64,7 +64,8 @@ export declare const customComponentOpticsOf: (componentOptics: readonly AnyDoma
64
64
  /**
65
65
  * Maps an application's runtime (`ApplicationRuntime`, built with the project's modules) and its
66
66
  * checked modules onto the spec slice of the domain runtime, the one input of every mounted
67
- * application: an application's first slice, or the editor's rebuild after a change of the project.
67
+ * application: an application's first slice, which `createApplication` builds with it, or the
68
+ * editor's rebuild after a change of the project.
68
69
  */
69
70
  export declare const applicationSpecSlice: (input: ApplicationSpecStart | ApplicationSpecUpdate) => RuntimeApplicationSpec;
70
71
  export {};
@@ -33,5 +33,7 @@ export type ConfiguratorRuntimeResult = {
33
33
  } | {
34
34
  readonly ok: false;
35
35
  readonly missingExpressions: readonly MissingExpression[];
36
+ /** The migrations the migration modules do not export, as `migrationRuntime.missingMigrations` lists them. */
37
+ readonly missingMigrations: readonly string[];
36
38
  };
37
39
  export declare const ConfiguratorRuntime: (spec: RuntimeSpec, referenceStore: RuntimeReferenceStore, expressionModules: readonly ProjectModule[], importedTransformers: readonly ImportedTransformer[], invariantImplementations: InvariantImplementations | undefined, migrationModules: MigrationModules, code: SpecCodeMap | undefined, errors: ImplementationErrorCollector) => ConfiguratorRuntimeResult;
@@ -1 +1 @@
1
- import{Branded as t}from"@salsita-ai/common/utils";import{MigrationRuntime as e}from"../migrations/index.js";import{ActionsRuntime as o}from"../sections/actions-runtime.js";import{AssistantRuntime as i}from"../sections/assistant-runtime.js";import{ComponentOptics as r}from"../sections/component-optic.js";import{ExpressionRuntime as s}from"../sections/expression-runtime.js";import{PresetRuntime as n}from"../sections/preset-runtime.js";import{ThemeRuntime as m}from"../sections/theme-runtime.js";import{TransformersRuntime as u}from"../sections/transformers-runtime.js";import{ConfiguratorSpecRuntime as c}from"./configurator-spec-runtime.js";import{ConfiguratorStatesRuntime as p}from"./states-runtime.js";export const ConfiguratorRuntime=(a,f,g,R,j,l,x,d)=>{let{modelRuntime:k,factoryDataRuntime:E}=c(a,f,x),S=s(a.configurator,f,g,"configuratorExpressionRuntime",j,x,d);return S.ok?{ok:!0,runtime:t({modelRuntime:k,componentOptics:r(f,{components:a.configurator.components,referenceScope:"configuratorRuntime/componentOptics",modelRuntime:k,code:x}),presetRuntime:n(f,{referenceScope:"configuratorRuntime/presetRuntime",presets:a.configurator.presets.presets}),statesRuntime:p(a,f),expressionRuntime:S.runtime,themeRuntime:m(a,f),transformersRuntime:u(a,f,R),assistantRuntime:i(a,f),actionsRuntime:o(a.configurator.actions,f),migrationRuntime:e(f,{referenceScope:"configuratorRuntime/migrationRuntime",resolvedVersions:a.configurator.resolvedVersions,latestEntities:k.entities,migrationModules:l}),factoryDataRuntime:E})}:{ok:!1,missingExpressions:S.missing}};
1
+ import{Branded as t}from"@salsita-ai/common/utils";import{MigrationRuntime as e}from"../migrations/index.js";import{ActionsRuntime as i}from"../sections/actions-runtime.js";import{AssistantRuntime as o}from"../sections/assistant-runtime.js";import{ComponentOptics as s}from"../sections/component-optic.js";import{ExpressionRuntime as r}from"../sections/expression-runtime.js";import{PresetRuntime as n}from"../sections/preset-runtime.js";import{ThemeRuntime as m}from"../sections/theme-runtime.js";import{TransformersRuntime as c}from"../sections/transformers-runtime.js";import{ConfiguratorSpecRuntime as u}from"./configurator-spec-runtime.js";import{ConfiguratorStatesRuntime as p}from"./states-runtime.js";export const ConfiguratorRuntime=(a,f,g,R,j,l,x,d)=>{let{modelRuntime:k,factoryDataRuntime:E}=u(a,f,x),S=r(a.configurator,f,g,"configuratorExpressionRuntime",j,x,d),h=e(f,{referenceScope:"configuratorRuntime/migrationRuntime",resolvedVersions:a.configurator.resolvedVersions,latestEntities:k.entities,migrationModules:l});return S.ok?{ok:!0,runtime:t({modelRuntime:k,componentOptics:s(f,{components:a.configurator.components,referenceScope:"configuratorRuntime/componentOptics",modelRuntime:k,code:x}),presetRuntime:n(f,{referenceScope:"configuratorRuntime/presetRuntime",presets:a.configurator.presets.presets}),statesRuntime:p(a,f),expressionRuntime:S.runtime,themeRuntime:m(a,f),transformersRuntime:c(a,f,R),assistantRuntime:o(a,f),actionsRuntime:i(a.configurator.actions,f),migrationRuntime:h,factoryDataRuntime:E})}:{ok:!1,missingExpressions:S.missing,missingMigrations:h.missingMigrations}};
@@ -0,0 +1,57 @@
1
+ import { type Messages } from '@lingui/core';
2
+ import { type Application, type ElementRegistration, type ProjectModule } from '#package/domain';
3
+ import type { RuntimeReferenceStore } from '../../caching/index.js';
4
+ import type { RuntimeSpec } from '../runtime-spec/index.js';
5
+ import { type ThemePresets } from './application-spec-slice.js';
6
+ import type { MigrationModules } from './migrations/index.js';
7
+ import type { SpecCodeModule } from './spec-code/index.js';
8
+ /**
9
+ * The project modules of an application, as the generated barrels list them: each file of a
10
+ * convention folder as `{ origin, exports }`, unchecked; the migration modules of both domains keyed
11
+ * by project path (`src/migrations/v2.ts`); and the message catalogs of `src/locales/<locale>/`,
12
+ * keyed by locale. `components` holds the files of `src/components/` and the frontend component
13
+ * files, in that order, and `elements` every element file the application mounts.
14
+ */
15
+ export interface ApplicationModules {
16
+ readonly expressions: readonly ProjectModule[];
17
+ readonly invariants: readonly ProjectModule[];
18
+ readonly actions: readonly ProjectModule[];
19
+ readonly components: readonly ProjectModule[];
20
+ readonly handlers: readonly ProjectModule[];
21
+ readonly elements: readonly ProjectModule[];
22
+ readonly transformers: readonly ProjectModule[];
23
+ readonly adminExpressions: readonly ProjectModule[];
24
+ readonly adminInvariants: readonly ProjectModule[];
25
+ readonly adminComponents: readonly ProjectModule[];
26
+ readonly migrations: MigrationModules;
27
+ readonly catalogs: Readonly<Record<string, Messages>>;
28
+ }
29
+ export interface CreateApplicationInput {
30
+ /** The runtime spec, `.phoenix/application-spec.json` decoded with `decodeRuntimeSpec`. */
31
+ readonly spec: RuntimeSpec;
32
+ /** The store `createPhx` built the `phx` values in. */
33
+ readonly referenceStore: RuntimeReferenceStore;
34
+ /** The generated `.phoenix/spec-code.ts` module of the same generation as `spec`. */
35
+ readonly specCode?: SpecCodeModule | undefined;
36
+ readonly modules: ApplicationModules;
37
+ /** The SDK's default elements of the application kind; a project element with the same name replaces one. */
38
+ readonly defaultElements: readonly ElementRegistration[];
39
+ /** The SDK's theme presets by name, `getPhoenixThemes()`. */
40
+ readonly themePresets: ThemePresets;
41
+ readonly environment?: Application['environment'] | undefined;
42
+ /** The services a host provides; i18n is built from the catalogs. */
43
+ readonly services?: Omit<Application['services'], 'i18n'> | undefined;
44
+ /** The tag the web component mounts as; by default the spec's `webComponentTag`, else `salsita-configurator`. */
45
+ readonly tag?: string | undefined;
46
+ }
47
+ /**
48
+ * Builds an application from its runtime spec and its project modules, ready to mount, with no
49
+ * `ConfiguratorBuilder` and no `ApplicationConfig`: the full `ApplicationRuntime` in the store
50
+ * `createPhx` built the `phx` values in, the spec slice of the domain runtime, the initial published
51
+ * data and i18n.
52
+ *
53
+ * Every mistake of the project's files is reported at once, as one `ImplementationErrors`: a file
54
+ * that breaks its folder's contract, an expression defined twice or one the spec already gives a
55
+ * value, a declared expression no file implements and a migration no file exports.
56
+ */
57
+ export declare const createApplication: <TYPES = unknown>(input: CreateApplicationInput) => Application<TYPES>;
@@ -0,0 +1 @@
1
+ import{setupI18n as e}from"@lingui/core";import{initConsoleLogger as t}from"@salsita-ai/common/utils";import{ImplementationError as i,NoopAnalyticsSystem as n,checkSingleInstanceHandlers as o,createDomainRuntime as a,createImplementationErrorCollector as r,createInitialPublishedData as s,resolveActionModules as m,resolveComponentOpticModules as c,resolveElementModule as l,resolveHandlerModule as p,resolveInvariantModules as u,resolveTransformerModule as d}from"#package/domain";import{defaultI18n as f,mergeCatalogs as g,sdkCatalog as h}from"#package/i18n";import{ApplicationRuntime as v}from"./application-runtime.js";import{applicationSpecSlice as E}from"./application-spec-slice.js";let M=(e,t,i)=>e.filter(e=>i.attempt(()=>(t(e),!0),!1)),w=(e,t,i)=>e.flatMap(e=>i.attempt(()=>t(e),[]));export const createApplication=I=>{let{spec:T,referenceStore:b,specCode:k,modules:x,environment:A={}}=I,C=r(),R=w(x.handlers,p,C),y=w(x.elements,l,C),N=w(x.transformers,e=>[d(e)],C),P=w(x.components,e=>c([e]),C),S=w(x.adminComponents,e=>c([e]),C),O=M(x.invariants,e=>u([e]),C),j=M(x.adminInvariants,e=>u([e]),C),L=M(x.actions,e=>m([e]),C),U=v(T,b,x.expressions,N,u(O),x.adminExpressions,u(j),x.migrations,k,C);if((U.ok?[...U.runtime.configurator.migrationRuntime.missingMigrations,...U.runtime.admin.migrationRuntime.missingMigrations]:U.missingMigrations).forEach(e=>C.add((e=>{let[t=e,n="migrateToVN"]=e.split("#");return new i({code:"MISSING_IMPLEMENTATION",origin:t,problem:`The migration ${n} is missing`,fix:`The spec declares the model version this file migrates to, so the file must export ${n}, the function that turns a state of the previous version into one of this version; without it a saved configuration of an earlier version cannot load. Add or rename the export.`})})(e))),C.throwIfAny(),!U.ok)throw Error("The application runtime could not be built, but no implementation error was recorded.");o(R);let $=E({runtime:U.runtime,spec:T,modules:{handlers:{handlers:R},elements:{elements:y},customComponentOptics:P,actionImplementations:m(L)},customAdminComponentOptics:S,defaultElements:I.defaultElements,themePresets:I.themePresets,environmentResourcesUrl:A.defaultEnvs?.resourcesUrl}),D=t(),F=s({adminDomainFactory:$.admin.factory,domainRuntime:a({application:{spec:$,environment:A},services:{analyticsService:new n,i18n:f,logger:D}}),adminPresets:U.runtime.admin.presetRuntime.presets,handlers:$.configurator.handlers,dataSpec:$.dataConfig??void 0,chunks:$.chunks,logger:D});return{spec:{...$,initialPublishedData:F},environment:A,services:{...I.services,i18n:e({messages:g([h,x.catalogs]),locale:T.configurator.ui.availableLocales[0]})},tag:I.tag??T.appMetadata.webComponentTag??"salsita-configurator"}};
@@ -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 o}from"./contract.js";let n=()=>new TransformStream({transform(t,a){a.enqueue(t)}}),s=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 o).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 o=await this._authHeaders(),n=await this._client.POST("/configurations/{configurationId}/{finalizationUuid}/finalize",{params:{path:{configurationId:t,finalizationUuid:a},query:{locale:r}},body:{finalizeData:e,frontendData:i},headers:o});if(n.error)throw h(n.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 o=i.data;if("completed"===o.state)return o.result[0];if("failed"===o.state)throw Error("finalization failed");if("unknown"===o.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(),o=await this._client.GET("/configurations/{configurationId}/assistant/chat/threads/{threadId}",{params:{path:{configurationId:t,threadId:a},query:{limit:e}},headers:r});if(o.error)throw new i(`getAssistantEarlierThread API request failed: ${JSON.stringify(o.error)}`,o.response.status);let{messages:n}=o.data;return{threadId:a,messages:Array.isArray(n)?n:[],previousThreadId:o.response.headers.get("x-assistant-previous-thread")}};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 o=i.data?.pipeThrough(new TextDecoderStream).getReader();if(!o)throw Error("sendMessage API response did not contain a readable stream");let c=n();return s(o,c.writable.getWriter()),c.readable};sendToolCallResults=async(t,a,e,r)=>{let i=await this._authHeaders(),o=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(o.error)throw h(o.error,"sendToolCallResults");let c=o.data?.pipeThrough(new TextDecoderStream).getReader();if(!c)throw Error("sendMessage API response did not contain a readable stream");let u=n();return s(c,u.writable.getWriter()),u.readable};generateShareLink=async(t,a,e,r,i)=>{let o=await this._authHeaders(),n=await this._client.POST("/configurations/{configurationId}/share-link",{params:{path:{configurationId:t}},body:{revisionId:a,expiration:e,access:r,baseUrl:i},headers:o});if(n.error)throw h(n.error,"generateShareLink");return n.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}}
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;
@@ -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 o}from"./local-authenticated-client.js";let r=(t,o)=>{let r={role:"assistant",content:["I see","Yes","Definitely"][Math.round(2*Math.random())]};return localStorage.setItem(`${o}-chat`,JSON.stringify([...t,r])),Promise.resolve(new ReadableStream({start(t){t.enqueue({type:e.content,content:r.content??""}),t.close()}}))};export class LocalStorageAuthorizedPhoenixApiClient extends o{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,o)=>{let r=this.getConfigurationData(e),n=t.v4(),a={...o,configurationId:e,revisionId:n,modelVersion:this._modelVersion};return localStorage.setItem(e,JSON.stringify([...r,a])),Promise.resolve({revisionId:n})};finalize=()=>{throw Error("Not implemented!")};waitForFinalizationToComplete=()=>{throw Error("Not implemented!")};getConfigurationRevision=(t,e)=>{let o=this.getConfigurationData(t).find(t=>t.revisionId===e);if(!o)throw Error("Revision not found!");return Promise.resolve(o)};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.")};getChatConversation=async t=>JSON.parse(localStorage.getItem(`${t}-chat`)??"[]");sendMessage=async(t,e)=>{let o=await this.getChatConversation(t);return localStorage.setItem(`${t}-chat`,JSON.stringify([...o,e])),r(o,t)};getSpeechToText=async()=>{throw Error("Not implemented!")};getTextToSpeech=async()=>{throw Error("Not implemented!")};sendToolCallResults=async t=>r(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 o=localStorage.getItem(t);if(!o)throw Error("Configuration not found");let r=JSON.parse(o).find(t=>t.revisionId===e);if(!r)throw Error("Revision not found");return this.createConfiguration(r)}}
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 e from"uuid";import{MemoryAuthenticatedClientPhoenixApiClient as t,memoryStorage as r}from"./memory-authenticated-client.js";export class MemoryAuthorizedPhoenixApiClient extends t{getConfigurationData=e=>{let t=r.get(e);if(!t||!t||0===t.length)throw Error("Configuration not found!");return t};getConfiguration=e=>{let t=this.getConfigurationData(e);return Promise.resolve(t[t.length-1])};updateConfiguration=(t,o)=>{let n=this.getConfigurationData(t),i=e.v4(),a={...o,configurationId:t,revisionId:i,modelVersion:this._modelVersion};return r.set(t,[...n,a]),Promise.resolve({revisionId:i})};finalize=()=>{throw Error("Not implemented!")};waitForFinalizationToComplete=()=>{throw Error("Not implemented!")};getConfigurationRevision=(e,t)=>{let r=this.getConfigurationData(e).find(e=>e.revisionId===t);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.")};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(e,t)=>{let o=r.get(e);if(!o)throw Error("Configuration not found");let n=o.find(e=>e.revisionId===t);if(!n)throw Error("Revision not found");return this.createConfiguration(n)}}
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)}}