@sanity/assist 4.0.2 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -915,6 +915,21 @@ the plugin will throw upon studio startup.
915
915
  Note that this is currently only available on a global level - it can not be defined
916
916
  per-field for now.
917
917
 
918
+ ### Dynamic styleguide
919
+
920
+ As of 4.1.0 it is also possible to provide a styleguide async function.
921
+ The function is passed a context object with Sanity client and the current documentId and schemaType.
922
+
923
+ Consider caching the results: the function is invoked every time translate runs.
924
+
925
+ ```ts
926
+ assist({
927
+ translate: {
928
+ styleguide: ({client, documentId, schemaType}) => client.fetch('* [_id=="styleguide.singleton"][0].styleguide')
929
+ },
930
+ })
931
+ ```
932
+
918
933
  ## Caveats
919
934
 
920
935
  Large Language Models (LLMs) are a new technology. Constraints and limitations are still being explored,
package/dist/index.d.mts CHANGED
@@ -1,5 +1,6 @@
1
1
  import {CurrentUser} from 'sanity'
2
2
  import {JSX as JSX_2} from 'react/jsx-runtime'
3
+ import {ObjectSchemaType} from 'sanity'
3
4
  import {Path} from 'sanity'
4
5
  import {Plugin as Plugin_2} from 'sanity'
5
6
  import {PortableTextBlock} from '@portabletext/types'
@@ -339,6 +340,20 @@ declare type PromptTextBlock = Omit<
339
340
 
340
341
  export declare function SchemaTypeTool(): JSX_2.Element
341
342
 
343
+ export declare type TranslateStyleguide =
344
+ | string
345
+ | ((context: TranslateStyleguideContext) => Promise<string>)
346
+
347
+ export declare interface TranslateStyleguideContext {
348
+ documentId: string
349
+ schemaType: ObjectSchemaType
350
+ client: SanityClient
351
+ /**
352
+ * Only provided for field translations
353
+ */
354
+ translatePath?: Path
355
+ }
356
+
342
357
  export declare interface TranslationConfig {
343
358
  /**
344
359
  * Config for document types with fields in multiple languages in the same document.
@@ -352,8 +367,10 @@ export declare interface TranslationConfig {
352
367
  * A "style guide" that can be used to provide guidance on how to translate content.
353
368
  * Will be passed to the LLM - ergo this is only a guide and the model _may_ not
354
369
  * always follow it to the letter.
370
+ *
371
+ * When providing a function, consider caching the results of any async operation; it will invoked every time translate runs
355
372
  */
356
- styleguide?: string
373
+ styleguide?: TranslateStyleguide
357
374
  }
358
375
 
359
376
  export declare interface TranslationOutput {
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import {CurrentUser} from 'sanity'
2
2
  import {JSX as JSX_2} from 'react/jsx-runtime'
3
+ import {ObjectSchemaType} from 'sanity'
3
4
  import {Path} from 'sanity'
4
5
  import {Plugin as Plugin_2} from 'sanity'
5
6
  import {PortableTextBlock} from '@portabletext/types'
@@ -339,6 +340,20 @@ declare type PromptTextBlock = Omit<
339
340
 
340
341
  export declare function SchemaTypeTool(): JSX_2.Element
341
342
 
343
+ export declare type TranslateStyleguide =
344
+ | string
345
+ | ((context: TranslateStyleguideContext) => Promise<string>)
346
+
347
+ export declare interface TranslateStyleguideContext {
348
+ documentId: string
349
+ schemaType: ObjectSchemaType
350
+ client: SanityClient
351
+ /**
352
+ * Only provided for field translations
353
+ */
354
+ translatePath?: Path
355
+ }
356
+
342
357
  export declare interface TranslationConfig {
343
358
  /**
344
359
  * Config for document types with fields in multiple languages in the same document.
@@ -352,8 +367,10 @@ export declare interface TranslationConfig {
352
367
  * A "style guide" that can be used to provide guidance on how to translate content.
353
368
  * Will be passed to the LLM - ergo this is only a guide and the model _may_ not
354
369
  * always follow it to the letter.
370
+ *
371
+ * When providing a function, consider caching the results of any async operation; it will invoked every time translate runs
355
372
  */
356
- styleguide?: string
373
+ styleguide?: TranslateStyleguide
357
374
  }
358
375
 
359
376
  export declare interface TranslationOutput {
package/dist/index.esm.js CHANGED
@@ -642,30 +642,36 @@ function useTranslate(apiClient) {
642
642
  translatePath,
643
643
  fieldLanguageMap,
644
644
  conditionalMembers
645
- }) => (setLoading(!0), apiClient.request({
646
- method: "POST",
647
- url: `/assist/tasks/translate/${apiClient.config().dataset}?projectId=${apiClient.config().projectId}`,
648
- body: {
649
- documentId,
650
- types,
651
- languagePath,
652
- userStyleguide: styleguide,
653
- fieldLanguageMap,
654
- conditionalMembers,
655
- translatePath: translatePath.length === 0 ? documentRootKey : pathToString(translatePath),
656
- userId: user?.id
645
+ }) => {
646
+ setLoading(!0);
647
+ async function run() {
648
+ return apiClient.request({
649
+ method: "POST",
650
+ url: `/assist/tasks/translate/${apiClient.config().dataset}?projectId=${apiClient.config().projectId}`,
651
+ body: {
652
+ documentId,
653
+ types,
654
+ languagePath,
655
+ userStyleguide: await styleguide(),
656
+ fieldLanguageMap,
657
+ conditionalMembers,
658
+ translatePath: translatePath.length === 0 ? documentRootKey : pathToString(translatePath),
659
+ userId: user?.id
660
+ }
661
+ });
657
662
  }
658
- }).catch((e) => {
659
- throw toast.push({
660
- status: "error",
661
- title: "Translate failed",
662
- description: e.message
663
- }), setLoading(!1), e;
664
- }).finally(() => {
665
- setTimeout(() => {
666
- setLoading(!1);
667
- }, 2e3);
668
- })),
663
+ return run().catch((e) => {
664
+ throw toast.push({
665
+ status: "error",
666
+ title: "Translate failed",
667
+ description: e.message
668
+ }), setLoading(!1), e;
669
+ }).finally(() => {
670
+ setTimeout(() => {
671
+ setLoading(!1);
672
+ }, 2e3);
673
+ });
674
+ },
669
675
  [setLoading, apiClient, toast, user, types]
670
676
  );
671
677
  return useMemo(
@@ -2220,6 +2226,21 @@ function AssistConnectorsOverlay(props) {
2220
2226
  DEBUG
2221
2227
  ] });
2222
2228
  }
2229
+ function validateStyleguide(styleguide) {
2230
+ if (styleguide && styleguide.length > 2e3)
2231
+ throw new Error(
2232
+ `[${packageName}]: \`translate.styleguide\` value is too long. It must be 2000 characters or less, but was ${styleguide.length} characters`
2233
+ );
2234
+ return styleguide;
2235
+ }
2236
+ function createStyleGuideResolver(styleguide, context) {
2237
+ return async () => {
2238
+ if (typeof styleguide != "function")
2239
+ return styleguide;
2240
+ const styleguideResult = await styleguide(context);
2241
+ return validateStyleguide(styleguideResult);
2242
+ };
2243
+ }
2223
2244
  const getLanguageParams = (select, document2) => {
2224
2245
  if (!select || !document2)
2225
2246
  return {};
@@ -2341,7 +2362,9 @@ function hasValuesToTranslate(fieldLanguageMaps, fromLanguage, basePath2) {
2341
2362
  function FieldTranslationProvider(props) {
2342
2363
  const { config: assistConfig } = useAiAssistanceConfig(), apiClient = useApiClient(assistConfig.__customApiClient), styleguide = assistConfig.translate?.styleguide, config = assistConfig.translate?.field, { translate: runTranslate } = useTranslate(apiClient), [dialogOpen, setDialogOpen] = useState(!1), [fieldTranslationParams, setFieldTranslationParams] = useState(), [languages, setLanguages] = useState(), [fromLanguage, setFromLanguage] = useState(void 0), [toLanguages, setToLanguages] = useState(void 0), [fieldLanguageMaps, setFieldLanguageMaps] = useState(), close = useCallback(() => {
2343
2364
  setDialogOpen(!1), setLanguages(void 0), setFieldTranslationParams(void 0);
2344
- }, []), languageClient = useClient({ apiVersion: config?.apiVersion ?? "2022-11-27" }), documentId = fieldTranslationParams?.document?._id, id = useId(), selectFromLanguage = useCallback(
2365
+ }, []), languageClient = useClient({
2366
+ apiVersion: config?.apiVersion ?? API_VERSION_WITH_EXTENDED_TYPES
2367
+ }), documentId = fieldTranslationParams?.document?._id, id = useId(), selectFromLanguage = useCallback(
2345
2368
  (from, languages2, params) => {
2346
2369
  const { document: document2, documentSchema } = params ?? {};
2347
2370
  if (setFromLanguage(from), !document2 || !documentSchema || !params || !languages2) {
@@ -2398,7 +2421,12 @@ function FieldTranslationProvider(props) {
2398
2421
  fieldLanguageMaps && documentId && translatePath && runTranslate({
2399
2422
  documentId,
2400
2423
  translatePath,
2401
- styleguide,
2424
+ styleguide: createStyleGuideResolver(styleguide, {
2425
+ client: languageClient,
2426
+ documentId,
2427
+ schemaType: fieldTranslationParams?.documentSchema,
2428
+ translatePath
2429
+ }),
2402
2430
  fieldLanguageMap: fieldLanguageMaps.map((map) => ({
2403
2431
  ...map,
2404
2432
  // eslint-disable-next-line max-nested-callbacks
@@ -2414,7 +2442,9 @@ function FieldTranslationProvider(props) {
2414
2442
  close,
2415
2443
  toLanguages,
2416
2444
  fieldTranslationParams?.translatePath,
2417
- fieldTranslationParams?.conditionalMembers
2445
+ fieldTranslationParams?.conditionalMembers,
2446
+ fieldTranslationParams?.documentSchema,
2447
+ languageClient
2418
2448
  ]), runButton = /* @__PURE__ */ jsx(
2419
2449
  Button,
2420
2450
  {
@@ -2602,7 +2632,7 @@ function useAssistSupported(path, schemaType) {
2602
2632
  const translateActions = {
2603
2633
  name: "sanity-assist-translate",
2604
2634
  useAction(props) {
2605
- const { config, status } = useAiAssistanceConfig(), apiClient = useApiClient(config?.__customApiClient), {
2635
+ const { config, status } = useAiAssistanceConfig(), apiClient = useApiClient(config?.__customApiClient), client = useClient({ apiVersion: API_VERSION_WITH_EXTENDED_TYPES }), {
2606
2636
  schemaType: fieldSchemaType,
2607
2637
  path,
2608
2638
  documentId,
@@ -2630,7 +2660,11 @@ const translateActions = {
2630
2660
  translationApi.loading || !languagePath || !documentId || translate({
2631
2661
  languagePath,
2632
2662
  translatePath: path,
2633
- styleguide,
2663
+ styleguide: createStyleGuideResolver(styleguide, {
2664
+ client,
2665
+ documentId,
2666
+ schemaType: documentSchemaType
2667
+ }),
2634
2668
  documentId: documentId ?? "",
2635
2669
  conditionalMembers: formStateRef.current ? getConditionalMembers(formStateRef.current) : []
2636
2670
  });
@@ -2646,7 +2680,9 @@ const translateActions = {
2646
2680
  translationApi.loading,
2647
2681
  documentTranslationEnabled,
2648
2682
  path,
2649
- readOnly
2683
+ readOnly,
2684
+ client,
2685
+ documentSchemaType
2650
2686
  ]), fieldTranslate = useFieldTranslation(), openFieldTranslation = useDraftDelayedTask({
2651
2687
  documentOnChange,
2652
2688
  isDocAssistable: documentIsAssistable ?? !1,
@@ -3887,11 +3923,7 @@ const instructionForm = [
3887
3923
  contextDocumentSchema
3888
3924
  ], assist = definePlugin((config) => {
3889
3925
  const configWithDefaults = config ?? {}, styleguide = configWithDefaults.translate?.styleguide || "", maxPathDepth = configWithDefaults.assist?.maxPathDepth, temperature = configWithDefaults.assist?.temperature;
3890
- if (styleguide.length > 2e3)
3891
- throw new Error(
3892
- `[${packageName}]: \`translate.styleguide\` value is too long. It must be 2000 characters or less, was ${styleguide.length} characters`
3893
- );
3894
- if (maxPathDepth !== void 0 && (maxPathDepth < 1 || maxPathDepth > 12))
3926
+ if (typeof styleguide == "string" && validateStyleguide(styleguide), maxPathDepth !== void 0 && (maxPathDepth < 1 || maxPathDepth > 12))
3895
3927
  throw new Error(
3896
3928
  `[${packageName}]: \`assist.maxPathDepth\` must be be in the range [1,12] inclusive, but was ${maxPathDepth}`
3897
3929
  );