From afb4d92a3a386715d04c97342eb8e11a88bac739 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Wed, 4 Nov 2026 18:31:38 +0100 Subject: [PATCH 001/195] privileges.md French --- .../current/ORDA/privileges.md | 40 +++---------------- 1 file changed, 6 insertions(+), 34 deletions(-) diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/ORDA/privileges.md b/i18n/fr/docusaurus-plugin-content-docs/current/ORDA/privileges.md index a23ede3289c37b..b0546d9c3b278d 100644 --- a/i18n/fr/docusaurus-plugin-content-docs/current/ORDA/privileges.md +++ b/i18n/fr/docusaurus-plugin-content-docs/current/ORDA/privileges.md @@ -39,40 +39,6 @@ The **execute** permission of a [shared singleton](../Concepts/classes.md#shared Permissions never apply to [desktop session code](../Desktop/sessions.md) (standalone, client/server, stored procedures) or [tool4d](../Admin/cli.md#tool4d). -:::warning - -When a permission entry references an undeclared [privilege](#privileges-and-roles), 4D logs an error and ignores the entry. In this case, the permission is ignored. If the [restricted mode by default](#restriction-modes) is not enabled, the resource is accessible to `guest` sessions. - -::: - -### MCP tools - -The same permissions apply to the sessions of the [MCP server](../WebServer/mcp-server.md), with nothing specific to configure: - -- A [custom tool](../WebServer/mcp-server.md#custom-tools) (`exposed MCP Function`) requires the **execute** permission on its function, and benefits from its **promote** permission. -- The [built-in CRUD tools](../WebServer/mcp-server.md#built-in-crud-tools) require the **read**, **create**, **update**, or **drop** permission on the dataclass, and the attribute permissions apply. Each attribute of a path used in a filter, a sort, or a projection requires the **read** permission. -- The CRUD tools are listed only if the session has at least one data permission on a dataclass, and the `describeModel` tool only describes the dataclasses on which the session has a data permission, with their readable or writable attributes. -- A tool, a dataclass, or an attribute that the session cannot access is reported as if it did not exist. - -#### Exemple - -MCP clients authenticated with the "salesReader" privilege can read the Customer and Order dataclasses with the CRUD tools, and call the tools published by the `OrderManager` singleton (for example `OrderManager-getYearTotal`): - -```json -{ - "privileges": [{"privilege": "salesReader", "includes": []}], - "roles": [], - "permissions": { - "allowed": [ - {"applyTo": "Customer", "type": "dataclass", "read": ["salesReader"]}, - {"applyTo": "Order", "type": "dataclass", "read": ["salesReader"]}, - {"applyTo": "OrderManager", "type": "singleton", "execute": ["salesReader"]} - ] - }, - "restrictedByDefault": true -} -``` - ### MCP tools The same permissions apply to the sessions of the [MCP server](../WebServer/mcp-server.md), with nothing specific to configure: @@ -294,6 +260,12 @@ The project's web security settings are defined in `roles.json`: ::: +:::warning + +When a permission entry references an undeclared [privilege](#privileges-and-roles), 4D logs an error and ignores the entry. In this case, the permission is ignored. If the [restricted mode by default](#restriction-modes) is not enabled, the resource is accessible to `guest` sessions. + +::: + ### Default location and content New projects generate `roles.json` at: From b363d2c027769675a424f9db54b5bfdb184954a6 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Wed, 4 Nov 2026 18:35:34 +0100 Subject: [PATCH 002/195] quotas.md French --- .../current/WebServer/quotas.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/WebServer/quotas.md b/i18n/fr/docusaurus-plugin-content-docs/current/WebServer/quotas.md index 8ad057192055f0..5152c83e3ef3e1 100644 --- a/i18n/fr/docusaurus-plugin-content-docs/current/WebServer/quotas.md +++ b/i18n/fr/docusaurus-plugin-content-docs/current/WebServer/quotas.md @@ -12,12 +12,6 @@ Les quotas du serveur Web vous permettent de contrôler l'utilisation des ressou ::: -:::tip Article de blog lié - -[Un serveur web 4D qui sait quand dire « non »](https://blog.4d.com/a-4d-web-server-that-knows-when-to-say-no/) - -::: - ## Conditions requises La configuration des quotas nécessite l'activation des [sessions évolutives](./sessions.md#enabling-web-sessions). From a8958e8e26483e3d3c102ce495edb82dd975f43b Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Wed, 4 Nov 2026 19:17:57 +0100 Subject: [PATCH 003/195] dataclassclass.md French --- .../version-21-R4/API/DataClassClass.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/fr/docusaurus-plugin-content-docs/version-21-R4/API/DataClassClass.md b/i18n/fr/docusaurus-plugin-content-docs/version-21-R4/API/DataClassClass.md index dedc785f9e8ae4..46e33024705b1b 100644 --- a/i18n/fr/docusaurus-plugin-content-docs/version-21-R4/API/DataClassClass.md +++ b/i18n/fr/docusaurus-plugin-content-docs/version-21-R4/API/DataClassClass.md @@ -1270,7 +1270,7 @@ Voir [plus d'exemples ci-dessous](#example-4-2) (exemples 4 et 5). - [4D AI : Recherche d'entités par similarité vectorielle en 4D](https://blog.4d.com/4d-ai-searching-entities-by-vector-similarity-in-4d) - [4D AI : Tri des résultats d'une requête en fonction de la similarité vectorielle](https://blog.4d.com/4d-ai-sorting-query-results-by-vector-similarity/) -- [Why Your Search Stack Feels Broken — and How Vector Search Fixes It](https://blog.4d.com/why-your-search-stack-feels-broken-and-how-vector-search-fixes-it) +- [Pourquoi votre pile de recherche semble brisée – et comment Vector Search y remédie](https://blog.4d.com/why-your-search-stack-feels-broken-and-how-vector-search-fixes-it) ::: From 00aa1b2c50350dca578fb5d07d22edb753b9f1f9 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Wed, 4 Nov 2026 20:22:00 +0100 Subject: [PATCH 004/195] write-class-method.md French --- .../code-editor/write-class-method.md | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/code-editor/write-class-method.md b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/code-editor/write-class-method.md index 0e77b2fcaecb8c..6f8f20b4b09c69 100644 --- a/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/code-editor/write-class-method.md +++ b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/code-editor/write-class-method.md @@ -25,16 +25,16 @@ Si vous avez l'habitude de coder avec **VS Code**, vous pouvez également utilis Chaque fenêtre de l'éditeur de code dispose d'une barre d'outils qui permet un accès instantané aux fonctionnalités de base liées à l'exécution et à l'édition du code. -| Élément | Icône | Description | -| --------------------------------------- | --------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **Exécuter la méthode** | ![execute-method](../assets/en/code-editor/execute-method.png) | Lorsque vous travaillez avec des méthodes, chaque fenêtre de l'éditeur de code dispose d'un bouton qui peut être utilisé pour exécuter la méthode en cours. En utilisant le menu associé à ce bouton, vous pouvez choisir le type d'exécution :
  • **Exécuter nouveau process** : Crée un process et exécute la méthode en mode standard dans ce process.
  • **Exécuter et déboguer nouveau process** : Crée un nouveau process et affiche la méthode dans la fenêtre du débogueur pour une exécution pas à pas dans ce process.
  • **Exécuter dans le process application** : Exécute la méthode en mode standard dans le contexte du process de l'application (c'est-à-dire la fenêtre d'affichage des enregistrements).
  • **Exécuter et déboguer dans le process application** : Affiche la méthode dans la fenêtre du débogueur pour une exécution pas à pas dans le contexte du process de l'application.
Pour plus d'informations sur l'exécution des méthodes, voir [Méthodes projet](../Project/project-method-properties.md). | -| **Chercher dans la méthode** | ![search-icon](../assets/en/code-editor/search.png) | Affiche la [*zone de recherche*](#find-and-replace). | -| **Macros** | ![macros-button](../assets/en/code-editor/macros.png) | Insère une macro dans la sélection. Cliquez sur la flèche déroulante pour afficher la liste des macros disponibles. Pour plus d'informations sur la création et l'instanciation des macros, voir [Macros](#macros). | -| **Déployer tout / Contracter tout** | ![expand-collapse-button](../assets/en/code-editor/expand-collapse-all.png) | Ces boutons permettent de déployer ou de contracter toutes les structures de flux de contrôle du code. | -| **Informations sur la méthode** | ![method-information-icon](../assets/en/code-editor/method-information.png) | Affiche la boîte de dialogue [Propriétés de la méthode](../Project/project-method-properties.md) (méthodes de projet uniquement). | -| **Dernières valeurs du presse-papiers** | ![last-clipboard-values-icon](../assets/en/code-editor/last-clipboard-values.png) | Affiche les dernières valeurs stockées dans le presse-papiers. | -| **Presse-papiers** | ![clipboard icons](../assets/en/code-editor/clipboards.png) | Neuf presse-papiers sont disponibles dans l'éditeur de code. Vous pouvez [utiliser ces presse-papiers](#clipboards) en cliquant directement dessus ou en utilisant des raccourcis clavier. Vous pouvez utiliser une option des [Préférences](Preferences/methods.md#options-1) pour les masquer. | -| **Menu déroulant de navigation** | ![code-navigation-icons](../assets/en/code-editor/tags.png) | Vous permet de naviguer à l'intérieur des méthodes et des classes avec du contenu étiqueté automatiquement ou des marqueurs déclarés manuellement. Voir ci-dessous | +| Élément | Icône | Description | +| --------------------------------------- | --------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Exécuter la méthode** | ![execute-method](../assets/en/code-editor/execute-method.png) | Lorsque vous travaillez avec des méthodes, chaque fenêtre de l'éditeur de code dispose d'un bouton qui peut être utilisé pour exécuter la méthode en cours. Le menu associé à ce bouton permet de choisir le type d'exécution :
  • **Exécuter nouveau process** : Crée un process et exécute la méthode en mode standard dans ce process.
  • **Exécuter et déboguer nouveau process** : Crée un nouveau process et affiche la méthode dans la fenêtre du débogueur pour une exécution pas à pas dans ce process.
  • **Exécuter dans le process de l'application** : Exécute la méthode en mode standard dans le contexte du process de l'application (c'est-à-dire la fenêtre d'affichage des enregistrements).
  • **Exécuter et déboguer dans le process de l'application** : Affiche la méthode dans la fenêtre du débogueur pour une exécution pas à pas dans le contexte du process de l'application (la fenêtre d'affichage des enregistrements).
Pour plus d'informations sur l'exécution des méthodes, consultez la page [Méthodes de projet](../Project/project-method-properties.md). | +| **Chercher dans la méthode** | ![search-icon](../assets/en/code-editor/search.png) | Affiche la [*zone de recherche*](#find-and-replace). | +| **Macros** | ![macros-button](../assets/en/code-editor/macros.png) | Insère une macro dans la sélection. Cliquez sur la flèche déroulante pour afficher la liste des macros disponibles. Pour plus d'informations sur la création et l'instanciation des macros, voir [Macros](#macros). | +| **Déployer tout / Contracter tout** | ![expand-collapse-button](../assets/en/code-editor/expand-collapse-all.png) | Ces boutons permettent de déployer ou de contracter toutes les structures de flux de contrôle du code. | +| **Informations sur la méthode** | ![method-information-icon](../assets/en/code-editor/method-information.png) | Affiche la boîte de dialogue [Propriétés de la méthode](../Project/project-method-properties.md) (méthodes de projet uniquement). | +| **Dernières valeurs du presse-papiers** | ![last-clipboard-values-icon](../assets/en/code-editor/last-clipboard-values.png) | Affiche les dernières valeurs stockées dans le presse-papiers. | +| **Presse-papiers** | ![clipboard icons](../assets/en/code-editor/clipboards.png) | Neuf presse-papiers sont disponibles dans l'éditeur de code. Vous pouvez [utiliser ces presse-papiers](#clipboards) en cliquant directement dessus ou en utilisant des raccourcis clavier. Vous pouvez utiliser une option des [Préférences](Preferences/methods.md#options-1) pour les masquer. | +| **Menu déroulant de navigation** | ![code-navigation-icons](../assets/en/code-editor/tags.png) | Vous permet de naviguer à l'intérieur des méthodes et des classes avec du contenu étiqueté automatiquement ou des marqueurs déclarés manuellement. Voir ci-dessous | ### Zone d'édition From e02c06cf51187c7927730e63e9437f8832379b8b Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Wed, 4 Nov 2026 20:59:49 +0100 Subject: [PATCH 005/195] privileges.md Spanish --- .../current/ORDA/privileges.md | 40 +++---------------- 1 file changed, 6 insertions(+), 34 deletions(-) diff --git a/i18n/es/docusaurus-plugin-content-docs/current/ORDA/privileges.md b/i18n/es/docusaurus-plugin-content-docs/current/ORDA/privileges.md index 073e5b23ce628c..20820d21a5773b 100644 --- a/i18n/es/docusaurus-plugin-content-docs/current/ORDA/privileges.md +++ b/i18n/es/docusaurus-plugin-content-docs/current/ORDA/privileges.md @@ -39,40 +39,6 @@ The **execute** permission of a [shared singleton](../Concepts/classes.md#shared Permissions never apply to [desktop session code](../Desktop/sessions.md) (standalone, client/server, stored procedures) or [tool4d](../Admin/cli.md#tool4d). -:::warning - -When a permission entry references an undeclared [privilege](#privileges-and-roles), 4D logs an error and ignores the entry. In this case, the permission is ignored. If the [restricted mode by default](#restriction-modes) is not enabled, the resource is accessible to `guest` sessions. - -::: - -### MCP tools - -The same permissions apply to the sessions of the [MCP server](../WebServer/mcp-server.md), with nothing specific to configure: - -- A [custom tool](../WebServer/mcp-server.md#custom-tools) (`exposed MCP Function`) requires the **execute** permission on its function, and benefits from its **promote** permission. -- The [built-in CRUD tools](../WebServer/mcp-server.md#built-in-crud-tools) require the **read**, **create**, **update**, or **drop** permission on the dataclass, and the attribute permissions apply. Each attribute of a path used in a filter, a sort, or a projection requires the **read** permission. -- The CRUD tools are listed only if the session has at least one data permission on a dataclass, and the `describeModel` tool only describes the dataclasses on which the session has a data permission, with their readable or writable attributes. -- A tool, a dataclass, or an attribute that the session cannot access is reported as if it did not exist. - -#### Ejemplo - -MCP clients authenticated with the "salesReader" privilege can read the Customer and Order dataclasses with the CRUD tools, and call the tools published by the `OrderManager` singleton (for example `OrderManager-getYearTotal`): - -```json -{ - "privileges": [{"privilege": "salesReader", "includes": []}], - "roles": [], - "permissions": { - "allowed": [ - {"applyTo": "Customer", "type": "dataclass", "read": ["salesReader"]}, - {"applyTo": "Order", "type": "dataclass", "read": ["salesReader"]}, - {"applyTo": "OrderManager", "type": "singleton", "execute": ["salesReader"]} - ] - }, - "restrictedByDefault": true -} -``` - ### MCP tools The same permissions apply to the sessions of the [MCP server](../WebServer/mcp-server.md), with nothing specific to configure: @@ -294,6 +260,12 @@ The project's web security settings are defined in `roles.json`: ::: +:::warning + +When a permission entry references an undeclared [privilege](#privileges-and-roles), 4D logs an error and ignores the entry. In this case, the permission is ignored. If the [restricted mode by default](#restriction-modes) is not enabled, the resource is accessible to `guest` sessions. + +::: + ### Default location and content New projects generate `roles.json` at: From 5d5687243344b70966f53905ccaa465539ececc8 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Wed, 4 Nov 2026 21:04:14 +0100 Subject: [PATCH 006/195] quotas.md Spanish --- .../current/WebServer/quotas.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/i18n/es/docusaurus-plugin-content-docs/current/WebServer/quotas.md b/i18n/es/docusaurus-plugin-content-docs/current/WebServer/quotas.md index 32690cf53b00ec..5d96247ccab09c 100644 --- a/i18n/es/docusaurus-plugin-content-docs/current/WebServer/quotas.md +++ b/i18n/es/docusaurus-plugin-content-docs/current/WebServer/quotas.md @@ -12,12 +12,6 @@ Las cuotas del servidor web le permiten controlar el uso de recursos limitando e ::: -:::tip Entradas de blog relacionadas - -[Un servidor web 4D que sabe cuándo decir No](https://blog.4d.com/a-4d-web-server-that-knows-when-to-say-no/) - -::: - ## Requisitos La configuración de cuotas requiere la activación de las [sesiones escalables](./sessions.md#enabling-web-sessions). From 1eb7e8e4ca71509718c00b6f6c0f1754faf87314 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Wed, 4 Nov 2026 21:26:10 +0100 Subject: [PATCH 007/195] exit.md Spanish --- .../docusaurus-plugin-content-docs/current/server/exit.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/i18n/es/docusaurus-plugin-content-docs/current/server/exit.md b/i18n/es/docusaurus-plugin-content-docs/current/server/exit.md index 7203df2d4d4348..8cf369d1645c45 100644 --- a/i18n/es/docusaurus-plugin-content-docs/current/server/exit.md +++ b/i18n/es/docusaurus-plugin-content-docs/current/server/exit.md @@ -27,15 +27,15 @@ Aparecerá una ventana idéntica en cada máquina 4D remota. Esta ventana se rep - **Espere a que todos los clientes se desconecten.** -El servidor solo se cerrará una vez que todos los clientes, incluidos los que estén en modo de suspensión, se hayan desconectado. Esta opción podría ser inadecuada para operaciones de mantenimiento durante el almuerzo, por ejemplo, ya que es probable que haya clientes en [modo inactivo](../ServerWindow/users.md#managing-sleeping-users). +El servidor solo se cerrará una vez que todos los clientes, incluidos los que estén en modo de suspensión, se hayan desconectado. Esta opción podría ser inadecuada para operaciones de mantenimiento durante el almuerzo, por ejemplo, ya que es probable que haya clientes en [modo inactivo](../ServerWindow/sessions.md#management-of-sleeping-client-sessions). - **Espere a que los clientes activos se desconecten. (Ignorar a los clientes inactivos)** -El servidor solo se cerrará después de que todos los clientes activos se hayan desconectado (en otras palabras, todas las máquinas cliente que no están en [modo inactivo](../ServerWindow/users.md#managing-sleeping-users)). Con esta opción, los clientes que se encuentren en modo inactivo no se consideran conectados. Utilice esta opción si desea realizar operaciones de mantenimiento durante el almuerzo, por ejemplo. Cuando se utiliza esta opción, cualquier cliente que se encuentre en modo inactivo experimentará un error de conexión al reactivarse. +El servidor solo se cerrará después de que todos los clientes activos se hayan desconectado (en otras palabras, todas las máquinas cliente que no están en [modo inactivo](../ServerWindow/sessions.md#management-of-sleeping-client-sessions)). Con esta opción, los clientes que se encuentren en modo inactivo no se consideran conectados. Utilice esta opción si desea realizar operaciones de mantenimiento durante el almuerzo, por ejemplo. Cuando se utiliza esta opción, cualquier cliente que se encuentre en modo inactivo experimentará un error de conexión al reactivarse. :::note -Un *cliente inactivo* se refiere a una aplicación 4D remota en una máquina que ha pasado a [modo inactivo](../ServerWindow/users.md#managing-sleeping-users) mientras la conexión a la máquina servidor seguía activa. +Un *cliente inactivo* se refiere a una aplicación 4D remota en una máquina que ha pasado a [modo inactivo](../ServerWindow/sessions.md#management-of-sleeping-client-sessions) mientras la conexión a la máquina servidor seguía activa. ::: From 2f06e17d99a40e551af5cd1552421f2edb66b778 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Wed, 4 Nov 2026 23:20:17 +0100 Subject: [PATCH 008/195] buttongrid_overview.md Japanese --- .../current/FormObjects/buttonGrid_overview.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/buttonGrid_overview.md b/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/buttonGrid_overview.md index cade194a67e03e..2115f3afd5cba8 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/buttonGrid_overview.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/buttonGrid_overview.md @@ -26,11 +26,11 @@ title: ボタングリッド ボタングリッドにページ指定用の `gotoPage` [標準アクション](/Desktop/standard-actions)を割り当てることができます。この標準アクションを設定すると、4D はボタングリッドで選択されたボタンの番号に相当するフォームページを自動的に表示します。たとえばグリッド上の 10 番目のボタンを選択すると、4D は現在のフォームの 10 ページ目を表示します (存在する場合)。 -## Supported standard actions +## サポートされる標準アクション -- [gotoPage](../Desktop-legacy/standard-actions.md#gotopage): Uses the selected button number as described in [Goto page](#goto-page). +- [gotoPage](../Desktop-legacy/standard-actions.md#gotopage): [ページ指定アクション](#ページ指定アクション) の説明に従って選択されたボタン番号を使用します。 -See the [standard action compatibility table](../Desktop-legacy/standard-actions.md#supported-form-objects). +詳細については[標準アクション互換性表](../Desktop-legacy/standard-actions.md#サポートされるフォームオブジェクト) を参照してください。 ## プロパティ一覧 From 01c499c3b4deea3c99113f780b6ace1b4c413699 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Wed, 4 Nov 2026 23:20:24 +0100 Subject: [PATCH 009/195] button_overview.md Japanese --- .../current/FormObjects/button_overview.md | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/button_overview.md b/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/button_overview.md index 125739531a6cfe..a39c1f0ec411f0 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/button_overview.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/button_overview.md @@ -332,11 +332,11 @@ Windows Classic UI テーマでは、このスタイルはサポートされま } ``` -## Supported standard actions +## サポートされる標準アクション -The following standard actions can be assigned to buttons: +ボタンには、以下の標準アクションを割り当てることができます: -### Records and forms +### レコードとフォーム - [accept](../Desktop-legacy/standard-actions.md#accept) - [cancel](../Desktop-legacy/standard-actions.md#cancel) @@ -350,7 +350,7 @@ The following standard actions can be assigned to buttons: - [nextRecord](../Desktop-legacy/standard-actions.md#nextrecord) - [previousRecord](../Desktop-legacy/standard-actions.md#previousrecord) -### Pages +### ページ - [firstPage](../Desktop-legacy/standard-actions.md#firstpage) - [lastPage](../Desktop-legacy/standard-actions.md#lastpage) @@ -358,7 +358,7 @@ The following standard actions can be assigned to buttons: - [previousPage](../Desktop-legacy/standard-actions.md#previouspage) - [gotoPage?value=\](../Desktop-legacy/standard-actions.md#gotopagevaluepage) -### Editing and expressions +### 編集と式 - [clear](../Desktop-legacy/standard-actions.md#clear) - [copy](../Desktop-legacy/standard-actions.md#copy) @@ -371,7 +371,7 @@ The following standard actions can be assigned to buttons: - [freezeExpressions](../Desktop-legacy/standard-actions.md#freezeexpressions) - [visibleReferences](../Desktop-legacy/standard-actions.md#visiblereferences) -### Formatting +### 書式設定 - [backgroundColor/showDialog](../Desktop-legacy/standard-actions.md#backgroundcolorshowdialog) - [backgroundColor?value=\](../Desktop-legacy/standard-actions.md#backgroundcolorvaluecolor) @@ -384,7 +384,7 @@ The following standard actions can be assigned to buttons: - [fontSize?value=\](../Desktop-legacy/standard-actions.md#fontsizevaluesize) - [fontUnderline](../Desktop-legacy/standard-actions.md#fontunderline) -### Spellchecking +### スペルチェック - [spell/autoCorrectionEnabled](../Desktop-legacy/standard-actions.md#spellautocorrectionenabled) - [spell/autoDashSubstitutionsEnabled](../Desktop-legacy/standard-actions.md#spellautodashsubstitutionsenabled) @@ -402,14 +402,14 @@ The following standard actions can be assigned to buttons: - [spell/unLearn](../Desktop-legacy/standard-actions.md#spellunlearn) - [spell/visibleSubstitutions](../Desktop-legacy/standard-actions.md#spellvisiblesubstitutions) -### Web-area controls +### Webエリアコントロール - [openBackURL](../Desktop-legacy/standard-actions.md#openbackurl) - [openForwardURL](../Desktop-legacy/standard-actions.md#openforwardurl) - [refreshCurrentURL](../Desktop-legacy/standard-actions.md#refreshcurrenturl) - [stopLoadingURL](../Desktop-legacy/standard-actions.md#stoploadingurl) -### Other actions +### その他のアクション - [databaseSettings](../Desktop-legacy/standard-actions.md#databasesettings) - [designMode](../Desktop-legacy/standard-actions.md#designmode) @@ -418,15 +418,15 @@ The following standard actions can be assigned to buttons: - [showClipboard](../Desktop-legacy/standard-actions.md#showclipboard) - [writingTools](../Desktop-legacy/standard-actions.md#writingtools) -### Invisible buttons only +### 非表示ボタンのみ - [automaticSplitter](../Desktop-legacy/standard-actions.md#automaticsplitter) -### 4D Write Pro standard actions +### 4D Write Pro標準アクション - [formulaHighlight?value=\](../WritePro/user-legacy/standard-actions.md#action-formulahighlight) -The [empty action](../Desktop-legacy/standard-actions.md#-empty-string) leaves the button's behavior to its method. See the [standard action compatibility table](../Desktop-legacy/standard-actions.md#supported-form-objects) for comparisons with other objects. +[empty アクション](../Desktop-legacy/standard-actions.md#-empty-string) の場合にはボタンの振る舞いはそのオブジェクトメソッドに移譲されます。他のオブジェクトとの比較のためには[標準アクション互換性表](../Desktop-legacy/standard-actions.md#サポートされるフォームオブジェクト) を参照してください。 ## プロパティ一覧 @@ -441,7 +441,7 @@ The [empty action](../Desktop-legacy/standard-actions.md#-empty-string) leaves t [カスタム](#カスタム) スタイルのボタンに対しては特有の追加のプロパティが利用可能です: -[背景パス名](properties_TextAndPicture.md#背景パス名) - [境界線カラー](./properties_BackgroundAndBorder.md#境界線カラー) - [境界線幅](./properties_BackgroundAndBorder.md#境界線幅) - [横方向マージン](properties_TextAndPicture.md#横方向マージン) - [アイコンオフセット](properties_TextAndPicture.md#アイコンオフセット) - [縦方向マージン](properties_TextAndPicture.md#縦方向マージン) - [角の半径](properties_CoordinatesAndSizing.md#角の半径) - [デフォルトボタン](properties_Appearance.md#デフォルトボタン) - [塗りカラー](./properties_BackgroundAndBorder.md#背景色塗りカラー) +[背景パス名](properties_TextAndPicture.md#背景パス名) - [境界線カラー](./properties_BackgroundAndBorder.md#border-color) - [境界線幅](./properties_BackgroundAndBorder.md#境界線幅) - [横方向マージン](properties_TextAndPicture.md#横方向マージン) - [アイコンオフセット](properties_TextAndPicture.md#アイコンオフセット) - [縦方向マージン](properties_TextAndPicture.md#縦方向マージン) - [角の半径](properties_CoordinatesAndSizing.md#角の半径) - [デフォルトボタン](properties_Appearance.md#デフォルトボタン) - [塗りカラー](./properties_BackgroundAndBorder.md#背景色塗りカラー) ### フラットおよび通常ボタンにおける追加のプロパティ From 43633aea5b5abd1dfecbe57810c5ea67a065df73 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Wed, 4 Nov 2026 23:20:26 +0100 Subject: [PATCH 010/195] checkbox_overview.md Japanese --- .../current/FormObjects/checkbox_overview.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/checkbox_overview.md b/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/checkbox_overview.md index f653d44656ba03..ebeb575fa6858a 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/checkbox_overview.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/checkbox_overview.md @@ -348,7 +348,7 @@ Office XP スタイルのチェックボックスの反転表示と背景のカ } ``` -## Supported standard actions +## サポートされる標準アクション true/false ステータスで表すことのできるアクション ("checkable" アクション) のみがサポートされます: @@ -385,7 +385,7 @@ true/false ステータスで表すことのできるアクション ("checkable これらのアクションについての詳細は、[標準アクション](properties_Action.md#標準アクション) の章を参照してください。 -See also the [standard action compatibility table](../Desktop-legacy/standard-actions.md#supported-form-objects). +[標準アクション互換性表](../Desktop-legacy/standard-actions.md#supported-form-objects) も参照してください。 ## プロパティ一覧 @@ -400,7 +400,7 @@ See also the [standard action compatibility table](../Desktop-legacy/standard-ac [カスタム](#カスタム) スタイルのチェックボックスに対しては特有の追加のプロパティが利用可能です: -[背景パス名](properties_TextAndPicture.md#背景パス名) - [境界線カラー](./properties_BackgroundAndBorder.md#境界線カラー) - [境界線幅](./properties_BackgroundAndBorder.md#境界線幅) - [横方向マージン](properties_TextAndPicture.md#横方向マージン) - [アイコンオフセット](properties_TextAndPicture.md#アイコンオフセット) - [縦方向マージン](properties_TextAndPicture.md#縦方向マージン) - [角の半径](properties_CoordinatesAndSizing.md#角の半径) - [塗りカラー](./properties_BackgroundAndBorder.md#背景色塗りカラー) +[背景パス名](properties_TextAndPicture.md#背景パス名) - [境界線カラー](./properties_BackgroundAndBorder.md#border-color) - [境界線幅](./properties_BackgroundAndBorder.md#境界線幅) - [横方向マージン](properties_TextAndPicture.md#横方向マージン) - [アイコンオフセット](properties_TextAndPicture.md#アイコンオフセット) - [縦方向マージン](properties_TextAndPicture.md#縦方向マージン) - [角の半径](properties_CoordinatesAndSizing.md#角の半径) - [塗りカラー](./properties_BackgroundAndBorder.md#背景色塗りカラー) ### フラットおよび通常チェックボックスにおける追加のプロパティ From 069cf853f2f6b810cbdc8e02bb51d2bb331d2fd4 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Wed, 4 Nov 2026 23:20:31 +0100 Subject: [PATCH 011/195] dropdownlist_overview.md Japanese --- .../current/FormObjects/dropdownList_Overview.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/dropdownList_Overview.md b/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/dropdownList_Overview.md index d7b4e2756d2794..6cf2fd2badde38 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/dropdownList_Overview.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/dropdownList_Overview.md @@ -163,21 +163,21 @@ Form.myDrop.index //3 > この機能は、階層型のドロップダウンリストでは使用できません。 -## Supported standard actions +## サポートされる標準アクション -The following actions are available in the drop-down list standard-action selector. See [Standard actions](../Desktop-legacy/standard-actions.md) and [4D Write Pro standard actions](../WritePro/user-legacy/standard-actions.md) for action descriptions and requirements. +ドロップダウンリストの標準アクションセレクターでは、以下の標準アクションが利用可能です。アクションの詳細と必要要件については[標準アクション](../Desktop-legacy/standard-actions.md) および[4D Write Pro 標準アクション](../WritePro/user-legacy/standard-actions.md) を参照してください。 [`gotoPage`](../Desktop-legacy/standard-actions.md#gotopage) - [`fontSize`](../Desktop-legacy/standard-actions.md#fontsize) - [`color`](../Desktop-legacy/standard-actions.md#color) - [`backgroundColor`](../WritePro/user-legacy/standard-actions.md#action-backgroundcolor) - [`textUnderlineStyle`](../WritePro/user-legacy/standard-actions.md#action-textunderlinestyle) - [`textUnderlineColor`](../WritePro/user-legacy/standard-actions.md#action-textunderlinecolor) - [`textLinethroughStyle`](../WritePro/user-legacy/standard-actions.md#action-textlinethroughstyle) - [`textLinethroughColor`](../WritePro/user-legacy/standard-actions.md#action-textlinethroughcolor) - [`textShadowOffset`](../WritePro/user-legacy/standard-actions.md#action-textshadowoffset) - [`textShadowColor`](../WritePro/user-legacy/standard-actions.md#action-textshadowcolor) - [`textTransform`](../WritePro/user-legacy/standard-actions.md#action-texttransform) - [`dpi`](../WritePro/user-legacy/standard-actions.md#action-dpi) - [`zoom`](../WritePro/user-legacy/standard-actions.md#action-zoom) - [`userUnit`](../WritePro/user-legacy/standard-actions.md#action-userunit) - [`pageMode`](../WritePro/user-legacy/standard-actions.md#action-pagemode) - [`pageSize`](../WritePro/user-legacy/standard-actions.md#action-pagesize) - [`tabDecimalSeparator`](../WritePro/user-legacy/standard-actions.md#action-tabdecimalseparator) - [`pageOrientation`](../WritePro/user-legacy/standard-actions.md#action-pageorientation) - [`section/pageOrientation`](../WritePro/user-legacy/standard-actions.md#action-pageorientation) - [`columnCount`](../WritePro/user-legacy/standard-actions.md#action-columncount) - [`section/columnCount`](../WritePro/user-legacy/standard-actions.md#action-columncount) - [`columnSpacing`](../WritePro/user-legacy/standard-actions.md#action-columnspacing) - [`section/columnSpacing`](../WritePro/user-legacy/standard-actions.md#action-columnspacing) - [`columnRuleStyle`](../WritePro/user-legacy/standard-actions.md#action-columnrulestyle) - [`section/columnRuleStyle`](../WritePro/user-legacy/standard-actions.md#action-columnrulestyle) - [`columnRuleColor`](../WritePro/user-legacy/standard-actions.md#action-columnrulecolor) - [`section/columnRuleColor`](../WritePro/user-legacy/standard-actions.md#action-columnrulecolor) - [`columnRuleWidth`](../WritePro/user-legacy/standard-actions.md#action-columnrulewidth) - [`section/columnRuleWidth`](../WritePro/user-legacy/standard-actions.md#action-columnrulewidth) - [`bookmark`](../WritePro/user-legacy/standard-actions.md#action-bookmark) - [`width`](../WritePro/user-legacy/standard-actions.md#action-width) - [`paragraph/width`](../WritePro/user-legacy/standard-actions.md#action-width) - [`image/width`](../WritePro/user-legacy/standard-actions.md#action-width) - [`column/width`](../WritePro/user-legacy/standard-actions.md#action-width) - [`image/height`](../WritePro/user-legacy/standard-actions.md#action-height) - [`row/height`](../WritePro/user-legacy/standard-actions.md#action-height) - [`minWidth`](../WritePro/user-legacy/standard-actions.md#action-minwidth) - [`paragraph/minWidth`](../WritePro/user-legacy/standard-actions.md#action-minwidth) - [`image/minWidth`](../WritePro/user-legacy/standard-actions.md#action-minwidth) - [`minHeight`](../WritePro/user-legacy/standard-actions.md#action-minheight) - [`paragraph/minHeight`](../WritePro/user-legacy/standard-actions.md#action-minheight) - [`image/minHeight`](../WritePro/user-legacy/standard-actions.md#action-minheight) - [`margin`](../WritePro/user-legacy/standard-actions.md#action-margin) - [`doc/margin`](../WritePro/user-legacy/standard-actions.md#action-margin) - [`paragraph/margin`](../WritePro/user-legacy/standard-actions.md#action-margin) - [`paragraph/inside/margin`](../WritePro/user-legacy/standard-actions.md#action-margin) - [`paragraph/outside/margin`](../WritePro/user-legacy/standard-actions.md#action-margin) - [`image/margin`](../WritePro/user-legacy/standard-actions.md#action-margin) - [`section/margin`](../WritePro/user-legacy/standard-actions.md#action-margin) - [`header/margin`](../WritePro/user-legacy/standard-actions.md#action-margin) - [`footer/margin`](../WritePro/user-legacy/standard-actions.md#action-margin) - [`table/margin`](../WritePro/user-legacy/standard-actions.md#action-margin) - [`padding`](../WritePro/user-legacy/standard-actions.md#action-padding) - [`doc/padding`](../WritePro/user-legacy/standard-actions.md#action-padding) - [`paragraph/padding`](../WritePro/user-legacy/standard-actions.md#action-padding) - [`paragraph/inside/padding`](../WritePro/user-legacy/standard-actions.md#action-padding) - [`paragraph/outside/padding`](../WritePro/user-legacy/standard-actions.md#action-padding) - [`image/padding`](../WritePro/user-legacy/standard-actions.md#action-padding) - [`section/padding`](../WritePro/user-legacy/standard-actions.md#action-padding) - [`header/padding`](../WritePro/user-legacy/standard-actions.md#action-padding) - [`footer/padding`](../WritePro/user-legacy/standard-actions.md#action-padding) - [`cell/padding`](../WritePro/user-legacy/standard-actions.md#action-padding) - [`column/padding`](../WritePro/user-legacy/standard-actions.md#action-padding) - [`doc/backgroundColor`](../WritePro/user-legacy/standard-actions.md#action-backgroundcolor) - [`paragraph/backgroundColor`](../WritePro/user-legacy/standard-actions.md#action-backgroundcolor) - [`image/backgroundColor`](../WritePro/user-legacy/standard-actions.md#action-backgroundcolor) - [`section/backgroundColor`](../WritePro/user-legacy/standard-actions.md#action-backgroundcolor) - [`header/backgroundColor`](../WritePro/user-legacy/standard-actions.md#action-backgroundcolor) - [`footer/backgroundColor`](../WritePro/user-legacy/standard-actions.md#action-backgroundcolor) - [`table/backgroundColor`](../WritePro/user-legacy/standard-actions.md#action-backgroundcolor) - [`row/backgroundColor`](../WritePro/user-legacy/standard-actions.md#action-backgroundcolor) - [`cell/backgroundColor`](../WritePro/user-legacy/standard-actions.md#action-backgroundcolor) - [`column/backgroundColor`](../WritePro/user-legacy/standard-actions.md#action-backgroundcolor) - [`backgroundPositionH`](../WritePro/user-legacy/standard-actions.md#action-backgroundpositionh) - [`doc/backgroundPositionH`](../WritePro/user-legacy/standard-actions.md#action-backgroundpositionh) - [`paragraph/backgroundPositionH`](../WritePro/user-legacy/standard-actions.md#action-backgroundpositionh) - [`image/backgroundPositionH`](../WritePro/user-legacy/standard-actions.md#action-backgroundpositionh) - [`section/backgroundPositionH`](../WritePro/user-legacy/standard-actions.md#action-backgroundpositionh) - [`header/backgroundPositionH`](../WritePro/user-legacy/standard-actions.md#action-backgroundpositionh) - [`footer/backgroundPositionH`](../WritePro/user-legacy/standard-actions.md#action-backgroundpositionh) - [`table/backgroundPositionH`](../WritePro/user-legacy/standard-actions.md#action-backgroundpositionh) - [`row/backgroundPositionH`](../WritePro/user-legacy/standard-actions.md#action-backgroundpositionh) - [`cell/backgroundPositionH`](../WritePro/user-legacy/standard-actions.md#action-backgroundpositionh) - [`column/backgroundPositionH`](../WritePro/user-legacy/standard-actions.md#action-backgroundpositionh) - [`backgroundPositionV`](../WritePro/user-legacy/standard-actions.md#action-backgroundpositionv) - [`doc/backgroundPositionV`](../WritePro/user-legacy/standard-actions.md#action-backgroundpositionv) - [`paragraph/backgroundPositionV`](../WritePro/user-legacy/standard-actions.md#action-backgroundpositionv) - [`image/backgroundPositionV`](../WritePro/user-legacy/standard-actions.md#action-backgroundpositionv) - [`section/backgroundPositionV`](../WritePro/user-legacy/standard-actions.md#action-backgroundpositionv) - [`header/backgroundPositionV`](../WritePro/user-legacy/standard-actions.md#action-backgroundpositionv) - [`footer/backgroundPositionV`](../WritePro/user-legacy/standard-actions.md#action-backgroundpositionv) - [`table/backgroundPositionV`](../WritePro/user-legacy/standard-actions.md#action-backgroundpositionv) - [`row/backgroundPositionV`](../WritePro/user-legacy/standard-actions.md#action-backgroundpositionv) - [`cell/backgroundPositionV`](../WritePro/user-legacy/standard-actions.md#action-backgroundpositionv) - [`column/backgroundPositionV`](../WritePro/user-legacy/standard-actions.md#action-backgroundpositionv) - [`backgroundRepeat`](../WritePro/user-legacy/standard-actions.md#action-backgroundrepeat) - [`doc/backgroundRepeat`](../WritePro/user-legacy/standard-actions.md#action-backgroundrepeat) - [`paragraph/backgroundRepeat`](../WritePro/user-legacy/standard-actions.md#action-backgroundrepeat) - [`image/backgroundRepeat`](../WritePro/user-legacy/standard-actions.md#action-backgroundrepeat) - [`section/backgroundRepeat`](../WritePro/user-legacy/standard-actions.md#action-backgroundrepeat) - [`header/backgroundRepeat`](../WritePro/user-legacy/standard-actions.md#action-backgroundrepeat) - [`footer/backgroundRepeat`](../WritePro/user-legacy/standard-actions.md#action-backgroundrepeat) - [`table/backgroundRepeat`](../WritePro/user-legacy/standard-actions.md#action-backgroundrepeat) - [`row/backgroundRepeat`](../WritePro/user-legacy/standard-actions.md#action-backgroundrepeat) - [`cell/backgroundRepeat`](../WritePro/user-legacy/standard-actions.md#action-backgroundrepeat) - [`column/backgroundRepeat`](../WritePro/user-legacy/standard-actions.md#action-backgroundrepeat) - [`backgroundClip`](../WritePro/user-legacy/standard-actions.md#action-backgroundclip) - [`doc/backgroundClip`](../WritePro/user-legacy/standard-actions.md#action-backgroundclip) - [`paragraph/backgroundClip`](../WritePro/user-legacy/standard-actions.md#action-backgroundclip) - [`image/backgroundClip`](../WritePro/user-legacy/standard-actions.md#action-backgroundclip) - [`section/backgroundClip`](../WritePro/user-legacy/standard-actions.md#action-backgroundclip) - [`header/backgroundClip`](../WritePro/user-legacy/standard-actions.md#action-backgroundclip) - [`table/backgroundClip`](../WritePro/user-legacy/standard-actions.md#action-backgroundclip) - [`row/backgroundClip`](../WritePro/user-legacy/standard-actions.md#action-backgroundclip) - [`cell/backgroundClip`](../WritePro/user-legacy/standard-actions.md#action-backgroundclip) - [`column/backgroundClip`](../WritePro/user-legacy/standard-actions.md#action-backgroundclip) - [`backgroundOrigin`](../WritePro/user-legacy/standard-actions.md#action-backgroundorigin) - [`doc/backgroundOrigin`](../WritePro/user-legacy/standard-actions.md#action-backgroundorigin) - [`paragraph/backgroundOrigin`](../WritePro/user-legacy/standard-actions.md#action-backgroundorigin) - [`image/backgroundOrigin`](../WritePro/user-legacy/standard-actions.md#action-backgroundorigin) - [`section/backgroundOrigin`](../WritePro/user-legacy/standard-actions.md#action-backgroundorigin) - [`header/backgroundOrigin`](../WritePro/user-legacy/standard-actions.md#action-backgroundorigin) - [`footer/backgroundOrigin`](../WritePro/user-legacy/standard-actions.md#action-backgroundorigin) - [`table/backgroundOrigin`](../WritePro/user-legacy/standard-actions.md#action-backgroundorigin) - [`row/backgroundOrigin`](../WritePro/user-legacy/standard-actions.md#action-backgroundorigin) - [`cell/backgroundOrigin`](../WritePro/user-legacy/standard-actions.md#action-backgroundorigin) - [`column/backgroundOrigin`](../WritePro/user-legacy/standard-actions.md#action-backgroundorigin) - [`backgroundSizeH`](../WritePro/user-legacy/standard-actions.md#action-backgroundsizeh) - [`doc/backgroundSizeH`](../WritePro/user-legacy/standard-actions.md#action-backgroundsizeh) - [`paragraph/backgroundSizeH`](../WritePro/user-legacy/standard-actions.md#action-backgroundsizeh) - [`image/backgroundSizeH`](../WritePro/user-legacy/standard-actions.md#action-backgroundsizeh) - [`section/backgroundSizeH`](../WritePro/user-legacy/standard-actions.md#action-backgroundsizeh) - [`header/backgroundSizeH`](../WritePro/user-legacy/standard-actions.md#action-backgroundsizeh) - [`footer/backgroundSizeH`](../WritePro/user-legacy/standard-actions.md#action-backgroundsizeh) - [`table/backgroundSizeH`](../WritePro/user-legacy/standard-actions.md#action-backgroundsizeh) - [`row/backgroundSizeH`](../WritePro/user-legacy/standard-actions.md#action-backgroundsizeh) - [`cell/backgroundSizeH`](../WritePro/user-legacy/standard-actions.md#action-backgroundsizeh) - [`column/backgroundSizeH`](../WritePro/user-legacy/standard-actions.md#action-backgroundsizeh) - [`backgroundSizeV`](../WritePro/user-legacy/standard-actions.md#action-backgroundsizev) - [`doc/backgroundSizeV`](../WritePro/user-legacy/standard-actions.md#action-backgroundsizev) - [`paragraph/backgroundSizeV`](../WritePro/user-legacy/standard-actions.md#action-backgroundsizev) - [`image/backgroundSizeV`](../WritePro/user-legacy/standard-actions.md#action-backgroundsizev) - [`section/backgroundSizeV`](../WritePro/user-legacy/standard-actions.md#action-backgroundsizev) - [`header/backgroundSizeV`](../WritePro/user-legacy/standard-actions.md#action-backgroundsizev) - [`footer/backgroundSizeV`](../WritePro/user-legacy/standard-actions.md#action-backgroundsizev) - [`table/backgroundSizeV`](../WritePro/user-legacy/standard-actions.md#action-backgroundsizev) - [`row/backgroundSizeV`](../WritePro/user-legacy/standard-actions.md#action-backgroundsizev) - [`cell/backgroundSizeV`](../WritePro/user-legacy/standard-actions.md#action-backgroundsizev) - [`column/backgroundSizev`](../WritePro/user-legacy/standard-actions.md#action-backgroundsizev) - [`borderStyle`](../WritePro/user-legacy/standard-actions.md#action-borderstyle) - [`doc/borderStyle`](../WritePro/user-legacy/standard-actions.md#action-borderstyle) - [`paragraph/borderStyle`](../WritePro/user-legacy/standard-actions.md#action-borderstyle) - [`paragraph/inside/borderStyle`](../WritePro/user-legacy/standard-actions.md#action-borderstyle) - [`paragraph/outside/borderStyle`](../WritePro/user-legacy/standard-actions.md#action-borderstyle) - [`image/borderStyle`](../WritePro/user-legacy/standard-actions.md#action-borderstyle) - [`section/borderStyle`](../WritePro/user-legacy/standard-actions.md#action-borderstyle) - [`header/borderStyle`](../WritePro/user-legacy/standard-actions.md#action-borderstyle) - [`footer/borderStyle`](../WritePro/user-legacy/standard-actions.md#action-borderstyle) - [`table/borderStyle`](../WritePro/user-legacy/standard-actions.md#action-borderstyle) - [`row/borderStyle`](../WritePro/user-legacy/standard-actions.md#action-borderstyle) - [`cell/borderStyle`](../WritePro/user-legacy/standard-actions.md#action-borderstyle) - [`column/borderStyle`](../WritePro/user-legacy/standard-actions.md#action-borderstyle) - [`borderColor`](../WritePro/user-legacy/standard-actions.md#action-bordercolor) - [`doc/borderColor`](../WritePro/user-legacy/standard-actions.md#action-bordercolor) - [`paragraph/borderColor`](../WritePro/user-legacy/standard-actions.md#action-bordercolor) - [`paragraph/inside/borderColor`](../WritePro/user-legacy/standard-actions.md#action-bordercolor) - [`paragraph/outside/borderColor`](../WritePro/user-legacy/standard-actions.md#action-bordercolor) - [`image/borderColor`](../WritePro/user-legacy/standard-actions.md#action-bordercolor) - [`section/borderColor`](../WritePro/user-legacy/standard-actions.md#action-bordercolor) - [`header/borderColor`](../WritePro/user-legacy/standard-actions.md#action-bordercolor) - [`footer/borderColor`](../WritePro/user-legacy/standard-actions.md#action-bordercolor) - [`table/borderColor`](../WritePro/user-legacy/standard-actions.md#action-bordercolor) - [`row/borderColor`](../WritePro/user-legacy/standard-actions.md#action-bordercolor) - [`cell/borderColor`](../WritePro/user-legacy/standard-actions.md#action-bordercolor) - [`column/borderColor`](../WritePro/user-legacy/standard-actions.md#action-bordercolor) - [`borderWidth`](../WritePro/user-legacy/standard-actions.md#action-borderwidth)- [`doc/borderWidth`](../WritePro/user-legacy/standard-actions.md#action-borderwidth) - [`paragraph/borderWidth`](../WritePro/user-legacy/standard-actions.md#action-borderwidth) - [`paragraph/inside/borderWidth`](../WritePro/user-legacy/standard-actions.md#action-borderwidth) - [`paragraph/outside/borderWidth`](../WritePro/user-legacy/standard-actions.md#action-borderwidth) - [`image/borderWidth`](../WritePro/user-legacy/standard-actions.md#action-borderwidth) - [`section/borderWidth`](../WritePro/user-legacy/standard-actions.md#action-borderwidth) - [`header/borderWidth`](../WritePro/user-legacy/standard-actions.md#action-borderwidth) - [`footer/borderWidth`](../WritePro/user-legacy/standard-actions.md#action-borderwidth) - [`table/borderWidth`](../WritePro/user-legacy/standard-actions.md#action-borderwidth) - [`row/borderWidth`](../WritePro/user-legacy/standard-actions.md#action-borderwidth) - [`cell/borderWidth`](../WritePro/user-legacy/standard-actions.md#action-borderwidth) - [`column/borderWidth`](../WritePro/user-legacy/standard-actions.md#action-borderwidth) - [`borderRadius`](../WritePro/user-legacy/standard-actions.md#action-borderradius) - [`doc/borderRadius`](../WritePro/user-legacy/standard-actions.md#action-borderradius) - [`paragraph/borderRadius`](../WritePro/user-legacy/standard-actions.md#action-borderradius) - [`image/borderRadius`](../WritePro/user-legacy/standard-actions.md#action-borderradius) - [`section/borderRadius`](../WritePro/user-legacy/standard-actions.md#action-borderradius) - [`header/borderRadius`](../WritePro/user-legacy/standard-actions.md#action-borderradius) - [`footer/borderRadius`](../WritePro/user-legacy/standard-actions.md#action-borderradius) - [`direction`](../WritePro/user-legacy/standard-actions.md#action-direction) - [`textAlign`](../WritePro/user-legacy/standard-actions.md#action-textalign) - [`lineHeight`](../WritePro/user-legacy/standard-actions.md#action-lineheight) - [`listStyleType`](../WritePro/user-legacy/standard-actions.md#action-liststyletype) - [`listStartNumber`](../WritePro/user-legacy/standard-actions.md#action-liststartnumber) - [`listNumberFormat`](../WritePro/user-legacy/standard-actions.md#action-listnumberformat) - [`textIndent`](../WritePro/user-legacy/standard-actions.md#action-textindent) - [`verticalAlign`](../WritePro/user-legacy/standard-actions.md#action-verticalalign) - [`image/verticalAlign`](../WritePro/user-legacy/standard-actions.md#action-image-verticalalign) - [`cell/verticalAlign`](../WritePro/user-legacy/standard-actions.md#action-verticalalign) - [`column/verticalAlign`](../WritePro/user-legacy/standard-actions.md#action-verticalalign) - [`tableAlign`](../WritePro/user-legacy/standard-actions.md#action-tablealign) - [`table/tableAlign`](../WritePro/user-legacy/standard-actions.md#action-tablealign) - [`emptyDatasource`](../WritePro/user-legacy/standard-actions.md#action-emptydatasource) - [`table/emptyDatasource`](../WritePro/user-legacy/standard-actions.md#action-emptydatasource) - [`styleSheet`](../WritePro/user-legacy/standard-actions.md#action-stylesheet) - [`paragraph/styleSheet`](../WritePro/user-legacy/standard-actions.md#action-stylesheet) - [`image/styleSheet`](../WritePro/user-legacy/standard-actions.md#action-stylesheet) - [`newLineStyleSheet`](../WritePro/user-legacy/standard-actions.md#action-newlinestylesheet) - [`anchorLayout`](../WritePro/user-legacy/standard-actions.md#action-anchorlayout) - [`anchorHorizontalAlign`](../WritePro/user-legacy/standard-actions.md#action-anchorhorizontalalign) - [`anchorVerticalAlign`](../WritePro/user-legacy/standard-actions.md#action-anchorverticalalign) - [`anchorOrigin`](../WritePro/user-legacy/standard-actions.md#action-anchororigin) - [`anchorSection`](../WritePro/user-legacy/standard-actions.md#action-anchorsection) - [`anchorPage`](../WritePro/user-legacy/standard-actions.md#action-anchorpage) - [`image/displayMode`](../WritePro/user-legacy/standard-actions.md#action-image-displaymode) - [`backgroundDisplayMode`](../WritePro/user-legacy/standard-actions.md#action-backgrounddisplaymode) - [`doc/backgroundDisplayMode`](../WritePro/user-legacy/standard-actions.md#action-backgrounddisplaymode) - [`paragraph/backgroundDisplayMode`](../WritePro/user-legacy/standard-actions.md#action-backgrounddisplaymode) - [`image/backgroundDisplayMode`](../WritePro/user-legacy/standard-actions.md#action-backgrounddisplaymode) - [`section/backgroundDisplayMode`](../WritePro/user-legacy/standard-actions.md#action-backgrounddisplaymode) - [`header/backgroundDisplayMode`](../WritePro/user-legacy/standard-actions.md#action-backgrounddisplaymode) - [`footer/backgroundDisplayMode`](../WritePro/user-legacy/standard-actions.md#action-backgrounddisplaymode) - [`table/backgroundDisplayMode`](../WritePro/user-legacy/standard-actions.md#action-backgrounddisplaymode) - [`row/backgroundDisplayMode`](../WritePro/user-legacy/standard-actions.md#action-backgrounddisplaymode) - [`cell/backgroundDisplayMode`](../WritePro/user-legacy/standard-actions.md#action-backgrounddisplaymode) - [`column/backgroundDisplayMode`](../WritePro/user-legacy/standard-actions.md#action-backgrounddisplaymode) - [`formulaHighlight`](../WritePro/user-legacy/standard-actions.md#action-formulahighlight) - [`formulaHighlightColor`](../WritePro/user-legacy/standard-actions.md#action-formulahighlightcolor) - [`headerRowCount`](../WritePro/user-legacy/standard-actions.md#action-headerrowcount) :::note -For automatic text-formatting lists, see [Using a standard action](#using-a-standard-action) for target-area and focus requirements, and the restriction on hierarchical drop-down lists. The text-formatting target-area and focus requirements do not apply to `gotoPage`. +リストの自動テキスト書式設定に関しては、階層ドロップダウンリストの使用可能エリア、フォーカス要件、および制約については[標準アクションの使用](#標準アクションの使用) を参照してください。テキスト書式設定ターゲットエリアとフォーカス要件は、`gotoPage` に関しては適用されません。 -Actions assigned to individual choice-list items are separate from the action assigned to the drop-down list. +個別の選択リスト項目に割り当てられたアクションは、ドロップダウンリストに割り当てられたアクションとは異なります。 ::: -See the [standard action compatibility table](../Desktop-legacy/standard-actions.md#supported-form-objects). +詳細については[標準アクション互換性表](../Desktop-legacy/standard-actions.md#サポートされるフォームオブジェクト) を参照してください。 ## プロパティ一覧 From 3bc7aa50bae370665cf2ce7dd4472bb4671d84df Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Wed, 4 Nov 2026 23:20:37 +0100 Subject: [PATCH 012/195] list_overview.md Japanese --- .../current/FormObjects/list_overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/list_overview.md b/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/list_overview.md index fd94cf34329db2..34b81a7fb41886 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/list_overview.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/list_overview.md @@ -145,7 +145,7 @@ SET LIST ITEM FONT(*;"mylist1";*;thefont) ## プロパティ一覧 -[タイプ](properties_Object.md#タイプ) - [オブジェクト名](properties_Object.md#オブジェクト名) - [変数あるいは式](properties_Object.md#変数あるいは式) - [CSSクラス](properties_Object.md#cssクラス) - [左](properties_CoordinatesAndSizing.md#左) - [上](properties_CoordinatesAndSizing.md#上) - [右](properties_CoordinatesAndSizing.md#右) - [下](properties_CoordinatesAndSizing.md#下) - [幅](properties_CoordinatesAndSizing.md#幅) - [高さ](properties_CoordinatesAndSizing.md#高さ) - [横方向サイズ変更](properties_ResizingOptions.md#横方向サイズ変更) - [縦方向サイズ変更](properties_ResizingOptions.md#縦方向サイズ変更) - [入力可](properties_Entry.md#入力可) - [フォーカス可](properties_Entry.md#フォーカス可) - [選択リスト](properties_DataSource.md#選択リスト) - [フォーカス可](properties_Entry.md#フォーカス可) - [表示状態](properties_Display.md#表示状態) - [フォーカスの四角を隠す](properties_Appearance.md#フォーカスの四角を隠す) - [横スクロールバー](properties_Appearance.md#横スクロールバー) - [縦スクロールバー](properties_Appearance.md#縦スクロールバー) - [塗りカラー](properties_BackgroundAndBorder.md#背景色-塗りカラー) - [境界線カラー](./properties_BackgroundAndBorder.md#境界線カラー) - [境界線スタイル](properties_BackgroundAndBorder.md#border-line-style) - [フォント](properties_Text.md#フォント) - [フォントサイズ](properties_Text.md#フォントサイズ) - [太字](properties_Text.md#太字) - [イタリック](properties_Text.md#イタリック) - [下線](properties_Text.md#下線) - [フォントカラー](properties_Text.md#フォントカラー) - [ドラッグ有効](properties_Action.md#ドラッグ有効) - [ドロップ有効](properties_Action.md#ドロップ有効) - [複数選択可](properties_Action.md#複数選択可) - [ヘルプTips](properties_Help.md#ヘルプtips) +[タイプ](properties_Object.md#タイプ) - [オブジェクト名](properties_Object.md#オブジェクト名) - [変数あるいは式](properties_Object.md#変数あるいは式) - [CSSクラス](properties_Object.md#cssクラス) - [左](properties_CoordinatesAndSizing.md#左) - [上](properties_CoordinatesAndSizing.md#上) - [右](properties_CoordinatesAndSizing.md#右) - [下](properties_CoordinatesAndSizing.md#下) - [幅](properties_CoordinatesAndSizing.md#幅) - [高さ](properties_CoordinatesAndSizing.md#高さ) - [横方向サイズ変更](properties_ResizingOptions.md#横方向サイズ変更) - [縦方向サイズ変更](properties_ResizingOptions.md#縦方向サイズ変更) - [入力可](properties_Entry.md#入力可) - [フォーカス可](properties_Entry.md#フォーカス可) - [選択リスト](properties_DataSource.md#選択リスト) - [フォーカス可](properties_Entry.md#フォーカス可) - [表示状態](properties_Display.md#表示状態) - [フォーカスの四角を隠す](properties_Appearance.md#フォーカスの四角を隠す) - [横スクロールバー](properties_Appearance.md#横スクロールバー) - [縦スクロールバー](properties_Appearance.md#縦スクロールバー) - [塗りカラー](properties_BackgroundAndBorder.md#背景色-塗りカラー) - [境界線カラー](./properties_BackgroundAndBorder.md#border-color) - [境界線スタイル](properties_BackgroundAndBorder.md#border-line-style) - [フォント](properties_Text.md#フォント) - [フォントサイズ](properties_Text.md#フォントサイズ) - [太字](properties_Text.md#太字) - [イタリック](properties_Text.md#イタリック) - [下線](properties_Text.md#下線) - [フォントカラー](properties_Text.md#フォントカラー) - [ドラッグ有効](properties_Action.md#ドラッグ有効) - [ドロップ有効](properties_Action.md#ドロップ有効) - [複数選択可](properties_Action.md#複数選択可) - [ヘルプTips](properties_Help.md#ヘルプtips) ## サポートされるイベント From 75d0572387419b334bfda357656148eca7a35f74 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Wed, 4 Nov 2026 23:20:44 +0100 Subject: [PATCH 013/195] listbox-object.md Japanese --- .../current/FormObjects/listbox-object.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/listbox-object.md b/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/listbox-object.md index 2c463b8f4c585d..76955e48d4ce6d 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/listbox-object.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/listbox-object.md @@ -53,13 +53,13 @@ LIST TO ARRAY("ListName";varCol) myCol:=myCol.push("new value") // リストボックスに new value を表示 ``` -## Supported standard actions +## サポートされる標準アクション -- [gotoPage](../Desktop-legacy/standard-actions.md#gotopage): Available for array list boxes; see the [supported properties by list box type](#supported-properties). +- [gotoPage](../Desktop-legacy/standard-actions.md#gotopage): 配列型リストボックスに対して利用可能です。詳細は[リストボックス型ごとにサポートされるプロパティ](#プロパティ一覧) を参照してください。 -The [addSubrecord](../Desktop-legacy/standard-actions.md#addsubrecord), [deleteSubrecord](../Desktop-legacy/standard-actions.md#deletesubrecord), [displaySubrecord](../Desktop-legacy/standard-actions.md#displaysubrecord), and [editSubrecord](../Desktop-legacy/standard-actions.md#editsubrecord) actions can affect selection list boxes, but are assigned to buttons or menu commands, not to the selection list box itself. +[addSubrecord](../Desktop-legacy/standard-actions.md#addsubrecord)、 [deleteSubrecord](../Desktop-legacy/standard-actions.md#deletesubrecord)、 [displaySubrecord](../Desktop-legacy/standard-actions.md#displaysubrecord)、および [editSubrecord](../Desktop-legacy/standard-actions.md#editsubrecord) アクションはセレクション型リストボックスに影響をおよぼす可能性がありますが、これらはボタンまたはメニューコマンドに対して割り当てられるもので、セレクション型リストボックス自体に割り当てられるものではありません。 -See the [standard action compatibility table](../Desktop-legacy/standard-actions.md#supported-form-objects). +詳細については[標準アクション互換性表](../Desktop-legacy/standard-actions.md#サポートされるフォームオブジェクト) を参照してください。 ## プロパティ一覧 From 11e479afd24341ad1f3404d4b55b764fbdc0e22b Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Wed, 4 Nov 2026 23:20:49 +0100 Subject: [PATCH 014/195] picturebutton_overview.md Japanese --- .../current/FormObjects/pictureButton_overview.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/pictureButton_overview.md b/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/pictureButton_overview.md index 33926b9b43accd..576b34ab592035 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/pictureButton_overview.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/pictureButton_overview.md @@ -58,15 +58,15 @@ title: ピクチャーボタン > ピクチャーボタンに [関連付けた変数](properties_Object.md#変数あるいは式) は、ピクチャーのサムネールテーブルで現在表示されているピクチャーのインデックス番号を返します。このテーブル内のピクチャー番号は 0 から始まります。 -## Supported standard actions +## サポートされる標準アクション -Picture buttons support the same [standard actions as buttons](button_overview.md#supported-standard-actions), except for actions restricted to a specific button style, such as [automaticSplitter](../Desktop-legacy/standard-actions.md#automaticsplitter) for invisible buttons. Assign an action using the [Standard action property](properties_Action.md#standard-action). +ピクチャーボタンは[ボタンと同じ標準アクション](button_overview.md#サポートされる標準アクション) と同じアクションをサポートしますが、非表示ボタンにおける[automaticSplitter](../Desktop-legacy/standard-actions.md#automaticsplitter) など、特定のボタンスタイルでのみ使用可能なアクションを除きます。[標準アクションプロパティ](properties_Action.md#標準アクション) を使用して標準アクションを割り当てます。 -For action descriptions and activation conditions, see [Standard actions](../Desktop-legacy/standard-actions.md#available-actions). See also the [standard action compatibility table](../Desktop-legacy/standard-actions.md#supported-form-objects). +アクションの詳細と有効化条件については、[標準アクション](../Desktop-legacy/standard-actions.md#利用可能なアクション) を参照してください。[標準アクション互換性表](../Desktop-legacy/standard-actions.md#supported-form-objects) も参照してください。 ## プロパティ一覧 -[タイプ](properties_Object.md#タイプ) - [オブジェクト名](properties_Object.md#オブジェクト名) - [変数あるいは式](properties_Object.md#変数あるいは式) - [タイトル](properties_Object.md#タイトル) - [CSSクラス](properties_Object.md#cssクラス) - [ボタンスタイル](properties_TextAndPicture.md#ボタンスタイル) - [パス名](properties_Picture.md#パス名) - [マウス押下中は自動更新](properties_Animation.md#マウス押下中は自動更新) - [先頭フレームに戻る](properties_Animation.md#先頭フレームに戻る) - [ロールオーバー効果](properties_Animation.md#ロールオーバー効果) - [無効時に最終フレームを使用](properties_Animation.md#無効時に最終フレームを使用) - [アニメーション間隔 (tick)](properties_Animation.md#アニメーション間隔-tick) - [行](properties_Crop.md#行) - [列](properties_Crop.md#列) - [左](properties_CoordinatesAndSizing.md#左) - [上](properties_CoordinatesAndSizing.md#上) - [右](properties_CoordinatesAndSizing.md#右) - [下](properties_CoordinatesAndSizing.md#下) - [幅](properties_CoordinatesAndSizing.md#幅) - [高さ](properties_CoordinatesAndSizing.md#高さ) - [横方向サイズ変更](properties_ResizingOptions.md#横方向サイズ変更) - [縦方向サイズ変更](properties_ResizingOptions.md#縦方向サイズ変更) - [ショートカット](properties_Entry.md#ショートカット) - [フォーカス可](properties_Entry.md#フォーカス可) - [表示状態](properties_Display.md#表示状態) - [境界線カラー](./properties_BackgroundAndBorder.md#境界線カラー) - [境界線スタイル](properties_BackgroundAndBorder.md#border-line-style) - [イタリック](properties_Text.md#イタリック) - [ヘルプTips](properties_Help.md#ヘルプtips) - [標準アクション](properties_Action.md#標準アクション) +[タイプ](properties_Object.md#タイプ) - [オブジェクト名](properties_Object.md#オブジェクト名) - [変数あるいは式](properties_Object.md#変数あるいは式) - [タイトル](properties_Object.md#タイトル) - [CSSクラス](properties_Object.md#cssクラス) - [ボタンスタイル](properties_TextAndPicture.md#ボタンスタイル) - [パス名](properties_Picture.md#パス名) - [マウス押下中は自動更新](properties_Animation.md#マウス押下中は自動更新) - [先頭フレームに戻る](properties_Animation.md#先頭フレームに戻る) - [ロールオーバー効果](properties_Animation.md#ロールオーバー効果) - [無効時に最終フレームを使用](properties_Animation.md#無効時に最終フレームを使用) - [アニメーション間隔 (tick)](properties_Animation.md#アニメーション間隔-tick) - [行](properties_Crop.md#行) - [列](properties_Crop.md#列) - [左](properties_CoordinatesAndSizing.md#左) - [上](properties_CoordinatesAndSizing.md#上) - [右](properties_CoordinatesAndSizing.md#右) - [下](properties_CoordinatesAndSizing.md#下) - [幅](properties_CoordinatesAndSizing.md#幅) - [高さ](properties_CoordinatesAndSizing.md#高さ) - [横方向サイズ変更](properties_ResizingOptions.md#横方向サイズ変更) - [縦方向サイズ変更](properties_ResizingOptions.md#縦方向サイズ変更) - [ショートカット](properties_Entry.md#ショートカット) - [フォーカス可](properties_Entry.md#フォーカス可) - [表示状態](properties_Display.md#表示状態) - [境界線カラー](./properties_BackgroundAndBorder.md#border-color) - [境界線スタイル](properties_BackgroundAndBorder.md#border-line-style) - [イタリック](properties_Text.md#イタリック) - [ヘルプTips](properties_Help.md#ヘルプtips) - [標準アクション](properties_Action.md#標準アクション) ## サポートされるイベント From 918645c6903b8c24a2cb615eb4ffbf8f44cd38df Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Wed, 4 Nov 2026 23:20:52 +0100 Subject: [PATCH 015/195] picturepopupmenu_overview.md Japanese --- .../current/FormObjects/picturePopupMenu_overview.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/picturePopupMenu_overview.md b/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/picturePopupMenu_overview.md index 6fb07ff3be640f..22a1f0df90bb26 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/picturePopupMenu_overview.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/picturePopupMenu_overview.md @@ -21,13 +21,13 @@ title: ピクチャーポップアップメニュー たとえば、ユーザーが3番目の要素をクリックすると、4D はカレントフォームの 3ページ目 (存在する場合) を表示します。クリックをプログラムから管理したい場合は "動作なし" を選択します。 -## Supported standard actions +## サポートされる標準アクション -The following standard actions are available for picture pop-up menus. See [Standard actions](../Desktop-legacy/standard-actions.md) for descriptions and activation conditions. +ピクチャーポップアップメニューにおいては以下の標準アクションが利用可能です。アクションの詳細と有効化条件については[標準アクション](../Desktop-legacy/standard-actions.md) を参照してください。 -[`cancel`](../Desktop-legacy/standard-actions.md#cancel) - [`accept`](../Desktop-legacy/standard-actions.md#accept) - [`nextRecord`](../Desktop-legacy/standard-actions.md#nextrecord) - [`previousRecord`](../Desktop-legacy/standard-actions.md#previousrecord) - [`firstRecord`](../Desktop-legacy/standard-actions.md#firstrecord) - [`lastRecord`](../Desktop-legacy/standard-actions.md#lastrecord) - [`deleteRecord`](../Desktop-legacy/standard-actions.md#deleterecord) - [`nextPage`](../Desktop-legacy/standard-actions.md#nextpage) - [`previousPage`](../Desktop-legacy/standard-actions.md#previouspage) - [`firstPage`](../Desktop-legacy/standard-actions.md#firstpage) - [`lastPage`](../Desktop-legacy/standard-actions.md#lastpage) - [`editSubrecord`](../Desktop-legacy/standard-actions.md#editsubrecord) - [`displaySubrecord`](../Desktop-legacy/standard-actions.md#displaysubrecord) - [`deleteSubrecord`](../Desktop-legacy/standard-actions.md#deletesubrecord) - `addSublist` - [`addSubrecord`](../Desktop-legacy/standard-actions.md#addsubrecord) - [`undo`](../Desktop-legacy/standard-actions.md#undo) - [`redo`](../Desktop-legacy/standard-actions.md#redo) - [`cut`](../Desktop-legacy/standard-actions.md#cut) - [`copy`](../Desktop-legacy/standard-actions.md#copy) - [`paste`](../Desktop-legacy/standard-actions.md#paste) - [`clear`](../Desktop-legacy/standard-actions.md#clear) - [`selectAll`](../Desktop-legacy/standard-actions.md#selectall) - [`showClipboard`](../Desktop-legacy/standard-actions.md#showclipboard) - [`design`](../Desktop-legacy/standard-actions.md#designmode) - [`databaseSettings`](../Desktop-legacy/standard-actions.md#databasesettings) - `userMode` - [`quit`](../Desktop-legacy/standard-actions.md#quit) - `duplicate` - [`msc`](../Desktop-legacy/standard-actions.md#msc) - [`openBackURL`](../Desktop-legacy/standard-actions.md#openbackurl) - [`openForwardURL`](../Desktop-legacy/standard-actions.md#openforwardurl) - [`refreshCurrentURL`](../Desktop-legacy/standard-actions.md#refreshcurrenturl) - [`stopLoadingURL`](../Desktop-legacy/standard-actions.md#stoploadingurl) - [`font/showDialog`](../Desktop-legacy/standard-actions.md#fontshowdialog) - [`spell/grammarEnabled`](../Desktop-legacy/standard-actions.md#spellgrammarenabled) - [`spell/autoDashSubstitutionsEnabled`](../Desktop-legacy/standard-actions.md#spellautodashsubstitutionsenabled) - [`spell/autoQuoteSubstitutionsEnabled`](../Desktop-legacy/standard-actions.md#spellautoquotesubstitutionsenabled) - [`spell/autoLanguageEnabled`](../Desktop-legacy/standard-actions.md#spellautolanguageenabled) - [`computeExpressions`](../Desktop-legacy/standard-actions.md#computeexpressions) - [`freezeExpressions`](../Desktop-legacy/standard-actions.md#freezeexpressions) - [`writingTools`](../Desktop-legacy/standard-actions.md#writingtools) - [`spell/removeSubstitutions`](../Desktop-legacy/standard-actions.md#spellremovesubstitution) - [`spell/learn`](../Desktop-legacy/standard-actions.md#spelllearn) - [`spell/unLearn`](../Desktop-legacy/standard-actions.md#spellunlearn) - [`spell/ignore`](../Desktop-legacy/standard-actions.md#spellignore) - [`spell/forgetIgnore`](../Desktop-legacy/standard-actions.md#spellforgetignore) - [`spell/showDialog`](../Desktop-legacy/standard-actions.md#spellshowdialog) - [`insertSoftHyphen`](../WritePro/user-legacy/standard-actions.md#action-insertsofthyphen) - [`removeSoftHyphens`](../WritePro/user-legacy/standard-actions.md#action-removesofthyphens) - [`insertImage`](../WritePro/user-legacy/standard-actions.md#action-insertimage) - [`insertPageBreak`](../WritePro/user-legacy/standard-actions.md#action-insertpagebreak) - [`insertSectionBreak`](../WritePro/user-legacy/standard-actions.md#action-insertsectionbreak) - [`insertContinuousSectionBreak`](../WritePro/user-legacy/standard-actions.md#action-insertcontinuoussectionbreak) - [`insertColumnBreak`](../WritePro/user-legacy/standard-actions.md#action-insertcolumnbreak) - [`insertTextBox`](../WritePro/user-legacy/standard-actions.md#action-inserttextbox) - [`textBox/remove`](../WritePro/user-legacy/standard-actions.md#action-textbox-remove) - [`listLevelInc`](../WritePro/user-legacy/standard-actions.md#action-listlevelinc) - [`listLevelDec`](../WritePro/user-legacy/standard-actions.md#action-listleveldec) - [`listLevelAppend`](../WritePro/user-legacy/standard-actions.md#action-listlevelappend) - [`insertRowAbove`](../WritePro/user-legacy/standard-actions.md#action-insertrowabove) - [`insertRowBelow`](../WritePro/user-legacy/standard-actions.md#action-insertrowbelow) - [`insertColumnToTheLeft`](../WritePro/user-legacy/standard-actions.md#action-insertcolumntotheleft) - [`insertColumnToTheRight`](../WritePro/user-legacy/standard-actions.md#action-insertcolumntotheright) - [`deleteRows`](../WritePro/user-legacy/standard-actions.md#action-deleterows) - [`deleteColumns`](../WritePro/user-legacy/standard-actions.md#action-deletecolumns) - [`cell/merge`](../WritePro/user-legacy/standard-actions.md#action-merge) - [`cell/split`](../WritePro/user-legacy/standard-actions.md#action-split) - [`refreshImages`](../WritePro/user-legacy/standard-actions.md#action-refreshimages) - [`print`](../WritePro/user-legacy/standard-actions.md#action-print) - [`merge`](../WritePro/user-legacy/standard-actions.md#action-merge) - [`split`](../WritePro/user-legacy/standard-actions.md#action-split) - [`borderCollapse`](../WritePro/user-legacy/standard-actions.md#action-bordercollapse) - [`section/name/showDialog`](../WritePro/user-legacy/standard-actions.md#action-section-nameshowdialog) - [`header/remove`](../WritePro/user-legacy/standard-actions.md#action-header-remove) - [`footer/remove`](../WritePro/user-legacy/standard-actions.md#action-footer-remove) - [`backgroundColor/showDialog`](../Desktop-legacy/standard-actions.md#backgroundcolorshowdialog) - [`section/remove`](../WritePro/user-legacy/standard-actions.md#action-section-remove) - [`moveToFront`](../WritePro/user-legacy/standard-actions.md#action-movetofront) - [`moveToBack`](../WritePro/user-legacy/standard-actions.md#action-movetoback) - [`gotoPage`](../Desktop-legacy/standard-actions.md#gotopage). +[`cancel`](../Desktop-legacy/standard-actions.md#cancel) - [`accept`](../Desktop-legacy/standard-actions.md#accept) - [`nextRecord`](../Desktop-legacy/standard-actions.md#nextrecord) - [`previousRecord`](../Desktop-legacy/standard-actions.md#previousrecord) - [`firstRecord`](../Desktop-legacy/standard-actions.md#firstrecord) - [`lastRecord`](../Desktop-legacy/standard-actions.md#lastrecord) - [`deleteRecord`](../Desktop-legacy/standard-actions.md#deleterecord) - [`nextPage`](../Desktop-legacy/standard-actions.md#nextpage) - [`previousPage`](../Desktop-legacy/standard-actions.md#previouspage) - [`firstPage`](../Desktop-legacy/standard-actions.md#firstpage) - [`lastPage`](../Desktop-legacy/standard-actions.md#lastpage) - [`editSubrecord`](../Desktop-legacy/standard-actions.md#editsubrecord) - [`displaySubrecord`](../Desktop-legacy/standard-actions.md#displaysubrecord) - [`deleteSubrecord`](../Desktop-legacy/standard-actions.md#deletesubrecord) - `addSublist` - [`addSubrecord`](../Desktop-legacy/standard-actions.md#addsubrecord) - [`undo`](../Desktop-legacy/standard-actions.md#undo) - [`redo`](../Desktop-legacy/standard-actions.md#redo) - [`cut`](../Desktop-legacy/standard-actions.md#cut) - [`copy`](../Desktop-legacy/standard-actions.md#copy) - [`paste`](../Desktop-legacy/standard-actions.md#paste) - [`clear`](../Desktop-legacy/standard-actions.md#clear) - [`selectAll`](../Desktop-legacy/standard-actions.md#selectall) - [`showClipboard`](../Desktop-legacy/standard-actions.md#showclipboard) - [`design`](../Desktop-legacy/standard-actions.md#designmode) - [`databaseSettings`](../Desktop-legacy/standard-actions.md#databasesettings) - `userMode` - [`quit`](../Desktop-legacy/standard-actions.md#quit) - `duplicate` - [`msc`](../Desktop-legacy/standard-actions.md#msc) - [`openBackURL`](../Desktop-legacy/standard-actions.md#openbackurl) - [`openForwardURL`](../Desktop-legacy/standard-actions.md#openforwardurl) - [`refreshCurrentURL`](../Desktop-legacy/standard-actions.md#refreshcurrenturl) - [`stopLoadingURL`](../Desktop-legacy/standard-actions.md#stoploadingurl) - [`font/showDialog`](../Desktop-legacy/standard-actions.md#fontshowdialog) - [`spell/grammarEnabled`](../Desktop-legacy/standard-actions.md#spellgrammarenabled) - [`spell/autoDashSubstitutionsEnabled`](../Desktop-legacy/standard-actions.md#spellautodashsubstitutionsenabled) - [`spell/autoQuoteSubstitutionsEnabled`](../Desktop-legacy/standard-actions.md#spellautoquotesubstitutionsenabled) - [`spell/autoLanguageEnabled`](../Desktop-legacy/standard-actions.md#spellautolanguageenabled) - [`computeExpressions`](../Desktop-legacy/standard-actions.md#computeexpressions) - [`freezeExpressions`](../Desktop-legacy/standard-actions.md#freezeexpressions) - [`writingTools`](../Desktop-legacy/standard-actions.md#writingtools) - [`spell/removeSubstitutions`](../Desktop-legacy/standard-actions.md#spellremovesubstitution) - [`spell/learn`](../Desktop-legacy/standard-actions.md#spelllearn) - [`spell/unLearn`](../Desktop-legacy/standard-actions.md#spellunlearn) - [`spell/ignore`](../Desktop-legacy/standard-actions.md#spellignore) - [`spell/forgetIgnore`](../Desktop-legacy/standard-actions.md#spellforgetignore) - [`spell/showDialog`](../Desktop-legacy/standard-actions.md#spellshowdialog) - [`insertSoftHyphen`](../WritePro/user-legacy/standard-actions.md#action-insertsofthyphen) - [`removeSoftHyphens`](../WritePro/user-legacy/standard-actions.md#action-removesofthyphens) - [`insertImage`](../WritePro/user-legacy/standard-actions.md#action-insertimage) - [`insertPageBreak`](../WritePro/user-legacy/standard-actions.md#action-insertpagebreak) - [`insertSectionBreak`](../WritePro/user-legacy/standard-actions.md#action-insertsectionbreak) - [`insertContinuousSectionBreak`](../WritePro/user-legacy/standard-actions.md#action-insertcontinuoussectionbreak) - [`insertColumnBreak`](../WritePro/user-legacy/standard-actions.md#action-insertcolumnbreak) - [`insertTextBox`](../WritePro/user-legacy/standard-actions.md#action-inserttextbox) - [`textBox/remove`](../WritePro/user-legacy/standard-actions.md#action-textbox-remove) - [`listLevelInc`](../WritePro/user-legacy/standard-actions.md#action-listlevelinc) - [`listLevelDec`](../WritePro/user-legacy/standard-actions.md#action-listleveldec) - [`listLevelAppend`](../WritePro/user-legacy/standard-actions.md#action-listlevelappend) - [`insertRowAbove`](../WritePro/user-legacy/standard-actions.md#action-insertrowabove) - [`insertRowBelow`](../WritePro/user-legacy/standard-actions.md#action-insertrowbelow) - [`insertColumnToTheLeft`](../WritePro/user-legacy/standard-actions.md#action-insertcolumntotheleft) - [`insertColumnToTheRight`](../WritePro/user-legacy/standard-actions.md#action-insertcolumntotheright) - [`deleteRows`](../WritePro/user-legacy/standard-actions.md#action-deleterows) - [`deleteColumns`](../WritePro/user-legacy/standard-actions.md#action-deletecolumns) - [`cell/merge`](../WritePro/user-legacy/standard-actions.md#action-merge) - [`cell/split`](../WritePro/user-legacy/standard-actions.md#action-split) - [`refreshImages`](../WritePro/user-legacy/standard-actions.md#action-refreshimages) - [`print`](../WritePro/user-legacy/standard-actions.md#action-print) - [`merge`](../WritePro/user-legacy/standard-actions.md#action-merge) - [`split`](../WritePro/user-legacy/standard-actions.md#action-split) - [`borderCollapse`](../WritePro/user-legacy/standard-actions.md#action-bordercollapse) - [`section/name/showDialog`](../WritePro/user-legacy/standard-actions.md#action-section-nameshowdialog) - [`header/remove`](../WritePro/user-legacy/standard-actions.md#action-header-remove) - [`footer/remove`](../WritePro/user-legacy/standard-actions.md#action-footer-remove) - [`backgroundColor/showDialog`](../Desktop-legacy/standard-actions.md#backgroundcolorshowdialog) - [`section/remove`](../WritePro/user-legacy/standard-actions.md#action-section-remove) - [`moveToFront`](../WritePro/user-legacy/standard-actions.md#action-movetofront) - [`moveToBack`](../WritePro/user-legacy/standard-actions.md#action-movetoback) - [`gotoPage`](../Desktop-legacy/standard-actions.md#gotopage) -See the [standard action compatibility table](../Desktop-legacy/standard-actions.md#supported-form-objects). +詳細については[標準アクション互換性表](../Desktop-legacy/standard-actions.md#サポートされるフォームオブジェクト) を参照してください。 ## プロパティ一覧 @@ -47,7 +47,7 @@ See the [standard action compatibility table](../Desktop-legacy/standard-actions [横方向サイズ変更](properties_ResizingOptions.md#横方向サイズ変更) - [縦方向サイズ変更](properties_ResizingOptions.md#縦方向サイズ変更) - [表示状態](properties_Display.md#表示状態) - -[境界線カラー](./properties_BackgroundAndBorder.md#境界線カラー) - +[境界線カラー](./properties_BackgroundAndBorder.md#border-color) - [境界線スタイル](properties_BackgroundAndBorder.md#境界線スタイル) - [太字](properties_Text.md#太字) - [ヘルプTips](properties_Help.md#ヘルプtips) - From 5a051a532201f6d2a7b14d70de04a8770ec9ded3 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Wed, 4 Nov 2026 23:20:54 +0100 Subject: [PATCH 016/195] pluginarea_overview.md Japanese --- .../current/FormObjects/pluginArea_overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/pluginArea_overview.md b/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/pluginArea_overview.md index 9637bfb4d8e6ce..2e7f7f6b0566a3 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/pluginArea_overview.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/pluginArea_overview.md @@ -19,7 +19,7 @@ title: プラグインエリア ## プロパティ一覧 -[タイプ](properties_Object.md#タイプ) - [プラグインの種類](properties_Object.md#プラグインの種類) - [オブジェクト名](properties_Object.md#オブジェクト名) - [変数あるいは式](properties_Object.md#変数あるいは式) - [式の型](properties_Object.md#式の型式タイプ) - [CSSクラス](properties_Object.md#cssクラス) - [左](properties_CoordinatesAndSizing.md#左) - [上](properties_CoordinatesAndSizing.md#上) - [右](properties_CoordinatesAndSizing.md#右) - [下](properties_CoordinatesAndSizing.md#下) - [幅](properties_CoordinatesAndSizing.md#幅) - [高さ](properties_CoordinatesAndSizing.md#高さ) - [横方向サイズ変更](properties_ResizingOptions.md#横方向サイズ変更) - [縦方向サイズ変更](properties_ResizingOptions.md#縦方向サイズ変更) - [フォーカス可](properties_Entry.md#フォーカス可) - [表示状態](properties_Display.md#表示状態) - [境界線カラー](./properties_BackgroundAndBorder.md#境界線カラー) - [境界線スタイル](properties_BackgroundAndBorder.md#border-line-style) - [詳細設定](properties_Plugins.md) - [ドラッグ有効](properties_Action.md#ドラッグ有効) - [ドロップ有効](properties_Action.md#ドロップ有効) - [メソッド](properties_Action.md#メソッド) +[タイプ](properties_Object.md#タイプ) - [プラグインの種類](properties_Object.md#プラグインの種類) - [オブジェクト名](properties_Object.md#オブジェクト名) - [変数あるいは式](properties_Object.md#変数あるいは式) - [式の型](properties_Object.md#式の型式タイプ) - [CSSクラス](properties_Object.md#cssクラス) - [左](properties_CoordinatesAndSizing.md#左) - [上](properties_CoordinatesAndSizing.md#上) - [右](properties_CoordinatesAndSizing.md#右) - [下](properties_CoordinatesAndSizing.md#下) - [幅](properties_CoordinatesAndSizing.md#幅) - [高さ](properties_CoordinatesAndSizing.md#高さ) - [横方向サイズ変更](properties_ResizingOptions.md#横方向サイズ変更) - [縦方向サイズ変更](properties_ResizingOptions.md#縦方向サイズ変更) - [フォーカス可](properties_Entry.md#フォーカス可) - [表示状態](properties_Display.md#表示状態) - [境界線カラー](./properties_BackgroundAndBorder.md#border-color) - [境界線スタイル](properties_BackgroundAndBorder.md#border-line-style) - [詳細設定](properties_Plugins.md) - [ドラッグ有効](properties_Action.md#ドラッグ有効) - [ドロップ有効](properties_Action.md#ドロップ有効) - [メソッド](properties_Action.md#メソッド) ## サポートされるイベント From 29fa1aee21083af36d41f86322ade8895cb208ea Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Wed, 4 Nov 2026 23:20:57 +0100 Subject: [PATCH 017/195] progressindicator.md Japanese --- .../current/FormObjects/progressIndicator.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/progressIndicator.md b/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/progressIndicator.md index b00234de9ddf83..4bcdcd59a4503e 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/progressIndicator.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/progressIndicator.md @@ -62,7 +62,7 @@ title: 進捗インジケーター [入力可](properties_Entry.md#入力可) - [数値フォーマット](properties_Display.md#数値フォーマット) - [表示状態](properties_Display.md#表示状態) - -[境界線カラー](./properties_BackgroundAndBorder.md#境界線カラー) - +[境界線カラー](./properties_BackgroundAndBorder.md#border-color) - [境界線スタイル](properties_BackgroundAndBorder.md#border-line-style) - [フォント](properties_Text.md#フォント) - [フォントサイズ](properties_Text.md#フォントサイズ) - From 538ad664758d545800dc9a79a467bf858f588d60 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Wed, 4 Nov 2026 23:21:05 +0100 Subject: [PATCH 018/195] properties_backgroundandborder.md Japanese --- .../FormObjects/properties_BackgroundAndBorder.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/properties_BackgroundAndBorder.md b/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/properties_BackgroundAndBorder.md index 659c3eb0e1ce96..074e0f42fd35e1 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/properties_BackgroundAndBorder.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/properties_BackgroundAndBorder.md @@ -27,7 +27,7 @@ title: 背景色と境界線 ## 背景色/塗りカラー -オブジェクトの背景色/塗りカラーを設定します。 It can be defined for some standard objects (`fill` JSON property) or ["custom style" objects](#custom-button-custom-check-box-or-custom-radio-button) (`borderFillColor` JSON property). +オブジェクトの背景色/塗りカラーを設定します。一部の標準のオブジェクト(`fill` JSON プロパティを使用) あるいは["custom style" オブジェクト](#custom-button-custom-check-box-or-custom-radio-button)(`borderFillColor` JSON プロパティを使用) に対して定義することが可能です。 :::note @@ -105,11 +105,11 @@ title: 背景色と境界線 ## 境界線カラー{#border-color} -Allows defining the border color. The effect of this property varies slightly depending on the type of object to which it is applied. +境界線のカラーを定義することができます。このプロパティの効果は、適用されるオブジェクトのタイプによって若干異なります。 -- **objects with text properties**: [buttons](./button_overview.md) (all styles except "custom", see below), [hierarchical lists](list_overview.md), [inputs](input_overview.md), [list boxes](listbox_overview.md), [progress indicators](./progressIndicator.md), [rulers](./ruler.md), and [text areas](text.md). - By default, the border color of these objects is automatically set to their [**font color**](./properties_Text.md#font-color) property. This default configuration corresponds to the **Same as font** option in the Property List (`borderColor` property is undefined in JSON). - You can separate these two properties by setting a color value for the object's "Border color" property (only available when the [**border line style**](#border-line-style) property is **plain** (`solid` in JSON property) or **dotted**). +- **テキストプロパティを持つオブジェクト**: [ボタン](./button_overview.md) ("カスタム" を除く全てのスタイル、詳細は以下参照)、[階層リスト](list_overview.md)、[入力](input_overview.md)、[リストボックス](listbox_overview.md)、[進捗インジケーター](./progressIndicator.md)、[ルーラー](./ruler.md), and [text areas](text.md)。 + デフォルトで、これらのオブジェクトの境界線カラーは自動的に[**フォントカラー**](./properties_Text.md#フォントカラー) プロパティと同じに設定されています。このデフォルトの設定はプロパティリストの**Same as font** オプションに対応しています(`borderColor` プロパティはJSON では未定義です)。 + これらの二つのプロパティはオブジェクトの"境界線カラー" プロパティ([**境界線スタイル**](#border-line-style) プロパティが**実線** (JSON プロパティでは`solid`) あるいは **点線**のときのみ利用可能) にカラー値を設定することで分離させることができます。 - **objects without text properties**: [4D View Pro areas](viewProArea_overview.md), [4D Write Pro areas](writeProArea_overview.md), [button grids](buttonGrid_overview.md), [picture buttons](pictureButton_overview.md), [picture pop-up menus](picturePopupMenu_overview.md), [plug-in areas](pluginArea_overview.md), [subforms](subform_overview.md), [spinners](spinner.md), [splitters](splitters.md), [steppers](stepper.md), [web areas](webArea_overview.md). The border color property sets the color of the borders. The default color value is "Automatic", i.e. the border is displayed with the automatic color set by your OS. From 4be61b3ee4129803ecc150a6d02f678ea5e4ab94 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Wed, 4 Nov 2026 23:21:43 +0100 Subject: [PATCH 019/195] radio_overview.md Japanese --- .../current/FormObjects/radio_overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/radio_overview.md b/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/radio_overview.md index 42308774eca1c3..3141ea53ed0c0a 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/radio_overview.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/radio_overview.md @@ -154,7 +154,7 @@ Office XPボタンの反転表示と背景のカラーはシステムカラー [カスタム](#カスタム) スタイルのラジオボタンに対しては特有の追加のプロパティが利用可能です: -[背景パス名](properties_TextAndPicture.md#背景パス名) - [境界線カラー](./properties_BackgroundAndBorder.md#境界線カラー) - [境界線幅](./properties_BackgroundAndBorder.md#境界線幅) - [横方向マージン](properties_TextAndPicture.md#横方向マージン) - [アイコンオフセット](properties_TextAndPicture.md#アイコンオフセット) - [縦方向マージン](properties_TextAndPicture.md#縦方向マージン) - [角の半径](properties_CoordinatesAndSizing.md#角の半径) - [塗りカラー](./properties_BackgroundAndBorder.md#背景色塗りカラー) +[背景パス名](properties_TextAndPicture.md#背景パス名) - [境界線カラー](./properties_BackgroundAndBorder.md#border-color) - [境界線幅](./properties_BackgroundAndBorder.md#境界線幅) - [横方向マージン](properties_TextAndPicture.md#横方向マージン) - [アイコンオフセット](properties_TextAndPicture.md#アイコンオフセット) - [縦方向マージン](properties_TextAndPicture.md#縦方向マージン) - [角の半径](properties_CoordinatesAndSizing.md#角の半径) - [塗りカラー](./properties_BackgroundAndBorder.md#背景色塗りカラー) ## サポートされるイベント From 0659b450febfc5e8d43a18c119655f9b66d52415 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Wed, 4 Nov 2026 23:21:53 +0100 Subject: [PATCH 020/195] tabcontrol.md Japanese --- .../current/FormObjects/tabControl.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/tabControl.md b/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/tabControl.md index 3ea815ce123ad3..b3860876cef6cd 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/tabControl.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/tabControl.md @@ -114,11 +114,11 @@ FORM GOTO PAGE(arrPages) たとえば、ユーザーが 3番目のタブをクリックすると、4Dはカレントフォームの 3ページ目 (存在する場合) を表示します。 -## Supported standard actions +## サポートされる標準アクション - [gotoPage](../Desktop-legacy/standard-actions.md#gotopage): Uses the selected tab number as described in [Goto Page action](#goto-page-action). -See the [standard action compatibility table](../Desktop-legacy/standard-actions.md#supported-form-objects). +詳細については[標準アクション互換性表](../Desktop-legacy/standard-actions.md#サポートされるフォームオブジェクト) を参照してください。 ## プロパティ一覧 From 968ecf0def494773b2cb9e335386c8d0acb9467b Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Wed, 4 Nov 2026 23:22:36 +0100 Subject: [PATCH 021/195] privileges.md Japanese --- .../current/ORDA/privileges.md | 40 +++---------------- 1 file changed, 6 insertions(+), 34 deletions(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/ORDA/privileges.md b/i18n/ja/docusaurus-plugin-content-docs/current/ORDA/privileges.md index dc6b76048c5606..fa88580e5159f8 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/ORDA/privileges.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/ORDA/privileges.md @@ -39,40 +39,6 @@ The **execute** permission of a [shared singleton](../Concepts/classes.md#shared Permissions never apply to [desktop session code](../Desktop/sessions.md) (standalone, client/server, stored procedures) or [tool4d](../Admin/cli.md#tool4d). -:::warning - -When a permission entry references an undeclared [privilege](#privileges-and-roles), 4D logs an error and ignores the entry. In this case, the permission is ignored. If the [restricted mode by default](#restriction-modes) is not enabled, the resource is accessible to `guest` sessions. - -::: - -### MCP tools - -The same permissions apply to the sessions of the [MCP server](../WebServer/mcp-server.md), with nothing specific to configure: - -- A [custom tool](../WebServer/mcp-server.md#custom-tools) (`exposed MCP Function`) requires the **execute** permission on its function, and benefits from its **promote** permission. -- The [built-in CRUD tools](../WebServer/mcp-server.md#built-in-crud-tools) require the **read**, **create**, **update**, or **drop** permission on the dataclass, and the attribute permissions apply. Each attribute of a path used in a filter, a sort, or a projection requires the **read** permission. -- The CRUD tools are listed only if the session has at least one data permission on a dataclass, and the `describeModel` tool only describes the dataclasses on which the session has a data permission, with their readable or writable attributes. -- A tool, a dataclass, or an attribute that the session cannot access is reported as if it did not exist. - -#### 例題 - -MCP clients authenticated with the "salesReader" privilege can read the Customer and Order dataclasses with the CRUD tools, and call the tools published by the `OrderManager` singleton (for example `OrderManager-getYearTotal`): - -```json -{ - "privileges": [{"privilege": "salesReader", "includes": []}], - "roles": [], - "permissions": { - "allowed": [ - {"applyTo": "Customer", "type": "dataclass", "read": ["salesReader"]}, - {"applyTo": "Order", "type": "dataclass", "read": ["salesReader"]}, - {"applyTo": "OrderManager", "type": "singleton", "execute": ["salesReader"]} - ] - }, - "restrictedByDefault": true -} -``` - ### MCP tools The same permissions apply to the sessions of the [MCP server](../WebServer/mcp-server.md), with nothing specific to configure: @@ -294,6 +260,12 @@ The project's web security settings are defined in `roles.json`: ::: +:::warning + +When a permission entry references an undeclared [privilege](#privileges-and-roles), 4D logs an error and ignores the entry. In this case, the permission is ignored. If the [restricted mode by default](#restriction-modes) is not enabled, the resource is accessible to `guest` sessions. + +::: + ### Default location and content New projects generate `roles.json` at: From 9bcc138d06ad3e87e0242c410591a6903ba5f46a Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Wed, 4 Nov 2026 23:26:25 +0100 Subject: [PATCH 022/195] quotas.md Japanese --- .../current/WebServer/quotas.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/WebServer/quotas.md b/i18n/ja/docusaurus-plugin-content-docs/current/WebServer/quotas.md index 9f2f6270a841c4..c0fe1d6fca8c80 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/WebServer/quotas.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/WebServer/quotas.md @@ -12,12 +12,6 @@ Web サーバークォータを使用して、トラフィック、リクエス ::: -:::tip 関連したBlog 記事 - -[A 4D web server that knows when to say No](https://blog.4d.com/a-4d-web-server-that-knows-when-to-say-no/) - -::: - ## 要件 クォータの設定のためには、[スケーラブルセッション](./sessions.md#Webセッションの有効化) が有効化されている必要があります。 From afbb8c5c43377afbf2476ecabb803b7f8bd973a0 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 00:39:53 +0100 Subject: [PATCH 023/195] radio_overview.md Japanese --- .../version-21-R5/FormObjects/radio_overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/FormObjects/radio_overview.md b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/FormObjects/radio_overview.md index 42308774eca1c3..3141ea53ed0c0a 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/FormObjects/radio_overview.md +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/FormObjects/radio_overview.md @@ -154,7 +154,7 @@ Office XPボタンの反転表示と背景のカラーはシステムカラー [カスタム](#カスタム) スタイルのラジオボタンに対しては特有の追加のプロパティが利用可能です: -[背景パス名](properties_TextAndPicture.md#背景パス名) - [境界線カラー](./properties_BackgroundAndBorder.md#境界線カラー) - [境界線幅](./properties_BackgroundAndBorder.md#境界線幅) - [横方向マージン](properties_TextAndPicture.md#横方向マージン) - [アイコンオフセット](properties_TextAndPicture.md#アイコンオフセット) - [縦方向マージン](properties_TextAndPicture.md#縦方向マージン) - [角の半径](properties_CoordinatesAndSizing.md#角の半径) - [塗りカラー](./properties_BackgroundAndBorder.md#背景色塗りカラー) +[背景パス名](properties_TextAndPicture.md#背景パス名) - [境界線カラー](./properties_BackgroundAndBorder.md#border-color) - [境界線幅](./properties_BackgroundAndBorder.md#境界線幅) - [横方向マージン](properties_TextAndPicture.md#横方向マージン) - [アイコンオフセット](properties_TextAndPicture.md#アイコンオフセット) - [縦方向マージン](properties_TextAndPicture.md#縦方向マージン) - [角の半径](properties_CoordinatesAndSizing.md#角の半径) - [塗りカラー](./properties_BackgroundAndBorder.md#背景色塗りカラー) ## サポートされるイベント From fbef9f49a8230b090cdec796434e2ecbb8cf4084 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 00:40:44 +0100 Subject: [PATCH 024/195] privileges.md Japanese --- .../version-21-R5/ORDA/privileges.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/ORDA/privileges.md b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/ORDA/privileges.md index 152a9ae07d86a3..45c7da959b4da2 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/ORDA/privileges.md +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/ORDA/privileges.md @@ -67,6 +67,12 @@ Webユーザーまたは RESTユーザーがログインすると、そのセッ 権限の設定には一貫性が必要です。特に、**update** および **drop** 権限は**read** 権限も必要とします(ただし**create** はそれを必要としません)。 +:::warning + +When a permission entry references an undeclared [privilege](#privileges-and-roles), 4D logs an error and ignores the entry. In this case, the permission is ignored. If the [restricted mode by default](#restriction-modes) is not enabled, the resource is accessible to `guest` sessions. + +::: + ### 継承されたパーミッション あるレベルにおいて定義されたパーミッションは基本的に下位レベルに継承されますが、パーミッションは複数のレベルで設定することもできます: From a480e99c999d6b4823da049ce3f54c09f26bd12c Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:35:44 +0100 Subject: [PATCH 025/195] quotamanagerclass.md French --- .../current/API/QuotaManagerClass.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/API/QuotaManagerClass.md b/i18n/fr/docusaurus-plugin-content-docs/current/API/QuotaManagerClass.md index 08c5d2b928ec6c..63398ec7faf8ec 100644 --- a/i18n/fr/docusaurus-plugin-content-docs/current/API/QuotaManagerClass.md +++ b/i18n/fr/docusaurus-plugin-content-docs/current/API/QuotaManagerClass.md @@ -11,12 +11,6 @@ La classe `4D.QuotaManager` vous offre une interface permettant de configurer et ::: -:::tip Article de blog lié - -[Un serveur web 4D qui sait quand dire « non »](https://blog.4d.com/a-4d-web-server-that-knows-when-to-say-no/) - -::: - Les objets `4D.QuotaManager` peuvent être instanciés par: - la [propriété `quotas` d'un objet Session](./SessionClass.md#quotas) From c72ab20683c9d958306e2850197aa833ccbd4e3b Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:36:40 +0100 Subject: [PATCH 026/195] quotamanagerclass.md Spanish --- .../current/API/QuotaManagerClass.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/i18n/es/docusaurus-plugin-content-docs/current/API/QuotaManagerClass.md b/i18n/es/docusaurus-plugin-content-docs/current/API/QuotaManagerClass.md index 13a1bbe1bc77a3..5a1a2846fc5303 100644 --- a/i18n/es/docusaurus-plugin-content-docs/current/API/QuotaManagerClass.md +++ b/i18n/es/docusaurus-plugin-content-docs/current/API/QuotaManagerClass.md @@ -11,12 +11,6 @@ La clase `4D.QuotaManager` le ofrece una interfaz para configurar y monitorizar ::: -:::tip Entradas de blog relacionadas - -[Un servidor web 4D que sabe cuándo decir No](https://blog.4d.com/a-4d-web-server-that-knows-when-to-say-no/) - -::: - Los objetos `4D.QuotaManager` se pueden instanciar de las siguientes maneras: - la [propiedad `quotas` de un objeto Session](./SessionClass.md#quotas) From 0f22ab2c493c7331d919a288ffa418b04310798a Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:38:38 +0100 Subject: [PATCH 027/195] menu.png French --- .../current/assets/en/embedding-studio/menu.png | Bin 0 -> 4938 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 i18n/fr/docusaurus-plugin-content-docs/current/assets/en/embedding-studio/menu.png diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/assets/en/embedding-studio/menu.png b/i18n/fr/docusaurus-plugin-content-docs/current/assets/en/embedding-studio/menu.png new file mode 100644 index 0000000000000000000000000000000000000000..425fd0d7e65879e34700b856cf6f88aaa9c502e1 GIT binary patch literal 4938 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 E0Cv$VrvLx| literal 0 HcmV?d00001 From 6365f36712728ba87a4308ef286612766e21a431 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:38:39 +0100 Subject: [PATCH 028/195] studio-interface.png French --- .../en/embedding-studio/studio-interface.png | Bin 0 -> 34492 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 i18n/fr/docusaurus-plugin-content-docs/current/assets/en/embedding-studio/studio-interface.png diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/assets/en/embedding-studio/studio-interface.png b/i18n/fr/docusaurus-plugin-content-docs/current/assets/en/embedding-studio/studio-interface.png new file mode 100644 index 0000000000000000000000000000000000000000..75dae7c9303297334e2fee1b404527957dfd4746 GIT binary patch literal 34492 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 Z0#D?x@H3fRStk8kMM>jk;f?!G{uip+WAXq1 literal 0 HcmV?d00001 From eba5f071b5655fc5045a6c2860ddc995156b2f91 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:38:42 +0100 Subject: [PATCH 029/195] definition.md French --- .../embedding-studio/Classes/Definition.md | 165 ++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Definition.md diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Definition.md b/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Definition.md new file mode 100644 index 00000000000000..fd8c5c92276afd --- /dev/null +++ b/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Definition.md @@ -0,0 +1,165 @@ +--- +id: définition +title: Définition +--- + +# Définition + +The `Definition` class describes how a single vector field on a dataclass should be computed: which dataclass, which vector field, which model alias, and which text template ([Phrase](Phrase.md)) to render from each entity. + +A collection of these is what [Settings](Settings.md) persists. + +## Propriétés + +| Nom de propriété | Type | Description | +| ---------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------- | +| `dataclassName` | Text | Name of the target dataclass. | +| `vectorName` | Text | Name of the `4D.Vector` field on that dataclass. | +| `modelAlias` | Text | Embedding model alias (e.g. `"text-embedding-3-small"`). | +| `phrase` | [Phrase](Phrase.md) | Compiled template used to build the text that will be embedded. | +| `autoInvalidate` | Boolean | Controls automatic invalidation on entity save. Default: `True`. | + +## Class constructor + +Create a definition. + +| Nom de l'argument | Type | Description | +| ----------------- | ---- | -------------------------------------------------------------------------------------------------- | +| *dataclassName* | Text | Name of the target dataclass. | +| *vectorName* | Text | Name of the target vector field. | +| *modelAlias* | Text | Embedding model alias. | +| *phraseTemplate* | Text | Phrase template with `{field}` placeholders — compiled into a [Phrase](Phrase.md). | + +```4d +var $def:=cs.EmbeddingStudio.Definition.new(\ + "Students"; \ + "student_vector_1"; \ + "text-embedding-3-small"; \ + "Student {firstName} {lastName}") +``` + +## Propriétés calculées + +### hasDefinition + +**hasDefinition** : Boolean *(read-only)* + +Returns `True` if at least a model or a phrase template has been set. A definition without either has no content to process. + +```4d +If ($def.hasDefinition) + // worth validating further +End if +``` + +## Fonctions + +### validate() + +**validate**( *settings* : Settings ) : Object + +Validates the definition against the live datastore model and the known embedding models. All errors are collected before returning — the result always describes the full set of problems found. + +| Argument | Type | Description | +| ----------------------- | ------------------------------- | ------------------------------------------------------------------------------------------------------------ | +| *settings* | [Settings](Settings.md) \| Null | Used to pass phrase validation options. Pass `Null` to skip phrase options. | +| Résultat de la fonction | Object | `{success: Boolean, errors: Collection}` where each error is `{field: Text, message: Text}`. | + +Checked in order: + +| Check | `field` value | +| ------------------------------------ | ----------------- | +| `dataclassName` is not empty | `"dataclassName"` | +| `vectorName` is not empty | `"vectorName"` | +| `modelAlias` is set and recognised | `"modelAlias"` | +| Dataclass exists in `ds` | `"dataclassName"` | +| Vector field exists | `"vectorName"` | +| Field type is `4D.Vector` | `"vectorName"` | +| Phrase template is not empty | `"phrase"` | +| Phrase keys resolve in the dataclass | `"phrase"` | + +The first two checks (identity) return immediately on failure; the remaining checks accumulate so all problems are reported in one pass. + +```4d +var $result:=$def.validate(cs.EmbeddingStudio.Settings.new()) + +If (Not($result.success)) + var $err : Object + For each ($err; $result.errors) + TRACE // $err.field, $err.message + End for each +End if +``` + +### invalidateVectors() + +**invalidateVectors**() : Object + +Marks all already-computed entities for re-embedding, forcing a full rebuild on the next run. Only entities that already have a vector value are processed — entities with a `Null` vector are skipped. + +Useful during development or after a model/phrase change to trigger a clean rebuild of all vectors. + +The strategy depends on whether a companion `_dirty` field exists on the dataclass: + +| Companion `_dirty` field | Action taken | +| ------------------------ | -------------------------------------------------------------- | +| Present | Sets `_dirty` to `True` — vector is left untouched | +| Absent | Nullifies the vector field | + +| Argument | Type | Description | +| ----------------------- | ------ | ------------------------------------------------------------------ | +| Résultat de la fonction | Object | `{updated: Integer, skipped: Integer, errors: Collection of Text}` | + +- `updated` — number of entities successfully marked +- `skipped` — number of entities that could not be saved +- `errors` — one entry per save failure, formatted as `"DataclassName: statusText"` + +```4d +var $result:=$def.invalidateVectors() + +If ($result.skipped > 0) + var $e : Text + For each ($e; $result.errors) + // $e + End for each +End if +// → { updated: 42; skipped: 0; errors: [] } +``` + +### toObject() + +**toObject**() : Object + +Returns a plain object suitable for JSON persistence. The phrase is flattened to its template text. + +| Argument | Type | Description | +| ----------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------- | +| Résultat de la fonction | Object | `{version, dataclassName, vectorName, modelAlias, phrase, autoInvalidate}` where `phrase` is the template string. | + +```4d +$def.toObject() +// → { version: 0; dataclassName: "Students"; vectorName: "student_vector_1"; +// modelAlias: "text-embedding-3-small"; phrase: "Student {firstName} {lastName}"; +// autoInvalidate: true } +``` + +## Automatic invalidation + +`autoInvalidate` controls whether save-time automatic invalidation is enabled for this definition. + +- `True` (default): when relevant attributes change on an entity save, vectors are automatically invalidated. +- `False`: save-time automatic invalidation is skipped for this definition. + +This setting does not affect manual invalidation via `invalidateVectors()`. + +## Dirty flag convention + +The pipeline in [Process](Process.md) will recompute an entity whenever the target vector is `Null`, or when a sibling field `_dirty` exists on the dataclass and is `True`. + +Declaring the dirty flag is optional — when absent, only the null-vector case triggers recomputation. When present, it is cleared automatically on successful save. + +## Voir également + +- [Settings](Settings.md) +- [Process](Process.md) +- [Phrase](Phrase.md) From c0922b0ef34f7eb35ffd595bc7acec4312ee9c78 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:38:44 +0100 Subject: [PATCH 030/195] embedder.md French --- .../embedding-studio/Classes/Embedder.md | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Embedder.md diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Embedder.md b/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Embedder.md new file mode 100644 index 00000000000000..2d8e5d846103ad --- /dev/null +++ b/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Embedder.md @@ -0,0 +1,96 @@ +--- +id: embedder +title: Embedder +--- + +# Embedder + +The `Embedder` class is a thin wrapper around [4D AIKit](https://developer.4d.com/docs/aikit/Classes/openai) focused on embeddings. It exposes two functions — one for a single text, one for a batch — and handles retries with exponential backoff (respecting the `Retry-After` header when present). + +It is stateless beyond configuration and safe to share between processes. + +## Propriétés + +| Nom de propriété | Type | Description | +| ---------------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | +| `client` | cs.AIKit.OpenAI | The underlying AIKit client used for HTTP requests. | +| `maxRetries` | Integer | Maximum number of retries on transient errors. Default: `3`. | +| `backoffMs` | Integer | Base delay (ms) between retries. Doubled each attempt. | + +## Class constructor + +Create a embedder. All options are optional. + +| Nom de l'argument | Type | Description | +| ----------------- | ------ | ----------------------------------------------------------------------------- | +| *options* | Object | `{client, maxRetries, backoffMs}` — any field may be omitted. | + +```4d +// Default — uses cs.AIKit.OpenAI.new() internally +var $proc:=cs.EmbeddingStudio.Embedder.new() + +// Provide a pre-configured AIKit client (custom API key, base URL, etc.) +var $client:=cs.AIKit.OpenAI.new({apiKey: "…"; baseURL: "https://server.ai"}) +var $proc:=cs.EmbeddingStudio.Embedder.new({client: $client; maxRetries: 5; backoffMs: 1000}) +``` + +> If the 4D AIKit component is not loaded (or is too old to provide `OpenAIProviders`), the constructor still succeeds with a `Null` client, and the first `embed()` / `embedBatch()` call throws an error whose `message` explains what is missing and whose `isAIKitMissing` property is `True`. + +## Fonctions + +### embed() + +**embed**(*text* : Text ; *model* : Text) : [cs.EmbeddingStudio.EmbedderResult](EmbedderResult.md) + +Embed a single text. Returns a typed result with the embedding vector, token usage, and rate-limit state. + +| Argument | Type | Description | +| ----------------------- | -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| *text* | Text | The text to vectorize. | +| *model* | Text | The embedding model to use (e.g. `"text-embedding-3-small"`). | +| Résultat de la fonction | [cs.EmbeddingStudio.EmbedderResult](EmbedderResult.md) | Typed wrapper — `.vector` holds the embedding, `.promptTokens` / `.totalTokens` hold usage, rate-limit fields are flat camelCase. | + +Throws if retries are exhausted or the API returns a non-retryable error. + +```4d +var $result:=$proc.embed("it rains cats and dogs"; "text-embedding-3-small") +// $result.vector → 4D.Vector +// $result.promptTokens → Integer +// $result.totalTokens → Integer +// $result.remainingTokens → Integer (-1 if unknown) +``` + +### embedBatch() + +**embedBatch**(*texts* : Collection ; *model* : Text) : [cs.EmbedderResult](EmbedderResult.md) + +Embed a collection of texts in a single API call. Returns a typed result with vectors in the same order as inputs, token usage, and rate-limit state. + +| Argument | Type | Description | +| ----------------------- | ------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------- | +| *texts* | Collection | Collection of Text to vectorize. Empty or `Null` returns an empty result. | +| *model* | Text | The embedding model to use. | +| Résultat de la fonction | [cs.EmbedderResult](EmbedderResult.md) | Typed wrapper — `.vectors` holds the embeddings collection, token and rate-limit fields are flat camelCase. | + +```4d +var $result:=$proc.embedBatch(["hello"; "world"]; "text-embedding-3-small") +// $result.vectors[0] → 4D.Vector for "hello" +// $result.vectors[1] → 4D.Vector for "world" +// $result.totalTokens → Integer (sum for the batch) +// $result.remainingTokens → Integer (after this call) +``` + +## Retry policy + +Transient errors (HTTP 408, 409, 429, 5xx) are retried up to `maxRetries` times. + +- If the response carries a `Retry-After` or `retry-after-ms` header, the embedder waits that long. +- Otherwise, it waits `backoffMs * 2^attempt`. + +Non-retryable errors are thrown immediately — see [OpenAIError](https://developer.4d.com/docs/aikit/Classes/openaierror) for the thrown shape. + +## Voir également + +- [EmbedderResult](EmbedderResult.md) +- [Process](Process.md) +- [OpenAIEmbeddingsAPI](https://developer.4d.com/docs/aikit/Classes/openaiembeddingsapi) (AIKit) From 87ee5be2760ee7ec8a79e7b548bf12e8b08d0a99 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:38:47 +0100 Subject: [PATCH 031/195] embedderresult.md French --- .../Classes/EmbedderResult.md | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/EmbedderResult.md diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/EmbedderResult.md b/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/EmbedderResult.md new file mode 100644 index 00000000000000..853bd158d5fd4d --- /dev/null +++ b/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/EmbedderResult.md @@ -0,0 +1,80 @@ +--- +id: embedderresult +title: EmbedderResult +--- + +# EmbedderResult + +Typed wrapper for `Embedder.embed()` and `Embedder.embedBatch()` responses. Normalizes OpenAI's snake_case API keys (`prompt_tokens`, `total_tokens`) to camelCase properties, and flattens the nested rate-limit structure into direct properties. + +A single class handles both single and batch results — `embed()` populates `.vector`, `embedBatch()` populates `.vectors`. + +## Propriétés + +### Embedding results + +| Propriété | Type | Par défaut | Description | +| --------- | ------------------------- | ---------- | ------------------------------------------------------------------------------ | +| `vector` | 4D.Vector | Null | Single embedding result. Null for batch calls. | +| `vectors` | Collection | `[]` | Batch embedding results. | + +### Token usage + +| Propriété | Type | Par défaut | Description | +| -------------- | ------- | ---------- | -------------------------------------------------------------------- | +| `promptTokens` | Integer | `0` | Input tokens consumed. | +| `totalTokens` | Integer | `0` | Total tokens consumed (in + out). | + +### Rate-limit state + +| Propriété | Type | Par défaut | Description | +| ------------------- | ------- | ---------- | ------------------------------------------------------------------------------------------------------------------- | +| `remainingTokens` | Integer | `-1` | Tokens left in the current window. `-1` = unknown. | +| `remainingRequests` | Integer | `-1` | Requests left in the current window. `-1` = unknown. | +| `limitTokens` | Integer | `0` | TPM ceiling for the account. | +| `limitRequests` | Integer | `0` | RPM ceiling for the account. | +| `resetTokens` | Text | `""` | Time until token bucket refills (e.g. `"6m0s"`). | +| `resetRequests` | Text | `""` | Time until request bucket refills (e.g. `"1s"`). | + +## Class constructor + +```4d +// From a real API result (used by Embedder internally) +var $result:=cs.EmbedderResult.new($aikitResult; True) // batch +var $result:=cs.EmbedderResult.new($aikitResult; False) // single + +// Empty result (no API call — e.g. empty batch) +var $result:=cs.EmbedderResult.new() +``` + +| Argument | Type | Description | +| --------- | ------- | ------------------------------------------------------------------------------------------------------------ | +| *result* | Object | An object with `.vector`/`.vectors`, `.usage`, `.rateLimit` (duck-typed). | +| *isBatch* | Boolean | `True` to read `.vectors`, `False` to read `.vector`. | + +The constructor accepts any object that exposes the expected shape — it does not require a specific class. This makes it easy to construct in tests. + +## Utilisation + +```4d +// Single embedding +var $r:=$embedder.embed("hello world"; "text-embedding-3-small") +$r.vector // → 4D.Vector +$r.promptTokens // → 6 +$r.totalTokens // → 6 + +// Batch embedding +var $r:=$embedder.embedBatch(["hello"; "world"]; "text-embedding-3-small") +$r.vectors.length // → 2 +$r.totalTokens // → 10 + +// Rate-limit awareness +$r.remainingTokens // → 148230 (or -1 if not yet known) +$r.resetTokens // → "6m0s" +``` + +## Voir également + +- [Embedder](Embedder.md) — creates EmbedderResult instances +- [ProcessResult](ProcessResult.md) — run-level report that accumulates EmbedderResult usage +- [Rate Limiting](../RateLimit.md) — how the pipeline uses rate-limit fields for throttling and batch sizing From 73ee234d14aeca7ccbb879a5c2d9e1dd8c061552 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:38:49 +0100 Subject: [PATCH 032/195] phrase.md French --- .../embedding-studio/Classes/Phrase.md | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Phrase.md diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Phrase.md b/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Phrase.md new file mode 100644 index 00000000000000..7f8a82daec5ef0 --- /dev/null +++ b/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Phrase.md @@ -0,0 +1,117 @@ +--- +id: phrase +title: Phrase +--- + +# Phrase + +The `Phrase` class is a lightweight template engine: a template with `{variable}` placeholders is compiled once, then rendered efficiently against different data objects. + +## Propriétés + +| Nom de propriété | Type | Description | +| ---------------- | ---------- | ---------------------------------------------------------------------------------------------------------------------- | +| `template` | Text | Computed — returns the original template string. | +| `keys` | Collection | Computed — returns the variable names found in the template, dot-notation keys joined back to strings. | + +## Class constructor + +Compile a template. Compilation walks the template once and extracts static parts and variable paths. + +| Nom de l'argument | Type | Description | +| ----------------- | ---- | ---------------------------------------------------------- | +| *template* | Text | Template string with `{variable}` markers. | + +```4d +var $tpl:=cs.EmbeddingStudio.Phrase.new("Hello {firstName}, you study at {schoolName}.") +$tpl.keys // → ["firstName"; "schoolName"] +``` + +## Fonctions + +### render() + +**render**(*data* : Object) : Text + +Render the compiled template by replacing variables with values from *data*. Missing keys produce an empty string. + +| Argument | Type | Description | +| ----------------------- | ------ | ------------------------------------------------------------------------------------------------------ | +| *data* | Object | A plain object or a 4D.Entity whose fields supply the variable values. | +| Résultat de la fonction | Text | The rendered text. | + +```4d +var $text:=$tpl.render({firstName: "Alice"; school: {name: "MIT"}}) +// → "Hello Alice, you study at MIT." + +// Works directly on entities +$text:=$tpl.render(ds.Students.first()) +``` + +### validate() + +**validate**(*dataclass* : 4D.DataClass ; *options* : Object) : Object + +Validate that all keys in the phrase can be resolved against the given dataclass. Walks dot-notation paths through N:1 / 1:1 relations. + +| Argument | Type | Description | +| ----------------------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| *dataclass* | 4D.DataClass | The dataclass to validate against. | +| *options* | Object | Optional validation flags (see below). All default to `False` — storage kind only. | +| Résultat de la fonction | Object | `{success: Boolean, errors: Collection of {key, message}}`. | + +#### Options + +| Champ | Type | Par défaut | Description | +| ----------------- | ------- | ---------- | ----------------------------------------------------------------------------------------------------- | +| `allowRelations` | Boolean | `False` | Allow dot-notation paths through N:1 / 1:1 relations. | +| `allowCalculated` | Boolean | `False` | Allow calculated attributes. | +| `allowAlias` | Boolean | `False` | Allow alias attributes. | + +```4d +var $tpl:=cs.EmbeddingStudio.Phrase.new("{firstName} at {school.name}") + +// Storage-only validation — fails because {school.name} uses a relation +var $v:=$tpl.validate(ds.Students) +// $v.success → False +// $v.errors → [{key: "school.name"; message: "..."}] + +// Allow relations +$v:=$tpl.validate(ds.Students; {allowRelations: True}) +// $v.success → True +``` + +#### Rejected shapes + +Regardless of options: + +- Attributes that do not exist on the dataclass. +- Attributes whose class ID is `4D.Vector`. +- 1:N relations (`relatedEntities`) as the final key. +- Intermediate segments that are not relations (when dot-notation is used). + +### attributs() + +**attributes**(*dataclass* : 4D.DataClass) : Collection + +Resolves each phrase key against *dataclass* and returns an ordered Collection of ORDA attribute descriptor objects, one per key in the same order as `.keys`. For dot-notation paths, traverses N:1 relations to reach the final attribute. Pushes `Null` for any key whose path cannot be resolved (unknown attribute or non-relation intermediate segment). + +| Argument | Type | Description | +| ----------------------- | ---------------------------- | -------------------------------------------------------------------------------------------- | +| *dataclass* | 4D.DataClass | The dataclass to resolve attributes against. | +| Résultat de la fonction | Collection | Ordered collection of ORDA attribute objects (or `Null`). | + +Each resolved entry is an ORDA attribute descriptor with `.name`, `.kind`, and more — see [DataClass.attributeName](https://developer.4d.com/docs/API/DataClassClass#attributename). + +```4d +var $tpl:=cs.EmbeddingStudio.Phrase.new("{firstName} graduated from {school.name}") +var $attrs:=$tpl.attributes(ds.Students) +// $attrs[0].name → "firstName" $attrs[0].type → "string" +// $attrs[1].name → "name" $attrs[1].type → "string" (from School dataclass) +// $attrs[1] is Null if school.name could not be resolved +``` + +## Voir également + +- [Definition](Definition.md) — holds a `Phrase`. +- [StudioEmbedder.render()](StudioEmbedder.md#render) — renders a phrase for an entity, non-persisting. From fa2867e9eb0281fd6ac2b631ab53514abcb9bdb3 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:38:52 +0100 Subject: [PATCH 033/195] process.md French --- .../embedding-studio/Classes/Process.md | 188 ++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Process.md diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Process.md b/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Process.md new file mode 100644 index 00000000000000..e15505f9d524e5 --- /dev/null +++ b/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Process.md @@ -0,0 +1,188 @@ +--- +id: process +title: Process +--- + +# Process + +The `Process` class orchestrates the full embedding pipeline: it browses 4D entities, renders text from their fields using a [Definition](Definition.md), calls the embeddings API through an [Embedder](Embedder.md), and stores the resulting `4D.Vector` on each entity. + +To render or embed on demand without persistence (search query vectors, phrase previews), see [StudioEmbedder](StudioEmbedder.md). + +## Propriétés + +| Nom de propriété | Type | Description | +| ---------------- | ----------------------- | -------------------------------------------------------------------------------------------------------- | +| `propriétés` | [Settings](Settings.md) | The settings (definitions, batch size, phrase validation options). | +| `embedder` | [Embedder](Embedder.md) | The API-calling engine. Stateless and swappable. | +| `options` | Object | Runtime options object (see [Options object](#options-object) below). | + +### Options object + +| Touche | Type | Description | +| ---------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `onProgress` | 4D.Function | Called after each processed chunk with `{definition, report}`. | +| `onSuccess` | 4D.Function | Called once at the end when `report.success = True`, with `{report, success, errors}`. | +| `onError` | 4D.Function | Called once at the end when `report.success = False`, with `{report, success, errors}`. | +| `onTerminate` | 4D.Function | Called once at the end in all cases (after `onSuccess`/`onError`), with `{report, success, errors}`. | +| `dryRun` | Boolean | If `True`, runs selection/filter logic but skips API calls and entity saves. | +| `force` | Boolean | If `True`, recomputes every entity ignoring null-vector / dirty-flag filter. | +| `debug` | Boolean | If `True`, emits additional diagnostic log entries. | +| `pauseIndexes` | Boolean | If `True`, index maintenance on the target table is paused for the duration of a `processEntitySelection` batch run, then resumed right after (or on early exit/critical error). Default `False` — indexes are left alone. See [Pausing indexes](#pausing-indexes) before enabling it. | +| `waitForIndexes` | Boolean | Only used with `pauseIndexes`. If `True`, resuming indexes blocks until they are rebuilt. Default `False` — resume is asynchronous (indexes rebuilt in the background). | +| `shouldCancel` | 4D.Function | Predicate called between chunks during selection processing. Returning `True` stops the run gracefully (cooperative cancel) — what [`Scheduler.cancel()`](Scheduler.md#cancel) uses. | +| `embedder` | [Embedder](Embedder.md) | Inject a custom embedder (otherwise a default one is created). | + +## Class constructor + +Create an instance of the orchestrator. + +| Nom de l'argument | Type | Description | +| ----------------- | ----------------------- | ----------------------------------------------------------------------------------------------------------------------- | +| *settings* | [Settings](Settings.md) | Optionnel. If omitted, settings are loaded from the default `Settings/embeddings.json`. | +| *options* | Object | Optional runtime options (see table above). | + +```4d +// Simplest — uses defaults +var $p:=cs.EmbeddingStudio.Process.new() + +// With explicit settings +var $p:=cs.EmbeddingStudio.Process.new($settings) + +// With options +var $p:=cs.EmbeddingStudio.Process.new($settings; {\ + force: True; \ + onProgress: Formula(ALERT("chunk done: "+String($1.report.entitiesUpdated)))}) +``` + +## Batch processing functions + +### process() + +**process**(*definition* : Variant) : [ProcessResult](ProcessResult.md) + +Process one, many, or all [Definition](Definition.md) entries against the full content of their target dataclass. + +| Argument | Type | Description | +| ----------------------- | -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | +| *définition* | `Null`, [Definition](Definition.md), `4D.DataClass`, plain object, or Collection | See [process() resolution](#process-resolution). `Null` → every definition in settings. | +| Résultat de la fonction | [ProcessResult](ProcessResult.md) | Statistics and per-error breakdown. | + +```4d +// Every definition in settings +var $r:=$p.process() + +// One specific definition +var $r:=$p.process($def) + +// Multiple definitions +var $r:=$p.process([$def1; $def2]) + +// Every definition configured for a whole dataclass +var $r:=$p.process(ds.Students) + +// A plain descriptor — looked up in settings, or built on the fly +var $r:=$p.process({dataclassName: "Students"; vectorName: "student_vector_1"}) + +// Any mix — each item is resolved independently and flattened +var $r:=$p.process([ds.Students; $def; {dataclassName: "School"; vectorName: "school_vector_1"}]) +``` + +#### process() resolution + +`process()` has no entity context, so it resolves each input into concrete [Definition](Definition.md) objects directly from settings: + +| Zone de saisie | Comportement | +| -------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `Null` | Every definition in settings. | +| [Definition](Definition.md) | Used as-is. | +| `4D.DataClass` (e.g. `ds.Students`) | Every definition in settings whose `dataclassName` matches that dataclass. | +| `{dataclassName: "..."; vectorName: "..."}` | The matching saved definition, or — if none is found — a new `Definition` built from the object's fields (`modelAlias`, `phrase.template`). | +| Collection | Each item is resolved with the rules above and the results are **flattened** into one collection (a `4D.DataClass` item can expand to several definitions). Unsupported items are dropped. | +| Anything else | Empty result. | + +### processEntity() + +**processEntity**(*entity* : 4D.Entity ; *definition* : Variant) : [ProcessResult](ProcessResult.md) + +Process a single entity. Cheap path — no chunking, no server-side filter. + +| Argument | Type | Description | +| ----------------------- | ----------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | +| *entity* | 4D.Entity | The entity to (re)compute vectors for. | +| *définition* | `Null`, [Definition](Definition.md), Collection, or `{vectorName: ...}` | See [resolution rules](#definition-resolution). `Null` infers from entity's dataclass. | +| Résultat de la fonction | [ProcessResult](ProcessResult.md) | Statistics and per-error breakdown. | + +```4d +// Auto-resolve every definition matching this entity's dataclass +var $r:=$p.processEntity($entity) + +// Specific definition +var $r:=$p.processEntity($entity; $def) + +// By vector name only (looked up in settings against the entity's dataclass) +var $r:=$p.processEntity($entity; {vectorName: "student_vector_1"}) +``` + +### processEntitySelection() + +**processEntitySelection**(*selection* : 4D.EntitySelection ; *definition* : Variant) : [ProcessResult](ProcessResult.md) + +Workhorse path for large jobs. Chunks the selection by `settings.batchSize`, sends one API call per chunk, saves each entity individually. + +| Argument | Type | Description | +| ----------------------- | ----------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | +| *selection* | 4D.EntitySelection | Entities to process. Pre-filtering by the caller is allowed; the pipeline still applies its null/dirty filter. | +| *définition* | `Null`, [Definition](Definition.md), Collection, or `{vectorName: ...}` | See [resolution rules](#definition-resolution). | +| Résultat de la fonction | [ProcessResult](ProcessResult.md) | Statistics and per-error breakdown. | + +```4d +var $todo:=ds.Students.query("country = :1"; "FR") +var $r:=$p.processEntitySelection($todo; $def) +``` + +### Definition resolution (entity context) + +The polymorphic *definition* argument accepted by `processEntity` and `processEntitySelection`. Unlike [`process()`](#process-resolution), these have an entity/selection to infer the dataclass from, so a bare `{vectorName: "..."}` stub is enough: + +| Zone de saisie | Comportement | +| --------------------------- | ----------------------------------------------------------------------------------------------- | +| `Null` | All definitions in settings whose `dataclassName` matches the entity/selection. | +| [Definition](Definition.md) | Used as-is; the `dataclassName` must match the entity/selection. | +| `{vectorName: "..."}` | Looked up in settings by `vectorName` against the entity/selection dataclass. | +| Collection | Each item resolved using the rules above; mismatches are silently dropped. | + +### Recompute rules + +An entity is (re)computed when **any** of these are true: + +- The target vector field is `Null`. +- A sibling field named `{vectorName}_dirty` exists and is `True`. +- The `force` option is `True`. + +The dirty field is optional per dataclass. If it doesn't exist, only the null-vector case triggers recomputation. Upon successful save, the pipeline clears the dirty flag (when present). + +For `processEntitySelection`, the filter is executed as a server-side ORDA query before any API call, so only the rows that actually need work are loaded into memory. For `processEntity`, the check is done in memory on the already-fetched entity. + +### Pausing indexes + +By default the indexes of the target table are maintained normally while vectors are saved. With the `pauseIndexes` option, a batch run calls [`PAUSE INDEXES`](https://developer.4d.com/docs/commands/pause-indexes) on the table before writing and [`RESUME INDEXES`](https://developer.4d.com/docs/commands/resume-indexes) once done (also on early exit or critical error). + +Be aware of what these commands do: + +- `PAUSE INDEXES` disables **all** the indexes of the table (except the primary key index), not only the vector ones: every index on every other field of the table is paused too. While paused, queries and sorts on that table, including those of other processes, run without any index. +- `RESUME INDEXES` then **rebuilds all these indexes**, for the whole table, not only for the records that were recomputed. On a table with several indexes, this rebuild can cost more than the time saved during the writes. +- With `waitForIndexes` set to `True`, the run blocks until the rebuild completes; otherwise the rebuild runs in the background. +- These commands cannot run on a 4D remote client: there the option is ignored (a warning is logged once) and the recalculation runs with indexes maintained normally. Run it on the server, for example through the [Scheduler](Scheduler.md), to use it. + +Enable it only for large recalculations, such as computing the vectors of a whole table for the first time. + +## Voir également + +- [StudioEmbedder](StudioEmbedder.md) +- [Settings](Settings.md) +- [Definition](Definition.md) +- [Embedder](Embedder.md) +- [ProcessResult](ProcessResult.md) +- [Phrase](Phrase.md) +- [Rate Limiting](../RateLimit.md) From b359567c747af9a49b99abf0d471ba0a2db87d3a Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:38:54 +0100 Subject: [PATCH 034/195] processerror.md French --- .../embedding-studio/Classes/ProcessError.md | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/ProcessError.md diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/ProcessError.md b/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/ProcessError.md new file mode 100644 index 00000000000000..3dfb9471b01545 --- /dev/null +++ b/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/ProcessError.md @@ -0,0 +1,87 @@ +--- +id: processerror +title: ProcessError +--- + +# ProcessError + +A `ProcessError` is one structured, typed entry in the `errors` collection of a [ProcessResult](ProcessResult.md). Its typed fields let callers react to a specific failure mode programmatically — retry transient failures, abort on a fatal model outage, count save failures — without parsing message strings. + +You read these instances from [ProcessResult](ProcessResult.md)`.errors`, directly or through its query helpers (`errorsByCode`, `errorsByScope`, `retryableErrors`). + +## Propriétés + +| Nom de propriété | Type | Description | +| ---------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `portée` | Text | Where the error originated: `"pipeline"`, `"definition"`, `"chunk"`, or `"entity"`. | +| `severity` | Text | `"warning"`, `"error"`, or `"fatal"`. Determined by `code` (see [ProcessErrorCode](ProcessErrorCode.md)). | +| `code` | Integer | Machine-readable error code — compare against the constants on [ProcessErrorCode](ProcessErrorCode.md). | +| `ref` | Variant | Scope-dependent reference: `"Dataclass.vector"`, an entity primary key, a model alias, or `Null`. | +| `message` | Text | Human-readable, localized message. | +| `retryable` | Boolean | `True` when re-running the operation could plausibly succeed. Determined by `code`. | + +### scope values + +| Portée | Description | +| -------------- | -------------------------------------------------------------------------------------------------------------------------- | +| `"pipeline"` | Top-level failure affecting the whole run (null selection, a model became unavailable). | +| `"definition"` | A [Definition](Definition.md) failed validation or was skipped. | +| `"chunk"` | A whole batch (chunk) of entities failed in a single API call. | +| `"entity"` | A single entity failed to embed or save. | + +### severity values + +| Severity | Description | +| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `"warning"` | Non-blocking — does **not** make [ProcessResult](ProcessResult.md)`.success` false. | +| `"error"` | A recoverable failure scoped to one entity, chunk, or definition. Makes `success` false. | +| `"fatal"` | Blocks the rest of the run (e.g. the model is unavailable). Also surfaces via `hasFatal`. | + +## Propriétés calculées + +| Propriété | Type | Description | +| --------- | ------- | ------------------------------------------------- | +| `isFatal` | Boolean | `True` when `severity = "fatal"`. | + +## Fonctions + +### toObject() + +**toObject**() : Object + +Returns a plain object (`{scope, severity, code, ref, message, retryable}`) suitable for logging or JSON serialization. + +| Argument | Type | Description | +| ----------------------- | ------ | ------------------------------------------------------ | +| Résultat de la fonction | Object | A JSON-friendly snapshot of the error. | + +## Exemple + +React to failures by type rather than by message text: + +```4d +var $r:=$p.process() + +If (Not($r.success)) + + If ($r.hasFatal) + ALERT("A model became unavailable — aborting until it recovers.") + End if + + var $codes:=cs.EmbeddingStudio.ProcessErrorCode.me + var $saveFailures:=$r.errorsByCode($codes.SAVE_FAILED) + If ($saveFailures.length>0) + ALERT(String($saveFailures.length)+" entities failed to save.") + End if + + // Collect entity keys worth retrying later + var $retry:=$r.retryableErrors().query("scope = :1"; "entity").extract("ref") + +End if +``` + +## Voir également + +- [ProcessErrorCode](ProcessErrorCode.md) — the catalogue of `code` values and their severity/retryability. +- [ProcessResult](ProcessResult.md) — owns the `errors` collection and the query helpers (`errorsByCode`, `errorsByScope`, `retryableErrors`). +- [Process](Process.md) — produces these errors. From 52cdb3dc5dd7b0da7c46c924f0464a9ecdf6ea57 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:38:56 +0100 Subject: [PATCH 035/195] processerrorcode.md French --- .../Classes/ProcessErrorCode.md | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/ProcessErrorCode.md diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/ProcessErrorCode.md b/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/ProcessErrorCode.md new file mode 100644 index 00000000000000..44567dbacab051 --- /dev/null +++ b/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/ProcessErrorCode.md @@ -0,0 +1,55 @@ +--- +id: processerrorcode +title: ProcessErrorCode +--- + +# ProcessErrorCode + +A `singleton` exposing the stable, machine-readable error codes carried by [ProcessError](ProcessError.md) `.code`, plus a `meta()` lookup mapping each code to its default `severity` and `retryable` flag. Compare against these constants instead of parsing message strings. + +Access the shared instance via `.me`: + +```4d +var $codes:=cs.EmbeddingStudio.ProcessErrorCode.me +If ($error.code=$codes.SAVE_FAILED) + // … +End if +``` + +## Codes + +| Constante | Valeur | Default severity | Retryable | Raised when… | +| ----------------------- | ------ | ---------------- | --------- | ------------------------------------------------------------------------------------------------- | +| `NULL_INPUT` | 100 | error | Non | A required entity, selection, or definition was `Null`. | +| `INVALID_DEFINITION` | 101 | error | Non | A value is not a usable [Definition](Definition.md) instance. | +| `VALIDATION_FAILED` | 102 | error | Non | `Definition.validate()` reported a problem. | +| `MODEL_UNAVAILABLE` | 200 | fatal | Oui | A critical API error made the model unusable for the rest of the run. | +| `MODEL_SKIPPED` | 201 | error | Oui | A definition was skipped because its model already failed critically. | +| `EMBED_FAILED` | 202 | error | Oui | A non-critical embedding call failed (single entity or chunk). | +| `VECTOR_COUNT_MISMATCH` | 300 | error | Non | The provider returned a different vector count than requested. | +| `SAVE_FAILED` | 400 | error | Oui | `entity.save()` failed (validation, lock, …). | + +Codes are grouped by hundreds: `1xx` input/configuration, `2xx` model/API, `3xx` data integrity, `4xx` persistence. Unknown codes resolve to `{severity: "error"; retryable: False; label: "UNKNOWN"}`. + +## Fonctions + +### meta() + +**meta**( $code : Integer ) : Object + +Returns the `severity` and `retryable` flag associated with a code — the same values carried by a [ProcessError](ProcessError.md) with that `code`. + +| Argument | Type | Description | +| ----------------------- | ------- | ----------------------------------------------------------------------- | +| `$code` | Integer | One of the code constants above. | +| Résultat de la fonction | Object | `{severity : Text; retryable : Boolean; label : Text}`. | + +```4d +var $m:=cs.EmbeddingStudio.ProcessErrorCode.me.meta(cs.EmbeddingStudio.ProcessErrorCode.me.MODEL_UNAVAILABLE) +// $m = {severity: "fatal"; retryable: True; label: "MODEL_UNAVAILABLE"} +``` + +## Voir également + +- [ProcessError](ProcessError.md) — carries a `.code` from this list. +- [ProcessResult](ProcessResult.md) — `errorsByCode()` filters errors by code. From c3e4554bd79a652882fc9281e787751712021808 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:38:59 +0100 Subject: [PATCH 036/195] processresult.md French --- .../embedding-studio/Classes/ProcessResult.md | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/ProcessResult.md diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/ProcessResult.md b/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/ProcessResult.md new file mode 100644 index 00000000000000..855a11dff50861 --- /dev/null +++ b/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/ProcessResult.md @@ -0,0 +1,91 @@ +--- +id: processresult +title: ProcessResult +--- + +# ProcessResult + +The `ProcessResult` class is the return value of every batch entry point of [Process](Process.md) (`process`, `processEntity`, `processEntitySelection`). It accumulates statistics, per-error breakdowns, and wall-clock duration. + +The orchestrator never throws out of its public batch API — failures are recorded here and the job continues. The caller decides what to do with them. + +## Propriétés + +| Nom de propriété | Type | Description | +| ---------------------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `definitionsProcessed` | Integer | Number of [Definition](Definition.md) entries processed. | +| `entitiesConsidered` | Integer | Number of entities that passed the "needs recompute" filter. | +| `entitiesUpdated` | Integer | Number of entities whose vector was successfully written and saved. | +| `entitiesSkipped` | Integer | Number of entities that could not be processed: individual embed or save errors, or whole-chunk API failures (those entities are left unchanged for the next run). | +| `apiCalls` | Integer | Number of embeddings API calls made. | +| `promptTokens` | Integer | Total prompt tokens consumed across all API calls in this run. | +| `totalTokens` | Integer | Total tokens consumed across all API calls in this run. | +| `durée` | Integer | Total duration of the job in milliseconds. | +| `errors` | Collection | List of [ProcessError](ProcessError.md) entries recorded during the run. | + +### Propriétés calculées + +| Propriété | Type | Description | +| ---------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `success` | Boolean | `True` when no `"error"` or `"fatal"` entry was recorded. `"warning"` entries do not fail the run. | +| `hasFatal` | Boolean | `True` when at least one `"fatal"` entry was recorded (e.g. a model became unavailable). | + +### Error entries + +Each item in `errors` is a [ProcessError](ProcessError.md) with `scope`, `severity`, `code`, `ref`, `message`, and `retryable`. See [ProcessError](ProcessError.md) for the field meanings and [ProcessErrorCode](ProcessErrorCode.md) for the `code` catalogue. + +## Fonctions + +### errorsByScope() + +**errorsByScope**( $scope : Text ) : Collection + +Errors filtered by `scope` (`"pipeline"`, `"definition"`, `"chunk"`, `"entity"`). + +### errorsByCode() + +**errorsByCode**( $code : Integer ) : Collection + +Errors filtered by machine-readable code — see [ProcessErrorCode](ProcessErrorCode.md). + +### retryableErrors() + +**retryableErrors**() : Collection + +Errors flagged `retryable` — re-running the operation could plausibly succeed. + +### toObject() + +**toObject**() : Object + +Returns a plain object suitable for logging or JSON serialization. + +| Argument | Type | Description | +| ----------------------- | ------ | ------------------------------------------------------- | +| Résultat de la fonction | Object | A JSON-friendly snapshot of the report. | + +```4d +var $r:=$p.process() +LOG EVENT(Into 4D log file; JSON Stringify($r.toObject())) +``` + +## Exemple + +```4d +var $r:=$p.processEntitySelection(ds.Students.all(); $def) + +If ($r.success) + ALERT("Updated "+String($r.entitiesUpdated)+" students in "+String($r.duration)+" ms") +Else + var $err : Object + For each ($err; $r.errors) + ALERT("[" + $err.scope + "] " + String($err.ref) + " — " + $err.message) + End for each +End if +``` + +## Voir également + +- [Process](Process.md) +- [ProcessError](ProcessError.md) — the typed shape of each `errors` entry. +- [ProcessErrorCode](ProcessErrorCode.md) — the `code` catalogue. From a3ecf6871507f39acdeefb76417f438ce38ee4c9 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:39:02 +0100 Subject: [PATCH 037/195] scheduler.md French --- .../embedding-studio/Classes/Scheduler.md | 369 ++++++++++++++++++ 1 file changed, 369 insertions(+) create mode 100644 i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Scheduler.md diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Scheduler.md b/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Scheduler.md new file mode 100644 index 00000000000000..67c5622ffdd04a --- /dev/null +++ b/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Scheduler.md @@ -0,0 +1,369 @@ +--- +id: périodicité +title: Périodicité +--- + +# Périodicité + +The `Scheduler` class is the public entry point for the **automated embedding recalculation** service. It maintains a background task that runs the embedding pipeline (see [Process](Process.md)) at a configured interval or a fixed daily time, guarantees that **at most one** recalculation batch runs at a time, and exposes runtime status for administration and monitoring interfaces. + +It is a **singleton**, accessed through `cs.EmbeddingStudio.Scheduler.me`. + +The scheduler runs two named workers: + +| Worker | Rôle | +| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `EmbeddingStudioScheduler` | Background loop that re-reads the config each cycle, computes the next run and fires when due. | +| `EmbeddingStudio` | Execution worker that runs one recalculation batch (shared with the Studio UI, so scheduled and manual runs are serialized). | + +## Configuration + +The configuration lives under the `scheduler` key of `Settings/embeddings.json`: + +```json +{ + "scheduler": { + "mode": "interval", + "intervalHours": 3, + "startFrom": "reference", + "startReference": "2026-09-02T14:00:00", + "dailyTime": "00:00" + } +} +``` + +| Touche | Type | Values / range | Description | +| ---------------- | ------- | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `mode` | Text | `"never"` \| `"interval"` \| `"daily"` | Scheduling mode. Absent/unknown ⇒ `never` (no automatic run). | +| `intervalHours` | Integer | `1`..`24` | Interval mode only. Out-of-range ⇒ default `3`. | +| `startFrom` | Text | `"reference"` \| `"lastExecution"` | Interval mode only. Anchor of the interval (see below). Anything other than `"lastExecution"` — including the legacy `"now"` — is normalized to `reference`. Default `reference`. | +| `startReference` | Text | `"YYYY-MM-DDThh:mm:ss"` | Interval mode with `startFrom = "reference"`. Fixed instant the interval counts from. Absent ⇒ the moment the scheduler was armed, then the current instant. | +| `dailyTime` | Text | `"HH:MM"` | Daily mode only. Time of day for the recalculation. Default `"00:00"`. | + +**Interval anchoring (`startFrom`)** + +- `reference` — **fixed rate**: the interval is anchored on the fixed `startReference` instant, so the slots do not drift whatever a run's duration is. Slots are advanced by `intervalHours` until the first one strictly after now. When `startReference` is absent (a fresh or legacy config), the anchor falls back to the moment the scheduler was armed (`start()`), then to the current instant. +- `lastExecution` — **fixed delay**: the interval is anchored on the last completed recalculation. If the elapsed time since the last run already exceeds the interval (e.g. after a restart), the run is triggered immediately. If there is no prior run, it runs immediately. + +The effective configuration is read from the file on **every loop cycle**, so changes take effect without restarting the scheduler. + +## Starting the scheduler + +Configuring a `mode` is **not enough**: nothing runs until the scheduler is started. There are two ways to get there, and which one applies depends on a single option of your host database. + +### 1. Automatic — let the host database start it + +In the host database, open **Settings > Security** and check **"Execute 'On Host Database Event' method of the components"** (it is *unchecked* by default, for security reasons). + +With this option on, 4D Embedding Studio starts the scheduler by itself when the host database opens, and stops it when the host database closes. There is nothing else to write. + +Use [`autoStart()`](#autostart) to check whether the option is on: + +```4d +If (Not(cs.EmbeddingStudio.Scheduler.me.autoStart())) + // the option is off — I must start the scheduler myself + cs.EmbeddingStudio.Scheduler.me.start() +End if +``` + +### 2. Manual — start it from your own code + +If you prefer to leave the option off, the scheduler never starts on its own. Call [`start()`](#start) from wherever it suits you — typically the host `On Startup` or `On Server Startup` database method — and [`stop()`](#stop) when the database closes (`On Exit` / `On Server Shutdown`): + +```4d +// Host "On Server Startup" +cs.EmbeddingStudio.Scheduler.me.start() + +// Host "On Server Shutdown" +cs.EmbeddingStudio.Scheduler.me.stop() +``` + +> In client/server, arm the scheduler from `On Server Startup`, not from `On Startup`: +> `On Startup` runs on every remote client, and the scheduler state is per machine — each +> client would arm its own loop and run its own batches. If you do call [`start()`](#start) +> from `On Startup` (single-user setups), guard it with +> `If (Application type#4D Remote mode)`. + +`start()` is idempotent, so calling it from several places is harmless. + +### Checking that it really runs + +[`isStarted()`](#isstarted) tells you whether the background loop is alive right now — the answer to "is my schedule actually being watched?": + +```4d +var $s:=cs.EmbeddingStudio.Scheduler.me.status() +If ($s.enabled && Not($s.started)) + ALERT("A schedule is configured but the scheduler is not started.") +End if +``` + +## Fonctions + +### start() + +**start**() : Boolean + +Arms the scheduler and starts the background loop worker if it is not already running. Idempotent — calling it again while already armed simply refreshes the "start from now" anchor. + +| Résultat | Type | Description | +| -------- | ------- | ------------------------------ | +| Résultat | Boolean | Always `True`. | + +```4d +cs.EmbeddingStudio.Scheduler.me.start() +``` + +### stop() + +**stop**() + +Disarms the scheduler and stops the background loop worker. A recalculation batch already in progress is **not** interrupted — it finishes normally (use [`cancel()`](#cancel) to request an early stop). + +```4d +cs.EmbeddingStudio.Scheduler.me.stop() +``` + +### annuler() + +**cancel**() + +Requests a **cooperative** cancel of the batch currently running. The running batch is never force-killed; it stops gracefully between two chunks. Has no effect if no batch is running. + +```4d +cs.EmbeddingStudio.Scheduler.me.cancel() +``` + +### force() + +**force**() : Object + +Forces a recalculation **now**, regardless of the schedule. It honors the single-batch rule: if a batch is already running, the forced trigger is skipped (and logged). Non-blocking — the run happens on the execution worker. + +| Résultat | Type | Description | +| -------- | ------ | ----------------------------------------------------- | +| Résultat | Object | The current [status](#status) object. | + +```4d +var $status:=cs.EmbeddingStudio.Scheduler.me.force() +``` + +### status() + +**status**() : Object + +Returns the current scheduler status, without any input parameter — suitable for administration and monitoring displays. + +| Résultat | Type | Description | +| -------- | ------ | ---------------------------------------------------- | +| Résultat | Object | See [Status object](#status-object). | + +```4d +var $s:=cs.EmbeddingStudio.Scheduler.me.status() +If ($s.running) + ALERT("A recalculation is running since "+$s.batchStart) +End if +``` + +#### Objet statut + +| Touche | Type | Description | +| ---------------------- | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `enabled` | Boolean | `False` when `mode = "never"`. | +| `mode` | Text | Effective mode (`never` \| `interval` \| `daily`). | +| `armed` | Boolean | `True` when the background loop is armed (after `start()`, until `stop()`). | +| `running` | Boolean | `True` while a recalculation batch is in progress. | +| `batchStart` | Text \| Null | ISO timestamp of the running batch start (`Null` when idle). | +| `lastExecution` | Text \| Null | ISO timestamp of the last completed run (`Null` if none yet). Restored from the persisted history after a restart, so it survives the loss of in-memory state. | +| `lastRunBeforeRestart` | Boolean | `True` when `lastExecution` was recovered from the history after a restart rather than produced by a run in the current session. | +| `nextRun` | Text \| Null | ISO timestamp of the next scheduled run (`Null` in `never` mode). | +| `lastResult` | Text \| Null | Result of the last trigger: `started` \| `skipped` \| `completed` \| `failed`. | +| `error` | Text \| Null | Error summary when the last run failed (safe for admin display), else `Null`. | +| `started` | Boolean | `True` when the background loop is really alive (see [`isStarted()`](#isstarted)). | +| `autoStart` | Boolean | `True` when the host database starts the scheduler by itself (see [`autoStart()`](#autostart)). | + +### isStarted() + +**isStarted**() : Boolean + +Tells whether the scheduler is **effectively running**, i.e. whether its background loop is alive at this very moment. Unlike the `armed` flag of the [status](#status-object), it reflects reality: if the loop was never started, or was killed, the result is `False`. + +| Résultat | Type | Description | +| -------- | ------- | --------------------------------------------------------- | +| Résultat | Boolean | `True` when the background loop is alive. | + +```4d +If (Not(cs.EmbeddingStudio.Scheduler.me.isStarted())) + cs.EmbeddingStudio.Scheduler.me.start() +End if +``` + +### autoStart() + +**autoStart**() : Boolean + +Tells whether the host database authorizes 4D Embedding Studio to start itself, i.e. whether the **"Execute 'On Host Database Event' method of the components"** option is checked in the host **Settings > Security** (see [Starting the scheduler](#starting-the-scheduler)). + +- `True` — the scheduler starts with the host database and stops with it. You have nothing to call. +- `False` — nothing starts automatically: your code must call [`start()`](#start) and [`stop()`](#stop). + +The answer is read from the host structure settings. When they cannot be read, the result is `False` — the safe answer, since starting an already-started scheduler is harmless. + +| Résultat | Type | Description | +| -------- | ------- | -------------------------------------------------------------------- | +| Résultat | Boolean | `True` when the host starts the scheduler by itself. | + +```4d +var $auto:=cs.EmbeddingStudio.Scheduler.me.autoStart() +``` + +### config() + +**config**() : Object + +Returns the effective scheduler configuration with defaults applied (as resolved from `embeddings.json`). + +| Résultat | Type | Description | +| -------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------- | +| Résultat | Object | `{mode; intervalHours; startFrom; startReference; dailyTime}` (see [Configuration](#configuration)). | + +```4d +var $cfg:=cs.EmbeddingStudio.Scheduler.me.config() +``` + +### saveConfig() + +**saveConfig**( *cfg* : Object ) : Object + +Validates, normalizes and **persists** a scheduler configuration to the `scheduler` key of `embeddings.json`, then returns the normalized value. This is the programmatic equivalent of the scheduler settings window: it lets you change the schedule entirely by code, without the GUI. Only the `scheduler` key is written — other keys of the settings file are preserved. + +The configuration is written **on the server**: in a 4D Server / 4D remote setup the file is always edited on the server machine, so a remote client can safely call this method. Because the loop re-reads the configuration on every cycle, the new schedule takes effect without restarting the scheduler. + +| Paramètres | Type | Description | +| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| cfg | Object | Raw configuration `{mode; intervalHours; startFrom; startReference; dailyTime}` (see [Configuration](#configuration)). Missing/out-of-range values are defaulted. | + +| Résultat | Type | Description | +| -------- | ------ | ---------------------------------------------------------------- | +| Résultat | Object | The normalized configuration that was persisted. | + +```4d +// Switch to a 6-hour interval counting from the last execution +cs.EmbeddingStudio.Scheduler.me.saveConfig({mode: "interval"; intervalHours: 6; startFrom: "lastExecution"}) + +// Switch to a daily run at 02:30 +cs.EmbeddingStudio.Scheduler.me.saveConfig({mode: "daily"; dailyTime: "02:30"}) + +// Disable the automatic schedule +cs.EmbeddingStudio.Scheduler.me.saveConfig({mode: "never"}) +``` + +### nextRun() + +**nextRun**() : Object + +Computes the next scheduled run from the current configuration and state. + +| Résultat | Type | Description | +| -------- | -------------- | --------------------------------------------------------------------------------------------------------------- | +| Résultat | Object \| Null | `{date : Date; time : Time; timestamp : Text; immediate : Boolean}`, or `Null` in `never` mode. | + +```4d +var $next:=cs.EmbeddingStudio.Scheduler.me.nextRun() +``` + +### reload() + +**reload**() : Object + +No-op convenience: the configuration is re-read automatically on each loop cycle, so this simply returns the current [status](#status). Provided for callers that want an explicit "config changed, give me the up-to-date status" call. + +| Résultat | Type | Description | +| -------- | ------ | ----------------------------------------------------- | +| Résultat | Object | The current [status](#status) object. | + +## Concurrency & logging + +- **Single batch** — at any time, at most one recalculation batch runs. A trigger (scheduled or forced) fired while a batch is running is **skipped**, not queued. +- **Skip traceability** — skipped triggers are logged with their timestamp in the execution history (`Logs/embeddingHistory.json`). +- **Cooperative cancel** — `cancel()` stops a running batch gracefully between chunks; it is never force-killed. +- **History** — each run records start/end timestamps, status, token usage and the computed next run date in `Logs/embeddingHistory.json` (see [ProcessResult](ProcessResult.md) for per-run details). + +### Execution history file + +`Logs/embeddingHistory.json` is written by the pipeline itself (every full `process()` run, scheduled or manual), guarded by a semaphore so concurrent processes never interleave writes. It holds the **current** run at the top level, the one before it under `previous`, and the same pair per definition under `definitions`. + +```json +{ + "startTime": "2026-09-01T14:03:00", + "endTime": "2026-09-01T14:03:00", + "status": "completed", + "trigger": "completed", + "error": null, + "nextComputeDate": "2026-09-02T14:03:00", + "promptTokens": 0, + "totalTokens": 0, + "cumulativePromptTokens": 37802, + "cumulativeTotalTokens": 37802, + "previous": { "startTime": "…", "endTime": "…", "status": "completed", "error": null, + "nextComputeDate": "…", "promptTokens": 12764, "totalTokens": 12764, + "cumulativePromptTokens": 37802, "cumulativeTotalTokens": 37802 }, + "skipped": ["2026-09-01T12:00:00"], + "definitions": { + "Students.student_vector_1": { + "startTime": "…", "endTime": "…", "status": "completed", "error": null, + "promptTokens": 1054, "totalTokens": 1054, + "cumulativePromptTokens": 4210, "cumulativeTotalTokens": 4210, + "previous": { "…": "…" } + } + } +} +``` + +| Touche | Type | Description | +| -------------------------------------------------- | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `startTime` / `endTime` | Text \| Null | ISO timestamps of the run, in the scheduler's local base. `endTime` is `null` while a run is in progress. | +| `status` | Text | `running` \| `completed` \| `failed`. | +| `trigger` | Text | Last event that touched the file: `started` \| `skipped` \| `completed` \| `failed`. | +| `error` | Text \| Null | Summary of the run's errors, or `null`. Never contains an API key. | +| `nextComputeDate` | Text \| Null | Next scheduled run computed at the end of the run (the `nextComputeDate` option of [Process](Process.md)). | +| `promptTokens` / `totalTokens` | Integer | Usage for this run alone. | +| `cumulativePromptTokens` / `cumulativeTotalTokens` | Integer | Running totals across all recorded runs. | +| `previous` | Object | Snapshot of the preceding run — the same keys, without `trigger`, `skipped` and `definitions`. Only one generation is kept. | +| `skipped` | Collection | ISO timestamps of triggers skipped because a batch was already running. Capped at the **last 50**. | +| `definitions` | Object | One entry per definition, keyed `"."`, each with its own `startTime`, `endTime`, `status` (`completed` \| `failed` \| `skipped`), `error`, token counters and `previous`. | + +[`status()`](#status) reads `startTime`, `endTime`, `status`, `trigger`, `error` and `nextComputeDate` back from this file, which is how `lastExecution` survives a server restart. + +## Lifecycle + +| Host setting | What happens | What you must do | +| ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | +| **"Execute 'On Host Database Event' method of the components"** checked | The scheduler starts when the host database opens and stops when it closes. | Nothing. | +| Option unchecked (default) | The scheduler never starts by itself. | Call [`start()`](#start) at startup and [`stop()`](#stop) at shutdown. | + +Ask [`autoStart()`](#autostart) which case you are in, and [`isStarted()`](#isstarted) whether the loop is currently alive. Stopping the scheduler never interrupts a batch in progress — it finishes normally. + +## Exemple + +```4d +// --- Start at server startup, unless the host does it for us --- +If (Not(cs.EmbeddingStudio.Scheduler.me.autoStart())) + cs.EmbeddingStudio.Scheduler.me.start() +End if + +// --- Admin panel: force a recalculation and read status --- +var $status:=cs.EmbeddingStudio.Scheduler.me.force() + +// --- Monitoring: display last / next run and current state --- +$status:=cs.EmbeddingStudio.Scheduler.me.status() +var $info:="Mode: "+$status.mode\ + +" — Last: "+String($status.lastExecution)\ + +" — Next: "+String($status.nextRun)\ + +" — "+($status.running ? "running" : String($status.lastResult)) + +// --- Cancel a long-running batch --- +cs.EmbeddingStudio.Scheduler.me.cancel() + +// --- Disable automatic runs --- +cs.EmbeddingStudio.Scheduler.me.stop() +``` From fe64c1cdf023d3ea40a9c1da3a07149f8d925eb1 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:39:05 +0100 Subject: [PATCH 038/195] settings.md French --- .../embedding-studio/Classes/Settings.md | 184 ++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Settings.md diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Settings.md b/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Settings.md new file mode 100644 index 00000000000000..45c3b4fc59db17 --- /dev/null +++ b/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Settings.md @@ -0,0 +1,184 @@ +--- +id: settings +title: Propriétés +--- + +# Propriétés + +The `Settings` class is the persisted configuration for the embedding pipeline. It loads and saves a JSON file (default: `Settings/embeddings.json`, overridable with the `EMBEDDINGS_SETTINGS_PATH` environment variable) containing a list of [Definition](Definition.md) entries, a batch size, and phrase-validation options. + +## Propriétés + +| Nom de propriété | Type | Description | +| ---------------- | -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `definitions` | Collection of [Definition](Definition.md) | The configured definitions. | +| `batchSize` | Integer | Chunk size used by [Process.processEntitySelection](Process.md#processentityselection). Default: `50`. | +| `phrase` | Object | Phrase-validation options (see below). | +| `embedder` | Object | Optional embedder configuration (see below). | +| `file` | 4D.File *(read-only)* | The backing file the settings are loaded from and saved to. | + +### phrase options + +Passed verbatim to [Phrase.validate()](Phrase.md#validate) whenever the pipeline validates a definition. + +| Champ | Type | Par défaut | Description | +| ----------------- | ------- | ---------- | ----------------------------------------------------------------------------------------------- | +| `allowRelations` | Boolean | `False` | Allow dot-notation through N:1 / 1:1 relations. | +| `allowCalculated` | Boolean | `False` | Allow calculated attributes in phrases. | +| `allowAlias` | Boolean | `False` | Allow alias attributes in phrases. | +| `allowObject` | Boolean | `False` | Allow object attributes in phrases. | + +> **Invalidation caveat.** Dirty-flag tracking only covers direct scalar fields on the entity. Fields that are only reachable through one of these options — a related entity's attribute, a calculated value, an alias, or a sub-property of an object — will **not** automatically mark the entity as dirty when they change. If such fields are part of a phrase and their source data changes, the vector will not be recomputed unless you call `invalidateVectors()` explicitly or use `force: true` when processing. + +### embedder options + +Controls how [Process](Process.md) builds its embedder. When absent, a default `Embedder` is created with its own defaults. + +| Champ | Type | Par défaut | Description | +| ------------ | ------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `className` | Text | — | Name of a project class to instantiate instead of the built-in `Embedder`. The class must expose `embed` and `embedBatch` functions. If instantiation fails or the interface is missing, a diagnostic error is logged and the default `Embedder` is used as fallback. | +| `maxRetries` | Integer | `3` | Number of retry attempts on rate-limit errors (forwarded to `Embedder`). | +| `backoffMs` | Integer | `500` | Base back-off delay in ms, doubled each retry (forwarded to `Embedder`). | + +Any additional keys are forwarded as-is to the constructor of the target class (built-in or custom). + +## Format de fichier + +```json +{ + "batchSize": 50, + "phrase": { + "allowRelations": false, + "allowCalculated": false, + "allowAlias": false, + "allowObject": false + }, + "embedder": { + "maxRetries": 5, + "backoffMs": 200 + }, + "definitions": [ + { + "dataclassName": "Students", + "vectorName": "student_vector_1", + "modelAlias": "text-embedding-3-small", + "phrase": "Student {firstName} {lastName}", + "autoInvalidate": true + } + ] +} +``` + +Each definition may include `autoInvalidate` (`true` by default) to control save-time automatic invalidation. + +The same file also carries the `scheduler` key (see [Scheduler](Scheduler.md#configuration)) and any other top-level key you add: `Settings` reads and rewrites only the keys listed above and leaves the rest untouched. + +With a custom embedder class: + +```json +{ + "embedder": { + "className": "MyCustomEmbedder" + }, + "definitions": [...] +} +``` + +## Class constructor + +Create a settings instance. The configuration file is loaded immediately. + +| Nom de l'argument | Type | Description | +| ----------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| *file* | 4D.File | Optionnel. A file to use instead of the default location. The override applies process-wide for subsequent settings access. **Not supported in 4D Remote mode** — pass it only when running locally or on the server. | + +When *file* is omitted, the default location is used: `Settings/embeddings.json`, or the path given by the `EMBEDDINGS_SETTINGS_PATH` environment variable. + +```4d +// Default location +var $settings:=cs.EmbeddingStudio.Settings.new() + +// Custom file (server / mono only) +var $settings:=cs.EmbeddingStudio.Settings.new(File("/some/path/custom.json")) +``` + +## Fonctions + +### load() + +**load**() + +Reload the backing file into memory, overwriting in-memory state. A missing file resets to defaults without raising. + +A file that **exists but cannot be parsed** also leaves the instance on defaults, but it is remembered: an error is logged and [`save()`](#save) then refuses to write, so a malformed file is never silently replaced by defaults. + +### sauvegarde() + +**save**() : Boolean + +Serialize the current in-memory state to the backing file. Only the keys this class owns (`batchSize`, `phrase`, `embedder`, `definitions`) are written — every other top-level key present in the file (the `scheduler` configuration, model aliases…) is preserved as-is. A key whose value is back to its default is *removed* from the file rather than written. + +Definitions are merged with what the file holds at that instant, using the snapshot taken at load time as the common ancestor: two editors open at the same time no longer drop each other's definitions. + +| Résultat | Type | Description | +| -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------ | +| Résultat | Boolean | `True` when written. `False` — nothing written — when the file could not be read at load time. | + +```4d +$settings.definitions.push(cs.EmbeddingStudio.Definition.new("Students"; "student_vector_1"; "text-embedding-3-small"; "{firstName}")) +$settings.batchSize:=100 +$settings.save() +``` + +### chercher() + +**find**(*dataclassName* : Text ; *vectorName* : Text) : [Definition](Definition.md) + +Look up the saved definition for the given dataclass/vector pair. + +| Argument | Type | Description | +| ----------------------- | --------------------------- | ------------------------------------------------------------------- | +| *dataclassName* | Text | Nom de la dataclass. | +| *vectorName* | Text | Name of the vector field on that dataclass. | +| Résultat de la fonction | [Definition](Definition.md) | The matching definition, or `Null` if none matches. | + +```4d +var $def:=$settings.find("Students"; "student_vector_1") +``` + +### findAll() + +**findAll**(*dataclassName* : Text) : Collection of [Definition](Definition.md) + +Return every saved definition configured for the given dataclass. + +| Argument | Type | Description | +| ----------------------- | ----------------------------------------- | --------------------------------------------------------------------------------------------- | +| *dataclassName* | Text | Nom de la dataclass. | +| Résultat de la fonction | Collection of [Definition](Definition.md) | All matching definitions (empty collection if none match). | + +```4d +var $defs:=$settings.findAll("Students") +// → every Students definition; used by Process.process(ds.Students) +``` + +### invalidateVectors() + +**invalidateVectors**() : Object + +Calls [`invalidateVectors()`](Definition.md#invalidatevectors) on every definition in `definitions` and merges the results into a single status object. + +| Argument | Type | Description | +| ----------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------ | +| Résultat de la fonction | Object | `{updated: Integer, skipped: Integer, errors: Collection of Text}` — accumulated across all definitions. | + +```4d +var $result:=cs.EmbeddingStudio.Settings.new().invalidateVectors() +// → { updated: 120; skipped: 0; errors: [] } +``` + +## Voir également + +- [Definition](Definition.md) +- [Process](Process.md) +- [Phrase](Phrase.md) From 0b12a575d8ccc9113765a5690f02de7898e614b4 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:39:07 +0100 Subject: [PATCH 039/195] studioembedder.md French --- .../Classes/StudioEmbedder.md | 125 ++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/StudioEmbedder.md diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/StudioEmbedder.md b/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/StudioEmbedder.md new file mode 100644 index 00000000000000..53ef4019d9b785 --- /dev/null +++ b/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/Classes/StudioEmbedder.md @@ -0,0 +1,125 @@ +--- +id: studioembedder +title: StudioEmbedder +--- + +# StudioEmbedder + +The `StudioEmbedder` class renders and embeds on demand, resolved against the Studio settings: a saved definition gives the phrase and the model, so the vector you compute matches the ones stored by [Process](Process.md). Nothing is persisted. Typical uses: building the vector of a search query, finding entities similar to a given one, or previewing the text sent for an entity. + +For the full batch pipeline that persists vectors on entities, see [Process](Process.md). + +## Propriétés + +| Nom de propriété | Type | Description | +| ---------------- | ----------------------- | ------------------------------------------------------------------------------------------------- | +| `propriétés` | [Settings](Settings.md) | The settings (vectors, batch size, phrase validation options). | +| `embedder` | [Embedder](Embedder.md) | The API-calling engine. Stateless and swappable. | +| `options` | Object | Runtime options object. | + +## Class constructor + +| Nom de l'argument | Type | Description | +| ----------------- | ----------------------- | ----------------------------------------------------------------------------------------------------------------------- | +| *settings* | [Settings](Settings.md) | Optionnel. If omitted, settings are loaded from the default `Settings/embeddings.json`. | +| *options* | Object | Optional runtime options. Supports `embedder` for injection. | + +```4d +var $studioEmbedder:=cs.EmbeddingStudio.StudioEmbedder.new() +var $studioEmbedder:=cs.EmbeddingStudio.StudioEmbedder.new($settings) +var $studioEmbedder:=cs.EmbeddingStudio.StudioEmbedder.new($settings; {embedder: $mockEmbedder}) +``` + +## Fonctions + +### render() + +**render**(*entity* : 4D.Entity ; *definitionOrPhrase* : Variant) : Text + +Return the text that [`embed()`](#embed) sends for an entity (the phrase rendered against it). No API call, no persistence. + +| Argument | Type | Description | +| ----------------------- | ------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| *entity* | 4D.Entity | The entity to render against. | +| *definitionOrPhrase* | `Null`, [Phrase](Phrase.md), [Definition](Definition.md), Text, or plain object stub | `Null` → auto-resolve via settings (requires a unique match). Text → compiled as a throwaway `cs.EmbeddingStudio.Phrase`. Object stub → see [stub resolution](#stub-resolution). | +| Résultat de la fonction | Text | The rendered text. | + +```4d +var $studioEmbedder:=cs.EmbeddingStudio.StudioEmbedder.new() +var $text: Text +$text:=$studioEmbedder.render($student; $def) // use def's phrase +$text:=$studioEmbedder.render($student; cs.EmbeddingStudio.Phrase.new("Hi {firstName}")) +$text:=$studioEmbedder.render($student; "Student: {lastName}") // raw template +$text:=$studioEmbedder.render($student) // auto-resolve +$text:=$studioEmbedder.render($student; {vectorName: "student_vector_1"}) // stub → saved definition's phrase +$text:=$studioEmbedder.render($student; {phrase: "Hi {firstName}"}) // ad-hoc stub → inline template +``` + +### embed() + +**embed**(*input* : Variant ; *context* : Variant ; *model* : Text) : [cs.EmbeddingStudio.EmbedderResult](EmbedderResult.md) + +Compute a vector for an arbitrary input, without persisting anywhere. + +| Argument | Type | Description | +| ----------------------- | --------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| *input* | Text or 4D.Entity | Text → embedded directly. Entity → phrase rendered then embedded. | +| *context* | Text, [Phrase](Phrase.md), [Definition](Definition.md), Text template, plain object stub, or `Null` | Provides phrase and/or model depending on *input*. Object stub → see [stub resolution](#stub-resolution). | +| *model* | Text | Optional explicit model name. Used when *context* does not carry one. | +| Résultat de la fonction | [EmbedderResult](EmbedderResult.md) | The embedding result (use `.vector` to get the 4D.Vector). | + +Throws if no model can be determined. + +```4d +var $studioEmbedder:=cs.EmbeddingStudio.StudioEmbedder.new() +var $vector: 4D.Vector + +// Text + model +$vector:=$studioEmbedder.embed("some text"; "text-embedding-3-small").vector + +// Text + definition (picks up def.modelAlias) +$vector:=$studioEmbedder.embed("some text"; $def).vector + +// Entity + definition (uses def.phrase + def.modelAlias) +$vector:=$studioEmbedder.embed($student; $def).vector + +// Entity + phrase + explicit model +$vector:=$studioEmbedder.embed($student; $phrase; "text-embedding-3-small").vector + +// Entity + ad-hoc template + model +$vector:=$studioEmbedder.embed($student; "Profile: {firstName} {lastName}"; "text-embedding-3-small").vector + +// Entity alone (auto-resolve, only when exactly one def matches the dataclass) +$vector:=$studioEmbedder.embed($student).vector + +// Entity + stub (deduces phrase + model from the matching saved definition) +$vector:=$studioEmbedder.embed($student; {vectorName: "student_vector_1"}).vector + +// Entity + ad-hoc stub (phrase compiled inline, model taken from the stub) +$vector:=$studioEmbedder.embed($student; {phrase: "Hi {firstName}"; modelAlias: "text-embedding-3-small"}).vector + +// Text + stub that only supplies the model +$vector:=$studioEmbedder.embed("some text"; {modelAlias: "text-embedding-3-small"}).vector +``` + +## Stub resolution + +Both `render()` and `embed()` accept a plain object in place of a `Phrase`/`Definition`. A stub is resolved the same way [`Process`](Process.md#definition-resolution-entity-context) resolves its `definition` argument, so the behavior matches. Two flavors are supported: + +| Stub | Resolves to | +| ------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `{vectorName: "..."}` (optionally `{dataclassName: "..."}`) | The matching **saved definition** for the entity's dataclass — deducing its phrase (and, for `embed`, its model). Resolves to nothing when there is no unique match. | +| `{phrase: "tpl {field}"}` or `{template: "tpl {field}"}` | An **ad-hoc** `Phrase` compiled inline; nothing is looked up. Pair with `{modelAlias: "..."}` to give `embed()` a model. | + +For `embed()`, the model is deduced in this order: an explicit `{modelAlias}` on the stub → the model of a stub-matched saved definition → the *model* argument → the entity's unique definition. An explicit `{modelAlias}` always wins. + +Unlike [`Process.process()`](Process.md#process-resolution), a stub is **not** turned into a brand-new `Definition` from its fields — `StudioEmbedder` persists nothing, so use `{phrase}`/`{template}` for one-off templates. + +## Voir également + +- [Process](Process.md) +- [Settings](Settings.md) +- [Definition](Definition.md) +- [Embedder](Embedder.md) +- [EmbedderResult](EmbedderResult.md) +- [Phrase](Phrase.md) From adc0308d16ae83f741437745cf030a05ceb9e403 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:39:10 +0100 Subject: [PATCH 040/195] license.md French --- .../current/embedding-studio/license.md | 167 ++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/license.md diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/license.md b/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/license.md new file mode 100644 index 00000000000000..8f6fc0dd2b5ffc --- /dev/null +++ b/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/license.md @@ -0,0 +1,167 @@ +--- +id: license +title: SOFTWARE LICENSE AGREEMENT +--- + +# SOFTWARE LICENSE AGREEMENT + +## Preamble + +The purpose of this Software license agreement is to grant users the right to modify and re-use the software governed by this license. + +The exercising of this right is conditional upon the obligation to make /available to the community the modifications made to the source code of the software so as to contribute to its evolution. + +In consideration of access to the source code and the rights to copy, modify and redistribute granted by the license, users are provided only with a limited warranty and the software's author, the holder of the economic rights, and the successive licensors only have limited liability. + +## Article 1 – DEFINITIONS + +***Agreement***: means this license agreement, and its possible subsequent versions and annexes. + +***Software***: means the software in its Object Code and/or Source Code form and, where applicable, its documentation, "as is" when the Licensee accepts the Agreement. + +***Initial Software***: means the Software in its Source Code and possibly its Object Code form and, where applicable, its documentation, "as is" when it is first distributed under the terms and conditions of the Agreement. + +***Modified Software***: means the Software modified by at least one Integrated Contribution. + +***Source Code***: means all the Software's instructions and program lines to which access is required so as to modify the Software. + +***Object Code***: means the binary files originating from the compilation of the Source Code. + +***Holder***: means the holder(s) of the economic rights over the Initial Software, in this case it is 4D SAS. + +***Licensee***: means the Software user(s) having accepted the Agreement. + +***Contributor***: means a Licensee having made at least one Integrated Contribution. + +***Licensor***: means the Holder, or any other individual or legal entity, who distributes the Software under the Agreement. + +***Integrated Contribution***: means new functions integrated into the Source Code by any or all Contributors. + +***Parties***: mean both the Licensee and the Licensor. + +These expressions may be used both in singular and plural form. + +## Article 2 - PURPOSE + +The purpose of the Agreement is the grant by the Licensor to the Licensee of a non-exclusive, transferable and worldwide license for the Software as set forth in Article 5 hereinafter for the whole term of the protection granted by the rights over said Software. + +## Article 3 - ACCEPTANCE + +The Licensee shall be deemed as having accepted the terms and conditions of this Agreement upon the occurrence of the first of the following events: + +- loading the Software by any or all means, notably, by downloading from a remote server; +- the first time the Licensee exercises any of the rights granted hereunder. + +## Article 4 - EFFECTIVE DATE AND TERM + +### 4.1 EFFECTIVE DATE + +The Agreement shall become effective on the date when it is accepted by the Licensee as set forth in Article 3. + +### 4.2 TERM + +The Agreement shall remain in force for the entire legal term of protection of the economic rights over the Software. + +## Article 5 - SCOPE OF RIGHTS GRANTED + +The Licensor hereby grants to the Licensee, who accepts, the following rights over the Software for the term of the Agreement, on the basis of the terms and conditions set forth hereinafter. + +### 5.1 RIGHT OF USE + +The Licensee is authorized to use the Software, without any limitation as to its fields of application, with it being hereinafter specified that this comprises: + +- permanent or temporary reproduction of all or part of the Software by any or all means and in any or all form. +- loading, displaying, running, or storing the Software on any or all medium. +- entitlement to observe, study or test its operation. + +### 5.2 RIGHT OF MODIFICATION + +The right of modification means the right to adapt, arrange, or make any or all modifications to the Software; being understood that such modifications of the Software shall results in a change of its functionalities and/or in an addition of functionalities to the Initial Software. + +Consequently to distribute a Modified Software according to the provision of section 5.3.2, the Licensee shall make exclusively significant modification as described above to the Software provided that it includes an explicit notice that it is the author of said modification and indicates the date of the creation thereof. + +### 5.3 RIGHT OF DISTRIBUTION + +In particular, the right of distribution includes the right to publish, transmit and communicate the Modified Software to the general public on any or all medium, and by any or all means, and the right to market, either in consideration of a fee, or + +#### 5.3.1 DISTRIBUTION OF SOFTWARE WITHOUT MODIFICATION + +The Licensee is forbidden to distribute true copies of the Software in Source Code or Object Code form. + +#### 5.3.2 DISTRIBUTION OF MODIFIED SOFTWARE + +When the Licensee creates Modified Software, this Modified Software may be distributed provided that said distribution complies with all the provisions of the Agreement and subject to compliance with the requirement to include a notice concerning the rights over the Software as defined in Article 6.3. + +In the event the creation of the Modified Software, the Licensee undertakes that: + +- the resulting Modified Software will be governed by this Agreement, being understood that such Agreement shall be integrated in the Modified Software the Integrated Contributions in the resulting Modified Software will be clearly identified and documented, +- the Licensee will allow effective access to the source code of the Modified Software, at a minimum during the entire period of distribution of the Derivative Software, such that such modifications may be carried over in a subsequent version of the Software. +- the Modified Software must be renamed to exclude any reference to 4D. For example, it is expressly prohibited to distribute a Modified Software named “4D SVG”; Licensee shall rename the Modified Software such as “Name of the Licensee SVG”. Consequently, Licensee is expressly forbidden to use 4D’s product name in general to promote his modified work. + +## Article 6 - INTELLECTUAL PROPERTY + +### 6.1 OVER THE INITIAL SOFTWARE + +The Holder owns the intellectual property rights over the Initial Software. Any or all use of the Initial Software is subject to compliance with the terms and conditions under which the Holder has elected to distribute its work and no one shall be entitled to modify the terms and conditions for the distribution of said Initial Software. + +### 6.2 OVER THE INTEGRATED CONTRIBUTIONS + +The Licensee who develops an Integrated Contribution is the owner of the intellectual property rights over this Contribution as defined by applicable law. + +### 6.3 NOTICE OF RIGHTS + +The Licensee expressly undertakes: + +- not to remove, or modify, in any manner, the intellectual property notices attached to the Software; +- to reproduce said notices, in an identical manner, in the copies of the Software modified; +- to ensure that use of the Software, its intellectual property notices and the fact that it is governed by the Agreement is indicated in a text that is easily accessible, specifically from the interface of any Modified Software. + +The Licensee undertakes not to directly or indirectly infringe the intellectual property rights of the Holder on the Software and to take, where applicable, vis- à-vis its staff, any and all measures required to ensure respect of said intellectual property rights of the Holder. + +## Article 7 - RELATED SERVICES + +Under no circumstances shall the Agreement oblige the Licensor to provide technical assistance or maintenance services for the Software. + +However, the Licensor is entitled to offer this type of services. The terms and conditions of such technical assistance, and/or such maintenance, shall be set forth in a separate instrument. + +## Article 8 - DISCLAIMER OF WARRANTY. + +THERE IS NO WARRANTY FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE HOLDER PROVIDES THE SOFTWARE “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH LICENSEE. SHOULD THE SOFTWARE PROVE DEFECTIVE, LICENSEE ASSUMES THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +## Article 9 - LIMITATION OF LIABILITY + +TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE TO LICENSEE ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS AGREEMENT OR USE OF THE SOFTWARE, EVEN IF THE LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR DAMAGES. + +## Article 10 – TERMINATION + +### 10.1 + +In the event of a breach by the Licensee of its obligations hereunder, the Licensor may automatically terminate this Agreement thirty (30) days after notice has been sent to the Licensee and has remained ineffective. + +### 10.2 + +A Licensee whose Agreement is terminated shall no longer be authorized to use, modify or distribute the Software. However, any licenses that it may have granted prior to termination of the Agreement shall remain valid subject to their having been granted in compliance with the terms and conditions hereof. + +## Article 11 – MISCELLANEOUS + +### 11.1 + +Neither Party shall be liable for any or all delay, or failure to perform the Agreement, that may be attributable to an event of force majeure, an act of God or an outside cause, such as defective functioning or interruptions of the electricity or telecommunications networks, network paralysis following a virus attack, intervention by government authorities, natural disasters, water damage, earthquakes, fire, explosions, strikes and labor unrest, war, etc. + +### 11.2 + +Any failure by either Party, on one or more occasions, to invoke one or more of the provisions hereof, shall under no circumstances be interpreted as being a waiver by the interested Party of its right to invoke said provision(s) subsequently. + +### 11.3 + +In the event that one or more of the provisions hereof were to conflict with a current or future applicable act or legislative text, said act or legislative text shall prevail, and the Parties shall make the necessary amendments so as to comply with said act or legislative text. All other provisions shall remain effective. Similarly, invalidity of a provision of the Agreement, for any reason whatsoever, shall not cause the Agreement as a whole to be invalid. + +## Article 12 - GOVERNING LAW AND JURISDICTION + +### 12.1 + +The Agreement is governed by French law. The Parties agree to endeavor to seek an amicable solution to any disagreements or disputes that may arise during the performance of the Agreement. + +### 12.2 + +Failing an amicable solution within two (2) months as from their occurrence, and unless emergency proceedings are necessary, the disagreements or disputes shall be referred to the Versailles Courts having jurisdiction, by the more diligent Party. \ No newline at end of file From 1f471bce4a851fa1d398604b21b11db71b3b78d5 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:39:12 +0100 Subject: [PATCH 041/195] overview.md French --- .../current/embedding-studio/overview.md | 211 ++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/overview.md diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/overview.md b/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/overview.md new file mode 100644 index 00000000000000..cf0a2bd93b1888 --- /dev/null +++ b/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/overview.md @@ -0,0 +1,211 @@ +--- +id: overview +title: 4D-Embedding-Studio +--- + +# 4D-Embedding-Studio + +## Vue d’ensemble + +4D Embedding Studio is a component for defining, processing, and maintaining AI embedding vectors directly in your 4D dataclass entities. + +You can use the component without writing a single line of code: select attributes from your dataclasses to construct the sentences to be vectorized and specify the model to use. For each entity, the component calls the embedding API and stores the resulting `4D.Vector` values. Configure the embedding scheduler to (re)calculate the vectors for your data at fixed intervals or on demand. + +You can then use the ORDA [`query()` by vector feature](https://developer.4d.com/docs/API/DataClassClass#query-by-vector-similarity) to request your data using semantics. + +If you want to have more control over your embeddings, the component offers an extensive API that allows you to customize each step of the data vectorization process, manage the scheduler, and integrate high-performance RAG (*Retrieval Augmented Generation*) features into your 4D application. + +## Conditions requises + +- [4D-AIKit](https://github.com/4d/4D-AIKit) (loaded automatically as a dependency). +- 4D project (21 R5 or later) with the following configuration: + - a valid model alias + - a dataclass with a `4D.Vector` attribute (object field at the database level). + +## Quick Start + +**1. Add a field of type Object to the table and associate it with the `4D.Vector` class.** +**2. Select **Embedding Studio...** in the **Design** menu to display the Embedding Studio window.** + +![menu](../assets/en/embedding-studio/menu.png) + +**3. For each listed `4D.Vector` attribute, write a descriptive phrase based upon attributes of the dataclass.** +Use the contextual menu to insert appropriate attributes. +This phrase will be vectorized for every entity. +**4. Select a model alias (or create a new one).** +**5. Select "Execute now" to launch the vectorization of your data or configure the scheduler.** + +## User Guide + +### Configuring the dataclass + +To use the 4D Embedding Studio interface, you need to create at least one object attribute associated to a `4D.Vector` class in your datastore. This must be done at the database level (only storage attributes can be embeddings). + +In the Structure editor, add an Object field to the dataclass (table) whose entities you want to query using AI and enter ["4D.Vector" as class](https://developer.4d.com/docs/Develop/structure-fields#class). + +#### Dirty-flag support + +In a production application, data is rarely static. If an embedding is based on an attribute value that has changed (e.g. a product description), it becomes obsolete and could no longer be relevant. By default, 4D automatically invalidates and flags for recalculation affected embeddings. + +If you do not use a dirty-flag field (see below), 4D simply replaces any invalidated vector by `Null`. It is therefore no longer used in searches until its next calculation. This option is suitable for applications that prioritize strict consistency: it is better to return no results than to rely on an embedding that no longer matches the current data. + +Or, you can add a Boolean field named `_dirty` (e.g. "myVector_dirty") to the structure. In this case, when an update is required, this field is set to `True`, and the associated vector is retained until it is recalculated. Your application can then choose to continue using this vector temporarily or exclude it using a filter on `dirty = False`. The flag is cleared automatically after a successful save. +This strategy promotes service continuity while allowing you to precisely identify vectors awaiting recalculation. If your business logic requires full control, you can also disable automatic invalidation and manage this lifecycle yourself. + +*Note: Certain modifications, such as a model changes, require vectors to be replaced immediately.* + +### Creating an embedding + +When you select **Embedding Studio...** in the **Design** menu, the Embedding Studio window is displayed. + +The list on the left side shows all `4D.Vector` class attributes defined in the datastore. You can add as many vector attributes as you want per dataclass. + +A check mark (✓) in the Dirty Flag column indicates that a [`_dirty` boolean field](#dirty-flag-support) is associated to the vector field. + +**Note:** Any change in the database structure will require that you restart the 4D application so that the 4D Embedding Studio lists up-to-date values. + +#### Writing a descriptive sentence + +To create or edit an embedding, select the attribute to configure in this list and write the embedding definition in the "Descriptive sentence" area on the right side. Use the associated menu to build the sentence and to add references to dataclass available attributes with the `{attribute_name}` syntax. + +The sentence must build a text that describes the entity just like a human would do it. The embedding could then capturate the semantics and not only attribute values. + +For example, for a `Product` dataclass with many attributes such as name and category, you could write: +"The {name} product is a {category} from the {brand} brand. Description: {description}. Key features: {features}." + +![menu](../assets/en/embedding-studio/studio-interface.png) + +### Selecting a model + +Once you have defined your vector attribute, choose the model to use for generating the embedding. The list of models includes the **model aliases** you defined in the [Project Settings](https://developer.4d.com/docs/settings/ai#model-aliases). + +The choice of model is important because it determines the relevance and quality of your embeddings. You’ll also need to provide this model with every query on the dataclass data so that the comparison is performed using the same model. + +### Auto-invalidate on save + +When this option is checked (default), embeddings are automatically invalidated when at least one of their definition attributes has been modified and the entity was successfully saved. + +However, you might want to handle invalidation in a custom way using the [4D Embedding Studio API](#api-guide). In this case, uncheck this option to disable the automatic mechanism. + +### Calculating embeddings + +Embeddings are calculated by sending a request to the AI model, which then returns the vectorization result, which is subsequently stored in the `4D.Vector` attribute in the dataclass. 4D automatically handles this operation and optimizes it by calculating only the necessary vectors. Each vector is processed independently. Thus, an error on one element does not interrupt the recalculation of the others. Elements that fail will be automatically retried during the next run. Recalculations are performed asynchronously, without blocking users. + +These calculations can be performed **on demand** or **scheduled at regular intervals** using the scheduler in the 4D Embedding Studio component. + +**Note:** You can also customize embedding calculations per dataclass or entity using the [4D Embedding Studio API](#api-guide). + +#### On demand + +To launch an embedding calculation, select **Run now** in the menu at the bottom of the 4D Embedding Studio window. This item is disabled if the datastore does not contain any embedding to calculate. When started, you can select **Cancel run** at any moment. + +#### Périodicité + +You can configure the 4D Embedding Studio component scheduler to adjust the calculation frequency to suit your application’s needs. + +**Important:** The scheduler needs a 4D worker process to run. You can start it manually for testing purposes (**Start now** button in the scheduler dialog box) but to make sure a worker is available every times the application opens, you need to configure it. Vous pouvez soit : + +- select the **Execute "On Host Database Event" method of the components** option in the [project Settings](https://developer.4d.com/docs/settings/security#options) +- or write the following code in your startup code: + +```4d + //at startup +cs.EmbeddingStudio.Scheduler.me.start() +``` + +The scheduler allows you can set the time interval between two calculations. Select the tab corresponding to your needs and click **Save**. + +- **Never**: the scheduler is off and never runs +- **At regular interval**: set the time interval between each calculation starting from a specified time. +- **Once a day**: the calculation takes place every day at a specific time + starting from a specific time. + +### Building queries with embeddings + +Once you have defined embeddings in your datastore, you can start [querying your dataclasses using AI-based features](https://developer.4d.com/docs/API/DataClassClass#query-by-vector-similarity). You just need to make sure that you use the same model for your embedding definition and in the query string. + +For example, assuming that: + +• you have defined a `4D.Vector` attribute named "product_vector" in the Products dataclass using a sentence: "The {name} is in the {category} category. It has these {features} features and can be used for {usage}." +• you want to find products that "can be used safely outside". + +Vous pouvez écrire : + +```4d +// Retrieve the model alias from the embedding definition, configured in 4D Embedding Studio +var $settings:=cs.EmbeddingStudio.Settings.new() +var $definition:=$settings.find("Products"; "product_vector") + +// Compute the vector of the query with the same model +var $result:=cs.EmbeddingStudio.StudioEmbedder.new().embed("products that can be used safely outside"; $definition) +var $vector:=$result.vector + + //search with default metric (cosine) +var $products:=ds.Products.query("product_vector > :1 order by product_vector desc"; {vector : $vector}) + +``` + +If you use a dirty field, simply add a criterion to exclude vectors waiting to be recalculated: + +```4d +var $products:=ds.Products.query("product_vector > :1 and product_vector_dirty = false order by product_vector desc"; {vector : $vector}) +``` + +## API Guide + +### Quick start + +**1. Configure your vectors** in `Settings/embeddings.json`: + +```json +{ + "batchSize": 50, + "definitions": [ + { + "dataclassName": "Students", + "vectorName": "student_vector_1", + "modelAlias": "text-embedding", + "phrase": "Student {firstName} {lastName}, enrolled in {program}", + "autoInvalidate": true + } + ] +} +``` + +**2. Run the full pipeline** (all definitions, all records): + +```4d +var $p:=cs.EmbeddingStudio.Process.new() +var $r:=$p.process() + +If ($r.success) + ALERT("Updated "+String($r.entitiesUpdated)+" entities in "+String($r.duration)+" ms") +End if +``` + +**3. Process a single entity on save** (e.g. in a trigger or REST hook): + +```4d +var $p:=cs.EmbeddingStudio.Process.new() +$p.processEntity($entity) +``` + +### Class reference + +| Class | Description | +| ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [Process](Classes/Process.md) | Main orchestrator — entry point for all batch and entity operations. | +| [Scheduler](Classes/Scheduler.md) | Automated recalculation scheduler — background task, force/cancel, and runtime status. | +| [StudioEmbedder](Classes/StudioEmbedder.md) | Renders and embeds on demand using your saved definitions — e.g. to build a search query vector. Nothing is persisted. | +| [Settings](Classes/Settings.md) | Loads and saves the `embeddings.json` configuration file. | +| [Definition](Classes/Definition.md) | Describes one vector field: dataclass, field name, model alias, and phrase template. | +| [Embedder](Classes/Embedder.md) | Thin wrapper around the AIKit embeddings API with retry/backoff logic. | +| [EmbedderResult](Classes/EmbedderResult.md) | Typed wrapper normalizing API responses — vectors, usage metrics, rate-limit state. | +| [ProcessResult](Classes/ProcessResult.md) | Returned by every batch function — statistics and error breakdown. | +| [ProcessError](Classes/ProcessError.md) | Typed entry in `ProcessResult.errors` — scope, severity, code, ref, message, retryable. | +| [ProcessErrorCode](Classes/ProcessErrorCode.md) | Singleton catalogue of machine-readable error codes and their default severity/retryability. | +| [Phrase](Classes/Phrase.md) | Lightweight `{variable}` template engine used to build text from entity attributes. | + +### Voir également + +Blog post: [Vectorize your data effortlessly with 4D Embedding Studio](https://blog.4d.com/vectorize-your-data-effortlessly-with-4d-vector-studio) \ No newline at end of file From f494508a02c94798d71d8c3ce8bece0bc8a71dcf Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:39:15 +0100 Subject: [PATCH 042/195] ratelimit.md French --- .../current/embedding-studio/ratelimit.md | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/ratelimit.md diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/ratelimit.md b/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/ratelimit.md new file mode 100644 index 00000000000000..757cf6d3c79040 --- /dev/null +++ b/i18n/fr/docusaurus-plugin-content-docs/current/embedding-studio/ratelimit.md @@ -0,0 +1,65 @@ +--- +id: ratelimit +title: Rate Limiting +--- + +# Rate Limiting + +The embedding pipeline includes built-in rate-limit awareness. When the API provider returns rate-limit headers (as OpenAI does), the system automatically throttles requests and adapts batch sizes to stay within budget. Providers that don't return rate-limit headers (e.g. Ollama) are unaffected — the pipeline runs at full speed. + +## Principes de fonctionnement + +Each call to [`Embedder.embed()`](Classes/Embedder.md) or [`Embedder.embedBatch()`](Classes/Embedder.md) returns an [`EmbedderResult`](Classes/EmbedderResult.md) that carries rate-limit state alongside the embedding vectors. The pipeline uses this data in a three-step loop: + +1. **Pre-flight throttle** — before sending a batch, the pipeline checks whether the remaining token budget is sufficient. If not, it waits for the reset window to elapse before proceeding. +2. **Adaptive batch sizing** — the pipeline computes the largest batch that fits within 80% of the remaining token budget. This avoids hitting the ceiling while still making efficient use of the quota. +3. **State update** — after each API response, the pipeline records the new remaining budget, computes an average tokens-per-entity estimate, and feeds both into the next iteration. + +## Rate-limit fields on EmbedderResult + +These fields are populated from the API response headers. When a provider doesn't return them, they keep their defaults and the pipeline skips throttling. + +| Champ | Par défaut | Description | +| ------------------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------- | +| `remainingTokens` | `-1` | Tokens left in the current window. `-1` = unknown. | +| `remainingRequests` | `-1` | Requests left in the current window. | +| `limitTokens` | `0` | TPM (tokens per minute) ceiling. | +| `limitRequests` | `0` | RPM (requests per minute) ceiling. | +| `resetTokens` | `""` | Time until the token bucket refills (e.g. `"6m0s"`, `"200ms"`). | +| `resetRequests` | `""` | Time until the request bucket refills. | + +## Batch size adaptation + +The pipeline starts with the configured `batchSize` (from [Settings](Classes/Settings.md), default 50). After the first API response provides rate-limit data, the batch size may shrink: + +``` +nextBatchSize = min( floor(remainingTokens × 0.8 / tokensPerEntity), configBatchSize ) +``` + +- `tokensPerEntity` is estimated from the last chunk (`totalTokens / chunkSize`). +- The result is clamped to a floor of 1 and a ceiling of `configBatchSize`. +- When `remainingTokens` is unknown (`-1`), the configured batch size is used as-is. + +## Pre-flight wait + +Before each batch, the pipeline checks: + +- **Token budget**: if `remainingTokens < estimatedTokens × 1.1`, it waits for the token reset window. +- **Request budget**: if `remainingRequests = 0`, it waits for the request reset window. + +The reset durations are parsed from the API's string format (`"6m0s"` → 360 seconds, `"200ms"` → 1 second). + +## Providers without rate limits + +Some providers (Ollama, local models) don't return rate-limit headers. Dans ce cas : + +- `remainingTokens` stays at `-1` (unknown) +- No throttling occurs — batches run at `configBatchSize` without waits +- The pipeline works identically to how it did before rate-limit support was added + +## Voir également + +- [EmbedderResult](Classes/EmbedderResult.md) — carries rate-limit fields +- [Embedder](Classes/Embedder.md) — wraps the API calls +- [Process](Classes/Process.md) — orchestrates the batch loop +- [Settings](Classes/Settings.md) — `batchSize` configuration From 77d7e470f2e2df493faf19993d88fb6f6e9dbddc Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:39:17 +0100 Subject: [PATCH 043/195] menu.png French --- .../assets/en/embedding-studio/menu.png | Bin 0 -> 4938 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 i18n/fr/docusaurus-plugin-content-docs/version-21-R5/assets/en/embedding-studio/menu.png diff --git a/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/assets/en/embedding-studio/menu.png b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/assets/en/embedding-studio/menu.png new file mode 100644 index 0000000000000000000000000000000000000000..425fd0d7e65879e34700b856cf6f88aaa9c502e1 GIT binary patch literal 4938 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 E0Cv$VrvLx| literal 0 HcmV?d00001 From c890fc2bd46553c8b42b945721cbf369627595d8 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:39:19 +0100 Subject: [PATCH 044/195] studio-interface.png French --- .../en/embedding-studio/studio-interface.png | Bin 0 -> 34492 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 i18n/fr/docusaurus-plugin-content-docs/version-21-R5/assets/en/embedding-studio/studio-interface.png diff --git a/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/assets/en/embedding-studio/studio-interface.png b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/assets/en/embedding-studio/studio-interface.png new file mode 100644 index 0000000000000000000000000000000000000000..75dae7c9303297334e2fee1b404527957dfd4746 GIT binary patch literal 34492 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 Z0#D?x@H3fRStk8kMM>jk;f?!G{uip+WAXq1 literal 0 HcmV?d00001 From ffb567ece683877c228e7bb2c9d57d7ba10fff27 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:39:21 +0100 Subject: [PATCH 045/195] definition.md French --- .../embedding-studio/Classes/Definition.md | 165 ++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Definition.md diff --git a/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Definition.md b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Definition.md new file mode 100644 index 00000000000000..fd8c5c92276afd --- /dev/null +++ b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Definition.md @@ -0,0 +1,165 @@ +--- +id: définition +title: Définition +--- + +# Définition + +The `Definition` class describes how a single vector field on a dataclass should be computed: which dataclass, which vector field, which model alias, and which text template ([Phrase](Phrase.md)) to render from each entity. + +A collection of these is what [Settings](Settings.md) persists. + +## Propriétés + +| Nom de propriété | Type | Description | +| ---------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------- | +| `dataclassName` | Text | Name of the target dataclass. | +| `vectorName` | Text | Name of the `4D.Vector` field on that dataclass. | +| `modelAlias` | Text | Embedding model alias (e.g. `"text-embedding-3-small"`). | +| `phrase` | [Phrase](Phrase.md) | Compiled template used to build the text that will be embedded. | +| `autoInvalidate` | Boolean | Controls automatic invalidation on entity save. Default: `True`. | + +## Class constructor + +Create a definition. + +| Nom de l'argument | Type | Description | +| ----------------- | ---- | -------------------------------------------------------------------------------------------------- | +| *dataclassName* | Text | Name of the target dataclass. | +| *vectorName* | Text | Name of the target vector field. | +| *modelAlias* | Text | Embedding model alias. | +| *phraseTemplate* | Text | Phrase template with `{field}` placeholders — compiled into a [Phrase](Phrase.md). | + +```4d +var $def:=cs.EmbeddingStudio.Definition.new(\ + "Students"; \ + "student_vector_1"; \ + "text-embedding-3-small"; \ + "Student {firstName} {lastName}") +``` + +## Propriétés calculées + +### hasDefinition + +**hasDefinition** : Boolean *(read-only)* + +Returns `True` if at least a model or a phrase template has been set. A definition without either has no content to process. + +```4d +If ($def.hasDefinition) + // worth validating further +End if +``` + +## Fonctions + +### validate() + +**validate**( *settings* : Settings ) : Object + +Validates the definition against the live datastore model and the known embedding models. All errors are collected before returning — the result always describes the full set of problems found. + +| Argument | Type | Description | +| ----------------------- | ------------------------------- | ------------------------------------------------------------------------------------------------------------ | +| *settings* | [Settings](Settings.md) \| Null | Used to pass phrase validation options. Pass `Null` to skip phrase options. | +| Résultat de la fonction | Object | `{success: Boolean, errors: Collection}` where each error is `{field: Text, message: Text}`. | + +Checked in order: + +| Check | `field` value | +| ------------------------------------ | ----------------- | +| `dataclassName` is not empty | `"dataclassName"` | +| `vectorName` is not empty | `"vectorName"` | +| `modelAlias` is set and recognised | `"modelAlias"` | +| Dataclass exists in `ds` | `"dataclassName"` | +| Vector field exists | `"vectorName"` | +| Field type is `4D.Vector` | `"vectorName"` | +| Phrase template is not empty | `"phrase"` | +| Phrase keys resolve in the dataclass | `"phrase"` | + +The first two checks (identity) return immediately on failure; the remaining checks accumulate so all problems are reported in one pass. + +```4d +var $result:=$def.validate(cs.EmbeddingStudio.Settings.new()) + +If (Not($result.success)) + var $err : Object + For each ($err; $result.errors) + TRACE // $err.field, $err.message + End for each +End if +``` + +### invalidateVectors() + +**invalidateVectors**() : Object + +Marks all already-computed entities for re-embedding, forcing a full rebuild on the next run. Only entities that already have a vector value are processed — entities with a `Null` vector are skipped. + +Useful during development or after a model/phrase change to trigger a clean rebuild of all vectors. + +The strategy depends on whether a companion `_dirty` field exists on the dataclass: + +| Companion `_dirty` field | Action taken | +| ------------------------ | -------------------------------------------------------------- | +| Present | Sets `_dirty` to `True` — vector is left untouched | +| Absent | Nullifies the vector field | + +| Argument | Type | Description | +| ----------------------- | ------ | ------------------------------------------------------------------ | +| Résultat de la fonction | Object | `{updated: Integer, skipped: Integer, errors: Collection of Text}` | + +- `updated` — number of entities successfully marked +- `skipped` — number of entities that could not be saved +- `errors` — one entry per save failure, formatted as `"DataclassName: statusText"` + +```4d +var $result:=$def.invalidateVectors() + +If ($result.skipped > 0) + var $e : Text + For each ($e; $result.errors) + // $e + End for each +End if +// → { updated: 42; skipped: 0; errors: [] } +``` + +### toObject() + +**toObject**() : Object + +Returns a plain object suitable for JSON persistence. The phrase is flattened to its template text. + +| Argument | Type | Description | +| ----------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------- | +| Résultat de la fonction | Object | `{version, dataclassName, vectorName, modelAlias, phrase, autoInvalidate}` where `phrase` is the template string. | + +```4d +$def.toObject() +// → { version: 0; dataclassName: "Students"; vectorName: "student_vector_1"; +// modelAlias: "text-embedding-3-small"; phrase: "Student {firstName} {lastName}"; +// autoInvalidate: true } +``` + +## Automatic invalidation + +`autoInvalidate` controls whether save-time automatic invalidation is enabled for this definition. + +- `True` (default): when relevant attributes change on an entity save, vectors are automatically invalidated. +- `False`: save-time automatic invalidation is skipped for this definition. + +This setting does not affect manual invalidation via `invalidateVectors()`. + +## Dirty flag convention + +The pipeline in [Process](Process.md) will recompute an entity whenever the target vector is `Null`, or when a sibling field `_dirty` exists on the dataclass and is `True`. + +Declaring the dirty flag is optional — when absent, only the null-vector case triggers recomputation. When present, it is cleared automatically on successful save. + +## Voir également + +- [Settings](Settings.md) +- [Process](Process.md) +- [Phrase](Phrase.md) From 2f84a651b1d100ca338e2ee0c84b11a5b0c30d06 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:39:24 +0100 Subject: [PATCH 046/195] embedder.md French --- .../embedding-studio/Classes/Embedder.md | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Embedder.md diff --git a/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Embedder.md b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Embedder.md new file mode 100644 index 00000000000000..2d8e5d846103ad --- /dev/null +++ b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Embedder.md @@ -0,0 +1,96 @@ +--- +id: embedder +title: Embedder +--- + +# Embedder + +The `Embedder` class is a thin wrapper around [4D AIKit](https://developer.4d.com/docs/aikit/Classes/openai) focused on embeddings. It exposes two functions — one for a single text, one for a batch — and handles retries with exponential backoff (respecting the `Retry-After` header when present). + +It is stateless beyond configuration and safe to share between processes. + +## Propriétés + +| Nom de propriété | Type | Description | +| ---------------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | +| `client` | cs.AIKit.OpenAI | The underlying AIKit client used for HTTP requests. | +| `maxRetries` | Integer | Maximum number of retries on transient errors. Default: `3`. | +| `backoffMs` | Integer | Base delay (ms) between retries. Doubled each attempt. | + +## Class constructor + +Create a embedder. All options are optional. + +| Nom de l'argument | Type | Description | +| ----------------- | ------ | ----------------------------------------------------------------------------- | +| *options* | Object | `{client, maxRetries, backoffMs}` — any field may be omitted. | + +```4d +// Default — uses cs.AIKit.OpenAI.new() internally +var $proc:=cs.EmbeddingStudio.Embedder.new() + +// Provide a pre-configured AIKit client (custom API key, base URL, etc.) +var $client:=cs.AIKit.OpenAI.new({apiKey: "…"; baseURL: "https://server.ai"}) +var $proc:=cs.EmbeddingStudio.Embedder.new({client: $client; maxRetries: 5; backoffMs: 1000}) +``` + +> If the 4D AIKit component is not loaded (or is too old to provide `OpenAIProviders`), the constructor still succeeds with a `Null` client, and the first `embed()` / `embedBatch()` call throws an error whose `message` explains what is missing and whose `isAIKitMissing` property is `True`. + +## Fonctions + +### embed() + +**embed**(*text* : Text ; *model* : Text) : [cs.EmbeddingStudio.EmbedderResult](EmbedderResult.md) + +Embed a single text. Returns a typed result with the embedding vector, token usage, and rate-limit state. + +| Argument | Type | Description | +| ----------------------- | -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| *text* | Text | The text to vectorize. | +| *model* | Text | The embedding model to use (e.g. `"text-embedding-3-small"`). | +| Résultat de la fonction | [cs.EmbeddingStudio.EmbedderResult](EmbedderResult.md) | Typed wrapper — `.vector` holds the embedding, `.promptTokens` / `.totalTokens` hold usage, rate-limit fields are flat camelCase. | + +Throws if retries are exhausted or the API returns a non-retryable error. + +```4d +var $result:=$proc.embed("it rains cats and dogs"; "text-embedding-3-small") +// $result.vector → 4D.Vector +// $result.promptTokens → Integer +// $result.totalTokens → Integer +// $result.remainingTokens → Integer (-1 if unknown) +``` + +### embedBatch() + +**embedBatch**(*texts* : Collection ; *model* : Text) : [cs.EmbedderResult](EmbedderResult.md) + +Embed a collection of texts in a single API call. Returns a typed result with vectors in the same order as inputs, token usage, and rate-limit state. + +| Argument | Type | Description | +| ----------------------- | ------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------- | +| *texts* | Collection | Collection of Text to vectorize. Empty or `Null` returns an empty result. | +| *model* | Text | The embedding model to use. | +| Résultat de la fonction | [cs.EmbedderResult](EmbedderResult.md) | Typed wrapper — `.vectors` holds the embeddings collection, token and rate-limit fields are flat camelCase. | + +```4d +var $result:=$proc.embedBatch(["hello"; "world"]; "text-embedding-3-small") +// $result.vectors[0] → 4D.Vector for "hello" +// $result.vectors[1] → 4D.Vector for "world" +// $result.totalTokens → Integer (sum for the batch) +// $result.remainingTokens → Integer (after this call) +``` + +## Retry policy + +Transient errors (HTTP 408, 409, 429, 5xx) are retried up to `maxRetries` times. + +- If the response carries a `Retry-After` or `retry-after-ms` header, the embedder waits that long. +- Otherwise, it waits `backoffMs * 2^attempt`. + +Non-retryable errors are thrown immediately — see [OpenAIError](https://developer.4d.com/docs/aikit/Classes/openaierror) for the thrown shape. + +## Voir également + +- [EmbedderResult](EmbedderResult.md) +- [Process](Process.md) +- [OpenAIEmbeddingsAPI](https://developer.4d.com/docs/aikit/Classes/openaiembeddingsapi) (AIKit) From 52d9c4a4aa6815c025c9455f706bb1ca07b9bf72 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:39:26 +0100 Subject: [PATCH 047/195] embedderresult.md French --- .../Classes/EmbedderResult.md | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/EmbedderResult.md diff --git a/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/EmbedderResult.md b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/EmbedderResult.md new file mode 100644 index 00000000000000..853bd158d5fd4d --- /dev/null +++ b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/EmbedderResult.md @@ -0,0 +1,80 @@ +--- +id: embedderresult +title: EmbedderResult +--- + +# EmbedderResult + +Typed wrapper for `Embedder.embed()` and `Embedder.embedBatch()` responses. Normalizes OpenAI's snake_case API keys (`prompt_tokens`, `total_tokens`) to camelCase properties, and flattens the nested rate-limit structure into direct properties. + +A single class handles both single and batch results — `embed()` populates `.vector`, `embedBatch()` populates `.vectors`. + +## Propriétés + +### Embedding results + +| Propriété | Type | Par défaut | Description | +| --------- | ------------------------- | ---------- | ------------------------------------------------------------------------------ | +| `vector` | 4D.Vector | Null | Single embedding result. Null for batch calls. | +| `vectors` | Collection | `[]` | Batch embedding results. | + +### Token usage + +| Propriété | Type | Par défaut | Description | +| -------------- | ------- | ---------- | -------------------------------------------------------------------- | +| `promptTokens` | Integer | `0` | Input tokens consumed. | +| `totalTokens` | Integer | `0` | Total tokens consumed (in + out). | + +### Rate-limit state + +| Propriété | Type | Par défaut | Description | +| ------------------- | ------- | ---------- | ------------------------------------------------------------------------------------------------------------------- | +| `remainingTokens` | Integer | `-1` | Tokens left in the current window. `-1` = unknown. | +| `remainingRequests` | Integer | `-1` | Requests left in the current window. `-1` = unknown. | +| `limitTokens` | Integer | `0` | TPM ceiling for the account. | +| `limitRequests` | Integer | `0` | RPM ceiling for the account. | +| `resetTokens` | Text | `""` | Time until token bucket refills (e.g. `"6m0s"`). | +| `resetRequests` | Text | `""` | Time until request bucket refills (e.g. `"1s"`). | + +## Class constructor + +```4d +// From a real API result (used by Embedder internally) +var $result:=cs.EmbedderResult.new($aikitResult; True) // batch +var $result:=cs.EmbedderResult.new($aikitResult; False) // single + +// Empty result (no API call — e.g. empty batch) +var $result:=cs.EmbedderResult.new() +``` + +| Argument | Type | Description | +| --------- | ------- | ------------------------------------------------------------------------------------------------------------ | +| *result* | Object | An object with `.vector`/`.vectors`, `.usage`, `.rateLimit` (duck-typed). | +| *isBatch* | Boolean | `True` to read `.vectors`, `False` to read `.vector`. | + +The constructor accepts any object that exposes the expected shape — it does not require a specific class. This makes it easy to construct in tests. + +## Utilisation + +```4d +// Single embedding +var $r:=$embedder.embed("hello world"; "text-embedding-3-small") +$r.vector // → 4D.Vector +$r.promptTokens // → 6 +$r.totalTokens // → 6 + +// Batch embedding +var $r:=$embedder.embedBatch(["hello"; "world"]; "text-embedding-3-small") +$r.vectors.length // → 2 +$r.totalTokens // → 10 + +// Rate-limit awareness +$r.remainingTokens // → 148230 (or -1 if not yet known) +$r.resetTokens // → "6m0s" +``` + +## Voir également + +- [Embedder](Embedder.md) — creates EmbedderResult instances +- [ProcessResult](ProcessResult.md) — run-level report that accumulates EmbedderResult usage +- [Rate Limiting](../RateLimit.md) — how the pipeline uses rate-limit fields for throttling and batch sizing From 02d0cf752dc304ed8fd94887eb8fb420c48df537 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:39:29 +0100 Subject: [PATCH 048/195] phrase.md French --- .../embedding-studio/Classes/Phrase.md | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Phrase.md diff --git a/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Phrase.md b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Phrase.md new file mode 100644 index 00000000000000..7f8a82daec5ef0 --- /dev/null +++ b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Phrase.md @@ -0,0 +1,117 @@ +--- +id: phrase +title: Phrase +--- + +# Phrase + +The `Phrase` class is a lightweight template engine: a template with `{variable}` placeholders is compiled once, then rendered efficiently against different data objects. + +## Propriétés + +| Nom de propriété | Type | Description | +| ---------------- | ---------- | ---------------------------------------------------------------------------------------------------------------------- | +| `template` | Text | Computed — returns the original template string. | +| `keys` | Collection | Computed — returns the variable names found in the template, dot-notation keys joined back to strings. | + +## Class constructor + +Compile a template. Compilation walks the template once and extracts static parts and variable paths. + +| Nom de l'argument | Type | Description | +| ----------------- | ---- | ---------------------------------------------------------- | +| *template* | Text | Template string with `{variable}` markers. | + +```4d +var $tpl:=cs.EmbeddingStudio.Phrase.new("Hello {firstName}, you study at {schoolName}.") +$tpl.keys // → ["firstName"; "schoolName"] +``` + +## Fonctions + +### render() + +**render**(*data* : Object) : Text + +Render the compiled template by replacing variables with values from *data*. Missing keys produce an empty string. + +| Argument | Type | Description | +| ----------------------- | ------ | ------------------------------------------------------------------------------------------------------ | +| *data* | Object | A plain object or a 4D.Entity whose fields supply the variable values. | +| Résultat de la fonction | Text | The rendered text. | + +```4d +var $text:=$tpl.render({firstName: "Alice"; school: {name: "MIT"}}) +// → "Hello Alice, you study at MIT." + +// Works directly on entities +$text:=$tpl.render(ds.Students.first()) +``` + +### validate() + +**validate**(*dataclass* : 4D.DataClass ; *options* : Object) : Object + +Validate that all keys in the phrase can be resolved against the given dataclass. Walks dot-notation paths through N:1 / 1:1 relations. + +| Argument | Type | Description | +| ----------------------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| *dataclass* | 4D.DataClass | The dataclass to validate against. | +| *options* | Object | Optional validation flags (see below). All default to `False` — storage kind only. | +| Résultat de la fonction | Object | `{success: Boolean, errors: Collection of {key, message}}`. | + +#### Options + +| Champ | Type | Par défaut | Description | +| ----------------- | ------- | ---------- | ----------------------------------------------------------------------------------------------------- | +| `allowRelations` | Boolean | `False` | Allow dot-notation paths through N:1 / 1:1 relations. | +| `allowCalculated` | Boolean | `False` | Allow calculated attributes. | +| `allowAlias` | Boolean | `False` | Allow alias attributes. | + +```4d +var $tpl:=cs.EmbeddingStudio.Phrase.new("{firstName} at {school.name}") + +// Storage-only validation — fails because {school.name} uses a relation +var $v:=$tpl.validate(ds.Students) +// $v.success → False +// $v.errors → [{key: "school.name"; message: "..."}] + +// Allow relations +$v:=$tpl.validate(ds.Students; {allowRelations: True}) +// $v.success → True +``` + +#### Rejected shapes + +Regardless of options: + +- Attributes that do not exist on the dataclass. +- Attributes whose class ID is `4D.Vector`. +- 1:N relations (`relatedEntities`) as the final key. +- Intermediate segments that are not relations (when dot-notation is used). + +### attributs() + +**attributes**(*dataclass* : 4D.DataClass) : Collection + +Resolves each phrase key against *dataclass* and returns an ordered Collection of ORDA attribute descriptor objects, one per key in the same order as `.keys`. For dot-notation paths, traverses N:1 relations to reach the final attribute. Pushes `Null` for any key whose path cannot be resolved (unknown attribute or non-relation intermediate segment). + +| Argument | Type | Description | +| ----------------------- | ---------------------------- | -------------------------------------------------------------------------------------------- | +| *dataclass* | 4D.DataClass | The dataclass to resolve attributes against. | +| Résultat de la fonction | Collection | Ordered collection of ORDA attribute objects (or `Null`). | + +Each resolved entry is an ORDA attribute descriptor with `.name`, `.kind`, and more — see [DataClass.attributeName](https://developer.4d.com/docs/API/DataClassClass#attributename). + +```4d +var $tpl:=cs.EmbeddingStudio.Phrase.new("{firstName} graduated from {school.name}") +var $attrs:=$tpl.attributes(ds.Students) +// $attrs[0].name → "firstName" $attrs[0].type → "string" +// $attrs[1].name → "name" $attrs[1].type → "string" (from School dataclass) +// $attrs[1] is Null if school.name could not be resolved +``` + +## Voir également + +- [Definition](Definition.md) — holds a `Phrase`. +- [StudioEmbedder.render()](StudioEmbedder.md#render) — renders a phrase for an entity, non-persisting. From 7345b78982e98977c7450719b5d44b7f3a87899f Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:39:32 +0100 Subject: [PATCH 049/195] process.md French --- .../embedding-studio/Classes/Process.md | 188 ++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Process.md diff --git a/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Process.md b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Process.md new file mode 100644 index 00000000000000..e15505f9d524e5 --- /dev/null +++ b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Process.md @@ -0,0 +1,188 @@ +--- +id: process +title: Process +--- + +# Process + +The `Process` class orchestrates the full embedding pipeline: it browses 4D entities, renders text from their fields using a [Definition](Definition.md), calls the embeddings API through an [Embedder](Embedder.md), and stores the resulting `4D.Vector` on each entity. + +To render or embed on demand without persistence (search query vectors, phrase previews), see [StudioEmbedder](StudioEmbedder.md). + +## Propriétés + +| Nom de propriété | Type | Description | +| ---------------- | ----------------------- | -------------------------------------------------------------------------------------------------------- | +| `propriétés` | [Settings](Settings.md) | The settings (definitions, batch size, phrase validation options). | +| `embedder` | [Embedder](Embedder.md) | The API-calling engine. Stateless and swappable. | +| `options` | Object | Runtime options object (see [Options object](#options-object) below). | + +### Options object + +| Touche | Type | Description | +| ---------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `onProgress` | 4D.Function | Called after each processed chunk with `{definition, report}`. | +| `onSuccess` | 4D.Function | Called once at the end when `report.success = True`, with `{report, success, errors}`. | +| `onError` | 4D.Function | Called once at the end when `report.success = False`, with `{report, success, errors}`. | +| `onTerminate` | 4D.Function | Called once at the end in all cases (after `onSuccess`/`onError`), with `{report, success, errors}`. | +| `dryRun` | Boolean | If `True`, runs selection/filter logic but skips API calls and entity saves. | +| `force` | Boolean | If `True`, recomputes every entity ignoring null-vector / dirty-flag filter. | +| `debug` | Boolean | If `True`, emits additional diagnostic log entries. | +| `pauseIndexes` | Boolean | If `True`, index maintenance on the target table is paused for the duration of a `processEntitySelection` batch run, then resumed right after (or on early exit/critical error). Default `False` — indexes are left alone. See [Pausing indexes](#pausing-indexes) before enabling it. | +| `waitForIndexes` | Boolean | Only used with `pauseIndexes`. If `True`, resuming indexes blocks until they are rebuilt. Default `False` — resume is asynchronous (indexes rebuilt in the background). | +| `shouldCancel` | 4D.Function | Predicate called between chunks during selection processing. Returning `True` stops the run gracefully (cooperative cancel) — what [`Scheduler.cancel()`](Scheduler.md#cancel) uses. | +| `embedder` | [Embedder](Embedder.md) | Inject a custom embedder (otherwise a default one is created). | + +## Class constructor + +Create an instance of the orchestrator. + +| Nom de l'argument | Type | Description | +| ----------------- | ----------------------- | ----------------------------------------------------------------------------------------------------------------------- | +| *settings* | [Settings](Settings.md) | Optionnel. If omitted, settings are loaded from the default `Settings/embeddings.json`. | +| *options* | Object | Optional runtime options (see table above). | + +```4d +// Simplest — uses defaults +var $p:=cs.EmbeddingStudio.Process.new() + +// With explicit settings +var $p:=cs.EmbeddingStudio.Process.new($settings) + +// With options +var $p:=cs.EmbeddingStudio.Process.new($settings; {\ + force: True; \ + onProgress: Formula(ALERT("chunk done: "+String($1.report.entitiesUpdated)))}) +``` + +## Batch processing functions + +### process() + +**process**(*definition* : Variant) : [ProcessResult](ProcessResult.md) + +Process one, many, or all [Definition](Definition.md) entries against the full content of their target dataclass. + +| Argument | Type | Description | +| ----------------------- | -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | +| *définition* | `Null`, [Definition](Definition.md), `4D.DataClass`, plain object, or Collection | See [process() resolution](#process-resolution). `Null` → every definition in settings. | +| Résultat de la fonction | [ProcessResult](ProcessResult.md) | Statistics and per-error breakdown. | + +```4d +// Every definition in settings +var $r:=$p.process() + +// One specific definition +var $r:=$p.process($def) + +// Multiple definitions +var $r:=$p.process([$def1; $def2]) + +// Every definition configured for a whole dataclass +var $r:=$p.process(ds.Students) + +// A plain descriptor — looked up in settings, or built on the fly +var $r:=$p.process({dataclassName: "Students"; vectorName: "student_vector_1"}) + +// Any mix — each item is resolved independently and flattened +var $r:=$p.process([ds.Students; $def; {dataclassName: "School"; vectorName: "school_vector_1"}]) +``` + +#### process() resolution + +`process()` has no entity context, so it resolves each input into concrete [Definition](Definition.md) objects directly from settings: + +| Zone de saisie | Comportement | +| -------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `Null` | Every definition in settings. | +| [Definition](Definition.md) | Used as-is. | +| `4D.DataClass` (e.g. `ds.Students`) | Every definition in settings whose `dataclassName` matches that dataclass. | +| `{dataclassName: "..."; vectorName: "..."}` | The matching saved definition, or — if none is found — a new `Definition` built from the object's fields (`modelAlias`, `phrase.template`). | +| Collection | Each item is resolved with the rules above and the results are **flattened** into one collection (a `4D.DataClass` item can expand to several definitions). Unsupported items are dropped. | +| Anything else | Empty result. | + +### processEntity() + +**processEntity**(*entity* : 4D.Entity ; *definition* : Variant) : [ProcessResult](ProcessResult.md) + +Process a single entity. Cheap path — no chunking, no server-side filter. + +| Argument | Type | Description | +| ----------------------- | ----------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | +| *entity* | 4D.Entity | The entity to (re)compute vectors for. | +| *définition* | `Null`, [Definition](Definition.md), Collection, or `{vectorName: ...}` | See [resolution rules](#definition-resolution). `Null` infers from entity's dataclass. | +| Résultat de la fonction | [ProcessResult](ProcessResult.md) | Statistics and per-error breakdown. | + +```4d +// Auto-resolve every definition matching this entity's dataclass +var $r:=$p.processEntity($entity) + +// Specific definition +var $r:=$p.processEntity($entity; $def) + +// By vector name only (looked up in settings against the entity's dataclass) +var $r:=$p.processEntity($entity; {vectorName: "student_vector_1"}) +``` + +### processEntitySelection() + +**processEntitySelection**(*selection* : 4D.EntitySelection ; *definition* : Variant) : [ProcessResult](ProcessResult.md) + +Workhorse path for large jobs. Chunks the selection by `settings.batchSize`, sends one API call per chunk, saves each entity individually. + +| Argument | Type | Description | +| ----------------------- | ----------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | +| *selection* | 4D.EntitySelection | Entities to process. Pre-filtering by the caller is allowed; the pipeline still applies its null/dirty filter. | +| *définition* | `Null`, [Definition](Definition.md), Collection, or `{vectorName: ...}` | See [resolution rules](#definition-resolution). | +| Résultat de la fonction | [ProcessResult](ProcessResult.md) | Statistics and per-error breakdown. | + +```4d +var $todo:=ds.Students.query("country = :1"; "FR") +var $r:=$p.processEntitySelection($todo; $def) +``` + +### Definition resolution (entity context) + +The polymorphic *definition* argument accepted by `processEntity` and `processEntitySelection`. Unlike [`process()`](#process-resolution), these have an entity/selection to infer the dataclass from, so a bare `{vectorName: "..."}` stub is enough: + +| Zone de saisie | Comportement | +| --------------------------- | ----------------------------------------------------------------------------------------------- | +| `Null` | All definitions in settings whose `dataclassName` matches the entity/selection. | +| [Definition](Definition.md) | Used as-is; the `dataclassName` must match the entity/selection. | +| `{vectorName: "..."}` | Looked up in settings by `vectorName` against the entity/selection dataclass. | +| Collection | Each item resolved using the rules above; mismatches are silently dropped. | + +### Recompute rules + +An entity is (re)computed when **any** of these are true: + +- The target vector field is `Null`. +- A sibling field named `{vectorName}_dirty` exists and is `True`. +- The `force` option is `True`. + +The dirty field is optional per dataclass. If it doesn't exist, only the null-vector case triggers recomputation. Upon successful save, the pipeline clears the dirty flag (when present). + +For `processEntitySelection`, the filter is executed as a server-side ORDA query before any API call, so only the rows that actually need work are loaded into memory. For `processEntity`, the check is done in memory on the already-fetched entity. + +### Pausing indexes + +By default the indexes of the target table are maintained normally while vectors are saved. With the `pauseIndexes` option, a batch run calls [`PAUSE INDEXES`](https://developer.4d.com/docs/commands/pause-indexes) on the table before writing and [`RESUME INDEXES`](https://developer.4d.com/docs/commands/resume-indexes) once done (also on early exit or critical error). + +Be aware of what these commands do: + +- `PAUSE INDEXES` disables **all** the indexes of the table (except the primary key index), not only the vector ones: every index on every other field of the table is paused too. While paused, queries and sorts on that table, including those of other processes, run without any index. +- `RESUME INDEXES` then **rebuilds all these indexes**, for the whole table, not only for the records that were recomputed. On a table with several indexes, this rebuild can cost more than the time saved during the writes. +- With `waitForIndexes` set to `True`, the run blocks until the rebuild completes; otherwise the rebuild runs in the background. +- These commands cannot run on a 4D remote client: there the option is ignored (a warning is logged once) and the recalculation runs with indexes maintained normally. Run it on the server, for example through the [Scheduler](Scheduler.md), to use it. + +Enable it only for large recalculations, such as computing the vectors of a whole table for the first time. + +## Voir également + +- [StudioEmbedder](StudioEmbedder.md) +- [Settings](Settings.md) +- [Definition](Definition.md) +- [Embedder](Embedder.md) +- [ProcessResult](ProcessResult.md) +- [Phrase](Phrase.md) +- [Rate Limiting](../RateLimit.md) From f822b53ee12d048e68908c24319fb9d2342c3544 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:39:34 +0100 Subject: [PATCH 050/195] processerror.md French --- .../embedding-studio/Classes/ProcessError.md | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/ProcessError.md diff --git a/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/ProcessError.md b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/ProcessError.md new file mode 100644 index 00000000000000..3dfb9471b01545 --- /dev/null +++ b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/ProcessError.md @@ -0,0 +1,87 @@ +--- +id: processerror +title: ProcessError +--- + +# ProcessError + +A `ProcessError` is one structured, typed entry in the `errors` collection of a [ProcessResult](ProcessResult.md). Its typed fields let callers react to a specific failure mode programmatically — retry transient failures, abort on a fatal model outage, count save failures — without parsing message strings. + +You read these instances from [ProcessResult](ProcessResult.md)`.errors`, directly or through its query helpers (`errorsByCode`, `errorsByScope`, `retryableErrors`). + +## Propriétés + +| Nom de propriété | Type | Description | +| ---------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `portée` | Text | Where the error originated: `"pipeline"`, `"definition"`, `"chunk"`, or `"entity"`. | +| `severity` | Text | `"warning"`, `"error"`, or `"fatal"`. Determined by `code` (see [ProcessErrorCode](ProcessErrorCode.md)). | +| `code` | Integer | Machine-readable error code — compare against the constants on [ProcessErrorCode](ProcessErrorCode.md). | +| `ref` | Variant | Scope-dependent reference: `"Dataclass.vector"`, an entity primary key, a model alias, or `Null`. | +| `message` | Text | Human-readable, localized message. | +| `retryable` | Boolean | `True` when re-running the operation could plausibly succeed. Determined by `code`. | + +### scope values + +| Portée | Description | +| -------------- | -------------------------------------------------------------------------------------------------------------------------- | +| `"pipeline"` | Top-level failure affecting the whole run (null selection, a model became unavailable). | +| `"definition"` | A [Definition](Definition.md) failed validation or was skipped. | +| `"chunk"` | A whole batch (chunk) of entities failed in a single API call. | +| `"entity"` | A single entity failed to embed or save. | + +### severity values + +| Severity | Description | +| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `"warning"` | Non-blocking — does **not** make [ProcessResult](ProcessResult.md)`.success` false. | +| `"error"` | A recoverable failure scoped to one entity, chunk, or definition. Makes `success` false. | +| `"fatal"` | Blocks the rest of the run (e.g. the model is unavailable). Also surfaces via `hasFatal`. | + +## Propriétés calculées + +| Propriété | Type | Description | +| --------- | ------- | ------------------------------------------------- | +| `isFatal` | Boolean | `True` when `severity = "fatal"`. | + +## Fonctions + +### toObject() + +**toObject**() : Object + +Returns a plain object (`{scope, severity, code, ref, message, retryable}`) suitable for logging or JSON serialization. + +| Argument | Type | Description | +| ----------------------- | ------ | ------------------------------------------------------ | +| Résultat de la fonction | Object | A JSON-friendly snapshot of the error. | + +## Exemple + +React to failures by type rather than by message text: + +```4d +var $r:=$p.process() + +If (Not($r.success)) + + If ($r.hasFatal) + ALERT("A model became unavailable — aborting until it recovers.") + End if + + var $codes:=cs.EmbeddingStudio.ProcessErrorCode.me + var $saveFailures:=$r.errorsByCode($codes.SAVE_FAILED) + If ($saveFailures.length>0) + ALERT(String($saveFailures.length)+" entities failed to save.") + End if + + // Collect entity keys worth retrying later + var $retry:=$r.retryableErrors().query("scope = :1"; "entity").extract("ref") + +End if +``` + +## Voir également + +- [ProcessErrorCode](ProcessErrorCode.md) — the catalogue of `code` values and their severity/retryability. +- [ProcessResult](ProcessResult.md) — owns the `errors` collection and the query helpers (`errorsByCode`, `errorsByScope`, `retryableErrors`). +- [Process](Process.md) — produces these errors. From 3a1eca51e6ccfea821a6736c3427004e9799f394 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:39:36 +0100 Subject: [PATCH 051/195] processerrorcode.md French --- .../Classes/ProcessErrorCode.md | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/ProcessErrorCode.md diff --git a/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/ProcessErrorCode.md b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/ProcessErrorCode.md new file mode 100644 index 00000000000000..44567dbacab051 --- /dev/null +++ b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/ProcessErrorCode.md @@ -0,0 +1,55 @@ +--- +id: processerrorcode +title: ProcessErrorCode +--- + +# ProcessErrorCode + +A `singleton` exposing the stable, machine-readable error codes carried by [ProcessError](ProcessError.md) `.code`, plus a `meta()` lookup mapping each code to its default `severity` and `retryable` flag. Compare against these constants instead of parsing message strings. + +Access the shared instance via `.me`: + +```4d +var $codes:=cs.EmbeddingStudio.ProcessErrorCode.me +If ($error.code=$codes.SAVE_FAILED) + // … +End if +``` + +## Codes + +| Constante | Valeur | Default severity | Retryable | Raised when… | +| ----------------------- | ------ | ---------------- | --------- | ------------------------------------------------------------------------------------------------- | +| `NULL_INPUT` | 100 | error | Non | A required entity, selection, or definition was `Null`. | +| `INVALID_DEFINITION` | 101 | error | Non | A value is not a usable [Definition](Definition.md) instance. | +| `VALIDATION_FAILED` | 102 | error | Non | `Definition.validate()` reported a problem. | +| `MODEL_UNAVAILABLE` | 200 | fatal | Oui | A critical API error made the model unusable for the rest of the run. | +| `MODEL_SKIPPED` | 201 | error | Oui | A definition was skipped because its model already failed critically. | +| `EMBED_FAILED` | 202 | error | Oui | A non-critical embedding call failed (single entity or chunk). | +| `VECTOR_COUNT_MISMATCH` | 300 | error | Non | The provider returned a different vector count than requested. | +| `SAVE_FAILED` | 400 | error | Oui | `entity.save()` failed (validation, lock, …). | + +Codes are grouped by hundreds: `1xx` input/configuration, `2xx` model/API, `3xx` data integrity, `4xx` persistence. Unknown codes resolve to `{severity: "error"; retryable: False; label: "UNKNOWN"}`. + +## Fonctions + +### meta() + +**meta**( $code : Integer ) : Object + +Returns the `severity` and `retryable` flag associated with a code — the same values carried by a [ProcessError](ProcessError.md) with that `code`. + +| Argument | Type | Description | +| ----------------------- | ------- | ----------------------------------------------------------------------- | +| `$code` | Integer | One of the code constants above. | +| Résultat de la fonction | Object | `{severity : Text; retryable : Boolean; label : Text}`. | + +```4d +var $m:=cs.EmbeddingStudio.ProcessErrorCode.me.meta(cs.EmbeddingStudio.ProcessErrorCode.me.MODEL_UNAVAILABLE) +// $m = {severity: "fatal"; retryable: True; label: "MODEL_UNAVAILABLE"} +``` + +## Voir également + +- [ProcessError](ProcessError.md) — carries a `.code` from this list. +- [ProcessResult](ProcessResult.md) — `errorsByCode()` filters errors by code. From 00dfa83ec542defcda31601fae9e604ce7b6e793 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:39:39 +0100 Subject: [PATCH 052/195] processresult.md French --- .../embedding-studio/Classes/ProcessResult.md | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/ProcessResult.md diff --git a/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/ProcessResult.md b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/ProcessResult.md new file mode 100644 index 00000000000000..855a11dff50861 --- /dev/null +++ b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/ProcessResult.md @@ -0,0 +1,91 @@ +--- +id: processresult +title: ProcessResult +--- + +# ProcessResult + +The `ProcessResult` class is the return value of every batch entry point of [Process](Process.md) (`process`, `processEntity`, `processEntitySelection`). It accumulates statistics, per-error breakdowns, and wall-clock duration. + +The orchestrator never throws out of its public batch API — failures are recorded here and the job continues. The caller decides what to do with them. + +## Propriétés + +| Nom de propriété | Type | Description | +| ---------------------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `definitionsProcessed` | Integer | Number of [Definition](Definition.md) entries processed. | +| `entitiesConsidered` | Integer | Number of entities that passed the "needs recompute" filter. | +| `entitiesUpdated` | Integer | Number of entities whose vector was successfully written and saved. | +| `entitiesSkipped` | Integer | Number of entities that could not be processed: individual embed or save errors, or whole-chunk API failures (those entities are left unchanged for the next run). | +| `apiCalls` | Integer | Number of embeddings API calls made. | +| `promptTokens` | Integer | Total prompt tokens consumed across all API calls in this run. | +| `totalTokens` | Integer | Total tokens consumed across all API calls in this run. | +| `durée` | Integer | Total duration of the job in milliseconds. | +| `errors` | Collection | List of [ProcessError](ProcessError.md) entries recorded during the run. | + +### Propriétés calculées + +| Propriété | Type | Description | +| ---------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `success` | Boolean | `True` when no `"error"` or `"fatal"` entry was recorded. `"warning"` entries do not fail the run. | +| `hasFatal` | Boolean | `True` when at least one `"fatal"` entry was recorded (e.g. a model became unavailable). | + +### Error entries + +Each item in `errors` is a [ProcessError](ProcessError.md) with `scope`, `severity`, `code`, `ref`, `message`, and `retryable`. See [ProcessError](ProcessError.md) for the field meanings and [ProcessErrorCode](ProcessErrorCode.md) for the `code` catalogue. + +## Fonctions + +### errorsByScope() + +**errorsByScope**( $scope : Text ) : Collection + +Errors filtered by `scope` (`"pipeline"`, `"definition"`, `"chunk"`, `"entity"`). + +### errorsByCode() + +**errorsByCode**( $code : Integer ) : Collection + +Errors filtered by machine-readable code — see [ProcessErrorCode](ProcessErrorCode.md). + +### retryableErrors() + +**retryableErrors**() : Collection + +Errors flagged `retryable` — re-running the operation could plausibly succeed. + +### toObject() + +**toObject**() : Object + +Returns a plain object suitable for logging or JSON serialization. + +| Argument | Type | Description | +| ----------------------- | ------ | ------------------------------------------------------- | +| Résultat de la fonction | Object | A JSON-friendly snapshot of the report. | + +```4d +var $r:=$p.process() +LOG EVENT(Into 4D log file; JSON Stringify($r.toObject())) +``` + +## Exemple + +```4d +var $r:=$p.processEntitySelection(ds.Students.all(); $def) + +If ($r.success) + ALERT("Updated "+String($r.entitiesUpdated)+" students in "+String($r.duration)+" ms") +Else + var $err : Object + For each ($err; $r.errors) + ALERT("[" + $err.scope + "] " + String($err.ref) + " — " + $err.message) + End for each +End if +``` + +## Voir également + +- [Process](Process.md) +- [ProcessError](ProcessError.md) — the typed shape of each `errors` entry. +- [ProcessErrorCode](ProcessErrorCode.md) — the `code` catalogue. From 9c763db82c7f9769d1c151208ac4c395fbf5bc82 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:39:41 +0100 Subject: [PATCH 053/195] scheduler.md French --- .../embedding-studio/Classes/Scheduler.md | 369 ++++++++++++++++++ 1 file changed, 369 insertions(+) create mode 100644 i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Scheduler.md diff --git a/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Scheduler.md b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Scheduler.md new file mode 100644 index 00000000000000..67c5622ffdd04a --- /dev/null +++ b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Scheduler.md @@ -0,0 +1,369 @@ +--- +id: périodicité +title: Périodicité +--- + +# Périodicité + +The `Scheduler` class is the public entry point for the **automated embedding recalculation** service. It maintains a background task that runs the embedding pipeline (see [Process](Process.md)) at a configured interval or a fixed daily time, guarantees that **at most one** recalculation batch runs at a time, and exposes runtime status for administration and monitoring interfaces. + +It is a **singleton**, accessed through `cs.EmbeddingStudio.Scheduler.me`. + +The scheduler runs two named workers: + +| Worker | Rôle | +| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `EmbeddingStudioScheduler` | Background loop that re-reads the config each cycle, computes the next run and fires when due. | +| `EmbeddingStudio` | Execution worker that runs one recalculation batch (shared with the Studio UI, so scheduled and manual runs are serialized). | + +## Configuration + +The configuration lives under the `scheduler` key of `Settings/embeddings.json`: + +```json +{ + "scheduler": { + "mode": "interval", + "intervalHours": 3, + "startFrom": "reference", + "startReference": "2026-09-02T14:00:00", + "dailyTime": "00:00" + } +} +``` + +| Touche | Type | Values / range | Description | +| ---------------- | ------- | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `mode` | Text | `"never"` \| `"interval"` \| `"daily"` | Scheduling mode. Absent/unknown ⇒ `never` (no automatic run). | +| `intervalHours` | Integer | `1`..`24` | Interval mode only. Out-of-range ⇒ default `3`. | +| `startFrom` | Text | `"reference"` \| `"lastExecution"` | Interval mode only. Anchor of the interval (see below). Anything other than `"lastExecution"` — including the legacy `"now"` — is normalized to `reference`. Default `reference`. | +| `startReference` | Text | `"YYYY-MM-DDThh:mm:ss"` | Interval mode with `startFrom = "reference"`. Fixed instant the interval counts from. Absent ⇒ the moment the scheduler was armed, then the current instant. | +| `dailyTime` | Text | `"HH:MM"` | Daily mode only. Time of day for the recalculation. Default `"00:00"`. | + +**Interval anchoring (`startFrom`)** + +- `reference` — **fixed rate**: the interval is anchored on the fixed `startReference` instant, so the slots do not drift whatever a run's duration is. Slots are advanced by `intervalHours` until the first one strictly after now. When `startReference` is absent (a fresh or legacy config), the anchor falls back to the moment the scheduler was armed (`start()`), then to the current instant. +- `lastExecution` — **fixed delay**: the interval is anchored on the last completed recalculation. If the elapsed time since the last run already exceeds the interval (e.g. after a restart), the run is triggered immediately. If there is no prior run, it runs immediately. + +The effective configuration is read from the file on **every loop cycle**, so changes take effect without restarting the scheduler. + +## Starting the scheduler + +Configuring a `mode` is **not enough**: nothing runs until the scheduler is started. There are two ways to get there, and which one applies depends on a single option of your host database. + +### 1. Automatic — let the host database start it + +In the host database, open **Settings > Security** and check **"Execute 'On Host Database Event' method of the components"** (it is *unchecked* by default, for security reasons). + +With this option on, 4D Embedding Studio starts the scheduler by itself when the host database opens, and stops it when the host database closes. There is nothing else to write. + +Use [`autoStart()`](#autostart) to check whether the option is on: + +```4d +If (Not(cs.EmbeddingStudio.Scheduler.me.autoStart())) + // the option is off — I must start the scheduler myself + cs.EmbeddingStudio.Scheduler.me.start() +End if +``` + +### 2. Manual — start it from your own code + +If you prefer to leave the option off, the scheduler never starts on its own. Call [`start()`](#start) from wherever it suits you — typically the host `On Startup` or `On Server Startup` database method — and [`stop()`](#stop) when the database closes (`On Exit` / `On Server Shutdown`): + +```4d +// Host "On Server Startup" +cs.EmbeddingStudio.Scheduler.me.start() + +// Host "On Server Shutdown" +cs.EmbeddingStudio.Scheduler.me.stop() +``` + +> In client/server, arm the scheduler from `On Server Startup`, not from `On Startup`: +> `On Startup` runs on every remote client, and the scheduler state is per machine — each +> client would arm its own loop and run its own batches. If you do call [`start()`](#start) +> from `On Startup` (single-user setups), guard it with +> `If (Application type#4D Remote mode)`. + +`start()` is idempotent, so calling it from several places is harmless. + +### Checking that it really runs + +[`isStarted()`](#isstarted) tells you whether the background loop is alive right now — the answer to "is my schedule actually being watched?": + +```4d +var $s:=cs.EmbeddingStudio.Scheduler.me.status() +If ($s.enabled && Not($s.started)) + ALERT("A schedule is configured but the scheduler is not started.") +End if +``` + +## Fonctions + +### start() + +**start**() : Boolean + +Arms the scheduler and starts the background loop worker if it is not already running. Idempotent — calling it again while already armed simply refreshes the "start from now" anchor. + +| Résultat | Type | Description | +| -------- | ------- | ------------------------------ | +| Résultat | Boolean | Always `True`. | + +```4d +cs.EmbeddingStudio.Scheduler.me.start() +``` + +### stop() + +**stop**() + +Disarms the scheduler and stops the background loop worker. A recalculation batch already in progress is **not** interrupted — it finishes normally (use [`cancel()`](#cancel) to request an early stop). + +```4d +cs.EmbeddingStudio.Scheduler.me.stop() +``` + +### annuler() + +**cancel**() + +Requests a **cooperative** cancel of the batch currently running. The running batch is never force-killed; it stops gracefully between two chunks. Has no effect if no batch is running. + +```4d +cs.EmbeddingStudio.Scheduler.me.cancel() +``` + +### force() + +**force**() : Object + +Forces a recalculation **now**, regardless of the schedule. It honors the single-batch rule: if a batch is already running, the forced trigger is skipped (and logged). Non-blocking — the run happens on the execution worker. + +| Résultat | Type | Description | +| -------- | ------ | ----------------------------------------------------- | +| Résultat | Object | The current [status](#status) object. | + +```4d +var $status:=cs.EmbeddingStudio.Scheduler.me.force() +``` + +### status() + +**status**() : Object + +Returns the current scheduler status, without any input parameter — suitable for administration and monitoring displays. + +| Résultat | Type | Description | +| -------- | ------ | ---------------------------------------------------- | +| Résultat | Object | See [Status object](#status-object). | + +```4d +var $s:=cs.EmbeddingStudio.Scheduler.me.status() +If ($s.running) + ALERT("A recalculation is running since "+$s.batchStart) +End if +``` + +#### Objet statut + +| Touche | Type | Description | +| ---------------------- | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `enabled` | Boolean | `False` when `mode = "never"`. | +| `mode` | Text | Effective mode (`never` \| `interval` \| `daily`). | +| `armed` | Boolean | `True` when the background loop is armed (after `start()`, until `stop()`). | +| `running` | Boolean | `True` while a recalculation batch is in progress. | +| `batchStart` | Text \| Null | ISO timestamp of the running batch start (`Null` when idle). | +| `lastExecution` | Text \| Null | ISO timestamp of the last completed run (`Null` if none yet). Restored from the persisted history after a restart, so it survives the loss of in-memory state. | +| `lastRunBeforeRestart` | Boolean | `True` when `lastExecution` was recovered from the history after a restart rather than produced by a run in the current session. | +| `nextRun` | Text \| Null | ISO timestamp of the next scheduled run (`Null` in `never` mode). | +| `lastResult` | Text \| Null | Result of the last trigger: `started` \| `skipped` \| `completed` \| `failed`. | +| `error` | Text \| Null | Error summary when the last run failed (safe for admin display), else `Null`. | +| `started` | Boolean | `True` when the background loop is really alive (see [`isStarted()`](#isstarted)). | +| `autoStart` | Boolean | `True` when the host database starts the scheduler by itself (see [`autoStart()`](#autostart)). | + +### isStarted() + +**isStarted**() : Boolean + +Tells whether the scheduler is **effectively running**, i.e. whether its background loop is alive at this very moment. Unlike the `armed` flag of the [status](#status-object), it reflects reality: if the loop was never started, or was killed, the result is `False`. + +| Résultat | Type | Description | +| -------- | ------- | --------------------------------------------------------- | +| Résultat | Boolean | `True` when the background loop is alive. | + +```4d +If (Not(cs.EmbeddingStudio.Scheduler.me.isStarted())) + cs.EmbeddingStudio.Scheduler.me.start() +End if +``` + +### autoStart() + +**autoStart**() : Boolean + +Tells whether the host database authorizes 4D Embedding Studio to start itself, i.e. whether the **"Execute 'On Host Database Event' method of the components"** option is checked in the host **Settings > Security** (see [Starting the scheduler](#starting-the-scheduler)). + +- `True` — the scheduler starts with the host database and stops with it. You have nothing to call. +- `False` — nothing starts automatically: your code must call [`start()`](#start) and [`stop()`](#stop). + +The answer is read from the host structure settings. When they cannot be read, the result is `False` — the safe answer, since starting an already-started scheduler is harmless. + +| Résultat | Type | Description | +| -------- | ------- | -------------------------------------------------------------------- | +| Résultat | Boolean | `True` when the host starts the scheduler by itself. | + +```4d +var $auto:=cs.EmbeddingStudio.Scheduler.me.autoStart() +``` + +### config() + +**config**() : Object + +Returns the effective scheduler configuration with defaults applied (as resolved from `embeddings.json`). + +| Résultat | Type | Description | +| -------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------- | +| Résultat | Object | `{mode; intervalHours; startFrom; startReference; dailyTime}` (see [Configuration](#configuration)). | + +```4d +var $cfg:=cs.EmbeddingStudio.Scheduler.me.config() +``` + +### saveConfig() + +**saveConfig**( *cfg* : Object ) : Object + +Validates, normalizes and **persists** a scheduler configuration to the `scheduler` key of `embeddings.json`, then returns the normalized value. This is the programmatic equivalent of the scheduler settings window: it lets you change the schedule entirely by code, without the GUI. Only the `scheduler` key is written — other keys of the settings file are preserved. + +The configuration is written **on the server**: in a 4D Server / 4D remote setup the file is always edited on the server machine, so a remote client can safely call this method. Because the loop re-reads the configuration on every cycle, the new schedule takes effect without restarting the scheduler. + +| Paramètres | Type | Description | +| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| cfg | Object | Raw configuration `{mode; intervalHours; startFrom; startReference; dailyTime}` (see [Configuration](#configuration)). Missing/out-of-range values are defaulted. | + +| Résultat | Type | Description | +| -------- | ------ | ---------------------------------------------------------------- | +| Résultat | Object | The normalized configuration that was persisted. | + +```4d +// Switch to a 6-hour interval counting from the last execution +cs.EmbeddingStudio.Scheduler.me.saveConfig({mode: "interval"; intervalHours: 6; startFrom: "lastExecution"}) + +// Switch to a daily run at 02:30 +cs.EmbeddingStudio.Scheduler.me.saveConfig({mode: "daily"; dailyTime: "02:30"}) + +// Disable the automatic schedule +cs.EmbeddingStudio.Scheduler.me.saveConfig({mode: "never"}) +``` + +### nextRun() + +**nextRun**() : Object + +Computes the next scheduled run from the current configuration and state. + +| Résultat | Type | Description | +| -------- | -------------- | --------------------------------------------------------------------------------------------------------------- | +| Résultat | Object \| Null | `{date : Date; time : Time; timestamp : Text; immediate : Boolean}`, or `Null` in `never` mode. | + +```4d +var $next:=cs.EmbeddingStudio.Scheduler.me.nextRun() +``` + +### reload() + +**reload**() : Object + +No-op convenience: the configuration is re-read automatically on each loop cycle, so this simply returns the current [status](#status). Provided for callers that want an explicit "config changed, give me the up-to-date status" call. + +| Résultat | Type | Description | +| -------- | ------ | ----------------------------------------------------- | +| Résultat | Object | The current [status](#status) object. | + +## Concurrency & logging + +- **Single batch** — at any time, at most one recalculation batch runs. A trigger (scheduled or forced) fired while a batch is running is **skipped**, not queued. +- **Skip traceability** — skipped triggers are logged with their timestamp in the execution history (`Logs/embeddingHistory.json`). +- **Cooperative cancel** — `cancel()` stops a running batch gracefully between chunks; it is never force-killed. +- **History** — each run records start/end timestamps, status, token usage and the computed next run date in `Logs/embeddingHistory.json` (see [ProcessResult](ProcessResult.md) for per-run details). + +### Execution history file + +`Logs/embeddingHistory.json` is written by the pipeline itself (every full `process()` run, scheduled or manual), guarded by a semaphore so concurrent processes never interleave writes. It holds the **current** run at the top level, the one before it under `previous`, and the same pair per definition under `definitions`. + +```json +{ + "startTime": "2026-09-01T14:03:00", + "endTime": "2026-09-01T14:03:00", + "status": "completed", + "trigger": "completed", + "error": null, + "nextComputeDate": "2026-09-02T14:03:00", + "promptTokens": 0, + "totalTokens": 0, + "cumulativePromptTokens": 37802, + "cumulativeTotalTokens": 37802, + "previous": { "startTime": "…", "endTime": "…", "status": "completed", "error": null, + "nextComputeDate": "…", "promptTokens": 12764, "totalTokens": 12764, + "cumulativePromptTokens": 37802, "cumulativeTotalTokens": 37802 }, + "skipped": ["2026-09-01T12:00:00"], + "definitions": { + "Students.student_vector_1": { + "startTime": "…", "endTime": "…", "status": "completed", "error": null, + "promptTokens": 1054, "totalTokens": 1054, + "cumulativePromptTokens": 4210, "cumulativeTotalTokens": 4210, + "previous": { "…": "…" } + } + } +} +``` + +| Touche | Type | Description | +| -------------------------------------------------- | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `startTime` / `endTime` | Text \| Null | ISO timestamps of the run, in the scheduler's local base. `endTime` is `null` while a run is in progress. | +| `status` | Text | `running` \| `completed` \| `failed`. | +| `trigger` | Text | Last event that touched the file: `started` \| `skipped` \| `completed` \| `failed`. | +| `error` | Text \| Null | Summary of the run's errors, or `null`. Never contains an API key. | +| `nextComputeDate` | Text \| Null | Next scheduled run computed at the end of the run (the `nextComputeDate` option of [Process](Process.md)). | +| `promptTokens` / `totalTokens` | Integer | Usage for this run alone. | +| `cumulativePromptTokens` / `cumulativeTotalTokens` | Integer | Running totals across all recorded runs. | +| `previous` | Object | Snapshot of the preceding run — the same keys, without `trigger`, `skipped` and `definitions`. Only one generation is kept. | +| `skipped` | Collection | ISO timestamps of triggers skipped because a batch was already running. Capped at the **last 50**. | +| `definitions` | Object | One entry per definition, keyed `"."`, each with its own `startTime`, `endTime`, `status` (`completed` \| `failed` \| `skipped`), `error`, token counters and `previous`. | + +[`status()`](#status) reads `startTime`, `endTime`, `status`, `trigger`, `error` and `nextComputeDate` back from this file, which is how `lastExecution` survives a server restart. + +## Lifecycle + +| Host setting | What happens | What you must do | +| ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | +| **"Execute 'On Host Database Event' method of the components"** checked | The scheduler starts when the host database opens and stops when it closes. | Nothing. | +| Option unchecked (default) | The scheduler never starts by itself. | Call [`start()`](#start) at startup and [`stop()`](#stop) at shutdown. | + +Ask [`autoStart()`](#autostart) which case you are in, and [`isStarted()`](#isstarted) whether the loop is currently alive. Stopping the scheduler never interrupts a batch in progress — it finishes normally. + +## Exemple + +```4d +// --- Start at server startup, unless the host does it for us --- +If (Not(cs.EmbeddingStudio.Scheduler.me.autoStart())) + cs.EmbeddingStudio.Scheduler.me.start() +End if + +// --- Admin panel: force a recalculation and read status --- +var $status:=cs.EmbeddingStudio.Scheduler.me.force() + +// --- Monitoring: display last / next run and current state --- +$status:=cs.EmbeddingStudio.Scheduler.me.status() +var $info:="Mode: "+$status.mode\ + +" — Last: "+String($status.lastExecution)\ + +" — Next: "+String($status.nextRun)\ + +" — "+($status.running ? "running" : String($status.lastResult)) + +// --- Cancel a long-running batch --- +cs.EmbeddingStudio.Scheduler.me.cancel() + +// --- Disable automatic runs --- +cs.EmbeddingStudio.Scheduler.me.stop() +``` From 4f2e669bf373a0233aa6cdb051159afa5c32a218 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:39:44 +0100 Subject: [PATCH 054/195] settings.md French --- .../embedding-studio/Classes/Settings.md | 184 ++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Settings.md diff --git a/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Settings.md b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Settings.md new file mode 100644 index 00000000000000..45c3b4fc59db17 --- /dev/null +++ b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Settings.md @@ -0,0 +1,184 @@ +--- +id: settings +title: Propriétés +--- + +# Propriétés + +The `Settings` class is the persisted configuration for the embedding pipeline. It loads and saves a JSON file (default: `Settings/embeddings.json`, overridable with the `EMBEDDINGS_SETTINGS_PATH` environment variable) containing a list of [Definition](Definition.md) entries, a batch size, and phrase-validation options. + +## Propriétés + +| Nom de propriété | Type | Description | +| ---------------- | -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `definitions` | Collection of [Definition](Definition.md) | The configured definitions. | +| `batchSize` | Integer | Chunk size used by [Process.processEntitySelection](Process.md#processentityselection). Default: `50`. | +| `phrase` | Object | Phrase-validation options (see below). | +| `embedder` | Object | Optional embedder configuration (see below). | +| `file` | 4D.File *(read-only)* | The backing file the settings are loaded from and saved to. | + +### phrase options + +Passed verbatim to [Phrase.validate()](Phrase.md#validate) whenever the pipeline validates a definition. + +| Champ | Type | Par défaut | Description | +| ----------------- | ------- | ---------- | ----------------------------------------------------------------------------------------------- | +| `allowRelations` | Boolean | `False` | Allow dot-notation through N:1 / 1:1 relations. | +| `allowCalculated` | Boolean | `False` | Allow calculated attributes in phrases. | +| `allowAlias` | Boolean | `False` | Allow alias attributes in phrases. | +| `allowObject` | Boolean | `False` | Allow object attributes in phrases. | + +> **Invalidation caveat.** Dirty-flag tracking only covers direct scalar fields on the entity. Fields that are only reachable through one of these options — a related entity's attribute, a calculated value, an alias, or a sub-property of an object — will **not** automatically mark the entity as dirty when they change. If such fields are part of a phrase and their source data changes, the vector will not be recomputed unless you call `invalidateVectors()` explicitly or use `force: true` when processing. + +### embedder options + +Controls how [Process](Process.md) builds its embedder. When absent, a default `Embedder` is created with its own defaults. + +| Champ | Type | Par défaut | Description | +| ------------ | ------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `className` | Text | — | Name of a project class to instantiate instead of the built-in `Embedder`. The class must expose `embed` and `embedBatch` functions. If instantiation fails or the interface is missing, a diagnostic error is logged and the default `Embedder` is used as fallback. | +| `maxRetries` | Integer | `3` | Number of retry attempts on rate-limit errors (forwarded to `Embedder`). | +| `backoffMs` | Integer | `500` | Base back-off delay in ms, doubled each retry (forwarded to `Embedder`). | + +Any additional keys are forwarded as-is to the constructor of the target class (built-in or custom). + +## Format de fichier + +```json +{ + "batchSize": 50, + "phrase": { + "allowRelations": false, + "allowCalculated": false, + "allowAlias": false, + "allowObject": false + }, + "embedder": { + "maxRetries": 5, + "backoffMs": 200 + }, + "definitions": [ + { + "dataclassName": "Students", + "vectorName": "student_vector_1", + "modelAlias": "text-embedding-3-small", + "phrase": "Student {firstName} {lastName}", + "autoInvalidate": true + } + ] +} +``` + +Each definition may include `autoInvalidate` (`true` by default) to control save-time automatic invalidation. + +The same file also carries the `scheduler` key (see [Scheduler](Scheduler.md#configuration)) and any other top-level key you add: `Settings` reads and rewrites only the keys listed above and leaves the rest untouched. + +With a custom embedder class: + +```json +{ + "embedder": { + "className": "MyCustomEmbedder" + }, + "definitions": [...] +} +``` + +## Class constructor + +Create a settings instance. The configuration file is loaded immediately. + +| Nom de l'argument | Type | Description | +| ----------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| *file* | 4D.File | Optionnel. A file to use instead of the default location. The override applies process-wide for subsequent settings access. **Not supported in 4D Remote mode** — pass it only when running locally or on the server. | + +When *file* is omitted, the default location is used: `Settings/embeddings.json`, or the path given by the `EMBEDDINGS_SETTINGS_PATH` environment variable. + +```4d +// Default location +var $settings:=cs.EmbeddingStudio.Settings.new() + +// Custom file (server / mono only) +var $settings:=cs.EmbeddingStudio.Settings.new(File("/some/path/custom.json")) +``` + +## Fonctions + +### load() + +**load**() + +Reload the backing file into memory, overwriting in-memory state. A missing file resets to defaults without raising. + +A file that **exists but cannot be parsed** also leaves the instance on defaults, but it is remembered: an error is logged and [`save()`](#save) then refuses to write, so a malformed file is never silently replaced by defaults. + +### sauvegarde() + +**save**() : Boolean + +Serialize the current in-memory state to the backing file. Only the keys this class owns (`batchSize`, `phrase`, `embedder`, `definitions`) are written — every other top-level key present in the file (the `scheduler` configuration, model aliases…) is preserved as-is. A key whose value is back to its default is *removed* from the file rather than written. + +Definitions are merged with what the file holds at that instant, using the snapshot taken at load time as the common ancestor: two editors open at the same time no longer drop each other's definitions. + +| Résultat | Type | Description | +| -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------ | +| Résultat | Boolean | `True` when written. `False` — nothing written — when the file could not be read at load time. | + +```4d +$settings.definitions.push(cs.EmbeddingStudio.Definition.new("Students"; "student_vector_1"; "text-embedding-3-small"; "{firstName}")) +$settings.batchSize:=100 +$settings.save() +``` + +### chercher() + +**find**(*dataclassName* : Text ; *vectorName* : Text) : [Definition](Definition.md) + +Look up the saved definition for the given dataclass/vector pair. + +| Argument | Type | Description | +| ----------------------- | --------------------------- | ------------------------------------------------------------------- | +| *dataclassName* | Text | Nom de la dataclass. | +| *vectorName* | Text | Name of the vector field on that dataclass. | +| Résultat de la fonction | [Definition](Definition.md) | The matching definition, or `Null` if none matches. | + +```4d +var $def:=$settings.find("Students"; "student_vector_1") +``` + +### findAll() + +**findAll**(*dataclassName* : Text) : Collection of [Definition](Definition.md) + +Return every saved definition configured for the given dataclass. + +| Argument | Type | Description | +| ----------------------- | ----------------------------------------- | --------------------------------------------------------------------------------------------- | +| *dataclassName* | Text | Nom de la dataclass. | +| Résultat de la fonction | Collection of [Definition](Definition.md) | All matching definitions (empty collection if none match). | + +```4d +var $defs:=$settings.findAll("Students") +// → every Students definition; used by Process.process(ds.Students) +``` + +### invalidateVectors() + +**invalidateVectors**() : Object + +Calls [`invalidateVectors()`](Definition.md#invalidatevectors) on every definition in `definitions` and merges the results into a single status object. + +| Argument | Type | Description | +| ----------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------ | +| Résultat de la fonction | Object | `{updated: Integer, skipped: Integer, errors: Collection of Text}` — accumulated across all definitions. | + +```4d +var $result:=cs.EmbeddingStudio.Settings.new().invalidateVectors() +// → { updated: 120; skipped: 0; errors: [] } +``` + +## Voir également + +- [Definition](Definition.md) +- [Process](Process.md) +- [Phrase](Phrase.md) From 37be6694d5351b52291555c39383376bfa269443 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:39:46 +0100 Subject: [PATCH 055/195] studioembedder.md French --- .../Classes/StudioEmbedder.md | 125 ++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/StudioEmbedder.md diff --git a/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/StudioEmbedder.md b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/StudioEmbedder.md new file mode 100644 index 00000000000000..53ef4019d9b785 --- /dev/null +++ b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/StudioEmbedder.md @@ -0,0 +1,125 @@ +--- +id: studioembedder +title: StudioEmbedder +--- + +# StudioEmbedder + +The `StudioEmbedder` class renders and embeds on demand, resolved against the Studio settings: a saved definition gives the phrase and the model, so the vector you compute matches the ones stored by [Process](Process.md). Nothing is persisted. Typical uses: building the vector of a search query, finding entities similar to a given one, or previewing the text sent for an entity. + +For the full batch pipeline that persists vectors on entities, see [Process](Process.md). + +## Propriétés + +| Nom de propriété | Type | Description | +| ---------------- | ----------------------- | ------------------------------------------------------------------------------------------------- | +| `propriétés` | [Settings](Settings.md) | The settings (vectors, batch size, phrase validation options). | +| `embedder` | [Embedder](Embedder.md) | The API-calling engine. Stateless and swappable. | +| `options` | Object | Runtime options object. | + +## Class constructor + +| Nom de l'argument | Type | Description | +| ----------------- | ----------------------- | ----------------------------------------------------------------------------------------------------------------------- | +| *settings* | [Settings](Settings.md) | Optionnel. If omitted, settings are loaded from the default `Settings/embeddings.json`. | +| *options* | Object | Optional runtime options. Supports `embedder` for injection. | + +```4d +var $studioEmbedder:=cs.EmbeddingStudio.StudioEmbedder.new() +var $studioEmbedder:=cs.EmbeddingStudio.StudioEmbedder.new($settings) +var $studioEmbedder:=cs.EmbeddingStudio.StudioEmbedder.new($settings; {embedder: $mockEmbedder}) +``` + +## Fonctions + +### render() + +**render**(*entity* : 4D.Entity ; *definitionOrPhrase* : Variant) : Text + +Return the text that [`embed()`](#embed) sends for an entity (the phrase rendered against it). No API call, no persistence. + +| Argument | Type | Description | +| ----------------------- | ------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| *entity* | 4D.Entity | The entity to render against. | +| *definitionOrPhrase* | `Null`, [Phrase](Phrase.md), [Definition](Definition.md), Text, or plain object stub | `Null` → auto-resolve via settings (requires a unique match). Text → compiled as a throwaway `cs.EmbeddingStudio.Phrase`. Object stub → see [stub resolution](#stub-resolution). | +| Résultat de la fonction | Text | The rendered text. | + +```4d +var $studioEmbedder:=cs.EmbeddingStudio.StudioEmbedder.new() +var $text: Text +$text:=$studioEmbedder.render($student; $def) // use def's phrase +$text:=$studioEmbedder.render($student; cs.EmbeddingStudio.Phrase.new("Hi {firstName}")) +$text:=$studioEmbedder.render($student; "Student: {lastName}") // raw template +$text:=$studioEmbedder.render($student) // auto-resolve +$text:=$studioEmbedder.render($student; {vectorName: "student_vector_1"}) // stub → saved definition's phrase +$text:=$studioEmbedder.render($student; {phrase: "Hi {firstName}"}) // ad-hoc stub → inline template +``` + +### embed() + +**embed**(*input* : Variant ; *context* : Variant ; *model* : Text) : [cs.EmbeddingStudio.EmbedderResult](EmbedderResult.md) + +Compute a vector for an arbitrary input, without persisting anywhere. + +| Argument | Type | Description | +| ----------------------- | --------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| *input* | Text or 4D.Entity | Text → embedded directly. Entity → phrase rendered then embedded. | +| *context* | Text, [Phrase](Phrase.md), [Definition](Definition.md), Text template, plain object stub, or `Null` | Provides phrase and/or model depending on *input*. Object stub → see [stub resolution](#stub-resolution). | +| *model* | Text | Optional explicit model name. Used when *context* does not carry one. | +| Résultat de la fonction | [EmbedderResult](EmbedderResult.md) | The embedding result (use `.vector` to get the 4D.Vector). | + +Throws if no model can be determined. + +```4d +var $studioEmbedder:=cs.EmbeddingStudio.StudioEmbedder.new() +var $vector: 4D.Vector + +// Text + model +$vector:=$studioEmbedder.embed("some text"; "text-embedding-3-small").vector + +// Text + definition (picks up def.modelAlias) +$vector:=$studioEmbedder.embed("some text"; $def).vector + +// Entity + definition (uses def.phrase + def.modelAlias) +$vector:=$studioEmbedder.embed($student; $def).vector + +// Entity + phrase + explicit model +$vector:=$studioEmbedder.embed($student; $phrase; "text-embedding-3-small").vector + +// Entity + ad-hoc template + model +$vector:=$studioEmbedder.embed($student; "Profile: {firstName} {lastName}"; "text-embedding-3-small").vector + +// Entity alone (auto-resolve, only when exactly one def matches the dataclass) +$vector:=$studioEmbedder.embed($student).vector + +// Entity + stub (deduces phrase + model from the matching saved definition) +$vector:=$studioEmbedder.embed($student; {vectorName: "student_vector_1"}).vector + +// Entity + ad-hoc stub (phrase compiled inline, model taken from the stub) +$vector:=$studioEmbedder.embed($student; {phrase: "Hi {firstName}"; modelAlias: "text-embedding-3-small"}).vector + +// Text + stub that only supplies the model +$vector:=$studioEmbedder.embed("some text"; {modelAlias: "text-embedding-3-small"}).vector +``` + +## Stub resolution + +Both `render()` and `embed()` accept a plain object in place of a `Phrase`/`Definition`. A stub is resolved the same way [`Process`](Process.md#definition-resolution-entity-context) resolves its `definition` argument, so the behavior matches. Two flavors are supported: + +| Stub | Resolves to | +| ------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `{vectorName: "..."}` (optionally `{dataclassName: "..."}`) | The matching **saved definition** for the entity's dataclass — deducing its phrase (and, for `embed`, its model). Resolves to nothing when there is no unique match. | +| `{phrase: "tpl {field}"}` or `{template: "tpl {field}"}` | An **ad-hoc** `Phrase` compiled inline; nothing is looked up. Pair with `{modelAlias: "..."}` to give `embed()` a model. | + +For `embed()`, the model is deduced in this order: an explicit `{modelAlias}` on the stub → the model of a stub-matched saved definition → the *model* argument → the entity's unique definition. An explicit `{modelAlias}` always wins. + +Unlike [`Process.process()`](Process.md#process-resolution), a stub is **not** turned into a brand-new `Definition` from its fields — `StudioEmbedder` persists nothing, so use `{phrase}`/`{template}` for one-off templates. + +## Voir également + +- [Process](Process.md) +- [Settings](Settings.md) +- [Definition](Definition.md) +- [Embedder](Embedder.md) +- [EmbedderResult](EmbedderResult.md) +- [Phrase](Phrase.md) From 827c73a65b5d45b748ed7097603b56e50ca33af8 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:39:48 +0100 Subject: [PATCH 056/195] license.md French --- .../version-21-R5/embedding-studio/license.md | 167 ++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/license.md diff --git a/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/license.md b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/license.md new file mode 100644 index 00000000000000..8f6fc0dd2b5ffc --- /dev/null +++ b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/license.md @@ -0,0 +1,167 @@ +--- +id: license +title: SOFTWARE LICENSE AGREEMENT +--- + +# SOFTWARE LICENSE AGREEMENT + +## Preamble + +The purpose of this Software license agreement is to grant users the right to modify and re-use the software governed by this license. + +The exercising of this right is conditional upon the obligation to make /available to the community the modifications made to the source code of the software so as to contribute to its evolution. + +In consideration of access to the source code and the rights to copy, modify and redistribute granted by the license, users are provided only with a limited warranty and the software's author, the holder of the economic rights, and the successive licensors only have limited liability. + +## Article 1 – DEFINITIONS + +***Agreement***: means this license agreement, and its possible subsequent versions and annexes. + +***Software***: means the software in its Object Code and/or Source Code form and, where applicable, its documentation, "as is" when the Licensee accepts the Agreement. + +***Initial Software***: means the Software in its Source Code and possibly its Object Code form and, where applicable, its documentation, "as is" when it is first distributed under the terms and conditions of the Agreement. + +***Modified Software***: means the Software modified by at least one Integrated Contribution. + +***Source Code***: means all the Software's instructions and program lines to which access is required so as to modify the Software. + +***Object Code***: means the binary files originating from the compilation of the Source Code. + +***Holder***: means the holder(s) of the economic rights over the Initial Software, in this case it is 4D SAS. + +***Licensee***: means the Software user(s) having accepted the Agreement. + +***Contributor***: means a Licensee having made at least one Integrated Contribution. + +***Licensor***: means the Holder, or any other individual or legal entity, who distributes the Software under the Agreement. + +***Integrated Contribution***: means new functions integrated into the Source Code by any or all Contributors. + +***Parties***: mean both the Licensee and the Licensor. + +These expressions may be used both in singular and plural form. + +## Article 2 - PURPOSE + +The purpose of the Agreement is the grant by the Licensor to the Licensee of a non-exclusive, transferable and worldwide license for the Software as set forth in Article 5 hereinafter for the whole term of the protection granted by the rights over said Software. + +## Article 3 - ACCEPTANCE + +The Licensee shall be deemed as having accepted the terms and conditions of this Agreement upon the occurrence of the first of the following events: + +- loading the Software by any or all means, notably, by downloading from a remote server; +- the first time the Licensee exercises any of the rights granted hereunder. + +## Article 4 - EFFECTIVE DATE AND TERM + +### 4.1 EFFECTIVE DATE + +The Agreement shall become effective on the date when it is accepted by the Licensee as set forth in Article 3. + +### 4.2 TERM + +The Agreement shall remain in force for the entire legal term of protection of the economic rights over the Software. + +## Article 5 - SCOPE OF RIGHTS GRANTED + +The Licensor hereby grants to the Licensee, who accepts, the following rights over the Software for the term of the Agreement, on the basis of the terms and conditions set forth hereinafter. + +### 5.1 RIGHT OF USE + +The Licensee is authorized to use the Software, without any limitation as to its fields of application, with it being hereinafter specified that this comprises: + +- permanent or temporary reproduction of all or part of the Software by any or all means and in any or all form. +- loading, displaying, running, or storing the Software on any or all medium. +- entitlement to observe, study or test its operation. + +### 5.2 RIGHT OF MODIFICATION + +The right of modification means the right to adapt, arrange, or make any or all modifications to the Software; being understood that such modifications of the Software shall results in a change of its functionalities and/or in an addition of functionalities to the Initial Software. + +Consequently to distribute a Modified Software according to the provision of section 5.3.2, the Licensee shall make exclusively significant modification as described above to the Software provided that it includes an explicit notice that it is the author of said modification and indicates the date of the creation thereof. + +### 5.3 RIGHT OF DISTRIBUTION + +In particular, the right of distribution includes the right to publish, transmit and communicate the Modified Software to the general public on any or all medium, and by any or all means, and the right to market, either in consideration of a fee, or + +#### 5.3.1 DISTRIBUTION OF SOFTWARE WITHOUT MODIFICATION + +The Licensee is forbidden to distribute true copies of the Software in Source Code or Object Code form. + +#### 5.3.2 DISTRIBUTION OF MODIFIED SOFTWARE + +When the Licensee creates Modified Software, this Modified Software may be distributed provided that said distribution complies with all the provisions of the Agreement and subject to compliance with the requirement to include a notice concerning the rights over the Software as defined in Article 6.3. + +In the event the creation of the Modified Software, the Licensee undertakes that: + +- the resulting Modified Software will be governed by this Agreement, being understood that such Agreement shall be integrated in the Modified Software the Integrated Contributions in the resulting Modified Software will be clearly identified and documented, +- the Licensee will allow effective access to the source code of the Modified Software, at a minimum during the entire period of distribution of the Derivative Software, such that such modifications may be carried over in a subsequent version of the Software. +- the Modified Software must be renamed to exclude any reference to 4D. For example, it is expressly prohibited to distribute a Modified Software named “4D SVG”; Licensee shall rename the Modified Software such as “Name of the Licensee SVG”. Consequently, Licensee is expressly forbidden to use 4D’s product name in general to promote his modified work. + +## Article 6 - INTELLECTUAL PROPERTY + +### 6.1 OVER THE INITIAL SOFTWARE + +The Holder owns the intellectual property rights over the Initial Software. Any or all use of the Initial Software is subject to compliance with the terms and conditions under which the Holder has elected to distribute its work and no one shall be entitled to modify the terms and conditions for the distribution of said Initial Software. + +### 6.2 OVER THE INTEGRATED CONTRIBUTIONS + +The Licensee who develops an Integrated Contribution is the owner of the intellectual property rights over this Contribution as defined by applicable law. + +### 6.3 NOTICE OF RIGHTS + +The Licensee expressly undertakes: + +- not to remove, or modify, in any manner, the intellectual property notices attached to the Software; +- to reproduce said notices, in an identical manner, in the copies of the Software modified; +- to ensure that use of the Software, its intellectual property notices and the fact that it is governed by the Agreement is indicated in a text that is easily accessible, specifically from the interface of any Modified Software. + +The Licensee undertakes not to directly or indirectly infringe the intellectual property rights of the Holder on the Software and to take, where applicable, vis- à-vis its staff, any and all measures required to ensure respect of said intellectual property rights of the Holder. + +## Article 7 - RELATED SERVICES + +Under no circumstances shall the Agreement oblige the Licensor to provide technical assistance or maintenance services for the Software. + +However, the Licensor is entitled to offer this type of services. The terms and conditions of such technical assistance, and/or such maintenance, shall be set forth in a separate instrument. + +## Article 8 - DISCLAIMER OF WARRANTY. + +THERE IS NO WARRANTY FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE HOLDER PROVIDES THE SOFTWARE “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH LICENSEE. SHOULD THE SOFTWARE PROVE DEFECTIVE, LICENSEE ASSUMES THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +## Article 9 - LIMITATION OF LIABILITY + +TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE TO LICENSEE ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS AGREEMENT OR USE OF THE SOFTWARE, EVEN IF THE LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR DAMAGES. + +## Article 10 – TERMINATION + +### 10.1 + +In the event of a breach by the Licensee of its obligations hereunder, the Licensor may automatically terminate this Agreement thirty (30) days after notice has been sent to the Licensee and has remained ineffective. + +### 10.2 + +A Licensee whose Agreement is terminated shall no longer be authorized to use, modify or distribute the Software. However, any licenses that it may have granted prior to termination of the Agreement shall remain valid subject to their having been granted in compliance with the terms and conditions hereof. + +## Article 11 – MISCELLANEOUS + +### 11.1 + +Neither Party shall be liable for any or all delay, or failure to perform the Agreement, that may be attributable to an event of force majeure, an act of God or an outside cause, such as defective functioning or interruptions of the electricity or telecommunications networks, network paralysis following a virus attack, intervention by government authorities, natural disasters, water damage, earthquakes, fire, explosions, strikes and labor unrest, war, etc. + +### 11.2 + +Any failure by either Party, on one or more occasions, to invoke one or more of the provisions hereof, shall under no circumstances be interpreted as being a waiver by the interested Party of its right to invoke said provision(s) subsequently. + +### 11.3 + +In the event that one or more of the provisions hereof were to conflict with a current or future applicable act or legislative text, said act or legislative text shall prevail, and the Parties shall make the necessary amendments so as to comply with said act or legislative text. All other provisions shall remain effective. Similarly, invalidity of a provision of the Agreement, for any reason whatsoever, shall not cause the Agreement as a whole to be invalid. + +## Article 12 - GOVERNING LAW AND JURISDICTION + +### 12.1 + +The Agreement is governed by French law. The Parties agree to endeavor to seek an amicable solution to any disagreements or disputes that may arise during the performance of the Agreement. + +### 12.2 + +Failing an amicable solution within two (2) months as from their occurrence, and unless emergency proceedings are necessary, the disagreements or disputes shall be referred to the Versailles Courts having jurisdiction, by the more diligent Party. \ No newline at end of file From 827d3c659b00acd60a9b58624f40ae59d8ae004c Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:39:51 +0100 Subject: [PATCH 057/195] overview.md French --- .../embedding-studio/overview.md | 211 ++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/overview.md diff --git a/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/overview.md b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/overview.md new file mode 100644 index 00000000000000..cf0a2bd93b1888 --- /dev/null +++ b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/overview.md @@ -0,0 +1,211 @@ +--- +id: overview +title: 4D-Embedding-Studio +--- + +# 4D-Embedding-Studio + +## Vue d’ensemble + +4D Embedding Studio is a component for defining, processing, and maintaining AI embedding vectors directly in your 4D dataclass entities. + +You can use the component without writing a single line of code: select attributes from your dataclasses to construct the sentences to be vectorized and specify the model to use. For each entity, the component calls the embedding API and stores the resulting `4D.Vector` values. Configure the embedding scheduler to (re)calculate the vectors for your data at fixed intervals or on demand. + +You can then use the ORDA [`query()` by vector feature](https://developer.4d.com/docs/API/DataClassClass#query-by-vector-similarity) to request your data using semantics. + +If you want to have more control over your embeddings, the component offers an extensive API that allows you to customize each step of the data vectorization process, manage the scheduler, and integrate high-performance RAG (*Retrieval Augmented Generation*) features into your 4D application. + +## Conditions requises + +- [4D-AIKit](https://github.com/4d/4D-AIKit) (loaded automatically as a dependency). +- 4D project (21 R5 or later) with the following configuration: + - a valid model alias + - a dataclass with a `4D.Vector` attribute (object field at the database level). + +## Quick Start + +**1. Add a field of type Object to the table and associate it with the `4D.Vector` class.** +**2. Select **Embedding Studio...** in the **Design** menu to display the Embedding Studio window.** + +![menu](../assets/en/embedding-studio/menu.png) + +**3. For each listed `4D.Vector` attribute, write a descriptive phrase based upon attributes of the dataclass.** +Use the contextual menu to insert appropriate attributes. +This phrase will be vectorized for every entity. +**4. Select a model alias (or create a new one).** +**5. Select "Execute now" to launch the vectorization of your data or configure the scheduler.** + +## User Guide + +### Configuring the dataclass + +To use the 4D Embedding Studio interface, you need to create at least one object attribute associated to a `4D.Vector` class in your datastore. This must be done at the database level (only storage attributes can be embeddings). + +In the Structure editor, add an Object field to the dataclass (table) whose entities you want to query using AI and enter ["4D.Vector" as class](https://developer.4d.com/docs/Develop/structure-fields#class). + +#### Dirty-flag support + +In a production application, data is rarely static. If an embedding is based on an attribute value that has changed (e.g. a product description), it becomes obsolete and could no longer be relevant. By default, 4D automatically invalidates and flags for recalculation affected embeddings. + +If you do not use a dirty-flag field (see below), 4D simply replaces any invalidated vector by `Null`. It is therefore no longer used in searches until its next calculation. This option is suitable for applications that prioritize strict consistency: it is better to return no results than to rely on an embedding that no longer matches the current data. + +Or, you can add a Boolean field named `_dirty` (e.g. "myVector_dirty") to the structure. In this case, when an update is required, this field is set to `True`, and the associated vector is retained until it is recalculated. Your application can then choose to continue using this vector temporarily or exclude it using a filter on `dirty = False`. The flag is cleared automatically after a successful save. +This strategy promotes service continuity while allowing you to precisely identify vectors awaiting recalculation. If your business logic requires full control, you can also disable automatic invalidation and manage this lifecycle yourself. + +*Note: Certain modifications, such as a model changes, require vectors to be replaced immediately.* + +### Creating an embedding + +When you select **Embedding Studio...** in the **Design** menu, the Embedding Studio window is displayed. + +The list on the left side shows all `4D.Vector` class attributes defined in the datastore. You can add as many vector attributes as you want per dataclass. + +A check mark (✓) in the Dirty Flag column indicates that a [`_dirty` boolean field](#dirty-flag-support) is associated to the vector field. + +**Note:** Any change in the database structure will require that you restart the 4D application so that the 4D Embedding Studio lists up-to-date values. + +#### Writing a descriptive sentence + +To create or edit an embedding, select the attribute to configure in this list and write the embedding definition in the "Descriptive sentence" area on the right side. Use the associated menu to build the sentence and to add references to dataclass available attributes with the `{attribute_name}` syntax. + +The sentence must build a text that describes the entity just like a human would do it. The embedding could then capturate the semantics and not only attribute values. + +For example, for a `Product` dataclass with many attributes such as name and category, you could write: +"The {name} product is a {category} from the {brand} brand. Description: {description}. Key features: {features}." + +![menu](../assets/en/embedding-studio/studio-interface.png) + +### Selecting a model + +Once you have defined your vector attribute, choose the model to use for generating the embedding. The list of models includes the **model aliases** you defined in the [Project Settings](https://developer.4d.com/docs/settings/ai#model-aliases). + +The choice of model is important because it determines the relevance and quality of your embeddings. You’ll also need to provide this model with every query on the dataclass data so that the comparison is performed using the same model. + +### Auto-invalidate on save + +When this option is checked (default), embeddings are automatically invalidated when at least one of their definition attributes has been modified and the entity was successfully saved. + +However, you might want to handle invalidation in a custom way using the [4D Embedding Studio API](#api-guide). In this case, uncheck this option to disable the automatic mechanism. + +### Calculating embeddings + +Embeddings are calculated by sending a request to the AI model, which then returns the vectorization result, which is subsequently stored in the `4D.Vector` attribute in the dataclass. 4D automatically handles this operation and optimizes it by calculating only the necessary vectors. Each vector is processed independently. Thus, an error on one element does not interrupt the recalculation of the others. Elements that fail will be automatically retried during the next run. Recalculations are performed asynchronously, without blocking users. + +These calculations can be performed **on demand** or **scheduled at regular intervals** using the scheduler in the 4D Embedding Studio component. + +**Note:** You can also customize embedding calculations per dataclass or entity using the [4D Embedding Studio API](#api-guide). + +#### On demand + +To launch an embedding calculation, select **Run now** in the menu at the bottom of the 4D Embedding Studio window. This item is disabled if the datastore does not contain any embedding to calculate. When started, you can select **Cancel run** at any moment. + +#### Périodicité + +You can configure the 4D Embedding Studio component scheduler to adjust the calculation frequency to suit your application’s needs. + +**Important:** The scheduler needs a 4D worker process to run. You can start it manually for testing purposes (**Start now** button in the scheduler dialog box) but to make sure a worker is available every times the application opens, you need to configure it. Vous pouvez soit : + +- select the **Execute "On Host Database Event" method of the components** option in the [project Settings](https://developer.4d.com/docs/settings/security#options) +- or write the following code in your startup code: + +```4d + //at startup +cs.EmbeddingStudio.Scheduler.me.start() +``` + +The scheduler allows you can set the time interval between two calculations. Select the tab corresponding to your needs and click **Save**. + +- **Never**: the scheduler is off and never runs +- **At regular interval**: set the time interval between each calculation starting from a specified time. +- **Once a day**: the calculation takes place every day at a specific time + starting from a specific time. + +### Building queries with embeddings + +Once you have defined embeddings in your datastore, you can start [querying your dataclasses using AI-based features](https://developer.4d.com/docs/API/DataClassClass#query-by-vector-similarity). You just need to make sure that you use the same model for your embedding definition and in the query string. + +For example, assuming that: + +• you have defined a `4D.Vector` attribute named "product_vector" in the Products dataclass using a sentence: "The {name} is in the {category} category. It has these {features} features and can be used for {usage}." +• you want to find products that "can be used safely outside". + +Vous pouvez écrire : + +```4d +// Retrieve the model alias from the embedding definition, configured in 4D Embedding Studio +var $settings:=cs.EmbeddingStudio.Settings.new() +var $definition:=$settings.find("Products"; "product_vector") + +// Compute the vector of the query with the same model +var $result:=cs.EmbeddingStudio.StudioEmbedder.new().embed("products that can be used safely outside"; $definition) +var $vector:=$result.vector + + //search with default metric (cosine) +var $products:=ds.Products.query("product_vector > :1 order by product_vector desc"; {vector : $vector}) + +``` + +If you use a dirty field, simply add a criterion to exclude vectors waiting to be recalculated: + +```4d +var $products:=ds.Products.query("product_vector > :1 and product_vector_dirty = false order by product_vector desc"; {vector : $vector}) +``` + +## API Guide + +### Quick start + +**1. Configure your vectors** in `Settings/embeddings.json`: + +```json +{ + "batchSize": 50, + "definitions": [ + { + "dataclassName": "Students", + "vectorName": "student_vector_1", + "modelAlias": "text-embedding", + "phrase": "Student {firstName} {lastName}, enrolled in {program}", + "autoInvalidate": true + } + ] +} +``` + +**2. Run the full pipeline** (all definitions, all records): + +```4d +var $p:=cs.EmbeddingStudio.Process.new() +var $r:=$p.process() + +If ($r.success) + ALERT("Updated "+String($r.entitiesUpdated)+" entities in "+String($r.duration)+" ms") +End if +``` + +**3. Process a single entity on save** (e.g. in a trigger or REST hook): + +```4d +var $p:=cs.EmbeddingStudio.Process.new() +$p.processEntity($entity) +``` + +### Class reference + +| Class | Description | +| ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [Process](Classes/Process.md) | Main orchestrator — entry point for all batch and entity operations. | +| [Scheduler](Classes/Scheduler.md) | Automated recalculation scheduler — background task, force/cancel, and runtime status. | +| [StudioEmbedder](Classes/StudioEmbedder.md) | Renders and embeds on demand using your saved definitions — e.g. to build a search query vector. Nothing is persisted. | +| [Settings](Classes/Settings.md) | Loads and saves the `embeddings.json` configuration file. | +| [Definition](Classes/Definition.md) | Describes one vector field: dataclass, field name, model alias, and phrase template. | +| [Embedder](Classes/Embedder.md) | Thin wrapper around the AIKit embeddings API with retry/backoff logic. | +| [EmbedderResult](Classes/EmbedderResult.md) | Typed wrapper normalizing API responses — vectors, usage metrics, rate-limit state. | +| [ProcessResult](Classes/ProcessResult.md) | Returned by every batch function — statistics and error breakdown. | +| [ProcessError](Classes/ProcessError.md) | Typed entry in `ProcessResult.errors` — scope, severity, code, ref, message, retryable. | +| [ProcessErrorCode](Classes/ProcessErrorCode.md) | Singleton catalogue of machine-readable error codes and their default severity/retryability. | +| [Phrase](Classes/Phrase.md) | Lightweight `{variable}` template engine used to build text from entity attributes. | + +### Voir également + +Blog post: [Vectorize your data effortlessly with 4D Embedding Studio](https://blog.4d.com/vectorize-your-data-effortlessly-with-4d-vector-studio) \ No newline at end of file From eeafbe3d9242e7f0bcabd59186b2dcf0e8e4d6e2 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:39:53 +0100 Subject: [PATCH 058/195] ratelimit.md French --- .../embedding-studio/ratelimit.md | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/ratelimit.md diff --git a/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/ratelimit.md b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/ratelimit.md new file mode 100644 index 00000000000000..757cf6d3c79040 --- /dev/null +++ b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/ratelimit.md @@ -0,0 +1,65 @@ +--- +id: ratelimit +title: Rate Limiting +--- + +# Rate Limiting + +The embedding pipeline includes built-in rate-limit awareness. When the API provider returns rate-limit headers (as OpenAI does), the system automatically throttles requests and adapts batch sizes to stay within budget. Providers that don't return rate-limit headers (e.g. Ollama) are unaffected — the pipeline runs at full speed. + +## Principes de fonctionnement + +Each call to [`Embedder.embed()`](Classes/Embedder.md) or [`Embedder.embedBatch()`](Classes/Embedder.md) returns an [`EmbedderResult`](Classes/EmbedderResult.md) that carries rate-limit state alongside the embedding vectors. The pipeline uses this data in a three-step loop: + +1. **Pre-flight throttle** — before sending a batch, the pipeline checks whether the remaining token budget is sufficient. If not, it waits for the reset window to elapse before proceeding. +2. **Adaptive batch sizing** — the pipeline computes the largest batch that fits within 80% of the remaining token budget. This avoids hitting the ceiling while still making efficient use of the quota. +3. **State update** — after each API response, the pipeline records the new remaining budget, computes an average tokens-per-entity estimate, and feeds both into the next iteration. + +## Rate-limit fields on EmbedderResult + +These fields are populated from the API response headers. When a provider doesn't return them, they keep their defaults and the pipeline skips throttling. + +| Champ | Par défaut | Description | +| ------------------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------- | +| `remainingTokens` | `-1` | Tokens left in the current window. `-1` = unknown. | +| `remainingRequests` | `-1` | Requests left in the current window. | +| `limitTokens` | `0` | TPM (tokens per minute) ceiling. | +| `limitRequests` | `0` | RPM (requests per minute) ceiling. | +| `resetTokens` | `""` | Time until the token bucket refills (e.g. `"6m0s"`, `"200ms"`). | +| `resetRequests` | `""` | Time until the request bucket refills. | + +## Batch size adaptation + +The pipeline starts with the configured `batchSize` (from [Settings](Classes/Settings.md), default 50). After the first API response provides rate-limit data, the batch size may shrink: + +``` +nextBatchSize = min( floor(remainingTokens × 0.8 / tokensPerEntity), configBatchSize ) +``` + +- `tokensPerEntity` is estimated from the last chunk (`totalTokens / chunkSize`). +- The result is clamped to a floor of 1 and a ceiling of `configBatchSize`. +- When `remainingTokens` is unknown (`-1`), the configured batch size is used as-is. + +## Pre-flight wait + +Before each batch, the pipeline checks: + +- **Token budget**: if `remainingTokens < estimatedTokens × 1.1`, it waits for the token reset window. +- **Request budget**: if `remainingRequests = 0`, it waits for the request reset window. + +The reset durations are parsed from the API's string format (`"6m0s"` → 360 seconds, `"200ms"` → 1 second). + +## Providers without rate limits + +Some providers (Ollama, local models) don't return rate-limit headers. Dans ce cas : + +- `remainingTokens` stays at `-1` (unknown) +- No throttling occurs — batches run at `configBatchSize` without waits +- The pipeline works identically to how it did before rate-limit support was added + +## Voir également + +- [EmbedderResult](Classes/EmbedderResult.md) — carries rate-limit fields +- [Embedder](Classes/Embedder.md) — wraps the API calls +- [Process](Classes/Process.md) — orchestrates the batch loop +- [Settings](Classes/Settings.md) — `batchSize` configuration From 9ea6ba908a39972385942aa3a756f51fd1b1f3c8 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:39:55 +0100 Subject: [PATCH 059/195] menu.png Spanish --- .../current/assets/en/embedding-studio/menu.png | Bin 0 -> 4938 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 i18n/es/docusaurus-plugin-content-docs/current/assets/en/embedding-studio/menu.png diff --git a/i18n/es/docusaurus-plugin-content-docs/current/assets/en/embedding-studio/menu.png b/i18n/es/docusaurus-plugin-content-docs/current/assets/en/embedding-studio/menu.png new file mode 100644 index 0000000000000000000000000000000000000000..425fd0d7e65879e34700b856cf6f88aaa9c502e1 GIT binary patch literal 4938 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 E0Cv$VrvLx| literal 0 HcmV?d00001 From fdbb0f9293186313af4a54ff16ac4aa86c7ec17c Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:39:57 +0100 Subject: [PATCH 060/195] studio-interface.png Spanish --- .../en/embedding-studio/studio-interface.png | Bin 0 -> 34492 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 i18n/es/docusaurus-plugin-content-docs/current/assets/en/embedding-studio/studio-interface.png diff --git a/i18n/es/docusaurus-plugin-content-docs/current/assets/en/embedding-studio/studio-interface.png b/i18n/es/docusaurus-plugin-content-docs/current/assets/en/embedding-studio/studio-interface.png new file mode 100644 index 0000000000000000000000000000000000000000..75dae7c9303297334e2fee1b404527957dfd4746 GIT binary patch literal 34492 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 Z0#D?x@H3fRStk8kMM>jk;f?!G{uip+WAXq1 literal 0 HcmV?d00001 From 7b0eb9fc7a4c57147273bc2e5268bd9fcd760bcc Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:39:59 +0100 Subject: [PATCH 061/195] definition.md Spanish --- .../embedding-studio/Classes/Definition.md | 165 ++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Definition.md diff --git a/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Definition.md b/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Definition.md new file mode 100644 index 00000000000000..f0ba84a11ef136 --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Definition.md @@ -0,0 +1,165 @@ +--- +id: definición +title: Definición +--- + +# Definición + +The `Definition` class describes how a single vector field on a dataclass should be computed: which dataclass, which vector field, which model alias, and which text template ([Phrase](Phrase.md)) to render from each entity. + +A collection of these is what [Settings](Settings.md) persists. + +## Propiedades + +| Nombre de la propiedad | Tipo | Descripción | +| ---------------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------- | +| `dataclassName` | Text | Name of the target dataclass. | +| `vectorName` | Text | Name of the `4D.Vector` field on that dataclass. | +| `modelAlias` | Text | Embedding model alias (e.g. `"text-embedding-3-small"`). | +| `phrase` | [Phrase](Phrase.md) | Compiled template used to build the text that will be embedded. | +| `autoInvalidate` | Boolean | Controls automatic invalidation on entity save. Default: `True`. | + +## Class constructor + +Create a definition. + +| Nombre del argumento | Tipo | Descripción | +| -------------------- | ---- | -------------------------------------------------------------------------------------------------- | +| *dataclassName* | Text | Name of the target dataclass. | +| *vectorName* | Text | Name of the target vector field. | +| *modelAlias* | Text | Embedding model alias. | +| *phraseTemplate* | Text | Phrase template with `{field}` placeholders — compiled into a [Phrase](Phrase.md). | + +```4d +var $def:=cs.EmbeddingStudio.Definition.new(\ + "Students"; \ + "student_vector_1"; \ + "text-embedding-3-small"; \ + "Student {firstName} {lastName}") +``` + +## Propiedades calculadas + +### hasDefinition + +**hasDefinition** : Boolean *(read-only)* + +Returns `True` if at least a model or a phrase template has been set. A definition without either has no content to process. + +```4d +If ($def.hasDefinition) + // worth validating further +End if +``` + +## Funciones + +### validate() + +**validate**( *settings* : Settings ) : Object + +Validates the definition against the live datastore model and the known embedding models. All errors are collected before returning — the result always describes the full set of problems found. + +| Argumento | Tipo | Descripción | +| ---------- | ------------------------------- | ------------------------------------------------------------------------------------------------------------ | +| *settings* | [Settings](Settings.md) \| Null | Used to pass phrase validation options. Pass `Null` to skip phrase options. | +| Resultado | Object | `{success: Boolean, errors: Collection}` where each error is `{field: Text, message: Text}`. | + +Checked in order: + +| Check | `field` value | +| ------------------------------------ | ----------------- | +| `dataclassName` is not empty | `"dataclassName"` | +| `vectorName` is not empty | `"vectorName"` | +| `modelAlias` is set and recognised | `"modelAlias"` | +| Dataclass exists in `ds` | `"dataclassName"` | +| Vector field exists | `"vectorName"` | +| Field type is `4D.Vector` | `"vectorName"` | +| Phrase template is not empty | `"phrase"` | +| Phrase keys resolve in the dataclass | `"phrase"` | + +The first two checks (identity) return immediately on failure; the remaining checks accumulate so all problems are reported in one pass. + +```4d +var $result:=$def.validate(cs.EmbeddingStudio.Settings.new()) + +If (Not($result.success)) + var $err : Object + For each ($err; $result.errors) + TRACE // $err.field, $err.message + End for each +End if +``` + +### invalidateVectors() + +**invalidateVectors**() : Object + +Marks all already-computed entities for re-embedding, forcing a full rebuild on the next run. Only entities that already have a vector value are processed — entities with a `Null` vector are skipped. + +Useful during development or after a model/phrase change to trigger a clean rebuild of all vectors. + +The strategy depends on whether a companion `_dirty` field exists on the dataclass: + +| Companion `_dirty` field | Action taken | +| ------------------------ | -------------------------------------------------------------- | +| Present | Sets `_dirty` to `True` — vector is left untouched | +| Absent | Nullifies the vector field | + +| Argumento | Tipo | Descripción | +| --------- | ------ | ------------------------------------------------------------------ | +| Resultado | Object | `{updated: Integer, skipped: Integer, errors: Collection of Text}` | + +- `updated` — number of entities successfully marked +- `skipped` — number of entities that could not be saved +- `errors` — one entry per save failure, formatted as `"DataclassName: statusText"` + +```4d +var $result:=$def.invalidateVectors() + +If ($result.skipped > 0) + var $e : Text + For each ($e; $result.errors) + // $e + End for each +End if +// → { updated: 42; skipped: 0; errors: [] } +``` + +### toObject() + +**toObject**() : Object + +Returns a plain object suitable for JSON persistence. The phrase is flattened to its template text. + +| Argumento | Tipo | Descripción | +| --------- | ------ | --------------------------------------------------------------------------------------------------------------------------------- | +| Resultado | Object | `{version, dataclassName, vectorName, modelAlias, phrase, autoInvalidate}` where `phrase` is the template string. | + +```4d +$def.toObject() +// → { version: 0; dataclassName: "Students"; vectorName: "student_vector_1"; +// modelAlias: "text-embedding-3-small"; phrase: "Student {firstName} {lastName}"; +// autoInvalidate: true } +``` + +## Automatic invalidation + +`autoInvalidate` controls whether save-time automatic invalidation is enabled for this definition. + +- `True` (default): when relevant attributes change on an entity save, vectors are automatically invalidated. +- `False`: save-time automatic invalidation is skipped for this definition. + +This setting does not affect manual invalidation via `invalidateVectors()`. + +## Dirty flag convention + +The pipeline in [Process](Process.md) will recompute an entity whenever the target vector is `Null`, or when a sibling field `_dirty` exists on the dataclass and is `True`. + +Declaring the dirty flag is optional — when absent, only the null-vector case triggers recomputation. When present, it is cleared automatically on successful save. + +## Ver también + +- [Settings](Settings.md) +- [Process](Process.md) +- [Phrase](Phrase.md) From 28d00f456be8e1f612631b6f4d37ad6aacd3c32b Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:40:02 +0100 Subject: [PATCH 062/195] embedder.md Spanish --- .../embedding-studio/Classes/Embedder.md | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Embedder.md diff --git a/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Embedder.md b/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Embedder.md new file mode 100644 index 00000000000000..211a2476dbd758 --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Embedder.md @@ -0,0 +1,96 @@ +--- +id: embedder +title: Embedder +--- + +# Embedder + +The `Embedder` class is a thin wrapper around [4D AIKit](https://developer.4d.com/docs/aikit/Classes/openai) focused on embeddings. It exposes two functions — one for a single text, one for a batch — and handles retries with exponential backoff (respecting the `Retry-After` header when present). + +It is stateless beyond configuration and safe to share between processes. + +## Propiedades + +| Nombre de la propiedad | Tipo | Descripción | +| ---------------------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | +| `client` | cs.AIKit.OpenAI | The underlying AIKit client used for HTTP requests. | +| `maxRetries` | Integer | Maximum number of retries on transient errors. Default: `3`. | +| `backoffMs` | Integer | Base delay (ms) between retries. Doubled each attempt. | + +## Class constructor + +Create a embedder. All options are optional. + +| Nombre del argumento | Tipo | Descripción | +| -------------------- | ------ | ----------------------------------------------------------------------------- | +| *opciones* | Object | `{client, maxRetries, backoffMs}` — any field may be omitted. | + +```4d +// Default — uses cs.AIKit.OpenAI.new() internally +var $proc:=cs.EmbeddingStudio.Embedder.new() + +// Provide a pre-configured AIKit client (custom API key, base URL, etc.) +var $client:=cs.AIKit.OpenAI.new({apiKey: "…"; baseURL: "https://server.ai"}) +var $proc:=cs.EmbeddingStudio.Embedder.new({client: $client; maxRetries: 5; backoffMs: 1000}) +``` + +> If the 4D AIKit component is not loaded (or is too old to provide `OpenAIProviders`), the constructor still succeeds with a `Null` client, and the first `embed()` / `embedBatch()` call throws an error whose `message` explains what is missing and whose `isAIKitMissing` property is `True`. + +## Funciones + +### embed() + +**embed**(*text* : Text ; *model* : Text) : [cs.EmbeddingStudio.EmbedderResult](EmbedderResult.md) + +Embed a single text. Returns a typed result with the embedding vector, token usage, and rate-limit state. + +| Argumento | Tipo | Descripción | +| --------- | -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| *text* | Text | The text to vectorize. | +| *model* | Text | The embedding model to use (e.g. `"text-embedding-3-small"`). | +| Resultado | [cs.EmbeddingStudio.EmbedderResult](EmbedderResult.md) | Typed wrapper — `.vector` holds the embedding, `.promptTokens` / `.totalTokens` hold usage, rate-limit fields are flat camelCase. | + +Throws if retries are exhausted or the API returns a non-retryable error. + +```4d +var $result:=$proc.embed("it rains cats and dogs"; "text-embedding-3-small") +// $result.vector → 4D.Vector +// $result.promptTokens → Integer +// $result.totalTokens → Integer +// $result.remainingTokens → Integer (-1 if unknown) +``` + +### embedBatch() + +**embedBatch**(*texts* : Collection ; *model* : Text) : [cs.EmbedderResult](EmbedderResult.md) + +Embed a collection of texts in a single API call. Returns a typed result with vectors in the same order as inputs, token usage, and rate-limit state. + +| Argumento | Tipo | Descripción | +| --------- | ------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------- | +| *texts* | Collection | Collection of Text to vectorize. Empty or `Null` returns an empty result. | +| *model* | Text | The embedding model to use. | +| Resultado | [cs.EmbedderResult](EmbedderResult.md) | Typed wrapper — `.vectors` holds the embeddings collection, token and rate-limit fields are flat camelCase. | + +```4d +var $result:=$proc.embedBatch(["hello"; "world"]; "text-embedding-3-small") +// $result.vectors[0] → 4D.Vector for "hello" +// $result.vectors[1] → 4D.Vector for "world" +// $result.totalTokens → Integer (sum for the batch) +// $result.remainingTokens → Integer (after this call) +``` + +## Retry policy + +Transient errors (HTTP 408, 409, 429, 5xx) are retried up to `maxRetries` times. + +- If the response carries a `Retry-After` or `retry-after-ms` header, the embedder waits that long. +- Otherwise, it waits `backoffMs * 2^attempt`. + +Non-retryable errors are thrown immediately — see [OpenAIError](https://developer.4d.com/docs/aikit/Classes/openaierror) for the thrown shape. + +## Ver también + +- [EmbedderResult](EmbedderResult.md) +- [Process](Process.md) +- [OpenAIEmbeddingsAPI](https://developer.4d.com/docs/aikit/Classes/openaiembeddingsapi) (AIKit) From dc00ba9889305dabb9099a040e6538c149b1c90e Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:40:04 +0100 Subject: [PATCH 063/195] embedderresult.md Spanish --- .../Classes/EmbedderResult.md | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/EmbedderResult.md diff --git a/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/EmbedderResult.md b/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/EmbedderResult.md new file mode 100644 index 00000000000000..b0da967bd3ba2f --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/EmbedderResult.md @@ -0,0 +1,80 @@ +--- +id: embedderresult +title: EmbedderResult +--- + +# EmbedderResult + +Typed wrapper for `Embedder.embed()` and `Embedder.embedBatch()` responses. Normalizes OpenAI's snake_case API keys (`prompt_tokens`, `total_tokens`) to camelCase properties, and flattens the nested rate-limit structure into direct properties. + +A single class handles both single and batch results — `embed()` populates `.vector`, `embedBatch()` populates `.vectors`. + +## Propiedades + +### Embedding results + +| Propiedad | Tipo | Por defecto | Descripción | +| --------- | ------------------------- | ----------- | ------------------------------------------------------------------------------ | +| `vector` | 4D.Vector | Null | Single embedding result. Null for batch calls. | +| `vectors` | Collection | `[]` | Batch embedding results. | + +### Token usage + +| Propiedad | Tipo | Por defecto | Descripción | +| -------------- | ------- | ----------- | -------------------------------------------------------------------- | +| `promptTokens` | Integer | `0` | Input tokens consumed. | +| `totalTokens` | Integer | `0` | Total tokens consumed (in + out). | + +### Rate-limit state + +| Propiedad | Tipo | Por defecto | Descripción | +| ------------------- | ------- | ----------- | ------------------------------------------------------------------------------------------------------------------- | +| `remainingTokens` | Integer | `-1` | Tokens left in the current window. `-1` = unknown. | +| `remainingRequests` | Integer | `-1` | Requests left in the current window. `-1` = unknown. | +| `limitTokens` | Integer | `0` | TPM ceiling for the account. | +| `limitRequests` | Integer | `0` | RPM ceiling for the account. | +| `resetTokens` | Text | `""` | Time until token bucket refills (e.g. `"6m0s"`). | +| `resetRequests` | Text | `""` | Time until request bucket refills (e.g. `"1s"`). | + +## Class constructor + +```4d +// From a real API result (used by Embedder internally) +var $result:=cs.EmbedderResult.new($aikitResult; True) // batch +var $result:=cs.EmbedderResult.new($aikitResult; False) // single + +// Empty result (no API call — e.g. empty batch) +var $result:=cs.EmbedderResult.new() +``` + +| Argumento | Tipo | Descripción | +| ----------- | ------- | ------------------------------------------------------------------------------------------------------------ | +| *resultado* | Object | An object with `.vector`/`.vectors`, `.usage`, `.rateLimit` (duck-typed). | +| *isBatch* | Boolean | `True` to read `.vectors`, `False` to read `.vector`. | + +The constructor accepts any object that exposes the expected shape — it does not require a specific class. This makes it easy to construct in tests. + +## Utilización + +```4d +// Single embedding +var $r:=$embedder.embed("hello world"; "text-embedding-3-small") +$r.vector // → 4D.Vector +$r.promptTokens // → 6 +$r.totalTokens // → 6 + +// Batch embedding +var $r:=$embedder.embedBatch(["hello"; "world"]; "text-embedding-3-small") +$r.vectors.length // → 2 +$r.totalTokens // → 10 + +// Rate-limit awareness +$r.remainingTokens // → 148230 (or -1 if not yet known) +$r.resetTokens // → "6m0s" +``` + +## Ver también + +- [Embedder](Embedder.md) — creates EmbedderResult instances +- [ProcessResult](ProcessResult.md) — run-level report that accumulates EmbedderResult usage +- [Rate Limiting](../RateLimit.md) — how the pipeline uses rate-limit fields for throttling and batch sizing From 8e95c8c0472b3731226e8787f14f1824eb01c08c Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:40:07 +0100 Subject: [PATCH 064/195] phrase.md Spanish --- .../embedding-studio/Classes/Phrase.md | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Phrase.md diff --git a/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Phrase.md b/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Phrase.md new file mode 100644 index 00000000000000..43155973191b05 --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Phrase.md @@ -0,0 +1,117 @@ +--- +id: phrase +title: Phrase +--- + +# Phrase + +The `Phrase` class is a lightweight template engine: a template with `{variable}` placeholders is compiled once, then rendered efficiently against different data objects. + +## Propiedades + +| Nombre de la propiedad | Tipo | Descripción | +| ---------------------- | ---------- | ---------------------------------------------------------------------------------------------------------------------- | +| `template` | Text | Computed — returns the original template string. | +| `keys` | Collection | Computed — returns the variable names found in the template, dot-notation keys joined back to strings. | + +## Class constructor + +Compile a template. Compilation walks the template once and extracts static parts and variable paths. + +| Nombre del argumento | Tipo | Descripción | +| -------------------- | ---- | ---------------------------------------------------------- | +| *template* | Text | Template string with `{variable}` markers. | + +```4d +var $tpl:=cs.EmbeddingStudio.Phrase.new("Hello {firstName}, you study at {schoolName}.") +$tpl.keys // → ["firstName"; "schoolName"] +``` + +## Funciones + +### render() + +**render**(*data* : Object) : Text + +Render the compiled template by replacing variables with values from *data*. Missing keys produce an empty string. + +| Argumento | Tipo | Descripción | +| --------- | ------ | ------------------------------------------------------------------------------------------------------ | +| *data* | Object | A plain object or a 4D.Entity whose fields supply the variable values. | +| Resultado | Text | The rendered text. | + +```4d +var $text:=$tpl.render({firstName: "Alice"; school: {name: "MIT"}}) +// → "Hello Alice, you study at MIT." + +// Works directly on entities +$text:=$tpl.render(ds.Students.first()) +``` + +### validate() + +**validate**(*dataclass* : 4D.DataClass ; *options* : Object) : Object + +Validate that all keys in the phrase can be resolved against the given dataclass. Walks dot-notation paths through N:1 / 1:1 relations. + +| Argumento | Tipo | Descripción | +| ----------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| *dataclass* | 4D.DataClass | The dataclass to validate against. | +| *opciones* | Object | Optional validation flags (see below). All default to `False` — storage kind only. | +| Resultado | Object | `{success: Boolean, errors: Collection of {key, message}}`. | + +#### Opciones + +| Campo | Tipo | Por defecto | Descripción | +| ----------------- | ------- | ----------- | ----------------------------------------------------------------------------------------------------- | +| `allowRelations` | Boolean | `False` | Allow dot-notation paths through N:1 / 1:1 relations. | +| `allowCalculated` | Boolean | `False` | Allow calculated attributes. | +| `allowAlias` | Boolean | `False` | Allow alias attributes. | + +```4d +var $tpl:=cs.EmbeddingStudio.Phrase.new("{firstName} at {school.name}") + +// Storage-only validation — fails because {school.name} uses a relation +var $v:=$tpl.validate(ds.Students) +// $v.success → False +// $v.errors → [{key: "school.name"; message: "..."}] + +// Allow relations +$v:=$tpl.validate(ds.Students; {allowRelations: True}) +// $v.success → True +``` + +#### Rejected shapes + +Regardless of options: + +- Attributes that do not exist on the dataclass. +- Attributes whose class ID is `4D.Vector`. +- 1:N relations (`relatedEntities`) as the final key. +- Intermediate segments that are not relations (when dot-notation is used). + +### atributos() + +**attributes**(*dataclass* : 4D.DataClass) : Collection + +Resolves each phrase key against *dataclass* and returns an ordered Collection of ORDA attribute descriptor objects, one per key in the same order as `.keys`. For dot-notation paths, traverses N:1 relations to reach the final attribute. Pushes `Null` for any key whose path cannot be resolved (unknown attribute or non-relation intermediate segment). + +| Argumento | Tipo | Descripción | +| ----------- | ---------------------------- | -------------------------------------------------------------------------------------------- | +| *dataclass* | 4D.DataClass | The dataclass to resolve attributes against. | +| Resultado | Collection | Ordered collection of ORDA attribute objects (or `Null`). | + +Each resolved entry is an ORDA attribute descriptor with `.name`, `.kind`, and more — see [DataClass.attributeName](https://developer.4d.com/docs/API/DataClassClass#attributename). + +```4d +var $tpl:=cs.EmbeddingStudio.Phrase.new("{firstName} graduated from {school.name}") +var $attrs:=$tpl.attributes(ds.Students) +// $attrs[0].name → "firstName" $attrs[0].type → "string" +// $attrs[1].name → "name" $attrs[1].type → "string" (from School dataclass) +// $attrs[1] is Null if school.name could not be resolved +``` + +## Ver también + +- [Definition](Definition.md) — holds a `Phrase`. +- [StudioEmbedder.render()](StudioEmbedder.md#render) — renders a phrase for an entity, non-persisting. From 518a843497b6efac6ce16e17d89c174a1149bf4d Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:40:09 +0100 Subject: [PATCH 065/195] process.md Spanish --- .../embedding-studio/Classes/Process.md | 188 ++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Process.md diff --git a/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Process.md b/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Process.md new file mode 100644 index 00000000000000..c35ad20417a1fd --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Process.md @@ -0,0 +1,188 @@ +--- +id: proceso +title: Proceso +--- + +# Proceso + +The `Process` class orchestrates the full embedding pipeline: it browses 4D entities, renders text from their fields using a [Definition](Definition.md), calls the embeddings API through an [Embedder](Embedder.md), and stores the resulting `4D.Vector` on each entity. + +To render or embed on demand without persistence (search query vectors, phrase previews), see [StudioEmbedder](StudioEmbedder.md). + +## Propiedades + +| Nombre de la propiedad | Tipo | Descripción | +| ---------------------- | ----------------------- | -------------------------------------------------------------------------------------------------------- | +| `propiedades` | [Settings](Settings.md) | The settings (definitions, batch size, phrase validation options). | +| `embedder` | [Embedder](Embedder.md) | The API-calling engine. Stateless and swappable. | +| `opciones` | Object | Runtime options object (see [Options object](#options-object) below). | + +### Options object + +| Llave | Tipo | Descripción | +| ---------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `onProgress` | 4D.Function | Called after each processed chunk with `{definition, report}`. | +| `onSuccess` | 4D.Function | Called once at the end when `report.success = True`, with `{report, success, errors}`. | +| `onError` | 4D.Function | Called once at the end when `report.success = False`, with `{report, success, errors}`. | +| `onTerminate` | 4D.Function | Called once at the end in all cases (after `onSuccess`/`onError`), with `{report, success, errors}`. | +| `dryRun` | Boolean | If `True`, runs selection/filter logic but skips API calls and entity saves. | +| `force` | Boolean | If `True`, recomputes every entity ignoring null-vector / dirty-flag filter. | +| `debug` | Boolean | If `True`, emits additional diagnostic log entries. | +| `pauseIndexes` | Boolean | If `True`, index maintenance on the target table is paused for the duration of a `processEntitySelection` batch run, then resumed right after (or on early exit/critical error). Default `False` — indexes are left alone. See [Pausing indexes](#pausing-indexes) before enabling it. | +| `waitForIndexes` | Boolean | Only used with `pauseIndexes`. If `True`, resuming indexes blocks until they are rebuilt. Default `False` — resume is asynchronous (indexes rebuilt in the background). | +| `shouldCancel` | 4D.Function | Predicate called between chunks during selection processing. Returning `True` stops the run gracefully (cooperative cancel) — what [`Scheduler.cancel()`](Scheduler.md#cancel) uses. | +| `embedder` | [Embedder](Embedder.md) | Inject a custom embedder (otherwise a default one is created). | + +## Class constructor + +Create an instance of the orchestrator. + +| Nombre del argumento | Tipo | Descripción | +| -------------------- | ----------------------- | ---------------------------------------------------------------------------------------------------------------------- | +| *settings* | [Settings](Settings.md) | Opcional. If omitted, settings are loaded from the default `Settings/embeddings.json`. | +| *opciones* | Object | Optional runtime options (see table above). | + +```4d +// Simplest — uses defaults +var $p:=cs.EmbeddingStudio.Process.new() + +// With explicit settings +var $p:=cs.EmbeddingStudio.Process.new($settings) + +// With options +var $p:=cs.EmbeddingStudio.Process.new($settings; {\ + force: True; \ + onProgress: Formula(ALERT("chunk done: "+String($1.report.entitiesUpdated)))}) +``` + +## Batch processing functions + +### proceso() + +**process**(*definition* : Variant) : [ProcessResult](ProcessResult.md) + +Process one, many, or all [Definition](Definition.md) entries against the full content of their target dataclass. + +| Argumento | Tipo | Descripción | +| ------------ | -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | +| *definición* | `Null`, [Definition](Definition.md), `4D.DataClass`, plain object, or Collection | See [process() resolution](#process-resolution). `Null` → every definition in settings. | +| Resultado | [ProcessResult](ProcessResult.md) | Statistics and per-error breakdown. | + +```4d +// Every definition in settings +var $r:=$p.process() + +// One specific definition +var $r:=$p.process($def) + +// Multiple definitions +var $r:=$p.process([$def1; $def2]) + +// Every definition configured for a whole dataclass +var $r:=$p.process(ds.Students) + +// A plain descriptor — looked up in settings, or built on the fly +var $r:=$p.process({dataclassName: "Students"; vectorName: "student_vector_1"}) + +// Any mix — each item is resolved independently and flattened +var $r:=$p.process([ds.Students; $def; {dataclassName: "School"; vectorName: "school_vector_1"}]) +``` + +#### process() resolution + +`process()` has no entity context, so it resolves each input into concrete [Definition](Definition.md) objects directly from settings: + +| Entrada | Comportamiento | +| -------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `Null` | Every definition in settings. | +| [Definition](Definition.md) | Used as-is. | +| `4D.DataClass` (e.g. `ds.Students`) | Every definition in settings whose `dataclassName` matches that dataclass. | +| `{dataclassName: "..."; vectorName: "..."}` | The matching saved definition, or — if none is found — a new `Definition` built from the object's fields (`modelAlias`, `phrase.template`). | +| Collection | Each item is resolved with the rules above and the results are **flattened** into one collection (a `4D.DataClass` item can expand to several definitions). Unsupported items are dropped. | +| Anything else | Empty result. | + +### processEntity() + +**processEntity**(*entity* : 4D.Entity ; *definition* : Variant) : [ProcessResult](ProcessResult.md) + +Process a single entity. Cheap path — no chunking, no server-side filter. + +| Argumento | Tipo | Descripción | +| ------------ | ----------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | +| *entity* | 4D.Entity | The entity to (re)compute vectors for. | +| *definición* | `Null`, [Definition](Definition.md), Collection, or `{vectorName: ...}` | See [resolution rules](#definition-resolution). `Null` infers from entity's dataclass. | +| Resultado | [ProcessResult](ProcessResult.md) | Statistics and per-error breakdown. | + +```4d +// Auto-resolve every definition matching this entity's dataclass +var $r:=$p.processEntity($entity) + +// Specific definition +var $r:=$p.processEntity($entity; $def) + +// By vector name only (looked up in settings against the entity's dataclass) +var $r:=$p.processEntity($entity; {vectorName: "student_vector_1"}) +``` + +### processEntitySelection() + +**processEntitySelection**(*selection* : 4D.EntitySelection ; *definition* : Variant) : [ProcessResult](ProcessResult.md) + +Workhorse path for large jobs. Chunks the selection by `settings.batchSize`, sends one API call per chunk, saves each entity individually. + +| Argumento | Tipo | Descripción | +| ------------ | ----------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | +| *selection* | 4D.EntitySelection | Entities to process. Pre-filtering by the caller is allowed; the pipeline still applies its null/dirty filter. | +| *definición* | `Null`, [Definition](Definition.md), Collection, or `{vectorName: ...}` | See [resolution rules](#definition-resolution). | +| Resultado | [ProcessResult](ProcessResult.md) | Statistics and per-error breakdown. | + +```4d +var $todo:=ds.Students.query("country = :1"; "FR") +var $r:=$p.processEntitySelection($todo; $def) +``` + +### Definition resolution (entity context) + +The polymorphic *definition* argument accepted by `processEntity` and `processEntitySelection`. Unlike [`process()`](#process-resolution), these have an entity/selection to infer the dataclass from, so a bare `{vectorName: "..."}` stub is enough: + +| Entrada | Comportamiento | +| --------------------------- | ----------------------------------------------------------------------------------------------- | +| `Null` | All definitions in settings whose `dataclassName` matches the entity/selection. | +| [Definition](Definition.md) | Used as-is; the `dataclassName` must match the entity/selection. | +| `{vectorName: "..."}` | Looked up in settings by `vectorName` against the entity/selection dataclass. | +| Collection | Each item resolved using the rules above; mismatches are silently dropped. | + +### Recompute rules + +An entity is (re)computed when **any** of these are true: + +- The target vector field is `Null`. +- A sibling field named `{vectorName}_dirty` exists and is `True`. +- The `force` option is `True`. + +The dirty field is optional per dataclass. If it doesn't exist, only the null-vector case triggers recomputation. Upon successful save, the pipeline clears the dirty flag (when present). + +For `processEntitySelection`, the filter is executed as a server-side ORDA query before any API call, so only the rows that actually need work are loaded into memory. For `processEntity`, the check is done in memory on the already-fetched entity. + +### Pausing indexes + +By default the indexes of the target table are maintained normally while vectors are saved. With the `pauseIndexes` option, a batch run calls [`PAUSE INDEXES`](https://developer.4d.com/docs/commands/pause-indexes) on the table before writing and [`RESUME INDEXES`](https://developer.4d.com/docs/commands/resume-indexes) once done (also on early exit or critical error). + +Be aware of what these commands do: + +- `PAUSE INDEXES` disables **all** the indexes of the table (except the primary key index), not only the vector ones: every index on every other field of the table is paused too. While paused, queries and sorts on that table, including those of other processes, run without any index. +- `RESUME INDEXES` then **rebuilds all these indexes**, for the whole table, not only for the records that were recomputed. On a table with several indexes, this rebuild can cost more than the time saved during the writes. +- With `waitForIndexes` set to `True`, the run blocks until the rebuild completes; otherwise the rebuild runs in the background. +- These commands cannot run on a 4D remote client: there the option is ignored (a warning is logged once) and the recalculation runs with indexes maintained normally. Run it on the server, for example through the [Scheduler](Scheduler.md), to use it. + +Enable it only for large recalculations, such as computing the vectors of a whole table for the first time. + +## Ver también + +- [StudioEmbedder](StudioEmbedder.md) +- [Settings](Settings.md) +- [Definition](Definition.md) +- [Embedder](Embedder.md) +- [ProcessResult](ProcessResult.md) +- [Phrase](Phrase.md) +- [Rate Limiting](../RateLimit.md) From 335ebf099ffe9afb0f96efd4d23f7fa4e1f9adea Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:40:12 +0100 Subject: [PATCH 066/195] processerror.md Spanish --- .../embedding-studio/Classes/ProcessError.md | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/ProcessError.md diff --git a/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/ProcessError.md b/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/ProcessError.md new file mode 100644 index 00000000000000..95a9debef40b85 --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/ProcessError.md @@ -0,0 +1,87 @@ +--- +id: processerror +title: ProcessError +--- + +# ProcessError + +A `ProcessError` is one structured, typed entry in the `errors` collection of a [ProcessResult](ProcessResult.md). Its typed fields let callers react to a specific failure mode programmatically — retry transient failures, abort on a fatal model outage, count save failures — without parsing message strings. + +You read these instances from [ProcessResult](ProcessResult.md)`.errors`, directly or through its query helpers (`errorsByCode`, `errorsByScope`, `retryableErrors`). + +## Propiedades + +| Nombre de la propiedad | Tipo | Descripción | +| ---------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `alcance` | Text | Where the error originated: `"pipeline"`, `"definition"`, `"chunk"`, or `"entity"`. | +| `severity` | Text | `"warning"`, `"error"`, or `"fatal"`. Determined by `code` (see [ProcessErrorCode](ProcessErrorCode.md)). | +| `code` | Integer | Machine-readable error code — compare against the constants on [ProcessErrorCode](ProcessErrorCode.md). | +| `ref` | Variant | Scope-dependent reference: `"Dataclass.vector"`, an entity primary key, a model alias, or `Null`. | +| `message` | Text | Human-readable, localized message. | +| `retryable` | Boolean | `True` when re-running the operation could plausibly succeed. Determined by `code`. | + +### scope values + +| Alcance | Significado | +| -------------- | -------------------------------------------------------------------------------------------------------------------------- | +| `"pipeline"` | Top-level failure affecting the whole run (null selection, a model became unavailable). | +| `"definition"` | A [Definition](Definition.md) failed validation or was skipped. | +| `"chunk"` | A whole batch (chunk) of entities failed in a single API call. | +| `"entidad"` | A single entity failed to embed or save. | + +### severity values + +| Severity | Significado | +| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `"warning"` | Non-blocking — does **not** make [ProcessResult](ProcessResult.md)`.success` false. | +| `"error"` | A recoverable failure scoped to one entity, chunk, or definition. Makes `success` false. | +| `"fatal"` | Blocks the rest of the run (e.g. the model is unavailable). Also surfaces via `hasFatal`. | + +## Propiedades calculadas + +| Propiedad | Tipo | Descripción | +| --------- | ------- | ------------------------------------------------- | +| `isFatal` | Boolean | `True` when `severity = "fatal"`. | + +## Funciones + +### toObject() + +**toObject**() : Object + +Returns a plain object (`{scope, severity, code, ref, message, retryable}`) suitable for logging or JSON serialization. + +| Argumento | Tipo | Descripción | +| --------- | ------ | ------------------------------------------------------ | +| Resultado | Object | A JSON-friendly snapshot of the error. | + +## Ejemplo + +React to failures by type rather than by message text: + +```4d +var $r:=$p.process() + +If (Not($r.success)) + + If ($r.hasFatal) + ALERT("A model became unavailable — aborting until it recovers.") + End if + + var $codes:=cs.EmbeddingStudio.ProcessErrorCode.me + var $saveFailures:=$r.errorsByCode($codes.SAVE_FAILED) + If ($saveFailures.length>0) + ALERT(String($saveFailures.length)+" entities failed to save.") + End if + + // Collect entity keys worth retrying later + var $retry:=$r.retryableErrors().query("scope = :1"; "entity").extract("ref") + +End if +``` + +## Ver también + +- [ProcessErrorCode](ProcessErrorCode.md) — the catalogue of `code` values and their severity/retryability. +- [ProcessResult](ProcessResult.md) — owns the `errors` collection and the query helpers (`errorsByCode`, `errorsByScope`, `retryableErrors`). +- [Process](Process.md) — produces these errors. From 6f77c2b515cf0a51d67b4153c82dc42f1402a70f Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:40:14 +0100 Subject: [PATCH 067/195] processerrorcode.md Spanish --- .../Classes/ProcessErrorCode.md | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/ProcessErrorCode.md diff --git a/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/ProcessErrorCode.md b/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/ProcessErrorCode.md new file mode 100644 index 00000000000000..f5d1b0d6e065bb --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/ProcessErrorCode.md @@ -0,0 +1,55 @@ +--- +id: processerrorcode +title: ProcessErrorCode +--- + +# ProcessErrorCode + +A `singleton` exposing the stable, machine-readable error codes carried by [ProcessError](ProcessError.md) `.code`, plus a `meta()` lookup mapping each code to its default `severity` and `retryable` flag. Compare against these constants instead of parsing message strings. + +Access the shared instance via `.me`: + +```4d +var $codes:=cs.EmbeddingStudio.ProcessErrorCode.me +If ($error.code=$codes.SAVE_FAILED) + // … +End if +``` + +## Codes + +| Constante | Valor | Default severity | Retryable | Raised when… | +| ----------------------- | ----- | ---------------- | --------- | ------------------------------------------------------------------------------------------------- | +| `NULL_INPUT` | 100 | error | No | A required entity, selection, or definition was `Null`. | +| `INVALID_DEFINITION` | 101 | error | No | A value is not a usable [Definition](Definition.md) instance. | +| `VALIDATION_FAILED` | 102 | error | No | `Definition.validate()` reported a problem. | +| `MODEL_UNAVAILABLE` | 200 | fatal | Sí | A critical API error made the model unusable for the rest of the run. | +| `MODEL_SKIPPED` | 201 | error | Sí | A definition was skipped because its model already failed critically. | +| `EMBED_FAILED` | 202 | error | Sí | A non-critical embedding call failed (single entity or chunk). | +| `VECTOR_COUNT_MISMATCH` | 300 | error | No | The provider returned a different vector count than requested. | +| `SAVE_FAILED` | 400 | error | Sí | `entity.save()` failed (validation, lock, …). | + +Codes are grouped by hundreds: `1xx` input/configuration, `2xx` model/API, `3xx` data integrity, `4xx` persistence. Unknown codes resolve to `{severity: "error"; retryable: False; label: "UNKNOWN"}`. + +## Funciones + +### meta() + +**meta**( $code : Integer ) : Object + +Returns the `severity` and `retryable` flag associated with a code — the same values carried by a [ProcessError](ProcessError.md) with that `code`. + +| Argumento | Tipo | Descripción | +| --------- | ------- | ----------------------------------------------------------------------- | +| `$code` | Integer | One of the code constants above. | +| Resultado | Object | `{severity : Text; retryable : Boolean; label : Text}`. | + +```4d +var $m:=cs.EmbeddingStudio.ProcessErrorCode.me.meta(cs.EmbeddingStudio.ProcessErrorCode.me.MODEL_UNAVAILABLE) +// $m = {severity: "fatal"; retryable: True; label: "MODEL_UNAVAILABLE"} +``` + +## Ver también + +- [ProcessError](ProcessError.md) — carries a `.code` from this list. +- [ProcessResult](ProcessResult.md) — `errorsByCode()` filters errors by code. From 1ed6732d817a83018aa10d3a544a9ba67b74adec Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:40:16 +0100 Subject: [PATCH 068/195] processresult.md Spanish --- .../embedding-studio/Classes/ProcessResult.md | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/ProcessResult.md diff --git a/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/ProcessResult.md b/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/ProcessResult.md new file mode 100644 index 00000000000000..7263643f095e95 --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/ProcessResult.md @@ -0,0 +1,91 @@ +--- +id: processresult +title: ProcessResult +--- + +# ProcessResult + +The `ProcessResult` class is the return value of every batch entry point of [Process](Process.md) (`process`, `processEntity`, `processEntitySelection`). It accumulates statistics, per-error breakdowns, and wall-clock duration. + +The orchestrator never throws out of its public batch API — failures are recorded here and the job continues. The caller decides what to do with them. + +## Propiedades + +| Nombre de la propiedad | Tipo | Descripción | +| ---------------------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `definitionsProcessed` | Integer | Number of [Definition](Definition.md) entries processed. | +| `entitiesConsidered` | Integer | Number of entities that passed the "needs recompute" filter. | +| `entitiesUpdated` | Integer | Number of entities whose vector was successfully written and saved. | +| `entitiesSkipped` | Integer | Number of entities that could not be processed: individual embed or save errors, or whole-chunk API failures (those entities are left unchanged for the next run). | +| `apiCalls` | Integer | Number of embeddings API calls made. | +| `promptTokens` | Integer | Total prompt tokens consumed across all API calls in this run. | +| `totalTokens` | Integer | Total tokens consumed across all API calls in this run. | +| `duración` | Integer | Total duration of the job in milliseconds. | +| `errors` | Collection | List of [ProcessError](ProcessError.md) entries recorded during the run. | + +### Propiedades calculadas + +| Propiedad | Tipo | Descripción | +| ---------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `success` | Boolean | `True` when no `"error"` or `"fatal"` entry was recorded. `"warning"` entries do not fail the run. | +| `hasFatal` | Boolean | `True` when at least one `"fatal"` entry was recorded (e.g. a model became unavailable). | + +### Error entries + +Each item in `errors` is a [ProcessError](ProcessError.md) with `scope`, `severity`, `code`, `ref`, `message`, and `retryable`. See [ProcessError](ProcessError.md) for the field meanings and [ProcessErrorCode](ProcessErrorCode.md) for the `code` catalogue. + +## Funciones + +### errorsByScope() + +**errorsByScope**( $scope : Text ) : Collection + +Errors filtered by `scope` (`"pipeline"`, `"definition"`, `"chunk"`, `"entity"`). + +### errorsByCode() + +**errorsByCode**( $code : Integer ) : Collection + +Errors filtered by machine-readable code — see [ProcessErrorCode](ProcessErrorCode.md). + +### retryableErrors() + +**retryableErrors**() : Collection + +Errors flagged `retryable` — re-running the operation could plausibly succeed. + +### toObject() + +**toObject**() : Object + +Returns a plain object suitable for logging or JSON serialization. + +| Argumento | Tipo | Descripción | +| --------- | ------ | ------------------------------------------------------- | +| Resultado | Object | A JSON-friendly snapshot of the report. | + +```4d +var $r:=$p.process() +LOG EVENT(Into 4D log file; JSON Stringify($r.toObject())) +``` + +## Ejemplo + +```4d +var $r:=$p.processEntitySelection(ds.Students.all(); $def) + +If ($r.success) + ALERT("Updated "+String($r.entitiesUpdated)+" students in "+String($r.duration)+" ms") +Else + var $err : Object + For each ($err; $r.errors) + ALERT("[" + $err.scope + "] " + String($err.ref) + " — " + $err.message) + End for each +End if +``` + +## Ver también + +- [Process](Process.md) +- [ProcessError](ProcessError.md) — the typed shape of each `errors` entry. +- [ProcessErrorCode](ProcessErrorCode.md) — the `code` catalogue. From 8dd67452f64f82a4c992a33cf834586ddb1e5c9b Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:40:19 +0100 Subject: [PATCH 069/195] scheduler.md Spanish --- .../embedding-studio/Classes/Scheduler.md | 369 ++++++++++++++++++ 1 file changed, 369 insertions(+) create mode 100644 i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Scheduler.md diff --git a/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Scheduler.md b/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Scheduler.md new file mode 100644 index 00000000000000..e2ba1bd8ee043e --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Scheduler.md @@ -0,0 +1,369 @@ +--- +id: backups periódicos +title: Backups periódicos +--- + +# Backups periódicos + +The `Scheduler` class is the public entry point for the **automated embedding recalculation** service. It maintains a background task that runs the embedding pipeline (see [Process](Process.md)) at a configured interval or a fixed daily time, guarantees that **at most one** recalculation batch runs at a time, and exposes runtime status for administration and monitoring interfaces. + +It is a **singleton**, accessed through `cs.EmbeddingStudio.Scheduler.me`. + +The scheduler runs two named workers: + +| Worker | Rol | +| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `EmbeddingStudioScheduler` | Background loop that re-reads the config each cycle, computes the next run and fires when due. | +| `EmbeddingStudio` | Execution worker that runs one recalculation batch (shared with the Studio UI, so scheduled and manual runs are serialized). | + +## Configuración + +The configuration lives under the `scheduler` key of `Settings/embeddings.json`: + +```json +{ + "scheduler": { + "mode": "interval", + "intervalHours": 3, + "startFrom": "reference", + "startReference": "2026-09-02T14:00:00", + "dailyTime": "00:00" + } +} +``` + +| Llave | Tipo | Values / range | Descripción | +| ---------------- | ------- | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `mode` | Text | `"never"` \| `"interval"` \| `"daily"` | Scheduling mode. Absent/unknown ⇒ `never` (no automatic run). | +| `intervalHours` | Integer | `1`..`24` | Interval mode only. Out-of-range ⇒ default `3`. | +| `startFrom` | Text | `"reference"` \| `"lastExecution"` | Interval mode only. Anchor of the interval (see below). Anything other than `"lastExecution"` — including the legacy `"now"` — is normalized to `reference`. Default `reference`. | +| `startReference` | Text | `"YYYY-MM-DDThh:mm:ss"` | Interval mode with `startFrom = "reference"`. Fixed instant the interval counts from. Absent ⇒ the moment the scheduler was armed, then the current instant. | +| `dailyTime` | Text | `"HH:MM"` | Daily mode only. Time of day for the recalculation. Default `"00:00"`. | + +**Interval anchoring (`startFrom`)** + +- `reference` — **fixed rate**: the interval is anchored on the fixed `startReference` instant, so the slots do not drift whatever a run's duration is. Slots are advanced by `intervalHours` until the first one strictly after now. When `startReference` is absent (a fresh or legacy config), the anchor falls back to the moment the scheduler was armed (`start()`), then to the current instant. +- `lastExecution` — **fixed delay**: the interval is anchored on the last completed recalculation. If the elapsed time since the last run already exceeds the interval (e.g. after a restart), the run is triggered immediately. If there is no prior run, it runs immediately. + +The effective configuration is read from the file on **every loop cycle**, so changes take effect without restarting the scheduler. + +## Starting the scheduler + +Configuring a `mode` is **not enough**: nothing runs until the scheduler is started. There are two ways to get there, and which one applies depends on a single option of your host database. + +### 1. Automatic — let the host database start it + +In the host database, open **Settings > Security** and check **"Execute 'On Host Database Event' method of the components"** (it is *unchecked* by default, for security reasons). + +With this option on, 4D Embedding Studio starts the scheduler by itself when the host database opens, and stops it when the host database closes. There is nothing else to write. + +Use [`autoStart()`](#autostart) to check whether the option is on: + +```4d +If (Not(cs.EmbeddingStudio.Scheduler.me.autoStart())) + // the option is off — I must start the scheduler myself + cs.EmbeddingStudio.Scheduler.me.start() +End if +``` + +### 2. Manual — start it from your own code + +If you prefer to leave the option off, the scheduler never starts on its own. Call [`start()`](#start) from wherever it suits you — typically the host `On Startup` or `On Server Startup` database method — and [`stop()`](#stop) when the database closes (`On Exit` / `On Server Shutdown`): + +```4d +// Host "On Server Startup" +cs.EmbeddingStudio.Scheduler.me.start() + +// Host "On Server Shutdown" +cs.EmbeddingStudio.Scheduler.me.stop() +``` + +> In client/server, arm the scheduler from `On Server Startup`, not from `On Startup`: +> `On Startup` runs on every remote client, and the scheduler state is per machine — each +> client would arm its own loop and run its own batches. If you do call [`start()`](#start) +> from `On Startup` (single-user setups), guard it with +> `If (Application type#4D Remote mode)`. + +`start()` is idempotent, so calling it from several places is harmless. + +### Checking that it really runs + +[`isStarted()`](#isstarted) tells you whether the background loop is alive right now — the answer to "is my schedule actually being watched?": + +```4d +var $s:=cs.EmbeddingStudio.Scheduler.me.status() +If ($s.enabled && Not($s.started)) + ALERT("A schedule is configured but the scheduler is not started.") +End if +``` + +## Funciones + +### start() + +**start**() : Boolean + +Arms the scheduler and starts the background loop worker if it is not already running. Idempotent — calling it again while already armed simply refreshes the "start from now" anchor. + +| Resultado | Tipo | Descripción | +| --------- | ------- | ------------------------------ | +| resultado | Boolean | Always `True`. | + +```4d +cs.EmbeddingStudio.Scheduler.me.start() +``` + +### stop() + +**stop**() + +Disarms the scheduler and stops the background loop worker. A recalculation batch already in progress is **not** interrupted — it finishes normally (use [`cancel()`](#cancel) to request an early stop). + +```4d +cs.EmbeddingStudio.Scheduler.me.stop() +``` + +### cancelado() + +**cancel**() + +Requests a **cooperative** cancel of the batch currently running. The running batch is never force-killed; it stops gracefully between two chunks. Has no effect if no batch is running. + +```4d +cs.EmbeddingStudio.Scheduler.me.cancel() +``` + +### force() + +**force**() : Object + +Forces a recalculation **now**, regardless of the schedule. It honors the single-batch rule: if a batch is already running, the forced trigger is skipped (and logged). Non-blocking — the run happens on the execution worker. + +| Resultado | Tipo | Descripción | +| --------- | ------ | ----------------------------------------------------- | +| resultado | Object | The current [status](#status) object. | + +```4d +var $status:=cs.EmbeddingStudio.Scheduler.me.force() +``` + +### status() + +**status**() : Object + +Returns the current scheduler status, without any input parameter — suitable for administration and monitoring displays. + +| Resultado | Tipo | Descripción | +| --------- | ------ | ---------------------------------------------------- | +| resultado | Object | See [Status object](#status-object). | + +```4d +var $s:=cs.EmbeddingStudio.Scheduler.me.status() +If ($s.running) + ALERT("A recalculation is running since "+$s.batchStart) +End if +``` + +#### Objeto estado + +| Llave | Tipo | Descripción | +| ---------------------- | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `enabled` | Boolean | `False` when `mode = "never"`. | +| `mode` | Text | Effective mode (`never` \| `interval` \| `daily`). | +| `armed` | Boolean | `True` when the background loop is armed (after `start()`, until `stop()`). | +| `running` | Boolean | `True` while a recalculation batch is in progress. | +| `batchStart` | Text \| Null | ISO timestamp of the running batch start (`Null` when idle). | +| `lastExecution` | Text \| Null | ISO timestamp of the last completed run (`Null` if none yet). Restored from the persisted history after a restart, so it survives the loss of in-memory state. | +| `lastRunBeforeRestart` | Boolean | `True` when `lastExecution` was recovered from the history after a restart rather than produced by a run in the current session. | +| `nextRun` | Text \| Null | ISO timestamp of the next scheduled run (`Null` in `never` mode). | +| `lastResult` | Text \| Null | Result of the last trigger: `started` \| `skipped` \| `completed` \| `failed`. | +| `error` | Text \| Null | Error summary when the last run failed (safe for admin display), else `Null`. | +| `started` | Boolean | `True` when the background loop is really alive (see [`isStarted()`](#isstarted)). | +| `autoStart` | Boolean | `True` when the host database starts the scheduler by itself (see [`autoStart()`](#autostart)). | + +### isStarted() + +**isStarted**() : Boolean + +Tells whether the scheduler is **effectively running**, i.e. whether its background loop is alive at this very moment. Unlike the `armed` flag of the [status](#status-object), it reflects reality: if the loop was never started, or was killed, the result is `False`. + +| Resultado | Tipo | Descripción | +| --------- | ------- | --------------------------------------------------------- | +| resultado | Boolean | `True` when the background loop is alive. | + +```4d +If (Not(cs.EmbeddingStudio.Scheduler.me.isStarted())) + cs.EmbeddingStudio.Scheduler.me.start() +End if +``` + +### autoStart() + +**autoStart**() : Boolean + +Tells whether the host database authorizes 4D Embedding Studio to start itself, i.e. whether the **"Execute 'On Host Database Event' method of the components"** option is checked in the host **Settings > Security** (see [Starting the scheduler](#starting-the-scheduler)). + +- `True` — the scheduler starts with the host database and stops with it. You have nothing to call. +- `False` — nothing starts automatically: your code must call [`start()`](#start) and [`stop()`](#stop). + +The answer is read from the host structure settings. When they cannot be read, the result is `False` — the safe answer, since starting an already-started scheduler is harmless. + +| Resultado | Tipo | Descripción | +| --------- | ------- | -------------------------------------------------------------------- | +| resultado | Boolean | `True` when the host starts the scheduler by itself. | + +```4d +var $auto:=cs.EmbeddingStudio.Scheduler.me.autoStart() +``` + +### config() + +**config**() : Object + +Returns the effective scheduler configuration with defaults applied (as resolved from `embeddings.json`). + +| Resultado | Tipo | Descripción | +| --------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------- | +| resultado | Object | `{mode; intervalHours; startFrom; startReference; dailyTime}` (see [Configuration](#configuration)). | + +```4d +var $cfg:=cs.EmbeddingStudio.Scheduler.me.config() +``` + +### saveConfig() + +**saveConfig**( *cfg* : Object ) : Object + +Validates, normalizes and **persists** a scheduler configuration to the `scheduler` key of `embeddings.json`, then returns the normalized value. This is the programmatic equivalent of the scheduler settings window: it lets you change the schedule entirely by code, without the GUI. Only the `scheduler` key is written — other keys of the settings file are preserved. + +The configuration is written **on the server**: in a 4D Server / 4D remote setup the file is always edited on the server machine, so a remote client can safely call this method. Because the loop re-reads the configuration on every cycle, the new schedule takes effect without restarting the scheduler. + +| Parámetros | Tipo | Descripción | +| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| cfg | Object | Raw configuration `{mode; intervalHours; startFrom; startReference; dailyTime}` (see [Configuration](#configuration)). Missing/out-of-range values are defaulted. | + +| Resultado | Tipo | Descripción | +| --------- | ------ | ---------------------------------------------------------------- | +| resultado | Object | The normalized configuration that was persisted. | + +```4d +// Switch to a 6-hour interval counting from the last execution +cs.EmbeddingStudio.Scheduler.me.saveConfig({mode: "interval"; intervalHours: 6; startFrom: "lastExecution"}) + +// Switch to a daily run at 02:30 +cs.EmbeddingStudio.Scheduler.me.saveConfig({mode: "daily"; dailyTime: "02:30"}) + +// Disable the automatic schedule +cs.EmbeddingStudio.Scheduler.me.saveConfig({mode: "never"}) +``` + +### nextRun() + +**nextRun**() : Object + +Computes the next scheduled run from the current configuration and state. + +| Resultado | Tipo | Descripción | +| --------- | -------------- | --------------------------------------------------------------------------------------------------------------- | +| resultado | Object \| Null | `{date : Date; time : Time; timestamp : Text; immediate : Boolean}`, or `Null` in `never` mode. | + +```4d +var $next:=cs.EmbeddingStudio.Scheduler.me.nextRun() +``` + +### reload() + +**reload**() : Object + +No-op convenience: the configuration is re-read automatically on each loop cycle, so this simply returns the current [status](#status). Provided for callers that want an explicit "config changed, give me the up-to-date status" call. + +| Resultado | Tipo | Descripción | +| --------- | ------ | ----------------------------------------------------- | +| resultado | Object | The current [status](#status) object. | + +## Concurrency & logging + +- **Single batch** — at any time, at most one recalculation batch runs. A trigger (scheduled or forced) fired while a batch is running is **skipped**, not queued. +- **Skip traceability** — skipped triggers are logged with their timestamp in the execution history (`Logs/embeddingHistory.json`). +- **Cooperative cancel** — `cancel()` stops a running batch gracefully between chunks; it is never force-killed. +- **History** — each run records start/end timestamps, status, token usage and the computed next run date in `Logs/embeddingHistory.json` (see [ProcessResult](ProcessResult.md) for per-run details). + +### Execution history file + +`Logs/embeddingHistory.json` is written by the pipeline itself (every full `process()` run, scheduled or manual), guarded by a semaphore so concurrent processes never interleave writes. It holds the **current** run at the top level, the one before it under `previous`, and the same pair per definition under `definitions`. + +```json +{ + "startTime": "2026-09-01T14:03:00", + "endTime": "2026-09-01T14:03:00", + "status": "completed", + "trigger": "completed", + "error": null, + "nextComputeDate": "2026-09-02T14:03:00", + "promptTokens": 0, + "totalTokens": 0, + "cumulativePromptTokens": 37802, + "cumulativeTotalTokens": 37802, + "previous": { "startTime": "…", "endTime": "…", "status": "completed", "error": null, + "nextComputeDate": "…", "promptTokens": 12764, "totalTokens": 12764, + "cumulativePromptTokens": 37802, "cumulativeTotalTokens": 37802 }, + "skipped": ["2026-09-01T12:00:00"], + "definitions": { + "Students.student_vector_1": { + "startTime": "…", "endTime": "…", "status": "completed", "error": null, + "promptTokens": 1054, "totalTokens": 1054, + "cumulativePromptTokens": 4210, "cumulativeTotalTokens": 4210, + "previous": { "…": "…" } + } + } +} +``` + +| Llave | Tipo | Descripción | +| -------------------------------------------------- | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `startTime` / `endTime` | Text \| Null | ISO timestamps of the run, in the scheduler's local base. `endTime` is `null` while a run is in progress. | +| `status` | Text | `running` \| `completed` \| `failed`. | +| `trigger` | Text | Last event that touched the file: `started` \| `skipped` \| `completed` \| `failed`. | +| `error` | Text \| Null | Summary of the run's errors, or `null`. Never contains an API key. | +| `nextComputeDate` | Text \| Null | Next scheduled run computed at the end of the run (the `nextComputeDate` option of [Process](Process.md)). | +| `promptTokens` / `totalTokens` | Integer | Usage for this run alone. | +| `cumulativePromptTokens` / `cumulativeTotalTokens` | Integer | Running totals across all recorded runs. | +| `previous` | Object | Snapshot of the preceding run — the same keys, without `trigger`, `skipped` and `definitions`. Only one generation is kept. | +| `skipped` | Collection | ISO timestamps of triggers skipped because a batch was already running. Capped at the **last 50**. | +| `definitions` | Object | One entry per definition, keyed `"."`, each with its own `startTime`, `endTime`, `status` (`completed` \| `failed` \| `skipped`), `error`, token counters and `previous`. | + +[`status()`](#status) reads `startTime`, `endTime`, `status`, `trigger`, `error` and `nextComputeDate` back from this file, which is how `lastExecution` survives a server restart. + +## Lifecycle + +| Host setting | What happens | What you must do | +| ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | +| **"Execute 'On Host Database Event' method of the components"** checked | The scheduler starts when the host database opens and stops when it closes. | Nothing. | +| Option unchecked (default) | The scheduler never starts by itself. | Call [`start()`](#start) at startup and [`stop()`](#stop) at shutdown. | + +Ask [`autoStart()`](#autostart) which case you are in, and [`isStarted()`](#isstarted) whether the loop is currently alive. Stopping the scheduler never interrupts a batch in progress — it finishes normally. + +## Ejemplo + +```4d +// --- Start at server startup, unless the host does it for us --- +If (Not(cs.EmbeddingStudio.Scheduler.me.autoStart())) + cs.EmbeddingStudio.Scheduler.me.start() +End if + +// --- Admin panel: force a recalculation and read status --- +var $status:=cs.EmbeddingStudio.Scheduler.me.force() + +// --- Monitoring: display last / next run and current state --- +$status:=cs.EmbeddingStudio.Scheduler.me.status() +var $info:="Mode: "+$status.mode\ + +" — Last: "+String($status.lastExecution)\ + +" — Next: "+String($status.nextRun)\ + +" — "+($status.running ? "running" : String($status.lastResult)) + +// --- Cancel a long-running batch --- +cs.EmbeddingStudio.Scheduler.me.cancel() + +// --- Disable automatic runs --- +cs.EmbeddingStudio.Scheduler.me.stop() +``` From 0e86c7822005567f0436bccbba0391ef0e943ea0 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:40:22 +0100 Subject: [PATCH 070/195] settings.md Spanish --- .../embedding-studio/Classes/Settings.md | 184 ++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Settings.md diff --git a/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Settings.md b/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Settings.md new file mode 100644 index 00000000000000..c7a4cef3f972f3 --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Settings.md @@ -0,0 +1,184 @@ +--- +id: settings +title: Propiedades +--- + +# Propiedades + +The `Settings` class is the persisted configuration for the embedding pipeline. It loads and saves a JSON file (default: `Settings/embeddings.json`, overridable with the `EMBEDDINGS_SETTINGS_PATH` environment variable) containing a list of [Definition](Definition.md) entries, a batch size, and phrase-validation options. + +## Propiedades + +| Nombre de la propiedad | Tipo | Descripción | +| ---------------------- | -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `definitions` | Collection of [Definition](Definition.md) | The configured definitions. | +| `batchSize` | Integer | Chunk size used by [Process.processEntitySelection](Process.md#processentityselection). Default: `50`. | +| `phrase` | Object | Phrase-validation options (see below). | +| `embedder` | Object | Optional embedder configuration (see below). | +| `file` | 4D.File *(read-only)* | The backing file the settings are loaded from and saved to. | + +### phrase options + +Passed verbatim to [Phrase.validate()](Phrase.md#validate) whenever the pipeline validates a definition. + +| Campo | Tipo | Por defecto | Descripción | +| ----------------- | ------- | ----------- | ----------------------------------------------------------------------------------------------- | +| `allowRelations` | Boolean | `False` | Allow dot-notation through N:1 / 1:1 relations. | +| `allowCalculated` | Boolean | `False` | Allow calculated attributes in phrases. | +| `allowAlias` | Boolean | `False` | Allow alias attributes in phrases. | +| `allowObject` | Boolean | `False` | Allow object attributes in phrases. | + +> **Invalidation caveat.** Dirty-flag tracking only covers direct scalar fields on the entity. Fields that are only reachable through one of these options — a related entity's attribute, a calculated value, an alias, or a sub-property of an object — will **not** automatically mark the entity as dirty when they change. If such fields are part of a phrase and their source data changes, the vector will not be recomputed unless you call `invalidateVectors()` explicitly or use `force: true` when processing. + +### embedder options + +Controls how [Process](Process.md) builds its embedder. When absent, a default `Embedder` is created with its own defaults. + +| Campo | Tipo | Por defecto | Descripción | +| ------------ | ------- | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `className` | Text | — | Name of a project class to instantiate instead of the built-in `Embedder`. The class must expose `embed` and `embedBatch` functions. If instantiation fails or the interface is missing, a diagnostic error is logged and the default `Embedder` is used as fallback. | +| `maxRetries` | Integer | `3` | Number of retry attempts on rate-limit errors (forwarded to `Embedder`). | +| `backoffMs` | Integer | `500` | Base back-off delay in ms, doubled each retry (forwarded to `Embedder`). | + +Any additional keys are forwarded as-is to the constructor of the target class (built-in or custom). + +## Formato del archivo + +```json +{ + "batchSize": 50, + "phrase": { + "allowRelations": false, + "allowCalculated": false, + "allowAlias": false, + "allowObject": false + }, + "embedder": { + "maxRetries": 5, + "backoffMs": 200 + }, + "definitions": [ + { + "dataclassName": "Students", + "vectorName": "student_vector_1", + "modelAlias": "text-embedding-3-small", + "phrase": "Student {firstName} {lastName}", + "autoInvalidate": true + } + ] +} +``` + +Each definition may include `autoInvalidate` (`true` by default) to control save-time automatic invalidation. + +The same file also carries the `scheduler` key (see [Scheduler](Scheduler.md#configuration)) and any other top-level key you add: `Settings` reads and rewrites only the keys listed above and leaves the rest untouched. + +With a custom embedder class: + +```json +{ + "embedder": { + "className": "MyCustomEmbedder" + }, + "definitions": [...] +} +``` + +## Class constructor + +Create a settings instance. The configuration file is loaded immediately. + +| Nombre del argumento | Tipo | Descripción | +| -------------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| *file* | 4D.File | Opcional. A file to use instead of the default location. The override applies process-wide for subsequent settings access. **Not supported in 4D Remote mode** — pass it only when running locally or on the server. | + +When *file* is omitted, the default location is used: `Settings/embeddings.json`, or the path given by the `EMBEDDINGS_SETTINGS_PATH` environment variable. + +```4d +// Default location +var $settings:=cs.EmbeddingStudio.Settings.new() + +// Custom file (server / mono only) +var $settings:=cs.EmbeddingStudio.Settings.new(File("/some/path/custom.json")) +``` + +## Funciones + +### load() + +**load**() + +Reload the backing file into memory, overwriting in-memory state. A missing file resets to defaults without raising. + +A file that **exists but cannot be parsed** also leaves the instance on defaults, but it is remembered: an error is logged and [`save()`](#save) then refuses to write, so a malformed file is never silently replaced by defaults. + +### save() + +**save**() : Boolean + +Serialize the current in-memory state to the backing file. Only the keys this class owns (`batchSize`, `phrase`, `embedder`, `definitions`) are written — every other top-level key present in the file (the `scheduler` configuration, model aliases…) is preserved as-is. A key whose value is back to its default is *removed* from the file rather than written. + +Definitions are merged with what the file holds at that instant, using the snapshot taken at load time as the common ancestor: two editors open at the same time no longer drop each other's definitions. + +| Resultado | Tipo | Descripción | +| --------- | ------- | ------------------------------------------------------------------------------------------------------------------------------ | +| resultado | Boolean | `True` when written. `False` — nothing written — when the file could not be read at load time. | + +```4d +$settings.definitions.push(cs.EmbeddingStudio.Definition.new("Students"; "student_vector_1"; "text-embedding-3-small"; "{firstName}")) +$settings.batchSize:=100 +$settings.save() +``` + +### find() + +**find**(*dataclassName* : Text ; *vectorName* : Text) : [Definition](Definition.md) + +Look up the saved definition for the given dataclass/vector pair. + +| Argumento | Tipo | Descripción | +| --------------- | --------------------------- | ------------------------------------------------------------------- | +| *dataclassName* | Text | Nombre de la dataclass. | +| *vectorName* | Text | Name of the vector field on that dataclass. | +| Resultado | [Definition](Definition.md) | The matching definition, or `Null` if none matches. | + +```4d +var $def:=$settings.find("Students"; "student_vector_1") +``` + +### findAll() + +**findAll**(*dataclassName* : Text) : Collection of [Definition](Definition.md) + +Return every saved definition configured for the given dataclass. + +| Argumento | Tipo | Descripción | +| --------------- | ----------------------------------------- | --------------------------------------------------------------------------------------------- | +| *dataclassName* | Text | Nombre de la dataclass. | +| Resultado | Collection of [Definition](Definition.md) | All matching definitions (empty collection if none match). | + +```4d +var $defs:=$settings.findAll("Students") +// → every Students definition; used by Process.process(ds.Students) +``` + +### invalidateVectors() + +**invalidateVectors**() : Object + +Calls [`invalidateVectors()`](Definition.md#invalidatevectors) on every definition in `definitions` and merges the results into a single status object. + +| Argumento | Tipo | Descripción | +| --------- | ------ | ------------------------------------------------------------------------------------------------------------------------ | +| Resultado | Object | `{updated: Integer, skipped: Integer, errors: Collection of Text}` — accumulated across all definitions. | + +```4d +var $result:=cs.EmbeddingStudio.Settings.new().invalidateVectors() +// → { updated: 120; skipped: 0; errors: [] } +``` + +## Ver también + +- [Definition](Definition.md) +- [Process](Process.md) +- [Phrase](Phrase.md) From 7bb6b3e6fad2effa46839344989c43335cbdef76 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:40:24 +0100 Subject: [PATCH 071/195] studioembedder.md Spanish --- .../Classes/StudioEmbedder.md | 125 ++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/StudioEmbedder.md diff --git a/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/StudioEmbedder.md b/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/StudioEmbedder.md new file mode 100644 index 00000000000000..96e099d3e1461b --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/Classes/StudioEmbedder.md @@ -0,0 +1,125 @@ +--- +id: studioembedder +title: StudioEmbedder +--- + +# StudioEmbedder + +The `StudioEmbedder` class renders and embeds on demand, resolved against the Studio settings: a saved definition gives the phrase and the model, so the vector you compute matches the ones stored by [Process](Process.md). Nothing is persisted. Typical uses: building the vector of a search query, finding entities similar to a given one, or previewing the text sent for an entity. + +For the full batch pipeline that persists vectors on entities, see [Process](Process.md). + +## Propiedades + +| Nombre de la propiedad | Tipo | Descripción | +| ---------------------- | ----------------------- | ------------------------------------------------------------------------------------------------- | +| `propiedades` | [Settings](Settings.md) | The settings (vectors, batch size, phrase validation options). | +| `embedder` | [Embedder](Embedder.md) | The API-calling engine. Stateless and swappable. | +| `opciones` | Object | Runtime options object. | + +## Class constructor + +| Nombre del argumento | Tipo | Descripción | +| -------------------- | ----------------------- | ---------------------------------------------------------------------------------------------------------------------- | +| *settings* | [Settings](Settings.md) | Opcional. If omitted, settings are loaded from the default `Settings/embeddings.json`. | +| *opciones* | Object | Optional runtime options. Supports `embedder` for injection. | + +```4d +var $studioEmbedder:=cs.EmbeddingStudio.StudioEmbedder.new() +var $studioEmbedder:=cs.EmbeddingStudio.StudioEmbedder.new($settings) +var $studioEmbedder:=cs.EmbeddingStudio.StudioEmbedder.new($settings; {embedder: $mockEmbedder}) +``` + +## Funciones + +### render() + +**render**(*entity* : 4D.Entity ; *definitionOrPhrase* : Variant) : Text + +Return the text that [`embed()`](#embed) sends for an entity (the phrase rendered against it). No API call, no persistence. + +| Argumento | Tipo | Descripción | +| -------------------- | ------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| *entity* | 4D.Entity | The entity to render against. | +| *definitionOrPhrase* | `Null`, [Phrase](Phrase.md), [Definition](Definition.md), Text, or plain object stub | `Null` → auto-resolve via settings (requires a unique match). Text → compiled as a throwaway `cs.EmbeddingStudio.Phrase`. Object stub → see [stub resolution](#stub-resolution). | +| Resultado | Text | The rendered text. | + +```4d +var $studioEmbedder:=cs.EmbeddingStudio.StudioEmbedder.new() +var $text: Text +$text:=$studioEmbedder.render($student; $def) // use def's phrase +$text:=$studioEmbedder.render($student; cs.EmbeddingStudio.Phrase.new("Hi {firstName}")) +$text:=$studioEmbedder.render($student; "Student: {lastName}") // raw template +$text:=$studioEmbedder.render($student) // auto-resolve +$text:=$studioEmbedder.render($student; {vectorName: "student_vector_1"}) // stub → saved definition's phrase +$text:=$studioEmbedder.render($student; {phrase: "Hi {firstName}"}) // ad-hoc stub → inline template +``` + +### embed() + +**embed**(*input* : Variant ; *context* : Variant ; *model* : Text) : [cs.EmbeddingStudio.EmbedderResult](EmbedderResult.md) + +Compute a vector for an arbitrary input, without persisting anywhere. + +| Argumento | Tipo | Descripción | +| --------- | --------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| *entrada* | Text or 4D.Entity | Text → embedded directly. Entity → phrase rendered then embedded. | +| *context* | Text, [Phrase](Phrase.md), [Definition](Definition.md), Text template, plain object stub, or `Null` | Provides phrase and/or model depending on *input*. Object stub → see [stub resolution](#stub-resolution). | +| *model* | Text | Optional explicit model name. Used when *context* does not carry one. | +| Resultado | [EmbedderResult](EmbedderResult.md) | The embedding result (use `.vector` to get the 4D.Vector). | + +Throws if no model can be determined. + +```4d +var $studioEmbedder:=cs.EmbeddingStudio.StudioEmbedder.new() +var $vector: 4D.Vector + +// Text + model +$vector:=$studioEmbedder.embed("some text"; "text-embedding-3-small").vector + +// Text + definition (picks up def.modelAlias) +$vector:=$studioEmbedder.embed("some text"; $def).vector + +// Entity + definition (uses def.phrase + def.modelAlias) +$vector:=$studioEmbedder.embed($student; $def).vector + +// Entity + phrase + explicit model +$vector:=$studioEmbedder.embed($student; $phrase; "text-embedding-3-small").vector + +// Entity + ad-hoc template + model +$vector:=$studioEmbedder.embed($student; "Profile: {firstName} {lastName}"; "text-embedding-3-small").vector + +// Entity alone (auto-resolve, only when exactly one def matches the dataclass) +$vector:=$studioEmbedder.embed($student).vector + +// Entity + stub (deduces phrase + model from the matching saved definition) +$vector:=$studioEmbedder.embed($student; {vectorName: "student_vector_1"}).vector + +// Entity + ad-hoc stub (phrase compiled inline, model taken from the stub) +$vector:=$studioEmbedder.embed($student; {phrase: "Hi {firstName}"; modelAlias: "text-embedding-3-small"}).vector + +// Text + stub that only supplies the model +$vector:=$studioEmbedder.embed("some text"; {modelAlias: "text-embedding-3-small"}).vector +``` + +## Stub resolution + +Both `render()` and `embed()` accept a plain object in place of a `Phrase`/`Definition`. A stub is resolved the same way [`Process`](Process.md#definition-resolution-entity-context) resolves its `definition` argument, so the behavior matches. Two flavors are supported: + +| Stub | Resolves to | +| ------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `{vectorName: "..."}` (optionally `{dataclassName: "..."}`) | The matching **saved definition** for the entity's dataclass — deducing its phrase (and, for `embed`, its model). Resolves to nothing when there is no unique match. | +| `{phrase: "tpl {field}"}` or `{template: "tpl {field}"}` | An **ad-hoc** `Phrase` compiled inline; nothing is looked up. Pair with `{modelAlias: "..."}` to give `embed()` a model. | + +For `embed()`, the model is deduced in this order: an explicit `{modelAlias}` on the stub → the model of a stub-matched saved definition → the *model* argument → the entity's unique definition. An explicit `{modelAlias}` always wins. + +Unlike [`Process.process()`](Process.md#process-resolution), a stub is **not** turned into a brand-new `Definition` from its fields — `StudioEmbedder` persists nothing, so use `{phrase}`/`{template}` for one-off templates. + +## Ver también + +- [Process](Process.md) +- [Settings](Settings.md) +- [Definition](Definition.md) +- [Embedder](Embedder.md) +- [EmbedderResult](EmbedderResult.md) +- [Phrase](Phrase.md) From 7669d4280d225d7e7923271fd01448514d0549ae Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:40:27 +0100 Subject: [PATCH 072/195] license.md Spanish --- .../current/embedding-studio/license.md | 167 ++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/license.md diff --git a/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/license.md b/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/license.md new file mode 100644 index 00000000000000..8f6fc0dd2b5ffc --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/license.md @@ -0,0 +1,167 @@ +--- +id: license +title: SOFTWARE LICENSE AGREEMENT +--- + +# SOFTWARE LICENSE AGREEMENT + +## Preamble + +The purpose of this Software license agreement is to grant users the right to modify and re-use the software governed by this license. + +The exercising of this right is conditional upon the obligation to make /available to the community the modifications made to the source code of the software so as to contribute to its evolution. + +In consideration of access to the source code and the rights to copy, modify and redistribute granted by the license, users are provided only with a limited warranty and the software's author, the holder of the economic rights, and the successive licensors only have limited liability. + +## Article 1 – DEFINITIONS + +***Agreement***: means this license agreement, and its possible subsequent versions and annexes. + +***Software***: means the software in its Object Code and/or Source Code form and, where applicable, its documentation, "as is" when the Licensee accepts the Agreement. + +***Initial Software***: means the Software in its Source Code and possibly its Object Code form and, where applicable, its documentation, "as is" when it is first distributed under the terms and conditions of the Agreement. + +***Modified Software***: means the Software modified by at least one Integrated Contribution. + +***Source Code***: means all the Software's instructions and program lines to which access is required so as to modify the Software. + +***Object Code***: means the binary files originating from the compilation of the Source Code. + +***Holder***: means the holder(s) of the economic rights over the Initial Software, in this case it is 4D SAS. + +***Licensee***: means the Software user(s) having accepted the Agreement. + +***Contributor***: means a Licensee having made at least one Integrated Contribution. + +***Licensor***: means the Holder, or any other individual or legal entity, who distributes the Software under the Agreement. + +***Integrated Contribution***: means new functions integrated into the Source Code by any or all Contributors. + +***Parties***: mean both the Licensee and the Licensor. + +These expressions may be used both in singular and plural form. + +## Article 2 - PURPOSE + +The purpose of the Agreement is the grant by the Licensor to the Licensee of a non-exclusive, transferable and worldwide license for the Software as set forth in Article 5 hereinafter for the whole term of the protection granted by the rights over said Software. + +## Article 3 - ACCEPTANCE + +The Licensee shall be deemed as having accepted the terms and conditions of this Agreement upon the occurrence of the first of the following events: + +- loading the Software by any or all means, notably, by downloading from a remote server; +- the first time the Licensee exercises any of the rights granted hereunder. + +## Article 4 - EFFECTIVE DATE AND TERM + +### 4.1 EFFECTIVE DATE + +The Agreement shall become effective on the date when it is accepted by the Licensee as set forth in Article 3. + +### 4.2 TERM + +The Agreement shall remain in force for the entire legal term of protection of the economic rights over the Software. + +## Article 5 - SCOPE OF RIGHTS GRANTED + +The Licensor hereby grants to the Licensee, who accepts, the following rights over the Software for the term of the Agreement, on the basis of the terms and conditions set forth hereinafter. + +### 5.1 RIGHT OF USE + +The Licensee is authorized to use the Software, without any limitation as to its fields of application, with it being hereinafter specified that this comprises: + +- permanent or temporary reproduction of all or part of the Software by any or all means and in any or all form. +- loading, displaying, running, or storing the Software on any or all medium. +- entitlement to observe, study or test its operation. + +### 5.2 RIGHT OF MODIFICATION + +The right of modification means the right to adapt, arrange, or make any or all modifications to the Software; being understood that such modifications of the Software shall results in a change of its functionalities and/or in an addition of functionalities to the Initial Software. + +Consequently to distribute a Modified Software according to the provision of section 5.3.2, the Licensee shall make exclusively significant modification as described above to the Software provided that it includes an explicit notice that it is the author of said modification and indicates the date of the creation thereof. + +### 5.3 RIGHT OF DISTRIBUTION + +In particular, the right of distribution includes the right to publish, transmit and communicate the Modified Software to the general public on any or all medium, and by any or all means, and the right to market, either in consideration of a fee, or + +#### 5.3.1 DISTRIBUTION OF SOFTWARE WITHOUT MODIFICATION + +The Licensee is forbidden to distribute true copies of the Software in Source Code or Object Code form. + +#### 5.3.2 DISTRIBUTION OF MODIFIED SOFTWARE + +When the Licensee creates Modified Software, this Modified Software may be distributed provided that said distribution complies with all the provisions of the Agreement and subject to compliance with the requirement to include a notice concerning the rights over the Software as defined in Article 6.3. + +In the event the creation of the Modified Software, the Licensee undertakes that: + +- the resulting Modified Software will be governed by this Agreement, being understood that such Agreement shall be integrated in the Modified Software the Integrated Contributions in the resulting Modified Software will be clearly identified and documented, +- the Licensee will allow effective access to the source code of the Modified Software, at a minimum during the entire period of distribution of the Derivative Software, such that such modifications may be carried over in a subsequent version of the Software. +- the Modified Software must be renamed to exclude any reference to 4D. For example, it is expressly prohibited to distribute a Modified Software named “4D SVG”; Licensee shall rename the Modified Software such as “Name of the Licensee SVG”. Consequently, Licensee is expressly forbidden to use 4D’s product name in general to promote his modified work. + +## Article 6 - INTELLECTUAL PROPERTY + +### 6.1 OVER THE INITIAL SOFTWARE + +The Holder owns the intellectual property rights over the Initial Software. Any or all use of the Initial Software is subject to compliance with the terms and conditions under which the Holder has elected to distribute its work and no one shall be entitled to modify the terms and conditions for the distribution of said Initial Software. + +### 6.2 OVER THE INTEGRATED CONTRIBUTIONS + +The Licensee who develops an Integrated Contribution is the owner of the intellectual property rights over this Contribution as defined by applicable law. + +### 6.3 NOTICE OF RIGHTS + +The Licensee expressly undertakes: + +- not to remove, or modify, in any manner, the intellectual property notices attached to the Software; +- to reproduce said notices, in an identical manner, in the copies of the Software modified; +- to ensure that use of the Software, its intellectual property notices and the fact that it is governed by the Agreement is indicated in a text that is easily accessible, specifically from the interface of any Modified Software. + +The Licensee undertakes not to directly or indirectly infringe the intellectual property rights of the Holder on the Software and to take, where applicable, vis- à-vis its staff, any and all measures required to ensure respect of said intellectual property rights of the Holder. + +## Article 7 - RELATED SERVICES + +Under no circumstances shall the Agreement oblige the Licensor to provide technical assistance or maintenance services for the Software. + +However, the Licensor is entitled to offer this type of services. The terms and conditions of such technical assistance, and/or such maintenance, shall be set forth in a separate instrument. + +## Article 8 - DISCLAIMER OF WARRANTY. + +THERE IS NO WARRANTY FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE HOLDER PROVIDES THE SOFTWARE “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH LICENSEE. SHOULD THE SOFTWARE PROVE DEFECTIVE, LICENSEE ASSUMES THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +## Article 9 - LIMITATION OF LIABILITY + +TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE TO LICENSEE ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS AGREEMENT OR USE OF THE SOFTWARE, EVEN IF THE LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR DAMAGES. + +## Article 10 – TERMINATION + +### 10.1 + +In the event of a breach by the Licensee of its obligations hereunder, the Licensor may automatically terminate this Agreement thirty (30) days after notice has been sent to the Licensee and has remained ineffective. + +### 10.2 + +A Licensee whose Agreement is terminated shall no longer be authorized to use, modify or distribute the Software. However, any licenses that it may have granted prior to termination of the Agreement shall remain valid subject to their having been granted in compliance with the terms and conditions hereof. + +## Article 11 – MISCELLANEOUS + +### 11.1 + +Neither Party shall be liable for any or all delay, or failure to perform the Agreement, that may be attributable to an event of force majeure, an act of God or an outside cause, such as defective functioning or interruptions of the electricity or telecommunications networks, network paralysis following a virus attack, intervention by government authorities, natural disasters, water damage, earthquakes, fire, explosions, strikes and labor unrest, war, etc. + +### 11.2 + +Any failure by either Party, on one or more occasions, to invoke one or more of the provisions hereof, shall under no circumstances be interpreted as being a waiver by the interested Party of its right to invoke said provision(s) subsequently. + +### 11.3 + +In the event that one or more of the provisions hereof were to conflict with a current or future applicable act or legislative text, said act or legislative text shall prevail, and the Parties shall make the necessary amendments so as to comply with said act or legislative text. All other provisions shall remain effective. Similarly, invalidity of a provision of the Agreement, for any reason whatsoever, shall not cause the Agreement as a whole to be invalid. + +## Article 12 - GOVERNING LAW AND JURISDICTION + +### 12.1 + +The Agreement is governed by French law. The Parties agree to endeavor to seek an amicable solution to any disagreements or disputes that may arise during the performance of the Agreement. + +### 12.2 + +Failing an amicable solution within two (2) months as from their occurrence, and unless emergency proceedings are necessary, the disagreements or disputes shall be referred to the Versailles Courts having jurisdiction, by the more diligent Party. \ No newline at end of file From a46cb41abe88b69829b10d944e438c53602f198c Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:40:29 +0100 Subject: [PATCH 073/195] overview.md Spanish --- .../current/embedding-studio/overview.md | 211 ++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/overview.md diff --git a/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/overview.md b/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/overview.md new file mode 100644 index 00000000000000..a45d58e4af31a5 --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/overview.md @@ -0,0 +1,211 @@ +--- +id: overview +title: 4D-Embedding-Studio +--- + +# 4D-Embedding-Studio + +## Generalidades + +4D Embedding Studio is a component for defining, processing, and maintaining AI embedding vectors directly in your 4D dataclass entities. + +You can use the component without writing a single line of code: select attributes from your dataclasses to construct the sentences to be vectorized and specify the model to use. For each entity, the component calls the embedding API and stores the resulting `4D.Vector` values. Configure the embedding scheduler to (re)calculate the vectors for your data at fixed intervals or on demand. + +You can then use the ORDA [`query()` by vector feature](https://developer.4d.com/docs/API/DataClassClass#query-by-vector-similarity) to request your data using semantics. + +If you want to have more control over your embeddings, the component offers an extensive API that allows you to customize each step of the data vectorization process, manage the scheduler, and integrate high-performance RAG (*Retrieval Augmented Generation*) features into your 4D application. + +## Requisitos + +- [4D-AIKit](https://github.com/4d/4D-AIKit) (loaded automatically as a dependency). +- 4D project (21 R5 or later) with the following configuration: + - a valid model alias + - a dataclass with a `4D.Vector` attribute (object field at the database level). + +## Quick Start + +**1. Add a field of type Object to the table and associate it with the `4D.Vector` class.** +**2. Select **Embedding Studio...** in the **Design** menu to display the Embedding Studio window.** + +![menu](../assets/en/embedding-studio/menu.png) + +**3. For each listed `4D.Vector` attribute, write a descriptive phrase based upon attributes of the dataclass.** +Use the contextual menu to insert appropriate attributes. +This phrase will be vectorized for every entity. +**4. Select a model alias (or create a new one).** +**5. Select "Execute now" to launch the vectorization of your data or configure the scheduler.** + +## User Guide + +### Configuring the dataclass + +To use the 4D Embedding Studio interface, you need to create at least one object attribute associated to a `4D.Vector` class in your datastore. This must be done at the database level (only storage attributes can be embeddings). + +In the Structure editor, add an Object field to the dataclass (table) whose entities you want to query using AI and enter ["4D.Vector" as class](https://developer.4d.com/docs/Develop/structure-fields#class). + +#### Dirty-flag support + +In a production application, data is rarely static. If an embedding is based on an attribute value that has changed (e.g. a product description), it becomes obsolete and could no longer be relevant. By default, 4D automatically invalidates and flags for recalculation affected embeddings. + +If you do not use a dirty-flag field (see below), 4D simply replaces any invalidated vector by `Null`. It is therefore no longer used in searches until its next calculation. This option is suitable for applications that prioritize strict consistency: it is better to return no results than to rely on an embedding that no longer matches the current data. + +Or, you can add a Boolean field named `_dirty` (e.g. "myVector_dirty") to the structure. In this case, when an update is required, this field is set to `True`, and the associated vector is retained until it is recalculated. Your application can then choose to continue using this vector temporarily or exclude it using a filter on `dirty = False`. The flag is cleared automatically after a successful save. +This strategy promotes service continuity while allowing you to precisely identify vectors awaiting recalculation. If your business logic requires full control, you can also disable automatic invalidation and manage this lifecycle yourself. + +*Note: Certain modifications, such as a model changes, require vectors to be replaced immediately.* + +### Creating an embedding + +When you select **Embedding Studio...** in the **Design** menu, the Embedding Studio window is displayed. + +The list on the left side shows all `4D.Vector` class attributes defined in the datastore. You can add as many vector attributes as you want per dataclass. + +A check mark (✓) in the Dirty Flag column indicates that a [`_dirty` boolean field](#dirty-flag-support) is associated to the vector field. + +**Note:** Any change in the database structure will require that you restart the 4D application so that the 4D Embedding Studio lists up-to-date values. + +#### Writing a descriptive sentence + +To create or edit an embedding, select the attribute to configure in this list and write the embedding definition in the "Descriptive sentence" area on the right side. Use the associated menu to build the sentence and to add references to dataclass available attributes with the `{attribute_name}` syntax. + +The sentence must build a text that describes the entity just like a human would do it. The embedding could then capturate the semantics and not only attribute values. + +For example, for a `Product` dataclass with many attributes such as name and category, you could write: +"The {name} product is a {category} from the {brand} brand. Description: {description}. Key features: {features}." + +![menu](../assets/en/embedding-studio/studio-interface.png) + +### Selecting a model + +Once you have defined your vector attribute, choose the model to use for generating the embedding. The list of models includes the **model aliases** you defined in the [Project Settings](https://developer.4d.com/docs/settings/ai#model-aliases). + +The choice of model is important because it determines the relevance and quality of your embeddings. You’ll also need to provide this model with every query on the dataclass data so that the comparison is performed using the same model. + +### Auto-invalidate on save + +When this option is checked (default), embeddings are automatically invalidated when at least one of their definition attributes has been modified and the entity was successfully saved. + +However, you might want to handle invalidation in a custom way using the [4D Embedding Studio API](#api-guide). In this case, uncheck this option to disable the automatic mechanism. + +### Calculating embeddings + +Embeddings are calculated by sending a request to the AI model, which then returns the vectorization result, which is subsequently stored in the `4D.Vector` attribute in the dataclass. 4D automatically handles this operation and optimizes it by calculating only the necessary vectors. Each vector is processed independently. Thus, an error on one element does not interrupt the recalculation of the others. Elements that fail will be automatically retried during the next run. Recalculations are performed asynchronously, without blocking users. + +These calculations can be performed **on demand** or **scheduled at regular intervals** using the scheduler in the 4D Embedding Studio component. + +**Note:** You can also customize embedding calculations per dataclass or entity using the [4D Embedding Studio API](#api-guide). + +#### On demand + +To launch an embedding calculation, select **Run now** in the menu at the bottom of the 4D Embedding Studio window. This item is disabled if the datastore does not contain any embedding to calculate. When started, you can select **Cancel run** at any moment. + +#### Backups periódicos + +You can configure the 4D Embedding Studio component scheduler to adjust the calculation frequency to suit your application’s needs. + +**Important:** The scheduler needs a 4D worker process to run. You can start it manually for testing purposes (**Start now** button in the scheduler dialog box) but to make sure a worker is available every times the application opens, you need to configure it. Puede: + +- select the **Execute "On Host Database Event" method of the components** option in the [project Settings](https://developer.4d.com/docs/settings/security#options) +- or write the following code in your startup code: + +```4d + //at startup +cs.EmbeddingStudio.Scheduler.me.start() +``` + +The scheduler allows you can set the time interval between two calculations. Select the tab corresponding to your needs and click **Save**. + +- **Never**: the scheduler is off and never runs +- **At regular interval**: set the time interval between each calculation starting from a specified time. +- **Once a day**: the calculation takes place every day at a specific time + starting from a specific time. + +### Building queries with embeddings + +Once you have defined embeddings in your datastore, you can start [querying your dataclasses using AI-based features](https://developer.4d.com/docs/API/DataClassClass#query-by-vector-similarity). You just need to make sure that you use the same model for your embedding definition and in the query string. + +For example, assuming that: + +• you have defined a `4D.Vector` attribute named "product_vector" in the Products dataclass using a sentence: "The {name} is in the {category} category. It has these {features} features and can be used for {usage}." +• you want to find products that "can be used safely outside". + +Puede escribir: + +```4d +// Retrieve the model alias from the embedding definition, configured in 4D Embedding Studio +var $settings:=cs.EmbeddingStudio.Settings.new() +var $definition:=$settings.find("Products"; "product_vector") + +// Compute the vector of the query with the same model +var $result:=cs.EmbeddingStudio.StudioEmbedder.new().embed("products that can be used safely outside"; $definition) +var $vector:=$result.vector + + //search with default metric (cosine) +var $products:=ds.Products.query("product_vector > :1 order by product_vector desc"; {vector : $vector}) + +``` + +If you use a dirty field, simply add a criterion to exclude vectors waiting to be recalculated: + +```4d +var $products:=ds.Products.query("product_vector > :1 and product_vector_dirty = false order by product_vector desc"; {vector : $vector}) +``` + +## API Guide + +### Quick start + +**1. Configure your vectors** in `Settings/embeddings.json`: + +```json +{ + "batchSize": 50, + "definitions": [ + { + "dataclassName": "Students", + "vectorName": "student_vector_1", + "modelAlias": "text-embedding", + "phrase": "Student {firstName} {lastName}, enrolled in {program}", + "autoInvalidate": true + } + ] +} +``` + +**2. Run the full pipeline** (all definitions, all records): + +```4d +var $p:=cs.EmbeddingStudio.Process.new() +var $r:=$p.process() + +If ($r.success) + ALERT("Updated "+String($r.entitiesUpdated)+" entities in "+String($r.duration)+" ms") +End if +``` + +**3. Process a single entity on save** (e.g. in a trigger or REST hook): + +```4d +var $p:=cs.EmbeddingStudio.Process.new() +$p.processEntity($entity) +``` + +### Class reference + +| Class | Descripción | +| ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [Process](Classes/Process.md) | Main orchestrator — entry point for all batch and entity operations. | +| [Scheduler](Classes/Scheduler.md) | Automated recalculation scheduler — background task, force/cancel, and runtime status. | +| [StudioEmbedder](Classes/StudioEmbedder.md) | Renders and embeds on demand using your saved definitions — e.g. to build a search query vector. Nothing is persisted. | +| [Settings](Classes/Settings.md) | Loads and saves the `embeddings.json` configuration file. | +| [Definition](Classes/Definition.md) | Describes one vector field: dataclass, field name, model alias, and phrase template. | +| [Embedder](Classes/Embedder.md) | Thin wrapper around the AIKit embeddings API with retry/backoff logic. | +| [EmbedderResult](Classes/EmbedderResult.md) | Typed wrapper normalizing API responses — vectors, usage metrics, rate-limit state. | +| [ProcessResult](Classes/ProcessResult.md) | Returned by every batch function — statistics and error breakdown. | +| [ProcessError](Classes/ProcessError.md) | Typed entry in `ProcessResult.errors` — scope, severity, code, ref, message, retryable. | +| [ProcessErrorCode](Classes/ProcessErrorCode.md) | Singleton catalogue of machine-readable error codes and their default severity/retryability. | +| [Phrase](Classes/Phrase.md) | Lightweight `{variable}` template engine used to build text from entity attributes. | + +### Ver también + +Blog post: [Vectorize your data effortlessly with 4D Embedding Studio](https://blog.4d.com/vectorize-your-data-effortlessly-with-4d-vector-studio) \ No newline at end of file From 229a9759ef8616877946e3bed8068f124c52d5b7 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:40:31 +0100 Subject: [PATCH 074/195] ratelimit.md Spanish --- .../current/embedding-studio/ratelimit.md | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/ratelimit.md diff --git a/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/ratelimit.md b/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/ratelimit.md new file mode 100644 index 00000000000000..ac90518d4805db --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/current/embedding-studio/ratelimit.md @@ -0,0 +1,65 @@ +--- +id: ratelimit +title: Rate Limiting +--- + +# Rate Limiting + +The embedding pipeline includes built-in rate-limit awareness. When the API provider returns rate-limit headers (as OpenAI does), the system automatically throttles requests and adapts batch sizes to stay within budget. Providers that don't return rate-limit headers (e.g. Ollama) are unaffected — the pipeline runs at full speed. + +## Principios de funcionamiento + +Each call to [`Embedder.embed()`](Classes/Embedder.md) or [`Embedder.embedBatch()`](Classes/Embedder.md) returns an [`EmbedderResult`](Classes/EmbedderResult.md) that carries rate-limit state alongside the embedding vectors. The pipeline uses this data in a three-step loop: + +1. **Pre-flight throttle** — before sending a batch, the pipeline checks whether the remaining token budget is sufficient. If not, it waits for the reset window to elapse before proceeding. +2. **Adaptive batch sizing** — the pipeline computes the largest batch that fits within 80% of the remaining token budget. This avoids hitting the ceiling while still making efficient use of the quota. +3. **State update** — after each API response, the pipeline records the new remaining budget, computes an average tokens-per-entity estimate, and feeds both into the next iteration. + +## Rate-limit fields on EmbedderResult + +These fields are populated from the API response headers. When a provider doesn't return them, they keep their defaults and the pipeline skips throttling. + +| Campo | Por defecto | Significado | +| ------------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------- | +| `remainingTokens` | `-1` | Tokens left in the current window. `-1` = unknown. | +| `remainingRequests` | `-1` | Requests left in the current window. | +| `limitTokens` | `0` | TPM (tokens per minute) ceiling. | +| `limitRequests` | `0` | RPM (requests per minute) ceiling. | +| `resetTokens` | `""` | Time until the token bucket refills (e.g. `"6m0s"`, `"200ms"`). | +| `resetRequests` | `""` | Time until the request bucket refills. | + +## Batch size adaptation + +The pipeline starts with the configured `batchSize` (from [Settings](Classes/Settings.md), default 50). After the first API response provides rate-limit data, the batch size may shrink: + +``` +nextBatchSize = min( floor(remainingTokens × 0.8 / tokensPerEntity), configBatchSize ) +``` + +- `tokensPerEntity` is estimated from the last chunk (`totalTokens / chunkSize`). +- The result is clamped to a floor of 1 and a ceiling of `configBatchSize`. +- When `remainingTokens` is unknown (`-1`), the configured batch size is used as-is. + +## Pre-flight wait + +Before each batch, the pipeline checks: + +- **Token budget**: if `remainingTokens < estimatedTokens × 1.1`, it waits for the token reset window. +- **Request budget**: if `remainingRequests = 0`, it waits for the request reset window. + +The reset durations are parsed from the API's string format (`"6m0s"` → 360 seconds, `"200ms"` → 1 second). + +## Providers without rate limits + +Some providers (Ollama, local models) don't return rate-limit headers. En este caso: + +- `remainingTokens` stays at `-1` (unknown) +- No throttling occurs — batches run at `configBatchSize` without waits +- The pipeline works identically to how it did before rate-limit support was added + +## Ver también + +- [EmbedderResult](Classes/EmbedderResult.md) — carries rate-limit fields +- [Embedder](Classes/Embedder.md) — wraps the API calls +- [Process](Classes/Process.md) — orchestrates the batch loop +- [Settings](Classes/Settings.md) — `batchSize` configuration From 3a82abd770c857b86c8029162f42738882785783 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:40:33 +0100 Subject: [PATCH 075/195] menu.png Spanish --- .../assets/en/embedding-studio/menu.png | Bin 0 -> 4938 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 i18n/es/docusaurus-plugin-content-docs/version-21-R5/assets/en/embedding-studio/menu.png diff --git a/i18n/es/docusaurus-plugin-content-docs/version-21-R5/assets/en/embedding-studio/menu.png b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/assets/en/embedding-studio/menu.png new file mode 100644 index 0000000000000000000000000000000000000000..425fd0d7e65879e34700b856cf6f88aaa9c502e1 GIT binary patch literal 4938 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 E0Cv$VrvLx| literal 0 HcmV?d00001 From e8c64a0f285c248f70edc0bf216f395d4d6205f3 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:40:35 +0100 Subject: [PATCH 076/195] studio-interface.png Spanish --- .../en/embedding-studio/studio-interface.png | Bin 0 -> 34492 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 i18n/es/docusaurus-plugin-content-docs/version-21-R5/assets/en/embedding-studio/studio-interface.png diff --git a/i18n/es/docusaurus-plugin-content-docs/version-21-R5/assets/en/embedding-studio/studio-interface.png b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/assets/en/embedding-studio/studio-interface.png new file mode 100644 index 0000000000000000000000000000000000000000..75dae7c9303297334e2fee1b404527957dfd4746 GIT binary patch literal 34492 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 Z0#D?x@H3fRStk8kMM>jk;f?!G{uip+WAXq1 literal 0 HcmV?d00001 From 334c5dedbbc14476177b88d8576c44f87a89b0ce Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:40:38 +0100 Subject: [PATCH 077/195] definition.md Spanish --- .../embedding-studio/Classes/Definition.md | 165 ++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Definition.md diff --git a/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Definition.md b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Definition.md new file mode 100644 index 00000000000000..f0ba84a11ef136 --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Definition.md @@ -0,0 +1,165 @@ +--- +id: definición +title: Definición +--- + +# Definición + +The `Definition` class describes how a single vector field on a dataclass should be computed: which dataclass, which vector field, which model alias, and which text template ([Phrase](Phrase.md)) to render from each entity. + +A collection of these is what [Settings](Settings.md) persists. + +## Propiedades + +| Nombre de la propiedad | Tipo | Descripción | +| ---------------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------- | +| `dataclassName` | Text | Name of the target dataclass. | +| `vectorName` | Text | Name of the `4D.Vector` field on that dataclass. | +| `modelAlias` | Text | Embedding model alias (e.g. `"text-embedding-3-small"`). | +| `phrase` | [Phrase](Phrase.md) | Compiled template used to build the text that will be embedded. | +| `autoInvalidate` | Boolean | Controls automatic invalidation on entity save. Default: `True`. | + +## Class constructor + +Create a definition. + +| Nombre del argumento | Tipo | Descripción | +| -------------------- | ---- | -------------------------------------------------------------------------------------------------- | +| *dataclassName* | Text | Name of the target dataclass. | +| *vectorName* | Text | Name of the target vector field. | +| *modelAlias* | Text | Embedding model alias. | +| *phraseTemplate* | Text | Phrase template with `{field}` placeholders — compiled into a [Phrase](Phrase.md). | + +```4d +var $def:=cs.EmbeddingStudio.Definition.new(\ + "Students"; \ + "student_vector_1"; \ + "text-embedding-3-small"; \ + "Student {firstName} {lastName}") +``` + +## Propiedades calculadas + +### hasDefinition + +**hasDefinition** : Boolean *(read-only)* + +Returns `True` if at least a model or a phrase template has been set. A definition without either has no content to process. + +```4d +If ($def.hasDefinition) + // worth validating further +End if +``` + +## Funciones + +### validate() + +**validate**( *settings* : Settings ) : Object + +Validates the definition against the live datastore model and the known embedding models. All errors are collected before returning — the result always describes the full set of problems found. + +| Argumento | Tipo | Descripción | +| ---------- | ------------------------------- | ------------------------------------------------------------------------------------------------------------ | +| *settings* | [Settings](Settings.md) \| Null | Used to pass phrase validation options. Pass `Null` to skip phrase options. | +| Resultado | Object | `{success: Boolean, errors: Collection}` where each error is `{field: Text, message: Text}`. | + +Checked in order: + +| Check | `field` value | +| ------------------------------------ | ----------------- | +| `dataclassName` is not empty | `"dataclassName"` | +| `vectorName` is not empty | `"vectorName"` | +| `modelAlias` is set and recognised | `"modelAlias"` | +| Dataclass exists in `ds` | `"dataclassName"` | +| Vector field exists | `"vectorName"` | +| Field type is `4D.Vector` | `"vectorName"` | +| Phrase template is not empty | `"phrase"` | +| Phrase keys resolve in the dataclass | `"phrase"` | + +The first two checks (identity) return immediately on failure; the remaining checks accumulate so all problems are reported in one pass. + +```4d +var $result:=$def.validate(cs.EmbeddingStudio.Settings.new()) + +If (Not($result.success)) + var $err : Object + For each ($err; $result.errors) + TRACE // $err.field, $err.message + End for each +End if +``` + +### invalidateVectors() + +**invalidateVectors**() : Object + +Marks all already-computed entities for re-embedding, forcing a full rebuild on the next run. Only entities that already have a vector value are processed — entities with a `Null` vector are skipped. + +Useful during development or after a model/phrase change to trigger a clean rebuild of all vectors. + +The strategy depends on whether a companion `_dirty` field exists on the dataclass: + +| Companion `_dirty` field | Action taken | +| ------------------------ | -------------------------------------------------------------- | +| Present | Sets `_dirty` to `True` — vector is left untouched | +| Absent | Nullifies the vector field | + +| Argumento | Tipo | Descripción | +| --------- | ------ | ------------------------------------------------------------------ | +| Resultado | Object | `{updated: Integer, skipped: Integer, errors: Collection of Text}` | + +- `updated` — number of entities successfully marked +- `skipped` — number of entities that could not be saved +- `errors` — one entry per save failure, formatted as `"DataclassName: statusText"` + +```4d +var $result:=$def.invalidateVectors() + +If ($result.skipped > 0) + var $e : Text + For each ($e; $result.errors) + // $e + End for each +End if +// → { updated: 42; skipped: 0; errors: [] } +``` + +### toObject() + +**toObject**() : Object + +Returns a plain object suitable for JSON persistence. The phrase is flattened to its template text. + +| Argumento | Tipo | Descripción | +| --------- | ------ | --------------------------------------------------------------------------------------------------------------------------------- | +| Resultado | Object | `{version, dataclassName, vectorName, modelAlias, phrase, autoInvalidate}` where `phrase` is the template string. | + +```4d +$def.toObject() +// → { version: 0; dataclassName: "Students"; vectorName: "student_vector_1"; +// modelAlias: "text-embedding-3-small"; phrase: "Student {firstName} {lastName}"; +// autoInvalidate: true } +``` + +## Automatic invalidation + +`autoInvalidate` controls whether save-time automatic invalidation is enabled for this definition. + +- `True` (default): when relevant attributes change on an entity save, vectors are automatically invalidated. +- `False`: save-time automatic invalidation is skipped for this definition. + +This setting does not affect manual invalidation via `invalidateVectors()`. + +## Dirty flag convention + +The pipeline in [Process](Process.md) will recompute an entity whenever the target vector is `Null`, or when a sibling field `_dirty` exists on the dataclass and is `True`. + +Declaring the dirty flag is optional — when absent, only the null-vector case triggers recomputation. When present, it is cleared automatically on successful save. + +## Ver también + +- [Settings](Settings.md) +- [Process](Process.md) +- [Phrase](Phrase.md) From e2bc87a583f4a5817cada373e974382c4778db89 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:40:40 +0100 Subject: [PATCH 078/195] embedder.md Spanish --- .../embedding-studio/Classes/Embedder.md | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Embedder.md diff --git a/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Embedder.md b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Embedder.md new file mode 100644 index 00000000000000..211a2476dbd758 --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Embedder.md @@ -0,0 +1,96 @@ +--- +id: embedder +title: Embedder +--- + +# Embedder + +The `Embedder` class is a thin wrapper around [4D AIKit](https://developer.4d.com/docs/aikit/Classes/openai) focused on embeddings. It exposes two functions — one for a single text, one for a batch — and handles retries with exponential backoff (respecting the `Retry-After` header when present). + +It is stateless beyond configuration and safe to share between processes. + +## Propiedades + +| Nombre de la propiedad | Tipo | Descripción | +| ---------------------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | +| `client` | cs.AIKit.OpenAI | The underlying AIKit client used for HTTP requests. | +| `maxRetries` | Integer | Maximum number of retries on transient errors. Default: `3`. | +| `backoffMs` | Integer | Base delay (ms) between retries. Doubled each attempt. | + +## Class constructor + +Create a embedder. All options are optional. + +| Nombre del argumento | Tipo | Descripción | +| -------------------- | ------ | ----------------------------------------------------------------------------- | +| *opciones* | Object | `{client, maxRetries, backoffMs}` — any field may be omitted. | + +```4d +// Default — uses cs.AIKit.OpenAI.new() internally +var $proc:=cs.EmbeddingStudio.Embedder.new() + +// Provide a pre-configured AIKit client (custom API key, base URL, etc.) +var $client:=cs.AIKit.OpenAI.new({apiKey: "…"; baseURL: "https://server.ai"}) +var $proc:=cs.EmbeddingStudio.Embedder.new({client: $client; maxRetries: 5; backoffMs: 1000}) +``` + +> If the 4D AIKit component is not loaded (or is too old to provide `OpenAIProviders`), the constructor still succeeds with a `Null` client, and the first `embed()` / `embedBatch()` call throws an error whose `message` explains what is missing and whose `isAIKitMissing` property is `True`. + +## Funciones + +### embed() + +**embed**(*text* : Text ; *model* : Text) : [cs.EmbeddingStudio.EmbedderResult](EmbedderResult.md) + +Embed a single text. Returns a typed result with the embedding vector, token usage, and rate-limit state. + +| Argumento | Tipo | Descripción | +| --------- | -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| *text* | Text | The text to vectorize. | +| *model* | Text | The embedding model to use (e.g. `"text-embedding-3-small"`). | +| Resultado | [cs.EmbeddingStudio.EmbedderResult](EmbedderResult.md) | Typed wrapper — `.vector` holds the embedding, `.promptTokens` / `.totalTokens` hold usage, rate-limit fields are flat camelCase. | + +Throws if retries are exhausted or the API returns a non-retryable error. + +```4d +var $result:=$proc.embed("it rains cats and dogs"; "text-embedding-3-small") +// $result.vector → 4D.Vector +// $result.promptTokens → Integer +// $result.totalTokens → Integer +// $result.remainingTokens → Integer (-1 if unknown) +``` + +### embedBatch() + +**embedBatch**(*texts* : Collection ; *model* : Text) : [cs.EmbedderResult](EmbedderResult.md) + +Embed a collection of texts in a single API call. Returns a typed result with vectors in the same order as inputs, token usage, and rate-limit state. + +| Argumento | Tipo | Descripción | +| --------- | ------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------- | +| *texts* | Collection | Collection of Text to vectorize. Empty or `Null` returns an empty result. | +| *model* | Text | The embedding model to use. | +| Resultado | [cs.EmbedderResult](EmbedderResult.md) | Typed wrapper — `.vectors` holds the embeddings collection, token and rate-limit fields are flat camelCase. | + +```4d +var $result:=$proc.embedBatch(["hello"; "world"]; "text-embedding-3-small") +// $result.vectors[0] → 4D.Vector for "hello" +// $result.vectors[1] → 4D.Vector for "world" +// $result.totalTokens → Integer (sum for the batch) +// $result.remainingTokens → Integer (after this call) +``` + +## Retry policy + +Transient errors (HTTP 408, 409, 429, 5xx) are retried up to `maxRetries` times. + +- If the response carries a `Retry-After` or `retry-after-ms` header, the embedder waits that long. +- Otherwise, it waits `backoffMs * 2^attempt`. + +Non-retryable errors are thrown immediately — see [OpenAIError](https://developer.4d.com/docs/aikit/Classes/openaierror) for the thrown shape. + +## Ver también + +- [EmbedderResult](EmbedderResult.md) +- [Process](Process.md) +- [OpenAIEmbeddingsAPI](https://developer.4d.com/docs/aikit/Classes/openaiembeddingsapi) (AIKit) From 89dfaaba757641d61afe740f3c34f9247d37fb19 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:40:42 +0100 Subject: [PATCH 079/195] embedderresult.md Spanish --- .../Classes/EmbedderResult.md | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/EmbedderResult.md diff --git a/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/EmbedderResult.md b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/EmbedderResult.md new file mode 100644 index 00000000000000..b0da967bd3ba2f --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/EmbedderResult.md @@ -0,0 +1,80 @@ +--- +id: embedderresult +title: EmbedderResult +--- + +# EmbedderResult + +Typed wrapper for `Embedder.embed()` and `Embedder.embedBatch()` responses. Normalizes OpenAI's snake_case API keys (`prompt_tokens`, `total_tokens`) to camelCase properties, and flattens the nested rate-limit structure into direct properties. + +A single class handles both single and batch results — `embed()` populates `.vector`, `embedBatch()` populates `.vectors`. + +## Propiedades + +### Embedding results + +| Propiedad | Tipo | Por defecto | Descripción | +| --------- | ------------------------- | ----------- | ------------------------------------------------------------------------------ | +| `vector` | 4D.Vector | Null | Single embedding result. Null for batch calls. | +| `vectors` | Collection | `[]` | Batch embedding results. | + +### Token usage + +| Propiedad | Tipo | Por defecto | Descripción | +| -------------- | ------- | ----------- | -------------------------------------------------------------------- | +| `promptTokens` | Integer | `0` | Input tokens consumed. | +| `totalTokens` | Integer | `0` | Total tokens consumed (in + out). | + +### Rate-limit state + +| Propiedad | Tipo | Por defecto | Descripción | +| ------------------- | ------- | ----------- | ------------------------------------------------------------------------------------------------------------------- | +| `remainingTokens` | Integer | `-1` | Tokens left in the current window. `-1` = unknown. | +| `remainingRequests` | Integer | `-1` | Requests left in the current window. `-1` = unknown. | +| `limitTokens` | Integer | `0` | TPM ceiling for the account. | +| `limitRequests` | Integer | `0` | RPM ceiling for the account. | +| `resetTokens` | Text | `""` | Time until token bucket refills (e.g. `"6m0s"`). | +| `resetRequests` | Text | `""` | Time until request bucket refills (e.g. `"1s"`). | + +## Class constructor + +```4d +// From a real API result (used by Embedder internally) +var $result:=cs.EmbedderResult.new($aikitResult; True) // batch +var $result:=cs.EmbedderResult.new($aikitResult; False) // single + +// Empty result (no API call — e.g. empty batch) +var $result:=cs.EmbedderResult.new() +``` + +| Argumento | Tipo | Descripción | +| ----------- | ------- | ------------------------------------------------------------------------------------------------------------ | +| *resultado* | Object | An object with `.vector`/`.vectors`, `.usage`, `.rateLimit` (duck-typed). | +| *isBatch* | Boolean | `True` to read `.vectors`, `False` to read `.vector`. | + +The constructor accepts any object that exposes the expected shape — it does not require a specific class. This makes it easy to construct in tests. + +## Utilización + +```4d +// Single embedding +var $r:=$embedder.embed("hello world"; "text-embedding-3-small") +$r.vector // → 4D.Vector +$r.promptTokens // → 6 +$r.totalTokens // → 6 + +// Batch embedding +var $r:=$embedder.embedBatch(["hello"; "world"]; "text-embedding-3-small") +$r.vectors.length // → 2 +$r.totalTokens // → 10 + +// Rate-limit awareness +$r.remainingTokens // → 148230 (or -1 if not yet known) +$r.resetTokens // → "6m0s" +``` + +## Ver también + +- [Embedder](Embedder.md) — creates EmbedderResult instances +- [ProcessResult](ProcessResult.md) — run-level report that accumulates EmbedderResult usage +- [Rate Limiting](../RateLimit.md) — how the pipeline uses rate-limit fields for throttling and batch sizing From d33c2321f985acd7cfcade3a4f2d4f15f80df5fd Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:40:44 +0100 Subject: [PATCH 080/195] phrase.md Spanish --- .../embedding-studio/Classes/Phrase.md | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Phrase.md diff --git a/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Phrase.md b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Phrase.md new file mode 100644 index 00000000000000..43155973191b05 --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Phrase.md @@ -0,0 +1,117 @@ +--- +id: phrase +title: Phrase +--- + +# Phrase + +The `Phrase` class is a lightweight template engine: a template with `{variable}` placeholders is compiled once, then rendered efficiently against different data objects. + +## Propiedades + +| Nombre de la propiedad | Tipo | Descripción | +| ---------------------- | ---------- | ---------------------------------------------------------------------------------------------------------------------- | +| `template` | Text | Computed — returns the original template string. | +| `keys` | Collection | Computed — returns the variable names found in the template, dot-notation keys joined back to strings. | + +## Class constructor + +Compile a template. Compilation walks the template once and extracts static parts and variable paths. + +| Nombre del argumento | Tipo | Descripción | +| -------------------- | ---- | ---------------------------------------------------------- | +| *template* | Text | Template string with `{variable}` markers. | + +```4d +var $tpl:=cs.EmbeddingStudio.Phrase.new("Hello {firstName}, you study at {schoolName}.") +$tpl.keys // → ["firstName"; "schoolName"] +``` + +## Funciones + +### render() + +**render**(*data* : Object) : Text + +Render the compiled template by replacing variables with values from *data*. Missing keys produce an empty string. + +| Argumento | Tipo | Descripción | +| --------- | ------ | ------------------------------------------------------------------------------------------------------ | +| *data* | Object | A plain object or a 4D.Entity whose fields supply the variable values. | +| Resultado | Text | The rendered text. | + +```4d +var $text:=$tpl.render({firstName: "Alice"; school: {name: "MIT"}}) +// → "Hello Alice, you study at MIT." + +// Works directly on entities +$text:=$tpl.render(ds.Students.first()) +``` + +### validate() + +**validate**(*dataclass* : 4D.DataClass ; *options* : Object) : Object + +Validate that all keys in the phrase can be resolved against the given dataclass. Walks dot-notation paths through N:1 / 1:1 relations. + +| Argumento | Tipo | Descripción | +| ----------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| *dataclass* | 4D.DataClass | The dataclass to validate against. | +| *opciones* | Object | Optional validation flags (see below). All default to `False` — storage kind only. | +| Resultado | Object | `{success: Boolean, errors: Collection of {key, message}}`. | + +#### Opciones + +| Campo | Tipo | Por defecto | Descripción | +| ----------------- | ------- | ----------- | ----------------------------------------------------------------------------------------------------- | +| `allowRelations` | Boolean | `False` | Allow dot-notation paths through N:1 / 1:1 relations. | +| `allowCalculated` | Boolean | `False` | Allow calculated attributes. | +| `allowAlias` | Boolean | `False` | Allow alias attributes. | + +```4d +var $tpl:=cs.EmbeddingStudio.Phrase.new("{firstName} at {school.name}") + +// Storage-only validation — fails because {school.name} uses a relation +var $v:=$tpl.validate(ds.Students) +// $v.success → False +// $v.errors → [{key: "school.name"; message: "..."}] + +// Allow relations +$v:=$tpl.validate(ds.Students; {allowRelations: True}) +// $v.success → True +``` + +#### Rejected shapes + +Regardless of options: + +- Attributes that do not exist on the dataclass. +- Attributes whose class ID is `4D.Vector`. +- 1:N relations (`relatedEntities`) as the final key. +- Intermediate segments that are not relations (when dot-notation is used). + +### atributos() + +**attributes**(*dataclass* : 4D.DataClass) : Collection + +Resolves each phrase key against *dataclass* and returns an ordered Collection of ORDA attribute descriptor objects, one per key in the same order as `.keys`. For dot-notation paths, traverses N:1 relations to reach the final attribute. Pushes `Null` for any key whose path cannot be resolved (unknown attribute or non-relation intermediate segment). + +| Argumento | Tipo | Descripción | +| ----------- | ---------------------------- | -------------------------------------------------------------------------------------------- | +| *dataclass* | 4D.DataClass | The dataclass to resolve attributes against. | +| Resultado | Collection | Ordered collection of ORDA attribute objects (or `Null`). | + +Each resolved entry is an ORDA attribute descriptor with `.name`, `.kind`, and more — see [DataClass.attributeName](https://developer.4d.com/docs/API/DataClassClass#attributename). + +```4d +var $tpl:=cs.EmbeddingStudio.Phrase.new("{firstName} graduated from {school.name}") +var $attrs:=$tpl.attributes(ds.Students) +// $attrs[0].name → "firstName" $attrs[0].type → "string" +// $attrs[1].name → "name" $attrs[1].type → "string" (from School dataclass) +// $attrs[1] is Null if school.name could not be resolved +``` + +## Ver también + +- [Definition](Definition.md) — holds a `Phrase`. +- [StudioEmbedder.render()](StudioEmbedder.md#render) — renders a phrase for an entity, non-persisting. From f485e0dd280de775f822ab62154f33912a2894e5 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:40:47 +0100 Subject: [PATCH 081/195] process.md Spanish --- .../embedding-studio/Classes/Process.md | 188 ++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Process.md diff --git a/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Process.md b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Process.md new file mode 100644 index 00000000000000..c35ad20417a1fd --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Process.md @@ -0,0 +1,188 @@ +--- +id: proceso +title: Proceso +--- + +# Proceso + +The `Process` class orchestrates the full embedding pipeline: it browses 4D entities, renders text from their fields using a [Definition](Definition.md), calls the embeddings API through an [Embedder](Embedder.md), and stores the resulting `4D.Vector` on each entity. + +To render or embed on demand without persistence (search query vectors, phrase previews), see [StudioEmbedder](StudioEmbedder.md). + +## Propiedades + +| Nombre de la propiedad | Tipo | Descripción | +| ---------------------- | ----------------------- | -------------------------------------------------------------------------------------------------------- | +| `propiedades` | [Settings](Settings.md) | The settings (definitions, batch size, phrase validation options). | +| `embedder` | [Embedder](Embedder.md) | The API-calling engine. Stateless and swappable. | +| `opciones` | Object | Runtime options object (see [Options object](#options-object) below). | + +### Options object + +| Llave | Tipo | Descripción | +| ---------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `onProgress` | 4D.Function | Called after each processed chunk with `{definition, report}`. | +| `onSuccess` | 4D.Function | Called once at the end when `report.success = True`, with `{report, success, errors}`. | +| `onError` | 4D.Function | Called once at the end when `report.success = False`, with `{report, success, errors}`. | +| `onTerminate` | 4D.Function | Called once at the end in all cases (after `onSuccess`/`onError`), with `{report, success, errors}`. | +| `dryRun` | Boolean | If `True`, runs selection/filter logic but skips API calls and entity saves. | +| `force` | Boolean | If `True`, recomputes every entity ignoring null-vector / dirty-flag filter. | +| `debug` | Boolean | If `True`, emits additional diagnostic log entries. | +| `pauseIndexes` | Boolean | If `True`, index maintenance on the target table is paused for the duration of a `processEntitySelection` batch run, then resumed right after (or on early exit/critical error). Default `False` — indexes are left alone. See [Pausing indexes](#pausing-indexes) before enabling it. | +| `waitForIndexes` | Boolean | Only used with `pauseIndexes`. If `True`, resuming indexes blocks until they are rebuilt. Default `False` — resume is asynchronous (indexes rebuilt in the background). | +| `shouldCancel` | 4D.Function | Predicate called between chunks during selection processing. Returning `True` stops the run gracefully (cooperative cancel) — what [`Scheduler.cancel()`](Scheduler.md#cancel) uses. | +| `embedder` | [Embedder](Embedder.md) | Inject a custom embedder (otherwise a default one is created). | + +## Class constructor + +Create an instance of the orchestrator. + +| Nombre del argumento | Tipo | Descripción | +| -------------------- | ----------------------- | ---------------------------------------------------------------------------------------------------------------------- | +| *settings* | [Settings](Settings.md) | Opcional. If omitted, settings are loaded from the default `Settings/embeddings.json`. | +| *opciones* | Object | Optional runtime options (see table above). | + +```4d +// Simplest — uses defaults +var $p:=cs.EmbeddingStudio.Process.new() + +// With explicit settings +var $p:=cs.EmbeddingStudio.Process.new($settings) + +// With options +var $p:=cs.EmbeddingStudio.Process.new($settings; {\ + force: True; \ + onProgress: Formula(ALERT("chunk done: "+String($1.report.entitiesUpdated)))}) +``` + +## Batch processing functions + +### proceso() + +**process**(*definition* : Variant) : [ProcessResult](ProcessResult.md) + +Process one, many, or all [Definition](Definition.md) entries against the full content of their target dataclass. + +| Argumento | Tipo | Descripción | +| ------------ | -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | +| *definición* | `Null`, [Definition](Definition.md), `4D.DataClass`, plain object, or Collection | See [process() resolution](#process-resolution). `Null` → every definition in settings. | +| Resultado | [ProcessResult](ProcessResult.md) | Statistics and per-error breakdown. | + +```4d +// Every definition in settings +var $r:=$p.process() + +// One specific definition +var $r:=$p.process($def) + +// Multiple definitions +var $r:=$p.process([$def1; $def2]) + +// Every definition configured for a whole dataclass +var $r:=$p.process(ds.Students) + +// A plain descriptor — looked up in settings, or built on the fly +var $r:=$p.process({dataclassName: "Students"; vectorName: "student_vector_1"}) + +// Any mix — each item is resolved independently and flattened +var $r:=$p.process([ds.Students; $def; {dataclassName: "School"; vectorName: "school_vector_1"}]) +``` + +#### process() resolution + +`process()` has no entity context, so it resolves each input into concrete [Definition](Definition.md) objects directly from settings: + +| Entrada | Comportamiento | +| -------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `Null` | Every definition in settings. | +| [Definition](Definition.md) | Used as-is. | +| `4D.DataClass` (e.g. `ds.Students`) | Every definition in settings whose `dataclassName` matches that dataclass. | +| `{dataclassName: "..."; vectorName: "..."}` | The matching saved definition, or — if none is found — a new `Definition` built from the object's fields (`modelAlias`, `phrase.template`). | +| Collection | Each item is resolved with the rules above and the results are **flattened** into one collection (a `4D.DataClass` item can expand to several definitions). Unsupported items are dropped. | +| Anything else | Empty result. | + +### processEntity() + +**processEntity**(*entity* : 4D.Entity ; *definition* : Variant) : [ProcessResult](ProcessResult.md) + +Process a single entity. Cheap path — no chunking, no server-side filter. + +| Argumento | Tipo | Descripción | +| ------------ | ----------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | +| *entity* | 4D.Entity | The entity to (re)compute vectors for. | +| *definición* | `Null`, [Definition](Definition.md), Collection, or `{vectorName: ...}` | See [resolution rules](#definition-resolution). `Null` infers from entity's dataclass. | +| Resultado | [ProcessResult](ProcessResult.md) | Statistics and per-error breakdown. | + +```4d +// Auto-resolve every definition matching this entity's dataclass +var $r:=$p.processEntity($entity) + +// Specific definition +var $r:=$p.processEntity($entity; $def) + +// By vector name only (looked up in settings against the entity's dataclass) +var $r:=$p.processEntity($entity; {vectorName: "student_vector_1"}) +``` + +### processEntitySelection() + +**processEntitySelection**(*selection* : 4D.EntitySelection ; *definition* : Variant) : [ProcessResult](ProcessResult.md) + +Workhorse path for large jobs. Chunks the selection by `settings.batchSize`, sends one API call per chunk, saves each entity individually. + +| Argumento | Tipo | Descripción | +| ------------ | ----------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | +| *selection* | 4D.EntitySelection | Entities to process. Pre-filtering by the caller is allowed; the pipeline still applies its null/dirty filter. | +| *definición* | `Null`, [Definition](Definition.md), Collection, or `{vectorName: ...}` | See [resolution rules](#definition-resolution). | +| Resultado | [ProcessResult](ProcessResult.md) | Statistics and per-error breakdown. | + +```4d +var $todo:=ds.Students.query("country = :1"; "FR") +var $r:=$p.processEntitySelection($todo; $def) +``` + +### Definition resolution (entity context) + +The polymorphic *definition* argument accepted by `processEntity` and `processEntitySelection`. Unlike [`process()`](#process-resolution), these have an entity/selection to infer the dataclass from, so a bare `{vectorName: "..."}` stub is enough: + +| Entrada | Comportamiento | +| --------------------------- | ----------------------------------------------------------------------------------------------- | +| `Null` | All definitions in settings whose `dataclassName` matches the entity/selection. | +| [Definition](Definition.md) | Used as-is; the `dataclassName` must match the entity/selection. | +| `{vectorName: "..."}` | Looked up in settings by `vectorName` against the entity/selection dataclass. | +| Collection | Each item resolved using the rules above; mismatches are silently dropped. | + +### Recompute rules + +An entity is (re)computed when **any** of these are true: + +- The target vector field is `Null`. +- A sibling field named `{vectorName}_dirty` exists and is `True`. +- The `force` option is `True`. + +The dirty field is optional per dataclass. If it doesn't exist, only the null-vector case triggers recomputation. Upon successful save, the pipeline clears the dirty flag (when present). + +For `processEntitySelection`, the filter is executed as a server-side ORDA query before any API call, so only the rows that actually need work are loaded into memory. For `processEntity`, the check is done in memory on the already-fetched entity. + +### Pausing indexes + +By default the indexes of the target table are maintained normally while vectors are saved. With the `pauseIndexes` option, a batch run calls [`PAUSE INDEXES`](https://developer.4d.com/docs/commands/pause-indexes) on the table before writing and [`RESUME INDEXES`](https://developer.4d.com/docs/commands/resume-indexes) once done (also on early exit or critical error). + +Be aware of what these commands do: + +- `PAUSE INDEXES` disables **all** the indexes of the table (except the primary key index), not only the vector ones: every index on every other field of the table is paused too. While paused, queries and sorts on that table, including those of other processes, run without any index. +- `RESUME INDEXES` then **rebuilds all these indexes**, for the whole table, not only for the records that were recomputed. On a table with several indexes, this rebuild can cost more than the time saved during the writes. +- With `waitForIndexes` set to `True`, the run blocks until the rebuild completes; otherwise the rebuild runs in the background. +- These commands cannot run on a 4D remote client: there the option is ignored (a warning is logged once) and the recalculation runs with indexes maintained normally. Run it on the server, for example through the [Scheduler](Scheduler.md), to use it. + +Enable it only for large recalculations, such as computing the vectors of a whole table for the first time. + +## Ver también + +- [StudioEmbedder](StudioEmbedder.md) +- [Settings](Settings.md) +- [Definition](Definition.md) +- [Embedder](Embedder.md) +- [ProcessResult](ProcessResult.md) +- [Phrase](Phrase.md) +- [Rate Limiting](../RateLimit.md) From 8806b3e931fe7a6e3c6333e7308a8334c92e8d1a Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:40:50 +0100 Subject: [PATCH 082/195] processerror.md Spanish --- .../embedding-studio/Classes/ProcessError.md | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/ProcessError.md diff --git a/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/ProcessError.md b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/ProcessError.md new file mode 100644 index 00000000000000..95a9debef40b85 --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/ProcessError.md @@ -0,0 +1,87 @@ +--- +id: processerror +title: ProcessError +--- + +# ProcessError + +A `ProcessError` is one structured, typed entry in the `errors` collection of a [ProcessResult](ProcessResult.md). Its typed fields let callers react to a specific failure mode programmatically — retry transient failures, abort on a fatal model outage, count save failures — without parsing message strings. + +You read these instances from [ProcessResult](ProcessResult.md)`.errors`, directly or through its query helpers (`errorsByCode`, `errorsByScope`, `retryableErrors`). + +## Propiedades + +| Nombre de la propiedad | Tipo | Descripción | +| ---------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `alcance` | Text | Where the error originated: `"pipeline"`, `"definition"`, `"chunk"`, or `"entity"`. | +| `severity` | Text | `"warning"`, `"error"`, or `"fatal"`. Determined by `code` (see [ProcessErrorCode](ProcessErrorCode.md)). | +| `code` | Integer | Machine-readable error code — compare against the constants on [ProcessErrorCode](ProcessErrorCode.md). | +| `ref` | Variant | Scope-dependent reference: `"Dataclass.vector"`, an entity primary key, a model alias, or `Null`. | +| `message` | Text | Human-readable, localized message. | +| `retryable` | Boolean | `True` when re-running the operation could plausibly succeed. Determined by `code`. | + +### scope values + +| Alcance | Significado | +| -------------- | -------------------------------------------------------------------------------------------------------------------------- | +| `"pipeline"` | Top-level failure affecting the whole run (null selection, a model became unavailable). | +| `"definition"` | A [Definition](Definition.md) failed validation or was skipped. | +| `"chunk"` | A whole batch (chunk) of entities failed in a single API call. | +| `"entidad"` | A single entity failed to embed or save. | + +### severity values + +| Severity | Significado | +| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `"warning"` | Non-blocking — does **not** make [ProcessResult](ProcessResult.md)`.success` false. | +| `"error"` | A recoverable failure scoped to one entity, chunk, or definition. Makes `success` false. | +| `"fatal"` | Blocks the rest of the run (e.g. the model is unavailable). Also surfaces via `hasFatal`. | + +## Propiedades calculadas + +| Propiedad | Tipo | Descripción | +| --------- | ------- | ------------------------------------------------- | +| `isFatal` | Boolean | `True` when `severity = "fatal"`. | + +## Funciones + +### toObject() + +**toObject**() : Object + +Returns a plain object (`{scope, severity, code, ref, message, retryable}`) suitable for logging or JSON serialization. + +| Argumento | Tipo | Descripción | +| --------- | ------ | ------------------------------------------------------ | +| Resultado | Object | A JSON-friendly snapshot of the error. | + +## Ejemplo + +React to failures by type rather than by message text: + +```4d +var $r:=$p.process() + +If (Not($r.success)) + + If ($r.hasFatal) + ALERT("A model became unavailable — aborting until it recovers.") + End if + + var $codes:=cs.EmbeddingStudio.ProcessErrorCode.me + var $saveFailures:=$r.errorsByCode($codes.SAVE_FAILED) + If ($saveFailures.length>0) + ALERT(String($saveFailures.length)+" entities failed to save.") + End if + + // Collect entity keys worth retrying later + var $retry:=$r.retryableErrors().query("scope = :1"; "entity").extract("ref") + +End if +``` + +## Ver también + +- [ProcessErrorCode](ProcessErrorCode.md) — the catalogue of `code` values and their severity/retryability. +- [ProcessResult](ProcessResult.md) — owns the `errors` collection and the query helpers (`errorsByCode`, `errorsByScope`, `retryableErrors`). +- [Process](Process.md) — produces these errors. From 79c1c1130d4c8887830d9c8e3f126f934369de89 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:40:52 +0100 Subject: [PATCH 083/195] processerrorcode.md Spanish --- .../Classes/ProcessErrorCode.md | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/ProcessErrorCode.md diff --git a/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/ProcessErrorCode.md b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/ProcessErrorCode.md new file mode 100644 index 00000000000000..f5d1b0d6e065bb --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/ProcessErrorCode.md @@ -0,0 +1,55 @@ +--- +id: processerrorcode +title: ProcessErrorCode +--- + +# ProcessErrorCode + +A `singleton` exposing the stable, machine-readable error codes carried by [ProcessError](ProcessError.md) `.code`, plus a `meta()` lookup mapping each code to its default `severity` and `retryable` flag. Compare against these constants instead of parsing message strings. + +Access the shared instance via `.me`: + +```4d +var $codes:=cs.EmbeddingStudio.ProcessErrorCode.me +If ($error.code=$codes.SAVE_FAILED) + // … +End if +``` + +## Codes + +| Constante | Valor | Default severity | Retryable | Raised when… | +| ----------------------- | ----- | ---------------- | --------- | ------------------------------------------------------------------------------------------------- | +| `NULL_INPUT` | 100 | error | No | A required entity, selection, or definition was `Null`. | +| `INVALID_DEFINITION` | 101 | error | No | A value is not a usable [Definition](Definition.md) instance. | +| `VALIDATION_FAILED` | 102 | error | No | `Definition.validate()` reported a problem. | +| `MODEL_UNAVAILABLE` | 200 | fatal | Sí | A critical API error made the model unusable for the rest of the run. | +| `MODEL_SKIPPED` | 201 | error | Sí | A definition was skipped because its model already failed critically. | +| `EMBED_FAILED` | 202 | error | Sí | A non-critical embedding call failed (single entity or chunk). | +| `VECTOR_COUNT_MISMATCH` | 300 | error | No | The provider returned a different vector count than requested. | +| `SAVE_FAILED` | 400 | error | Sí | `entity.save()` failed (validation, lock, …). | + +Codes are grouped by hundreds: `1xx` input/configuration, `2xx` model/API, `3xx` data integrity, `4xx` persistence. Unknown codes resolve to `{severity: "error"; retryable: False; label: "UNKNOWN"}`. + +## Funciones + +### meta() + +**meta**( $code : Integer ) : Object + +Returns the `severity` and `retryable` flag associated with a code — the same values carried by a [ProcessError](ProcessError.md) with that `code`. + +| Argumento | Tipo | Descripción | +| --------- | ------- | ----------------------------------------------------------------------- | +| `$code` | Integer | One of the code constants above. | +| Resultado | Object | `{severity : Text; retryable : Boolean; label : Text}`. | + +```4d +var $m:=cs.EmbeddingStudio.ProcessErrorCode.me.meta(cs.EmbeddingStudio.ProcessErrorCode.me.MODEL_UNAVAILABLE) +// $m = {severity: "fatal"; retryable: True; label: "MODEL_UNAVAILABLE"} +``` + +## Ver también + +- [ProcessError](ProcessError.md) — carries a `.code` from this list. +- [ProcessResult](ProcessResult.md) — `errorsByCode()` filters errors by code. From 9ebc5d0259acde6765468dd626feeb0a791fc390 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:40:54 +0100 Subject: [PATCH 084/195] processresult.md Spanish --- .../embedding-studio/Classes/ProcessResult.md | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/ProcessResult.md diff --git a/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/ProcessResult.md b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/ProcessResult.md new file mode 100644 index 00000000000000..7263643f095e95 --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/ProcessResult.md @@ -0,0 +1,91 @@ +--- +id: processresult +title: ProcessResult +--- + +# ProcessResult + +The `ProcessResult` class is the return value of every batch entry point of [Process](Process.md) (`process`, `processEntity`, `processEntitySelection`). It accumulates statistics, per-error breakdowns, and wall-clock duration. + +The orchestrator never throws out of its public batch API — failures are recorded here and the job continues. The caller decides what to do with them. + +## Propiedades + +| Nombre de la propiedad | Tipo | Descripción | +| ---------------------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `definitionsProcessed` | Integer | Number of [Definition](Definition.md) entries processed. | +| `entitiesConsidered` | Integer | Number of entities that passed the "needs recompute" filter. | +| `entitiesUpdated` | Integer | Number of entities whose vector was successfully written and saved. | +| `entitiesSkipped` | Integer | Number of entities that could not be processed: individual embed or save errors, or whole-chunk API failures (those entities are left unchanged for the next run). | +| `apiCalls` | Integer | Number of embeddings API calls made. | +| `promptTokens` | Integer | Total prompt tokens consumed across all API calls in this run. | +| `totalTokens` | Integer | Total tokens consumed across all API calls in this run. | +| `duración` | Integer | Total duration of the job in milliseconds. | +| `errors` | Collection | List of [ProcessError](ProcessError.md) entries recorded during the run. | + +### Propiedades calculadas + +| Propiedad | Tipo | Descripción | +| ---------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `success` | Boolean | `True` when no `"error"` or `"fatal"` entry was recorded. `"warning"` entries do not fail the run. | +| `hasFatal` | Boolean | `True` when at least one `"fatal"` entry was recorded (e.g. a model became unavailable). | + +### Error entries + +Each item in `errors` is a [ProcessError](ProcessError.md) with `scope`, `severity`, `code`, `ref`, `message`, and `retryable`. See [ProcessError](ProcessError.md) for the field meanings and [ProcessErrorCode](ProcessErrorCode.md) for the `code` catalogue. + +## Funciones + +### errorsByScope() + +**errorsByScope**( $scope : Text ) : Collection + +Errors filtered by `scope` (`"pipeline"`, `"definition"`, `"chunk"`, `"entity"`). + +### errorsByCode() + +**errorsByCode**( $code : Integer ) : Collection + +Errors filtered by machine-readable code — see [ProcessErrorCode](ProcessErrorCode.md). + +### retryableErrors() + +**retryableErrors**() : Collection + +Errors flagged `retryable` — re-running the operation could plausibly succeed. + +### toObject() + +**toObject**() : Object + +Returns a plain object suitable for logging or JSON serialization. + +| Argumento | Tipo | Descripción | +| --------- | ------ | ------------------------------------------------------- | +| Resultado | Object | A JSON-friendly snapshot of the report. | + +```4d +var $r:=$p.process() +LOG EVENT(Into 4D log file; JSON Stringify($r.toObject())) +``` + +## Ejemplo + +```4d +var $r:=$p.processEntitySelection(ds.Students.all(); $def) + +If ($r.success) + ALERT("Updated "+String($r.entitiesUpdated)+" students in "+String($r.duration)+" ms") +Else + var $err : Object + For each ($err; $r.errors) + ALERT("[" + $err.scope + "] " + String($err.ref) + " — " + $err.message) + End for each +End if +``` + +## Ver también + +- [Process](Process.md) +- [ProcessError](ProcessError.md) — the typed shape of each `errors` entry. +- [ProcessErrorCode](ProcessErrorCode.md) — the `code` catalogue. From 6c9f06e33ba53b32989b31b5a35b17c677731fa3 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:40:57 +0100 Subject: [PATCH 085/195] scheduler.md Spanish --- .../embedding-studio/Classes/Scheduler.md | 369 ++++++++++++++++++ 1 file changed, 369 insertions(+) create mode 100644 i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Scheduler.md diff --git a/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Scheduler.md b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Scheduler.md new file mode 100644 index 00000000000000..e2ba1bd8ee043e --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Scheduler.md @@ -0,0 +1,369 @@ +--- +id: backups periódicos +title: Backups periódicos +--- + +# Backups periódicos + +The `Scheduler` class is the public entry point for the **automated embedding recalculation** service. It maintains a background task that runs the embedding pipeline (see [Process](Process.md)) at a configured interval or a fixed daily time, guarantees that **at most one** recalculation batch runs at a time, and exposes runtime status for administration and monitoring interfaces. + +It is a **singleton**, accessed through `cs.EmbeddingStudio.Scheduler.me`. + +The scheduler runs two named workers: + +| Worker | Rol | +| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `EmbeddingStudioScheduler` | Background loop that re-reads the config each cycle, computes the next run and fires when due. | +| `EmbeddingStudio` | Execution worker that runs one recalculation batch (shared with the Studio UI, so scheduled and manual runs are serialized). | + +## Configuración + +The configuration lives under the `scheduler` key of `Settings/embeddings.json`: + +```json +{ + "scheduler": { + "mode": "interval", + "intervalHours": 3, + "startFrom": "reference", + "startReference": "2026-09-02T14:00:00", + "dailyTime": "00:00" + } +} +``` + +| Llave | Tipo | Values / range | Descripción | +| ---------------- | ------- | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `mode` | Text | `"never"` \| `"interval"` \| `"daily"` | Scheduling mode. Absent/unknown ⇒ `never` (no automatic run). | +| `intervalHours` | Integer | `1`..`24` | Interval mode only. Out-of-range ⇒ default `3`. | +| `startFrom` | Text | `"reference"` \| `"lastExecution"` | Interval mode only. Anchor of the interval (see below). Anything other than `"lastExecution"` — including the legacy `"now"` — is normalized to `reference`. Default `reference`. | +| `startReference` | Text | `"YYYY-MM-DDThh:mm:ss"` | Interval mode with `startFrom = "reference"`. Fixed instant the interval counts from. Absent ⇒ the moment the scheduler was armed, then the current instant. | +| `dailyTime` | Text | `"HH:MM"` | Daily mode only. Time of day for the recalculation. Default `"00:00"`. | + +**Interval anchoring (`startFrom`)** + +- `reference` — **fixed rate**: the interval is anchored on the fixed `startReference` instant, so the slots do not drift whatever a run's duration is. Slots are advanced by `intervalHours` until the first one strictly after now. When `startReference` is absent (a fresh or legacy config), the anchor falls back to the moment the scheduler was armed (`start()`), then to the current instant. +- `lastExecution` — **fixed delay**: the interval is anchored on the last completed recalculation. If the elapsed time since the last run already exceeds the interval (e.g. after a restart), the run is triggered immediately. If there is no prior run, it runs immediately. + +The effective configuration is read from the file on **every loop cycle**, so changes take effect without restarting the scheduler. + +## Starting the scheduler + +Configuring a `mode` is **not enough**: nothing runs until the scheduler is started. There are two ways to get there, and which one applies depends on a single option of your host database. + +### 1. Automatic — let the host database start it + +In the host database, open **Settings > Security** and check **"Execute 'On Host Database Event' method of the components"** (it is *unchecked* by default, for security reasons). + +With this option on, 4D Embedding Studio starts the scheduler by itself when the host database opens, and stops it when the host database closes. There is nothing else to write. + +Use [`autoStart()`](#autostart) to check whether the option is on: + +```4d +If (Not(cs.EmbeddingStudio.Scheduler.me.autoStart())) + // the option is off — I must start the scheduler myself + cs.EmbeddingStudio.Scheduler.me.start() +End if +``` + +### 2. Manual — start it from your own code + +If you prefer to leave the option off, the scheduler never starts on its own. Call [`start()`](#start) from wherever it suits you — typically the host `On Startup` or `On Server Startup` database method — and [`stop()`](#stop) when the database closes (`On Exit` / `On Server Shutdown`): + +```4d +// Host "On Server Startup" +cs.EmbeddingStudio.Scheduler.me.start() + +// Host "On Server Shutdown" +cs.EmbeddingStudio.Scheduler.me.stop() +``` + +> In client/server, arm the scheduler from `On Server Startup`, not from `On Startup`: +> `On Startup` runs on every remote client, and the scheduler state is per machine — each +> client would arm its own loop and run its own batches. If you do call [`start()`](#start) +> from `On Startup` (single-user setups), guard it with +> `If (Application type#4D Remote mode)`. + +`start()` is idempotent, so calling it from several places is harmless. + +### Checking that it really runs + +[`isStarted()`](#isstarted) tells you whether the background loop is alive right now — the answer to "is my schedule actually being watched?": + +```4d +var $s:=cs.EmbeddingStudio.Scheduler.me.status() +If ($s.enabled && Not($s.started)) + ALERT("A schedule is configured but the scheduler is not started.") +End if +``` + +## Funciones + +### start() + +**start**() : Boolean + +Arms the scheduler and starts the background loop worker if it is not already running. Idempotent — calling it again while already armed simply refreshes the "start from now" anchor. + +| Resultado | Tipo | Descripción | +| --------- | ------- | ------------------------------ | +| resultado | Boolean | Always `True`. | + +```4d +cs.EmbeddingStudio.Scheduler.me.start() +``` + +### stop() + +**stop**() + +Disarms the scheduler and stops the background loop worker. A recalculation batch already in progress is **not** interrupted — it finishes normally (use [`cancel()`](#cancel) to request an early stop). + +```4d +cs.EmbeddingStudio.Scheduler.me.stop() +``` + +### cancelado() + +**cancel**() + +Requests a **cooperative** cancel of the batch currently running. The running batch is never force-killed; it stops gracefully between two chunks. Has no effect if no batch is running. + +```4d +cs.EmbeddingStudio.Scheduler.me.cancel() +``` + +### force() + +**force**() : Object + +Forces a recalculation **now**, regardless of the schedule. It honors the single-batch rule: if a batch is already running, the forced trigger is skipped (and logged). Non-blocking — the run happens on the execution worker. + +| Resultado | Tipo | Descripción | +| --------- | ------ | ----------------------------------------------------- | +| resultado | Object | The current [status](#status) object. | + +```4d +var $status:=cs.EmbeddingStudio.Scheduler.me.force() +``` + +### status() + +**status**() : Object + +Returns the current scheduler status, without any input parameter — suitable for administration and monitoring displays. + +| Resultado | Tipo | Descripción | +| --------- | ------ | ---------------------------------------------------- | +| resultado | Object | See [Status object](#status-object). | + +```4d +var $s:=cs.EmbeddingStudio.Scheduler.me.status() +If ($s.running) + ALERT("A recalculation is running since "+$s.batchStart) +End if +``` + +#### Objeto estado + +| Llave | Tipo | Descripción | +| ---------------------- | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `enabled` | Boolean | `False` when `mode = "never"`. | +| `mode` | Text | Effective mode (`never` \| `interval` \| `daily`). | +| `armed` | Boolean | `True` when the background loop is armed (after `start()`, until `stop()`). | +| `running` | Boolean | `True` while a recalculation batch is in progress. | +| `batchStart` | Text \| Null | ISO timestamp of the running batch start (`Null` when idle). | +| `lastExecution` | Text \| Null | ISO timestamp of the last completed run (`Null` if none yet). Restored from the persisted history after a restart, so it survives the loss of in-memory state. | +| `lastRunBeforeRestart` | Boolean | `True` when `lastExecution` was recovered from the history after a restart rather than produced by a run in the current session. | +| `nextRun` | Text \| Null | ISO timestamp of the next scheduled run (`Null` in `never` mode). | +| `lastResult` | Text \| Null | Result of the last trigger: `started` \| `skipped` \| `completed` \| `failed`. | +| `error` | Text \| Null | Error summary when the last run failed (safe for admin display), else `Null`. | +| `started` | Boolean | `True` when the background loop is really alive (see [`isStarted()`](#isstarted)). | +| `autoStart` | Boolean | `True` when the host database starts the scheduler by itself (see [`autoStart()`](#autostart)). | + +### isStarted() + +**isStarted**() : Boolean + +Tells whether the scheduler is **effectively running**, i.e. whether its background loop is alive at this very moment. Unlike the `armed` flag of the [status](#status-object), it reflects reality: if the loop was never started, or was killed, the result is `False`. + +| Resultado | Tipo | Descripción | +| --------- | ------- | --------------------------------------------------------- | +| resultado | Boolean | `True` when the background loop is alive. | + +```4d +If (Not(cs.EmbeddingStudio.Scheduler.me.isStarted())) + cs.EmbeddingStudio.Scheduler.me.start() +End if +``` + +### autoStart() + +**autoStart**() : Boolean + +Tells whether the host database authorizes 4D Embedding Studio to start itself, i.e. whether the **"Execute 'On Host Database Event' method of the components"** option is checked in the host **Settings > Security** (see [Starting the scheduler](#starting-the-scheduler)). + +- `True` — the scheduler starts with the host database and stops with it. You have nothing to call. +- `False` — nothing starts automatically: your code must call [`start()`](#start) and [`stop()`](#stop). + +The answer is read from the host structure settings. When they cannot be read, the result is `False` — the safe answer, since starting an already-started scheduler is harmless. + +| Resultado | Tipo | Descripción | +| --------- | ------- | -------------------------------------------------------------------- | +| resultado | Boolean | `True` when the host starts the scheduler by itself. | + +```4d +var $auto:=cs.EmbeddingStudio.Scheduler.me.autoStart() +``` + +### config() + +**config**() : Object + +Returns the effective scheduler configuration with defaults applied (as resolved from `embeddings.json`). + +| Resultado | Tipo | Descripción | +| --------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------- | +| resultado | Object | `{mode; intervalHours; startFrom; startReference; dailyTime}` (see [Configuration](#configuration)). | + +```4d +var $cfg:=cs.EmbeddingStudio.Scheduler.me.config() +``` + +### saveConfig() + +**saveConfig**( *cfg* : Object ) : Object + +Validates, normalizes and **persists** a scheduler configuration to the `scheduler` key of `embeddings.json`, then returns the normalized value. This is the programmatic equivalent of the scheduler settings window: it lets you change the schedule entirely by code, without the GUI. Only the `scheduler` key is written — other keys of the settings file are preserved. + +The configuration is written **on the server**: in a 4D Server / 4D remote setup the file is always edited on the server machine, so a remote client can safely call this method. Because the loop re-reads the configuration on every cycle, the new schedule takes effect without restarting the scheduler. + +| Parámetros | Tipo | Descripción | +| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| cfg | Object | Raw configuration `{mode; intervalHours; startFrom; startReference; dailyTime}` (see [Configuration](#configuration)). Missing/out-of-range values are defaulted. | + +| Resultado | Tipo | Descripción | +| --------- | ------ | ---------------------------------------------------------------- | +| resultado | Object | The normalized configuration that was persisted. | + +```4d +// Switch to a 6-hour interval counting from the last execution +cs.EmbeddingStudio.Scheduler.me.saveConfig({mode: "interval"; intervalHours: 6; startFrom: "lastExecution"}) + +// Switch to a daily run at 02:30 +cs.EmbeddingStudio.Scheduler.me.saveConfig({mode: "daily"; dailyTime: "02:30"}) + +// Disable the automatic schedule +cs.EmbeddingStudio.Scheduler.me.saveConfig({mode: "never"}) +``` + +### nextRun() + +**nextRun**() : Object + +Computes the next scheduled run from the current configuration and state. + +| Resultado | Tipo | Descripción | +| --------- | -------------- | --------------------------------------------------------------------------------------------------------------- | +| resultado | Object \| Null | `{date : Date; time : Time; timestamp : Text; immediate : Boolean}`, or `Null` in `never` mode. | + +```4d +var $next:=cs.EmbeddingStudio.Scheduler.me.nextRun() +``` + +### reload() + +**reload**() : Object + +No-op convenience: the configuration is re-read automatically on each loop cycle, so this simply returns the current [status](#status). Provided for callers that want an explicit "config changed, give me the up-to-date status" call. + +| Resultado | Tipo | Descripción | +| --------- | ------ | ----------------------------------------------------- | +| resultado | Object | The current [status](#status) object. | + +## Concurrency & logging + +- **Single batch** — at any time, at most one recalculation batch runs. A trigger (scheduled or forced) fired while a batch is running is **skipped**, not queued. +- **Skip traceability** — skipped triggers are logged with their timestamp in the execution history (`Logs/embeddingHistory.json`). +- **Cooperative cancel** — `cancel()` stops a running batch gracefully between chunks; it is never force-killed. +- **History** — each run records start/end timestamps, status, token usage and the computed next run date in `Logs/embeddingHistory.json` (see [ProcessResult](ProcessResult.md) for per-run details). + +### Execution history file + +`Logs/embeddingHistory.json` is written by the pipeline itself (every full `process()` run, scheduled or manual), guarded by a semaphore so concurrent processes never interleave writes. It holds the **current** run at the top level, the one before it under `previous`, and the same pair per definition under `definitions`. + +```json +{ + "startTime": "2026-09-01T14:03:00", + "endTime": "2026-09-01T14:03:00", + "status": "completed", + "trigger": "completed", + "error": null, + "nextComputeDate": "2026-09-02T14:03:00", + "promptTokens": 0, + "totalTokens": 0, + "cumulativePromptTokens": 37802, + "cumulativeTotalTokens": 37802, + "previous": { "startTime": "…", "endTime": "…", "status": "completed", "error": null, + "nextComputeDate": "…", "promptTokens": 12764, "totalTokens": 12764, + "cumulativePromptTokens": 37802, "cumulativeTotalTokens": 37802 }, + "skipped": ["2026-09-01T12:00:00"], + "definitions": { + "Students.student_vector_1": { + "startTime": "…", "endTime": "…", "status": "completed", "error": null, + "promptTokens": 1054, "totalTokens": 1054, + "cumulativePromptTokens": 4210, "cumulativeTotalTokens": 4210, + "previous": { "…": "…" } + } + } +} +``` + +| Llave | Tipo | Descripción | +| -------------------------------------------------- | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `startTime` / `endTime` | Text \| Null | ISO timestamps of the run, in the scheduler's local base. `endTime` is `null` while a run is in progress. | +| `status` | Text | `running` \| `completed` \| `failed`. | +| `trigger` | Text | Last event that touched the file: `started` \| `skipped` \| `completed` \| `failed`. | +| `error` | Text \| Null | Summary of the run's errors, or `null`. Never contains an API key. | +| `nextComputeDate` | Text \| Null | Next scheduled run computed at the end of the run (the `nextComputeDate` option of [Process](Process.md)). | +| `promptTokens` / `totalTokens` | Integer | Usage for this run alone. | +| `cumulativePromptTokens` / `cumulativeTotalTokens` | Integer | Running totals across all recorded runs. | +| `previous` | Object | Snapshot of the preceding run — the same keys, without `trigger`, `skipped` and `definitions`. Only one generation is kept. | +| `skipped` | Collection | ISO timestamps of triggers skipped because a batch was already running. Capped at the **last 50**. | +| `definitions` | Object | One entry per definition, keyed `"."`, each with its own `startTime`, `endTime`, `status` (`completed` \| `failed` \| `skipped`), `error`, token counters and `previous`. | + +[`status()`](#status) reads `startTime`, `endTime`, `status`, `trigger`, `error` and `nextComputeDate` back from this file, which is how `lastExecution` survives a server restart. + +## Lifecycle + +| Host setting | What happens | What you must do | +| ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | +| **"Execute 'On Host Database Event' method of the components"** checked | The scheduler starts when the host database opens and stops when it closes. | Nothing. | +| Option unchecked (default) | The scheduler never starts by itself. | Call [`start()`](#start) at startup and [`stop()`](#stop) at shutdown. | + +Ask [`autoStart()`](#autostart) which case you are in, and [`isStarted()`](#isstarted) whether the loop is currently alive. Stopping the scheduler never interrupts a batch in progress — it finishes normally. + +## Ejemplo + +```4d +// --- Start at server startup, unless the host does it for us --- +If (Not(cs.EmbeddingStudio.Scheduler.me.autoStart())) + cs.EmbeddingStudio.Scheduler.me.start() +End if + +// --- Admin panel: force a recalculation and read status --- +var $status:=cs.EmbeddingStudio.Scheduler.me.force() + +// --- Monitoring: display last / next run and current state --- +$status:=cs.EmbeddingStudio.Scheduler.me.status() +var $info:="Mode: "+$status.mode\ + +" — Last: "+String($status.lastExecution)\ + +" — Next: "+String($status.nextRun)\ + +" — "+($status.running ? "running" : String($status.lastResult)) + +// --- Cancel a long-running batch --- +cs.EmbeddingStudio.Scheduler.me.cancel() + +// --- Disable automatic runs --- +cs.EmbeddingStudio.Scheduler.me.stop() +``` From 73dc1a30ad2ed0b6ad4551857879d39567b1a8bc Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:41:00 +0100 Subject: [PATCH 086/195] settings.md Spanish --- .../embedding-studio/Classes/Settings.md | 184 ++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Settings.md diff --git a/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Settings.md b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Settings.md new file mode 100644 index 00000000000000..c7a4cef3f972f3 --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Settings.md @@ -0,0 +1,184 @@ +--- +id: settings +title: Propiedades +--- + +# Propiedades + +The `Settings` class is the persisted configuration for the embedding pipeline. It loads and saves a JSON file (default: `Settings/embeddings.json`, overridable with the `EMBEDDINGS_SETTINGS_PATH` environment variable) containing a list of [Definition](Definition.md) entries, a batch size, and phrase-validation options. + +## Propiedades + +| Nombre de la propiedad | Tipo | Descripción | +| ---------------------- | -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `definitions` | Collection of [Definition](Definition.md) | The configured definitions. | +| `batchSize` | Integer | Chunk size used by [Process.processEntitySelection](Process.md#processentityselection). Default: `50`. | +| `phrase` | Object | Phrase-validation options (see below). | +| `embedder` | Object | Optional embedder configuration (see below). | +| `file` | 4D.File *(read-only)* | The backing file the settings are loaded from and saved to. | + +### phrase options + +Passed verbatim to [Phrase.validate()](Phrase.md#validate) whenever the pipeline validates a definition. + +| Campo | Tipo | Por defecto | Descripción | +| ----------------- | ------- | ----------- | ----------------------------------------------------------------------------------------------- | +| `allowRelations` | Boolean | `False` | Allow dot-notation through N:1 / 1:1 relations. | +| `allowCalculated` | Boolean | `False` | Allow calculated attributes in phrases. | +| `allowAlias` | Boolean | `False` | Allow alias attributes in phrases. | +| `allowObject` | Boolean | `False` | Allow object attributes in phrases. | + +> **Invalidation caveat.** Dirty-flag tracking only covers direct scalar fields on the entity. Fields that are only reachable through one of these options — a related entity's attribute, a calculated value, an alias, or a sub-property of an object — will **not** automatically mark the entity as dirty when they change. If such fields are part of a phrase and their source data changes, the vector will not be recomputed unless you call `invalidateVectors()` explicitly or use `force: true` when processing. + +### embedder options + +Controls how [Process](Process.md) builds its embedder. When absent, a default `Embedder` is created with its own defaults. + +| Campo | Tipo | Por defecto | Descripción | +| ------------ | ------- | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `className` | Text | — | Name of a project class to instantiate instead of the built-in `Embedder`. The class must expose `embed` and `embedBatch` functions. If instantiation fails or the interface is missing, a diagnostic error is logged and the default `Embedder` is used as fallback. | +| `maxRetries` | Integer | `3` | Number of retry attempts on rate-limit errors (forwarded to `Embedder`). | +| `backoffMs` | Integer | `500` | Base back-off delay in ms, doubled each retry (forwarded to `Embedder`). | + +Any additional keys are forwarded as-is to the constructor of the target class (built-in or custom). + +## Formato del archivo + +```json +{ + "batchSize": 50, + "phrase": { + "allowRelations": false, + "allowCalculated": false, + "allowAlias": false, + "allowObject": false + }, + "embedder": { + "maxRetries": 5, + "backoffMs": 200 + }, + "definitions": [ + { + "dataclassName": "Students", + "vectorName": "student_vector_1", + "modelAlias": "text-embedding-3-small", + "phrase": "Student {firstName} {lastName}", + "autoInvalidate": true + } + ] +} +``` + +Each definition may include `autoInvalidate` (`true` by default) to control save-time automatic invalidation. + +The same file also carries the `scheduler` key (see [Scheduler](Scheduler.md#configuration)) and any other top-level key you add: `Settings` reads and rewrites only the keys listed above and leaves the rest untouched. + +With a custom embedder class: + +```json +{ + "embedder": { + "className": "MyCustomEmbedder" + }, + "definitions": [...] +} +``` + +## Class constructor + +Create a settings instance. The configuration file is loaded immediately. + +| Nombre del argumento | Tipo | Descripción | +| -------------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| *file* | 4D.File | Opcional. A file to use instead of the default location. The override applies process-wide for subsequent settings access. **Not supported in 4D Remote mode** — pass it only when running locally or on the server. | + +When *file* is omitted, the default location is used: `Settings/embeddings.json`, or the path given by the `EMBEDDINGS_SETTINGS_PATH` environment variable. + +```4d +// Default location +var $settings:=cs.EmbeddingStudio.Settings.new() + +// Custom file (server / mono only) +var $settings:=cs.EmbeddingStudio.Settings.new(File("/some/path/custom.json")) +``` + +## Funciones + +### load() + +**load**() + +Reload the backing file into memory, overwriting in-memory state. A missing file resets to defaults without raising. + +A file that **exists but cannot be parsed** also leaves the instance on defaults, but it is remembered: an error is logged and [`save()`](#save) then refuses to write, so a malformed file is never silently replaced by defaults. + +### save() + +**save**() : Boolean + +Serialize the current in-memory state to the backing file. Only the keys this class owns (`batchSize`, `phrase`, `embedder`, `definitions`) are written — every other top-level key present in the file (the `scheduler` configuration, model aliases…) is preserved as-is. A key whose value is back to its default is *removed* from the file rather than written. + +Definitions are merged with what the file holds at that instant, using the snapshot taken at load time as the common ancestor: two editors open at the same time no longer drop each other's definitions. + +| Resultado | Tipo | Descripción | +| --------- | ------- | ------------------------------------------------------------------------------------------------------------------------------ | +| resultado | Boolean | `True` when written. `False` — nothing written — when the file could not be read at load time. | + +```4d +$settings.definitions.push(cs.EmbeddingStudio.Definition.new("Students"; "student_vector_1"; "text-embedding-3-small"; "{firstName}")) +$settings.batchSize:=100 +$settings.save() +``` + +### find() + +**find**(*dataclassName* : Text ; *vectorName* : Text) : [Definition](Definition.md) + +Look up the saved definition for the given dataclass/vector pair. + +| Argumento | Tipo | Descripción | +| --------------- | --------------------------- | ------------------------------------------------------------------- | +| *dataclassName* | Text | Nombre de la dataclass. | +| *vectorName* | Text | Name of the vector field on that dataclass. | +| Resultado | [Definition](Definition.md) | The matching definition, or `Null` if none matches. | + +```4d +var $def:=$settings.find("Students"; "student_vector_1") +``` + +### findAll() + +**findAll**(*dataclassName* : Text) : Collection of [Definition](Definition.md) + +Return every saved definition configured for the given dataclass. + +| Argumento | Tipo | Descripción | +| --------------- | ----------------------------------------- | --------------------------------------------------------------------------------------------- | +| *dataclassName* | Text | Nombre de la dataclass. | +| Resultado | Collection of [Definition](Definition.md) | All matching definitions (empty collection if none match). | + +```4d +var $defs:=$settings.findAll("Students") +// → every Students definition; used by Process.process(ds.Students) +``` + +### invalidateVectors() + +**invalidateVectors**() : Object + +Calls [`invalidateVectors()`](Definition.md#invalidatevectors) on every definition in `definitions` and merges the results into a single status object. + +| Argumento | Tipo | Descripción | +| --------- | ------ | ------------------------------------------------------------------------------------------------------------------------ | +| Resultado | Object | `{updated: Integer, skipped: Integer, errors: Collection of Text}` — accumulated across all definitions. | + +```4d +var $result:=cs.EmbeddingStudio.Settings.new().invalidateVectors() +// → { updated: 120; skipped: 0; errors: [] } +``` + +## Ver también + +- [Definition](Definition.md) +- [Process](Process.md) +- [Phrase](Phrase.md) From ddb22cd02acbfbfb64b3c95de6388a6666793bff Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:41:02 +0100 Subject: [PATCH 087/195] studioembedder.md Spanish --- .../Classes/StudioEmbedder.md | 125 ++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/StudioEmbedder.md diff --git a/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/StudioEmbedder.md b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/StudioEmbedder.md new file mode 100644 index 00000000000000..96e099d3e1461b --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/StudioEmbedder.md @@ -0,0 +1,125 @@ +--- +id: studioembedder +title: StudioEmbedder +--- + +# StudioEmbedder + +The `StudioEmbedder` class renders and embeds on demand, resolved against the Studio settings: a saved definition gives the phrase and the model, so the vector you compute matches the ones stored by [Process](Process.md). Nothing is persisted. Typical uses: building the vector of a search query, finding entities similar to a given one, or previewing the text sent for an entity. + +For the full batch pipeline that persists vectors on entities, see [Process](Process.md). + +## Propiedades + +| Nombre de la propiedad | Tipo | Descripción | +| ---------------------- | ----------------------- | ------------------------------------------------------------------------------------------------- | +| `propiedades` | [Settings](Settings.md) | The settings (vectors, batch size, phrase validation options). | +| `embedder` | [Embedder](Embedder.md) | The API-calling engine. Stateless and swappable. | +| `opciones` | Object | Runtime options object. | + +## Class constructor + +| Nombre del argumento | Tipo | Descripción | +| -------------------- | ----------------------- | ---------------------------------------------------------------------------------------------------------------------- | +| *settings* | [Settings](Settings.md) | Opcional. If omitted, settings are loaded from the default `Settings/embeddings.json`. | +| *opciones* | Object | Optional runtime options. Supports `embedder` for injection. | + +```4d +var $studioEmbedder:=cs.EmbeddingStudio.StudioEmbedder.new() +var $studioEmbedder:=cs.EmbeddingStudio.StudioEmbedder.new($settings) +var $studioEmbedder:=cs.EmbeddingStudio.StudioEmbedder.new($settings; {embedder: $mockEmbedder}) +``` + +## Funciones + +### render() + +**render**(*entity* : 4D.Entity ; *definitionOrPhrase* : Variant) : Text + +Return the text that [`embed()`](#embed) sends for an entity (the phrase rendered against it). No API call, no persistence. + +| Argumento | Tipo | Descripción | +| -------------------- | ------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| *entity* | 4D.Entity | The entity to render against. | +| *definitionOrPhrase* | `Null`, [Phrase](Phrase.md), [Definition](Definition.md), Text, or plain object stub | `Null` → auto-resolve via settings (requires a unique match). Text → compiled as a throwaway `cs.EmbeddingStudio.Phrase`. Object stub → see [stub resolution](#stub-resolution). | +| Resultado | Text | The rendered text. | + +```4d +var $studioEmbedder:=cs.EmbeddingStudio.StudioEmbedder.new() +var $text: Text +$text:=$studioEmbedder.render($student; $def) // use def's phrase +$text:=$studioEmbedder.render($student; cs.EmbeddingStudio.Phrase.new("Hi {firstName}")) +$text:=$studioEmbedder.render($student; "Student: {lastName}") // raw template +$text:=$studioEmbedder.render($student) // auto-resolve +$text:=$studioEmbedder.render($student; {vectorName: "student_vector_1"}) // stub → saved definition's phrase +$text:=$studioEmbedder.render($student; {phrase: "Hi {firstName}"}) // ad-hoc stub → inline template +``` + +### embed() + +**embed**(*input* : Variant ; *context* : Variant ; *model* : Text) : [cs.EmbeddingStudio.EmbedderResult](EmbedderResult.md) + +Compute a vector for an arbitrary input, without persisting anywhere. + +| Argumento | Tipo | Descripción | +| --------- | --------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| *entrada* | Text or 4D.Entity | Text → embedded directly. Entity → phrase rendered then embedded. | +| *context* | Text, [Phrase](Phrase.md), [Definition](Definition.md), Text template, plain object stub, or `Null` | Provides phrase and/or model depending on *input*. Object stub → see [stub resolution](#stub-resolution). | +| *model* | Text | Optional explicit model name. Used when *context* does not carry one. | +| Resultado | [EmbedderResult](EmbedderResult.md) | The embedding result (use `.vector` to get the 4D.Vector). | + +Throws if no model can be determined. + +```4d +var $studioEmbedder:=cs.EmbeddingStudio.StudioEmbedder.new() +var $vector: 4D.Vector + +// Text + model +$vector:=$studioEmbedder.embed("some text"; "text-embedding-3-small").vector + +// Text + definition (picks up def.modelAlias) +$vector:=$studioEmbedder.embed("some text"; $def).vector + +// Entity + definition (uses def.phrase + def.modelAlias) +$vector:=$studioEmbedder.embed($student; $def).vector + +// Entity + phrase + explicit model +$vector:=$studioEmbedder.embed($student; $phrase; "text-embedding-3-small").vector + +// Entity + ad-hoc template + model +$vector:=$studioEmbedder.embed($student; "Profile: {firstName} {lastName}"; "text-embedding-3-small").vector + +// Entity alone (auto-resolve, only when exactly one def matches the dataclass) +$vector:=$studioEmbedder.embed($student).vector + +// Entity + stub (deduces phrase + model from the matching saved definition) +$vector:=$studioEmbedder.embed($student; {vectorName: "student_vector_1"}).vector + +// Entity + ad-hoc stub (phrase compiled inline, model taken from the stub) +$vector:=$studioEmbedder.embed($student; {phrase: "Hi {firstName}"; modelAlias: "text-embedding-3-small"}).vector + +// Text + stub that only supplies the model +$vector:=$studioEmbedder.embed("some text"; {modelAlias: "text-embedding-3-small"}).vector +``` + +## Stub resolution + +Both `render()` and `embed()` accept a plain object in place of a `Phrase`/`Definition`. A stub is resolved the same way [`Process`](Process.md#definition-resolution-entity-context) resolves its `definition` argument, so the behavior matches. Two flavors are supported: + +| Stub | Resolves to | +| ------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `{vectorName: "..."}` (optionally `{dataclassName: "..."}`) | The matching **saved definition** for the entity's dataclass — deducing its phrase (and, for `embed`, its model). Resolves to nothing when there is no unique match. | +| `{phrase: "tpl {field}"}` or `{template: "tpl {field}"}` | An **ad-hoc** `Phrase` compiled inline; nothing is looked up. Pair with `{modelAlias: "..."}` to give `embed()` a model. | + +For `embed()`, the model is deduced in this order: an explicit `{modelAlias}` on the stub → the model of a stub-matched saved definition → the *model* argument → the entity's unique definition. An explicit `{modelAlias}` always wins. + +Unlike [`Process.process()`](Process.md#process-resolution), a stub is **not** turned into a brand-new `Definition` from its fields — `StudioEmbedder` persists nothing, so use `{phrase}`/`{template}` for one-off templates. + +## Ver también + +- [Process](Process.md) +- [Settings](Settings.md) +- [Definition](Definition.md) +- [Embedder](Embedder.md) +- [EmbedderResult](EmbedderResult.md) +- [Phrase](Phrase.md) From d1ab8d375cec953269a4753096bf47ca3df1d37e Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:41:05 +0100 Subject: [PATCH 088/195] license.md Spanish --- .../version-21-R5/embedding-studio/license.md | 167 ++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/license.md diff --git a/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/license.md b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/license.md new file mode 100644 index 00000000000000..8f6fc0dd2b5ffc --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/license.md @@ -0,0 +1,167 @@ +--- +id: license +title: SOFTWARE LICENSE AGREEMENT +--- + +# SOFTWARE LICENSE AGREEMENT + +## Preamble + +The purpose of this Software license agreement is to grant users the right to modify and re-use the software governed by this license. + +The exercising of this right is conditional upon the obligation to make /available to the community the modifications made to the source code of the software so as to contribute to its evolution. + +In consideration of access to the source code and the rights to copy, modify and redistribute granted by the license, users are provided only with a limited warranty and the software's author, the holder of the economic rights, and the successive licensors only have limited liability. + +## Article 1 – DEFINITIONS + +***Agreement***: means this license agreement, and its possible subsequent versions and annexes. + +***Software***: means the software in its Object Code and/or Source Code form and, where applicable, its documentation, "as is" when the Licensee accepts the Agreement. + +***Initial Software***: means the Software in its Source Code and possibly its Object Code form and, where applicable, its documentation, "as is" when it is first distributed under the terms and conditions of the Agreement. + +***Modified Software***: means the Software modified by at least one Integrated Contribution. + +***Source Code***: means all the Software's instructions and program lines to which access is required so as to modify the Software. + +***Object Code***: means the binary files originating from the compilation of the Source Code. + +***Holder***: means the holder(s) of the economic rights over the Initial Software, in this case it is 4D SAS. + +***Licensee***: means the Software user(s) having accepted the Agreement. + +***Contributor***: means a Licensee having made at least one Integrated Contribution. + +***Licensor***: means the Holder, or any other individual or legal entity, who distributes the Software under the Agreement. + +***Integrated Contribution***: means new functions integrated into the Source Code by any or all Contributors. + +***Parties***: mean both the Licensee and the Licensor. + +These expressions may be used both in singular and plural form. + +## Article 2 - PURPOSE + +The purpose of the Agreement is the grant by the Licensor to the Licensee of a non-exclusive, transferable and worldwide license for the Software as set forth in Article 5 hereinafter for the whole term of the protection granted by the rights over said Software. + +## Article 3 - ACCEPTANCE + +The Licensee shall be deemed as having accepted the terms and conditions of this Agreement upon the occurrence of the first of the following events: + +- loading the Software by any or all means, notably, by downloading from a remote server; +- the first time the Licensee exercises any of the rights granted hereunder. + +## Article 4 - EFFECTIVE DATE AND TERM + +### 4.1 EFFECTIVE DATE + +The Agreement shall become effective on the date when it is accepted by the Licensee as set forth in Article 3. + +### 4.2 TERM + +The Agreement shall remain in force for the entire legal term of protection of the economic rights over the Software. + +## Article 5 - SCOPE OF RIGHTS GRANTED + +The Licensor hereby grants to the Licensee, who accepts, the following rights over the Software for the term of the Agreement, on the basis of the terms and conditions set forth hereinafter. + +### 5.1 RIGHT OF USE + +The Licensee is authorized to use the Software, without any limitation as to its fields of application, with it being hereinafter specified that this comprises: + +- permanent or temporary reproduction of all or part of the Software by any or all means and in any or all form. +- loading, displaying, running, or storing the Software on any or all medium. +- entitlement to observe, study or test its operation. + +### 5.2 RIGHT OF MODIFICATION + +The right of modification means the right to adapt, arrange, or make any or all modifications to the Software; being understood that such modifications of the Software shall results in a change of its functionalities and/or in an addition of functionalities to the Initial Software. + +Consequently to distribute a Modified Software according to the provision of section 5.3.2, the Licensee shall make exclusively significant modification as described above to the Software provided that it includes an explicit notice that it is the author of said modification and indicates the date of the creation thereof. + +### 5.3 RIGHT OF DISTRIBUTION + +In particular, the right of distribution includes the right to publish, transmit and communicate the Modified Software to the general public on any or all medium, and by any or all means, and the right to market, either in consideration of a fee, or + +#### 5.3.1 DISTRIBUTION OF SOFTWARE WITHOUT MODIFICATION + +The Licensee is forbidden to distribute true copies of the Software in Source Code or Object Code form. + +#### 5.3.2 DISTRIBUTION OF MODIFIED SOFTWARE + +When the Licensee creates Modified Software, this Modified Software may be distributed provided that said distribution complies with all the provisions of the Agreement and subject to compliance with the requirement to include a notice concerning the rights over the Software as defined in Article 6.3. + +In the event the creation of the Modified Software, the Licensee undertakes that: + +- the resulting Modified Software will be governed by this Agreement, being understood that such Agreement shall be integrated in the Modified Software the Integrated Contributions in the resulting Modified Software will be clearly identified and documented, +- the Licensee will allow effective access to the source code of the Modified Software, at a minimum during the entire period of distribution of the Derivative Software, such that such modifications may be carried over in a subsequent version of the Software. +- the Modified Software must be renamed to exclude any reference to 4D. For example, it is expressly prohibited to distribute a Modified Software named “4D SVG”; Licensee shall rename the Modified Software such as “Name of the Licensee SVG”. Consequently, Licensee is expressly forbidden to use 4D’s product name in general to promote his modified work. + +## Article 6 - INTELLECTUAL PROPERTY + +### 6.1 OVER THE INITIAL SOFTWARE + +The Holder owns the intellectual property rights over the Initial Software. Any or all use of the Initial Software is subject to compliance with the terms and conditions under which the Holder has elected to distribute its work and no one shall be entitled to modify the terms and conditions for the distribution of said Initial Software. + +### 6.2 OVER THE INTEGRATED CONTRIBUTIONS + +The Licensee who develops an Integrated Contribution is the owner of the intellectual property rights over this Contribution as defined by applicable law. + +### 6.3 NOTICE OF RIGHTS + +The Licensee expressly undertakes: + +- not to remove, or modify, in any manner, the intellectual property notices attached to the Software; +- to reproduce said notices, in an identical manner, in the copies of the Software modified; +- to ensure that use of the Software, its intellectual property notices and the fact that it is governed by the Agreement is indicated in a text that is easily accessible, specifically from the interface of any Modified Software. + +The Licensee undertakes not to directly or indirectly infringe the intellectual property rights of the Holder on the Software and to take, where applicable, vis- à-vis its staff, any and all measures required to ensure respect of said intellectual property rights of the Holder. + +## Article 7 - RELATED SERVICES + +Under no circumstances shall the Agreement oblige the Licensor to provide technical assistance or maintenance services for the Software. + +However, the Licensor is entitled to offer this type of services. The terms and conditions of such technical assistance, and/or such maintenance, shall be set forth in a separate instrument. + +## Article 8 - DISCLAIMER OF WARRANTY. + +THERE IS NO WARRANTY FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE HOLDER PROVIDES THE SOFTWARE “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH LICENSEE. SHOULD THE SOFTWARE PROVE DEFECTIVE, LICENSEE ASSUMES THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +## Article 9 - LIMITATION OF LIABILITY + +TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE TO LICENSEE ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS AGREEMENT OR USE OF THE SOFTWARE, EVEN IF THE LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR DAMAGES. + +## Article 10 – TERMINATION + +### 10.1 + +In the event of a breach by the Licensee of its obligations hereunder, the Licensor may automatically terminate this Agreement thirty (30) days after notice has been sent to the Licensee and has remained ineffective. + +### 10.2 + +A Licensee whose Agreement is terminated shall no longer be authorized to use, modify or distribute the Software. However, any licenses that it may have granted prior to termination of the Agreement shall remain valid subject to their having been granted in compliance with the terms and conditions hereof. + +## Article 11 – MISCELLANEOUS + +### 11.1 + +Neither Party shall be liable for any or all delay, or failure to perform the Agreement, that may be attributable to an event of force majeure, an act of God or an outside cause, such as defective functioning or interruptions of the electricity or telecommunications networks, network paralysis following a virus attack, intervention by government authorities, natural disasters, water damage, earthquakes, fire, explosions, strikes and labor unrest, war, etc. + +### 11.2 + +Any failure by either Party, on one or more occasions, to invoke one or more of the provisions hereof, shall under no circumstances be interpreted as being a waiver by the interested Party of its right to invoke said provision(s) subsequently. + +### 11.3 + +In the event that one or more of the provisions hereof were to conflict with a current or future applicable act or legislative text, said act or legislative text shall prevail, and the Parties shall make the necessary amendments so as to comply with said act or legislative text. All other provisions shall remain effective. Similarly, invalidity of a provision of the Agreement, for any reason whatsoever, shall not cause the Agreement as a whole to be invalid. + +## Article 12 - GOVERNING LAW AND JURISDICTION + +### 12.1 + +The Agreement is governed by French law. The Parties agree to endeavor to seek an amicable solution to any disagreements or disputes that may arise during the performance of the Agreement. + +### 12.2 + +Failing an amicable solution within two (2) months as from their occurrence, and unless emergency proceedings are necessary, the disagreements or disputes shall be referred to the Versailles Courts having jurisdiction, by the more diligent Party. \ No newline at end of file From 4c32fd232bb7f48671ea6a8e01b907a3c11cb141 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:41:08 +0100 Subject: [PATCH 089/195] overview.md Spanish --- .../embedding-studio/overview.md | 211 ++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/overview.md diff --git a/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/overview.md b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/overview.md new file mode 100644 index 00000000000000..a45d58e4af31a5 --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/overview.md @@ -0,0 +1,211 @@ +--- +id: overview +title: 4D-Embedding-Studio +--- + +# 4D-Embedding-Studio + +## Generalidades + +4D Embedding Studio is a component for defining, processing, and maintaining AI embedding vectors directly in your 4D dataclass entities. + +You can use the component without writing a single line of code: select attributes from your dataclasses to construct the sentences to be vectorized and specify the model to use. For each entity, the component calls the embedding API and stores the resulting `4D.Vector` values. Configure the embedding scheduler to (re)calculate the vectors for your data at fixed intervals or on demand. + +You can then use the ORDA [`query()` by vector feature](https://developer.4d.com/docs/API/DataClassClass#query-by-vector-similarity) to request your data using semantics. + +If you want to have more control over your embeddings, the component offers an extensive API that allows you to customize each step of the data vectorization process, manage the scheduler, and integrate high-performance RAG (*Retrieval Augmented Generation*) features into your 4D application. + +## Requisitos + +- [4D-AIKit](https://github.com/4d/4D-AIKit) (loaded automatically as a dependency). +- 4D project (21 R5 or later) with the following configuration: + - a valid model alias + - a dataclass with a `4D.Vector` attribute (object field at the database level). + +## Quick Start + +**1. Add a field of type Object to the table and associate it with the `4D.Vector` class.** +**2. Select **Embedding Studio...** in the **Design** menu to display the Embedding Studio window.** + +![menu](../assets/en/embedding-studio/menu.png) + +**3. For each listed `4D.Vector` attribute, write a descriptive phrase based upon attributes of the dataclass.** +Use the contextual menu to insert appropriate attributes. +This phrase will be vectorized for every entity. +**4. Select a model alias (or create a new one).** +**5. Select "Execute now" to launch the vectorization of your data or configure the scheduler.** + +## User Guide + +### Configuring the dataclass + +To use the 4D Embedding Studio interface, you need to create at least one object attribute associated to a `4D.Vector` class in your datastore. This must be done at the database level (only storage attributes can be embeddings). + +In the Structure editor, add an Object field to the dataclass (table) whose entities you want to query using AI and enter ["4D.Vector" as class](https://developer.4d.com/docs/Develop/structure-fields#class). + +#### Dirty-flag support + +In a production application, data is rarely static. If an embedding is based on an attribute value that has changed (e.g. a product description), it becomes obsolete and could no longer be relevant. By default, 4D automatically invalidates and flags for recalculation affected embeddings. + +If you do not use a dirty-flag field (see below), 4D simply replaces any invalidated vector by `Null`. It is therefore no longer used in searches until its next calculation. This option is suitable for applications that prioritize strict consistency: it is better to return no results than to rely on an embedding that no longer matches the current data. + +Or, you can add a Boolean field named `_dirty` (e.g. "myVector_dirty") to the structure. In this case, when an update is required, this field is set to `True`, and the associated vector is retained until it is recalculated. Your application can then choose to continue using this vector temporarily or exclude it using a filter on `dirty = False`. The flag is cleared automatically after a successful save. +This strategy promotes service continuity while allowing you to precisely identify vectors awaiting recalculation. If your business logic requires full control, you can also disable automatic invalidation and manage this lifecycle yourself. + +*Note: Certain modifications, such as a model changes, require vectors to be replaced immediately.* + +### Creating an embedding + +When you select **Embedding Studio...** in the **Design** menu, the Embedding Studio window is displayed. + +The list on the left side shows all `4D.Vector` class attributes defined in the datastore. You can add as many vector attributes as you want per dataclass. + +A check mark (✓) in the Dirty Flag column indicates that a [`_dirty` boolean field](#dirty-flag-support) is associated to the vector field. + +**Note:** Any change in the database structure will require that you restart the 4D application so that the 4D Embedding Studio lists up-to-date values. + +#### Writing a descriptive sentence + +To create or edit an embedding, select the attribute to configure in this list and write the embedding definition in the "Descriptive sentence" area on the right side. Use the associated menu to build the sentence and to add references to dataclass available attributes with the `{attribute_name}` syntax. + +The sentence must build a text that describes the entity just like a human would do it. The embedding could then capturate the semantics and not only attribute values. + +For example, for a `Product` dataclass with many attributes such as name and category, you could write: +"The {name} product is a {category} from the {brand} brand. Description: {description}. Key features: {features}." + +![menu](../assets/en/embedding-studio/studio-interface.png) + +### Selecting a model + +Once you have defined your vector attribute, choose the model to use for generating the embedding. The list of models includes the **model aliases** you defined in the [Project Settings](https://developer.4d.com/docs/settings/ai#model-aliases). + +The choice of model is important because it determines the relevance and quality of your embeddings. You’ll also need to provide this model with every query on the dataclass data so that the comparison is performed using the same model. + +### Auto-invalidate on save + +When this option is checked (default), embeddings are automatically invalidated when at least one of their definition attributes has been modified and the entity was successfully saved. + +However, you might want to handle invalidation in a custom way using the [4D Embedding Studio API](#api-guide). In this case, uncheck this option to disable the automatic mechanism. + +### Calculating embeddings + +Embeddings are calculated by sending a request to the AI model, which then returns the vectorization result, which is subsequently stored in the `4D.Vector` attribute in the dataclass. 4D automatically handles this operation and optimizes it by calculating only the necessary vectors. Each vector is processed independently. Thus, an error on one element does not interrupt the recalculation of the others. Elements that fail will be automatically retried during the next run. Recalculations are performed asynchronously, without blocking users. + +These calculations can be performed **on demand** or **scheduled at regular intervals** using the scheduler in the 4D Embedding Studio component. + +**Note:** You can also customize embedding calculations per dataclass or entity using the [4D Embedding Studio API](#api-guide). + +#### On demand + +To launch an embedding calculation, select **Run now** in the menu at the bottom of the 4D Embedding Studio window. This item is disabled if the datastore does not contain any embedding to calculate. When started, you can select **Cancel run** at any moment. + +#### Backups periódicos + +You can configure the 4D Embedding Studio component scheduler to adjust the calculation frequency to suit your application’s needs. + +**Important:** The scheduler needs a 4D worker process to run. You can start it manually for testing purposes (**Start now** button in the scheduler dialog box) but to make sure a worker is available every times the application opens, you need to configure it. Puede: + +- select the **Execute "On Host Database Event" method of the components** option in the [project Settings](https://developer.4d.com/docs/settings/security#options) +- or write the following code in your startup code: + +```4d + //at startup +cs.EmbeddingStudio.Scheduler.me.start() +``` + +The scheduler allows you can set the time interval between two calculations. Select the tab corresponding to your needs and click **Save**. + +- **Never**: the scheduler is off and never runs +- **At regular interval**: set the time interval between each calculation starting from a specified time. +- **Once a day**: the calculation takes place every day at a specific time + starting from a specific time. + +### Building queries with embeddings + +Once you have defined embeddings in your datastore, you can start [querying your dataclasses using AI-based features](https://developer.4d.com/docs/API/DataClassClass#query-by-vector-similarity). You just need to make sure that you use the same model for your embedding definition and in the query string. + +For example, assuming that: + +• you have defined a `4D.Vector` attribute named "product_vector" in the Products dataclass using a sentence: "The {name} is in the {category} category. It has these {features} features and can be used for {usage}." +• you want to find products that "can be used safely outside". + +Puede escribir: + +```4d +// Retrieve the model alias from the embedding definition, configured in 4D Embedding Studio +var $settings:=cs.EmbeddingStudio.Settings.new() +var $definition:=$settings.find("Products"; "product_vector") + +// Compute the vector of the query with the same model +var $result:=cs.EmbeddingStudio.StudioEmbedder.new().embed("products that can be used safely outside"; $definition) +var $vector:=$result.vector + + //search with default metric (cosine) +var $products:=ds.Products.query("product_vector > :1 order by product_vector desc"; {vector : $vector}) + +``` + +If you use a dirty field, simply add a criterion to exclude vectors waiting to be recalculated: + +```4d +var $products:=ds.Products.query("product_vector > :1 and product_vector_dirty = false order by product_vector desc"; {vector : $vector}) +``` + +## API Guide + +### Quick start + +**1. Configure your vectors** in `Settings/embeddings.json`: + +```json +{ + "batchSize": 50, + "definitions": [ + { + "dataclassName": "Students", + "vectorName": "student_vector_1", + "modelAlias": "text-embedding", + "phrase": "Student {firstName} {lastName}, enrolled in {program}", + "autoInvalidate": true + } + ] +} +``` + +**2. Run the full pipeline** (all definitions, all records): + +```4d +var $p:=cs.EmbeddingStudio.Process.new() +var $r:=$p.process() + +If ($r.success) + ALERT("Updated "+String($r.entitiesUpdated)+" entities in "+String($r.duration)+" ms") +End if +``` + +**3. Process a single entity on save** (e.g. in a trigger or REST hook): + +```4d +var $p:=cs.EmbeddingStudio.Process.new() +$p.processEntity($entity) +``` + +### Class reference + +| Class | Descripción | +| ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [Process](Classes/Process.md) | Main orchestrator — entry point for all batch and entity operations. | +| [Scheduler](Classes/Scheduler.md) | Automated recalculation scheduler — background task, force/cancel, and runtime status. | +| [StudioEmbedder](Classes/StudioEmbedder.md) | Renders and embeds on demand using your saved definitions — e.g. to build a search query vector. Nothing is persisted. | +| [Settings](Classes/Settings.md) | Loads and saves the `embeddings.json` configuration file. | +| [Definition](Classes/Definition.md) | Describes one vector field: dataclass, field name, model alias, and phrase template. | +| [Embedder](Classes/Embedder.md) | Thin wrapper around the AIKit embeddings API with retry/backoff logic. | +| [EmbedderResult](Classes/EmbedderResult.md) | Typed wrapper normalizing API responses — vectors, usage metrics, rate-limit state. | +| [ProcessResult](Classes/ProcessResult.md) | Returned by every batch function — statistics and error breakdown. | +| [ProcessError](Classes/ProcessError.md) | Typed entry in `ProcessResult.errors` — scope, severity, code, ref, message, retryable. | +| [ProcessErrorCode](Classes/ProcessErrorCode.md) | Singleton catalogue of machine-readable error codes and their default severity/retryability. | +| [Phrase](Classes/Phrase.md) | Lightweight `{variable}` template engine used to build text from entity attributes. | + +### Ver también + +Blog post: [Vectorize your data effortlessly with 4D Embedding Studio](https://blog.4d.com/vectorize-your-data-effortlessly-with-4d-vector-studio) \ No newline at end of file From c9828ca111f10ec880931a7e7215a3fbefd1f7e5 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:41:10 +0100 Subject: [PATCH 090/195] ratelimit.md Spanish --- .../embedding-studio/ratelimit.md | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/ratelimit.md diff --git a/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/ratelimit.md b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/ratelimit.md new file mode 100644 index 00000000000000..ac90518d4805db --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/ratelimit.md @@ -0,0 +1,65 @@ +--- +id: ratelimit +title: Rate Limiting +--- + +# Rate Limiting + +The embedding pipeline includes built-in rate-limit awareness. When the API provider returns rate-limit headers (as OpenAI does), the system automatically throttles requests and adapts batch sizes to stay within budget. Providers that don't return rate-limit headers (e.g. Ollama) are unaffected — the pipeline runs at full speed. + +## Principios de funcionamiento + +Each call to [`Embedder.embed()`](Classes/Embedder.md) or [`Embedder.embedBatch()`](Classes/Embedder.md) returns an [`EmbedderResult`](Classes/EmbedderResult.md) that carries rate-limit state alongside the embedding vectors. The pipeline uses this data in a three-step loop: + +1. **Pre-flight throttle** — before sending a batch, the pipeline checks whether the remaining token budget is sufficient. If not, it waits for the reset window to elapse before proceeding. +2. **Adaptive batch sizing** — the pipeline computes the largest batch that fits within 80% of the remaining token budget. This avoids hitting the ceiling while still making efficient use of the quota. +3. **State update** — after each API response, the pipeline records the new remaining budget, computes an average tokens-per-entity estimate, and feeds both into the next iteration. + +## Rate-limit fields on EmbedderResult + +These fields are populated from the API response headers. When a provider doesn't return them, they keep their defaults and the pipeline skips throttling. + +| Campo | Por defecto | Significado | +| ------------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------- | +| `remainingTokens` | `-1` | Tokens left in the current window. `-1` = unknown. | +| `remainingRequests` | `-1` | Requests left in the current window. | +| `limitTokens` | `0` | TPM (tokens per minute) ceiling. | +| `limitRequests` | `0` | RPM (requests per minute) ceiling. | +| `resetTokens` | `""` | Time until the token bucket refills (e.g. `"6m0s"`, `"200ms"`). | +| `resetRequests` | `""` | Time until the request bucket refills. | + +## Batch size adaptation + +The pipeline starts with the configured `batchSize` (from [Settings](Classes/Settings.md), default 50). After the first API response provides rate-limit data, the batch size may shrink: + +``` +nextBatchSize = min( floor(remainingTokens × 0.8 / tokensPerEntity), configBatchSize ) +``` + +- `tokensPerEntity` is estimated from the last chunk (`totalTokens / chunkSize`). +- The result is clamped to a floor of 1 and a ceiling of `configBatchSize`. +- When `remainingTokens` is unknown (`-1`), the configured batch size is used as-is. + +## Pre-flight wait + +Before each batch, the pipeline checks: + +- **Token budget**: if `remainingTokens < estimatedTokens × 1.1`, it waits for the token reset window. +- **Request budget**: if `remainingRequests = 0`, it waits for the request reset window. + +The reset durations are parsed from the API's string format (`"6m0s"` → 360 seconds, `"200ms"` → 1 second). + +## Providers without rate limits + +Some providers (Ollama, local models) don't return rate-limit headers. En este caso: + +- `remainingTokens` stays at `-1` (unknown) +- No throttling occurs — batches run at `configBatchSize` without waits +- The pipeline works identically to how it did before rate-limit support was added + +## Ver también + +- [EmbedderResult](Classes/EmbedderResult.md) — carries rate-limit fields +- [Embedder](Classes/Embedder.md) — wraps the API calls +- [Process](Classes/Process.md) — orchestrates the batch loop +- [Settings](Classes/Settings.md) — `batchSize` configuration From 0a755745d4b15e950a155fa76752f39d2c870ef2 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:41:13 +0100 Subject: [PATCH 091/195] menu.png Japanese --- .../current/assets/en/embedding-studio/menu.png | Bin 0 -> 4938 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 i18n/ja/docusaurus-plugin-content-docs/current/assets/en/embedding-studio/menu.png diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/assets/en/embedding-studio/menu.png b/i18n/ja/docusaurus-plugin-content-docs/current/assets/en/embedding-studio/menu.png new file mode 100644 index 0000000000000000000000000000000000000000..425fd0d7e65879e34700b856cf6f88aaa9c502e1 GIT binary patch literal 4938 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 E0Cv$VrvLx| literal 0 HcmV?d00001 From 71afde8bb66818e7d57a6d6996b7ac055b066d3d Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:41:15 +0100 Subject: [PATCH 092/195] studio-interface.png Japanese --- .../en/embedding-studio/studio-interface.png | Bin 0 -> 34492 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 i18n/ja/docusaurus-plugin-content-docs/current/assets/en/embedding-studio/studio-interface.png diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/assets/en/embedding-studio/studio-interface.png b/i18n/ja/docusaurus-plugin-content-docs/current/assets/en/embedding-studio/studio-interface.png new file mode 100644 index 0000000000000000000000000000000000000000..75dae7c9303297334e2fee1b404527957dfd4746 GIT binary patch literal 34492 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 Z0#D?x@H3fRStk8kMM>jk;f?!G{uip+WAXq1 literal 0 HcmV?d00001 From f5cde3dc6a45e99fa4391b2a0d6ef8d0a2cecccd Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:41:18 +0100 Subject: [PATCH 093/195] definition.md Japanese --- .../embedding-studio/Classes/Definition.md | 165 ++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Definition.md diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Definition.md b/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Definition.md new file mode 100644 index 00000000000000..7b9bf4e7a585df --- /dev/null +++ b/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Definition.md @@ -0,0 +1,165 @@ +--- +id: 定義 +title: 定義 +--- + +# 定義 + +The `Definition` class describes how a single vector field on a dataclass should be computed: which dataclass, which vector field, which model alias, and which text template ([Phrase](Phrase.md)) to render from each entity. + +A collection of these is what [Settings](Settings.md) persists. + +## プロパティ + +| プロパティ名 | 型 | 説明 | +| ---------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------- | +| `dataclassName` | Text | Name of the target dataclass. | +| `vectorName` | Text | Name of the `4D.Vector` field on that dataclass. | +| `modelAlias` | Text | Embedding model alias (e.g. `"text-embedding-3-small"`). | +| `phrase` | [Phrase](Phrase.md) | Compiled template used to build the text that will be embedded. | +| `autoInvalidate` | Boolean | Controls automatic invalidation on entity save. Default: `True`. | + +## Class constructor + +Create a definition. + +| 引数名 | 型 | 説明 | +| ---------------- | ---- | -------------------------------------------------------------------------------------------------- | +| *dataclassName* | Text | Name of the target dataclass. | +| *vectorName* | Text | Name of the target vector field. | +| *modelAlias* | Text | Embedding model alias. | +| *phraseTemplate* | Text | Phrase template with `{field}` placeholders — compiled into a [Phrase](Phrase.md). | + +```4d +var $def:=cs.EmbeddingStudio.Definition.new(\ + "Students"; \ + "student_vector_1"; \ + "text-embedding-3-small"; \ + "Student {firstName} {lastName}") +``` + +## 計算プロパティ + +### hasDefinition + +**hasDefinition** : Boolean *(read-only)* + +Returns `True` if at least a model or a phrase template has been set. A definition without either has no content to process. + +```4d +If ($def.hasDefinition) + // worth validating further +End if +``` + +## 関数 + +### validate() + +**validate**( *settings* : Settings ) : Object + +Validates the definition against the live datastore model and the known embedding models. All errors are collected before returning — the result always describes the full set of problems found. + +| 引数 | 型 | 説明 | +| ---- | ------------------------------- | ------------------------------------------------------------------------------------------------------------ | +| *設定* | [Settings](Settings.md) \| Null | Used to pass phrase validation options. Pass `Null` to skip phrase options. | +| 戻り値 | Object | `{success: Boolean, errors: Collection}` where each error is `{field: Text, message: Text}`. | + +Checked in order: + +| Check | `field` value | +| ------------------------------------ | ----------------- | +| `dataclassName` is not empty | `"dataclassName"` | +| `vectorName` is not empty | `"vectorName"` | +| `modelAlias` is set and recognised | `"modelAlias"` | +| Dataclass exists in `ds` | `"dataclassName"` | +| Vector field exists | `"vectorName"` | +| Field type is `4D.Vector` | `"vectorName"` | +| Phrase template is not empty | `"phrase"` | +| Phrase keys resolve in the dataclass | `"phrase"` | + +The first two checks (identity) return immediately on failure; the remaining checks accumulate so all problems are reported in one pass. + +```4d +var $result:=$def.validate(cs.EmbeddingStudio.Settings.new()) + +If (Not($result.success)) + var $err : Object + For each ($err; $result.errors) + TRACE // $err.field, $err.message + End for each +End if +``` + +### invalidateVectors() + +**invalidateVectors**() : Object + +Marks all already-computed entities for re-embedding, forcing a full rebuild on the next run. Only entities that already have a vector value are processed — entities with a `Null` vector are skipped. + +Useful during development or after a model/phrase change to trigger a clean rebuild of all vectors. + +The strategy depends on whether a companion `_dirty` field exists on the dataclass: + +| Companion `_dirty` field | Action taken | +| ------------------------ | -------------------------------------------------------------- | +| Present | Sets `_dirty` to `True` — vector is left untouched | +| Absent | Nullifies the vector field | + +| 引数 | 型 | 説明 | +| --- | ------ | ------------------------------------------------------------------ | +| 戻り値 | Object | `{updated: Integer, skipped: Integer, errors: Collection of Text}` | + +- `updated` — number of entities successfully marked +- `skipped` — number of entities that could not be saved +- `errors` — one entry per save failure, formatted as `"DataclassName: statusText"` + +```4d +var $result:=$def.invalidateVectors() + +If ($result.skipped > 0) + var $e : Text + For each ($e; $result.errors) + // $e + End for each +End if +// → { updated: 42; skipped: 0; errors: [] } +``` + +### toObject() + +**toObject**() : Object + +Returns a plain object suitable for JSON persistence. The phrase is flattened to its template text. + +| 引数 | 型 | 説明 | +| --- | ------ | --------------------------------------------------------------------------------------------------------------------------------- | +| 戻り値 | Object | `{version, dataclassName, vectorName, modelAlias, phrase, autoInvalidate}` where `phrase` is the template string. | + +```4d +$def.toObject() +// → { version: 0; dataclassName: "Students"; vectorName: "student_vector_1"; +// modelAlias: "text-embedding-3-small"; phrase: "Student {firstName} {lastName}"; +// autoInvalidate: true } +``` + +## Automatic invalidation + +`autoInvalidate` controls whether save-time automatic invalidation is enabled for this definition. + +- `True` (default): when relevant attributes change on an entity save, vectors are automatically invalidated. +- `False`: save-time automatic invalidation is skipped for this definition. + +This setting does not affect manual invalidation via `invalidateVectors()`. + +## Dirty flag convention + +The pipeline in [Process](Process.md) will recompute an entity whenever the target vector is `Null`, or when a sibling field `_dirty` exists on the dataclass and is `True`. + +Declaring the dirty flag is optional — when absent, only the null-vector case triggers recomputation. When present, it is cleared automatically on successful save. + +## 参照 + +- [Settings](Settings.md) +- [Process](Process.md) +- [Phrase](Phrase.md) From 73a18228317bdf1180828979ab91d071bd2a4686 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:41:20 +0100 Subject: [PATCH 094/195] embedder.md Japanese --- .../embedding-studio/Classes/Embedder.md | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Embedder.md diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Embedder.md b/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Embedder.md new file mode 100644 index 00000000000000..1d0f1ae886f748 --- /dev/null +++ b/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Embedder.md @@ -0,0 +1,96 @@ +--- +id: embedder +title: Embedder +--- + +# Embedder + +The `Embedder` class is a thin wrapper around [4D AIKit](https://developer.4d.com/docs/aikit/Classes/openai) focused on embeddings. It exposes two functions — one for a single text, one for a batch — and handles retries with exponential backoff (respecting the `Retry-After` header when present). + +It is stateless beyond configuration and safe to share between processes. + +## プロパティ + +| プロパティ名 | 型 | 説明 | +| ------------ | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | +| `client` | cs.AIKit.OpenAI | The underlying AIKit client used for HTTP requests. | +| `maxRetries` | Integer | Maximum number of retries on transient errors. Default: `3`. | +| `backoffMs` | Integer | Base delay (ms) between retries. Doubled each attempt. | + +## Class constructor + +Create a embedder. All options are optional. + +| 引数名 | 型 | 説明 | +| --------- | ------ | ----------------------------------------------------------------------------- | +| *options* | Object | `{client, maxRetries, backoffMs}` — any field may be omitted. | + +```4d +// Default — uses cs.AIKit.OpenAI.new() internally +var $proc:=cs.EmbeddingStudio.Embedder.new() + +// Provide a pre-configured AIKit client (custom API key, base URL, etc.) +var $client:=cs.AIKit.OpenAI.new({apiKey: "…"; baseURL: "https://server.ai"}) +var $proc:=cs.EmbeddingStudio.Embedder.new({client: $client; maxRetries: 5; backoffMs: 1000}) +``` + +> If the 4D AIKit component is not loaded (or is too old to provide `OpenAIProviders`), the constructor still succeeds with a `Null` client, and the first `embed()` / `embedBatch()` call throws an error whose `message` explains what is missing and whose `isAIKitMissing` property is `True`. + +## 関数 + +### embed() + +**embed**(*text* : Text ; *model* : Text) : [cs.EmbeddingStudio.EmbedderResult](EmbedderResult.md) + +Embed a single text. Returns a typed result with the embedding vector, token usage, and rate-limit state. + +| 引数 | 型 | 説明 | +| ------- | -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| *テキスト* | Text | The text to vectorize. | +| *model* | Text | The embedding model to use (e.g. `"text-embedding-3-small"`). | +| 戻り値 | [cs.EmbeddingStudio.EmbedderResult](EmbedderResult.md) | Typed wrapper — `.vector` holds the embedding, `.promptTokens` / `.totalTokens` hold usage, rate-limit fields are flat camelCase. | + +Throws if retries are exhausted or the API returns a non-retryable error. + +```4d +var $result:=$proc.embed("it rains cats and dogs"; "text-embedding-3-small") +// $result.vector → 4D.Vector +// $result.promptTokens → Integer +// $result.totalTokens → Integer +// $result.remainingTokens → Integer (-1 if unknown) +``` + +### embedBatch() + +**embedBatch**(*texts* : Collection ; *model* : Text) : [cs.EmbedderResult](EmbedderResult.md) + +Embed a collection of texts in a single API call. Returns a typed result with vectors in the same order as inputs, token usage, and rate-limit state. + +| 引数 | 型 | 説明 | +| ------- | ------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------- | +| *texts* | Collection | Collection of Text to vectorize. Empty or `Null` returns an empty result. | +| *model* | Text | The embedding model to use. | +| 戻り値 | [cs.EmbedderResult](EmbedderResult.md) | Typed wrapper — `.vectors` holds the embeddings collection, token and rate-limit fields are flat camelCase. | + +```4d +var $result:=$proc.embedBatch(["hello"; "world"]; "text-embedding-3-small") +// $result.vectors[0] → 4D.Vector for "hello" +// $result.vectors[1] → 4D.Vector for "world" +// $result.totalTokens → Integer (sum for the batch) +// $result.remainingTokens → Integer (after this call) +``` + +## Retry policy + +Transient errors (HTTP 408, 409, 429, 5xx) are retried up to `maxRetries` times. + +- If the response carries a `Retry-After` or `retry-after-ms` header, the embedder waits that long. +- Otherwise, it waits `backoffMs * 2^attempt`. + +Non-retryable errors are thrown immediately — see [OpenAIError](https://developer.4d.com/docs/aikit/Classes/openaierror) for the thrown shape. + +## 参照 + +- [EmbedderResult](EmbedderResult.md) +- [Process](Process.md) +- [OpenAIEmbeddingsAPI](https://developer.4d.com/docs/aikit/Classes/openaiembeddingsapi) (AIKit) From b99792ef81c40fbe5819b1df517a5ff22693737c Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:41:23 +0100 Subject: [PATCH 095/195] embedderresult.md Japanese --- .../Classes/EmbedderResult.md | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/EmbedderResult.md diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/EmbedderResult.md b/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/EmbedderResult.md new file mode 100644 index 00000000000000..c2c44f170ee6e7 --- /dev/null +++ b/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/EmbedderResult.md @@ -0,0 +1,80 @@ +--- +id: embedderresult +title: EmbedderResult +--- + +# EmbedderResult + +Typed wrapper for `Embedder.embed()` and `Embedder.embedBatch()` responses. Normalizes OpenAI's snake_case API keys (`prompt_tokens`, `total_tokens`) to camelCase properties, and flattens the nested rate-limit structure into direct properties. + +A single class handles both single and batch results — `embed()` populates `.vector`, `embedBatch()` populates `.vectors`. + +## プロパティ + +### Embedding results + +| プロパティ | 型 | デフォルト | 説明 | +| --------- | ------------------------- | ----- | ------------------------------------------------------------------------------ | +| `vector` | 4D.Vector | Null | Single embedding result. Null for batch calls. | +| `vectors` | Collection | `[]` | Batch embedding results. | + +### Token usage + +| プロパティ | 型 | デフォルト | 説明 | +| -------------- | ------- | ----- | -------------------------------------------------------------------- | +| `promptTokens` | Integer | `0` | Input tokens consumed. | +| `totalTokens` | Integer | `0` | Total tokens consumed (in + out). | + +### Rate-limit state + +| プロパティ | 型 | デフォルト | 説明 | +| ------------------- | ------- | ----- | ------------------------------------------------------------------------------------------------------------------- | +| `remainingTokens` | Integer | `-1` | Tokens left in the current window. `-1` = unknown. | +| `remainingRequests` | Integer | `-1` | Requests left in the current window. `-1` = unknown. | +| `limitTokens` | Integer | `0` | TPM ceiling for the account. | +| `limitRequests` | Integer | `0` | RPM ceiling for the account. | +| `resetTokens` | Text | `""` | Time until token bucket refills (e.g. `"6m0s"`). | +| `resetRequests` | Text | `""` | Time until request bucket refills (e.g. `"1s"`). | + +## Class constructor + +```4d +// From a real API result (used by Embedder internally) +var $result:=cs.EmbedderResult.new($aikitResult; True) // batch +var $result:=cs.EmbedderResult.new($aikitResult; False) // single + +// Empty result (no API call — e.g. empty batch) +var $result:=cs.EmbedderResult.new() +``` + +| 引数 | 型 | 説明 | +| --------- | ------- | ------------------------------------------------------------------------------------------------------------ | +| *実行結果* | Object | An object with `.vector`/`.vectors`, `.usage`, `.rateLimit` (duck-typed). | +| *isBatch* | Boolean | `True` to read `.vectors`, `False` to read `.vector`. | + +The constructor accepts any object that exposes the expected shape — it does not require a specific class. This makes it easy to construct in tests. + +## 効果 + +```4d +// Single embedding +var $r:=$embedder.embed("hello world"; "text-embedding-3-small") +$r.vector // → 4D.Vector +$r.promptTokens // → 6 +$r.totalTokens // → 6 + +// Batch embedding +var $r:=$embedder.embedBatch(["hello"; "world"]; "text-embedding-3-small") +$r.vectors.length // → 2 +$r.totalTokens // → 10 + +// Rate-limit awareness +$r.remainingTokens // → 148230 (or -1 if not yet known) +$r.resetTokens // → "6m0s" +``` + +## 参照 + +- [Embedder](Embedder.md) — creates EmbedderResult instances +- [ProcessResult](ProcessResult.md) — run-level report that accumulates EmbedderResult usage +- [Rate Limiting](../RateLimit.md) — how the pipeline uses rate-limit fields for throttling and batch sizing From facf38df109c20730c769a482c0a85529363822f Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:41:25 +0100 Subject: [PATCH 096/195] phrase.md Japanese --- .../embedding-studio/Classes/Phrase.md | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Phrase.md diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Phrase.md b/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Phrase.md new file mode 100644 index 00000000000000..151bec7cb2c351 --- /dev/null +++ b/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Phrase.md @@ -0,0 +1,117 @@ +--- +id: phrase +title: Phrase +--- + +# Phrase + +The `Phrase` class is a lightweight template engine: a template with `{variable}` placeholders is compiled once, then rendered efficiently against different data objects. + +## プロパティ + +| プロパティ名 | 型 | 説明 | +| ---------- | ---------- | ---------------------------------------------------------------------------------------------------------------------- | +| `template` | Text | Computed — returns the original template string. | +| `keys` | Collection | Computed — returns the variable names found in the template, dot-notation keys joined back to strings. | + +## Class constructor + +Compile a template. Compilation walks the template once and extracts static parts and variable paths. + +| 引数名 | 型 | 説明 | +| ---------- | ---- | ---------------------------------------------------------- | +| *template* | Text | Template string with `{variable}` markers. | + +```4d +var $tpl:=cs.EmbeddingStudio.Phrase.new("Hello {firstName}, you study at {schoolName}.") +$tpl.keys // → ["firstName"; "schoolName"] +``` + +## 関数 + +### render() + +**render**(*data* : Object) : Text + +Render the compiled template by replacing variables with values from *data*. Missing keys produce an empty string. + +| 引数 | 型 | 説明 | +| ------ | ------ | ------------------------------------------------------------------------------------------------------ | +| *data* | Object | A plain object or a 4D.Entity whose fields supply the variable values. | +| 戻り値 | Text | The rendered text. | + +```4d +var $text:=$tpl.render({firstName: "Alice"; school: {name: "MIT"}}) +// → "Hello Alice, you study at MIT." + +// Works directly on entities +$text:=$tpl.render(ds.Students.first()) +``` + +### validate() + +**validate**(*dataclass* : 4D.DataClass ; *options* : Object) : Object + +Validate that all keys in the phrase can be resolved against the given dataclass. Walks dot-notation paths through N:1 / 1:1 relations. + +| 引数 | 型 | 説明 | +| --------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| *データクラス* | 4D.DataClass | The dataclass to validate against. | +| *options* | Object | Optional validation flags (see below). All default to `False` — storage kind only. | +| 戻り値 | Object | `{success: Boolean, errors: Collection of {key, message}}`. | + +#### オプション + +| フィールド | 型 | デフォルト | 説明 | +| ----------------- | ------- | ------- | ----------------------------------------------------------------------------------------------------- | +| `allowRelations` | Boolean | `false` | Allow dot-notation paths through N:1 / 1:1 relations. | +| `allowCalculated` | Boolean | `false` | Allow calculated attributes. | +| `allowAlias` | Boolean | `false` | Allow alias attributes. | + +```4d +var $tpl:=cs.EmbeddingStudio.Phrase.new("{firstName} at {school.name}") + +// Storage-only validation — fails because {school.name} uses a relation +var $v:=$tpl.validate(ds.Students) +// $v.success → False +// $v.errors → [{key: "school.name"; message: "..."}] + +// Allow relations +$v:=$tpl.validate(ds.Students; {allowRelations: True}) +// $v.success → True +``` + +#### Rejected shapes + +Regardless of options: + +- Attributes that do not exist on the dataclass. +- Attributes whose class ID is `4D.Vector`. +- 1:N relations (`relatedEntities`) as the final key. +- Intermediate segments that are not relations (when dot-notation is used). + +### 属性() + +**attributes**(*dataclass* : 4D.DataClass) : Collection + +Resolves each phrase key against *dataclass* and returns an ordered Collection of ORDA attribute descriptor objects, one per key in the same order as `.keys`. For dot-notation paths, traverses N:1 relations to reach the final attribute. Pushes `Null` for any key whose path cannot be resolved (unknown attribute or non-relation intermediate segment). + +| 引数 | 型 | 説明 | +| -------- | ---------------------------- | -------------------------------------------------------------------------------------------- | +| *データクラス* | 4D.DataClass | The dataclass to resolve attributes against. | +| 戻り値 | Collection | Ordered collection of ORDA attribute objects (or `Null`). | + +Each resolved entry is an ORDA attribute descriptor with `.name`, `.kind`, and more — see [DataClass.attributeName](https://developer.4d.com/docs/API/DataClassClass#attributename). + +```4d +var $tpl:=cs.EmbeddingStudio.Phrase.new("{firstName} graduated from {school.name}") +var $attrs:=$tpl.attributes(ds.Students) +// $attrs[0].name → "firstName" $attrs[0].type → "string" +// $attrs[1].name → "name" $attrs[1].type → "string" (from School dataclass) +// $attrs[1] is Null if school.name could not be resolved +``` + +## 参照 + +- [Definition](Definition.md) — holds a `Phrase`. +- [StudioEmbedder.render()](StudioEmbedder.md#render) — renders a phrase for an entity, non-persisting. From fba1c9e7d29786f804761fb787cd8fc8aaf53382 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:41:28 +0100 Subject: [PATCH 097/195] process.md Japanese --- .../embedding-studio/Classes/Process.md | 188 ++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Process.md diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Process.md b/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Process.md new file mode 100644 index 00000000000000..c71a3fa7cee303 --- /dev/null +++ b/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Process.md @@ -0,0 +1,188 @@ +--- +id: プロセス +title: プロセス +--- + +# プロセス + +The `Process` class orchestrates the full embedding pipeline: it browses 4D entities, renders text from their fields using a [Definition](Definition.md), calls the embeddings API through an [Embedder](Embedder.md), and stores the resulting `4D.Vector` on each entity. + +To render or embed on demand without persistence (search query vectors, phrase previews), see [StudioEmbedder](StudioEmbedder.md). + +## プロパティ + +| プロパティ名 | 型 | 説明 | +| ---------- | ----------------------- | -------------------------------------------------------------------------------------------------------- | +| `設定` | [Settings](Settings.md) | The settings (definitions, batch size, phrase validation options). | +| `embedder` | [Embedder](Embedder.md) | The API-calling engine. Stateless and swappable. | +| `options` | Object | Runtime options object (see [Options object](#options-object) below). | + +### Options object + +| キー | 型 | 説明 | +| ---------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `onProgress` | 4D.Function | Called after each processed chunk with `{definition, report}`. | +| `onSuccess` | 4D.Function | Called once at the end when `report.success = True`, with `{report, success, errors}`. | +| `onError` | 4D.Function | Called once at the end when `report.success = False`, with `{report, success, errors}`. | +| `onTerminate` | 4D.Function | Called once at the end in all cases (after `onSuccess`/`onError`), with `{report, success, errors}`. | +| `dryRun` | Boolean | If `True`, runs selection/filter logic but skips API calls and entity saves. | +| `force` | Boolean | If `True`, recomputes every entity ignoring null-vector / dirty-flag filter. | +| `debug` | Boolean | If `True`, emits additional diagnostic log entries. | +| `pauseIndexes` | Boolean | If `True`, index maintenance on the target table is paused for the duration of a `processEntitySelection` batch run, then resumed right after (or on early exit/critical error). Default `False` — indexes are left alone. See [Pausing indexes](#pausing-indexes) before enabling it. | +| `waitForIndexes` | Boolean | Only used with `pauseIndexes`. If `True`, resuming indexes blocks until they are rebuilt. Default `False` — resume is asynchronous (indexes rebuilt in the background). | +| `shouldCancel` | 4D.Function | Predicate called between chunks during selection processing. Returning `True` stops the run gracefully (cooperative cancel) — what [`Scheduler.cancel()`](Scheduler.md#cancel) uses. | +| `embedder` | [Embedder](Embedder.md) | Inject a custom embedder (otherwise a default one is created). | + +## Class constructor + +Create an instance of the orchestrator. + +| 引数名 | 型 | 説明 | +| --------- | ----------------------- | ------------------------------------------------------------------------------------------------ | +| *設定* | [Settings](Settings.md) | 任意。 If omitted, settings are loaded from the default `Settings/embeddings.json`. | +| *options* | Object | Optional runtime options (see table above). | + +```4d +// Simplest — uses defaults +var $p:=cs.EmbeddingStudio.Process.new() + +// With explicit settings +var $p:=cs.EmbeddingStudio.Process.new($settings) + +// With options +var $p:=cs.EmbeddingStudio.Process.new($settings; {\ + force: True; \ + onProgress: Formula(ALERT("chunk done: "+String($1.report.entitiesUpdated)))}) +``` + +## Batch processing functions + +### プロセス() + +**process**(*definition* : Variant) : [ProcessResult](ProcessResult.md) + +Process one, many, or all [Definition](Definition.md) entries against the full content of their target dataclass. + +| 引数 | 型 | 説明 | +| ---- | -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | +| *定義* | `Null`, [Definition](Definition.md), `4D.DataClass`, plain object, or Collection | See [process() resolution](#process-resolution). `Null` → every definition in settings. | +| 戻り値 | [ProcessResult](ProcessResult.md) | Statistics and per-error breakdown. | + +```4d +// Every definition in settings +var $r:=$p.process() + +// One specific definition +var $r:=$p.process($def) + +// Multiple definitions +var $r:=$p.process([$def1; $def2]) + +// Every definition configured for a whole dataclass +var $r:=$p.process(ds.Students) + +// A plain descriptor — looked up in settings, or built on the fly +var $r:=$p.process({dataclassName: "Students"; vectorName: "student_vector_1"}) + +// Any mix — each item is resolved independently and flattened +var $r:=$p.process([ds.Students; $def; {dataclassName: "School"; vectorName: "school_vector_1"}]) +``` + +#### process() resolution + +`process()` has no entity context, so it resolves each input into concrete [Definition](Definition.md) objects directly from settings: + +| 入力 | 動作 | +| -------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `Null` | Every definition in settings. | +| [Definition](Definition.md) | Used as-is. | +| `4D.DataClass` (e.g. `ds.Students`) | Every definition in settings whose `dataclassName` matches that dataclass. | +| `{dataclassName: "..."; vectorName: "..."}` | The matching saved definition, or — if none is found — a new `Definition` built from the object's fields (`modelAlias`, `phrase.template`). | +| Collection | Each item is resolved with the rules above and the results are **flattened** into one collection (a `4D.DataClass` item can expand to several definitions). Unsupported items are dropped. | +| Anything else | Empty result. | + +### processEntity() + +**processEntity**(*entity* : 4D.Entity ; *definition* : Variant) : [ProcessResult](ProcessResult.md) + +Process a single entity. Cheap path — no chunking, no server-side filter. + +| 引数 | 型 | 説明 | +| -------- | ----------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | +| *entity* | 4D.Entity | The entity to (re)compute vectors for. | +| *定義* | `Null`, [Definition](Definition.md), Collection, or `{vectorName: ...}` | See [resolution rules](#definition-resolution). `Null` infers from entity's dataclass. | +| 戻り値 | [ProcessResult](ProcessResult.md) | Statistics and per-error breakdown. | + +```4d +// Auto-resolve every definition matching this entity's dataclass +var $r:=$p.processEntity($entity) + +// Specific definition +var $r:=$p.processEntity($entity; $def) + +// By vector name only (looked up in settings against the entity's dataclass) +var $r:=$p.processEntity($entity; {vectorName: "student_vector_1"}) +``` + +### processEntitySelection() + +**processEntitySelection**(*selection* : 4D.EntitySelection ; *definition* : Variant) : [ProcessResult](ProcessResult.md) + +Workhorse path for large jobs. Chunks the selection by `settings.batchSize`, sends one API call per chunk, saves each entity individually. + +| 引数 | 型 | 説明 | +| ----------- | ----------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | +| *selection* | 4D.EntitySelection | Entities to process. Pre-filtering by the caller is allowed; the pipeline still applies its null/dirty filter. | +| *定義* | `Null`, [Definition](Definition.md), Collection, or `{vectorName: ...}` | See [resolution rules](#definition-resolution). | +| 戻り値 | [ProcessResult](ProcessResult.md) | Statistics and per-error breakdown. | + +```4d +var $todo:=ds.Students.query("country = :1"; "FR") +var $r:=$p.processEntitySelection($todo; $def) +``` + +### Definition resolution (entity context) + +The polymorphic *definition* argument accepted by `processEntity` and `processEntitySelection`. Unlike [`process()`](#process-resolution), these have an entity/selection to infer the dataclass from, so a bare `{vectorName: "..."}` stub is enough: + +| 入力 | 動作 | +| --------------------------- | ----------------------------------------------------------------------------------------------- | +| `Null` | All definitions in settings whose `dataclassName` matches the entity/selection. | +| [Definition](Definition.md) | Used as-is; the `dataclassName` must match the entity/selection. | +| `{vectorName: "..."}` | Looked up in settings by `vectorName` against the entity/selection dataclass. | +| Collection | Each item resolved using the rules above; mismatches are silently dropped. | + +### Recompute rules + +An entity is (re)computed when **any** of these are true: + +- The target vector field is `Null`. +- A sibling field named `{vectorName}_dirty` exists and is `True`. +- The `force` option is `True`. + +The dirty field is optional per dataclass. If it doesn't exist, only the null-vector case triggers recomputation. Upon successful save, the pipeline clears the dirty flag (when present). + +For `processEntitySelection`, the filter is executed as a server-side ORDA query before any API call, so only the rows that actually need work are loaded into memory. For `processEntity`, the check is done in memory on the already-fetched entity. + +### Pausing indexes + +By default the indexes of the target table are maintained normally while vectors are saved. With the `pauseIndexes` option, a batch run calls [`PAUSE INDEXES`](https://developer.4d.com/docs/commands/pause-indexes) on the table before writing and [`RESUME INDEXES`](https://developer.4d.com/docs/commands/resume-indexes) once done (also on early exit or critical error). + +Be aware of what these commands do: + +- `PAUSE INDEXES` disables **all** the indexes of the table (except the primary key index), not only the vector ones: every index on every other field of the table is paused too. While paused, queries and sorts on that table, including those of other processes, run without any index. +- `RESUME INDEXES` then **rebuilds all these indexes**, for the whole table, not only for the records that were recomputed. On a table with several indexes, this rebuild can cost more than the time saved during the writes. +- With `waitForIndexes` set to `True`, the run blocks until the rebuild completes; otherwise the rebuild runs in the background. +- These commands cannot run on a 4D remote client: there the option is ignored (a warning is logged once) and the recalculation runs with indexes maintained normally. Run it on the server, for example through the [Scheduler](Scheduler.md), to use it. + +Enable it only for large recalculations, such as computing the vectors of a whole table for the first time. + +## 参照 + +- [StudioEmbedder](StudioEmbedder.md) +- [Settings](Settings.md) +- [Definition](Definition.md) +- [Embedder](Embedder.md) +- [ProcessResult](ProcessResult.md) +- [Phrase](Phrase.md) +- [Rate Limiting](../RateLimit.md) From bef5bd8c50c167155cc20cbf157ddcac9ffc63cc Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:41:30 +0100 Subject: [PATCH 098/195] processerror.md Japanese --- .../embedding-studio/Classes/ProcessError.md | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/ProcessError.md diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/ProcessError.md b/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/ProcessError.md new file mode 100644 index 00000000000000..fa8a4e0316d6d6 --- /dev/null +++ b/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/ProcessError.md @@ -0,0 +1,87 @@ +--- +id: processerror +title: ProcessError +--- + +# ProcessError + +A `ProcessError` is one structured, typed entry in the `errors` collection of a [ProcessResult](ProcessResult.md). Its typed fields let callers react to a specific failure mode programmatically — retry transient failures, abort on a fatal model outage, count save failures — without parsing message strings. + +You read these instances from [ProcessResult](ProcessResult.md)`.errors`, directly or through its query helpers (`errorsByCode`, `errorsByScope`, `retryableErrors`). + +## プロパティ + +| プロパティ名 | 型 | 説明 | +| ----------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `スコープ` | Text | Where the error originated: `"pipeline"`, `"definition"`, `"chunk"`, or `"entity"`. | +| `severity` | Text | `"warning"`, `"error"`, or `"fatal"`. Determined by `code` (see [ProcessErrorCode](ProcessErrorCode.md)). | +| `code` | Integer | Machine-readable error code — compare against the constants on [ProcessErrorCode](ProcessErrorCode.md). | +| `ref` | Variant | Scope-dependent reference: `"Dataclass.vector"`, an entity primary key, a model alias, or `Null`. | +| `message` | Text | Human-readable, localized message. | +| `retryable` | Boolean | `True` when re-running the operation could plausibly succeed. Determined by `code`. | + +### scope values + +| スコープ | 意味 | +| -------------- | -------------------------------------------------------------------------------------------------------------------------- | +| `"pipeline"` | Top-level failure affecting the whole run (null selection, a model became unavailable). | +| `"definition"` | A [Definition](Definition.md) failed validation or was skipped. | +| `"chunk"` | A whole batch (chunk) of entities failed in a single API call. | +| `"entity"` | A single entity failed to embed or save. | + +### severity values + +| Severity | 意味 | +| --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `"警告"` | Non-blocking — does **not** make [ProcessResult](ProcessResult.md)`.success` false. | +| `"error"` | A recoverable failure scoped to one entity, chunk, or definition. Makes `success` false. | +| `"fatal"` | Blocks the rest of the run (e.g. the model is unavailable). Also surfaces via `hasFatal`. | + +## 計算プロパティ + +| プロパティ | 型 | 説明 | +| --------- | ------- | ------------------------------------------------- | +| `isFatal` | Boolean | `True` when `severity = "fatal"`. | + +## 関数 + +### toObject() + +**toObject**() : Object + +Returns a plain object (`{scope, severity, code, ref, message, retryable}`) suitable for logging or JSON serialization. + +| 引数 | 型 | 説明 | +| --- | ------ | ------------------------------------------------------ | +| 戻り値 | Object | A JSON-friendly snapshot of the error. | + +## 例題 + +React to failures by type rather than by message text: + +```4d +var $r:=$p.process() + +If (Not($r.success)) + + If ($r.hasFatal) + ALERT("A model became unavailable — aborting until it recovers.") + End if + + var $codes:=cs.EmbeddingStudio.ProcessErrorCode.me + var $saveFailures:=$r.errorsByCode($codes.SAVE_FAILED) + If ($saveFailures.length>0) + ALERT(String($saveFailures.length)+" entities failed to save.") + End if + + // Collect entity keys worth retrying later + var $retry:=$r.retryableErrors().query("scope = :1"; "entity").extract("ref") + +End if +``` + +## 参照 + +- [ProcessErrorCode](ProcessErrorCode.md) — the catalogue of `code` values and their severity/retryability. +- [ProcessResult](ProcessResult.md) — owns the `errors` collection and the query helpers (`errorsByCode`, `errorsByScope`, `retryableErrors`). +- [Process](Process.md) — produces these errors. From 96e6efa3a87f774286541e0740151f08986efc71 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:41:32 +0100 Subject: [PATCH 099/195] processerrorcode.md Japanese --- .../Classes/ProcessErrorCode.md | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/ProcessErrorCode.md diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/ProcessErrorCode.md b/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/ProcessErrorCode.md new file mode 100644 index 00000000000000..dafd474bde19ec --- /dev/null +++ b/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/ProcessErrorCode.md @@ -0,0 +1,55 @@ +--- +id: processerrorcode +title: ProcessErrorCode +--- + +# ProcessErrorCode + +A `singleton` exposing the stable, machine-readable error codes carried by [ProcessError](ProcessError.md) `.code`, plus a `meta()` lookup mapping each code to its default `severity` and `retryable` flag. Compare against these constants instead of parsing message strings. + +Access the shared instance via `.me`: + +```4d +var $codes:=cs.EmbeddingStudio.ProcessErrorCode.me +If ($error.code=$codes.SAVE_FAILED) + // … +End if +``` + +## Codes + +| 定数 | 値 | Default severity | Retryable | Raised when… | +| ----------------------- | --- | ---------------- | --------- | ------------------------------------------------------------------------------------------------- | +| `NULL_INPUT` | 100 | error | × | A required entity, selection, or definition was `Null`. | +| `INVALID_DEFINITION` | 101 | error | × | A value is not a usable [Definition](Definition.md) instance. | +| `VALIDATION_FAILED` | 102 | error | × | `Definition.validate()` reported a problem. | +| `MODEL_UNAVAILABLE` | 200 | fatal | ◯ | A critical API error made the model unusable for the rest of the run. | +| `MODEL_SKIPPED` | 201 | error | ◯ | A definition was skipped because its model already failed critically. | +| `EMBED_FAILED` | 202 | error | ◯ | A non-critical embedding call failed (single entity or chunk). | +| `VECTOR_COUNT_MISMATCH` | 300 | error | × | The provider returned a different vector count than requested. | +| `SAVE_FAILED` | 400 | error | ◯ | `entity.save()` failed (validation, lock, …). | + +Codes are grouped by hundreds: `1xx` input/configuration, `2xx` model/API, `3xx` data integrity, `4xx` persistence. Unknown codes resolve to `{severity: "error"; retryable: False; label: "UNKNOWN"}`. + +## 関数 + +### meta() + +**meta**( $code : Integer ) : Object + +Returns the `severity` and `retryable` flag associated with a code — the same values carried by a [ProcessError](ProcessError.md) with that `code`. + +| 引数 | 型 | 説明 | +| ------- | ------- | ----------------------------------------------------------------------- | +| `$code` | Integer | One of the code constants above. | +| 戻り値 | Object | `{severity : Text; retryable : Boolean; label : Text}`. | + +```4d +var $m:=cs.EmbeddingStudio.ProcessErrorCode.me.meta(cs.EmbeddingStudio.ProcessErrorCode.me.MODEL_UNAVAILABLE) +// $m = {severity: "fatal"; retryable: True; label: "MODEL_UNAVAILABLE"} +``` + +## 参照 + +- [ProcessError](ProcessError.md) — carries a `.code` from this list. +- [ProcessResult](ProcessResult.md) — `errorsByCode()` filters errors by code. From 8d92a01a894136c1165c5188a72b87a865071fed Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:41:35 +0100 Subject: [PATCH 100/195] processresult.md Japanese --- .../embedding-studio/Classes/ProcessResult.md | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/ProcessResult.md diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/ProcessResult.md b/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/ProcessResult.md new file mode 100644 index 00000000000000..7c690d7eeda9f1 --- /dev/null +++ b/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/ProcessResult.md @@ -0,0 +1,91 @@ +--- +id: processresult +title: ProcessResult +--- + +# ProcessResult + +The `ProcessResult` class is the return value of every batch entry point of [Process](Process.md) (`process`, `processEntity`, `processEntitySelection`). It accumulates statistics, per-error breakdowns, and wall-clock duration. + +The orchestrator never throws out of its public batch API — failures are recorded here and the job continues. The caller decides what to do with them. + +## プロパティ + +| プロパティ名 | 型 | 説明 | +| ---------------------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `definitionsProcessed` | Integer | Number of [Definition](Definition.md) entries processed. | +| `entitiesConsidered` | Integer | Number of entities that passed the "needs recompute" filter. | +| `entitiesUpdated` | Integer | Number of entities whose vector was successfully written and saved. | +| `entitiesSkipped` | Integer | Number of entities that could not be processed: individual embed or save errors, or whole-chunk API failures (those entities are left unchanged for the next run). | +| `apiCalls` | Integer | Number of embeddings API calls made. | +| `promptTokens` | Integer | Total prompt tokens consumed across all API calls in this run. | +| `totalTokens` | Integer | Total tokens consumed across all API calls in this run. | +| `経過時間` | Integer | Total duration of the job in milliseconds. | +| `errors` | Collection | List of [ProcessError](ProcessError.md) entries recorded during the run. | + +### 計算プロパティ + +| プロパティ | 型 | 説明 | +| ---------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `success` | Boolean | `True` when no `"error"` or `"fatal"` entry was recorded. `"warning"` entries do not fail the run. | +| `hasFatal` | Boolean | `True` when at least one `"fatal"` entry was recorded (e.g. a model became unavailable). | + +### Error entries + +Each item in `errors` is a [ProcessError](ProcessError.md) with `scope`, `severity`, `code`, `ref`, `message`, and `retryable`. See [ProcessError](ProcessError.md) for the field meanings and [ProcessErrorCode](ProcessErrorCode.md) for the `code` catalogue. + +## 関数 + +### errorsByScope() + +**errorsByScope**( $scope : Text ) : Collection + +Errors filtered by `scope` (`"pipeline"`, `"definition"`, `"chunk"`, `"entity"`). + +### errorsByCode() + +**errorsByCode**( $code : Integer ) : Collection + +Errors filtered by machine-readable code — see [ProcessErrorCode](ProcessErrorCode.md). + +### retryableErrors() + +**retryableErrors**() : Collection + +Errors flagged `retryable` — re-running the operation could plausibly succeed. + +### toObject() + +**toObject**() : Object + +Returns a plain object suitable for logging or JSON serialization. + +| 引数 | 型 | 説明 | +| --- | ------ | ------------------------------------------------------- | +| 戻り値 | Object | A JSON-friendly snapshot of the report. | + +```4d +var $r:=$p.process() +LOG EVENT(Into 4D log file; JSON Stringify($r.toObject())) +``` + +## 例題 + +```4d +var $r:=$p.processEntitySelection(ds.Students.all(); $def) + +If ($r.success) + ALERT("Updated "+String($r.entitiesUpdated)+" students in "+String($r.duration)+" ms") +Else + var $err : Object + For each ($err; $r.errors) + ALERT("[" + $err.scope + "] " + String($err.ref) + " — " + $err.message) + End for each +End if +``` + +## 参照 + +- [Process](Process.md) +- [ProcessError](ProcessError.md) — the typed shape of each `errors` entry. +- [ProcessErrorCode](ProcessErrorCode.md) — the `code` catalogue. From 53cb6deb8b1eb34ddb01980671d6b48952f4a6b1 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:41:38 +0100 Subject: [PATCH 101/195] scheduler.md Japanese --- .../embedding-studio/Classes/Scheduler.md | 369 ++++++++++++++++++ 1 file changed, 369 insertions(+) create mode 100644 i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Scheduler.md diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Scheduler.md b/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Scheduler.md new file mode 100644 index 00000000000000..975db1e02ec8e0 --- /dev/null +++ b/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Scheduler.md @@ -0,0 +1,369 @@ +--- +id: スケジューラー +title: スケジューラー +--- + +# スケジューラー + +The `Scheduler` class is the public entry point for the **automated embedding recalculation** service. It maintains a background task that runs the embedding pipeline (see [Process](Process.md)) at a configured interval or a fixed daily time, guarantees that **at most one** recalculation batch runs at a time, and exposes runtime status for administration and monitoring interfaces. + +It is a **singleton**, accessed through `cs.EmbeddingStudio.Scheduler.me`. + +The scheduler runs two named workers: + +| Worker | ロール | +| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `EmbeddingStudioScheduler` | Background loop that re-reads the config each cycle, computes the next run and fires when due. | +| `EmbeddingStudio` | Execution worker that runs one recalculation batch (shared with the Studio UI, so scheduled and manual runs are serialized). | + +## 設定 + +The configuration lives under the `scheduler` key of `Settings/embeddings.json`: + +```json +{ + "scheduler": { + "mode": "interval", + "intervalHours": 3, + "startFrom": "reference", + "startReference": "2026-09-02T14:00:00", + "dailyTime": "00:00" + } +} +``` + +| キー | 型 | Values / range | 説明 | +| ---------------- | ------- | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `mode` | Text | `"never"` \| `"interval"` \| `"daily"` | Scheduling mode. Absent/unknown ⇒ `never` (no automatic run). | +| `intervalHours` | Integer | `1`..`24` | Interval mode only. Out-of-range ⇒ default `3`. | +| `startFrom` | Text | `"reference"` \| `"lastExecution"` | Interval mode only. Anchor of the interval (see below). Anything other than `"lastExecution"` — including the legacy `"now"` — is normalized to `reference`. Default `reference`. | +| `startReference` | Text | `"YYYY-MM-DDThh:mm:ss"` | Interval mode with `startFrom = "reference"`. Fixed instant the interval counts from. Absent ⇒ the moment the scheduler was armed, then the current instant. | +| `dailyTime` | Text | `"HH:MM"` | Daily mode only. Time of day for the recalculation. Default `"00:00"`. | + +**Interval anchoring (`startFrom`)** + +- `reference` — **fixed rate**: the interval is anchored on the fixed `startReference` instant, so the slots do not drift whatever a run's duration is. Slots are advanced by `intervalHours` until the first one strictly after now. When `startReference` is absent (a fresh or legacy config), the anchor falls back to the moment the scheduler was armed (`start()`), then to the current instant. +- `lastExecution` — **fixed delay**: the interval is anchored on the last completed recalculation. If the elapsed time since the last run already exceeds the interval (e.g. after a restart), the run is triggered immediately. If there is no prior run, it runs immediately. + +The effective configuration is read from the file on **every loop cycle**, so changes take effect without restarting the scheduler. + +## Starting the scheduler + +Configuring a `mode` is **not enough**: nothing runs until the scheduler is started. There are two ways to get there, and which one applies depends on a single option of your host database. + +### 1. Automatic — let the host database start it + +In the host database, open **Settings > Security** and check **"Execute 'On Host Database Event' method of the components"** (it is *unchecked* by default, for security reasons). + +With this option on, 4D Embedding Studio starts the scheduler by itself when the host database opens, and stops it when the host database closes. There is nothing else to write. + +Use [`autoStart()`](#autostart) to check whether the option is on: + +```4d +If (Not(cs.EmbeddingStudio.Scheduler.me.autoStart())) + // the option is off — I must start the scheduler myself + cs.EmbeddingStudio.Scheduler.me.start() +End if +``` + +### 2. Manual — start it from your own code + +If you prefer to leave the option off, the scheduler never starts on its own. Call [`start()`](#start) from wherever it suits you — typically the host `On Startup` or `On Server Startup` database method — and [`stop()`](#stop) when the database closes (`On Exit` / `On Server Shutdown`): + +```4d +// Host "On Server Startup" +cs.EmbeddingStudio.Scheduler.me.start() + +// Host "On Server Shutdown" +cs.EmbeddingStudio.Scheduler.me.stop() +``` + +> In client/server, arm the scheduler from `On Server Startup`, not from `On Startup`: +> `On Startup` runs on every remote client, and the scheduler state is per machine — each +> client would arm its own loop and run its own batches. If you do call [`start()`](#start) +> from `On Startup` (single-user setups), guard it with +> `If (Application type#4D Remote mode)`. + +`start()` is idempotent, so calling it from several places is harmless. + +### Checking that it really runs + +[`isStarted()`](#isstarted) tells you whether the background loop is alive right now — the answer to "is my schedule actually being watched?": + +```4d +var $s:=cs.EmbeddingStudio.Scheduler.me.status() +If ($s.enabled && Not($s.started)) + ALERT("A schedule is configured but the scheduler is not started.") +End if +``` + +## 関数 + +### start() + +**start**() : Boolean + +Arms the scheduler and starts the background loop worker if it is not already running. Idempotent — calling it again while already armed simply refreshes the "start from now" anchor. + +| 戻り値 | 型 | 説明 | +| --- | ------- | ------------------------------ | +| 戻り値 | Boolean | Always `True`. | + +```4d +cs.EmbeddingStudio.Scheduler.me.start() +``` + +### stop() + +**stop**() + +Disarms the scheduler and stops the background loop worker. A recalculation batch already in progress is **not** interrupted — it finishes normally (use [`cancel()`](#cancel) to request an early stop). + +```4d +cs.EmbeddingStudio.Scheduler.me.stop() +``` + +### キャンセル() + +**cancel**() + +Requests a **cooperative** cancel of the batch currently running. The running batch is never force-killed; it stops gracefully between two chunks. Has no effect if no batch is running. + +```4d +cs.EmbeddingStudio.Scheduler.me.cancel() +``` + +### force() + +**force**() : Object + +Forces a recalculation **now**, regardless of the schedule. It honors the single-batch rule: if a batch is already running, the forced trigger is skipped (and logged). Non-blocking — the run happens on the execution worker. + +| 戻り値 | 型 | 説明 | +| --- | ------ | ----------------------------------------------------- | +| 戻り値 | Object | The current [status](#status) object. | + +```4d +var $status:=cs.EmbeddingStudio.Scheduler.me.force() +``` + +### status() + +**status**() : Object + +Returns the current scheduler status, without any input parameter — suitable for administration and monitoring displays. + +| 戻り値 | 型 | 説明 | +| --- | ------ | ---------------------------------------------------- | +| 戻り値 | Object | See [Status object](#status-object). | + +```4d +var $s:=cs.EmbeddingStudio.Scheduler.me.status() +If ($s.running) + ALERT("A recalculation is running since "+$s.batchStart) +End if +``` + +#### ステータスオブジェクト + +| キー | 型 | 説明 | +| ---------------------- | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `enabled` | Boolean | `False` when `mode = "never"`. | +| `mode` | Text | Effective mode (`never` \| `interval` \| `daily`). | +| `armed` | Boolean | `True` when the background loop is armed (after `start()`, until `stop()`). | +| `running` | Boolean | `True` while a recalculation batch is in progress. | +| `batchStart` | Text \| Null | ISO timestamp of the running batch start (`Null` when idle). | +| `lastExecution` | Text \| Null | ISO timestamp of the last completed run (`Null` if none yet). Restored from the persisted history after a restart, so it survives the loss of in-memory state. | +| `lastRunBeforeRestart` | Boolean | `True` when `lastExecution` was recovered from the history after a restart rather than produced by a run in the current session. | +| `nextRun` | Text \| Null | ISO timestamp of the next scheduled run (`Null` in `never` mode). | +| `lastResult` | Text \| Null | Result of the last trigger: `started` \| `skipped` \| `completed` \| `failed`. | +| `エラー発生` | Text \| Null | Error summary when the last run failed (safe for admin display), else `Null`. | +| `started` | Boolean | `True` when the background loop is really alive (see [`isStarted()`](#isstarted)). | +| `autoStart` | Boolean | `True` when the host database starts the scheduler by itself (see [`autoStart()`](#autostart)). | + +### isStarted() + +**isStarted**() : Boolean + +Tells whether the scheduler is **effectively running**, i.e. whether its background loop is alive at this very moment. Unlike the `armed` flag of the [status](#status-object), it reflects reality: if the loop was never started, or was killed, the result is `False`. + +| 戻り値 | 型 | 説明 | +| --- | ------- | --------------------------------------------------------- | +| 戻り値 | Boolean | `True` when the background loop is alive. | + +```4d +If (Not(cs.EmbeddingStudio.Scheduler.me.isStarted())) + cs.EmbeddingStudio.Scheduler.me.start() +End if +``` + +### autoStart() + +**autoStart**() : Boolean + +Tells whether the host database authorizes 4D Embedding Studio to start itself, i.e. whether the **"Execute 'On Host Database Event' method of the components"** option is checked in the host **Settings > Security** (see [Starting the scheduler](#starting-the-scheduler)). + +- `True` — the scheduler starts with the host database and stops with it. You have nothing to call. +- `False` — nothing starts automatically: your code must call [`start()`](#start) and [`stop()`](#stop). + +The answer is read from the host structure settings. When they cannot be read, the result is `False` — the safe answer, since starting an already-started scheduler is harmless. + +| 戻り値 | 型 | 説明 | +| --- | ------- | -------------------------------------------------------------------- | +| 戻り値 | Boolean | `True` when the host starts the scheduler by itself. | + +```4d +var $auto:=cs.EmbeddingStudio.Scheduler.me.autoStart() +``` + +### config() + +**config**() : Object + +Returns the effective scheduler configuration with defaults applied (as resolved from `embeddings.json`). + +| 戻り値 | 型 | 説明 | +| --- | ------ | --------------------------------------------------------------------------------------------------------------------------------------- | +| 戻り値 | Object | `{mode; intervalHours; startFrom; startReference; dailyTime}` (see [Configuration](#configuration)). | + +```4d +var $cfg:=cs.EmbeddingStudio.Scheduler.me.config() +``` + +### saveConfig() + +**saveConfig**( *cfg* : Object ) : Object + +Validates, normalizes and **persists** a scheduler configuration to the `scheduler` key of `embeddings.json`, then returns the normalized value. This is the programmatic equivalent of the scheduler settings window: it lets you change the schedule entirely by code, without the GUI. Only the `scheduler` key is written — other keys of the settings file are preserved. + +The configuration is written **on the server**: in a 4D Server / 4D remote setup the file is always edited on the server machine, so a remote client can safely call this method. Because the loop re-reads the configuration on every cycle, the new schedule takes effect without restarting the scheduler. + +| 引数 | 型 | 説明 | +| --- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| cfg | Object | Raw configuration `{mode; intervalHours; startFrom; startReference; dailyTime}` (see [Configuration](#configuration)). Missing/out-of-range values are defaulted. | + +| 戻り値 | 型 | 説明 | +| --- | ------ | ---------------------------------------------------------------- | +| 戻り値 | Object | The normalized configuration that was persisted. | + +```4d +// Switch to a 6-hour interval counting from the last execution +cs.EmbeddingStudio.Scheduler.me.saveConfig({mode: "interval"; intervalHours: 6; startFrom: "lastExecution"}) + +// Switch to a daily run at 02:30 +cs.EmbeddingStudio.Scheduler.me.saveConfig({mode: "daily"; dailyTime: "02:30"}) + +// Disable the automatic schedule +cs.EmbeddingStudio.Scheduler.me.saveConfig({mode: "never"}) +``` + +### nextRun() + +**nextRun**() : Object + +Computes the next scheduled run from the current configuration and state. + +| 戻り値 | 型 | 説明 | +| --- | -------------- | --------------------------------------------------------------------------------------------------------------- | +| 戻り値 | Object \| Null | `{date : Date; time : Time; timestamp : Text; immediate : Boolean}`, or `Null` in `never` mode. | + +```4d +var $next:=cs.EmbeddingStudio.Scheduler.me.nextRun() +``` + +### reload() + +**reload**() : Object + +No-op convenience: the configuration is re-read automatically on each loop cycle, so this simply returns the current [status](#status). Provided for callers that want an explicit "config changed, give me the up-to-date status" call. + +| 戻り値 | 型 | 説明 | +| --- | ------ | ----------------------------------------------------- | +| 戻り値 | Object | The current [status](#status) object. | + +## Concurrency & logging + +- **Single batch** — at any time, at most one recalculation batch runs. A trigger (scheduled or forced) fired while a batch is running is **skipped**, not queued. +- **Skip traceability** — skipped triggers are logged with their timestamp in the execution history (`Logs/embeddingHistory.json`). +- **Cooperative cancel** — `cancel()` stops a running batch gracefully between chunks; it is never force-killed. +- **History** — each run records start/end timestamps, status, token usage and the computed next run date in `Logs/embeddingHistory.json` (see [ProcessResult](ProcessResult.md) for per-run details). + +### Execution history file + +`Logs/embeddingHistory.json` is written by the pipeline itself (every full `process()` run, scheduled or manual), guarded by a semaphore so concurrent processes never interleave writes. It holds the **current** run at the top level, the one before it under `previous`, and the same pair per definition under `definitions`. + +```json +{ + "startTime": "2026-09-01T14:03:00", + "endTime": "2026-09-01T14:03:00", + "status": "completed", + "trigger": "completed", + "error": null, + "nextComputeDate": "2026-09-02T14:03:00", + "promptTokens": 0, + "totalTokens": 0, + "cumulativePromptTokens": 37802, + "cumulativeTotalTokens": 37802, + "previous": { "startTime": "…", "endTime": "…", "status": "completed", "error": null, + "nextComputeDate": "…", "promptTokens": 12764, "totalTokens": 12764, + "cumulativePromptTokens": 37802, "cumulativeTotalTokens": 37802 }, + "skipped": ["2026-09-01T12:00:00"], + "definitions": { + "Students.student_vector_1": { + "startTime": "…", "endTime": "…", "status": "completed", "error": null, + "promptTokens": 1054, "totalTokens": 1054, + "cumulativePromptTokens": 4210, "cumulativeTotalTokens": 4210, + "previous": { "…": "…" } + } + } +} +``` + +| キー | 型 | 説明 | +| -------------------------------------------------- | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `startTime` / `endTime` | Text \| Null | ISO timestamps of the run, in the scheduler's local base. `endTime` is `null` while a run is in progress. | +| `status` | Text | `running` \| `completed` \| `failed`. | +| `trigger` | Text | Last event that touched the file: `started` \| `skipped` \| `completed` \| `failed`. | +| `エラー発生` | Text \| Null | Summary of the run's errors, or `null`. Never contains an API key. | +| `nextComputeDate` | Text \| Null | Next scheduled run computed at the end of the run (the `nextComputeDate` option of [Process](Process.md)). | +| `promptTokens` / `totalTokens` | Integer | Usage for this run alone. | +| `cumulativePromptTokens` / `cumulativeTotalTokens` | Integer | Running totals across all recorded runs. | +| `previous` | Object | Snapshot of the preceding run — the same keys, without `trigger`, `skipped` and `definitions`. Only one generation is kept. | +| `skipped` | Collection | ISO timestamps of triggers skipped because a batch was already running. Capped at the **last 50**. | +| `definitions` | Object | One entry per definition, keyed `"."`, each with its own `startTime`, `endTime`, `status` (`completed` \| `failed` \| `skipped`), `error`, token counters and `previous`. | + +[`status()`](#status) reads `startTime`, `endTime`, `status`, `trigger`, `error` and `nextComputeDate` back from this file, which is how `lastExecution` survives a server restart. + +## Lifecycle + +| Host setting | What happens | What you must do | +| ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | +| **"Execute 'On Host Database Event' method of the components"** checked | The scheduler starts when the host database opens and stops when it closes. | Nothing. | +| Option unchecked (default) | The scheduler never starts by itself. | Call [`start()`](#start) at startup and [`stop()`](#stop) at shutdown. | + +Ask [`autoStart()`](#autostart) which case you are in, and [`isStarted()`](#isstarted) whether the loop is currently alive. Stopping the scheduler never interrupts a batch in progress — it finishes normally. + +## 例題 + +```4d +// --- Start at server startup, unless the host does it for us --- +If (Not(cs.EmbeddingStudio.Scheduler.me.autoStart())) + cs.EmbeddingStudio.Scheduler.me.start() +End if + +// --- Admin panel: force a recalculation and read status --- +var $status:=cs.EmbeddingStudio.Scheduler.me.force() + +// --- Monitoring: display last / next run and current state --- +$status:=cs.EmbeddingStudio.Scheduler.me.status() +var $info:="Mode: "+$status.mode\ + +" — Last: "+String($status.lastExecution)\ + +" — Next: "+String($status.nextRun)\ + +" — "+($status.running ? "running" : String($status.lastResult)) + +// --- Cancel a long-running batch --- +cs.EmbeddingStudio.Scheduler.me.cancel() + +// --- Disable automatic runs --- +cs.EmbeddingStudio.Scheduler.me.stop() +``` From 81ad4fd57eedb2ac98376477437fe57498d6771e Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:41:41 +0100 Subject: [PATCH 102/195] settings.md Japanese --- .../embedding-studio/Classes/Settings.md | 184 ++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Settings.md diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Settings.md b/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Settings.md new file mode 100644 index 00000000000000..cb8643648e3d68 --- /dev/null +++ b/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/Settings.md @@ -0,0 +1,184 @@ +--- +id: settings +title: 設定 +--- + +# 設定 + +The `Settings` class is the persisted configuration for the embedding pipeline. It loads and saves a JSON file (default: `Settings/embeddings.json`, overridable with the `EMBEDDINGS_SETTINGS_PATH` environment variable) containing a list of [Definition](Definition.md) entries, a batch size, and phrase-validation options. + +## プロパティ + +| プロパティ名 | 型 | 説明 | +| ------------- | -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `definitions` | Collection of [Definition](Definition.md) | The configured definitions. | +| `batchSize` | Integer | Chunk size used by [Process.processEntitySelection](Process.md#processentityselection). Default: `50`. | +| `phrase` | Object | Phrase-validation options (see below). | +| `embedder` | Object | Optional embedder configuration (see below). | +| `file` | 4D.File *(read-only)* | The backing file the settings are loaded from and saved to. | + +### phrase options + +Passed verbatim to [Phrase.validate()](Phrase.md#validate) whenever the pipeline validates a definition. + +| フィールド | 型 | デフォルト | 説明 | +| ----------------- | ------- | ------- | ----------------------------------------------------------------------------------------------- | +| `allowRelations` | Boolean | `false` | Allow dot-notation through N:1 / 1:1 relations. | +| `allowCalculated` | Boolean | `false` | Allow calculated attributes in phrases. | +| `allowAlias` | Boolean | `false` | Allow alias attributes in phrases. | +| `allowObject` | Boolean | `false` | Allow object attributes in phrases. | + +> **Invalidation caveat.** Dirty-flag tracking only covers direct scalar fields on the entity. Fields that are only reachable through one of these options — a related entity's attribute, a calculated value, an alias, or a sub-property of an object — will **not** automatically mark the entity as dirty when they change. If such fields are part of a phrase and their source data changes, the vector will not be recomputed unless you call `invalidateVectors()` explicitly or use `force: true` when processing. + +### embedder options + +Controls how [Process](Process.md) builds its embedder. When absent, a default `Embedder` is created with its own defaults. + +| フィールド | 型 | デフォルト | 説明 | +| ------------ | ------- | ----- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `className` | Text | — | Name of a project class to instantiate instead of the built-in `Embedder`. The class must expose `embed` and `embedBatch` functions. If instantiation fails or the interface is missing, a diagnostic error is logged and the default `Embedder` is used as fallback. | +| `maxRetries` | Integer | `3` | Number of retry attempts on rate-limit errors (forwarded to `Embedder`). | +| `backoffMs` | Integer | `500` | Base back-off delay in ms, doubled each retry (forwarded to `Embedder`). | + +Any additional keys are forwarded as-is to the constructor of the target class (built-in or custom). + +## ファイル形式 + +```json +{ + "batchSize": 50, + "phrase": { + "allowRelations": false, + "allowCalculated": false, + "allowAlias": false, + "allowObject": false + }, + "embedder": { + "maxRetries": 5, + "backoffMs": 200 + }, + "definitions": [ + { + "dataclassName": "Students", + "vectorName": "student_vector_1", + "modelAlias": "text-embedding-3-small", + "phrase": "Student {firstName} {lastName}", + "autoInvalidate": true + } + ] +} +``` + +Each definition may include `autoInvalidate` (`true` by default) to control save-time automatic invalidation. + +The same file also carries the `scheduler` key (see [Scheduler](Scheduler.md#configuration)) and any other top-level key you add: `Settings` reads and rewrites only the keys listed above and leaves the rest untouched. + +With a custom embedder class: + +```json +{ + "embedder": { + "className": "MyCustomEmbedder" + }, + "definitions": [...] +} +``` + +## Class constructor + +Create a settings instance. The configuration file is loaded immediately. + +| 引数名 | 型 | 説明 | +| ------ | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| *ファイル* | 4D.File | 任意。 A file to use instead of the default location. The override applies process-wide for subsequent settings access. **Not supported in 4D Remote mode** — pass it only when running locally or on the server. | + +When *file* is omitted, the default location is used: `Settings/embeddings.json`, or the path given by the `EMBEDDINGS_SETTINGS_PATH` environment variable. + +```4d +// Default location +var $settings:=cs.EmbeddingStudio.Settings.new() + +// Custom file (server / mono only) +var $settings:=cs.EmbeddingStudio.Settings.new(File("/some/path/custom.json")) +``` + +## 関数 + +### load() + +**load**() + +Reload the backing file into memory, overwriting in-memory state. A missing file resets to defaults without raising. + +A file that **exists but cannot be parsed** also leaves the instance on defaults, but it is remembered: an error is logged and [`save()`](#save) then refuses to write, so a malformed file is never silently replaced by defaults. + +### save() + +**save**() : Boolean + +Serialize the current in-memory state to the backing file. Only the keys this class owns (`batchSize`, `phrase`, `embedder`, `definitions`) are written — every other top-level key present in the file (the `scheduler` configuration, model aliases…) is preserved as-is. A key whose value is back to its default is *removed* from the file rather than written. + +Definitions are merged with what the file holds at that instant, using the snapshot taken at load time as the common ancestor: two editors open at the same time no longer drop each other's definitions. + +| 戻り値 | 型 | 説明 | +| --- | ------- | ------------------------------------------------------------------------------------------------------------------------------ | +| 戻り値 | Boolean | `True` when written. `False` — nothing written — when the file could not be read at load time. | + +```4d +$settings.definitions.push(cs.EmbeddingStudio.Definition.new("Students"; "student_vector_1"; "text-embedding-3-small"; "{firstName}")) +$settings.batchSize:=100 +$settings.save() +``` + +### find() + +**find**(*dataclassName* : Text ; *vectorName* : Text) : [Definition](Definition.md) + +Look up the saved definition for the given dataclass/vector pair. + +| 引数 | 型 | 説明 | +| --------------- | --------------------------- | ------------------------------------------------------------------- | +| *dataclassName* | Text | データクラスの名称。 | +| *vectorName* | Text | Name of the vector field on that dataclass. | +| 戻り値 | [Definition](Definition.md) | The matching definition, or `Null` if none matches. | + +```4d +var $def:=$settings.find("Students"; "student_vector_1") +``` + +### findAll() + +**findAll**(*dataclassName* : Text) : Collection of [Definition](Definition.md) + +Return every saved definition configured for the given dataclass. + +| 引数 | 型 | 説明 | +| --------------- | ----------------------------------------- | --------------------------------------------------------------------------------------------- | +| *dataclassName* | Text | データクラスの名称。 | +| 戻り値 | Collection of [Definition](Definition.md) | All matching definitions (empty collection if none match). | + +```4d +var $defs:=$settings.findAll("Students") +// → every Students definition; used by Process.process(ds.Students) +``` + +### invalidateVectors() + +**invalidateVectors**() : Object + +Calls [`invalidateVectors()`](Definition.md#invalidatevectors) on every definition in `definitions` and merges the results into a single status object. + +| 引数 | 型 | 説明 | +| --- | ------ | ------------------------------------------------------------------------------------------------------------------------ | +| 戻り値 | Object | `{updated: Integer, skipped: Integer, errors: Collection of Text}` — accumulated across all definitions. | + +```4d +var $result:=cs.EmbeddingStudio.Settings.new().invalidateVectors() +// → { updated: 120; skipped: 0; errors: [] } +``` + +## 参照 + +- [Definition](Definition.md) +- [Process](Process.md) +- [Phrase](Phrase.md) From 8155574f03c01a3c80148aecff1c047d70b82dee Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:41:43 +0100 Subject: [PATCH 103/195] studioembedder.md Japanese --- .../Classes/StudioEmbedder.md | 125 ++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/StudioEmbedder.md diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/StudioEmbedder.md b/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/StudioEmbedder.md new file mode 100644 index 00000000000000..02cd8721b57487 --- /dev/null +++ b/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/Classes/StudioEmbedder.md @@ -0,0 +1,125 @@ +--- +id: studioembedder +title: StudioEmbedder +--- + +# StudioEmbedder + +The `StudioEmbedder` class renders and embeds on demand, resolved against the Studio settings: a saved definition gives the phrase and the model, so the vector you compute matches the ones stored by [Process](Process.md). Nothing is persisted. Typical uses: building the vector of a search query, finding entities similar to a given one, or previewing the text sent for an entity. + +For the full batch pipeline that persists vectors on entities, see [Process](Process.md). + +## プロパティ + +| プロパティ名 | 型 | 説明 | +| ---------- | ----------------------- | ------------------------------------------------------------------------------------------------- | +| `設定` | [Settings](Settings.md) | The settings (vectors, batch size, phrase validation options). | +| `embedder` | [Embedder](Embedder.md) | The API-calling engine. Stateless and swappable. | +| `options` | Object | Runtime options object. | + +## Class constructor + +| 引数名 | 型 | 説明 | +| --------- | ----------------------- | ------------------------------------------------------------------------------------------------ | +| *設定* | [Settings](Settings.md) | 任意。 If omitted, settings are loaded from the default `Settings/embeddings.json`. | +| *options* | Object | Optional runtime options. Supports `embedder` for injection. | + +```4d +var $studioEmbedder:=cs.EmbeddingStudio.StudioEmbedder.new() +var $studioEmbedder:=cs.EmbeddingStudio.StudioEmbedder.new($settings) +var $studioEmbedder:=cs.EmbeddingStudio.StudioEmbedder.new($settings; {embedder: $mockEmbedder}) +``` + +## 関数 + +### render() + +**render**(*entity* : 4D.Entity ; *definitionOrPhrase* : Variant) : Text + +Return the text that [`embed()`](#embed) sends for an entity (the phrase rendered against it). No API call, no persistence. + +| 引数 | 型 | 説明 | +| -------------------- | ------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| *entity* | 4D.Entity | The entity to render against. | +| *definitionOrPhrase* | `Null`, [Phrase](Phrase.md), [Definition](Definition.md), Text, or plain object stub | `Null` → auto-resolve via settings (requires a unique match). Text → compiled as a throwaway `cs.EmbeddingStudio.Phrase`. Object stub → see [stub resolution](#stub-resolution). | +| 戻り値 | Text | The rendered text. | + +```4d +var $studioEmbedder:=cs.EmbeddingStudio.StudioEmbedder.new() +var $text: Text +$text:=$studioEmbedder.render($student; $def) // use def's phrase +$text:=$studioEmbedder.render($student; cs.EmbeddingStudio.Phrase.new("Hi {firstName}")) +$text:=$studioEmbedder.render($student; "Student: {lastName}") // raw template +$text:=$studioEmbedder.render($student) // auto-resolve +$text:=$studioEmbedder.render($student; {vectorName: "student_vector_1"}) // stub → saved definition's phrase +$text:=$studioEmbedder.render($student; {phrase: "Hi {firstName}"}) // ad-hoc stub → inline template +``` + +### embed() + +**embed**(*input* : Variant ; *context* : Variant ; *model* : Text) : [cs.EmbeddingStudio.EmbedderResult](EmbedderResult.md) + +Compute a vector for an arbitrary input, without persisting anywhere. + +| 引数 | 型 | 説明 | +| --------- | --------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| *input* | Text or 4D.Entity | Text → embedded directly. Entity → phrase rendered then embedded. | +| *context* | Text, [Phrase](Phrase.md), [Definition](Definition.md), Text template, plain object stub, or `Null` | Provides phrase and/or model depending on *input*. Object stub → see [stub resolution](#stub-resolution). | +| *model* | Text | Optional explicit model name. Used when *context* does not carry one. | +| 戻り値 | [EmbedderResult](EmbedderResult.md) | The embedding result (use `.vector` to get the 4D.Vector). | + +Throws if no model can be determined. + +```4d +var $studioEmbedder:=cs.EmbeddingStudio.StudioEmbedder.new() +var $vector: 4D.Vector + +// Text + model +$vector:=$studioEmbedder.embed("some text"; "text-embedding-3-small").vector + +// Text + definition (picks up def.modelAlias) +$vector:=$studioEmbedder.embed("some text"; $def).vector + +// Entity + definition (uses def.phrase + def.modelAlias) +$vector:=$studioEmbedder.embed($student; $def).vector + +// Entity + phrase + explicit model +$vector:=$studioEmbedder.embed($student; $phrase; "text-embedding-3-small").vector + +// Entity + ad-hoc template + model +$vector:=$studioEmbedder.embed($student; "Profile: {firstName} {lastName}"; "text-embedding-3-small").vector + +// Entity alone (auto-resolve, only when exactly one def matches the dataclass) +$vector:=$studioEmbedder.embed($student).vector + +// Entity + stub (deduces phrase + model from the matching saved definition) +$vector:=$studioEmbedder.embed($student; {vectorName: "student_vector_1"}).vector + +// Entity + ad-hoc stub (phrase compiled inline, model taken from the stub) +$vector:=$studioEmbedder.embed($student; {phrase: "Hi {firstName}"; modelAlias: "text-embedding-3-small"}).vector + +// Text + stub that only supplies the model +$vector:=$studioEmbedder.embed("some text"; {modelAlias: "text-embedding-3-small"}).vector +``` + +## Stub resolution + +Both `render()` and `embed()` accept a plain object in place of a `Phrase`/`Definition`. A stub is resolved the same way [`Process`](Process.md#definition-resolution-entity-context) resolves its `definition` argument, so the behavior matches. Two flavors are supported: + +| Stub | Resolves to | +| ------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `{vectorName: "..."}` (optionally `{dataclassName: "..."}`) | The matching **saved definition** for the entity's dataclass — deducing its phrase (and, for `embed`, its model). Resolves to nothing when there is no unique match. | +| `{phrase: "tpl {field}"}` or `{template: "tpl {field}"}` | An **ad-hoc** `Phrase` compiled inline; nothing is looked up. Pair with `{modelAlias: "..."}` to give `embed()` a model. | + +For `embed()`, the model is deduced in this order: an explicit `{modelAlias}` on the stub → the model of a stub-matched saved definition → the *model* argument → the entity's unique definition. An explicit `{modelAlias}` always wins. + +Unlike [`Process.process()`](Process.md#process-resolution), a stub is **not** turned into a brand-new `Definition` from its fields — `StudioEmbedder` persists nothing, so use `{phrase}`/`{template}` for one-off templates. + +## 参照 + +- [Process](Process.md) +- [Settings](Settings.md) +- [Definition](Definition.md) +- [Embedder](Embedder.md) +- [EmbedderResult](EmbedderResult.md) +- [Phrase](Phrase.md) From adde6d5c8ca75668c4f1dfcb9ca1aed9507f2e69 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:41:46 +0100 Subject: [PATCH 104/195] license.md Japanese --- .../current/embedding-studio/license.md | 167 ++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/license.md diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/license.md b/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/license.md new file mode 100644 index 00000000000000..8f6fc0dd2b5ffc --- /dev/null +++ b/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/license.md @@ -0,0 +1,167 @@ +--- +id: license +title: SOFTWARE LICENSE AGREEMENT +--- + +# SOFTWARE LICENSE AGREEMENT + +## Preamble + +The purpose of this Software license agreement is to grant users the right to modify and re-use the software governed by this license. + +The exercising of this right is conditional upon the obligation to make /available to the community the modifications made to the source code of the software so as to contribute to its evolution. + +In consideration of access to the source code and the rights to copy, modify and redistribute granted by the license, users are provided only with a limited warranty and the software's author, the holder of the economic rights, and the successive licensors only have limited liability. + +## Article 1 – DEFINITIONS + +***Agreement***: means this license agreement, and its possible subsequent versions and annexes. + +***Software***: means the software in its Object Code and/or Source Code form and, where applicable, its documentation, "as is" when the Licensee accepts the Agreement. + +***Initial Software***: means the Software in its Source Code and possibly its Object Code form and, where applicable, its documentation, "as is" when it is first distributed under the terms and conditions of the Agreement. + +***Modified Software***: means the Software modified by at least one Integrated Contribution. + +***Source Code***: means all the Software's instructions and program lines to which access is required so as to modify the Software. + +***Object Code***: means the binary files originating from the compilation of the Source Code. + +***Holder***: means the holder(s) of the economic rights over the Initial Software, in this case it is 4D SAS. + +***Licensee***: means the Software user(s) having accepted the Agreement. + +***Contributor***: means a Licensee having made at least one Integrated Contribution. + +***Licensor***: means the Holder, or any other individual or legal entity, who distributes the Software under the Agreement. + +***Integrated Contribution***: means new functions integrated into the Source Code by any or all Contributors. + +***Parties***: mean both the Licensee and the Licensor. + +These expressions may be used both in singular and plural form. + +## Article 2 - PURPOSE + +The purpose of the Agreement is the grant by the Licensor to the Licensee of a non-exclusive, transferable and worldwide license for the Software as set forth in Article 5 hereinafter for the whole term of the protection granted by the rights over said Software. + +## Article 3 - ACCEPTANCE + +The Licensee shall be deemed as having accepted the terms and conditions of this Agreement upon the occurrence of the first of the following events: + +- loading the Software by any or all means, notably, by downloading from a remote server; +- the first time the Licensee exercises any of the rights granted hereunder. + +## Article 4 - EFFECTIVE DATE AND TERM + +### 4.1 EFFECTIVE DATE + +The Agreement shall become effective on the date when it is accepted by the Licensee as set forth in Article 3. + +### 4.2 TERM + +The Agreement shall remain in force for the entire legal term of protection of the economic rights over the Software. + +## Article 5 - SCOPE OF RIGHTS GRANTED + +The Licensor hereby grants to the Licensee, who accepts, the following rights over the Software for the term of the Agreement, on the basis of the terms and conditions set forth hereinafter. + +### 5.1 RIGHT OF USE + +The Licensee is authorized to use the Software, without any limitation as to its fields of application, with it being hereinafter specified that this comprises: + +- permanent or temporary reproduction of all or part of the Software by any or all means and in any or all form. +- loading, displaying, running, or storing the Software on any or all medium. +- entitlement to observe, study or test its operation. + +### 5.2 RIGHT OF MODIFICATION + +The right of modification means the right to adapt, arrange, or make any or all modifications to the Software; being understood that such modifications of the Software shall results in a change of its functionalities and/or in an addition of functionalities to the Initial Software. + +Consequently to distribute a Modified Software according to the provision of section 5.3.2, the Licensee shall make exclusively significant modification as described above to the Software provided that it includes an explicit notice that it is the author of said modification and indicates the date of the creation thereof. + +### 5.3 RIGHT OF DISTRIBUTION + +In particular, the right of distribution includes the right to publish, transmit and communicate the Modified Software to the general public on any or all medium, and by any or all means, and the right to market, either in consideration of a fee, or + +#### 5.3.1 DISTRIBUTION OF SOFTWARE WITHOUT MODIFICATION + +The Licensee is forbidden to distribute true copies of the Software in Source Code or Object Code form. + +#### 5.3.2 DISTRIBUTION OF MODIFIED SOFTWARE + +When the Licensee creates Modified Software, this Modified Software may be distributed provided that said distribution complies with all the provisions of the Agreement and subject to compliance with the requirement to include a notice concerning the rights over the Software as defined in Article 6.3. + +In the event the creation of the Modified Software, the Licensee undertakes that: + +- the resulting Modified Software will be governed by this Agreement, being understood that such Agreement shall be integrated in the Modified Software the Integrated Contributions in the resulting Modified Software will be clearly identified and documented, +- the Licensee will allow effective access to the source code of the Modified Software, at a minimum during the entire period of distribution of the Derivative Software, such that such modifications may be carried over in a subsequent version of the Software. +- the Modified Software must be renamed to exclude any reference to 4D. For example, it is expressly prohibited to distribute a Modified Software named “4D SVG”; Licensee shall rename the Modified Software such as “Name of the Licensee SVG”. Consequently, Licensee is expressly forbidden to use 4D’s product name in general to promote his modified work. + +## Article 6 - INTELLECTUAL PROPERTY + +### 6.1 OVER THE INITIAL SOFTWARE + +The Holder owns the intellectual property rights over the Initial Software. Any or all use of the Initial Software is subject to compliance with the terms and conditions under which the Holder has elected to distribute its work and no one shall be entitled to modify the terms and conditions for the distribution of said Initial Software. + +### 6.2 OVER THE INTEGRATED CONTRIBUTIONS + +The Licensee who develops an Integrated Contribution is the owner of the intellectual property rights over this Contribution as defined by applicable law. + +### 6.3 NOTICE OF RIGHTS + +The Licensee expressly undertakes: + +- not to remove, or modify, in any manner, the intellectual property notices attached to the Software; +- to reproduce said notices, in an identical manner, in the copies of the Software modified; +- to ensure that use of the Software, its intellectual property notices and the fact that it is governed by the Agreement is indicated in a text that is easily accessible, specifically from the interface of any Modified Software. + +The Licensee undertakes not to directly or indirectly infringe the intellectual property rights of the Holder on the Software and to take, where applicable, vis- à-vis its staff, any and all measures required to ensure respect of said intellectual property rights of the Holder. + +## Article 7 - RELATED SERVICES + +Under no circumstances shall the Agreement oblige the Licensor to provide technical assistance or maintenance services for the Software. + +However, the Licensor is entitled to offer this type of services. The terms and conditions of such technical assistance, and/or such maintenance, shall be set forth in a separate instrument. + +## Article 8 - DISCLAIMER OF WARRANTY. + +THERE IS NO WARRANTY FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE HOLDER PROVIDES THE SOFTWARE “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH LICENSEE. SHOULD THE SOFTWARE PROVE DEFECTIVE, LICENSEE ASSUMES THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +## Article 9 - LIMITATION OF LIABILITY + +TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE TO LICENSEE ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS AGREEMENT OR USE OF THE SOFTWARE, EVEN IF THE LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR DAMAGES. + +## Article 10 – TERMINATION + +### 10.1 + +In the event of a breach by the Licensee of its obligations hereunder, the Licensor may automatically terminate this Agreement thirty (30) days after notice has been sent to the Licensee and has remained ineffective. + +### 10.2 + +A Licensee whose Agreement is terminated shall no longer be authorized to use, modify or distribute the Software. However, any licenses that it may have granted prior to termination of the Agreement shall remain valid subject to their having been granted in compliance with the terms and conditions hereof. + +## Article 11 – MISCELLANEOUS + +### 11.1 + +Neither Party shall be liable for any or all delay, or failure to perform the Agreement, that may be attributable to an event of force majeure, an act of God or an outside cause, such as defective functioning or interruptions of the electricity or telecommunications networks, network paralysis following a virus attack, intervention by government authorities, natural disasters, water damage, earthquakes, fire, explosions, strikes and labor unrest, war, etc. + +### 11.2 + +Any failure by either Party, on one or more occasions, to invoke one or more of the provisions hereof, shall under no circumstances be interpreted as being a waiver by the interested Party of its right to invoke said provision(s) subsequently. + +### 11.3 + +In the event that one or more of the provisions hereof were to conflict with a current or future applicable act or legislative text, said act or legislative text shall prevail, and the Parties shall make the necessary amendments so as to comply with said act or legislative text. All other provisions shall remain effective. Similarly, invalidity of a provision of the Agreement, for any reason whatsoever, shall not cause the Agreement as a whole to be invalid. + +## Article 12 - GOVERNING LAW AND JURISDICTION + +### 12.1 + +The Agreement is governed by French law. The Parties agree to endeavor to seek an amicable solution to any disagreements or disputes that may arise during the performance of the Agreement. + +### 12.2 + +Failing an amicable solution within two (2) months as from their occurrence, and unless emergency proceedings are necessary, the disagreements or disputes shall be referred to the Versailles Courts having jurisdiction, by the more diligent Party. \ No newline at end of file From 325c240d76538baf85cde5cffc40cb10b86db48d Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:41:48 +0100 Subject: [PATCH 105/195] overview.md Japanese --- .../current/embedding-studio/overview.md | 211 ++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/overview.md diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/overview.md b/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/overview.md new file mode 100644 index 00000000000000..9053d57312e94a --- /dev/null +++ b/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/overview.md @@ -0,0 +1,211 @@ +--- +id: overview +title: 4D-Embedding-Studio +--- + +# 4D-Embedding-Studio + +## 概要 + +4D Embedding Studio is a component for defining, processing, and maintaining AI embedding vectors directly in your 4D dataclass entities. + +You can use the component without writing a single line of code: select attributes from your dataclasses to construct the sentences to be vectorized and specify the model to use. For each entity, the component calls the embedding API and stores the resulting `4D.Vector` values. Configure the embedding scheduler to (re)calculate the vectors for your data at fixed intervals or on demand. + +You can then use the ORDA [`query()` by vector feature](https://developer.4d.com/docs/API/DataClassClass#query-by-vector-similarity) to request your data using semantics. + +If you want to have more control over your embeddings, the component offers an extensive API that allows you to customize each step of the data vectorization process, manage the scheduler, and integrate high-performance RAG (*Retrieval Augmented Generation*) features into your 4D application. + +## 要件 + +- [4D-AIKit](https://github.com/4d/4D-AIKit) (loaded automatically as a dependency). +- 4D project (21 R5 or later) with the following configuration: + - a valid model alias + - a dataclass with a `4D.Vector` attribute (object field at the database level). + +## Quick Start + +**1. Add a field of type Object to the table and associate it with the `4D.Vector` class.** +**2. Select **Embedding Studio...** in the **Design** menu to display the Embedding Studio window.** + +![menu](../assets/en/embedding-studio/menu.png) + +**3. For each listed `4D.Vector` attribute, write a descriptive phrase based upon attributes of the dataclass.** +Use the contextual menu to insert appropriate attributes. +This phrase will be vectorized for every entity. +**4. Select a model alias (or create a new one).** +**5. Select "Execute now" to launch the vectorization of your data or configure the scheduler.** + +## User Guide + +### Configuring the dataclass + +To use the 4D Embedding Studio interface, you need to create at least one object attribute associated to a `4D.Vector` class in your datastore. This must be done at the database level (only storage attributes can be embeddings). + +In the Structure editor, add an Object field to the dataclass (table) whose entities you want to query using AI and enter ["4D.Vector" as class](https://developer.4d.com/docs/Develop/structure-fields#class). + +#### Dirty-flag support + +In a production application, data is rarely static. If an embedding is based on an attribute value that has changed (e.g. a product description), it becomes obsolete and could no longer be relevant. By default, 4D automatically invalidates and flags for recalculation affected embeddings. + +If you do not use a dirty-flag field (see below), 4D simply replaces any invalidated vector by `Null`. It is therefore no longer used in searches until its next calculation. This option is suitable for applications that prioritize strict consistency: it is better to return no results than to rely on an embedding that no longer matches the current data. + +Or, you can add a Boolean field named `_dirty` (e.g. "myVector_dirty") to the structure. In this case, when an update is required, this field is set to `True`, and the associated vector is retained until it is recalculated. Your application can then choose to continue using this vector temporarily or exclude it using a filter on `dirty = False`. The flag is cleared automatically after a successful save. +This strategy promotes service continuity while allowing you to precisely identify vectors awaiting recalculation. If your business logic requires full control, you can also disable automatic invalidation and manage this lifecycle yourself. + +*Note: Certain modifications, such as a model changes, require vectors to be replaced immediately.* + +### Creating an embedding + +When you select **Embedding Studio...** in the **Design** menu, the Embedding Studio window is displayed. + +The list on the left side shows all `4D.Vector` class attributes defined in the datastore. You can add as many vector attributes as you want per dataclass. + +A check mark (✓) in the Dirty Flag column indicates that a [`_dirty` boolean field](#dirty-flag-support) is associated to the vector field. + +**Note:** Any change in the database structure will require that you restart the 4D application so that the 4D Embedding Studio lists up-to-date values. + +#### Writing a descriptive sentence + +To create or edit an embedding, select the attribute to configure in this list and write the embedding definition in the "Descriptive sentence" area on the right side. Use the associated menu to build the sentence and to add references to dataclass available attributes with the `{attribute_name}` syntax. + +The sentence must build a text that describes the entity just like a human would do it. The embedding could then capturate the semantics and not only attribute values. + +For example, for a `Product` dataclass with many attributes such as name and category, you could write: +"The {name} product is a {category} from the {brand} brand. Description: {description}. Key features: {features}." + +![menu](../assets/en/embedding-studio/studio-interface.png) + +### Selecting a model + +Once you have defined your vector attribute, choose the model to use for generating the embedding. The list of models includes the **model aliases** you defined in the [Project Settings](https://developer.4d.com/docs/settings/ai#model-aliases). + +The choice of model is important because it determines the relevance and quality of your embeddings. You’ll also need to provide this model with every query on the dataclass data so that the comparison is performed using the same model. + +### Auto-invalidate on save + +When this option is checked (default), embeddings are automatically invalidated when at least one of their definition attributes has been modified and the entity was successfully saved. + +However, you might want to handle invalidation in a custom way using the [4D Embedding Studio API](#api-guide). In this case, uncheck this option to disable the automatic mechanism. + +### Calculating embeddings + +Embeddings are calculated by sending a request to the AI model, which then returns the vectorization result, which is subsequently stored in the `4D.Vector` attribute in the dataclass. 4D automatically handles this operation and optimizes it by calculating only the necessary vectors. Each vector is processed independently. Thus, an error on one element does not interrupt the recalculation of the others. Elements that fail will be automatically retried during the next run. Recalculations are performed asynchronously, without blocking users. + +These calculations can be performed **on demand** or **scheduled at regular intervals** using the scheduler in the 4D Embedding Studio component. + +**Note:** You can also customize embedding calculations per dataclass or entity using the [4D Embedding Studio API](#api-guide). + +#### On demand + +To launch an embedding calculation, select **Run now** in the menu at the bottom of the 4D Embedding Studio window. This item is disabled if the datastore does not contain any embedding to calculate. When started, you can select **Cancel run** at any moment. + +#### スケジューラー + +You can configure the 4D Embedding Studio component scheduler to adjust the calculation frequency to suit your application’s needs. + +**Important:** The scheduler needs a 4D worker process to run. You can start it manually for testing purposes (**Start now** button in the scheduler dialog box) but to make sure a worker is available every times the application opens, you need to configure it. これには、次の二つの方法があります: + +- select the **Execute "On Host Database Event" method of the components** option in the [project Settings](https://developer.4d.com/docs/settings/security#options) +- or write the following code in your startup code: + +```4d + //at startup +cs.EmbeddingStudio.Scheduler.me.start() +``` + +The scheduler allows you can set the time interval between two calculations. Select the tab corresponding to your needs and click **Save**. + +- **Never**: the scheduler is off and never runs +- **At regular interval**: set the time interval between each calculation starting from a specified time. +- **Once a day**: the calculation takes place every day at a specific time + starting from a specific time. + +### Building queries with embeddings + +Once you have defined embeddings in your datastore, you can start [querying your dataclasses using AI-based features](https://developer.4d.com/docs/API/DataClassClass#query-by-vector-similarity). You just need to make sure that you use the same model for your embedding definition and in the query string. + +For example, assuming that: + +• you have defined a `4D.Vector` attribute named "product_vector" in the Products dataclass using a sentence: "The {name} is in the {category} category. It has these {features} features and can be used for {usage}." +• you want to find products that "can be used safely outside". + +以下のように書くことができます: + +```4d +// Retrieve the model alias from the embedding definition, configured in 4D Embedding Studio +var $settings:=cs.EmbeddingStudio.Settings.new() +var $definition:=$settings.find("Products"; "product_vector") + +// Compute the vector of the query with the same model +var $result:=cs.EmbeddingStudio.StudioEmbedder.new().embed("products that can be used safely outside"; $definition) +var $vector:=$result.vector + + //search with default metric (cosine) +var $products:=ds.Products.query("product_vector > :1 order by product_vector desc"; {vector : $vector}) + +``` + +If you use a dirty field, simply add a criterion to exclude vectors waiting to be recalculated: + +```4d +var $products:=ds.Products.query("product_vector > :1 and product_vector_dirty = false order by product_vector desc"; {vector : $vector}) +``` + +## API Guide + +### Quick start + +**1. Configure your vectors** in `Settings/embeddings.json`: + +```json +{ + "batchSize": 50, + "definitions": [ + { + "dataclassName": "Students", + "vectorName": "student_vector_1", + "modelAlias": "text-embedding", + "phrase": "Student {firstName} {lastName}, enrolled in {program}", + "autoInvalidate": true + } + ] +} +``` + +**2. Run the full pipeline** (all definitions, all records): + +```4d +var $p:=cs.EmbeddingStudio.Process.new() +var $r:=$p.process() + +If ($r.success) + ALERT("Updated "+String($r.entitiesUpdated)+" entities in "+String($r.duration)+" ms") +End if +``` + +**3. Process a single entity on save** (e.g. in a trigger or REST hook): + +```4d +var $p:=cs.EmbeddingStudio.Process.new() +$p.processEntity($entity) +``` + +### Class reference + +| Class | 説明 | +| ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [Process](Classes/Process.md) | Main orchestrator — entry point for all batch and entity operations. | +| [Scheduler](Classes/Scheduler.md) | Automated recalculation scheduler — background task, force/cancel, and runtime status. | +| [StudioEmbedder](Classes/StudioEmbedder.md) | Renders and embeds on demand using your saved definitions — e.g. to build a search query vector. Nothing is persisted. | +| [Settings](Classes/Settings.md) | Loads and saves the `embeddings.json` configuration file. | +| [Definition](Classes/Definition.md) | Describes one vector field: dataclass, field name, model alias, and phrase template. | +| [Embedder](Classes/Embedder.md) | Thin wrapper around the AIKit embeddings API with retry/backoff logic. | +| [EmbedderResult](Classes/EmbedderResult.md) | Typed wrapper normalizing API responses — vectors, usage metrics, rate-limit state. | +| [ProcessResult](Classes/ProcessResult.md) | Returned by every batch function — statistics and error breakdown. | +| [ProcessError](Classes/ProcessError.md) | Typed entry in `ProcessResult.errors` — scope, severity, code, ref, message, retryable. | +| [ProcessErrorCode](Classes/ProcessErrorCode.md) | Singleton catalogue of machine-readable error codes and their default severity/retryability. | +| [Phrase](Classes/Phrase.md) | Lightweight `{variable}` template engine used to build text from entity attributes. | + +### 参照 + +Blog post: [Vectorize your data effortlessly with 4D Embedding Studio](https://blog.4d.com/vectorize-your-data-effortlessly-with-4d-vector-studio) \ No newline at end of file From 4c37c50c4b8c808f311cf7faa2d129c5a83c74d2 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:41:50 +0100 Subject: [PATCH 106/195] ratelimit.md Japanese --- .../current/embedding-studio/ratelimit.md | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/ratelimit.md diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/ratelimit.md b/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/ratelimit.md new file mode 100644 index 00000000000000..00f50ec3d2bb7d --- /dev/null +++ b/i18n/ja/docusaurus-plugin-content-docs/current/embedding-studio/ratelimit.md @@ -0,0 +1,65 @@ +--- +id: ratelimit +title: Rate Limiting +--- + +# Rate Limiting + +The embedding pipeline includes built-in rate-limit awareness. When the API provider returns rate-limit headers (as OpenAI does), the system automatically throttles requests and adapts batch sizes to stay within budget. Providers that don't return rate-limit headers (e.g. Ollama) are unaffected — the pipeline runs at full speed. + +## 動作 + +Each call to [`Embedder.embed()`](Classes/Embedder.md) or [`Embedder.embedBatch()`](Classes/Embedder.md) returns an [`EmbedderResult`](Classes/EmbedderResult.md) that carries rate-limit state alongside the embedding vectors. The pipeline uses this data in a three-step loop: + +1. **Pre-flight throttle** — before sending a batch, the pipeline checks whether the remaining token budget is sufficient. If not, it waits for the reset window to elapse before proceeding. +2. **Adaptive batch sizing** — the pipeline computes the largest batch that fits within 80% of the remaining token budget. This avoids hitting the ceiling while still making efficient use of the quota. +3. **State update** — after each API response, the pipeline records the new remaining budget, computes an average tokens-per-entity estimate, and feeds both into the next iteration. + +## Rate-limit fields on EmbedderResult + +These fields are populated from the API response headers. When a provider doesn't return them, they keep their defaults and the pipeline skips throttling. + +| フィールド | デフォルト | 意味 | +| ------------------- | ----- | ---------------------------------------------------------------------------------------------------------------------------------- | +| `remainingTokens` | `-1` | Tokens left in the current window. `-1` = unknown. | +| `remainingRequests` | `-1` | Requests left in the current window. | +| `limitTokens` | `0` | TPM (tokens per minute) ceiling. | +| `limitRequests` | `0` | RPM (requests per minute) ceiling. | +| `resetTokens` | `""` | Time until the token bucket refills (e.g. `"6m0s"`, `"200ms"`). | +| `resetRequests` | `""` | Time until the request bucket refills. | + +## Batch size adaptation + +The pipeline starts with the configured `batchSize` (from [Settings](Classes/Settings.md), default 50). After the first API response provides rate-limit data, the batch size may shrink: + +``` +nextBatchSize = min( floor(remainingTokens × 0.8 / tokensPerEntity), configBatchSize ) +``` + +- `tokensPerEntity` is estimated from the last chunk (`totalTokens / chunkSize`). +- The result is clamped to a floor of 1 and a ceiling of `configBatchSize`. +- When `remainingTokens` is unknown (`-1`), the configured batch size is used as-is. + +## Pre-flight wait + +Before each batch, the pipeline checks: + +- **Token budget**: if `remainingTokens < estimatedTokens × 1.1`, it waits for the token reset window. +- **Request budget**: if `remainingRequests = 0`, it waits for the request reset window. + +The reset durations are parsed from the API's string format (`"6m0s"` → 360 seconds, `"200ms"` → 1 second). + +## Providers without rate limits + +Some providers (Ollama, local models) don't return rate-limit headers. この場合において: + +- `remainingTokens` stays at `-1` (unknown) +- No throttling occurs — batches run at `configBatchSize` without waits +- The pipeline works identically to how it did before rate-limit support was added + +## 参照 + +- [EmbedderResult](Classes/EmbedderResult.md) — carries rate-limit fields +- [Embedder](Classes/Embedder.md) — wraps the API calls +- [Process](Classes/Process.md) — orchestrates the batch loop +- [Settings](Classes/Settings.md) — `batchSize` configuration From 18d388bda7ef95b581a8e377c3108227f804f6c1 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:41:52 +0100 Subject: [PATCH 107/195] menu.png Japanese --- .../assets/en/embedding-studio/menu.png | Bin 0 -> 4938 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 i18n/ja/docusaurus-plugin-content-docs/version-21-R5/assets/en/embedding-studio/menu.png diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/assets/en/embedding-studio/menu.png b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/assets/en/embedding-studio/menu.png new file mode 100644 index 0000000000000000000000000000000000000000..425fd0d7e65879e34700b856cf6f88aaa9c502e1 GIT binary patch literal 4938 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 E0Cv$VrvLx| literal 0 HcmV?d00001 From b433903d2a14e3e3304455fd1e5decd74ab40750 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:41:54 +0100 Subject: [PATCH 108/195] studio-interface.png Japanese --- .../en/embedding-studio/studio-interface.png | Bin 0 -> 34492 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 i18n/ja/docusaurus-plugin-content-docs/version-21-R5/assets/en/embedding-studio/studio-interface.png diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/assets/en/embedding-studio/studio-interface.png b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/assets/en/embedding-studio/studio-interface.png new file mode 100644 index 0000000000000000000000000000000000000000..75dae7c9303297334e2fee1b404527957dfd4746 GIT binary patch literal 34492 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 Z0#D?x@H3fRStk8kMM>jk;f?!G{uip+WAXq1 literal 0 HcmV?d00001 From cf2bf86e71eecbe581b125488e2dc3d6cae5b7a9 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:41:56 +0100 Subject: [PATCH 109/195] definition.md Japanese --- .../embedding-studio/Classes/Definition.md | 165 ++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Definition.md diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Definition.md b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Definition.md new file mode 100644 index 00000000000000..7b9bf4e7a585df --- /dev/null +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Definition.md @@ -0,0 +1,165 @@ +--- +id: 定義 +title: 定義 +--- + +# 定義 + +The `Definition` class describes how a single vector field on a dataclass should be computed: which dataclass, which vector field, which model alias, and which text template ([Phrase](Phrase.md)) to render from each entity. + +A collection of these is what [Settings](Settings.md) persists. + +## プロパティ + +| プロパティ名 | 型 | 説明 | +| ---------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------- | +| `dataclassName` | Text | Name of the target dataclass. | +| `vectorName` | Text | Name of the `4D.Vector` field on that dataclass. | +| `modelAlias` | Text | Embedding model alias (e.g. `"text-embedding-3-small"`). | +| `phrase` | [Phrase](Phrase.md) | Compiled template used to build the text that will be embedded. | +| `autoInvalidate` | Boolean | Controls automatic invalidation on entity save. Default: `True`. | + +## Class constructor + +Create a definition. + +| 引数名 | 型 | 説明 | +| ---------------- | ---- | -------------------------------------------------------------------------------------------------- | +| *dataclassName* | Text | Name of the target dataclass. | +| *vectorName* | Text | Name of the target vector field. | +| *modelAlias* | Text | Embedding model alias. | +| *phraseTemplate* | Text | Phrase template with `{field}` placeholders — compiled into a [Phrase](Phrase.md). | + +```4d +var $def:=cs.EmbeddingStudio.Definition.new(\ + "Students"; \ + "student_vector_1"; \ + "text-embedding-3-small"; \ + "Student {firstName} {lastName}") +``` + +## 計算プロパティ + +### hasDefinition + +**hasDefinition** : Boolean *(read-only)* + +Returns `True` if at least a model or a phrase template has been set. A definition without either has no content to process. + +```4d +If ($def.hasDefinition) + // worth validating further +End if +``` + +## 関数 + +### validate() + +**validate**( *settings* : Settings ) : Object + +Validates the definition against the live datastore model and the known embedding models. All errors are collected before returning — the result always describes the full set of problems found. + +| 引数 | 型 | 説明 | +| ---- | ------------------------------- | ------------------------------------------------------------------------------------------------------------ | +| *設定* | [Settings](Settings.md) \| Null | Used to pass phrase validation options. Pass `Null` to skip phrase options. | +| 戻り値 | Object | `{success: Boolean, errors: Collection}` where each error is `{field: Text, message: Text}`. | + +Checked in order: + +| Check | `field` value | +| ------------------------------------ | ----------------- | +| `dataclassName` is not empty | `"dataclassName"` | +| `vectorName` is not empty | `"vectorName"` | +| `modelAlias` is set and recognised | `"modelAlias"` | +| Dataclass exists in `ds` | `"dataclassName"` | +| Vector field exists | `"vectorName"` | +| Field type is `4D.Vector` | `"vectorName"` | +| Phrase template is not empty | `"phrase"` | +| Phrase keys resolve in the dataclass | `"phrase"` | + +The first two checks (identity) return immediately on failure; the remaining checks accumulate so all problems are reported in one pass. + +```4d +var $result:=$def.validate(cs.EmbeddingStudio.Settings.new()) + +If (Not($result.success)) + var $err : Object + For each ($err; $result.errors) + TRACE // $err.field, $err.message + End for each +End if +``` + +### invalidateVectors() + +**invalidateVectors**() : Object + +Marks all already-computed entities for re-embedding, forcing a full rebuild on the next run. Only entities that already have a vector value are processed — entities with a `Null` vector are skipped. + +Useful during development or after a model/phrase change to trigger a clean rebuild of all vectors. + +The strategy depends on whether a companion `_dirty` field exists on the dataclass: + +| Companion `_dirty` field | Action taken | +| ------------------------ | -------------------------------------------------------------- | +| Present | Sets `_dirty` to `True` — vector is left untouched | +| Absent | Nullifies the vector field | + +| 引数 | 型 | 説明 | +| --- | ------ | ------------------------------------------------------------------ | +| 戻り値 | Object | `{updated: Integer, skipped: Integer, errors: Collection of Text}` | + +- `updated` — number of entities successfully marked +- `skipped` — number of entities that could not be saved +- `errors` — one entry per save failure, formatted as `"DataclassName: statusText"` + +```4d +var $result:=$def.invalidateVectors() + +If ($result.skipped > 0) + var $e : Text + For each ($e; $result.errors) + // $e + End for each +End if +// → { updated: 42; skipped: 0; errors: [] } +``` + +### toObject() + +**toObject**() : Object + +Returns a plain object suitable for JSON persistence. The phrase is flattened to its template text. + +| 引数 | 型 | 説明 | +| --- | ------ | --------------------------------------------------------------------------------------------------------------------------------- | +| 戻り値 | Object | `{version, dataclassName, vectorName, modelAlias, phrase, autoInvalidate}` where `phrase` is the template string. | + +```4d +$def.toObject() +// → { version: 0; dataclassName: "Students"; vectorName: "student_vector_1"; +// modelAlias: "text-embedding-3-small"; phrase: "Student {firstName} {lastName}"; +// autoInvalidate: true } +``` + +## Automatic invalidation + +`autoInvalidate` controls whether save-time automatic invalidation is enabled for this definition. + +- `True` (default): when relevant attributes change on an entity save, vectors are automatically invalidated. +- `False`: save-time automatic invalidation is skipped for this definition. + +This setting does not affect manual invalidation via `invalidateVectors()`. + +## Dirty flag convention + +The pipeline in [Process](Process.md) will recompute an entity whenever the target vector is `Null`, or when a sibling field `_dirty` exists on the dataclass and is `True`. + +Declaring the dirty flag is optional — when absent, only the null-vector case triggers recomputation. When present, it is cleared automatically on successful save. + +## 参照 + +- [Settings](Settings.md) +- [Process](Process.md) +- [Phrase](Phrase.md) From 57fa83f13fca5eae2b2042ba5ae0dd79fc18395d Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:41:59 +0100 Subject: [PATCH 110/195] embedder.md Japanese --- .../embedding-studio/Classes/Embedder.md | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Embedder.md diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Embedder.md b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Embedder.md new file mode 100644 index 00000000000000..1d0f1ae886f748 --- /dev/null +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Embedder.md @@ -0,0 +1,96 @@ +--- +id: embedder +title: Embedder +--- + +# Embedder + +The `Embedder` class is a thin wrapper around [4D AIKit](https://developer.4d.com/docs/aikit/Classes/openai) focused on embeddings. It exposes two functions — one for a single text, one for a batch — and handles retries with exponential backoff (respecting the `Retry-After` header when present). + +It is stateless beyond configuration and safe to share between processes. + +## プロパティ + +| プロパティ名 | 型 | 説明 | +| ------------ | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | +| `client` | cs.AIKit.OpenAI | The underlying AIKit client used for HTTP requests. | +| `maxRetries` | Integer | Maximum number of retries on transient errors. Default: `3`. | +| `backoffMs` | Integer | Base delay (ms) between retries. Doubled each attempt. | + +## Class constructor + +Create a embedder. All options are optional. + +| 引数名 | 型 | 説明 | +| --------- | ------ | ----------------------------------------------------------------------------- | +| *options* | Object | `{client, maxRetries, backoffMs}` — any field may be omitted. | + +```4d +// Default — uses cs.AIKit.OpenAI.new() internally +var $proc:=cs.EmbeddingStudio.Embedder.new() + +// Provide a pre-configured AIKit client (custom API key, base URL, etc.) +var $client:=cs.AIKit.OpenAI.new({apiKey: "…"; baseURL: "https://server.ai"}) +var $proc:=cs.EmbeddingStudio.Embedder.new({client: $client; maxRetries: 5; backoffMs: 1000}) +``` + +> If the 4D AIKit component is not loaded (or is too old to provide `OpenAIProviders`), the constructor still succeeds with a `Null` client, and the first `embed()` / `embedBatch()` call throws an error whose `message` explains what is missing and whose `isAIKitMissing` property is `True`. + +## 関数 + +### embed() + +**embed**(*text* : Text ; *model* : Text) : [cs.EmbeddingStudio.EmbedderResult](EmbedderResult.md) + +Embed a single text. Returns a typed result with the embedding vector, token usage, and rate-limit state. + +| 引数 | 型 | 説明 | +| ------- | -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| *テキスト* | Text | The text to vectorize. | +| *model* | Text | The embedding model to use (e.g. `"text-embedding-3-small"`). | +| 戻り値 | [cs.EmbeddingStudio.EmbedderResult](EmbedderResult.md) | Typed wrapper — `.vector` holds the embedding, `.promptTokens` / `.totalTokens` hold usage, rate-limit fields are flat camelCase. | + +Throws if retries are exhausted or the API returns a non-retryable error. + +```4d +var $result:=$proc.embed("it rains cats and dogs"; "text-embedding-3-small") +// $result.vector → 4D.Vector +// $result.promptTokens → Integer +// $result.totalTokens → Integer +// $result.remainingTokens → Integer (-1 if unknown) +``` + +### embedBatch() + +**embedBatch**(*texts* : Collection ; *model* : Text) : [cs.EmbedderResult](EmbedderResult.md) + +Embed a collection of texts in a single API call. Returns a typed result with vectors in the same order as inputs, token usage, and rate-limit state. + +| 引数 | 型 | 説明 | +| ------- | ------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------- | +| *texts* | Collection | Collection of Text to vectorize. Empty or `Null` returns an empty result. | +| *model* | Text | The embedding model to use. | +| 戻り値 | [cs.EmbedderResult](EmbedderResult.md) | Typed wrapper — `.vectors` holds the embeddings collection, token and rate-limit fields are flat camelCase. | + +```4d +var $result:=$proc.embedBatch(["hello"; "world"]; "text-embedding-3-small") +// $result.vectors[0] → 4D.Vector for "hello" +// $result.vectors[1] → 4D.Vector for "world" +// $result.totalTokens → Integer (sum for the batch) +// $result.remainingTokens → Integer (after this call) +``` + +## Retry policy + +Transient errors (HTTP 408, 409, 429, 5xx) are retried up to `maxRetries` times. + +- If the response carries a `Retry-After` or `retry-after-ms` header, the embedder waits that long. +- Otherwise, it waits `backoffMs * 2^attempt`. + +Non-retryable errors are thrown immediately — see [OpenAIError](https://developer.4d.com/docs/aikit/Classes/openaierror) for the thrown shape. + +## 参照 + +- [EmbedderResult](EmbedderResult.md) +- [Process](Process.md) +- [OpenAIEmbeddingsAPI](https://developer.4d.com/docs/aikit/Classes/openaiembeddingsapi) (AIKit) From fa03a447589277bb77026223b9dd0e1627e2a56c Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:42:01 +0100 Subject: [PATCH 111/195] embedderresult.md Japanese --- .../Classes/EmbedderResult.md | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/EmbedderResult.md diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/EmbedderResult.md b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/EmbedderResult.md new file mode 100644 index 00000000000000..c2c44f170ee6e7 --- /dev/null +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/EmbedderResult.md @@ -0,0 +1,80 @@ +--- +id: embedderresult +title: EmbedderResult +--- + +# EmbedderResult + +Typed wrapper for `Embedder.embed()` and `Embedder.embedBatch()` responses. Normalizes OpenAI's snake_case API keys (`prompt_tokens`, `total_tokens`) to camelCase properties, and flattens the nested rate-limit structure into direct properties. + +A single class handles both single and batch results — `embed()` populates `.vector`, `embedBatch()` populates `.vectors`. + +## プロパティ + +### Embedding results + +| プロパティ | 型 | デフォルト | 説明 | +| --------- | ------------------------- | ----- | ------------------------------------------------------------------------------ | +| `vector` | 4D.Vector | Null | Single embedding result. Null for batch calls. | +| `vectors` | Collection | `[]` | Batch embedding results. | + +### Token usage + +| プロパティ | 型 | デフォルト | 説明 | +| -------------- | ------- | ----- | -------------------------------------------------------------------- | +| `promptTokens` | Integer | `0` | Input tokens consumed. | +| `totalTokens` | Integer | `0` | Total tokens consumed (in + out). | + +### Rate-limit state + +| プロパティ | 型 | デフォルト | 説明 | +| ------------------- | ------- | ----- | ------------------------------------------------------------------------------------------------------------------- | +| `remainingTokens` | Integer | `-1` | Tokens left in the current window. `-1` = unknown. | +| `remainingRequests` | Integer | `-1` | Requests left in the current window. `-1` = unknown. | +| `limitTokens` | Integer | `0` | TPM ceiling for the account. | +| `limitRequests` | Integer | `0` | RPM ceiling for the account. | +| `resetTokens` | Text | `""` | Time until token bucket refills (e.g. `"6m0s"`). | +| `resetRequests` | Text | `""` | Time until request bucket refills (e.g. `"1s"`). | + +## Class constructor + +```4d +// From a real API result (used by Embedder internally) +var $result:=cs.EmbedderResult.new($aikitResult; True) // batch +var $result:=cs.EmbedderResult.new($aikitResult; False) // single + +// Empty result (no API call — e.g. empty batch) +var $result:=cs.EmbedderResult.new() +``` + +| 引数 | 型 | 説明 | +| --------- | ------- | ------------------------------------------------------------------------------------------------------------ | +| *実行結果* | Object | An object with `.vector`/`.vectors`, `.usage`, `.rateLimit` (duck-typed). | +| *isBatch* | Boolean | `True` to read `.vectors`, `False` to read `.vector`. | + +The constructor accepts any object that exposes the expected shape — it does not require a specific class. This makes it easy to construct in tests. + +## 効果 + +```4d +// Single embedding +var $r:=$embedder.embed("hello world"; "text-embedding-3-small") +$r.vector // → 4D.Vector +$r.promptTokens // → 6 +$r.totalTokens // → 6 + +// Batch embedding +var $r:=$embedder.embedBatch(["hello"; "world"]; "text-embedding-3-small") +$r.vectors.length // → 2 +$r.totalTokens // → 10 + +// Rate-limit awareness +$r.remainingTokens // → 148230 (or -1 if not yet known) +$r.resetTokens // → "6m0s" +``` + +## 参照 + +- [Embedder](Embedder.md) — creates EmbedderResult instances +- [ProcessResult](ProcessResult.md) — run-level report that accumulates EmbedderResult usage +- [Rate Limiting](../RateLimit.md) — how the pipeline uses rate-limit fields for throttling and batch sizing From 614dbc255c57eb484e14af99dcb1fe74b9f1ad1c Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:42:03 +0100 Subject: [PATCH 112/195] phrase.md Japanese --- .../embedding-studio/Classes/Phrase.md | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Phrase.md diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Phrase.md b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Phrase.md new file mode 100644 index 00000000000000..151bec7cb2c351 --- /dev/null +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Phrase.md @@ -0,0 +1,117 @@ +--- +id: phrase +title: Phrase +--- + +# Phrase + +The `Phrase` class is a lightweight template engine: a template with `{variable}` placeholders is compiled once, then rendered efficiently against different data objects. + +## プロパティ + +| プロパティ名 | 型 | 説明 | +| ---------- | ---------- | ---------------------------------------------------------------------------------------------------------------------- | +| `template` | Text | Computed — returns the original template string. | +| `keys` | Collection | Computed — returns the variable names found in the template, dot-notation keys joined back to strings. | + +## Class constructor + +Compile a template. Compilation walks the template once and extracts static parts and variable paths. + +| 引数名 | 型 | 説明 | +| ---------- | ---- | ---------------------------------------------------------- | +| *template* | Text | Template string with `{variable}` markers. | + +```4d +var $tpl:=cs.EmbeddingStudio.Phrase.new("Hello {firstName}, you study at {schoolName}.") +$tpl.keys // → ["firstName"; "schoolName"] +``` + +## 関数 + +### render() + +**render**(*data* : Object) : Text + +Render the compiled template by replacing variables with values from *data*. Missing keys produce an empty string. + +| 引数 | 型 | 説明 | +| ------ | ------ | ------------------------------------------------------------------------------------------------------ | +| *data* | Object | A plain object or a 4D.Entity whose fields supply the variable values. | +| 戻り値 | Text | The rendered text. | + +```4d +var $text:=$tpl.render({firstName: "Alice"; school: {name: "MIT"}}) +// → "Hello Alice, you study at MIT." + +// Works directly on entities +$text:=$tpl.render(ds.Students.first()) +``` + +### validate() + +**validate**(*dataclass* : 4D.DataClass ; *options* : Object) : Object + +Validate that all keys in the phrase can be resolved against the given dataclass. Walks dot-notation paths through N:1 / 1:1 relations. + +| 引数 | 型 | 説明 | +| --------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| *データクラス* | 4D.DataClass | The dataclass to validate against. | +| *options* | Object | Optional validation flags (see below). All default to `False` — storage kind only. | +| 戻り値 | Object | `{success: Boolean, errors: Collection of {key, message}}`. | + +#### オプション + +| フィールド | 型 | デフォルト | 説明 | +| ----------------- | ------- | ------- | ----------------------------------------------------------------------------------------------------- | +| `allowRelations` | Boolean | `false` | Allow dot-notation paths through N:1 / 1:1 relations. | +| `allowCalculated` | Boolean | `false` | Allow calculated attributes. | +| `allowAlias` | Boolean | `false` | Allow alias attributes. | + +```4d +var $tpl:=cs.EmbeddingStudio.Phrase.new("{firstName} at {school.name}") + +// Storage-only validation — fails because {school.name} uses a relation +var $v:=$tpl.validate(ds.Students) +// $v.success → False +// $v.errors → [{key: "school.name"; message: "..."}] + +// Allow relations +$v:=$tpl.validate(ds.Students; {allowRelations: True}) +// $v.success → True +``` + +#### Rejected shapes + +Regardless of options: + +- Attributes that do not exist on the dataclass. +- Attributes whose class ID is `4D.Vector`. +- 1:N relations (`relatedEntities`) as the final key. +- Intermediate segments that are not relations (when dot-notation is used). + +### 属性() + +**attributes**(*dataclass* : 4D.DataClass) : Collection + +Resolves each phrase key against *dataclass* and returns an ordered Collection of ORDA attribute descriptor objects, one per key in the same order as `.keys`. For dot-notation paths, traverses N:1 relations to reach the final attribute. Pushes `Null` for any key whose path cannot be resolved (unknown attribute or non-relation intermediate segment). + +| 引数 | 型 | 説明 | +| -------- | ---------------------------- | -------------------------------------------------------------------------------------------- | +| *データクラス* | 4D.DataClass | The dataclass to resolve attributes against. | +| 戻り値 | Collection | Ordered collection of ORDA attribute objects (or `Null`). | + +Each resolved entry is an ORDA attribute descriptor with `.name`, `.kind`, and more — see [DataClass.attributeName](https://developer.4d.com/docs/API/DataClassClass#attributename). + +```4d +var $tpl:=cs.EmbeddingStudio.Phrase.new("{firstName} graduated from {school.name}") +var $attrs:=$tpl.attributes(ds.Students) +// $attrs[0].name → "firstName" $attrs[0].type → "string" +// $attrs[1].name → "name" $attrs[1].type → "string" (from School dataclass) +// $attrs[1] is Null if school.name could not be resolved +``` + +## 参照 + +- [Definition](Definition.md) — holds a `Phrase`. +- [StudioEmbedder.render()](StudioEmbedder.md#render) — renders a phrase for an entity, non-persisting. From 0ba09d7e6f2abe3385a20cc2042c7baac4ce7fbe Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:42:06 +0100 Subject: [PATCH 113/195] process.md Japanese --- .../embedding-studio/Classes/Process.md | 188 ++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Process.md diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Process.md b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Process.md new file mode 100644 index 00000000000000..c71a3fa7cee303 --- /dev/null +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Process.md @@ -0,0 +1,188 @@ +--- +id: プロセス +title: プロセス +--- + +# プロセス + +The `Process` class orchestrates the full embedding pipeline: it browses 4D entities, renders text from their fields using a [Definition](Definition.md), calls the embeddings API through an [Embedder](Embedder.md), and stores the resulting `4D.Vector` on each entity. + +To render or embed on demand without persistence (search query vectors, phrase previews), see [StudioEmbedder](StudioEmbedder.md). + +## プロパティ + +| プロパティ名 | 型 | 説明 | +| ---------- | ----------------------- | -------------------------------------------------------------------------------------------------------- | +| `設定` | [Settings](Settings.md) | The settings (definitions, batch size, phrase validation options). | +| `embedder` | [Embedder](Embedder.md) | The API-calling engine. Stateless and swappable. | +| `options` | Object | Runtime options object (see [Options object](#options-object) below). | + +### Options object + +| キー | 型 | 説明 | +| ---------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `onProgress` | 4D.Function | Called after each processed chunk with `{definition, report}`. | +| `onSuccess` | 4D.Function | Called once at the end when `report.success = True`, with `{report, success, errors}`. | +| `onError` | 4D.Function | Called once at the end when `report.success = False`, with `{report, success, errors}`. | +| `onTerminate` | 4D.Function | Called once at the end in all cases (after `onSuccess`/`onError`), with `{report, success, errors}`. | +| `dryRun` | Boolean | If `True`, runs selection/filter logic but skips API calls and entity saves. | +| `force` | Boolean | If `True`, recomputes every entity ignoring null-vector / dirty-flag filter. | +| `debug` | Boolean | If `True`, emits additional diagnostic log entries. | +| `pauseIndexes` | Boolean | If `True`, index maintenance on the target table is paused for the duration of a `processEntitySelection` batch run, then resumed right after (or on early exit/critical error). Default `False` — indexes are left alone. See [Pausing indexes](#pausing-indexes) before enabling it. | +| `waitForIndexes` | Boolean | Only used with `pauseIndexes`. If `True`, resuming indexes blocks until they are rebuilt. Default `False` — resume is asynchronous (indexes rebuilt in the background). | +| `shouldCancel` | 4D.Function | Predicate called between chunks during selection processing. Returning `True` stops the run gracefully (cooperative cancel) — what [`Scheduler.cancel()`](Scheduler.md#cancel) uses. | +| `embedder` | [Embedder](Embedder.md) | Inject a custom embedder (otherwise a default one is created). | + +## Class constructor + +Create an instance of the orchestrator. + +| 引数名 | 型 | 説明 | +| --------- | ----------------------- | ------------------------------------------------------------------------------------------------ | +| *設定* | [Settings](Settings.md) | 任意。 If omitted, settings are loaded from the default `Settings/embeddings.json`. | +| *options* | Object | Optional runtime options (see table above). | + +```4d +// Simplest — uses defaults +var $p:=cs.EmbeddingStudio.Process.new() + +// With explicit settings +var $p:=cs.EmbeddingStudio.Process.new($settings) + +// With options +var $p:=cs.EmbeddingStudio.Process.new($settings; {\ + force: True; \ + onProgress: Formula(ALERT("chunk done: "+String($1.report.entitiesUpdated)))}) +``` + +## Batch processing functions + +### プロセス() + +**process**(*definition* : Variant) : [ProcessResult](ProcessResult.md) + +Process one, many, or all [Definition](Definition.md) entries against the full content of their target dataclass. + +| 引数 | 型 | 説明 | +| ---- | -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | +| *定義* | `Null`, [Definition](Definition.md), `4D.DataClass`, plain object, or Collection | See [process() resolution](#process-resolution). `Null` → every definition in settings. | +| 戻り値 | [ProcessResult](ProcessResult.md) | Statistics and per-error breakdown. | + +```4d +// Every definition in settings +var $r:=$p.process() + +// One specific definition +var $r:=$p.process($def) + +// Multiple definitions +var $r:=$p.process([$def1; $def2]) + +// Every definition configured for a whole dataclass +var $r:=$p.process(ds.Students) + +// A plain descriptor — looked up in settings, or built on the fly +var $r:=$p.process({dataclassName: "Students"; vectorName: "student_vector_1"}) + +// Any mix — each item is resolved independently and flattened +var $r:=$p.process([ds.Students; $def; {dataclassName: "School"; vectorName: "school_vector_1"}]) +``` + +#### process() resolution + +`process()` has no entity context, so it resolves each input into concrete [Definition](Definition.md) objects directly from settings: + +| 入力 | 動作 | +| -------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `Null` | Every definition in settings. | +| [Definition](Definition.md) | Used as-is. | +| `4D.DataClass` (e.g. `ds.Students`) | Every definition in settings whose `dataclassName` matches that dataclass. | +| `{dataclassName: "..."; vectorName: "..."}` | The matching saved definition, or — if none is found — a new `Definition` built from the object's fields (`modelAlias`, `phrase.template`). | +| Collection | Each item is resolved with the rules above and the results are **flattened** into one collection (a `4D.DataClass` item can expand to several definitions). Unsupported items are dropped. | +| Anything else | Empty result. | + +### processEntity() + +**processEntity**(*entity* : 4D.Entity ; *definition* : Variant) : [ProcessResult](ProcessResult.md) + +Process a single entity. Cheap path — no chunking, no server-side filter. + +| 引数 | 型 | 説明 | +| -------- | ----------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | +| *entity* | 4D.Entity | The entity to (re)compute vectors for. | +| *定義* | `Null`, [Definition](Definition.md), Collection, or `{vectorName: ...}` | See [resolution rules](#definition-resolution). `Null` infers from entity's dataclass. | +| 戻り値 | [ProcessResult](ProcessResult.md) | Statistics and per-error breakdown. | + +```4d +// Auto-resolve every definition matching this entity's dataclass +var $r:=$p.processEntity($entity) + +// Specific definition +var $r:=$p.processEntity($entity; $def) + +// By vector name only (looked up in settings against the entity's dataclass) +var $r:=$p.processEntity($entity; {vectorName: "student_vector_1"}) +``` + +### processEntitySelection() + +**processEntitySelection**(*selection* : 4D.EntitySelection ; *definition* : Variant) : [ProcessResult](ProcessResult.md) + +Workhorse path for large jobs. Chunks the selection by `settings.batchSize`, sends one API call per chunk, saves each entity individually. + +| 引数 | 型 | 説明 | +| ----------- | ----------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | +| *selection* | 4D.EntitySelection | Entities to process. Pre-filtering by the caller is allowed; the pipeline still applies its null/dirty filter. | +| *定義* | `Null`, [Definition](Definition.md), Collection, or `{vectorName: ...}` | See [resolution rules](#definition-resolution). | +| 戻り値 | [ProcessResult](ProcessResult.md) | Statistics and per-error breakdown. | + +```4d +var $todo:=ds.Students.query("country = :1"; "FR") +var $r:=$p.processEntitySelection($todo; $def) +``` + +### Definition resolution (entity context) + +The polymorphic *definition* argument accepted by `processEntity` and `processEntitySelection`. Unlike [`process()`](#process-resolution), these have an entity/selection to infer the dataclass from, so a bare `{vectorName: "..."}` stub is enough: + +| 入力 | 動作 | +| --------------------------- | ----------------------------------------------------------------------------------------------- | +| `Null` | All definitions in settings whose `dataclassName` matches the entity/selection. | +| [Definition](Definition.md) | Used as-is; the `dataclassName` must match the entity/selection. | +| `{vectorName: "..."}` | Looked up in settings by `vectorName` against the entity/selection dataclass. | +| Collection | Each item resolved using the rules above; mismatches are silently dropped. | + +### Recompute rules + +An entity is (re)computed when **any** of these are true: + +- The target vector field is `Null`. +- A sibling field named `{vectorName}_dirty` exists and is `True`. +- The `force` option is `True`. + +The dirty field is optional per dataclass. If it doesn't exist, only the null-vector case triggers recomputation. Upon successful save, the pipeline clears the dirty flag (when present). + +For `processEntitySelection`, the filter is executed as a server-side ORDA query before any API call, so only the rows that actually need work are loaded into memory. For `processEntity`, the check is done in memory on the already-fetched entity. + +### Pausing indexes + +By default the indexes of the target table are maintained normally while vectors are saved. With the `pauseIndexes` option, a batch run calls [`PAUSE INDEXES`](https://developer.4d.com/docs/commands/pause-indexes) on the table before writing and [`RESUME INDEXES`](https://developer.4d.com/docs/commands/resume-indexes) once done (also on early exit or critical error). + +Be aware of what these commands do: + +- `PAUSE INDEXES` disables **all** the indexes of the table (except the primary key index), not only the vector ones: every index on every other field of the table is paused too. While paused, queries and sorts on that table, including those of other processes, run without any index. +- `RESUME INDEXES` then **rebuilds all these indexes**, for the whole table, not only for the records that were recomputed. On a table with several indexes, this rebuild can cost more than the time saved during the writes. +- With `waitForIndexes` set to `True`, the run blocks until the rebuild completes; otherwise the rebuild runs in the background. +- These commands cannot run on a 4D remote client: there the option is ignored (a warning is logged once) and the recalculation runs with indexes maintained normally. Run it on the server, for example through the [Scheduler](Scheduler.md), to use it. + +Enable it only for large recalculations, such as computing the vectors of a whole table for the first time. + +## 参照 + +- [StudioEmbedder](StudioEmbedder.md) +- [Settings](Settings.md) +- [Definition](Definition.md) +- [Embedder](Embedder.md) +- [ProcessResult](ProcessResult.md) +- [Phrase](Phrase.md) +- [Rate Limiting](../RateLimit.md) From 6cf42ab337409111bd042ce5f38a6ac8728d3cbb Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:42:09 +0100 Subject: [PATCH 114/195] processerror.md Japanese --- .../embedding-studio/Classes/ProcessError.md | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/ProcessError.md diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/ProcessError.md b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/ProcessError.md new file mode 100644 index 00000000000000..fa8a4e0316d6d6 --- /dev/null +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/ProcessError.md @@ -0,0 +1,87 @@ +--- +id: processerror +title: ProcessError +--- + +# ProcessError + +A `ProcessError` is one structured, typed entry in the `errors` collection of a [ProcessResult](ProcessResult.md). Its typed fields let callers react to a specific failure mode programmatically — retry transient failures, abort on a fatal model outage, count save failures — without parsing message strings. + +You read these instances from [ProcessResult](ProcessResult.md)`.errors`, directly or through its query helpers (`errorsByCode`, `errorsByScope`, `retryableErrors`). + +## プロパティ + +| プロパティ名 | 型 | 説明 | +| ----------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `スコープ` | Text | Where the error originated: `"pipeline"`, `"definition"`, `"chunk"`, or `"entity"`. | +| `severity` | Text | `"warning"`, `"error"`, or `"fatal"`. Determined by `code` (see [ProcessErrorCode](ProcessErrorCode.md)). | +| `code` | Integer | Machine-readable error code — compare against the constants on [ProcessErrorCode](ProcessErrorCode.md). | +| `ref` | Variant | Scope-dependent reference: `"Dataclass.vector"`, an entity primary key, a model alias, or `Null`. | +| `message` | Text | Human-readable, localized message. | +| `retryable` | Boolean | `True` when re-running the operation could plausibly succeed. Determined by `code`. | + +### scope values + +| スコープ | 意味 | +| -------------- | -------------------------------------------------------------------------------------------------------------------------- | +| `"pipeline"` | Top-level failure affecting the whole run (null selection, a model became unavailable). | +| `"definition"` | A [Definition](Definition.md) failed validation or was skipped. | +| `"chunk"` | A whole batch (chunk) of entities failed in a single API call. | +| `"entity"` | A single entity failed to embed or save. | + +### severity values + +| Severity | 意味 | +| --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `"警告"` | Non-blocking — does **not** make [ProcessResult](ProcessResult.md)`.success` false. | +| `"error"` | A recoverable failure scoped to one entity, chunk, or definition. Makes `success` false. | +| `"fatal"` | Blocks the rest of the run (e.g. the model is unavailable). Also surfaces via `hasFatal`. | + +## 計算プロパティ + +| プロパティ | 型 | 説明 | +| --------- | ------- | ------------------------------------------------- | +| `isFatal` | Boolean | `True` when `severity = "fatal"`. | + +## 関数 + +### toObject() + +**toObject**() : Object + +Returns a plain object (`{scope, severity, code, ref, message, retryable}`) suitable for logging or JSON serialization. + +| 引数 | 型 | 説明 | +| --- | ------ | ------------------------------------------------------ | +| 戻り値 | Object | A JSON-friendly snapshot of the error. | + +## 例題 + +React to failures by type rather than by message text: + +```4d +var $r:=$p.process() + +If (Not($r.success)) + + If ($r.hasFatal) + ALERT("A model became unavailable — aborting until it recovers.") + End if + + var $codes:=cs.EmbeddingStudio.ProcessErrorCode.me + var $saveFailures:=$r.errorsByCode($codes.SAVE_FAILED) + If ($saveFailures.length>0) + ALERT(String($saveFailures.length)+" entities failed to save.") + End if + + // Collect entity keys worth retrying later + var $retry:=$r.retryableErrors().query("scope = :1"; "entity").extract("ref") + +End if +``` + +## 参照 + +- [ProcessErrorCode](ProcessErrorCode.md) — the catalogue of `code` values and their severity/retryability. +- [ProcessResult](ProcessResult.md) — owns the `errors` collection and the query helpers (`errorsByCode`, `errorsByScope`, `retryableErrors`). +- [Process](Process.md) — produces these errors. From ca1d3d135a136a01743c7be749201a2a48ed9d93 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:42:11 +0100 Subject: [PATCH 115/195] processerrorcode.md Japanese --- .../Classes/ProcessErrorCode.md | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/ProcessErrorCode.md diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/ProcessErrorCode.md b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/ProcessErrorCode.md new file mode 100644 index 00000000000000..dafd474bde19ec --- /dev/null +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/ProcessErrorCode.md @@ -0,0 +1,55 @@ +--- +id: processerrorcode +title: ProcessErrorCode +--- + +# ProcessErrorCode + +A `singleton` exposing the stable, machine-readable error codes carried by [ProcessError](ProcessError.md) `.code`, plus a `meta()` lookup mapping each code to its default `severity` and `retryable` flag. Compare against these constants instead of parsing message strings. + +Access the shared instance via `.me`: + +```4d +var $codes:=cs.EmbeddingStudio.ProcessErrorCode.me +If ($error.code=$codes.SAVE_FAILED) + // … +End if +``` + +## Codes + +| 定数 | 値 | Default severity | Retryable | Raised when… | +| ----------------------- | --- | ---------------- | --------- | ------------------------------------------------------------------------------------------------- | +| `NULL_INPUT` | 100 | error | × | A required entity, selection, or definition was `Null`. | +| `INVALID_DEFINITION` | 101 | error | × | A value is not a usable [Definition](Definition.md) instance. | +| `VALIDATION_FAILED` | 102 | error | × | `Definition.validate()` reported a problem. | +| `MODEL_UNAVAILABLE` | 200 | fatal | ◯ | A critical API error made the model unusable for the rest of the run. | +| `MODEL_SKIPPED` | 201 | error | ◯ | A definition was skipped because its model already failed critically. | +| `EMBED_FAILED` | 202 | error | ◯ | A non-critical embedding call failed (single entity or chunk). | +| `VECTOR_COUNT_MISMATCH` | 300 | error | × | The provider returned a different vector count than requested. | +| `SAVE_FAILED` | 400 | error | ◯ | `entity.save()` failed (validation, lock, …). | + +Codes are grouped by hundreds: `1xx` input/configuration, `2xx` model/API, `3xx` data integrity, `4xx` persistence. Unknown codes resolve to `{severity: "error"; retryable: False; label: "UNKNOWN"}`. + +## 関数 + +### meta() + +**meta**( $code : Integer ) : Object + +Returns the `severity` and `retryable` flag associated with a code — the same values carried by a [ProcessError](ProcessError.md) with that `code`. + +| 引数 | 型 | 説明 | +| ------- | ------- | ----------------------------------------------------------------------- | +| `$code` | Integer | One of the code constants above. | +| 戻り値 | Object | `{severity : Text; retryable : Boolean; label : Text}`. | + +```4d +var $m:=cs.EmbeddingStudio.ProcessErrorCode.me.meta(cs.EmbeddingStudio.ProcessErrorCode.me.MODEL_UNAVAILABLE) +// $m = {severity: "fatal"; retryable: True; label: "MODEL_UNAVAILABLE"} +``` + +## 参照 + +- [ProcessError](ProcessError.md) — carries a `.code` from this list. +- [ProcessResult](ProcessResult.md) — `errorsByCode()` filters errors by code. From 49a51bbbd17af94ac6a9f7e6368b2add20fd8c33 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:42:13 +0100 Subject: [PATCH 116/195] processresult.md Japanese --- .../embedding-studio/Classes/ProcessResult.md | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/ProcessResult.md diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/ProcessResult.md b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/ProcessResult.md new file mode 100644 index 00000000000000..7c690d7eeda9f1 --- /dev/null +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/ProcessResult.md @@ -0,0 +1,91 @@ +--- +id: processresult +title: ProcessResult +--- + +# ProcessResult + +The `ProcessResult` class is the return value of every batch entry point of [Process](Process.md) (`process`, `processEntity`, `processEntitySelection`). It accumulates statistics, per-error breakdowns, and wall-clock duration. + +The orchestrator never throws out of its public batch API — failures are recorded here and the job continues. The caller decides what to do with them. + +## プロパティ + +| プロパティ名 | 型 | 説明 | +| ---------------------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `definitionsProcessed` | Integer | Number of [Definition](Definition.md) entries processed. | +| `entitiesConsidered` | Integer | Number of entities that passed the "needs recompute" filter. | +| `entitiesUpdated` | Integer | Number of entities whose vector was successfully written and saved. | +| `entitiesSkipped` | Integer | Number of entities that could not be processed: individual embed or save errors, or whole-chunk API failures (those entities are left unchanged for the next run). | +| `apiCalls` | Integer | Number of embeddings API calls made. | +| `promptTokens` | Integer | Total prompt tokens consumed across all API calls in this run. | +| `totalTokens` | Integer | Total tokens consumed across all API calls in this run. | +| `経過時間` | Integer | Total duration of the job in milliseconds. | +| `errors` | Collection | List of [ProcessError](ProcessError.md) entries recorded during the run. | + +### 計算プロパティ + +| プロパティ | 型 | 説明 | +| ---------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `success` | Boolean | `True` when no `"error"` or `"fatal"` entry was recorded. `"warning"` entries do not fail the run. | +| `hasFatal` | Boolean | `True` when at least one `"fatal"` entry was recorded (e.g. a model became unavailable). | + +### Error entries + +Each item in `errors` is a [ProcessError](ProcessError.md) with `scope`, `severity`, `code`, `ref`, `message`, and `retryable`. See [ProcessError](ProcessError.md) for the field meanings and [ProcessErrorCode](ProcessErrorCode.md) for the `code` catalogue. + +## 関数 + +### errorsByScope() + +**errorsByScope**( $scope : Text ) : Collection + +Errors filtered by `scope` (`"pipeline"`, `"definition"`, `"chunk"`, `"entity"`). + +### errorsByCode() + +**errorsByCode**( $code : Integer ) : Collection + +Errors filtered by machine-readable code — see [ProcessErrorCode](ProcessErrorCode.md). + +### retryableErrors() + +**retryableErrors**() : Collection + +Errors flagged `retryable` — re-running the operation could plausibly succeed. + +### toObject() + +**toObject**() : Object + +Returns a plain object suitable for logging or JSON serialization. + +| 引数 | 型 | 説明 | +| --- | ------ | ------------------------------------------------------- | +| 戻り値 | Object | A JSON-friendly snapshot of the report. | + +```4d +var $r:=$p.process() +LOG EVENT(Into 4D log file; JSON Stringify($r.toObject())) +``` + +## 例題 + +```4d +var $r:=$p.processEntitySelection(ds.Students.all(); $def) + +If ($r.success) + ALERT("Updated "+String($r.entitiesUpdated)+" students in "+String($r.duration)+" ms") +Else + var $err : Object + For each ($err; $r.errors) + ALERT("[" + $err.scope + "] " + String($err.ref) + " — " + $err.message) + End for each +End if +``` + +## 参照 + +- [Process](Process.md) +- [ProcessError](ProcessError.md) — the typed shape of each `errors` entry. +- [ProcessErrorCode](ProcessErrorCode.md) — the `code` catalogue. From 45c0cc3c5eedc6b6e7881e062dcc8267d4cc3b8c Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:42:16 +0100 Subject: [PATCH 117/195] scheduler.md Japanese --- .../embedding-studio/Classes/Scheduler.md | 369 ++++++++++++++++++ 1 file changed, 369 insertions(+) create mode 100644 i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Scheduler.md diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Scheduler.md b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Scheduler.md new file mode 100644 index 00000000000000..975db1e02ec8e0 --- /dev/null +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Scheduler.md @@ -0,0 +1,369 @@ +--- +id: スケジューラー +title: スケジューラー +--- + +# スケジューラー + +The `Scheduler` class is the public entry point for the **automated embedding recalculation** service. It maintains a background task that runs the embedding pipeline (see [Process](Process.md)) at a configured interval or a fixed daily time, guarantees that **at most one** recalculation batch runs at a time, and exposes runtime status for administration and monitoring interfaces. + +It is a **singleton**, accessed through `cs.EmbeddingStudio.Scheduler.me`. + +The scheduler runs two named workers: + +| Worker | ロール | +| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `EmbeddingStudioScheduler` | Background loop that re-reads the config each cycle, computes the next run and fires when due. | +| `EmbeddingStudio` | Execution worker that runs one recalculation batch (shared with the Studio UI, so scheduled and manual runs are serialized). | + +## 設定 + +The configuration lives under the `scheduler` key of `Settings/embeddings.json`: + +```json +{ + "scheduler": { + "mode": "interval", + "intervalHours": 3, + "startFrom": "reference", + "startReference": "2026-09-02T14:00:00", + "dailyTime": "00:00" + } +} +``` + +| キー | 型 | Values / range | 説明 | +| ---------------- | ------- | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `mode` | Text | `"never"` \| `"interval"` \| `"daily"` | Scheduling mode. Absent/unknown ⇒ `never` (no automatic run). | +| `intervalHours` | Integer | `1`..`24` | Interval mode only. Out-of-range ⇒ default `3`. | +| `startFrom` | Text | `"reference"` \| `"lastExecution"` | Interval mode only. Anchor of the interval (see below). Anything other than `"lastExecution"` — including the legacy `"now"` — is normalized to `reference`. Default `reference`. | +| `startReference` | Text | `"YYYY-MM-DDThh:mm:ss"` | Interval mode with `startFrom = "reference"`. Fixed instant the interval counts from. Absent ⇒ the moment the scheduler was armed, then the current instant. | +| `dailyTime` | Text | `"HH:MM"` | Daily mode only. Time of day for the recalculation. Default `"00:00"`. | + +**Interval anchoring (`startFrom`)** + +- `reference` — **fixed rate**: the interval is anchored on the fixed `startReference` instant, so the slots do not drift whatever a run's duration is. Slots are advanced by `intervalHours` until the first one strictly after now. When `startReference` is absent (a fresh or legacy config), the anchor falls back to the moment the scheduler was armed (`start()`), then to the current instant. +- `lastExecution` — **fixed delay**: the interval is anchored on the last completed recalculation. If the elapsed time since the last run already exceeds the interval (e.g. after a restart), the run is triggered immediately. If there is no prior run, it runs immediately. + +The effective configuration is read from the file on **every loop cycle**, so changes take effect without restarting the scheduler. + +## Starting the scheduler + +Configuring a `mode` is **not enough**: nothing runs until the scheduler is started. There are two ways to get there, and which one applies depends on a single option of your host database. + +### 1. Automatic — let the host database start it + +In the host database, open **Settings > Security** and check **"Execute 'On Host Database Event' method of the components"** (it is *unchecked* by default, for security reasons). + +With this option on, 4D Embedding Studio starts the scheduler by itself when the host database opens, and stops it when the host database closes. There is nothing else to write. + +Use [`autoStart()`](#autostart) to check whether the option is on: + +```4d +If (Not(cs.EmbeddingStudio.Scheduler.me.autoStart())) + // the option is off — I must start the scheduler myself + cs.EmbeddingStudio.Scheduler.me.start() +End if +``` + +### 2. Manual — start it from your own code + +If you prefer to leave the option off, the scheduler never starts on its own. Call [`start()`](#start) from wherever it suits you — typically the host `On Startup` or `On Server Startup` database method — and [`stop()`](#stop) when the database closes (`On Exit` / `On Server Shutdown`): + +```4d +// Host "On Server Startup" +cs.EmbeddingStudio.Scheduler.me.start() + +// Host "On Server Shutdown" +cs.EmbeddingStudio.Scheduler.me.stop() +``` + +> In client/server, arm the scheduler from `On Server Startup`, not from `On Startup`: +> `On Startup` runs on every remote client, and the scheduler state is per machine — each +> client would arm its own loop and run its own batches. If you do call [`start()`](#start) +> from `On Startup` (single-user setups), guard it with +> `If (Application type#4D Remote mode)`. + +`start()` is idempotent, so calling it from several places is harmless. + +### Checking that it really runs + +[`isStarted()`](#isstarted) tells you whether the background loop is alive right now — the answer to "is my schedule actually being watched?": + +```4d +var $s:=cs.EmbeddingStudio.Scheduler.me.status() +If ($s.enabled && Not($s.started)) + ALERT("A schedule is configured but the scheduler is not started.") +End if +``` + +## 関数 + +### start() + +**start**() : Boolean + +Arms the scheduler and starts the background loop worker if it is not already running. Idempotent — calling it again while already armed simply refreshes the "start from now" anchor. + +| 戻り値 | 型 | 説明 | +| --- | ------- | ------------------------------ | +| 戻り値 | Boolean | Always `True`. | + +```4d +cs.EmbeddingStudio.Scheduler.me.start() +``` + +### stop() + +**stop**() + +Disarms the scheduler and stops the background loop worker. A recalculation batch already in progress is **not** interrupted — it finishes normally (use [`cancel()`](#cancel) to request an early stop). + +```4d +cs.EmbeddingStudio.Scheduler.me.stop() +``` + +### キャンセル() + +**cancel**() + +Requests a **cooperative** cancel of the batch currently running. The running batch is never force-killed; it stops gracefully between two chunks. Has no effect if no batch is running. + +```4d +cs.EmbeddingStudio.Scheduler.me.cancel() +``` + +### force() + +**force**() : Object + +Forces a recalculation **now**, regardless of the schedule. It honors the single-batch rule: if a batch is already running, the forced trigger is skipped (and logged). Non-blocking — the run happens on the execution worker. + +| 戻り値 | 型 | 説明 | +| --- | ------ | ----------------------------------------------------- | +| 戻り値 | Object | The current [status](#status) object. | + +```4d +var $status:=cs.EmbeddingStudio.Scheduler.me.force() +``` + +### status() + +**status**() : Object + +Returns the current scheduler status, without any input parameter — suitable for administration and monitoring displays. + +| 戻り値 | 型 | 説明 | +| --- | ------ | ---------------------------------------------------- | +| 戻り値 | Object | See [Status object](#status-object). | + +```4d +var $s:=cs.EmbeddingStudio.Scheduler.me.status() +If ($s.running) + ALERT("A recalculation is running since "+$s.batchStart) +End if +``` + +#### ステータスオブジェクト + +| キー | 型 | 説明 | +| ---------------------- | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `enabled` | Boolean | `False` when `mode = "never"`. | +| `mode` | Text | Effective mode (`never` \| `interval` \| `daily`). | +| `armed` | Boolean | `True` when the background loop is armed (after `start()`, until `stop()`). | +| `running` | Boolean | `True` while a recalculation batch is in progress. | +| `batchStart` | Text \| Null | ISO timestamp of the running batch start (`Null` when idle). | +| `lastExecution` | Text \| Null | ISO timestamp of the last completed run (`Null` if none yet). Restored from the persisted history after a restart, so it survives the loss of in-memory state. | +| `lastRunBeforeRestart` | Boolean | `True` when `lastExecution` was recovered from the history after a restart rather than produced by a run in the current session. | +| `nextRun` | Text \| Null | ISO timestamp of the next scheduled run (`Null` in `never` mode). | +| `lastResult` | Text \| Null | Result of the last trigger: `started` \| `skipped` \| `completed` \| `failed`. | +| `エラー発生` | Text \| Null | Error summary when the last run failed (safe for admin display), else `Null`. | +| `started` | Boolean | `True` when the background loop is really alive (see [`isStarted()`](#isstarted)). | +| `autoStart` | Boolean | `True` when the host database starts the scheduler by itself (see [`autoStart()`](#autostart)). | + +### isStarted() + +**isStarted**() : Boolean + +Tells whether the scheduler is **effectively running**, i.e. whether its background loop is alive at this very moment. Unlike the `armed` flag of the [status](#status-object), it reflects reality: if the loop was never started, or was killed, the result is `False`. + +| 戻り値 | 型 | 説明 | +| --- | ------- | --------------------------------------------------------- | +| 戻り値 | Boolean | `True` when the background loop is alive. | + +```4d +If (Not(cs.EmbeddingStudio.Scheduler.me.isStarted())) + cs.EmbeddingStudio.Scheduler.me.start() +End if +``` + +### autoStart() + +**autoStart**() : Boolean + +Tells whether the host database authorizes 4D Embedding Studio to start itself, i.e. whether the **"Execute 'On Host Database Event' method of the components"** option is checked in the host **Settings > Security** (see [Starting the scheduler](#starting-the-scheduler)). + +- `True` — the scheduler starts with the host database and stops with it. You have nothing to call. +- `False` — nothing starts automatically: your code must call [`start()`](#start) and [`stop()`](#stop). + +The answer is read from the host structure settings. When they cannot be read, the result is `False` — the safe answer, since starting an already-started scheduler is harmless. + +| 戻り値 | 型 | 説明 | +| --- | ------- | -------------------------------------------------------------------- | +| 戻り値 | Boolean | `True` when the host starts the scheduler by itself. | + +```4d +var $auto:=cs.EmbeddingStudio.Scheduler.me.autoStart() +``` + +### config() + +**config**() : Object + +Returns the effective scheduler configuration with defaults applied (as resolved from `embeddings.json`). + +| 戻り値 | 型 | 説明 | +| --- | ------ | --------------------------------------------------------------------------------------------------------------------------------------- | +| 戻り値 | Object | `{mode; intervalHours; startFrom; startReference; dailyTime}` (see [Configuration](#configuration)). | + +```4d +var $cfg:=cs.EmbeddingStudio.Scheduler.me.config() +``` + +### saveConfig() + +**saveConfig**( *cfg* : Object ) : Object + +Validates, normalizes and **persists** a scheduler configuration to the `scheduler` key of `embeddings.json`, then returns the normalized value. This is the programmatic equivalent of the scheduler settings window: it lets you change the schedule entirely by code, without the GUI. Only the `scheduler` key is written — other keys of the settings file are preserved. + +The configuration is written **on the server**: in a 4D Server / 4D remote setup the file is always edited on the server machine, so a remote client can safely call this method. Because the loop re-reads the configuration on every cycle, the new schedule takes effect without restarting the scheduler. + +| 引数 | 型 | 説明 | +| --- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| cfg | Object | Raw configuration `{mode; intervalHours; startFrom; startReference; dailyTime}` (see [Configuration](#configuration)). Missing/out-of-range values are defaulted. | + +| 戻り値 | 型 | 説明 | +| --- | ------ | ---------------------------------------------------------------- | +| 戻り値 | Object | The normalized configuration that was persisted. | + +```4d +// Switch to a 6-hour interval counting from the last execution +cs.EmbeddingStudio.Scheduler.me.saveConfig({mode: "interval"; intervalHours: 6; startFrom: "lastExecution"}) + +// Switch to a daily run at 02:30 +cs.EmbeddingStudio.Scheduler.me.saveConfig({mode: "daily"; dailyTime: "02:30"}) + +// Disable the automatic schedule +cs.EmbeddingStudio.Scheduler.me.saveConfig({mode: "never"}) +``` + +### nextRun() + +**nextRun**() : Object + +Computes the next scheduled run from the current configuration and state. + +| 戻り値 | 型 | 説明 | +| --- | -------------- | --------------------------------------------------------------------------------------------------------------- | +| 戻り値 | Object \| Null | `{date : Date; time : Time; timestamp : Text; immediate : Boolean}`, or `Null` in `never` mode. | + +```4d +var $next:=cs.EmbeddingStudio.Scheduler.me.nextRun() +``` + +### reload() + +**reload**() : Object + +No-op convenience: the configuration is re-read automatically on each loop cycle, so this simply returns the current [status](#status). Provided for callers that want an explicit "config changed, give me the up-to-date status" call. + +| 戻り値 | 型 | 説明 | +| --- | ------ | ----------------------------------------------------- | +| 戻り値 | Object | The current [status](#status) object. | + +## Concurrency & logging + +- **Single batch** — at any time, at most one recalculation batch runs. A trigger (scheduled or forced) fired while a batch is running is **skipped**, not queued. +- **Skip traceability** — skipped triggers are logged with their timestamp in the execution history (`Logs/embeddingHistory.json`). +- **Cooperative cancel** — `cancel()` stops a running batch gracefully between chunks; it is never force-killed. +- **History** — each run records start/end timestamps, status, token usage and the computed next run date in `Logs/embeddingHistory.json` (see [ProcessResult](ProcessResult.md) for per-run details). + +### Execution history file + +`Logs/embeddingHistory.json` is written by the pipeline itself (every full `process()` run, scheduled or manual), guarded by a semaphore so concurrent processes never interleave writes. It holds the **current** run at the top level, the one before it under `previous`, and the same pair per definition under `definitions`. + +```json +{ + "startTime": "2026-09-01T14:03:00", + "endTime": "2026-09-01T14:03:00", + "status": "completed", + "trigger": "completed", + "error": null, + "nextComputeDate": "2026-09-02T14:03:00", + "promptTokens": 0, + "totalTokens": 0, + "cumulativePromptTokens": 37802, + "cumulativeTotalTokens": 37802, + "previous": { "startTime": "…", "endTime": "…", "status": "completed", "error": null, + "nextComputeDate": "…", "promptTokens": 12764, "totalTokens": 12764, + "cumulativePromptTokens": 37802, "cumulativeTotalTokens": 37802 }, + "skipped": ["2026-09-01T12:00:00"], + "definitions": { + "Students.student_vector_1": { + "startTime": "…", "endTime": "…", "status": "completed", "error": null, + "promptTokens": 1054, "totalTokens": 1054, + "cumulativePromptTokens": 4210, "cumulativeTotalTokens": 4210, + "previous": { "…": "…" } + } + } +} +``` + +| キー | 型 | 説明 | +| -------------------------------------------------- | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `startTime` / `endTime` | Text \| Null | ISO timestamps of the run, in the scheduler's local base. `endTime` is `null` while a run is in progress. | +| `status` | Text | `running` \| `completed` \| `failed`. | +| `trigger` | Text | Last event that touched the file: `started` \| `skipped` \| `completed` \| `failed`. | +| `エラー発生` | Text \| Null | Summary of the run's errors, or `null`. Never contains an API key. | +| `nextComputeDate` | Text \| Null | Next scheduled run computed at the end of the run (the `nextComputeDate` option of [Process](Process.md)). | +| `promptTokens` / `totalTokens` | Integer | Usage for this run alone. | +| `cumulativePromptTokens` / `cumulativeTotalTokens` | Integer | Running totals across all recorded runs. | +| `previous` | Object | Snapshot of the preceding run — the same keys, without `trigger`, `skipped` and `definitions`. Only one generation is kept. | +| `skipped` | Collection | ISO timestamps of triggers skipped because a batch was already running. Capped at the **last 50**. | +| `definitions` | Object | One entry per definition, keyed `"."`, each with its own `startTime`, `endTime`, `status` (`completed` \| `failed` \| `skipped`), `error`, token counters and `previous`. | + +[`status()`](#status) reads `startTime`, `endTime`, `status`, `trigger`, `error` and `nextComputeDate` back from this file, which is how `lastExecution` survives a server restart. + +## Lifecycle + +| Host setting | What happens | What you must do | +| ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | +| **"Execute 'On Host Database Event' method of the components"** checked | The scheduler starts when the host database opens and stops when it closes. | Nothing. | +| Option unchecked (default) | The scheduler never starts by itself. | Call [`start()`](#start) at startup and [`stop()`](#stop) at shutdown. | + +Ask [`autoStart()`](#autostart) which case you are in, and [`isStarted()`](#isstarted) whether the loop is currently alive. Stopping the scheduler never interrupts a batch in progress — it finishes normally. + +## 例題 + +```4d +// --- Start at server startup, unless the host does it for us --- +If (Not(cs.EmbeddingStudio.Scheduler.me.autoStart())) + cs.EmbeddingStudio.Scheduler.me.start() +End if + +// --- Admin panel: force a recalculation and read status --- +var $status:=cs.EmbeddingStudio.Scheduler.me.force() + +// --- Monitoring: display last / next run and current state --- +$status:=cs.EmbeddingStudio.Scheduler.me.status() +var $info:="Mode: "+$status.mode\ + +" — Last: "+String($status.lastExecution)\ + +" — Next: "+String($status.nextRun)\ + +" — "+($status.running ? "running" : String($status.lastResult)) + +// --- Cancel a long-running batch --- +cs.EmbeddingStudio.Scheduler.me.cancel() + +// --- Disable automatic runs --- +cs.EmbeddingStudio.Scheduler.me.stop() +``` From cbe2ef2c9706838b00d2c571221305c7fd288168 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:42:19 +0100 Subject: [PATCH 118/195] settings.md Japanese --- .../embedding-studio/Classes/Settings.md | 184 ++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Settings.md diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Settings.md b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Settings.md new file mode 100644 index 00000000000000..cb8643648e3d68 --- /dev/null +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Settings.md @@ -0,0 +1,184 @@ +--- +id: settings +title: 設定 +--- + +# 設定 + +The `Settings` class is the persisted configuration for the embedding pipeline. It loads and saves a JSON file (default: `Settings/embeddings.json`, overridable with the `EMBEDDINGS_SETTINGS_PATH` environment variable) containing a list of [Definition](Definition.md) entries, a batch size, and phrase-validation options. + +## プロパティ + +| プロパティ名 | 型 | 説明 | +| ------------- | -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `definitions` | Collection of [Definition](Definition.md) | The configured definitions. | +| `batchSize` | Integer | Chunk size used by [Process.processEntitySelection](Process.md#processentityselection). Default: `50`. | +| `phrase` | Object | Phrase-validation options (see below). | +| `embedder` | Object | Optional embedder configuration (see below). | +| `file` | 4D.File *(read-only)* | The backing file the settings are loaded from and saved to. | + +### phrase options + +Passed verbatim to [Phrase.validate()](Phrase.md#validate) whenever the pipeline validates a definition. + +| フィールド | 型 | デフォルト | 説明 | +| ----------------- | ------- | ------- | ----------------------------------------------------------------------------------------------- | +| `allowRelations` | Boolean | `false` | Allow dot-notation through N:1 / 1:1 relations. | +| `allowCalculated` | Boolean | `false` | Allow calculated attributes in phrases. | +| `allowAlias` | Boolean | `false` | Allow alias attributes in phrases. | +| `allowObject` | Boolean | `false` | Allow object attributes in phrases. | + +> **Invalidation caveat.** Dirty-flag tracking only covers direct scalar fields on the entity. Fields that are only reachable through one of these options — a related entity's attribute, a calculated value, an alias, or a sub-property of an object — will **not** automatically mark the entity as dirty when they change. If such fields are part of a phrase and their source data changes, the vector will not be recomputed unless you call `invalidateVectors()` explicitly or use `force: true` when processing. + +### embedder options + +Controls how [Process](Process.md) builds its embedder. When absent, a default `Embedder` is created with its own defaults. + +| フィールド | 型 | デフォルト | 説明 | +| ------------ | ------- | ----- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `className` | Text | — | Name of a project class to instantiate instead of the built-in `Embedder`. The class must expose `embed` and `embedBatch` functions. If instantiation fails or the interface is missing, a diagnostic error is logged and the default `Embedder` is used as fallback. | +| `maxRetries` | Integer | `3` | Number of retry attempts on rate-limit errors (forwarded to `Embedder`). | +| `backoffMs` | Integer | `500` | Base back-off delay in ms, doubled each retry (forwarded to `Embedder`). | + +Any additional keys are forwarded as-is to the constructor of the target class (built-in or custom). + +## ファイル形式 + +```json +{ + "batchSize": 50, + "phrase": { + "allowRelations": false, + "allowCalculated": false, + "allowAlias": false, + "allowObject": false + }, + "embedder": { + "maxRetries": 5, + "backoffMs": 200 + }, + "definitions": [ + { + "dataclassName": "Students", + "vectorName": "student_vector_1", + "modelAlias": "text-embedding-3-small", + "phrase": "Student {firstName} {lastName}", + "autoInvalidate": true + } + ] +} +``` + +Each definition may include `autoInvalidate` (`true` by default) to control save-time automatic invalidation. + +The same file also carries the `scheduler` key (see [Scheduler](Scheduler.md#configuration)) and any other top-level key you add: `Settings` reads and rewrites only the keys listed above and leaves the rest untouched. + +With a custom embedder class: + +```json +{ + "embedder": { + "className": "MyCustomEmbedder" + }, + "definitions": [...] +} +``` + +## Class constructor + +Create a settings instance. The configuration file is loaded immediately. + +| 引数名 | 型 | 説明 | +| ------ | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| *ファイル* | 4D.File | 任意。 A file to use instead of the default location. The override applies process-wide for subsequent settings access. **Not supported in 4D Remote mode** — pass it only when running locally or on the server. | + +When *file* is omitted, the default location is used: `Settings/embeddings.json`, or the path given by the `EMBEDDINGS_SETTINGS_PATH` environment variable. + +```4d +// Default location +var $settings:=cs.EmbeddingStudio.Settings.new() + +// Custom file (server / mono only) +var $settings:=cs.EmbeddingStudio.Settings.new(File("/some/path/custom.json")) +``` + +## 関数 + +### load() + +**load**() + +Reload the backing file into memory, overwriting in-memory state. A missing file resets to defaults without raising. + +A file that **exists but cannot be parsed** also leaves the instance on defaults, but it is remembered: an error is logged and [`save()`](#save) then refuses to write, so a malformed file is never silently replaced by defaults. + +### save() + +**save**() : Boolean + +Serialize the current in-memory state to the backing file. Only the keys this class owns (`batchSize`, `phrase`, `embedder`, `definitions`) are written — every other top-level key present in the file (the `scheduler` configuration, model aliases…) is preserved as-is. A key whose value is back to its default is *removed* from the file rather than written. + +Definitions are merged with what the file holds at that instant, using the snapshot taken at load time as the common ancestor: two editors open at the same time no longer drop each other's definitions. + +| 戻り値 | 型 | 説明 | +| --- | ------- | ------------------------------------------------------------------------------------------------------------------------------ | +| 戻り値 | Boolean | `True` when written. `False` — nothing written — when the file could not be read at load time. | + +```4d +$settings.definitions.push(cs.EmbeddingStudio.Definition.new("Students"; "student_vector_1"; "text-embedding-3-small"; "{firstName}")) +$settings.batchSize:=100 +$settings.save() +``` + +### find() + +**find**(*dataclassName* : Text ; *vectorName* : Text) : [Definition](Definition.md) + +Look up the saved definition for the given dataclass/vector pair. + +| 引数 | 型 | 説明 | +| --------------- | --------------------------- | ------------------------------------------------------------------- | +| *dataclassName* | Text | データクラスの名称。 | +| *vectorName* | Text | Name of the vector field on that dataclass. | +| 戻り値 | [Definition](Definition.md) | The matching definition, or `Null` if none matches. | + +```4d +var $def:=$settings.find("Students"; "student_vector_1") +``` + +### findAll() + +**findAll**(*dataclassName* : Text) : Collection of [Definition](Definition.md) + +Return every saved definition configured for the given dataclass. + +| 引数 | 型 | 説明 | +| --------------- | ----------------------------------------- | --------------------------------------------------------------------------------------------- | +| *dataclassName* | Text | データクラスの名称。 | +| 戻り値 | Collection of [Definition](Definition.md) | All matching definitions (empty collection if none match). | + +```4d +var $defs:=$settings.findAll("Students") +// → every Students definition; used by Process.process(ds.Students) +``` + +### invalidateVectors() + +**invalidateVectors**() : Object + +Calls [`invalidateVectors()`](Definition.md#invalidatevectors) on every definition in `definitions` and merges the results into a single status object. + +| 引数 | 型 | 説明 | +| --- | ------ | ------------------------------------------------------------------------------------------------------------------------ | +| 戻り値 | Object | `{updated: Integer, skipped: Integer, errors: Collection of Text}` — accumulated across all definitions. | + +```4d +var $result:=cs.EmbeddingStudio.Settings.new().invalidateVectors() +// → { updated: 120; skipped: 0; errors: [] } +``` + +## 参照 + +- [Definition](Definition.md) +- [Process](Process.md) +- [Phrase](Phrase.md) From 565a85f3611ad2482b8658b33c4ebf23c670dc68 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:42:21 +0100 Subject: [PATCH 119/195] studioembedder.md Japanese --- .../Classes/StudioEmbedder.md | 125 ++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/StudioEmbedder.md diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/StudioEmbedder.md b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/StudioEmbedder.md new file mode 100644 index 00000000000000..02cd8721b57487 --- /dev/null +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/StudioEmbedder.md @@ -0,0 +1,125 @@ +--- +id: studioembedder +title: StudioEmbedder +--- + +# StudioEmbedder + +The `StudioEmbedder` class renders and embeds on demand, resolved against the Studio settings: a saved definition gives the phrase and the model, so the vector you compute matches the ones stored by [Process](Process.md). Nothing is persisted. Typical uses: building the vector of a search query, finding entities similar to a given one, or previewing the text sent for an entity. + +For the full batch pipeline that persists vectors on entities, see [Process](Process.md). + +## プロパティ + +| プロパティ名 | 型 | 説明 | +| ---------- | ----------------------- | ------------------------------------------------------------------------------------------------- | +| `設定` | [Settings](Settings.md) | The settings (vectors, batch size, phrase validation options). | +| `embedder` | [Embedder](Embedder.md) | The API-calling engine. Stateless and swappable. | +| `options` | Object | Runtime options object. | + +## Class constructor + +| 引数名 | 型 | 説明 | +| --------- | ----------------------- | ------------------------------------------------------------------------------------------------ | +| *設定* | [Settings](Settings.md) | 任意。 If omitted, settings are loaded from the default `Settings/embeddings.json`. | +| *options* | Object | Optional runtime options. Supports `embedder` for injection. | + +```4d +var $studioEmbedder:=cs.EmbeddingStudio.StudioEmbedder.new() +var $studioEmbedder:=cs.EmbeddingStudio.StudioEmbedder.new($settings) +var $studioEmbedder:=cs.EmbeddingStudio.StudioEmbedder.new($settings; {embedder: $mockEmbedder}) +``` + +## 関数 + +### render() + +**render**(*entity* : 4D.Entity ; *definitionOrPhrase* : Variant) : Text + +Return the text that [`embed()`](#embed) sends for an entity (the phrase rendered against it). No API call, no persistence. + +| 引数 | 型 | 説明 | +| -------------------- | ------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| *entity* | 4D.Entity | The entity to render against. | +| *definitionOrPhrase* | `Null`, [Phrase](Phrase.md), [Definition](Definition.md), Text, or plain object stub | `Null` → auto-resolve via settings (requires a unique match). Text → compiled as a throwaway `cs.EmbeddingStudio.Phrase`. Object stub → see [stub resolution](#stub-resolution). | +| 戻り値 | Text | The rendered text. | + +```4d +var $studioEmbedder:=cs.EmbeddingStudio.StudioEmbedder.new() +var $text: Text +$text:=$studioEmbedder.render($student; $def) // use def's phrase +$text:=$studioEmbedder.render($student; cs.EmbeddingStudio.Phrase.new("Hi {firstName}")) +$text:=$studioEmbedder.render($student; "Student: {lastName}") // raw template +$text:=$studioEmbedder.render($student) // auto-resolve +$text:=$studioEmbedder.render($student; {vectorName: "student_vector_1"}) // stub → saved definition's phrase +$text:=$studioEmbedder.render($student; {phrase: "Hi {firstName}"}) // ad-hoc stub → inline template +``` + +### embed() + +**embed**(*input* : Variant ; *context* : Variant ; *model* : Text) : [cs.EmbeddingStudio.EmbedderResult](EmbedderResult.md) + +Compute a vector for an arbitrary input, without persisting anywhere. + +| 引数 | 型 | 説明 | +| --------- | --------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| *input* | Text or 4D.Entity | Text → embedded directly. Entity → phrase rendered then embedded. | +| *context* | Text, [Phrase](Phrase.md), [Definition](Definition.md), Text template, plain object stub, or `Null` | Provides phrase and/or model depending on *input*. Object stub → see [stub resolution](#stub-resolution). | +| *model* | Text | Optional explicit model name. Used when *context* does not carry one. | +| 戻り値 | [EmbedderResult](EmbedderResult.md) | The embedding result (use `.vector` to get the 4D.Vector). | + +Throws if no model can be determined. + +```4d +var $studioEmbedder:=cs.EmbeddingStudio.StudioEmbedder.new() +var $vector: 4D.Vector + +// Text + model +$vector:=$studioEmbedder.embed("some text"; "text-embedding-3-small").vector + +// Text + definition (picks up def.modelAlias) +$vector:=$studioEmbedder.embed("some text"; $def).vector + +// Entity + definition (uses def.phrase + def.modelAlias) +$vector:=$studioEmbedder.embed($student; $def).vector + +// Entity + phrase + explicit model +$vector:=$studioEmbedder.embed($student; $phrase; "text-embedding-3-small").vector + +// Entity + ad-hoc template + model +$vector:=$studioEmbedder.embed($student; "Profile: {firstName} {lastName}"; "text-embedding-3-small").vector + +// Entity alone (auto-resolve, only when exactly one def matches the dataclass) +$vector:=$studioEmbedder.embed($student).vector + +// Entity + stub (deduces phrase + model from the matching saved definition) +$vector:=$studioEmbedder.embed($student; {vectorName: "student_vector_1"}).vector + +// Entity + ad-hoc stub (phrase compiled inline, model taken from the stub) +$vector:=$studioEmbedder.embed($student; {phrase: "Hi {firstName}"; modelAlias: "text-embedding-3-small"}).vector + +// Text + stub that only supplies the model +$vector:=$studioEmbedder.embed("some text"; {modelAlias: "text-embedding-3-small"}).vector +``` + +## Stub resolution + +Both `render()` and `embed()` accept a plain object in place of a `Phrase`/`Definition`. A stub is resolved the same way [`Process`](Process.md#definition-resolution-entity-context) resolves its `definition` argument, so the behavior matches. Two flavors are supported: + +| Stub | Resolves to | +| ------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `{vectorName: "..."}` (optionally `{dataclassName: "..."}`) | The matching **saved definition** for the entity's dataclass — deducing its phrase (and, for `embed`, its model). Resolves to nothing when there is no unique match. | +| `{phrase: "tpl {field}"}` or `{template: "tpl {field}"}` | An **ad-hoc** `Phrase` compiled inline; nothing is looked up. Pair with `{modelAlias: "..."}` to give `embed()` a model. | + +For `embed()`, the model is deduced in this order: an explicit `{modelAlias}` on the stub → the model of a stub-matched saved definition → the *model* argument → the entity's unique definition. An explicit `{modelAlias}` always wins. + +Unlike [`Process.process()`](Process.md#process-resolution), a stub is **not** turned into a brand-new `Definition` from its fields — `StudioEmbedder` persists nothing, so use `{phrase}`/`{template}` for one-off templates. + +## 参照 + +- [Process](Process.md) +- [Settings](Settings.md) +- [Definition](Definition.md) +- [Embedder](Embedder.md) +- [EmbedderResult](EmbedderResult.md) +- [Phrase](Phrase.md) From 9e5e483ed5d10c007e450143922630b674847333 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:42:24 +0100 Subject: [PATCH 120/195] license.md Japanese --- .../version-21-R5/embedding-studio/license.md | 167 ++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/license.md diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/license.md b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/license.md new file mode 100644 index 00000000000000..8f6fc0dd2b5ffc --- /dev/null +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/license.md @@ -0,0 +1,167 @@ +--- +id: license +title: SOFTWARE LICENSE AGREEMENT +--- + +# SOFTWARE LICENSE AGREEMENT + +## Preamble + +The purpose of this Software license agreement is to grant users the right to modify and re-use the software governed by this license. + +The exercising of this right is conditional upon the obligation to make /available to the community the modifications made to the source code of the software so as to contribute to its evolution. + +In consideration of access to the source code and the rights to copy, modify and redistribute granted by the license, users are provided only with a limited warranty and the software's author, the holder of the economic rights, and the successive licensors only have limited liability. + +## Article 1 – DEFINITIONS + +***Agreement***: means this license agreement, and its possible subsequent versions and annexes. + +***Software***: means the software in its Object Code and/or Source Code form and, where applicable, its documentation, "as is" when the Licensee accepts the Agreement. + +***Initial Software***: means the Software in its Source Code and possibly its Object Code form and, where applicable, its documentation, "as is" when it is first distributed under the terms and conditions of the Agreement. + +***Modified Software***: means the Software modified by at least one Integrated Contribution. + +***Source Code***: means all the Software's instructions and program lines to which access is required so as to modify the Software. + +***Object Code***: means the binary files originating from the compilation of the Source Code. + +***Holder***: means the holder(s) of the economic rights over the Initial Software, in this case it is 4D SAS. + +***Licensee***: means the Software user(s) having accepted the Agreement. + +***Contributor***: means a Licensee having made at least one Integrated Contribution. + +***Licensor***: means the Holder, or any other individual or legal entity, who distributes the Software under the Agreement. + +***Integrated Contribution***: means new functions integrated into the Source Code by any or all Contributors. + +***Parties***: mean both the Licensee and the Licensor. + +These expressions may be used both in singular and plural form. + +## Article 2 - PURPOSE + +The purpose of the Agreement is the grant by the Licensor to the Licensee of a non-exclusive, transferable and worldwide license for the Software as set forth in Article 5 hereinafter for the whole term of the protection granted by the rights over said Software. + +## Article 3 - ACCEPTANCE + +The Licensee shall be deemed as having accepted the terms and conditions of this Agreement upon the occurrence of the first of the following events: + +- loading the Software by any or all means, notably, by downloading from a remote server; +- the first time the Licensee exercises any of the rights granted hereunder. + +## Article 4 - EFFECTIVE DATE AND TERM + +### 4.1 EFFECTIVE DATE + +The Agreement shall become effective on the date when it is accepted by the Licensee as set forth in Article 3. + +### 4.2 TERM + +The Agreement shall remain in force for the entire legal term of protection of the economic rights over the Software. + +## Article 5 - SCOPE OF RIGHTS GRANTED + +The Licensor hereby grants to the Licensee, who accepts, the following rights over the Software for the term of the Agreement, on the basis of the terms and conditions set forth hereinafter. + +### 5.1 RIGHT OF USE + +The Licensee is authorized to use the Software, without any limitation as to its fields of application, with it being hereinafter specified that this comprises: + +- permanent or temporary reproduction of all or part of the Software by any or all means and in any or all form. +- loading, displaying, running, or storing the Software on any or all medium. +- entitlement to observe, study or test its operation. + +### 5.2 RIGHT OF MODIFICATION + +The right of modification means the right to adapt, arrange, or make any or all modifications to the Software; being understood that such modifications of the Software shall results in a change of its functionalities and/or in an addition of functionalities to the Initial Software. + +Consequently to distribute a Modified Software according to the provision of section 5.3.2, the Licensee shall make exclusively significant modification as described above to the Software provided that it includes an explicit notice that it is the author of said modification and indicates the date of the creation thereof. + +### 5.3 RIGHT OF DISTRIBUTION + +In particular, the right of distribution includes the right to publish, transmit and communicate the Modified Software to the general public on any or all medium, and by any or all means, and the right to market, either in consideration of a fee, or + +#### 5.3.1 DISTRIBUTION OF SOFTWARE WITHOUT MODIFICATION + +The Licensee is forbidden to distribute true copies of the Software in Source Code or Object Code form. + +#### 5.3.2 DISTRIBUTION OF MODIFIED SOFTWARE + +When the Licensee creates Modified Software, this Modified Software may be distributed provided that said distribution complies with all the provisions of the Agreement and subject to compliance with the requirement to include a notice concerning the rights over the Software as defined in Article 6.3. + +In the event the creation of the Modified Software, the Licensee undertakes that: + +- the resulting Modified Software will be governed by this Agreement, being understood that such Agreement shall be integrated in the Modified Software the Integrated Contributions in the resulting Modified Software will be clearly identified and documented, +- the Licensee will allow effective access to the source code of the Modified Software, at a minimum during the entire period of distribution of the Derivative Software, such that such modifications may be carried over in a subsequent version of the Software. +- the Modified Software must be renamed to exclude any reference to 4D. For example, it is expressly prohibited to distribute a Modified Software named “4D SVG”; Licensee shall rename the Modified Software such as “Name of the Licensee SVG”. Consequently, Licensee is expressly forbidden to use 4D’s product name in general to promote his modified work. + +## Article 6 - INTELLECTUAL PROPERTY + +### 6.1 OVER THE INITIAL SOFTWARE + +The Holder owns the intellectual property rights over the Initial Software. Any or all use of the Initial Software is subject to compliance with the terms and conditions under which the Holder has elected to distribute its work and no one shall be entitled to modify the terms and conditions for the distribution of said Initial Software. + +### 6.2 OVER THE INTEGRATED CONTRIBUTIONS + +The Licensee who develops an Integrated Contribution is the owner of the intellectual property rights over this Contribution as defined by applicable law. + +### 6.3 NOTICE OF RIGHTS + +The Licensee expressly undertakes: + +- not to remove, or modify, in any manner, the intellectual property notices attached to the Software; +- to reproduce said notices, in an identical manner, in the copies of the Software modified; +- to ensure that use of the Software, its intellectual property notices and the fact that it is governed by the Agreement is indicated in a text that is easily accessible, specifically from the interface of any Modified Software. + +The Licensee undertakes not to directly or indirectly infringe the intellectual property rights of the Holder on the Software and to take, where applicable, vis- à-vis its staff, any and all measures required to ensure respect of said intellectual property rights of the Holder. + +## Article 7 - RELATED SERVICES + +Under no circumstances shall the Agreement oblige the Licensor to provide technical assistance or maintenance services for the Software. + +However, the Licensor is entitled to offer this type of services. The terms and conditions of such technical assistance, and/or such maintenance, shall be set forth in a separate instrument. + +## Article 8 - DISCLAIMER OF WARRANTY. + +THERE IS NO WARRANTY FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE HOLDER PROVIDES THE SOFTWARE “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH LICENSEE. SHOULD THE SOFTWARE PROVE DEFECTIVE, LICENSEE ASSUMES THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +## Article 9 - LIMITATION OF LIABILITY + +TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE TO LICENSEE ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS AGREEMENT OR USE OF THE SOFTWARE, EVEN IF THE LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR DAMAGES. + +## Article 10 – TERMINATION + +### 10.1 + +In the event of a breach by the Licensee of its obligations hereunder, the Licensor may automatically terminate this Agreement thirty (30) days after notice has been sent to the Licensee and has remained ineffective. + +### 10.2 + +A Licensee whose Agreement is terminated shall no longer be authorized to use, modify or distribute the Software. However, any licenses that it may have granted prior to termination of the Agreement shall remain valid subject to their having been granted in compliance with the terms and conditions hereof. + +## Article 11 – MISCELLANEOUS + +### 11.1 + +Neither Party shall be liable for any or all delay, or failure to perform the Agreement, that may be attributable to an event of force majeure, an act of God or an outside cause, such as defective functioning or interruptions of the electricity or telecommunications networks, network paralysis following a virus attack, intervention by government authorities, natural disasters, water damage, earthquakes, fire, explosions, strikes and labor unrest, war, etc. + +### 11.2 + +Any failure by either Party, on one or more occasions, to invoke one or more of the provisions hereof, shall under no circumstances be interpreted as being a waiver by the interested Party of its right to invoke said provision(s) subsequently. + +### 11.3 + +In the event that one or more of the provisions hereof were to conflict with a current or future applicable act or legislative text, said act or legislative text shall prevail, and the Parties shall make the necessary amendments so as to comply with said act or legislative text. All other provisions shall remain effective. Similarly, invalidity of a provision of the Agreement, for any reason whatsoever, shall not cause the Agreement as a whole to be invalid. + +## Article 12 - GOVERNING LAW AND JURISDICTION + +### 12.1 + +The Agreement is governed by French law. The Parties agree to endeavor to seek an amicable solution to any disagreements or disputes that may arise during the performance of the Agreement. + +### 12.2 + +Failing an amicable solution within two (2) months as from their occurrence, and unless emergency proceedings are necessary, the disagreements or disputes shall be referred to the Versailles Courts having jurisdiction, by the more diligent Party. \ No newline at end of file From 0a68bf7427100a5e8bb76c838bbf3b5cfbe804c1 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:42:26 +0100 Subject: [PATCH 121/195] overview.md Japanese --- .../embedding-studio/overview.md | 211 ++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/overview.md diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/overview.md b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/overview.md new file mode 100644 index 00000000000000..9053d57312e94a --- /dev/null +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/overview.md @@ -0,0 +1,211 @@ +--- +id: overview +title: 4D-Embedding-Studio +--- + +# 4D-Embedding-Studio + +## 概要 + +4D Embedding Studio is a component for defining, processing, and maintaining AI embedding vectors directly in your 4D dataclass entities. + +You can use the component without writing a single line of code: select attributes from your dataclasses to construct the sentences to be vectorized and specify the model to use. For each entity, the component calls the embedding API and stores the resulting `4D.Vector` values. Configure the embedding scheduler to (re)calculate the vectors for your data at fixed intervals or on demand. + +You can then use the ORDA [`query()` by vector feature](https://developer.4d.com/docs/API/DataClassClass#query-by-vector-similarity) to request your data using semantics. + +If you want to have more control over your embeddings, the component offers an extensive API that allows you to customize each step of the data vectorization process, manage the scheduler, and integrate high-performance RAG (*Retrieval Augmented Generation*) features into your 4D application. + +## 要件 + +- [4D-AIKit](https://github.com/4d/4D-AIKit) (loaded automatically as a dependency). +- 4D project (21 R5 or later) with the following configuration: + - a valid model alias + - a dataclass with a `4D.Vector` attribute (object field at the database level). + +## Quick Start + +**1. Add a field of type Object to the table and associate it with the `4D.Vector` class.** +**2. Select **Embedding Studio...** in the **Design** menu to display the Embedding Studio window.** + +![menu](../assets/en/embedding-studio/menu.png) + +**3. For each listed `4D.Vector` attribute, write a descriptive phrase based upon attributes of the dataclass.** +Use the contextual menu to insert appropriate attributes. +This phrase will be vectorized for every entity. +**4. Select a model alias (or create a new one).** +**5. Select "Execute now" to launch the vectorization of your data or configure the scheduler.** + +## User Guide + +### Configuring the dataclass + +To use the 4D Embedding Studio interface, you need to create at least one object attribute associated to a `4D.Vector` class in your datastore. This must be done at the database level (only storage attributes can be embeddings). + +In the Structure editor, add an Object field to the dataclass (table) whose entities you want to query using AI and enter ["4D.Vector" as class](https://developer.4d.com/docs/Develop/structure-fields#class). + +#### Dirty-flag support + +In a production application, data is rarely static. If an embedding is based on an attribute value that has changed (e.g. a product description), it becomes obsolete and could no longer be relevant. By default, 4D automatically invalidates and flags for recalculation affected embeddings. + +If you do not use a dirty-flag field (see below), 4D simply replaces any invalidated vector by `Null`. It is therefore no longer used in searches until its next calculation. This option is suitable for applications that prioritize strict consistency: it is better to return no results than to rely on an embedding that no longer matches the current data. + +Or, you can add a Boolean field named `_dirty` (e.g. "myVector_dirty") to the structure. In this case, when an update is required, this field is set to `True`, and the associated vector is retained until it is recalculated. Your application can then choose to continue using this vector temporarily or exclude it using a filter on `dirty = False`. The flag is cleared automatically after a successful save. +This strategy promotes service continuity while allowing you to precisely identify vectors awaiting recalculation. If your business logic requires full control, you can also disable automatic invalidation and manage this lifecycle yourself. + +*Note: Certain modifications, such as a model changes, require vectors to be replaced immediately.* + +### Creating an embedding + +When you select **Embedding Studio...** in the **Design** menu, the Embedding Studio window is displayed. + +The list on the left side shows all `4D.Vector` class attributes defined in the datastore. You can add as many vector attributes as you want per dataclass. + +A check mark (✓) in the Dirty Flag column indicates that a [`_dirty` boolean field](#dirty-flag-support) is associated to the vector field. + +**Note:** Any change in the database structure will require that you restart the 4D application so that the 4D Embedding Studio lists up-to-date values. + +#### Writing a descriptive sentence + +To create or edit an embedding, select the attribute to configure in this list and write the embedding definition in the "Descriptive sentence" area on the right side. Use the associated menu to build the sentence and to add references to dataclass available attributes with the `{attribute_name}` syntax. + +The sentence must build a text that describes the entity just like a human would do it. The embedding could then capturate the semantics and not only attribute values. + +For example, for a `Product` dataclass with many attributes such as name and category, you could write: +"The {name} product is a {category} from the {brand} brand. Description: {description}. Key features: {features}." + +![menu](../assets/en/embedding-studio/studio-interface.png) + +### Selecting a model + +Once you have defined your vector attribute, choose the model to use for generating the embedding. The list of models includes the **model aliases** you defined in the [Project Settings](https://developer.4d.com/docs/settings/ai#model-aliases). + +The choice of model is important because it determines the relevance and quality of your embeddings. You’ll also need to provide this model with every query on the dataclass data so that the comparison is performed using the same model. + +### Auto-invalidate on save + +When this option is checked (default), embeddings are automatically invalidated when at least one of their definition attributes has been modified and the entity was successfully saved. + +However, you might want to handle invalidation in a custom way using the [4D Embedding Studio API](#api-guide). In this case, uncheck this option to disable the automatic mechanism. + +### Calculating embeddings + +Embeddings are calculated by sending a request to the AI model, which then returns the vectorization result, which is subsequently stored in the `4D.Vector` attribute in the dataclass. 4D automatically handles this operation and optimizes it by calculating only the necessary vectors. Each vector is processed independently. Thus, an error on one element does not interrupt the recalculation of the others. Elements that fail will be automatically retried during the next run. Recalculations are performed asynchronously, without blocking users. + +These calculations can be performed **on demand** or **scheduled at regular intervals** using the scheduler in the 4D Embedding Studio component. + +**Note:** You can also customize embedding calculations per dataclass or entity using the [4D Embedding Studio API](#api-guide). + +#### On demand + +To launch an embedding calculation, select **Run now** in the menu at the bottom of the 4D Embedding Studio window. This item is disabled if the datastore does not contain any embedding to calculate. When started, you can select **Cancel run** at any moment. + +#### スケジューラー + +You can configure the 4D Embedding Studio component scheduler to adjust the calculation frequency to suit your application’s needs. + +**Important:** The scheduler needs a 4D worker process to run. You can start it manually for testing purposes (**Start now** button in the scheduler dialog box) but to make sure a worker is available every times the application opens, you need to configure it. これには、次の二つの方法があります: + +- select the **Execute "On Host Database Event" method of the components** option in the [project Settings](https://developer.4d.com/docs/settings/security#options) +- or write the following code in your startup code: + +```4d + //at startup +cs.EmbeddingStudio.Scheduler.me.start() +``` + +The scheduler allows you can set the time interval between two calculations. Select the tab corresponding to your needs and click **Save**. + +- **Never**: the scheduler is off and never runs +- **At regular interval**: set the time interval between each calculation starting from a specified time. +- **Once a day**: the calculation takes place every day at a specific time + starting from a specific time. + +### Building queries with embeddings + +Once you have defined embeddings in your datastore, you can start [querying your dataclasses using AI-based features](https://developer.4d.com/docs/API/DataClassClass#query-by-vector-similarity). You just need to make sure that you use the same model for your embedding definition and in the query string. + +For example, assuming that: + +• you have defined a `4D.Vector` attribute named "product_vector" in the Products dataclass using a sentence: "The {name} is in the {category} category. It has these {features} features and can be used for {usage}." +• you want to find products that "can be used safely outside". + +以下のように書くことができます: + +```4d +// Retrieve the model alias from the embedding definition, configured in 4D Embedding Studio +var $settings:=cs.EmbeddingStudio.Settings.new() +var $definition:=$settings.find("Products"; "product_vector") + +// Compute the vector of the query with the same model +var $result:=cs.EmbeddingStudio.StudioEmbedder.new().embed("products that can be used safely outside"; $definition) +var $vector:=$result.vector + + //search with default metric (cosine) +var $products:=ds.Products.query("product_vector > :1 order by product_vector desc"; {vector : $vector}) + +``` + +If you use a dirty field, simply add a criterion to exclude vectors waiting to be recalculated: + +```4d +var $products:=ds.Products.query("product_vector > :1 and product_vector_dirty = false order by product_vector desc"; {vector : $vector}) +``` + +## API Guide + +### Quick start + +**1. Configure your vectors** in `Settings/embeddings.json`: + +```json +{ + "batchSize": 50, + "definitions": [ + { + "dataclassName": "Students", + "vectorName": "student_vector_1", + "modelAlias": "text-embedding", + "phrase": "Student {firstName} {lastName}, enrolled in {program}", + "autoInvalidate": true + } + ] +} +``` + +**2. Run the full pipeline** (all definitions, all records): + +```4d +var $p:=cs.EmbeddingStudio.Process.new() +var $r:=$p.process() + +If ($r.success) + ALERT("Updated "+String($r.entitiesUpdated)+" entities in "+String($r.duration)+" ms") +End if +``` + +**3. Process a single entity on save** (e.g. in a trigger or REST hook): + +```4d +var $p:=cs.EmbeddingStudio.Process.new() +$p.processEntity($entity) +``` + +### Class reference + +| Class | 説明 | +| ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [Process](Classes/Process.md) | Main orchestrator — entry point for all batch and entity operations. | +| [Scheduler](Classes/Scheduler.md) | Automated recalculation scheduler — background task, force/cancel, and runtime status. | +| [StudioEmbedder](Classes/StudioEmbedder.md) | Renders and embeds on demand using your saved definitions — e.g. to build a search query vector. Nothing is persisted. | +| [Settings](Classes/Settings.md) | Loads and saves the `embeddings.json` configuration file. | +| [Definition](Classes/Definition.md) | Describes one vector field: dataclass, field name, model alias, and phrase template. | +| [Embedder](Classes/Embedder.md) | Thin wrapper around the AIKit embeddings API with retry/backoff logic. | +| [EmbedderResult](Classes/EmbedderResult.md) | Typed wrapper normalizing API responses — vectors, usage metrics, rate-limit state. | +| [ProcessResult](Classes/ProcessResult.md) | Returned by every batch function — statistics and error breakdown. | +| [ProcessError](Classes/ProcessError.md) | Typed entry in `ProcessResult.errors` — scope, severity, code, ref, message, retryable. | +| [ProcessErrorCode](Classes/ProcessErrorCode.md) | Singleton catalogue of machine-readable error codes and their default severity/retryability. | +| [Phrase](Classes/Phrase.md) | Lightweight `{variable}` template engine used to build text from entity attributes. | + +### 参照 + +Blog post: [Vectorize your data effortlessly with 4D Embedding Studio](https://blog.4d.com/vectorize-your-data-effortlessly-with-4d-vector-studio) \ No newline at end of file From 51c1eb60555d055b98663eba2669e79fbef120ce Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 01:42:29 +0100 Subject: [PATCH 122/195] ratelimit.md Japanese --- .../embedding-studio/ratelimit.md | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/ratelimit.md diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/ratelimit.md b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/ratelimit.md new file mode 100644 index 00000000000000..00f50ec3d2bb7d --- /dev/null +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/ratelimit.md @@ -0,0 +1,65 @@ +--- +id: ratelimit +title: Rate Limiting +--- + +# Rate Limiting + +The embedding pipeline includes built-in rate-limit awareness. When the API provider returns rate-limit headers (as OpenAI does), the system automatically throttles requests and adapts batch sizes to stay within budget. Providers that don't return rate-limit headers (e.g. Ollama) are unaffected — the pipeline runs at full speed. + +## 動作 + +Each call to [`Embedder.embed()`](Classes/Embedder.md) or [`Embedder.embedBatch()`](Classes/Embedder.md) returns an [`EmbedderResult`](Classes/EmbedderResult.md) that carries rate-limit state alongside the embedding vectors. The pipeline uses this data in a three-step loop: + +1. **Pre-flight throttle** — before sending a batch, the pipeline checks whether the remaining token budget is sufficient. If not, it waits for the reset window to elapse before proceeding. +2. **Adaptive batch sizing** — the pipeline computes the largest batch that fits within 80% of the remaining token budget. This avoids hitting the ceiling while still making efficient use of the quota. +3. **State update** — after each API response, the pipeline records the new remaining budget, computes an average tokens-per-entity estimate, and feeds both into the next iteration. + +## Rate-limit fields on EmbedderResult + +These fields are populated from the API response headers. When a provider doesn't return them, they keep their defaults and the pipeline skips throttling. + +| フィールド | デフォルト | 意味 | +| ------------------- | ----- | ---------------------------------------------------------------------------------------------------------------------------------- | +| `remainingTokens` | `-1` | Tokens left in the current window. `-1` = unknown. | +| `remainingRequests` | `-1` | Requests left in the current window. | +| `limitTokens` | `0` | TPM (tokens per minute) ceiling. | +| `limitRequests` | `0` | RPM (requests per minute) ceiling. | +| `resetTokens` | `""` | Time until the token bucket refills (e.g. `"6m0s"`, `"200ms"`). | +| `resetRequests` | `""` | Time until the request bucket refills. | + +## Batch size adaptation + +The pipeline starts with the configured `batchSize` (from [Settings](Classes/Settings.md), default 50). After the first API response provides rate-limit data, the batch size may shrink: + +``` +nextBatchSize = min( floor(remainingTokens × 0.8 / tokensPerEntity), configBatchSize ) +``` + +- `tokensPerEntity` is estimated from the last chunk (`totalTokens / chunkSize`). +- The result is clamped to a floor of 1 and a ceiling of `configBatchSize`. +- When `remainingTokens` is unknown (`-1`), the configured batch size is used as-is. + +## Pre-flight wait + +Before each batch, the pipeline checks: + +- **Token budget**: if `remainingTokens < estimatedTokens × 1.1`, it waits for the token reset window. +- **Request budget**: if `remainingRequests = 0`, it waits for the request reset window. + +The reset durations are parsed from the API's string format (`"6m0s"` → 360 seconds, `"200ms"` → 1 second). + +## Providers without rate limits + +Some providers (Ollama, local models) don't return rate-limit headers. この場合において: + +- `remainingTokens` stays at `-1` (unknown) +- No throttling occurs — batches run at `configBatchSize` without waits +- The pipeline works identically to how it did before rate-limit support was added + +## 参照 + +- [EmbedderResult](Classes/EmbedderResult.md) — carries rate-limit fields +- [Embedder](Classes/Embedder.md) — wraps the API calls +- [Process](Classes/Process.md) — orchestrates the batch loop +- [Settings](Classes/Settings.md) — `batchSize` configuration From 116333e981cb104c51af011fbe3809bf4d46429a Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 11:47:07 +0100 Subject: [PATCH 123/195] dataclassclass.md French --- .../current/API/DataClassClass.md | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/API/DataClassClass.md b/i18n/fr/docusaurus-plugin-content-docs/current/API/DataClassClass.md index d7a157d1e8e383..46c030662a1a6d 100644 --- a/i18n/fr/docusaurus-plugin-content-docs/current/API/DataClassClass.md +++ b/i18n/fr/docusaurus-plugin-content-docs/current/API/DataClassClass.md @@ -636,42 +636,42 @@ La méthode projet ***SearchDuplicate*** recherche des valeurs dupliquées dans
-| Paramètres | Type | | Description | -| ---------- | ---------- | --------------------------- | --------------------------- | -| Résultat | Collection | <- | Collection of index objects | +| Paramètres | Type | | Description | +| ---------- | ---------- | --------------------------- | ------------------------- | +| Résultat | Collection | <- | Collection d'objets index |
#### Description -The `.getIndexes()` function returns a collection of all indexes related to the dataclass. +La fonction `.getIndexes()` retourne une collection de tous les index liés à la dataclass. -Each index is an object of the collection. Indexes are returned in the creation/modification order. An empty collection is returned if there is no index in the dataclass. +Chaque index est un objet de la collection. Les index sont retournés dans l'ordre de création/modification. Une collection vide est retournée s'il n'y a pas d'index dans la dataclass. **Collection retournée** -Each object of the returned collection has the following properties: +Chaque objet de la collection retournée contient les propriétés suivantes : -| Propriété | Type | Description | -| ---------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| type | Integer | Index type: -1 = Keywords, 0 = default, 1 = Standard B-Tree, 3 = Cluster B-Tree, 4 = Cosine, 5 = Dot, 6 = Euclidean. If the index is set to Automatic, the type property represents the type of the indexing algorithm used | -| automatic | Boolean | True if "automatic" index is selected | -| name | Text | Index name if defined | -| kind | Text | "keywords" if *keyword index* checked, otherwise "regular" | -| attributes | Collection | Index attribute or list of attributes (for composite index) | -| UUID | Text | Index UUID | -| uniqueKey | Boolean | True if index has the Unique key property | +| Propriété | Type | Description | +| ---------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| type | Integer | Type d'index : -1 = Mots-clés, 0 = Par défaut, 1 = B-Tree standard, 3 = B-Tree cluster, 4 = Cosinus, 5 = Produit scalaire, 6 = Euclidien. Si l'index est défini sur Automatique, la propriété type représente le type de l'algorithme d'indexation utilisé | +| automatic | Boolean | True si l'index "automatique" est sélectionné | +| name | Text | Nom de l'index si défini | +| kind | Text | "keywords" si *Index mots-clés* est coché, sinon "regular" | +| attributes | Collection | Attribut de l'index ou liste d'attributs (pour les index composites) | +| UUID | Text | UUID de l'index | +| uniqueKey | Boolean | True si l'index a la propriété Unique | :::tip Article(s) de blog sur le sujet -[Managing 4D Indexes Programmatically with getIndexes()](https://blog.4d.com/managing-4d-indexes-programmatically-with-getindexes) +[Gestion des index 4D par programmation à l’aide de la fonction getIndexes()](https://blog.4d.com/managing-4d-indexes-programmatically-with-getindexes) ::: #### Exemple -Considering the following table: +Considérant la table suivante : ![table-indexes](../assets/en/API/table-index.png) @@ -1342,7 +1342,7 @@ Voir [plus d'exemples ci-dessous](#example-4-2) (exemples 4 et 5). - [4D AI : Recherche d'entités par similarité vectorielle en 4D](https://blog.4d.com/4d-ai-searching-entities-by-vector-similarity-in-4d) - [4D AI : Tri des résultats d'une requête en fonction de la similarité vectorielle](https://blog.4d.com/4d-ai-sorting-query-results-by-vector-similarity/) -- [Why Your Search Stack Feels Broken — and How Vector Search Fixes It](https://blog.4d.com/why-your-search-stack-feels-broken-and-how-vector-search-fixes-it) +- [Pourquoi votre pile de recherche semble brisée – et comment Vector Search y remédie](https://blog.4d.com/why-your-search-stack-feels-broken-and-how-vector-search-fixes-it) ::: From 5bf1d2886c52a205191ac622f991423625762a58 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 11:50:24 +0100 Subject: [PATCH 124/195] udpsocketclass.md Japanese --- .../current/API/UDPSocketClass.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/API/UDPSocketClass.md b/i18n/ja/docusaurus-plugin-content-docs/current/API/UDPSocketClass.md index d33015ed99ac86..c7ca24f1434184 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/API/UDPSocketClass.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/API/UDPSocketClass.md @@ -50,7 +50,7 @@ UDPSocket オブジェクトは以下のプロパティと関数を提供しま | 引数 | 型 | | 説明 | | ------- | ---------------------------- | --------------------------- | ------------------------------------------------------------------------ | | port | Integer | -> | UDP ソケットに使用されるローカルのポート番号(0 または省略時には使用されていないポートを探して使用) | -| options | Object | -> | ソケットの接続[オプション](#options引数) | +| options | Object | -> | ソケットの接続[オプション](#options-引数) | | 戻り値 | 4D.UDPSocket | <- | 新規UDPSocket オブジェクト | From c23d1633f5df8635c3f7b841ea41af7fa3501916 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 11:51:02 +0100 Subject: [PATCH 125/195] websocketserverclass.md Japanese --- .../current/API/WebSocketServerClass.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/API/WebSocketServerClass.md b/i18n/ja/docusaurus-plugin-content-docs/current/API/WebSocketServerClass.md index 80c0e06aa26048..09d2a346b74a78 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/API/WebSocketServerClass.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/API/WebSocketServerClass.md @@ -37,7 +37,7 @@ WebSocketプロトコルは、WebSocketサーバーとクライアント (Webブ - サーバー接続を処理するためのユーザークラス - メッセージを処理するためのユーザークラス -接続を維持するため、[WebSocketサーバーの作成](#4dwebsocketservernew) は [ワーカー](../Develop/processes.md#worker-プロセス) 内にて行う必要があります。 +接続を維持するため、[WebSocketサーバーの作成](#4dwebsocketservernew) は [ワーカー](../Develop/processes.md#ワーカープロセス) 内にて行う必要があります。 [4D Webサーバー](WebServerClass.md) を起動しておく必要があります。 From 281534448817a2e282a9a8038ae49917572eeec5 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 11:53:36 +0100 Subject: [PATCH 126/195] methods.md Japanese --- .../current/Concepts/methods.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/Concepts/methods.md b/i18n/ja/docusaurus-plugin-content-docs/current/Concepts/methods.md index 6fceb51a31e39a..6779385e1814af 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/Concepts/methods.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/Concepts/methods.md @@ -5,7 +5,7 @@ title: メソッド メソッドとは、1つ以上の動作を実行するコードのことです。メソッドは、1つ以上のステートメントで構成されます。 -ステートメントは 1つの命令を実行し、単純な場合もあれば複雑な場合もあります。ステートメントとは通常、メソッドの 1行のことを指します (必要に応じて [`\` 文字を使って行を分割](quick-tour.md#行を分割する) することができます。 +ステートメントは 1つの命令を実行し、単純な場合もあれば複雑な場合もあります。ステートメントとは通常、メソッドの 1行のことを指します (必要に応じて [`\` 文字を使って行を分割](quick-tour.md#行を分割する)することができます)。 メソッドは最大 2GBのテキストまたは、32000行まで記述できます。 @@ -17,14 +17,14 @@ title: メソッド | ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **プロジェクトメソッド** | プロジェクトメソッド名が[呼び出された時](../Project/project-method-properties.md) に応じて | ◯ | 任意のアクションを実行するためのコードです。作成されたプロジェクトメソッドは、そのプロジェクトのランゲージの一部となります。 | | **オブジェクト (ウィジェット) メソッド** | メソッドが設定されたフォームオブジェクトに関連したイベント発生時に | × | フォームオブジェクト (ウィジェットとも呼びます) のプロパティです。 | -| **フォームメソッド** | メソッドが設定されたフォームに関連したイベント発生時に | × | フォームのプロパティです。フォームメソッドを使用してデータとオブジェクトを管理することができます。 ただし、これら目的には、オブジェクトメソッドを使用する方が通常は簡単であり、より効果的です。 | +| **フォームメソッド** | メソッドが設定されたフォームに関連したイベント発生時に | × | フォームのプロパティです。フォームメソッドを使用してデータとオブジェクトを管理することができます。ただし、これら目的には、オブジェクトメソッドを使用する方が通常は簡単であり、より効果的です。 | | **トリガー** (別名 *テーブルメソッド*) | テーブルのレコード操作 (追加・削除・修正) の度に | × | テーブルのプロパティです。トリガーは、データベースのレコードに対して「不正な」操作がおこなわれることを防ぎます。 | | **データベースメソッド** | 作業セッションのイベント発生時に | ○ (既定) | 4D には 16のデータベースメソッドがあります。 | | **クラス** | クラスのオブジェクトがインスタンス化されたとき、あるいは他のメソッドや[データベースフィールド](../Develop/field-properties.md#class) 内においてオブジェクトインスタンス上でクラスの関数が実行されたときに自動的に呼び出されます。 | ◯(クラス関数) | オブジェクトのクラスの[constructor](./classes.md#class-constructor), [properties](./classes.md#property) と[関数](./classes.md#function) を宣言および設定するためには、**Class** が使用されます。[**クラス**](classes.md) および[**Function** クラス](../API/FunctionClass.md) 参照。 | ## ランゲージトークン -4Dランゲージでは、コード内で使用される全てのオブジェクト名(定数、コマンド、テーブル、フィールドそしてキーワード) 全てに対してユニークな トークナイゼーションシステムというものを持っています。これらの名前をトークナイズするということは、それらをコードエディターにタイプする際に内部で絶対参照 (数値) として保存され、実行時、あるいは表示時にコンテキストに応じてテキストとして復元されるということを意味します。これにより、コードは常に正しく解釈されるということが保証され、テーブルやフィールドの名前を変更した場合でも、4Dランゲージコマンドが異なるアプリケーションのバージョンに置いて改名された場合等でも正しく解釈されます。 +4Dランゲージでは、コード内で使用される全てのオブジェクト名(定数、コマンド、テーブル、フィールドそしてキーワード) 全てに対してユニークな トークナイゼーションシステムというものを持っています。これらの名前をトークナイズするということは、それらをコードエディターにタイプする際に内部で絶対参照 (数値) として保存され、実行時、あるいは表示時にコンテキストに応じてテキストとして復元されるということを意味します。これにより、コードは常に正しく解釈されるということが保証され、テーブルやフィールドの名前を変更した場合でも、4Dランゲージコマンドが異なるアプリケーションのバージョンにおいて改名された場合等でも正しく解釈されます。 **注意:** これは環境設定のメソッドページの["リージョンシステム設定を使用"オプション](../Preferences/methods.md#4dプログラミングランゲージ-リージョンシステム設定を使う) を有効化し、お使いの4D を異なる言語設定でデータベースを開いた際にも、コードの自動翻訳が正確であることを保証します。 @@ -48,7 +48,7 @@ title: メソッド ### トークンシンタックス -式の中でトークナイズ可能な名前付き要素に対して、4D はトークンを直接参照するための特別な信託巣を提供しています。要素名の後に型(コマンド、フィールド、など)を指定する特定の接頭辞を追加し、そのあとに参照を追加します。以下の表にこのトークンシンタックスについての詳細がまとめてあります: +式の中でトークナイズ可能な名前付き要素に対して、4D はトークンを直接参照するための特別なシンタックスを提供しています。要素名の後に型(コマンド、フィールド、など)を指定する特定の接頭辞を追加し、そのあとに参照を追加します。以下の表にこのトークンシンタックスについての詳細がまとめてあります: | 機能 | 使用例(標準のシンタックス) | 接尾辞 | 使用例(トークンシンタックス) | コメント | | -------- | ------------------------------------------------------------------- | --------------------------------------- | ------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- | @@ -58,7 +58,7 @@ title: メソッド | フィールド | [Employees]Name | :xx | [Employees:1]Name:2 | xx はフィールド番号です | | 4D プラグイン | PV PRINT(area) | :Pxx:yy | PV PRINT:P13000:229(area) | xx はプラグインIDで、yy はコマンドのインデックスです | -**注意:** 接頭辞には大文字(C, P)を使用しなければなりません。そうでない場合には正常に解釈されません。 +**注意:** 接尾辞には大文字 (C, P) を使用しなければなりません。そうでない場合には正常に解釈されません。 このシンタックスを使用することにより、フォーミュラの名前が変更された場合でも、データベースが異なる言語において実行された場合でも、フォーミュラが正しく解釈される事を保証します。 From a3de5388f10c5b79ddf9e811c3f1be7c89d22c26 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 11:54:59 +0100 Subject: [PATCH 127/195] labels.md Japanese --- .../ja/docusaurus-plugin-content-docs/current/Desktop/labels.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/Desktop/labels.md b/i18n/ja/docusaurus-plugin-content-docs/current/Desktop/labels.md index 70073d18ad1a8d..29b65f2314faab 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/Desktop/labels.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/Desktop/labels.md @@ -164,7 +164,7 @@ title: ラベル var myVar+=1 ``` -3. プロジェクトメソッドに対して["コンポーネントとホストデータベース間で共有"](../Project/project-method-properties.md#コンポーネントとホストデータベース間で共有) オプションを設定します。 +3. プロジェクトメソッドに対して["コンポーネントとホストデータベース間で共有"](../Project/project-method-properties.md#コンポーネントとホストプロジェクト間で共有) オプションを設定します。 4. ラベルエディターを表示する前に、以下のコードを実行してプロジェクトメソッドが確実に許可されているようにします: From 70875ad890102db41db088df219235ac7266ab2e Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 11:55:23 +0100 Subject: [PATCH 128/195] preemptive.md French --- .../current/Develop/preemptive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/Develop/preemptive.md b/i18n/fr/docusaurus-plugin-content-docs/current/Develop/preemptive.md index 548b17b1d76767..f910900c7a523f 100644 --- a/i18n/fr/docusaurus-plugin-content-docs/current/Develop/preemptive.md +++ b/i18n/fr/docusaurus-plugin-content-docs/current/Develop/preemptive.md @@ -41,7 +41,7 @@ Le code 4D ne peut être exécuté dans un process préemptif que lorsque certai La propriété "thread safety" de chaque élément dépend de l'élément lui-même : -- Commandes 4D : la propriété thread-safe est une propriété interne. Dans la documentation 4D, les commandes thread-safe sont identifiées par l'icône ![](../assets/en/Develop/thread-safe.png). Vous pouvez également utiliser la commande [`Command name`](../commands/command-name) pour savoir si une commande est thread-safe. Une grande partie des commandes 4D peut s'exécuter en mode préemptif. +- Commandes 4D : la propriété thread-safe est une propriété interne. The 4D documentation indicates whether each command is thread-safe or not in the Properties section. Vous pouvez également utiliser la commande [`Command name`](../commands/command-name) pour savoir si une commande est thread-safe. Une grande partie des commandes 4D peut s'exécuter en mode préemptif. - Méthodes projet : les conditions pour être thread-safe sont répertoriées dans [ce paragraphe](#writing-a-thread-safe-method). Fondamentalement, le code à exécuter dans des threads préemptifs ne peut pas appeler des parties avec des interactions externes, telles que du code de plug-in ou des variables interprocess. Cependant, l'accès aux données est autorisé car le serveur de données 4D et ORDA prennent en charge l'exécution préemptive. From 83cb9ec89ce70db0e9b6ad2521dfdb8772199434 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 11:55:26 +0100 Subject: [PATCH 129/195] preemptive.md Spanish --- .../current/Develop/preemptive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/es/docusaurus-plugin-content-docs/current/Develop/preemptive.md b/i18n/es/docusaurus-plugin-content-docs/current/Develop/preemptive.md index 3d68172398d401..6d49343ef332ff 100644 --- a/i18n/es/docusaurus-plugin-content-docs/current/Develop/preemptive.md +++ b/i18n/es/docusaurus-plugin-content-docs/current/Develop/preemptive.md @@ -41,7 +41,7 @@ Dado que un hilo se maneja de forma independiente a partir del método del proce La propiedad "seguridad de hilo" de cada elemento depende del elemento en sí: -- Comandos 4D: hilo seguro es una propiedad interna. En la documentación de 4D, los comandos hilo seguro se identifican con el icono ![](../assets/en/Develop/thread-safe.png). También puede utilizar el comando [`Nombre del comando`](../commands/command-name) para saber si un comando es hilo seguro. Gran parte de los comandos 4D pueden ejecutarse en modo apropiativo. +- Comandos 4D: hilo seguro es una propiedad interna. The 4D documentation indicates whether each command is thread-safe or not in the Properties section. También puede utilizar el comando [`Nombre del comando`](../commands/command-name) para saber si un comando es hilo seguro. Gran parte de los comandos 4D pueden ejecutarse en modo apropiativo. - Métodos de proyecto: las condiciones para seguridad de hilo se listan en [este párrafo](#writing-a-thread-safe-method). Básicamente, el código que se ejecuta en hilos apropiativos no puede llamar a las partes con las interacciones externas, tal como el código plug-in o las variables interproceso. Los accesos a los datos, sin embargo, son permitidos desde el servidor de datos 4D que soporta la ejecución apropiativa. From 31faae807fcb1382c875dc71a45068060bd4ae39 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 11:55:29 +0100 Subject: [PATCH 130/195] preemptive.md Japanese --- .../current/Develop/preemptive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/Develop/preemptive.md b/i18n/ja/docusaurus-plugin-content-docs/current/Develop/preemptive.md index 8f3647df6fbe95..15b0b4faa7ef73 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/Develop/preemptive.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/Develop/preemptive.md @@ -41,7 +41,7 @@ title: プリエンプティブプロセス 要素毎の "スレッドセーフティ" プロパティは、その要素自身によります: -- 4Dコマンド: スレッドセーフティは内部プロパティです。 4D ドキュメンテーション内においては、スレッドセーフなコマンドには ![](../assets/en/Develop/thread-safe.png) アイコンが表示されています。 [`Command name`](../commands/command-name) コマンドを使用して、コマンドがスレッドセーフであるかどうかを知ることもできます。 4Dコマンドの大部分はプリエンプティブモードで実行可能です。 +- 4Dコマンド: スレッドセーフティは内部プロパティです。 The 4D documentation indicates whether each command is thread-safe or not in the Properties section. [`Command name`](../commands/command-name) コマンドを使用して、コマンドがスレッドセーフであるかどうかを知ることもできます。 4Dコマンドの大部分はプリエンプティブモードで実行可能です。 - プロジェクトメソッド: スレッドセーフであるための条件は [こちらの段落](#スレッドセーフなメソッドの書き方) にまとめられています。 原則として、プリエンプティブスレッド内で実行されるコードは外部との相互作用する部分、たとえばプラグインコードやインタープロセス変数などを呼び出すことはできません。しかしながら、4Dデータサーバーと ORDA はプリエンプティブ実行をサポートしていることから、データアクセスは可能です。 From 58419be9ec4b54a7cc951bb218dec5cea0593f03 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 11:55:34 +0100 Subject: [PATCH 131/195] processes.md Japanese --- .../docusaurus-plugin-content-docs/current/Develop/processes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/Develop/processes.md b/i18n/ja/docusaurus-plugin-content-docs/current/Develop/processes.md index d7eb693b4a3da8..65c53df3caa564 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/Develop/processes.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/Develop/processes.md @@ -50,7 +50,7 @@ title: プロセスとワーカー ### インターフェース要素 -インターフェース要素は、[デスクトップアプリケーション](../category/desktop-applications) で使用されます。 以下のものがあります: 以下のものがあります: +インターフェース要素は、[デスクトップアプリケーション](../category/desktop-applications) で使用されます。以下のものがあります: - [メニューバー](../Menus/creating.md): 各プロセスは、独自のカレントメニューバーを持つことができます。最前面のプロセスのメニューバーがアプリケーションのカレントメニューバーになります。 - 1つ以上のウィンドウ: 各プロセスは、1つまたは複数のウィンドウを同時に開くことができます。他方、ウィンドウをまったく持たないプロセスもあります。 From d77f0a07f8712b7d6c8962fadf689c5b35876e63 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 11:59:33 +0100 Subject: [PATCH 132/195] createstylesheet.md Japanese --- .../current/FormEditor/createStylesheet.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/FormEditor/createStylesheet.md b/i18n/ja/docusaurus-plugin-content-docs/current/FormEditor/createStylesheet.md index 7437841e5f8e7e..259036be4d84d9 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/FormEditor/createStylesheet.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/FormEditor/createStylesheet.md @@ -101,7 +101,7 @@ text, input { } ``` -### Class +### クラス CSS の **クラスセレクター**と同様に、スタイルの適用対象をフォームオブジェクトの `class` 属性で指定することができます。 @@ -126,7 +126,7 @@ text.center { } ``` -4D フォームの詳細では、[CSSクラス](../FormObjects/properties_Object.md#cssクラス) 属性を使用してクラス名を割り当てます。この属性には一つ以上のクラス名を指定することができます。 複数の場合はクラス名を半角スペースで区切ります: +4D フォームの詳細では、[CSSクラス](../FormObjects/properties_Object.md#cssクラス) 属性を使用してクラス名を割り当てます。この属性には一つ以上のクラス名を指定することができます。複数の場合はクラス名を半角スペースで区切ります: ```css class: "okButtons important" From 3c06c58bc4355920cee6bb9f8bd53614457a3d09 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 12:02:42 +0100 Subject: [PATCH 133/195] properties_backgroundandborder.md Japanese --- .../properties_BackgroundAndBorder.md | 67 ++++++++++++------- 1 file changed, 43 insertions(+), 24 deletions(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/properties_BackgroundAndBorder.md b/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/properties_BackgroundAndBorder.md index 074e0f42fd35e1..c98697bfd7bd99 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/properties_BackgroundAndBorder.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/properties_BackgroundAndBorder.md @@ -111,11 +111,11 @@ title: 背景色と境界線 デフォルトで、これらのオブジェクトの境界線カラーは自動的に[**フォントカラー**](./properties_Text.md#フォントカラー) プロパティと同じに設定されています。このデフォルトの設定はプロパティリストの**Same as font** オプションに対応しています(`borderColor` プロパティはJSON では未定義です)。 これらの二つのプロパティはオブジェクトの"境界線カラー" プロパティ([**境界線スタイル**](#border-line-style) プロパティが**実線** (JSON プロパティでは`solid`) あるいは **点線**のときのみ利用可能) にカラー値を設定することで分離させることができます。 -- **objects without text properties**: [4D View Pro areas](viewProArea_overview.md), [4D Write Pro areas](writeProArea_overview.md), [button grids](buttonGrid_overview.md), [picture buttons](pictureButton_overview.md), [picture pop-up menus](picturePopupMenu_overview.md), [plug-in areas](pluginArea_overview.md), [subforms](subform_overview.md), [spinners](spinner.md), [splitters](splitters.md), [steppers](stepper.md), [web areas](webArea_overview.md). - The border color property sets the color of the borders. The default color value is "Automatic", i.e. the border is displayed with the automatic color set by your OS. +- **テキストプロパティを持たないオブジェクト**: [4D View Pro エリア](viewProArea_overview.md)、[4D Write Pro エリア](writeProArea_overview.md)、[ボタングリッド](buttonGrid_overview.md)、[ピクチャーボタン](pictureButton_overview.md)、[ピクチャーポップアップメニュー](picturePopupMenu_overview.md)、[プラグインエリア](pluginArea_overview.md)、[サブフォーム](subform_overview.md)、[スピナー](spinner.md)、[スプリッター](splitters.md)、[ステッパー](stepper.md)、[Web エリア](webArea_overview.md)。 + 境界線カラープロパティは境界線のカラーを設定します。デフォルトのカラー値は"自動"で、これは境界線がOS によって設定されている自動カラーで表示されることを意味します。 -- **custom-styled buttons**: [custom buttons](./button_overview.md#custom) with ["custom" Border Line Style](#border-line-style), [custom check boxes](./checkbox_overview.md#custom), and [custom radio buttons](./radio_overview.md#custom). - In this case, the border color property defines the color of an *inner* border, which is an attribute of the object itself ans not a decoration property. This inner border can also have a [width](#border-width) (it is displayed only if the width > 0). +- **カスタムスタイルのボタン**: ["カスタム" 境界線スタイル](#border-line-style)をもった[カスタムボタン](./button_overview.md#カスタム)、[カスタムチェックボックス](./checkbox_overview.md#カスタム)、および[カスタムラジオボタン](./radio_overview.md#カスタム)。 + この場合、境界線カラープロパティーは*内側の* 境界線カラーを定義し、これはオブジェクト自身の属性であり、装飾プロパティではありません。内側の境界線は[幅](#border-width) を持つこともできます(幅が0 より大きい場合にのみ表示されます)。 #### JSON 文法 @@ -125,7 +125,26 @@ title: 背景色と境界線 #### 対象オブジェクト -[4D View Pro area](viewProArea_overview.md) - [4D Write Pro area](writeProArea_overview.md) - [Button](./button_overview.md) - [Button Grid](buttonGrid_overview.md) - [Check Box ("custom" style)](checkbox_overview.md#custom) - [Hierarchical List](list_overview.md) - [Input](input_overview.md) - [List Box](listbox_overview.md) - [Picture Button](pictureButton_overview.md) - [Picture Pop-up Menu](picturePopupMenu_overview.md) - [Plug-in Area](pluginArea_overview.md) - [Progress Indicator](./progressIndicator.md) - [Radio Button ("custom" style)](radio_overview.md#custom) - [Ruler](./ruler.md) - [Text Area](text.md) - [Spinner](spinner.md) - [Splitter](splitters.md) - [Stepper](stepper.md) - [Subform](subform_overview.md) - [Web Area](webArea_overview.md) +[4D View Pro エリア](viewProArea_overview.md) - +[4D Write Pro エリア](writeProArea_overview.md) - +[ボタン](button_overview.md) - +[ボタングリッド](buttonGrid_overview.md) - +[チェックボックス("カスタム"スタイル)](checkbox_overview.md#custom) - +[階層リスト](list_overview.md) - +[入力](input_overview.md) - +[リストボックス](listbox_overview.md) - +[ピクチャーボタン](pictureButton_overview.md) - +[ピクチャーポップアップメニュー](picturePopupMenu_overview.md) - +[プラグインエリア](pluginArea_overview.md) - +[進捗インジケーター](progressIndicator.md) - +[ラジオボタン("カスタム"スタイル)](radio_overview.md#custom) - +[ルーラー](ruler.md) - +[テキストエリア](text.md) - +[スピナー](spinner.md) - +[Splitter](splitters.md) - +[ステッパー](stepper.md) - +[サブフォーム](subform_overview.md) - +[Web エリア](webArea_overview.md) #### コマンド @@ -133,25 +152,25 @@ title: 背景色と境界線 #### 参照 -[Line Color](#line-color) (for shapes) +[線カラー](#線カラー) (図形用) ## 境界線スタイル{#border-line-style} -Allows setting a style for the object border. The following choices are available (all choices are not possible depending on the object): +オブジェクトの境界線のスタイルを設定することができます。以下の選択肢が利用可能です(オブジェクトによっては全ての選択肢が利用可能ではないこともあります): -| Style | Objects (\*) | 説明 | -| -------------- | -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| なし | all | Objects appear with no border. | -| Plain | all | Objects appear framed with a continuous 1-pt. border line. ("solid" json value) | -| Dotted | all | Objects appear framed with a dotted 1-pt. border line. | -| Raised | all | Objects appear framed with a 3D effect. | -| Sunken | all | Objects appear framed with a sunken 3D effect. | -| Double | all | Objects appear framed with a double line, i.e., two continuous 1-pt. lines separated by a pixel. | -| System | all *except* [buttons](button_overview.md) and [text areas](text.md) | Objects appear with a border line based on the graphic specifications of the OS. | -| System rounded | [inputs](input_overview.md) | On macOS, objects appear with a native "Liquid Glass" system border effect (for information about Liquid Glass, see [this 4D blog post](https://blog.4d.com/the-new-macos-tahoe-design-comes-to-your-4d-applications/)). It includes system-defined inner border, corner radius, grey border color, and inner padding. Note that the "Liquid Glass" appearance is *not* used in a multiline input object if the [scroll bars property](./properties_Appearance.md#vertical-scroll-bar) is enabled ("System" is used in this case).
On Windows, this style is similar to "System" at runtime. | -| カスタム | [custom buttons](./button_overview.md#custom) | Enables the inner border design, that includes a set of extra properties: [Fill color](#fill-color), [Border color](#border-color), [Border width](#border-width), and [Corner radius](#corner-radius).
![](../assets/en/FormObjects/custom-button.png) | +| スタイル | オブジェクト(\*) | 説明 | +| --------- | --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| なし | all | オブジェクトは境界線なしで表示されます。 | +| 標準 | all | オブジェクトは連続した1pt の幅の境界線で表示されます。 ("solid" json 値) | +| ドット | all | オブジェクトは点線の1pt の幅の境界線で表示されます。 | +| 浮き上がり | all | オブジェクトは3D エフェクトの境界線で表示されます。 | +| くぼみ | all | オブジェクトは、くぼみ3D エフェクトの境界線で表示されます。 | +| 二重 | all | オブジェクトは連続した1pt の幅の二重線の境界線で表示されます。二重線は1ピクセル間の隙間で表示されます。 | +| システム | [ボタン](button_overview.md)および [テキストエリア](text.md) を *除く* 全て | オブジェクトはOS のグラフィック仕様に基づいた境界線で表示されます。 | +| システムの角の丸み | [入力](input_overview.md) | macOS では、オブジェクトはネイティブの"Liquid Glass" システム境界線エフェクトで表示されます(Liquid Glass についての情報については[こちらの4D blog 記事](https://blog.4d.com/the-new-macos-tahoe-design-comes-to-your-4d-applications/))。これにはシステム定義の内側の境界線、角の半径、グレーの境界線カラー、そして内側のパディングが含まれます。[スクロールバープロパティ](./properties_Appearance.md#縦スクロールバー) が有効化されている複数行の入力オブジェクト内においてはアピアランスは使用されないという点に注意してください(この場合には"システム"が使用されます)。
Windows においては、このスタイルはランタイムでは"システム" に似たスタイルで表示されます。 | +| カスタム | [カスタムボタン](./button_overview.md#カスタム) | 内側の境界線デザインを有効化し、これには以下の追加のプロパティのセットが含まれます: [塗りカラー](#背景色-塗りカラー)、[境界線カラー](#border-color)、[境界線幅](#border-width)、および[角の半径](#角の半径)。
![](../assets/en/FormObjects/custom-button.png) | -(\*) "all" means "all objects supported" listed below. +(\*) この"all" または"全て" とは、以下の"サポートされる全てのオブジェクト" を意味します。 :::tip 関連したblog 記事 @@ -165,7 +184,7 @@ Allows setting a style for the object border. The following choices are availabl | 名称 | データタイプ | とりうる値 | | ----------- | ------ | -------------------------------------------------------------------------------------------- | -| borderStyle | text | "custom", "dotted", "double", "none", "raised", "solid", "sunken", "system", "systemRounded" | +| borderStyle | text | "custom"、 "dotted"、 "double"、 "none"、 "raised"、 "solid"、 "sunken"、 "system"、 "systemRounded" | #### 対象オブジェクト @@ -193,7 +212,7 @@ Allows setting a style for the object border. The following choices are availabl #### 参照 -[Dotted Line Type](#dotted-line-type) (shapes) +[点線タイプ](#dotted-line-type) (図形) --- @@ -217,7 +236,7 @@ Allows setting a style for the object border. The following choices are availabl #### 対象オブジェクト -[Button ("custom" style)](./button_overview.md#custom) (with ["custom" Border Line Style](#border-line-style)) - [Check Box ("custom style")](checkbox_overview.md#custom) - [Radio Button ("custom" style)](radio_overview.md#custom) +(["カスタム" 境界線スタイル](#border-line-style)を持った)[ボタン("カスタム"スタイル)](./button_overview.md#カスタム) - [チェックボックス("カスタムスタイル")](checkbox_overview.md#カスタム) - [ラジオボタン("カスタム" スタイル)](radio_overview.md#カスタム) --- @@ -258,7 +277,7 @@ Allows setting a style for the object border. The following choices are availabl #### 対象オブジェクト -[Button ("custom" style)](./button_overview.md#custom) (with ["custom" Border Line Style](#border-line-style)) - [Check Box ("custom" style)](checkbox_overview.md#custom) - [Input](input_overview.md) - [Rectangle](shapes_overview.md#rectangle) - [Text Area](text.md) - [Radio Button ("custom" style)](radio_overview.md#custom) +(["カスタム"境界線スタイル](#border-line-style)を持った)[ボタン("カスタム"スタイル)](./button_overview.md#カスタム) - [チェックボックス("カスタム" スタイル)](checkbox_overview.md#カスタム) - [入力](input_overview.md) - [四角形](shapes_overview.md#四角形) - [テキストエリア](text.md) - [ラジオボタン("カスタム" スタイル)](radio_overview.md#カスタム) #### コマンド @@ -326,7 +345,7 @@ Allows setting a style for the object border. The following choices are availabl :::note -This property is also available for objects with text properties, in which case it designates both the [Font color](properties_Text.md#font-color) and the object's lines, except if you used the [Border color](#border-color) property. +このプロパティはテキストプロパティを持つオブジェクトでも利用可能で、その場合には[フォントカラー](properties_Text.md#フォントカラー) とオブジェクトの線の両方を指定します(ただし[境界線カラー](#border-color) プロパティを使用していた場合を除く)。 ::: From 301a2178e5f0d4b00b5422cb9423733e00f08981 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 12:02:59 +0100 Subject: [PATCH 134/195] properties_datasource.md Japanese --- .../current/FormObjects/properties_DataSource.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/properties_DataSource.md b/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/properties_DataSource.md index eb65c9a24b8189..a49a59fa28efef 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/properties_DataSource.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/FormObjects/properties_DataSource.md @@ -330,7 +330,7 @@ title: データソース 使用する命名セレクションを指定します。有効な命名セレクションの名前を入力しなければなりません。使用できるのはプロセスあるいはインタープロセス命名セレクションです。リストボックスの内容はこのセレクションに基づきます。選択された命名セレクションは、リストボックスが表示される時点で存在し、有効でなければなりません。 そうでない場合、リストボックスは空で表示されます。 -> 命名セレクションはソート済みのレコードリストです。これはセレクション中のカレントレコードと並び順をメモリに保持するために使用されます。 For more information, refer to [**Named Selections**](../Develop/named-selections) section. +> 命名セレクションはソート済みのレコードリストです。これはセレクション中のカレントレコードと並び順をメモリに保持するために使用されます。詳細な情報については、[**命名セレクション**](../Develop/named-selections) の章を参照してください。 #### JSON 文法 From 9915704bfdc1eba663706905265aff2d4c5e8f7a Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 12:07:37 +0100 Subject: [PATCH 135/195] privileges.md French --- .../current/ORDA/privileges.md | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/ORDA/privileges.md b/i18n/fr/docusaurus-plugin-content-docs/current/ORDA/privileges.md index b0546d9c3b278d..f5c2fc4526cfb2 100644 --- a/i18n/fr/docusaurus-plugin-content-docs/current/ORDA/privileges.md +++ b/i18n/fr/docusaurus-plugin-content-docs/current/ORDA/privileges.md @@ -39,6 +39,40 @@ The **execute** permission of a [shared singleton](../Concepts/classes.md#shared Permissions never apply to [desktop session code](../Desktop/sessions.md) (standalone, client/server, stored procedures) or [tool4d](../Admin/cli.md#tool4d). +:::warning + +When a permission entry references an undeclared [privilege](#privileges-and-roles), 4D logs an error and ignores the entry. In this case, the permission is ignored. If the [restricted mode by default](#restriction-modes) is not enabled, the resource is accessible to `guest` sessions. + +::: + +### MCP tools + +The same permissions apply to the sessions of the [MCP server](../WebServer/mcp-server.md), with nothing specific to configure: + +- A [custom tool](../WebServer/mcp-server.md#custom-tools) (`exposed MCP Function`) requires the **execute** permission on its function, and benefits from its **promote** permission. +- The [built-in CRUD tools](../WebServer/mcp-server.md#built-in-crud-tools) require the **read**, **create**, **update**, or **drop** permission on the dataclass, and the attribute permissions apply. Each attribute of a path used in a filter, a sort, or a projection requires the **read** permission. +- The CRUD tools are listed only if the session has at least one data permission on a dataclass, and the `describeModel` tool only describes the dataclasses on which the session has a data permission, with their readable or writable attributes. +- A tool, a dataclass, or an attribute that the session cannot access is reported as if it did not exist. + +#### Exemple + +MCP clients authenticated with the "salesReader" privilege can read the Customer and Order dataclasses with the CRUD tools, and call the tools published by the `OrderManager` singleton (for example `OrderManager-getYearTotal`): + +```json +{ + "privileges": [{"privilege": "salesReader", "includes": []}], + "roles": [], + "permissions": { + "allowed": [ + {"applyTo": "Customer", "type": "dataclass", "read": ["salesReader"]}, + {"applyTo": "Order", "type": "dataclass", "read": ["salesReader"]}, + {"applyTo": "OrderManager", "type": "singleton", "execute": ["salesReader"]} + ] + }, + "restrictedByDefault": true +} +``` + ### MCP tools The same permissions apply to the sessions of the [MCP server](../WebServer/mcp-server.md), with nothing specific to configure: From 95e973a00cd68355ac39e2117f36414ba0242c35 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 12:07:40 +0100 Subject: [PATCH 136/195] privileges.md Spanish --- .../current/ORDA/privileges.md | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/i18n/es/docusaurus-plugin-content-docs/current/ORDA/privileges.md b/i18n/es/docusaurus-plugin-content-docs/current/ORDA/privileges.md index 20820d21a5773b..1994b1debf07f8 100644 --- a/i18n/es/docusaurus-plugin-content-docs/current/ORDA/privileges.md +++ b/i18n/es/docusaurus-plugin-content-docs/current/ORDA/privileges.md @@ -39,6 +39,40 @@ The **execute** permission of a [shared singleton](../Concepts/classes.md#shared Permissions never apply to [desktop session code](../Desktop/sessions.md) (standalone, client/server, stored procedures) or [tool4d](../Admin/cli.md#tool4d). +:::warning + +When a permission entry references an undeclared [privilege](#privileges-and-roles), 4D logs an error and ignores the entry. In this case, the permission is ignored. If the [restricted mode by default](#restriction-modes) is not enabled, the resource is accessible to `guest` sessions. + +::: + +### MCP tools + +The same permissions apply to the sessions of the [MCP server](../WebServer/mcp-server.md), with nothing specific to configure: + +- A [custom tool](../WebServer/mcp-server.md#custom-tools) (`exposed MCP Function`) requires the **execute** permission on its function, and benefits from its **promote** permission. +- The [built-in CRUD tools](../WebServer/mcp-server.md#built-in-crud-tools) require the **read**, **create**, **update**, or **drop** permission on the dataclass, and the attribute permissions apply. Each attribute of a path used in a filter, a sort, or a projection requires the **read** permission. +- The CRUD tools are listed only if the session has at least one data permission on a dataclass, and the `describeModel` tool only describes the dataclasses on which the session has a data permission, with their readable or writable attributes. +- A tool, a dataclass, or an attribute that the session cannot access is reported as if it did not exist. + +#### Ejemplo + +MCP clients authenticated with the "salesReader" privilege can read the Customer and Order dataclasses with the CRUD tools, and call the tools published by the `OrderManager` singleton (for example `OrderManager-getYearTotal`): + +```json +{ + "privileges": [{"privilege": "salesReader", "includes": []}], + "roles": [], + "permissions": { + "allowed": [ + {"applyTo": "Customer", "type": "dataclass", "read": ["salesReader"]}, + {"applyTo": "Order", "type": "dataclass", "read": ["salesReader"]}, + {"applyTo": "OrderManager", "type": "singleton", "execute": ["salesReader"]} + ] + }, + "restrictedByDefault": true +} +``` + ### MCP tools The same permissions apply to the sessions of the [MCP server](../WebServer/mcp-server.md), with nothing specific to configure: From f826f6696d648e74dcef142ee96013ba3eacaf94 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 12:07:44 +0100 Subject: [PATCH 137/195] privileges.md Japanese --- .../current/ORDA/privileges.md | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/ORDA/privileges.md b/i18n/ja/docusaurus-plugin-content-docs/current/ORDA/privileges.md index fa88580e5159f8..c847cf6200c088 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/ORDA/privileges.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/ORDA/privileges.md @@ -39,6 +39,40 @@ The **execute** permission of a [shared singleton](../Concepts/classes.md#shared Permissions never apply to [desktop session code](../Desktop/sessions.md) (standalone, client/server, stored procedures) or [tool4d](../Admin/cli.md#tool4d). +:::warning + +When a permission entry references an undeclared [privilege](#privileges-and-roles), 4D logs an error and ignores the entry. In this case, the permission is ignored. If the [restricted mode by default](#restriction-modes) is not enabled, the resource is accessible to `guest` sessions. + +::: + +### MCP tools + +The same permissions apply to the sessions of the [MCP server](../WebServer/mcp-server.md), with nothing specific to configure: + +- A [custom tool](../WebServer/mcp-server.md#custom-tools) (`exposed MCP Function`) requires the **execute** permission on its function, and benefits from its **promote** permission. +- The [built-in CRUD tools](../WebServer/mcp-server.md#built-in-crud-tools) require the **read**, **create**, **update**, or **drop** permission on the dataclass, and the attribute permissions apply. Each attribute of a path used in a filter, a sort, or a projection requires the **read** permission. +- The CRUD tools are listed only if the session has at least one data permission on a dataclass, and the `describeModel` tool only describes the dataclasses on which the session has a data permission, with their readable or writable attributes. +- A tool, a dataclass, or an attribute that the session cannot access is reported as if it did not exist. + +#### 例題 + +MCP clients authenticated with the "salesReader" privilege can read the Customer and Order dataclasses with the CRUD tools, and call the tools published by the `OrderManager` singleton (for example `OrderManager-getYearTotal`): + +```json +{ + "privileges": [{"privilege": "salesReader", "includes": []}], + "roles": [], + "permissions": { + "allowed": [ + {"applyTo": "Customer", "type": "dataclass", "read": ["salesReader"]}, + {"applyTo": "Order", "type": "dataclass", "read": ["salesReader"]}, + {"applyTo": "OrderManager", "type": "singleton", "execute": ["salesReader"]} + ] + }, + "restrictedByDefault": true +} +``` + ### MCP tools The same permissions apply to the sessions of the [MCP server](../WebServer/mcp-server.md), with nothing specific to configure: From 217fc91cf1f1a0f847d9ee48add2aac39d77f78c Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 13:23:57 +0100 Subject: [PATCH 138/195] client-server.md French --- .../current/settings/client-server.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/settings/client-server.md b/i18n/fr/docusaurus-plugin-content-docs/current/settings/client-server.md index 28de1150c14efa..7b182cb2eb6684 100644 --- a/i18n/fr/docusaurus-plugin-content-docs/current/settings/client-server.md +++ b/i18n/fr/docusaurus-plugin-content-docs/current/settings/client-server.md @@ -135,7 +135,7 @@ Ce paramètre permet de définir globalement le mode de mise à jour de l'instan - **Jamais** : Le dossier **Resources** local n'est pas mis à jour pendant la session. La notification envoyée par le serveur est ignorée. Le dossier **Resources** local peut être mis à jour manuellement à l'aide de la commande **Update Local Resources** du menu d'action (voir [Utilisation de l'explorateur de ressources](https://doc.4d.com/4Dv20/4D/20.2/Using-the-Resources-explorer.300-6750254.en.html)). - **Toujours** : La synchronisation du dossier local **Resources** est automatiquement effectuée pendant la session chaque fois qu'une notification est envoyée par le serveur. - **Demander** : Lorsque la notification est envoyée par le serveur, une boîte de dialogue est affichée sur les postes clients, indiquant la modification. L'utilisateur peut ensuite accepter ou refuser la synchronisation du dossier **Resources** local.\ - Le dossier **Resources** centralise les fichiers personnalisés nécessaires à l'interface de la base de données (fichiers de traduction, images, etc.). Des mécanismes automatiques ou manuels permettent de notifier chaque client lorsque le contenu de ce dossier a été modifié. Pour plus d'informations, veuillez consulter la section [Gestion du dossier Resources](../Desktop/clientServer.md#managing-the-resources-folder). + Le dossier **Resources** centralise les fichiers personnalisés nécessaires à l'interface de la base de données (fichiers de traduction, images, etc.). Des mécanismes automatiques ou manuels permettent de notifier chaque client lorsque le contenu de ce dossier a été modifié. For more information, please refer to the [Resources folder](../Desktop/clientServer.md#resources-folder) section. ## Page Configuration IP From f2092766dded209a3fc4553324da90a4249d8c38 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 13:25:13 +0100 Subject: [PATCH 139/195] collectionclass.md French --- .../version-20/API/CollectionClass.md | 43 +++++++++---------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/i18n/fr/docusaurus-plugin-content-docs/version-20/API/CollectionClass.md b/i18n/fr/docusaurus-plugin-content-docs/version-20/API/CollectionClass.md index eb76591dd1c51a..39a475e8259846 100644 --- a/i18n/fr/docusaurus-plugin-content-docs/version-20/API/CollectionClass.md +++ b/i18n/fr/docusaurus-plugin-content-docs/version-20/API/CollectionClass.md @@ -81,27 +81,27 @@ Une collection est initialisée avec : | Paramètres | Type | | Description | | ---------- | ----------------------------------------------------------------------- | :-------------------------: | ------------------------------------------ | | value | Number, Text, Date, Time, Boolean, Object, Collection, Picture, Pointer | -> | Valeur(s) de collection | -| Résultat | Collection | <- | nombres | +| Résultat | Collection | <- | La nouvelle collection | #### Description -Recherche avec des dates : +La commande `New collection` crée une nouvelle collection vide ou préremplie et retourne sa référence. -Prise en charge des formules +Si vous ne passez aucun paramètre, `New collection` crée une collection vide et retourne sa référence. Vous devez affecter la référence retournée à une variable 4D de type Collection. -> Utilisation de parenthèses +> N'oubliez pas que les instructions `var : Collection` ou `C_COLLECTION` déclarent une variable du type `Collection` mais ne créent pas de collection. -Condition Not appliquée à une assertion +Optionnellement, vous pouvez préremplir la nouvelle collection en passant une ou plusieurs *value*(s) comme paramètre(s). Sinon, vous pouvez ajouter ou modifier des éléments ultérieurement par affectation. Par exemple : ```4d -Vous pouvez fournir des paramètres supplémentaires à la callback si nécessaire. + myCol[10]:="Mon nouvel élément" ``` Si l'indice du nouvel élément est au-delà du dernier élément existant de la collection, la collection est automatiquement redimensionnée et tous les nouveaux éléments intermédiaires reçoivent la valeur **null**. @@ -110,7 +110,7 @@ Vous pouvez passer n'importe quel nombre de valeurs de n'importe quel type pris Vous devez prêter attention aux problèmes de conversion suivants : -- La nouvelle collection partagée +- Si vous passez un pointeur, il est conservé "tel quel" ; il est évalué à l'aide de la commande `JSON Stringify` - Les dates sont stockées sous la forme de date « aaaa-mm-jj » ou des chaînes au format « AAAA-MM-JJTHH: ss.SSSZ: mm » , selon la configuration actuelle « dates à l'intérieur des objets » de la base de données. Lors de la conversion de dates 4D en texte avant de les stocker dans la collection, par défaut le programme prend en compte le fuseau horaire local. Indice de fin (non inclus) - Si vous passez une heure, elle est stockée sous la forme d'un nombre de millisecondes (Réel). @@ -175,11 +175,11 @@ Vous souhaitez créer une nouvelle collection puis ajouter un élément : La commande `New shared collection` crée une nouvelle collection partagée vide ou préremplie et retourne sa référence. -Par exemple : Par exemple : La lecture d'un élément sans structure *Use...End use* est cependant possible. +L'ajout d'un élément à cette collection à l'aide de l'opérateur d'assignation doit être entouré de la structure [`Use...End use`](Concepts/shared.md#useend-use), sinon une erreur est générée (cela n'est pas nécessaire lors de l'ajout d'éléments à l'aide de fonctions telles que [`push()`](#push) ou [`map()`](#map) car elles utilisent automatiquement une structure interne *Use...End use*). La lecture d'un élément sans structure *Use...End use* est cependant possible. :::info -Les symboles suivants sont pris en charge : +Pour plus d'informations sur les collections partagées, veuillez vous référer à la page [Objets et collections partagés](Concepts/shared.md). ::: @@ -187,7 +187,7 @@ Si vous ne passez aucun paramètre, `New shared collection` crée une collection Vous devez affecter la référence retournée à une variable 4D de type Collection. -> Utilisation de parenthèses +> N'oubliez pas que les instructions `var : Collection` ou `C_COLLECTION` déclarent une variable du type `Collection` mais ne créent pas de collection. Optionnellement, vous pouvez préremplir la nouvelle collection partagée en passant une ou plusieurs *value*(s) comme paramètre(s). Sinon, vous pouvez ajouter ou modifier des éléments ultérieurement via l'assignation en notation objet (cf. exemple). @@ -201,8 +201,8 @@ Vous pouvez passer tout nombre de valeurs de n'importe quel type pris en charge - date - heure (stockée en nombre de milliseconds - réel) - Null -- Si vous souhaitez que l'évaluation soit sensible à la casse ou pour différencier des caractères accentués, passez la constante `ck diacritical` dans le paramètre option. -- Sommaire +- objet partagé +- collection partagée :::note @@ -1224,7 +1224,7 @@ Vous désignez le code de rétroappel (callback) à exécuter pour évaluer les - *formula* (syntaxe recommandée), un [objet Formula](FunctionClass.md) qui peut encapsuler toute expression exécutable, y compris des fonctions et des méthodes projet; - soit *methodName*, le nom d'une méthode projet (texte). -La callback est appelée avec le(s) paramètre(s) passé(s) dans *param* (facultatif). La callback peut effectuer n'importe quel test, avec ou sans le(s) paramètre(s) et doit retourner **true** pour chaque élément remplissant le test. Elle reçoit un `Objet` en premier paramètre ($1). +La callback est appelée avec le(s) paramètre(s) passé(s) dans *param* (facultatif). La callback est appelée avec le(s) paramètre(s) passé(s) dans *param* (facultatif). Elle reçoit un `Objet` en premier paramètre ($1). La callback reçoit les paramètres suivants : @@ -1315,7 +1315,7 @@ Vous désignez le code de rétroappel (callback) à exécuter pour évaluer les - *formula* (syntaxe recommandée), un [objet Formula](FunctionClass.md) qui peut encapsuler toute expression exécutable, y compris des fonctions et des méthodes projet; - *methodName*, le nom d'une méthode projet (texte). -La callback est appelée avec le(s) paramètre(s) passé(s) dans *param* (facultatif). La callback peut effectuer n'importe quel test, avec ou sans le(s) paramètre(s) et doit retourner **true** pour chaque élément remplissant le test. Elle reçoit un `Objet` en premier paramètre ($1). +La callback est appelée avec le(s) paramètre(s) passé(s) dans *param* (facultatif). La callback est appelée avec le(s) paramètre(s) passé(s) dans *param* (facultatif). Elle reçoit un `Objet` en premier paramètre ($1). La callback reçoit les paramètres suivants : @@ -1499,7 +1499,7 @@ Vous désignez le code de rétroappel (callback) à exécuter pour évaluer les - *formula* (syntaxe recommandée), un [objet Formula](FunctionClass.md) qui peut encapsuler toute expression exécutable, y compris des fonctions et des méthodes projet; - soit *methodName*, le nom d'une méthode projet (texte). -La callback est appelée avec le(s) paramètre(s) passé(s) dans *param* (facultatif). La callback est appelée avec le(s) paramètre(s) passé(s) dans *param* (facultatif). Elle reçoit un `Objet` en premier paramètre ($1). +La callback est appelée avec le(s) paramètre(s) passé(s) dans *param* (facultatif). La callback est appelée avec le(s) paramètre(s) passés dans param (facultatif). Elle reçoit un `Objet` en premier paramètre ($1). La callback reçoit les paramètres suivants : @@ -1597,7 +1597,7 @@ Dans *toSearch*, passez l'expression à trouver dans la collection. Vous pouvez Optionnellement, vous pouvez passer l'indice de la collection à partir duquel démarrer la recherche dans *startFrom*. - Si *startFrom* >= la longueur de la collection, False est retourné, ce qui signifie que la recherche n'est pas effectuée. -- Si *startFrom* < 0, la fin de la collection est considérée comme point de départ du calcul de la position (*startFrom:=startFrom+length*). **Note**: Même si *startFrom* est négatif, la collection est toujours recherchée de gauche à droite. +- Si *startFrom* < 0, la fin de la collection est considérée comme point de départ du calcul de la position (*startFrom:=startFrom+length*). **Attention** : N'oubliez pas que la numérotation des éléments de collection débute à 0. - Si *startFrom* = 0, l'ensemble de la collection est évalué (défaut). #### Exemple @@ -2023,7 +2023,7 @@ Vous désignez le code de rétroappel (callback) à exécuter pour évaluer les - *formula* (syntaxe recommandée), un [objet Formula](FunctionClass.md) qui peut encapsuler toute expression exécutable, y compris des fonctions et des méthodes projet; - soit *methodName*, le nom d'une méthode projet (texte). -La callback est appelée avec le(s) paramètre(s) passé(s) dans *param* (facultatif). La callback est appelée avec le(s) paramètre(s) passé(s) dans *param* (facultatif). Elle reçoit un `Objet` en premier paramètre ($1). +La callback est appelée avec le(s) paramètre(s) passé(s) dans *param* (facultatif). La callback est appelée avec le(s) paramètre(s) passés dans param (facultatif). Elle reçoit un `Objet` en premier paramètre ($1). La callback reçoit les paramètres suivants : @@ -2543,9 +2543,9 @@ Le paramètre *queryString* doit respecter la syntaxe suivante : propertyPath comparator value {logicalOperator propertyPath comparator value} ``` -For detailed information on how to build a query using *queryString*, *value* and *querySettings* parameters, please refer to the [`dataClass.query()`](DataClassClass.md#query) function description. +Pour plus d'informations sur la génération d'une requête à l'aide des paramètres *queryString*, *value* et *querySettings*, reportez-vous à la description de la fonction de DataClass [`query()`](DataClassClass.md#query). -> Formulas are not supported by the `collection.query()` function, neither in the *queryString* parameter nor as *formula* object parameter. +> Les formules ne sont pas prises en charge par la fonction `collection.query()`, ni dans le paramètre *queryString*, ni en tant que paramètre objet *formula*. #### Exemple 1 @@ -2758,8 +2758,7 @@ Elle peut définir le(s) paramètre(s) suivant(s) : ```4d var $c : Collection $c:=New collection(5;3;5;1;3;4;4;6;2;2) -$r:=$c.reduceRight(Formula($1.accumulator=$1.value); 1) //returns 86400 - +$r:=$c.reduceRight(Formula($1.accumulator=$1.value); 1) //86400 ``` @@ -3195,7 +3194,7 @@ La callback reçoit les paramètres suivants : Si vous avez utilisé une méthode, vous devez définir le paramètre suivant : -- *$1.result* (boolean): **True** if *$1.value < $1.value2*, **False** otherwise. +- *$1.result* (booléen) : **true** si *$1.value < $1.value2*, **false** sinon. #### Exemple 1 From d2b3f4831dedc0084462708565bfa2a9e6f7ea4d Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 13:29:43 +0100 Subject: [PATCH 140/195] dt_number.md French --- .../version-20/Concepts/dt_number.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/fr/docusaurus-plugin-content-docs/version-20/Concepts/dt_number.md b/i18n/fr/docusaurus-plugin-content-docs/version-20/Concepts/dt_number.md index 0b254e27ab9be2..663e68937a5e73 100644 --- a/i18n/fr/docusaurus-plugin-content-docs/version-20/Concepts/dt_number.md +++ b/i18n/fr/docusaurus-plugin-content-docs/version-20/Concepts/dt_number.md @@ -69,7 +69,7 @@ L'opérateur modulo % divise le premier nombre par le second et retourne le rest :::warning -L'opérateur modulo % retourne des valeurs significatives avec des nombres appartenant à la catégorie des entiers longs (de –2^31 à +2^31 moins 1). Pour calculer le modulo avec des nombres en dehors de cet intervalle, utilisez la commande [Mod](https://doc.4d.com/4dv20/help/command/en/page98.html). +L'opérateur modulo % retourne des valeurs significatives avec des nombres appartenant à la catégorie des entiers longs (de –2^31 à +2^31 moins 1). Pour calculer le modulo avec des nombres en dehors de cette plage, utilisez la commande [`Mod`](https://doc.4d.com/4dv20/help/command/en/page98.html). ::: From 54b10d3f8daa1f6abea81402ce160431eff3b17c Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 13:29:46 +0100 Subject: [PATCH 141/195] dt_number.md Spanish --- .../version-20/Concepts/dt_number.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/es/docusaurus-plugin-content-docs/version-20/Concepts/dt_number.md b/i18n/es/docusaurus-plugin-content-docs/version-20/Concepts/dt_number.md index 6769ae087795d5..f3e123979ce720 100644 --- a/i18n/es/docusaurus-plugin-content-docs/version-20/Concepts/dt_number.md +++ b/i18n/es/docusaurus-plugin-content-docs/version-20/Concepts/dt_number.md @@ -69,7 +69,7 @@ El operador modulo % divide el primer número entre el segundo y devuelve un res :::warning -El operador modulo % devuelve valores significativos con números que están en el rango de los enteros largos (de –2^31 hasta 2^31 menos 1). To calculate the modulo with numbers outside of this range, use the [`Mod`(https://doc.4d.com/4dv20/help/command/en/page98.html)] command. +El operador modulo % devuelve valores significativos con números que están en el rango de los enteros largos (de –2^31 hasta 2^31 menos 1). Para calcular el módulo con números fuera de este rango, utilice el comando [`Mod`](https://doc.4d.com/4dv20/help/command/en/page98.html). ::: From ea1bc836c8242f33092923038767d5f955c1f534 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 13:29:49 +0100 Subject: [PATCH 142/195] dt_number.md Japanese --- .../version-20/Concepts/dt_number.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-20/Concepts/dt_number.md b/i18n/ja/docusaurus-plugin-content-docs/version-20/Concepts/dt_number.md index 75e2ddbdda1e4f..631b5099ef4acb 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/version-20/Concepts/dt_number.md +++ b/i18n/ja/docusaurus-plugin-content-docs/version-20/Concepts/dt_number.md @@ -69,7 +69,7 @@ title: 数値 (実数、倍長整数、整数) :::warning -モジューロ演算子 % は倍長整数の範囲内 (-2^31 から (2^31)-1 まで) の数値に対して有効な値を返します。この範囲外の数値のモジューロ演算を実行するには、[`Mod`](https://doc.4d.com/4dv20/help/command/ja/page98.html) コマンドを使用します。 +モジューロ演算子 % は倍長整数の範囲内 (-2^31 から (2^31)-1 まで) の数値に対して有効な値を返します。範囲外の数値に対してモジューロを計算したい場合には、[`Mod`](https://doc.4d.com/4dv20/help/command/en/page98.html) コマンドを使用してください。 ::: From a09fd5cc5074b8ecabb2e7d4ee91697e80fcdca4 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 13:35:28 +0100 Subject: [PATCH 143/195] createstylesheet.md Japanese --- .../version-20/FormEditor/createStylesheet.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-20/FormEditor/createStylesheet.md b/i18n/ja/docusaurus-plugin-content-docs/version-20/FormEditor/createStylesheet.md index a9f7e82321de26..bec2c9ab9fb1cd 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/version-20/FormEditor/createStylesheet.md +++ b/i18n/ja/docusaurus-plugin-content-docs/version-20/FormEditor/createStylesheet.md @@ -126,7 +126,7 @@ text.center { } ``` -4D フォームの詳細では、[CSSクラス](../FormObjects/properties_Object.md#cssクラス) 属性を使用してクラス名を割り当てます。この属性には一つ以上のクラス名を指定することができます。 複数の場合はクラス名を半角スペースで区切ります: +4D フォームの詳細では、[CSSクラス](../FormObjects/properties_Object.md#cssクラス) 属性を使用してクラス名を割り当てます。この属性には一つ以上のクラス名を指定することができます。複数の場合はクラス名を半角スペースで区切ります: ``` class: "okButtons important" From 75dbe44023c9ab75f1af4b3fab7d0e87f7fbd081 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 14:27:01 +0100 Subject: [PATCH 144/195] labels.md Japanese --- .../version-21-R4/Desktop/labels.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21-R4/Desktop/labels.md b/i18n/ja/docusaurus-plugin-content-docs/version-21-R4/Desktop/labels.md index 70073d18ad1a8d..29b65f2314faab 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/version-21-R4/Desktop/labels.md +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21-R4/Desktop/labels.md @@ -164,7 +164,7 @@ title: ラベル var myVar+=1 ``` -3. プロジェクトメソッドに対して["コンポーネントとホストデータベース間で共有"](../Project/project-method-properties.md#コンポーネントとホストデータベース間で共有) オプションを設定します。 +3. プロジェクトメソッドに対して["コンポーネントとホストデータベース間で共有"](../Project/project-method-properties.md#コンポーネントとホストプロジェクト間で共有) オプションを設定します。 4. ラベルエディターを表示する前に、以下のコードを実行してプロジェクトメソッドが確実に許可されているようにします: From aad27d5c58239d3367c4cb34fbed5e96ff4d2348 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 14:27:22 +0100 Subject: [PATCH 145/195] preemptive.md French --- .../version-21-R4/Develop/preemptive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/fr/docusaurus-plugin-content-docs/version-21-R4/Develop/preemptive.md b/i18n/fr/docusaurus-plugin-content-docs/version-21-R4/Develop/preemptive.md index 548b17b1d76767..f910900c7a523f 100644 --- a/i18n/fr/docusaurus-plugin-content-docs/version-21-R4/Develop/preemptive.md +++ b/i18n/fr/docusaurus-plugin-content-docs/version-21-R4/Develop/preemptive.md @@ -41,7 +41,7 @@ Le code 4D ne peut être exécuté dans un process préemptif que lorsque certai La propriété "thread safety" de chaque élément dépend de l'élément lui-même : -- Commandes 4D : la propriété thread-safe est une propriété interne. Dans la documentation 4D, les commandes thread-safe sont identifiées par l'icône ![](../assets/en/Develop/thread-safe.png). Vous pouvez également utiliser la commande [`Command name`](../commands/command-name) pour savoir si une commande est thread-safe. Une grande partie des commandes 4D peut s'exécuter en mode préemptif. +- Commandes 4D : la propriété thread-safe est une propriété interne. The 4D documentation indicates whether each command is thread-safe or not in the Properties section. Vous pouvez également utiliser la commande [`Command name`](../commands/command-name) pour savoir si une commande est thread-safe. Une grande partie des commandes 4D peut s'exécuter en mode préemptif. - Méthodes projet : les conditions pour être thread-safe sont répertoriées dans [ce paragraphe](#writing-a-thread-safe-method). Fondamentalement, le code à exécuter dans des threads préemptifs ne peut pas appeler des parties avec des interactions externes, telles que du code de plug-in ou des variables interprocess. Cependant, l'accès aux données est autorisé car le serveur de données 4D et ORDA prennent en charge l'exécution préemptive. From 70981c9896530bb7f54288a8bb6436e030ceb00b Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 14:27:25 +0100 Subject: [PATCH 146/195] preemptive.md Spanish --- .../version-21-R4/Develop/preemptive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/es/docusaurus-plugin-content-docs/version-21-R4/Develop/preemptive.md b/i18n/es/docusaurus-plugin-content-docs/version-21-R4/Develop/preemptive.md index 3d68172398d401..6d49343ef332ff 100644 --- a/i18n/es/docusaurus-plugin-content-docs/version-21-R4/Develop/preemptive.md +++ b/i18n/es/docusaurus-plugin-content-docs/version-21-R4/Develop/preemptive.md @@ -41,7 +41,7 @@ Dado que un hilo se maneja de forma independiente a partir del método del proce La propiedad "seguridad de hilo" de cada elemento depende del elemento en sí: -- Comandos 4D: hilo seguro es una propiedad interna. En la documentación de 4D, los comandos hilo seguro se identifican con el icono ![](../assets/en/Develop/thread-safe.png). También puede utilizar el comando [`Nombre del comando`](../commands/command-name) para saber si un comando es hilo seguro. Gran parte de los comandos 4D pueden ejecutarse en modo apropiativo. +- Comandos 4D: hilo seguro es una propiedad interna. The 4D documentation indicates whether each command is thread-safe or not in the Properties section. También puede utilizar el comando [`Nombre del comando`](../commands/command-name) para saber si un comando es hilo seguro. Gran parte de los comandos 4D pueden ejecutarse en modo apropiativo. - Métodos de proyecto: las condiciones para seguridad de hilo se listan en [este párrafo](#writing-a-thread-safe-method). Básicamente, el código que se ejecuta en hilos apropiativos no puede llamar a las partes con las interacciones externas, tal como el código plug-in o las variables interproceso. Los accesos a los datos, sin embargo, son permitidos desde el servidor de datos 4D que soporta la ejecución apropiativa. From 0f211eca0ee9fa1a0c9aaed3b1bc6a0683b86ffa Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 14:27:28 +0100 Subject: [PATCH 147/195] preemptive.md Japanese --- .../version-21-R4/Develop/preemptive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21-R4/Develop/preemptive.md b/i18n/ja/docusaurus-plugin-content-docs/version-21-R4/Develop/preemptive.md index 8f3647df6fbe95..15b0b4faa7ef73 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/version-21-R4/Develop/preemptive.md +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21-R4/Develop/preemptive.md @@ -41,7 +41,7 @@ title: プリエンプティブプロセス 要素毎の "スレッドセーフティ" プロパティは、その要素自身によります: -- 4Dコマンド: スレッドセーフティは内部プロパティです。 4D ドキュメンテーション内においては、スレッドセーフなコマンドには ![](../assets/en/Develop/thread-safe.png) アイコンが表示されています。 [`Command name`](../commands/command-name) コマンドを使用して、コマンドがスレッドセーフであるかどうかを知ることもできます。 4Dコマンドの大部分はプリエンプティブモードで実行可能です。 +- 4Dコマンド: スレッドセーフティは内部プロパティです。 The 4D documentation indicates whether each command is thread-safe or not in the Properties section. [`Command name`](../commands/command-name) コマンドを使用して、コマンドがスレッドセーフであるかどうかを知ることもできます。 4Dコマンドの大部分はプリエンプティブモードで実行可能です。 - プロジェクトメソッド: スレッドセーフであるための条件は [こちらの段落](#スレッドセーフなメソッドの書き方) にまとめられています。 原則として、プリエンプティブスレッド内で実行されるコードは外部との相互作用する部分、たとえばプラグインコードやインタープロセス変数などを呼び出すことはできません。しかしながら、4Dデータサーバーと ORDA はプリエンプティブ実行をサポートしていることから、データアクセスは可能です。 From dbde6a9b35177ae61b510cc99ab1394e46172e94 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 14:27:34 +0100 Subject: [PATCH 148/195] processes.md Japanese --- .../version-21-R4/Develop/processes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21-R4/Develop/processes.md b/i18n/ja/docusaurus-plugin-content-docs/version-21-R4/Develop/processes.md index d7eb693b4a3da8..65c53df3caa564 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/version-21-R4/Develop/processes.md +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21-R4/Develop/processes.md @@ -50,7 +50,7 @@ title: プロセスとワーカー ### インターフェース要素 -インターフェース要素は、[デスクトップアプリケーション](../category/desktop-applications) で使用されます。 以下のものがあります: 以下のものがあります: +インターフェース要素は、[デスクトップアプリケーション](../category/desktop-applications) で使用されます。以下のものがあります: - [メニューバー](../Menus/creating.md): 各プロセスは、独自のカレントメニューバーを持つことができます。最前面のプロセスのメニューバーがアプリケーションのカレントメニューバーになります。 - 1つ以上のウィンドウ: 各プロセスは、1つまたは複数のウィンドウを同時に開くことができます。他方、ウィンドウをまったく持たないプロセスもあります。 From 7d7fa9730f9fd0973f6ea2d3f81fd8071addfc64 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 14:31:18 +0100 Subject: [PATCH 149/195] createstylesheet.md Japanese --- .../version-21-R4/FormEditor/createStylesheet.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21-R4/FormEditor/createStylesheet.md b/i18n/ja/docusaurus-plugin-content-docs/version-21-R4/FormEditor/createStylesheet.md index 5e5cd912ba4201..68b7055ec7ae72 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/version-21-R4/FormEditor/createStylesheet.md +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21-R4/FormEditor/createStylesheet.md @@ -126,7 +126,7 @@ text.center { } ``` -4D フォームの詳細では、[CSSクラス](../FormObjects/properties_Object.md#cssクラス) 属性を使用してクラス名を割り当てます。この属性には一つ以上のクラス名を指定することができます。 複数の場合はクラス名を半角スペースで区切ります: +4D フォームの詳細では、[CSSクラス](../FormObjects/properties_Object.md#cssクラス) 属性を使用してクラス名を割り当てます。この属性には一つ以上のクラス名を指定することができます。複数の場合はクラス名を半角スペースで区切ります: ```css class: "okButtons important" From e1404dd21e55147e47bbc20d614ddd987927621e Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 15:54:45 +0100 Subject: [PATCH 150/195] collectionclass.md Spanish --- .../version-21-R5/API/CollectionClass.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/es/docusaurus-plugin-content-docs/version-21-R5/API/CollectionClass.md b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/API/CollectionClass.md index 6efed8c62af40d..6c8c482f75ecfd 100644 --- a/i18n/es/docusaurus-plugin-content-docs/version-21-R5/API/CollectionClass.md +++ b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/API/CollectionClass.md @@ -2207,7 +2207,7 @@ También puede pasar un parámetro de criterios para definir cómo deben ordenar Esta sintaxis sólo ordena los valores escalares de la colección (otros tipos de elementos, como objetos o colecciones, se devuelven desordenados). -Si la colección contiene elementos de diferentes [tipos](../Concepts/data-types.md), se ordenarán según los [principios de ordenación de 4D](../Concepts/ordering.md). +Si la colección contiene elementos de diferentes [tipos](../Concepts/data-types.md), se ordenarán según los [principios de ordenación 4D](../Concepts/ordering.md). #### Ejemplo 1 From e75192b08f55ace7808e9b14b25b8dfee58b1b3f Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 15:54:55 +0100 Subject: [PATCH 151/195] cryptokeyclass.md French --- .../version-21-R5/API/CryptoKeyClass.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/API/CryptoKeyClass.md b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/API/CryptoKeyClass.md index f9e55bee5c5ab0..5747ef65cf51c0 100644 --- a/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/API/CryptoKeyClass.md +++ b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/API/CryptoKeyClass.md @@ -57,12 +57,12 @@ La fonction `4D.CryptoKey.new()` crée u #### *settings* -| Propriété | Type | Description | -| --------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [type](#type) | text | Définit le type de clé à créer : "
  • RSA" : génère une paire de clés RSA, en utilisant [.size](#size) comme taille.
  • "ECDSA" : génère une paire de clés Elliptic Curve Digital Signature Algorithm, en utilisant [.curve](#curve) comme courbe. Notez que les clés ECDSA ne peuvent pas être utilisées pour le chiffrement, mais uniquement pour la signature.
  • "PEM" : charge une définition de paire de clés au format PEM, en utilisant [.pem](#pem)
  • . | -| [curve](#curve) | text | Nom de la courbe ECDSA | -| [pem](#pem) | text | Définition PEM d'une clé de chiffrement à charger | -| [size](#size) | integer | Taille de la clé RSA en octets | +| Propriété | Type | Description | +| --------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [type](#type) | text | Définit le type de clé à créer :
  • "RSA" : génère une paire de clés RSA, en utilisant [.size](#size) comme taille.
  • "ECDSA" : génère une paire de clés Elliptic Curve Digital Signature Algorithm, en utilisant [.curve](#curve) comme courbe. A noter que les clés ECDSA ne peuvent pas être utilisées pour le chiffrement, mais uniquement pour la signature.
  • "PEM" : charge une définition de paire de clés au format PEM, en utilisant [.pem](#pem).
  • | +| [curve](#curve) | text | Nom de la courbe ECDSA | +| [pem](#pem) | text | Définition PEM d'une clé de chiffrement à charger | +| [size](#size) | integer | Taille de la clé RSA en octets | #### *CryptoKey* From cb53f52fa40dd70ce12c8307e66a9a7a65360d42 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 15:54:58 +0100 Subject: [PATCH 152/195] cryptokeyclass.md Spanish --- .../version-21-R5/API/CryptoKeyClass.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/i18n/es/docusaurus-plugin-content-docs/version-21-R5/API/CryptoKeyClass.md b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/API/CryptoKeyClass.md index b1ae8c232a244c..504b76a599bf12 100644 --- a/i18n/es/docusaurus-plugin-content-docs/version-21-R5/API/CryptoKeyClass.md +++ b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/API/CryptoKeyClass.md @@ -57,12 +57,12 @@ La función `4D.CryptoKey.new()` crea un #### *settings* -| Propiedad | Tipo | Descripción | -| --------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [type](#type) | text | Define el tipo de clave a crear:
  • "RSA": genera un par de llaves RSA, utilizando [.size](#size) como tamaño.
  • "ECDSA": genera un par de llaves Elliptic Curve Digital Signature Algorithm, utilizando [.curve](#curve) como curva. Tenga en cuenta que las llaves ECDSA no pueden utilizarse para cifrar, sino sólo para firmar.
  • "PEM": carga una definición de par de llaves en formato PEM, utilizando [.pem](#pem).
  • | -| [curve](#curve) | text | Nombre de la curva ECDSA | -| [pem](#pem) | text | Definición PEM de una llave de cifrado a cargar | -| [size](#size) | integer | Tamaño de la llave RSA en bits | +| Propiedad | Tipo | Descripción | +| --------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [type](#type) | text | Define el tipo de llave a crear:
  • "RSA": genera un par de llaves RSA, utilizando [.size](#size) como tamaño.
  • "ECDSA": genera un par de llaves Elliptic Curve Digital Signature Algorithm, utilizando [.curve](#curve) como curva. Tenga en cuenta que las llaves ECDSA no pueden utilizarse para el cifrado, sino solo para la firma.
  • "PEM": carga una definición de par de llaves en formato PEM, utilizando [.pem](#pem).
  • | +| [curve](#curve) | text | Nombre de la curva ECDSA | +| [pem](#pem) | text | Definición PEM de una llave de cifrado a cargar | +| [size](#size) | integer | Tamaño de la llave RSA en bits | #### *CryptoKey* From 74f516431d8edbf2af62a7c5a05f01b158446778 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 15:55:04 +0100 Subject: [PATCH 153/195] dataclassclass.md French --- .../version-21-R5/API/DataClassClass.md | 108 +++++++++--------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/API/DataClassClass.md b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/API/DataClassClass.md index 61b725e12317b6..46c030662a1a6d 100644 --- a/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/API/DataClassClass.md +++ b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/API/DataClassClass.md @@ -51,24 +51,24 @@ Les objets renvoyés ont des propriétés que vous pouvez lire pour obtenir des Les objets attributs retournés contiennent les propriétés suivantes : -| Propriété | Type | Description | -| ---------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| autoFilled | Boolean | Vrai si la valeur de l'attribut est automatiquement remplie par 4D. Correspond aux propriétés de champs 4D suivantes : "Autoincrement" pour les champs de type numérique et "UUID Auto" pour les champs UUID (alpha). Non retourné si `.kind` = "relatedEntity" ou "relatedEntities". | -| exposed | Boolean | Vrai si l'attribut est exposé en REST | -| fieldNumber | integer | Numéro interne du champ 4D correspondant à l'attribut. Non retourné si `.kind` = "relatedEntity" ou "relatedEntities". | -| fieldType | Integer | Type de champ de la base de données 4D de l'attribut. Dépend de l'attribut `kind`. Valeurs possibles :
  • si `.kind` = "storage" : type de champ 4D correspondant, voir [`Value type`](../commands/value-type)
  • si `.kind` = "relatedEntity" : 38 (`is object`)
  • si `.kind` = "relatedEntities" : 42 (`is collection`)
  • si `.kind` = "calculated" ou "alias" = même chose que ci-dessus, en fonction de la valeur résultante (type de champ, relatedEntity ou relatedEntities)
  • | -| indexed | Boolean | Vrai s'il existe un index B-tree ou Cluster B-tree sur l'attribut. Non retourné si `.kind` = "relatedEntity" ou "relatedEntities". | -| inverseName | Text | Nom de l'attribut qui se trouve à l'autre côté de la relation. Renvoyé uniquement lorsque `.kind` = "relatedEntity" ou "relatedEntities". | -| keywordIndexed | Boolean | Vrai s'il existe un index de mots-clés sur l'attribut. Non retourné si `.kind` = "relatedEntity" ou "relatedEntities". | -| kind | Text | Catégorie de l'attribut. Valeurs possibles :
  • "storage" : attribut de stockage (ou scalaire), c'est-à-dire attribut stockant une valeur et non une référence à un autre attribut
  • "calculated" : attribut calculé, c'est-à-dire défini par une [fonction `get`](../ORDA/ordaClasses.md#function-get-attributename)
  • "alias" : attribut construit sur [un autre attribut](../ORDA/ordaClasses.md#alias-attributes-1)
  • "relatedEntity" : attribut de relation N -> 1 (référence à une entité)
  • "relatedEntities" : attribut de relation 1->N (référence à une entity selection)
  • | -| obligatoire | Boolean | Vrai si la saisie d'une valeur null est rejetée pour l'attribut. Non retourné si `.kind` = "relatedEntity" ou "relatedEntities". Attention : Cette propriété correspond à la propriété du champ "Reject NULL value input" au niveau de la base de données 4D. Elle n'est pas liée à la propriété "Mandatory" existante qui est une option de contrôle de la saisie de données pour une table. | -| name | Text | Nom de l'attribut sous forme de chaîne | -| path | Text | Chemin d'un [attribut alias](../ORDA/ordaClasses.md#alias-attributes-1) basé sur une relation | -| readOnly | Boolean | Vrai si l'attribut est en lecture seule. Par exemple, les attributs calculés sans la fonction [`set`](../ORDA/ordaClasses.md#function-set-attributename) sont en lecture seule. | -| relatedDataClass | Text | Nom de la dataclass liée à l'attribut. Renvoyé uniquement lorsque `.kind` = "relatedEntity" ou "relatedEntities". | -| type | Text | Type conceptuel de la valeur de l'attribut, utile pour la programmation générique. Dépend de l'attribut `kind`. Valeurs possibles :
  • si `.kind` = "storage" : "blob", "bool", "date", "image", "number", "object", ou "string". "number" est renvoyé pour tous les types numériques, y compris la durée ; "string" est renvoyé pour les types d'attributs uuid, alpha et texte ; les attributs "blob" sont des [objets blob](../Concepts/dt_blob.md#blob-types).
  • si `.kind` = "relatedEntity" : nom de la dataClass liée
  • si `.kind` = "relatedEntities" : nom de la dataClass liée + suffixe "Selection"
  • si `.kind` = "calculated" ou "alias" : même chose que ci-dessus, en fonction du résultat
  • | -| unique | Boolean | Vrai si la valeur de l'attribut doit être unique. Non retourné si `.kind` = "relatedEntity" ou "relatedEntities". | -| classID | Text | Disponible uniquement si `.type = "object"` et si une classe a été spécifiée dans l'éditeur de structure.
    Retourne le nom de la classe utilisée pour instancier l'objet. | +| Propriété | Type | Description | +| ---------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| autoFilled | Boolean | Vrai si la valeur de l'attribut est automatiquement remplie par 4D. Correspond aux propriétés de champs 4D suivantes : "Autoincrement" pour les champs de type numérique et "UUID Auto" pour les champs UUID (alpha). Non retourné si `.kind` = "relatedEntity" ou "relatedEntities". | +| exposed | Boolean | Vrai si l'attribut est exposé en REST | +| fieldNumber | integer | Numéro interne du champ 4D correspondant à l'attribut. Non retourné si `.kind` = "relatedEntity" ou "relatedEntities". | +| fieldType | Integer | Type de champ de la base de données 4D de l'attribut. Dépend de l'attribut `kind`. Valeurs possibles :
  • si `.kind` = "storage" : type de champ 4D correspondant, voir [`Value type`](../commands/value-type)
  • si `.kind` = "relatedEntity" : 38 (`is object`)
  • si `.kind` = "relatedEntities" : 42 (`is collection`)
  • si `.kind` = "calculated" ou "alias" = même chose que ci-dessus, en fonction de la valeur résultante (type de champ, relatedEntity ou relatedEntities)
  • | +| indexed | Boolean | Vrai s'il existe un index B-tree ou Cluster B-tree sur l'attribut. Non retourné si `.kind` = "relatedEntity" ou "relatedEntities". | +| inverseName | Text | Nom de l'attribut qui se trouve à l'autre côté de la relation. Renvoyé uniquement lorsque `.kind` = "relatedEntity" ou "relatedEntities". | +| keywordIndexed | Boolean | Vrai s'il existe un index de mots-clés sur l'attribut. Non retourné si `.kind` = "relatedEntity" ou "relatedEntities". | +| kind | Text | Catégorie de l'attribut. Valeurs possibles :
  • "storage" : attribut de stockage (ou scalaire), c'est-à-dire attribut stockant une valeur et non une référence à un autre attribut
  • "calculated" : attribut calculé, c'est-à-dire défini par une [fonction `get`](../ORDA/ordaClasses.md#function-get-attributename)
  • "alias" : attribut construit sur [un autre attribut](../ORDA/ordaClasses.md#alias-attributes-1)
  • "relatedEntity" : attribut de relation N -> 1 (référence à une entité)
  • "relatedEntities" : attribut de relation 1->N (référence à une entity selection)
  • | +| obligatoire | Boolean | Vrai si la saisie d'une valeur null est rejetée pour l'attribut. Non retourné si `.kind` = "relatedEntity" ou "relatedEntities". Attention : Cette propriété correspond à la propriété du champ "Reject NULL value input" au niveau de la base de données 4D. Elle n'est pas liée à la propriété "Mandatory" existante qui est une option de contrôle de la saisie de données pour une table. | +| name | Text | Nom de l'attribut sous forme de chaîne | +| path | Text | Chemin d'un [attribut alias](../ORDA/ordaClasses.md#alias-attributes-1) basé sur une relation | +| readOnly | Boolean | Vrai si l'attribut est en lecture seule. Par exemple, les attributs calculés sans la fonction [`set`](../ORDA/ordaClasses.md#function-set-attributename) sont en lecture seule. | +| relatedDataClass | Text | Nom de la dataclass liée à l'attribut. Renvoyé uniquement lorsque `.kind` = "relatedEntity" ou "relatedEntities". | +| type | Text | Type conceptuel de la valeur de l'attribut, utile pour la programmation générique. Dépend de l'attribut `kind`. Valeurs possibles :
  • si `.kind` = "storage" : "blob", "bool", "date", "image", "number", "object", ou "string". "number" est renvoyé pour tous les types numériques, y compris duration ; "string" est renvoyé pour les types d'attributs uuid, alpha et texte ; les attributs "blob" sont des [objets blob](../Concepts/dt_blob.md#blob-types).
  • si `.kind` = "relatedEntity" : nom de la dataClass liée
  • si `.kind` = "relatedEntities" : nom de la dataClass liée + suffixe "Selection
  • si `.kind` = "calculated" ou "alias" : même chose que ci-dessus, en fonction du résultat
  • | +| unique | Boolean | Vrai si la valeur de l'attribut doit être unique. Non retourné si `.kind` = "relatedEntity" ou "relatedEntities". | +| classID | Text | Disponible uniquement si `.type = "object"` et si une classe a été spécifiée dans l'éditeur de structure.
    Retourne le nom de la classe utilisée pour instancier l'objet. | :::tip @@ -636,42 +636,42 @@ La méthode projet ***SearchDuplicate*** recherche des valeurs dupliquées dans
    -| Paramètres | Type | | Description | -| ---------- | ---------- | --------------------------- | --------------------------- | -| Résultat | Collection | <- | Collection of index objects | +| Paramètres | Type | | Description | +| ---------- | ---------- | --------------------------- | ------------------------- | +| Résultat | Collection | <- | Collection d'objets index |
    #### Description -The `.getIndexes()` function returns a collection of all indexes related to the dataclass. +La fonction `.getIndexes()` retourne une collection de tous les index liés à la dataclass. -Each index is an object of the collection. Indexes are returned in the creation/modification order. An empty collection is returned if there is no index in the dataclass. +Chaque index est un objet de la collection. Les index sont retournés dans l'ordre de création/modification. Une collection vide est retournée s'il n'y a pas d'index dans la dataclass. **Collection retournée** -Each object of the returned collection has the following properties: +Chaque objet de la collection retournée contient les propriétés suivantes : -| Propriété | Type | Description | -| ---------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| type | Integer | Index type: -1 = Keywords, 0 = default, 1 = Standard B-Tree, 3 = Cluster B-Tree, 4 = Cosine, 5 = Dot, 6 = Euclidean. If the index is set to Automatic, the type property represents the type of the indexing algorithm used | -| automatic | Boolean | True if "automatic" index is selected | -| name | Text | Index name if defined | -| kind | Text | "keywords" if *keyword index* checked, otherwise "regular" | -| attributes | Collection | Index attribute or list of attributes (for composite index) | -| UUID | Text | Index UUID | -| uniqueKey | Boolean | True if index has the Unique key property | +| Propriété | Type | Description | +| ---------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| type | Integer | Type d'index : -1 = Mots-clés, 0 = Par défaut, 1 = B-Tree standard, 3 = B-Tree cluster, 4 = Cosinus, 5 = Produit scalaire, 6 = Euclidien. Si l'index est défini sur Automatique, la propriété type représente le type de l'algorithme d'indexation utilisé | +| automatic | Boolean | True si l'index "automatique" est sélectionné | +| name | Text | Nom de l'index si défini | +| kind | Text | "keywords" si *Index mots-clés* est coché, sinon "regular" | +| attributes | Collection | Attribut de l'index ou liste d'attributs (pour les index composites) | +| UUID | Text | UUID de l'index | +| uniqueKey | Boolean | True si l'index a la propriété Unique | :::tip Article(s) de blog sur le sujet -[Managing 4D Indexes Programmatically with getIndexes()](https://blog.4d.com/managing-4d-indexes-programmatically-with-getindexes) +[Gestion des index 4D par programmation à l’aide de la fonction getIndexes()](https://blog.4d.com/managing-4d-indexes-programmatically-with-getindexes) ::: #### Exemple -Considering the following table: +Considérant la table suivante : ![table-indexes](../assets/en/API/table-index.png) @@ -793,7 +793,7 @@ La fonction `.getInfo()` renvoie u #### Description -La fonction `.getRemoteCache()` renvoie un objet qui contient le contenu du cache ORDA pour une dataclass. +La fonction `.setRemoteCacheSettings()` définit le timeout et la taille maximale du cache ORDA pour une dataclass.. Si elle est appelée depuis une application 4D monoposte, la fonction retourne `Null`. @@ -1096,18 +1096,18 @@ L'utilisation de placeholders dans les recherches **est recommandée** pour les 1. Cela empêche l'injection de code malveillant : si vous utilisez dans la chaîne de recherche des variables dont le contenu provient directement de la saisie de l'utilisateur, celui-ci pourrait modifier les conditions de recherche en saisissant des arguments de recherche supplémentaires. Par exemple, imaginez une chaîne de recherche du type : -```4d - $vquery:="status = 'public' & name = "+myname //l'utilisateur saisit son nom - $result:=$col.query($vquery) -``` + ```4d + $vquery:="status = 'public' & name = "+myname //l'utilisateur saisit son nom + $result:=$col.query($vquery) + ``` Cette recherche semble sécurisée puisque les données non publiques sont filtrées. Cependant, si l'utilisateur saisit dans la zone *myname* une chaîne du type *"smith OR status='private'*, la chaîne de recherche sera modifiée à l'étape de l'interprétation et pourra retourner des données privées. Lorsque vous utilisez des placeholders, le contournement des options de sécurité n'est pas possible : -```4d - $result:=$col.query("status='public' & name=:1";myname) -``` + ```4d + $result:=$col.query("status='public' & name=:1";myname) + ``` Dans ce cas, si l'utilisateur saisit *smith OR status='private'* dans la zone *myname*, cela ne sera pas interprété dans la chaîne de recherche, mais uniquement passé en tant que valeur. La recherche d'une personne nommée "smith OR status='private"' échouera simplement. @@ -1115,10 +1115,10 @@ Dans ce cas, si l'utilisateur saisit *smith OR status='private'* dans la zone *m 3. Cela permet l'utilisation de variables ou d'expressions dans les arguments de recherche. Exemples : -```4d -$result:=$col.query("address.city = :1 & name =:2";$city;$myVar+"@") -$result2:=$col.query("company.name = :1";"John's Pizzas") -``` + ```4d + $result:=$col.query("address.city = :1 & name =:2";$city;$myVar+"@") + $result2:=$col.query("company.name = :1";"John's Pizzas") + ``` ### Recherche de valeurs null @@ -1288,11 +1288,11 @@ Si *attributePath* désigne un attribut stockant des [**objets vecteurs**](../AP Dans ce cas, le paramètre *value* doit être un **objet vecteur de comparaison** contenant les propriétés suivantes : -| Propriété | Type | Description | -| --------- | -------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| vector | [4D.Vector](../API/VectorClass.md) | Obligatoire. Le vecteur à comparer | -| metric | Text | Optionnel. [Calcul vectoriel](../API/VectorClass.md#understanding-the-different-vector-computations) à utiliser pour la recherche. Vous pouvez utiliser l'une des constantes (texte) suivantes :
  • `mk cosine` (valeur par défaut si non spécifiée) : calcule la [similarité cosinus](./VectorClass.md#cosinesimilarity) entre deux vecteurs.
  • `mk dot` : calcule la [similarité scalaire](VectorClass.md#dotsimilarity) entre deux vecteurs.
  • `mk euclidean` : calcule la [distance euclidienne](./VectorClass.md#euclideandistance) entre des vecteurs. | -| threshold | Real | Facultatif (valeur par défaut : 0,5). Valeur seuil utilisée pour filtrer les comparaisons de vecteurs sur la base de leur score de similarité cosinus, point ou euclidienne selon la "métrique" sélectionnée. Il est fortement recommandé de choisir une similitude qui corresponde le mieux à votre cas d'utilisation spécifique pour des résultats optimaux. | +| Propriété | Type | Description | +| --------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| vector | [4D.Vector](../API/VectorClass.md) | Obligatoire. Le vecteur à comparer | +| metric | Text | Optionnel. [Calcul vectoriel](../API/VectorClass.md#understanding-the-different-vector-computations) à utiliser pour la recherche. Vous pouvez utiliser l'une des constantes (Text) suivantes :
  • `mk cosine` (valeur par défaut si non spécifiée) : calcule la [similarité cosinus](./VectorClass.md#cosinesimilarity) entre deux vecteurs.
  • `mk dot` : calcule la [similarité par produit scalaire](VectorClass.md#dotsimilarity) entre des vecteurs.
  • `mk euclidean` : calcule la [distance euclidienne](./VectorClass.md#euclideandistance) entre deux vecteurs. | +| threshold | Real | Facultatif (valeur par défaut : 0,5). Valeur seuil utilisée pour filtrer les comparaisons de vecteurs sur la base de leur score de similarité cosinus, point ou euclidienne selon la "métrique" sélectionnée. Il est fortement recommandé de choisir une similitude qui corresponde le mieux à votre cas d'utilisation spécifique pour des résultats optimaux. | Seul un sous-ensemble de symboles **comparateurs** est pris en charge. Notez qu'ils comparent les résultats à la valeur de seuil (threshold) : @@ -1342,7 +1342,7 @@ Voir [plus d'exemples ci-dessous](#example-4-2) (exemples 4 et 5). - [4D AI : Recherche d'entités par similarité vectorielle en 4D](https://blog.4d.com/4d-ai-searching-entities-by-vector-similarity-in-4d) - [4D AI : Tri des résultats d'une requête en fonction de la similarité vectorielle](https://blog.4d.com/4d-ai-sorting-query-results-by-vector-similarity/) -- [Why Your Search Stack Feels Broken — and How Vector Search Fixes It](https://blog.4d.com/why-your-search-stack-feels-broken-and-how-vector-search-fixes-it) +- [Pourquoi votre pile de recherche semble brisée – et comment Vector Search y remédie](https://blog.4d.com/why-your-search-stack-feels-broken-and-how-vector-search-fixes-it) ::: @@ -1766,7 +1766,7 @@ var $results := ds.MyTable.query("myVectorField <= :1 AND salary>100000 order by #### Description -La fonction `.setRemoteCacheSettings()` définit le timeout et la taille maximale du cache ORDA pour une dataclass.. +La fonction `.getRemoteCache()` renvoie un objet qui contient le contenu du cache ORDA pour une dataclass.. Dans le paramètre *settings*, passez un objet contenant les propriétés suivantes : From b6049b365b0b7328c67a052774bdd4e6db94f5c6 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 15:55:15 +0100 Subject: [PATCH 154/195] datastoreclass.md French --- .../version-21-R5/API/DataStoreClass.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/API/DataStoreClass.md b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/API/DataStoreClass.md index 80d9d4535a9855..d6d91dd09d0479 100644 --- a/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/API/DataStoreClass.md +++ b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/API/DataStoreClass.md @@ -457,7 +457,7 @@ La fonction `.getInfo()` renvoie u | Propriété | Type | Description | | ---------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | type | string |
  • "4D": datastore principal, disponible via ds
  • "4D Server": datastore distant, ouvert avec Open datastore
  • | -| networked | boolean |
  • True: le datastore est atteint via une connexion réseau.
  • False : le datastore n'est pas atteint via une connexion réseau (base de données locale)
  • | +| networked | boolean |
  • Vrai : le datastore est accessible via une connexion réseau.
  • Faux : le datastore n'est pas accessible via une connexion réseau (base locale)
  • | | localID | text | Identifiant du datastore sur la machine. Identifiant du datastore sur la machine. Chaîne vide ("") pour le datastore principal. | | connection | object | Objet décrivant la connexion au datastore distant (non retourné pour le datastore principal). Propriétés disponibles:
    PropriétéTypeDescription
    hostnametextAdresse IP ou nom du datastore distant + ":" + numéro de port
    tlsbooleannTrue si une connexion sécurisée est utilisée avec le datastore distant
    idleTimeoutnumberDélai d'inactivité de la session (en minutes)
    usertextUtilisateur authentifié sur le datastore distant
    | @@ -524,7 +524,7 @@ Sur un datastore distant : #### Description -La fonction `.getRemoteContextInfo()` renvoie un objet qui contient des informations sur le contexte d'optimisation *contextName* dans le datastore. +La fonction `.getRemoteContextInfo()` renvoie un objet qui contient des informations sur le contexte d'optimisation *contextName* dans le datastore.. Pour plus d'informations sur la façon dont les contextes peuvent être créés, voir [Optimisation client/serveur](../ORDA/client-server-optimization.md#optimization-context). @@ -1064,12 +1064,12 @@ Pour une description du format du journal des requêtes ORDA, veuillez vous réf Pour créer un journal des requêtes ORDA côté client, appelez cette fonction sur une machine distante. Le journal peut être envoyé à un fichier ou en mémoire, selon le type de paramètre : -- Si vous avez passé un objet *file* créé à l'aide de la commande `File`, les données de l'enregistrement sont écrites dans ce fichier sous forme de collection d'objets (format JSON). Chaque objet représente une requête.
    Si le fichier n'existe pas encore, il est créé. Sinon, s'il existe déjà, les nouvelles données d'enregistrement y sont ajoutées. +- Si vous avez passé un objet *file* créé à l'aide de la commande `File`, les données de l'enregistrement sont écrites dans ce fichier sous forme de collection d'objets (format JSON). Si vous avez passé un objet *file* créé à l'aide de la commande `File`, les données de l'enregistrement sont écrites dans ce fichier sous forme de collection d'objets (format JSON).Si le fichier n'existe pas encore, il est créé. Sinon, s'il existe déjà, les nouvelles données d'enregistrement y sont ajoutées. Si la fonction `.startRequestLog()` est appelée avec un fichier alors qu'un enregistrement des requêtes est déjà en cours en mémoire, l'enregistrement en mémoire est stoppé et vidé. > Un caractère \] doit être ajouté manuellement à la fin du fichier pour effectuer une validation JSON -- Si vous avez passé un numéro *reqNum*, l'enregistrement en mémoire est vidé (le cas échéant) et un nouvel enregistrement est lancé. Il gardera en mémoire les requêtes jusqu'à atteindre le nombre *reqNum*, auquel cas les entrées les plus anciennes sont vidées (pile FIFO).
    Si la fonction `.startRequestLog()` est appelée avec un *reqNum* alors qu'un enregistrement des requêtes était déjà en cours dans un fichier, l'enregistrement dans le fichier est stoppé. +- Si vous avez passé un numéro *reqNum*, l'enregistrement en mémoire est vidé (le cas échéant) et un nouvel enregistrement est lancé. Si vous avez passé un numéro *reqNum*, l'enregistrement en mémoire est vidé (le cas échéant) et un nouvel enregistrement est lancé.Il conserve les demandes *reqNum* en mémoire jusqu'à ce que le nombre soit atteint, auquel cas les entrées les plus anciennes sont vidées (pile FIFO).
    - Si vous n'avez passé aucun paramètre, l'enregistrement est lancé dans la mémoire. Si `.startRequestLog()` a été préalablement appelée avec un *reqNum* (avant un `.stopRequestLog()`), les données enregistrées sont empilées dans la mémoire jusqu'au prochain vidage ou appel de `.stopRequestLog()`. From fd174d37308ae3203907de0fef406546fad0130f Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 15:55:19 +0100 Subject: [PATCH 155/195] datastoreclass.md Spanish --- .../version-21-R5/API/DataStoreClass.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/i18n/es/docusaurus-plugin-content-docs/version-21-R5/API/DataStoreClass.md b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/API/DataStoreClass.md index 5e26815a43b39b..58003eb5d415be 100644 --- a/i18n/es/docusaurus-plugin-content-docs/version-21-R5/API/DataStoreClass.md +++ b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/API/DataStoreClass.md @@ -457,7 +457,7 @@ La función `.getInfo()` devuelve | Propiedad | Tipo | Descripción | | ---------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | type | string |
  • "4D": datastore principal, disponible a través de ds
  • "4D Server": datastore remoto, abrir con Open datastore
  • | -| networked | boolean |
  • True: el datastore se alcanza a través de una conexión de red.
  • False: el datastore no se alcanza a través de una conexión de red (base de datos local)
  • | +| networked | boolean |
  • True: el almacén de datos se alcanza a través de una conexión de red.
  • False: no se llega al almacén de datos a través de una conexión de red (base de datos local)
  • | | localID | text | ID del almacén de datos en la máquina. ID del almacén de datos en la máquina. Cadena vacía ("") para el almacén de datos principal. | | connection | object | Objeto que describe la conexión del almacén de datos remoto (no se devuelve para el almacén de datos principal). Propiedades disponibles:
    PropiedadTipoDescripción
    nombre de hosttextoDirección IP o nombre del datastore remoto + ":" + número de puerto
    tlsbooleanoTrue si se utiliza una conexión segura con el datastore remoto
    idleTimeoutnúmeroTiempo de inactividad de la sesión (en minutos)
    usuariotextoUsuario autenticado en el almacén de datos remoto
    | @@ -524,7 +524,7 @@ En un almacén de datos remoto: #### Descripción -La función `.getRemoteContextInfo()` devuelve un objeto que contiene información sobre el contexto de optimización *contextName* en el datastore. +La función `.getRemoteContextInfo()` devuelve un objeto que contiene información sobre el contexto de optimización *contextName* en el datastore.. Para obtener más información sobre cómo se pueden crear contextos de optimización, consulte [optimización cliente/servidor](../ORDA/client-server-optimization.md#optimization-context). @@ -1063,13 +1063,13 @@ Para una descripción del formato del registro de peticiones ORDA, por favor con Para crear un registro de peticiones ORDA del lado del cliente, llame a esta función en una máquina remota. El registro puede enviarse a un archivo o a la memoria, según el tipo de parámetro: -- Si se pasa un objeto *file* creado con el comando `File`, los datos de registro se escriben en este archivo como una colección de objetos (formato JSON). Cada objeto representa una petición.
    Si el archivo no existe ya, se crea. En caso contrario, si el archivo ya existe, los nuevos datos de registro se añaden a él. +- Si se pasa un objeto *file* creado con el comando `File`, los datos de registro se escriben en este archivo como una colección de objetos (formato JSON). Cada objeto representa una petición.
    Si el archivo no existe, se crea. En caso contrario, si el archivo ya existe, los nuevos datos de registro se añaden a él. En caso contrario, si el archivo ya existe, los nuevos datos de registro se añaden a él. Si se llama a `.startRequestLog()` con un archivo mientras se inició previamente un registro en memoria, el registro en memoria se detiene y se vacía. > Debe añadirse manualmente un carácter \N al final del archivo para realizar una validación JSON -- Si se pasa un entero *reqNum*, se vacía el registro en memoria (si lo hay) y se inicializa un nuevo registro. Mantendrá *reqNum* en memoria las peticiones hasta que se alcance el número, en cuyo caso se vacían las entradas más antiguas (pila FIFO).
    Si se llama a `.startRequestLog()` con un *reqNum* mientras se ha iniciado previamente un registro en un archivo, se detiene el registro en el archivo. +- Si se pasa un entero *reqNum*, se vacía el registro en memoria (si lo hay) y se inicializa un nuevo registro. Si se pasa un entero *reqNum*, se vacía el registro en memoria (si lo hay) y se inicializa un nuevo registro.Conserva las peticiones *reqNum* en memoria hasta que se alcance el número, en cuyo caso se vacían las entradas más antiguas (pila FIFO).
    - Si no ha pasado ningún parámetro, el registro se inicia en la memoria. Si `.startRequestLog()` fue llamado previamente con un *reqNum* (antes de una `.stopRequestLog()`), los datos del registro se apilan en memoria hasta la próxima vez que se vacíe el registro o se llame a `.stopRequestLog()`. From 3a31741c1dc751c4efaf1969a5ead58cbdbed15d Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 15:55:41 +0100 Subject: [PATCH 156/195] entityclass.md French --- .../version-21-R5/API/EntityClass.md | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/API/EntityClass.md b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/API/EntityClass.md index d8a0740e3397d8..36658fb937d632 100644 --- a/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/API/EntityClass.md +++ b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/API/EntityClass.md @@ -399,15 +399,15 @@ L'objet renvoyé par `.drop()` contient les propriétés suivantes : (\*) Les valeurs suivantes peuvent être retournées dans les propriétés *status* et *statusText* de l'objet *Résultat* en cas d'erreur : -| Constante | Valeur | Commentaire | -| ----------------------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `dk status entity does not exist anymore` | 5 | L'entité n'existe plus dans les données. Cette erreur peut se produire dans les cas suivants:
  • l'entité a été supprimée (le marqueur a changé et l'espace mémoire est maintenant libre)
  • l'entité a été supprimée et remplacée par une autre avec une autre clé primaire (le marqueur a changé et une nouvelle entité utilise maintenant l'espace mémoire). Lors de l'utilisation de entity.drop(), cette erreur peut être renvoyée lorsque l'option dk force drop if stamp changed est utilisée. Lors de l'utilisation de entity.lock(), cette erreur peut être renvoyée lorsque l'option dk reload if stamp changed est utilisée.
  • **statusText associé** : "Entity does not exist anymore" | -| `dk status locked` | 3 | L'entité est verrouillée par un verrou pessimiste.
    **statusText associé** : "Already locked" | -| `dk status validation failed` | 7 | Erreur non fatale envoyée par le développeur pour un [événement de validation](../ORDA/orda-events.md). **statusText associé**: "Mild Validation Error" | -| `dk status serious error` | 4 | Une erreur critique peut être une erreur de bas niveau de la base de données (ex. clé dupliquée), une erreur matérielle, etc.
    **statusText associé** : "Other error" | -| `dk status serious validation error` | 8 | Erreur critique envoyée par le développeur pour un [événement de validation](../ORDA/orda-events.md). **statusText associé**: "Serious Validation Error" | -| `dk status stamp has changed` | 2 | La valeur interne du stamp de l'entité ne correspond pas à celle de l'entité stockée dans les données (verrouillage optimiste).
  • avec `.save()` : erreur seulement si l'option `dk auto merge` n'est pas utilisée
  • avec `.drop()` : erreur seulement si l'option `dk force drop if stamp changed` n'est pas utilisée
  • avec `.lock()` : erreur seulement si l'option `dk reload if stamp changed` n'est pas utilisée
  • **statusText associé** : "Stamp has changed"
  • | -| `dk status wrong permission` | 1 | Les privilèges courants ne permettent pas de supprimer l'entité. **statusText associé** : "Permission error" | +| Constante | Valeur | Commentaire | +| ----------------------------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `dk status entity does not exist anymore` | 5 | L'entité n'existe plus dans les données. Cette erreur peut se produire dans les cas suivants:
  • l'entité a été supprimée (le marqueur a changé et l'espace mémoire est maintenant libre)
  • l'entité a été supprimée et remplacée par une autre avec une autre clé primaire (le marqueur a changé et une nouvelle entité utilise maintenant l'espace mémoire). Lors de l'utilisation de entity.drop(), cette erreur peut être renvoyée lorsque l'option dk force drop if stamp changed est utilisée. Lors de l'utilisation de entity.lock(), cette erreur peut être renvoyée si l'option dk reload if stamp changed est utilisée.
  • \*\*statusText associé : "Entity does not exist anymore" | +| `dk status locked` | 3 | L'entité est verrouillée par un verrou pessimiste.
    **statusText associé** : "Already locked" | +| `dk status validation failed` | 7 | Erreur non fatale envoyée par le développeur pour un [événement de validation](../ORDA/orda-events.md). **statusText associé**: "Mild Validation Error" | +| `dk status serious error` | 4 | Une erreur critique peut être une erreur de bas niveau de la base de données (ex. clé dupliquée), une erreur matérielle, etc.
    **statusText associé** : "Other error" | +| `dk status serious validation error` | 8 | Erreur critique envoyée par le développeur pour un [événement de validation](../ORDA/orda-events.md). **statusText associé**: "Serious Validation Error" | +| `dk status stamp has changed` | 2 | La valeur du marqueur interne (stamp) de l'entité ne correspond pas à celle de l'entité stockée dans les données (verrouillage optimiste).
  • avec `.save()` : erreur seulement si l'option `dk auto merge` n'est pas utilisée
  • avec `.drop()` : erreur seulement si l'option `dk force drop if stamp changed` n'est pas utilisée
  • avec `.lock()` : erreur seulement si l'option `dk reload if stamp changed` n'est pas utilisée

  • **Associated statusText** : "Stamp has changed" | +| `dk status wrong permission` | 1 | Les privilèges courants ne permettent pas de supprimer l'entité. **statusText associé** : "Permission error" | #### Exemple 1 @@ -1058,7 +1058,7 @@ L'objet retourné par `.lock()` contient les propriétés suivantes : | `dk status entity does not exist anymore` | 5 | L'entité n'existe plus dans les données. Cette erreur peut se produire dans les cas suivants:
  • l'entité a été supprimée (le marqueur a changé et l'espace mémoire est maintenant libre)
  • l'entité a été supprimée et remplacée par une autre avec une autre clé primaire (le marqueur a changé et une nouvelle entité utilise maintenant l'espace mémoire). Lors de l'utilisation de `.drop()`, cette erreur peut être retournée lorsque l'option dk force drop if stamp changed est utilisée. Lors de l'utilisation de `.lock()`, cette erreur peut être retournée lorsque l'option `dk reload if stamp changed` est utilisée

  • **statusText associé** : "Entity does not exist anymore" | | `dk status locked` | 3 | L'entité est verrouillée par un verrou pessimiste.
    **statusText associé** : "Already locked" | | `dk status serious error` | 4 | Une erreur critique peut être une erreur de bas niveau de la base de données (ex. clé dupliquée), une erreur matérielle, etc.
    **statusText associé** : "Other error" | -| `dk status stamp has changed` | 2 | La valeur du stamp interne de l'entité ne correspond pas à celle de l'entité stockée dans les données (verrouillage optimiste).
  • avec `.save()` : erreur seulement si l'option `dk auto merge` n'est pas utilisée
  • avec `.drop()` : erreur seulement si l'option `dk force drop if stamp changed` n'est pas utilisée
  • avec `.lock()`: erreur seulement si l'option `dk reload if stamp changed` n'est pas utilisée

  • **statusText associé** : "Stamp has changed" | +| `dk status stamp has changed` | 2 | La valeur du marqueur interne (stamp) de l'entité ne correspond pas à celle de l'entité stockée dans les données (verrouillage optimiste).
  • avec `.save()` : erreur seulement si l'option `dk auto merge` n'est pas utilisée
  • avec `.drop()` : erreur seulement si l'option `dk force drop if stamp changed` n'est pas utilisée
  • avec `.lock()` : erreur seulement si l'option `dk reload if stamp changed` n'est pas utilisée

  • **statusText associé** : "Stamp has changed" | #### Exemple 1 @@ -1334,7 +1334,7 @@ Les valeurs suivantes peuvent être retournées dans les propriétés `status` e | `dk status validation failed` | 7 | Erreur non fatale envoyée par le développeur pour un [événement de validation](../ORDA/orda-events.md). **statusText associé**: "Mild Validation Error" | | `dk status serious error` | 4 | Une erreur critique peut être une erreur de bas niveau de la base de données (ex. clé dupliquée), une erreur matérielle, etc. **statusText associé** : "Other error" | | `dk status serious validation error` | 8 | Erreur critique envoyée par le développeur pour un [événement de validation](../ORDA/orda-events.md). **statusText associé**: "Serious Validation Error" | -| `dk status stamp has changed` | 2 | La valeur du marqueur interne de l'entité ne correspond pas à celle de l'entité stockée dans les données (verrouillage optimiste).
  • avec `.save()`: erreur uniquement si l'option `dk auto merge` n'est pas utilisée
  • avec `.drop()`: erreur uniquement si l'option `dk force drop if stamp changed` n'est pas utilisée
  • avec `.lock()`: erreur uniquement si l'option `dk reload if stamp changed` n'est pas utilisée

  • **StatusText associé**: "Stamp has changed" | +| `dk status stamp has changed` | 2 | La valeur du marqueur interne (stamp) de l'entité ne correspond pas à celle de l'entité stockée dans les données (verrouillage optimiste).
  • avec `.save()` : erreur seulement si l'option `dk auto merge` n'est pas utilisée
  • avec `.drop()` : erreur uniquement si l'option `dk force drop if stamp changed` n'est pas utilisée
  • avec `.lock()` : erreur seulement si l'option `dk reload if stamp changed` n'est pas utilisée
  • **statusText associé** : "Stamp has chaged"
  • | | `dk status wrong permission` | 1 | Les privilèges courants ne permettent pas de supprimer l'entité. **statusText associé** : "Permission error" | #### Exemple 1 From d9bddcd97c684c3a79c25ec4605f21c39aab12c7 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 15:56:24 +0100 Subject: [PATCH 157/195] httprequestclass.md French --- .../version-21-R5/API/HTTPRequestClass.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/API/HTTPRequestClass.md b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/API/HTTPRequestClass.md index e551709aa5f01f..02ece52e0ff76f 100644 --- a/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/API/HTTPRequestClass.md +++ b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/API/HTTPRequestClass.md @@ -412,7 +412,7 @@ La propriété `.url` contient l'URL d ## .wait() -**.wait**( { *timeout* : Real } ) : 4D.HTTPRequest +**.wait**( { *time* : Real } ) : 4D.HTTPRequest From 3b76db5b8bf523431f97fd682813a30ab62f4992 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 15:56:38 +0100 Subject: [PATCH 158/195] imaptransporterclass.md French --- .../version-21-R5/API/IMAPTransporterClass.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/API/IMAPTransporterClass.md b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/API/IMAPTransporterClass.md index 6816ff744e187d..57d21497732143 100644 --- a/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/API/IMAPTransporterClass.md +++ b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/API/IMAPTransporterClass.md @@ -53,7 +53,7 @@ Les objets IMAP Transporter sont instanciés avec la commande [IMAP New transpor | Paramètres | Type | | Description | | ---------- | ---------------------------------- | :-------------------------: | -------------------------------------------------- | -| parameter | Object | -> | Configuration du serveur de messagerie | +| paramètres | Object | -> | Configuration du serveur de messagerie | | Résultat | 4D.IMAPTransporter | <- | [Objet transporteur IMAP](#objet-imap-transporter) | @@ -683,7 +683,7 @@ End if #### Description -La fonction `.expunge()` supprime tous les messages marqués "deleted" du serveur de messagerie IMAP. Le marqueur "deleted" peut être fixé avec les fonctions [`.delete()`](#delete) ou [`.addFlags()`](#addflags). +La fonction `.expunge()` supprime tous les messages avec le flag "deleted" du serveur de messagerie IMAP. Le flag "deleted" peut être défini avec les méthodes [`.delete()`](#delete) ou [`.addFlags()`](#addflags). **Objet retourné** @@ -835,7 +835,7 @@ Chaque objet de la collection retournée contient les propriétés suivantes : | \[].name | Text | Nom de la boîte de réception. Retourné si withBoxProperties=true ou withBoxInfo=true | | \[].selectable | Boolean | Indique si les droits d'accès permettent ou non de sélectionner la boîte aux lettres :
    • true - la boîte aux lettres peut être sélectionnée
    • false - la boîte aux lettres ne peut pas être sélectionnée
    Retourné si withBoxProperties=true | | \[].inferior | Boolean | Indique si les droits d'accès permettent ou non de créer une hiérarchie inférieure dans la boîte aux lettres :
    • true - un niveau inférieur peut être créé
    • false - un niveau inférieur ne peut pas être créé
    Retourné si withBoxProperties=true | -| \[].interesting | Boolean | Indique si la boîte aux lettres a été marquée comme "intéressante" par le serveur :
    • true - La boîte aux lettres a été marquée comme "intéressante" par le serveur. Par exemple, elle peut contenir de nouveaux messages.
    • false - La boîte aux lettres n'a pas été marquée comme "intéressante" par le serveur
    • .
    Retourné si withBoxProperties=true | +| \[].interesting | Boolean | Indique si la boîte aux lettres a été marquée comme "intéressante" par le serveur :
    • true - La boîte aux lettres a été marquée comme "intéressante" par le serveur. Par exemple, elle peut contenir de nouveaux messages.
    • faux - la boite de réception n'a pas été marquée comme "intéressante" par le serveur.
    Retourné si withBoxProperties=true | | [].mailCount | Number | Nombre de messages dans la boîte inbox. Retourné si withBoxInfo=true | | [].mailRecent | Number | Nombre de messages portant le marqueur "recent" (indiquant les nouveaux messages). Retourné si withBoxInfo=true | | [].mailUnseen | Number | Nombre de messages marqués "unseen". Retourné si withBoxInfo=true | @@ -969,7 +969,7 @@ Le paramètre facultatif *options* vous permet de passer un objet définissant d > - La fonction génère une erreur et retourne **Null** si *msgID* désigne un message non existant, > - Si aucune boite de réception n'est sélectionnée avec la [fonction `.selectBox()`](#selectbox), une erreur est générée, -> - S'il n'y a pas de connexion ouverte, `.getMail()` ouvrira une connexion avec la dernière boite de réception spécifiée à l'aide de [`.selectBox()`](#selectbox)\\\\`. +> - S'il n'y a pas de connexion ouverte, `.getMail()` ouvrira une connexion avec la dernière boite de réception spécifiée à l'aide de [`.selectBox()`](#selectbox)\\\`. #### Résultat @@ -1071,10 +1071,10 @@ Le paramètre optionnel *options* vous permet de définir les parties de message `.getMails()` retourne un objet contenant les collections suivantes : -| Propriété | Type | Description | -| --------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| list | Collection | Collection d'[objets Email](EmailObjectClass.md#objet-email). Si aucun objet Email n'est trouvé, une collection vide est retournée. | -| notFound | Collection | Collection de :
    • première syntaxe - ID de messages passés précédemment qui n'existent pas
    • deuxième syntaxe - numéros de séquence des messages entre startMsg et endMsg qui n'existent pas.
    Une collection vide est renvoyée si tous les messages ont été trouvés. | +| Propriété | Type | Description | +| --------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| list | Collection | Collection d'[objets Email](EmailObjectClass.md#objet-email). Si aucun objet Email n'est trouvé, une collection vide est retournée. | +| notFound | Collection | Collection de :
    • première syntaxe - ID de messages passés précédemment qui n'existent pas
    • deuxième syntaxe - numéros de séquence des messages entre startMsg et endMsg qui n'existent pas.
    Une collection vide est renvoyée si tous les messages ont été trouvés. | #### Exemple @@ -1589,7 +1589,7 @@ End if > Cette fonction est basée sur la spécification du [protocole IMAP](https://en.wikipedia.org/wiki/Internet_Message_Access_Protocol). -La fonction `.searchMails()` recherche les messages qui correspondent aux critères de recherche *searchCriteria* dans la boîte aux lettres courante. . . +La fonction `.searchMails()` recherche les messages qui correspondent aux critères de recherche *searchCriteria* dans la boîte aux lettres courante. . *searchCriteria* est un paramètre texte listant un ou plusieurs critères de recherche (voir [Mots-clés de recherche autorisés](#mots-cles-de-recherche-autorises) ci-dessous) associés ou non à des valeurs à rechercher. Un critère de recherche peut être composé d'un ou plusieurs éléments. Par exemple : From 2f9efd65beaa7ef0c666dd7fd84c5142db48a30f Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 15:57:57 +0100 Subject: [PATCH 159/195] udpsocketclass.md Japanese --- .../version-21-R5/API/UDPSocketClass.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/API/UDPSocketClass.md b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/API/UDPSocketClass.md index d33015ed99ac86..c7ca24f1434184 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/API/UDPSocketClass.md +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/API/UDPSocketClass.md @@ -50,7 +50,7 @@ UDPSocket オブジェクトは以下のプロパティと関数を提供しま | 引数 | 型 | | 説明 | | ------- | ---------------------------- | --------------------------- | ------------------------------------------------------------------------ | | port | Integer | -> | UDP ソケットに使用されるローカルのポート番号(0 または省略時には使用されていないポートを探して使用) | -| options | Object | -> | ソケットの接続[オプション](#options引数) | +| options | Object | -> | ソケットの接続[オプション](#options-引数) | | 戻り値 | 4D.UDPSocket | <- | 新規UDPSocket オブジェクト | From 2d635431a36ccb0f585263ffcc12d84189e2b0b5 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 15:58:32 +0100 Subject: [PATCH 160/195] websocketserverclass.md Japanese --- .../version-21-R5/API/WebSocketServerClass.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/API/WebSocketServerClass.md b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/API/WebSocketServerClass.md index 80c0e06aa26048..09d2a346b74a78 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/API/WebSocketServerClass.md +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/API/WebSocketServerClass.md @@ -37,7 +37,7 @@ WebSocketプロトコルは、WebSocketサーバーとクライアント (Webブ - サーバー接続を処理するためのユーザークラス - メッセージを処理するためのユーザークラス -接続を維持するため、[WebSocketサーバーの作成](#4dwebsocketservernew) は [ワーカー](../Develop/processes.md#worker-プロセス) 内にて行う必要があります。 +接続を維持するため、[WebSocketサーバーの作成](#4dwebsocketservernew) は [ワーカー](../Develop/processes.md#ワーカープロセス) 内にて行う必要があります。 [4D Webサーバー](WebServerClass.md) を起動しておく必要があります。 From ab86f3fcb3c179cd1b24a08918b12e919a822cdd Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 16:02:44 +0100 Subject: [PATCH 161/195] labels.md Japanese --- .../version-21-R5/Desktop/labels.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/Desktop/labels.md b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/Desktop/labels.md index 70073d18ad1a8d..29b65f2314faab 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/Desktop/labels.md +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/Desktop/labels.md @@ -164,7 +164,7 @@ title: ラベル var myVar+=1 ``` -3. プロジェクトメソッドに対して["コンポーネントとホストデータベース間で共有"](../Project/project-method-properties.md#コンポーネントとホストデータベース間で共有) オプションを設定します。 +3. プロジェクトメソッドに対して["コンポーネントとホストデータベース間で共有"](../Project/project-method-properties.md#コンポーネントとホストプロジェクト間で共有) オプションを設定します。 4. ラベルエディターを表示する前に、以下のコードを実行してプロジェクトメソッドが確実に許可されているようにします: From 439ad00c85d9e836fa88550c7b40247e1741fa18 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 16:03:05 +0100 Subject: [PATCH 162/195] preemptive.md French --- .../version-21-R5/Develop/preemptive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/Develop/preemptive.md b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/Develop/preemptive.md index 548b17b1d76767..f910900c7a523f 100644 --- a/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/Develop/preemptive.md +++ b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/Develop/preemptive.md @@ -41,7 +41,7 @@ Le code 4D ne peut être exécuté dans un process préemptif que lorsque certai La propriété "thread safety" de chaque élément dépend de l'élément lui-même : -- Commandes 4D : la propriété thread-safe est une propriété interne. Dans la documentation 4D, les commandes thread-safe sont identifiées par l'icône ![](../assets/en/Develop/thread-safe.png). Vous pouvez également utiliser la commande [`Command name`](../commands/command-name) pour savoir si une commande est thread-safe. Une grande partie des commandes 4D peut s'exécuter en mode préemptif. +- Commandes 4D : la propriété thread-safe est une propriété interne. The 4D documentation indicates whether each command is thread-safe or not in the Properties section. Vous pouvez également utiliser la commande [`Command name`](../commands/command-name) pour savoir si une commande est thread-safe. Une grande partie des commandes 4D peut s'exécuter en mode préemptif. - Méthodes projet : les conditions pour être thread-safe sont répertoriées dans [ce paragraphe](#writing-a-thread-safe-method). Fondamentalement, le code à exécuter dans des threads préemptifs ne peut pas appeler des parties avec des interactions externes, telles que du code de plug-in ou des variables interprocess. Cependant, l'accès aux données est autorisé car le serveur de données 4D et ORDA prennent en charge l'exécution préemptive. From 7d103891f6958b6eaae601ffa51eea239bf40530 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 16:03:08 +0100 Subject: [PATCH 163/195] preemptive.md Spanish --- .../version-21-R5/Develop/preemptive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/es/docusaurus-plugin-content-docs/version-21-R5/Develop/preemptive.md b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/Develop/preemptive.md index 3d68172398d401..6d49343ef332ff 100644 --- a/i18n/es/docusaurus-plugin-content-docs/version-21-R5/Develop/preemptive.md +++ b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/Develop/preemptive.md @@ -41,7 +41,7 @@ Dado que un hilo se maneja de forma independiente a partir del método del proce La propiedad "seguridad de hilo" de cada elemento depende del elemento en sí: -- Comandos 4D: hilo seguro es una propiedad interna. En la documentación de 4D, los comandos hilo seguro se identifican con el icono ![](../assets/en/Develop/thread-safe.png). También puede utilizar el comando [`Nombre del comando`](../commands/command-name) para saber si un comando es hilo seguro. Gran parte de los comandos 4D pueden ejecutarse en modo apropiativo. +- Comandos 4D: hilo seguro es una propiedad interna. The 4D documentation indicates whether each command is thread-safe or not in the Properties section. También puede utilizar el comando [`Nombre del comando`](../commands/command-name) para saber si un comando es hilo seguro. Gran parte de los comandos 4D pueden ejecutarse en modo apropiativo. - Métodos de proyecto: las condiciones para seguridad de hilo se listan en [este párrafo](#writing-a-thread-safe-method). Básicamente, el código que se ejecuta en hilos apropiativos no puede llamar a las partes con las interacciones externas, tal como el código plug-in o las variables interproceso. Los accesos a los datos, sin embargo, son permitidos desde el servidor de datos 4D que soporta la ejecución apropiativa. From 6c9853b94f0c2cac7e9b5fbad837d1f7cd979730 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 16:03:12 +0100 Subject: [PATCH 164/195] preemptive.md Japanese --- .../version-21-R5/Develop/preemptive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/Develop/preemptive.md b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/Develop/preemptive.md index 8f3647df6fbe95..15b0b4faa7ef73 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/Develop/preemptive.md +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/Develop/preemptive.md @@ -41,7 +41,7 @@ title: プリエンプティブプロセス 要素毎の "スレッドセーフティ" プロパティは、その要素自身によります: -- 4Dコマンド: スレッドセーフティは内部プロパティです。 4D ドキュメンテーション内においては、スレッドセーフなコマンドには ![](../assets/en/Develop/thread-safe.png) アイコンが表示されています。 [`Command name`](../commands/command-name) コマンドを使用して、コマンドがスレッドセーフであるかどうかを知ることもできます。 4Dコマンドの大部分はプリエンプティブモードで実行可能です。 +- 4Dコマンド: スレッドセーフティは内部プロパティです。 The 4D documentation indicates whether each command is thread-safe or not in the Properties section. [`Command name`](../commands/command-name) コマンドを使用して、コマンドがスレッドセーフであるかどうかを知ることもできます。 4Dコマンドの大部分はプリエンプティブモードで実行可能です。 - プロジェクトメソッド: スレッドセーフであるための条件は [こちらの段落](#スレッドセーフなメソッドの書き方) にまとめられています。 原則として、プリエンプティブスレッド内で実行されるコードは外部との相互作用する部分、たとえばプラグインコードやインタープロセス変数などを呼び出すことはできません。しかしながら、4Dデータサーバーと ORDA はプリエンプティブ実行をサポートしていることから、データアクセスは可能です。 From 1fccfcb86c6e303153604849a78b2afbec3d53b4 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 16:03:17 +0100 Subject: [PATCH 165/195] processes.md Japanese --- .../version-21-R5/Develop/processes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/Develop/processes.md b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/Develop/processes.md index d7eb693b4a3da8..65c53df3caa564 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/Develop/processes.md +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/Develop/processes.md @@ -50,7 +50,7 @@ title: プロセスとワーカー ### インターフェース要素 -インターフェース要素は、[デスクトップアプリケーション](../category/desktop-applications) で使用されます。 以下のものがあります: 以下のものがあります: +インターフェース要素は、[デスクトップアプリケーション](../category/desktop-applications) で使用されます。以下のものがあります: - [メニューバー](../Menus/creating.md): 各プロセスは、独自のカレントメニューバーを持つことができます。最前面のプロセスのメニューバーがアプリケーションのカレントメニューバーになります。 - 1つ以上のウィンドウ: 各プロセスは、1つまたは複数のウィンドウを同時に開くことができます。他方、ウィンドウをまったく持たないプロセスもあります。 From a5095af86ef4dc15f469b1a03757fa0f40aa46c5 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 16:03:24 +0100 Subject: [PATCH 166/195] structure-indexes.md French --- .../version-21-R5/Develop/structure-indexes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/Develop/structure-indexes.md b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/Develop/structure-indexes.md index d831a6fda84d21..2f897e2c80f683 100644 --- a/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/Develop/structure-indexes.md +++ b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/Develop/structure-indexes.md @@ -147,7 +147,7 @@ Pour ajouter un champ à l'index, cliquez sur le bouton **[+]**. La liste des ch - Si vous souhaitez créer un index composite, ajoutez successivement chaque champ à inclure dans l'index. Une fois la liste complétée, vous pouvez réorganiser les champs à l'aide des boutons fléchés ou par glisser-déposer. - Si vous créez un index composite basé sur les champs de la clé primaire, veillez à ce que l'ordre des champs soit identique dans la clé primaire et dans l'index. -- Si vous avez choisi le type "Index de mots-clés", seuls les champs Alpha ou Texte peuvent être sélectionnés. Dans ce cas également, vous ne pouvez inclure qu'un seul champ dans l'index. +- If you have chosen the “Keyword Index” type, only Alpha, Text, or Picture fields can be selected. Also in this case, you can include only one field in the index. Pour supprimer un champ de l'index, sélectionnez-le dans la liste et cliquez sur le bouton **[-]**. From f3d3ea5da5682e7dba7da76365e757bc846a50dd Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 16:03:27 +0100 Subject: [PATCH 167/195] structure-indexes.md Spanish --- .../version-21-R5/Develop/structure-indexes.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/i18n/es/docusaurus-plugin-content-docs/version-21-R5/Develop/structure-indexes.md b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/Develop/structure-indexes.md index 0f30ac45b441df..2e75ed028fb22b 100644 --- a/i18n/es/docusaurus-plugin-content-docs/version-21-R5/Develop/structure-indexes.md +++ b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/Develop/structure-indexes.md @@ -1,11 +1,11 @@ --- id: structure-indexes -title: Indexes +title: Índices --- -You can associate indexes with fields that you frequently use for searching and sorting. For example, you might index LastName, CompanyName, or ProductName if you plan to search or sort entities using these attributes. You also use this property for fields that establish relations between tables. +Puede asociar índices con campos que utiliza frecuentemente para buscar y ordenar. Por ejemplo, puede indexar LastName, CompanyName o ProductName si planea buscar o ordenar entidades usando estos atributos. También utiliza esta propiedad para campos que establecen relaciones entre las tablas. -When an index is associated with a field, 4D creates an internal index table for the field. This table allows 4D to perform rapid searches and sorts on the field. When searching or sorting on an unindexed field, 4D moves through data sequentially, examining each record in order. Indexing allows 4D to search and sort without going through every record. +Cuando un índice está asociado con un campo, 4D crea una tabla de índice interna para el campo. Esta tabla permite a 4D realizar búsquedas y ordenaciones rápidas en ese campo. Al buscar o ordenar en un campo indexado, 4D se mueve a través de datos secuencialmente, examinando cada registro en el orden. La indexación permite a 4D realizar búsquedas y ordenar los datos sin tener que revisar todos los registros. You can index fields of the Alpha, Text, Date, Time, Boolean, Integer, Long integer, Integer 64 bits, Real, Picture and Object type. As you add and delete records, 4D automatically updates its index table. If you create an index for a field that already exists, 4D automatically indexes the existing data. You can specify as many indexed fields as you want. Indexes are also rebuilt during specific operations such as conversion of earlier databases or [data compacting](../MSC/compact.md). @@ -105,7 +105,7 @@ The ![](../assets/en/Develop/index-list.png) button of the toolbar in the Struct The Index List can be used to view the main properties of the indexes: -- **Type:** Index type. Each type of index (B-tree, Cluster B-tree, Keyword, Euclidean, Cosine, Dot) is depicted with a different icon. +- **Tipo:** tipo de índice. Each type of index (B-tree, Cluster B-tree, Keyword, Euclidean, Cosine, Dot) is depicted with a different icon. - **Description:** Table and field(s) of index. For a composite index, this list contains all the fields of the index. - **Name:** Index name. This property is used in particular by the language commands. You can change or add an index name by double-clicking in this column. @@ -147,7 +147,7 @@ To add a field to the index, click on the **[+]** button. The list of fields of - If you want to create a composite index, add each field to be included in the index successively. Once the list is completed, you can reorder the fields using the arrow buttons or using drag and drop. - If you create a composite index based on primary key fields, make sure you put the fields in the same order in the primary key and in the index. -- If you have chosen the “Keyword Index” type, only Alpha or Text fields can be selected. Also in this case, you cannot include only one field in the index. +- If you have chosen the “Keyword Index” type, only Alpha, Text, or Picture fields can be selected. Also in this case, you can include only one field in the index. To delete a field from the index, select it in the list and click on the **[-]** button. From 75140ea7fae1d95d2d8932f9e873dfe62fd2bfb3 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 16:03:31 +0100 Subject: [PATCH 168/195] structure-indexes.md Japanese --- .../version-21-R5/Develop/structure-indexes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/Develop/structure-indexes.md b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/Develop/structure-indexes.md index 51fb40856f799a..900653e927faf4 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/Develop/structure-indexes.md +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/Develop/structure-indexes.md @@ -144,7 +144,7 @@ QUERY([PICTURES];[PICTURES]Photos %"cats") - 複合インデックスを作成するには、インデックスに含めるフィールドを複数選択します。フィールドリストが完成したら、矢印ボタンやドラッグ&ドロップを使用してフィールドの並びを変更できます。 - 主キーフィールドをもとに複合インデックスを作成する場合、フィールドの並び順が主キーとインデックスとで同じ順番になるようにしてください。 -- If you have chosen the “Keyword Index” type, only Alpha or Text fields can be selected. Also in this case, you cannot include only one field in the index. +- “キーワードインデックス”タイプは文字やテキスト、またはピクチャーフィールドタイプでのみ使用できます。またこの場合、インデックスに含めることができるのは1つのフィールドのみです。 インデックスからフィールドを削除するには、リスト中でそれを選択し、 **[-]** ボタンをクリックします。 From e65c1d634b4eba0909667bcda0331cfb797c7558 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 16:07:53 +0100 Subject: [PATCH 169/195] createstylesheet.md Japanese --- .../version-21-R5/FormEditor/createStylesheet.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/FormEditor/createStylesheet.md b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/FormEditor/createStylesheet.md index 95135802fba700..c04b7efede079d 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/FormEditor/createStylesheet.md +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/FormEditor/createStylesheet.md @@ -126,7 +126,7 @@ text.center { } ``` -4D フォームの詳細では、[CSSクラス](../FormObjects/properties_Object.md#cssクラス) 属性を使用してクラス名を割り当てます。この属性には一つ以上のクラス名を指定することができます。 複数の場合はクラス名を半角スペースで区切ります: +4D フォームの詳細では、[CSSクラス](../FormObjects/properties_Object.md#cssクラス) 属性を使用してクラス名を割り当てます。この属性には一つ以上のクラス名を指定することができます。複数の場合はクラス名を半角スペースで区切ります: ```css class: "okButtons important" From 06f838896f59a95bcbdd28bb51eab543bd5eb5f7 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 16:09:03 +0100 Subject: [PATCH 170/195] button_overview.md Japanese --- .../version-21-R5/FormObjects/button_overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/FormObjects/button_overview.md b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/FormObjects/button_overview.md index fecdf422a61587..02cd7b02532fde 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/FormObjects/button_overview.md +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/FormObjects/button_overview.md @@ -345,7 +345,7 @@ Windows Classic UI テーマでは、このスタイルはサポートされま [カスタム](#カスタム) スタイルのボタンに対しては特有の追加のプロパティが利用可能です: -[背景パス名](properties_TextAndPicture.md#背景パス名) - [境界線カラー](./properties_BackgroundAndBorder.md#境界線カラー) - [境界線幅](./properties_BackgroundAndBorder.md#境界線幅) - [横方向マージン](properties_TextAndPicture.md#横方向マージン) - [アイコンオフセット](properties_TextAndPicture.md#アイコンオフセット) - [縦方向マージン](properties_TextAndPicture.md#縦方向マージン) - [角の半径](properties_CoordinatesAndSizing.md#角の半径) - [デフォルトボタン](properties_Appearance.md#デフォルトボタン) - [塗りカラー](./properties_BackgroundAndBorder.md#背景色塗りカラー) +[背景パス名](properties_TextAndPicture.md#背景パス名) - [境界線カラー](./properties_BackgroundAndBorder.md#border-color) - [境界線幅](./properties_BackgroundAndBorder.md#境界線幅) - [横方向マージン](properties_TextAndPicture.md#横方向マージン) - [アイコンオフセット](properties_TextAndPicture.md#アイコンオフセット) - [縦方向マージン](properties_TextAndPicture.md#縦方向マージン) - [角の半径](properties_CoordinatesAndSizing.md#角の半径) - [デフォルトボタン](properties_Appearance.md#デフォルトボタン) - [塗りカラー](./properties_BackgroundAndBorder.md#背景色塗りカラー) ### フラットおよび通常ボタンにおける追加のプロパティ From a9eb6035196692eee856b4e962d285e97a0d19b2 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 16:09:10 +0100 Subject: [PATCH 171/195] checkbox_overview.md Japanese --- .../version-21-R5/FormObjects/checkbox_overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/FormObjects/checkbox_overview.md b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/FormObjects/checkbox_overview.md index 080be1d0eaaa86..5b9373e65e4647 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/FormObjects/checkbox_overview.md +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/FormObjects/checkbox_overview.md @@ -396,7 +396,7 @@ Office XP スタイルのチェックボックスの反転表示と背景のカ [カスタム](#カスタム) スタイルのチェックボックスに対しては特有の追加のプロパティが利用可能です: -[背景パス名](properties_TextAndPicture.md#背景パス名) - [境界線カラー](./properties_BackgroundAndBorder.md#境界線カラー) - [境界線幅](./properties_BackgroundAndBorder.md#境界線幅) - [横方向マージン](properties_TextAndPicture.md#横方向マージン) - [アイコンオフセット](properties_TextAndPicture.md#アイコンオフセット) - [縦方向マージン](properties_TextAndPicture.md#縦方向マージン) - [角の半径](properties_CoordinatesAndSizing.md#角の半径) - [塗りカラー](./properties_BackgroundAndBorder.md#背景色塗りカラー) +[背景パス名](properties_TextAndPicture.md#背景パス名) - [境界線カラー](./properties_BackgroundAndBorder.md#border-color) - [境界線幅](./properties_BackgroundAndBorder.md#境界線幅) - [横方向マージン](properties_TextAndPicture.md#横方向マージン) - [アイコンオフセット](properties_TextAndPicture.md#アイコンオフセット) - [縦方向マージン](properties_TextAndPicture.md#縦方向マージン) - [角の半径](properties_CoordinatesAndSizing.md#角の半径) - [塗りカラー](./properties_BackgroundAndBorder.md#背景色塗りカラー) ### フラットおよび通常チェックボックスにおける追加のプロパティ From 1af0ceb3cbeeb74d743a604ad6f741293a29e5ef Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 16:10:41 +0100 Subject: [PATCH 172/195] properties_backgroundandborder.md Japanese --- .../properties_BackgroundAndBorder.md | 77 ++++++++++++------- 1 file changed, 48 insertions(+), 29 deletions(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/FormObjects/properties_BackgroundAndBorder.md b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/FormObjects/properties_BackgroundAndBorder.md index 659c3eb0e1ce96..c98697bfd7bd99 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/FormObjects/properties_BackgroundAndBorder.md +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/FormObjects/properties_BackgroundAndBorder.md @@ -27,7 +27,7 @@ title: 背景色と境界線 ## 背景色/塗りカラー -オブジェクトの背景色/塗りカラーを設定します。 It can be defined for some standard objects (`fill` JSON property) or ["custom style" objects](#custom-button-custom-check-box-or-custom-radio-button) (`borderFillColor` JSON property). +オブジェクトの背景色/塗りカラーを設定します。一部の標準のオブジェクト(`fill` JSON プロパティを使用) あるいは["custom style" オブジェクト](#custom-button-custom-check-box-or-custom-radio-button)(`borderFillColor` JSON プロパティを使用) に対して定義することが可能です。 :::note @@ -105,17 +105,17 @@ title: 背景色と境界線 ## 境界線カラー{#border-color} -Allows defining the border color. The effect of this property varies slightly depending on the type of object to which it is applied. +境界線のカラーを定義することができます。このプロパティの効果は、適用されるオブジェクトのタイプによって若干異なります。 -- **objects with text properties**: [buttons](./button_overview.md) (all styles except "custom", see below), [hierarchical lists](list_overview.md), [inputs](input_overview.md), [list boxes](listbox_overview.md), [progress indicators](./progressIndicator.md), [rulers](./ruler.md), and [text areas](text.md). - By default, the border color of these objects is automatically set to their [**font color**](./properties_Text.md#font-color) property. This default configuration corresponds to the **Same as font** option in the Property List (`borderColor` property is undefined in JSON). - You can separate these two properties by setting a color value for the object's "Border color" property (only available when the [**border line style**](#border-line-style) property is **plain** (`solid` in JSON property) or **dotted**). +- **テキストプロパティを持つオブジェクト**: [ボタン](./button_overview.md) ("カスタム" を除く全てのスタイル、詳細は以下参照)、[階層リスト](list_overview.md)、[入力](input_overview.md)、[リストボックス](listbox_overview.md)、[進捗インジケーター](./progressIndicator.md)、[ルーラー](./ruler.md), and [text areas](text.md)。 + デフォルトで、これらのオブジェクトの境界線カラーは自動的に[**フォントカラー**](./properties_Text.md#フォントカラー) プロパティと同じに設定されています。このデフォルトの設定はプロパティリストの**Same as font** オプションに対応しています(`borderColor` プロパティはJSON では未定義です)。 + これらの二つのプロパティはオブジェクトの"境界線カラー" プロパティ([**境界線スタイル**](#border-line-style) プロパティが**実線** (JSON プロパティでは`solid`) あるいは **点線**のときのみ利用可能) にカラー値を設定することで分離させることができます。 -- **objects without text properties**: [4D View Pro areas](viewProArea_overview.md), [4D Write Pro areas](writeProArea_overview.md), [button grids](buttonGrid_overview.md), [picture buttons](pictureButton_overview.md), [picture pop-up menus](picturePopupMenu_overview.md), [plug-in areas](pluginArea_overview.md), [subforms](subform_overview.md), [spinners](spinner.md), [splitters](splitters.md), [steppers](stepper.md), [web areas](webArea_overview.md). - The border color property sets the color of the borders. The default color value is "Automatic", i.e. the border is displayed with the automatic color set by your OS. +- **テキストプロパティを持たないオブジェクト**: [4D View Pro エリア](viewProArea_overview.md)、[4D Write Pro エリア](writeProArea_overview.md)、[ボタングリッド](buttonGrid_overview.md)、[ピクチャーボタン](pictureButton_overview.md)、[ピクチャーポップアップメニュー](picturePopupMenu_overview.md)、[プラグインエリア](pluginArea_overview.md)、[サブフォーム](subform_overview.md)、[スピナー](spinner.md)、[スプリッター](splitters.md)、[ステッパー](stepper.md)、[Web エリア](webArea_overview.md)。 + 境界線カラープロパティは境界線のカラーを設定します。デフォルトのカラー値は"自動"で、これは境界線がOS によって設定されている自動カラーで表示されることを意味します。 -- **custom-styled buttons**: [custom buttons](./button_overview.md#custom) with ["custom" Border Line Style](#border-line-style), [custom check boxes](./checkbox_overview.md#custom), and [custom radio buttons](./radio_overview.md#custom). - In this case, the border color property defines the color of an *inner* border, which is an attribute of the object itself ans not a decoration property. This inner border can also have a [width](#border-width) (it is displayed only if the width > 0). +- **カスタムスタイルのボタン**: ["カスタム" 境界線スタイル](#border-line-style)をもった[カスタムボタン](./button_overview.md#カスタム)、[カスタムチェックボックス](./checkbox_overview.md#カスタム)、および[カスタムラジオボタン](./radio_overview.md#カスタム)。 + この場合、境界線カラープロパティーは*内側の* 境界線カラーを定義し、これはオブジェクト自身の属性であり、装飾プロパティではありません。内側の境界線は[幅](#border-width) を持つこともできます(幅が0 より大きい場合にのみ表示されます)。 #### JSON 文法 @@ -125,7 +125,26 @@ Allows defining the border color. The effect of this property varies slightly de #### 対象オブジェクト -[4D View Pro area](viewProArea_overview.md) - [4D Write Pro area](writeProArea_overview.md) - [Button](./button_overview.md) - [Button Grid](buttonGrid_overview.md) - [Check Box ("custom" style)](checkbox_overview.md#custom) - [Hierarchical List](list_overview.md) - [Input](input_overview.md) - [List Box](listbox_overview.md) - [Picture Button](pictureButton_overview.md) - [Picture Pop-up Menu](picturePopupMenu_overview.md) - [Plug-in Area](pluginArea_overview.md) - [Progress Indicator](./progressIndicator.md) - [Radio Button ("custom" style)](radio_overview.md#custom) - [Ruler](./ruler.md) - [Text Area](text.md) - [Spinner](spinner.md) - [Splitter](splitters.md) - [Stepper](stepper.md) - [Subform](subform_overview.md) - [Web Area](webArea_overview.md) +[4D View Pro エリア](viewProArea_overview.md) - +[4D Write Pro エリア](writeProArea_overview.md) - +[ボタン](button_overview.md) - +[ボタングリッド](buttonGrid_overview.md) - +[チェックボックス("カスタム"スタイル)](checkbox_overview.md#custom) - +[階層リスト](list_overview.md) - +[入力](input_overview.md) - +[リストボックス](listbox_overview.md) - +[ピクチャーボタン](pictureButton_overview.md) - +[ピクチャーポップアップメニュー](picturePopupMenu_overview.md) - +[プラグインエリア](pluginArea_overview.md) - +[進捗インジケーター](progressIndicator.md) - +[ラジオボタン("カスタム"スタイル)](radio_overview.md#custom) - +[ルーラー](ruler.md) - +[テキストエリア](text.md) - +[スピナー](spinner.md) - +[Splitter](splitters.md) - +[ステッパー](stepper.md) - +[サブフォーム](subform_overview.md) - +[Web エリア](webArea_overview.md) #### コマンド @@ -133,25 +152,25 @@ Allows defining the border color. The effect of this property varies slightly de #### 参照 -[Line Color](#line-color) (for shapes) +[線カラー](#線カラー) (図形用) ## 境界線スタイル{#border-line-style} -Allows setting a style for the object border. The following choices are available (all choices are not possible depending on the object): +オブジェクトの境界線のスタイルを設定することができます。以下の選択肢が利用可能です(オブジェクトによっては全ての選択肢が利用可能ではないこともあります): -| Style | Objects (\*) | 説明 | -| -------------- | -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| なし | all | Objects appear with no border. | -| Plain | all | Objects appear framed with a continuous 1-pt. border line. ("solid" json value) | -| Dotted | all | Objects appear framed with a dotted 1-pt. border line. | -| Raised | all | Objects appear framed with a 3D effect. | -| Sunken | all | Objects appear framed with a sunken 3D effect. | -| Double | all | Objects appear framed with a double line, i.e., two continuous 1-pt. lines separated by a pixel. | -| System | all *except* [buttons](button_overview.md) and [text areas](text.md) | Objects appear with a border line based on the graphic specifications of the OS. | -| System rounded | [inputs](input_overview.md) | On macOS, objects appear with a native "Liquid Glass" system border effect (for information about Liquid Glass, see [this 4D blog post](https://blog.4d.com/the-new-macos-tahoe-design-comes-to-your-4d-applications/)). It includes system-defined inner border, corner radius, grey border color, and inner padding. Note that the "Liquid Glass" appearance is *not* used in a multiline input object if the [scroll bars property](./properties_Appearance.md#vertical-scroll-bar) is enabled ("System" is used in this case).
    On Windows, this style is similar to "System" at runtime. | -| カスタム | [custom buttons](./button_overview.md#custom) | Enables the inner border design, that includes a set of extra properties: [Fill color](#fill-color), [Border color](#border-color), [Border width](#border-width), and [Corner radius](#corner-radius).
    ![](../assets/en/FormObjects/custom-button.png) | +| スタイル | オブジェクト(\*) | 説明 | +| --------- | --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| なし | all | オブジェクトは境界線なしで表示されます。 | +| 標準 | all | オブジェクトは連続した1pt の幅の境界線で表示されます。 ("solid" json 値) | +| ドット | all | オブジェクトは点線の1pt の幅の境界線で表示されます。 | +| 浮き上がり | all | オブジェクトは3D エフェクトの境界線で表示されます。 | +| くぼみ | all | オブジェクトは、くぼみ3D エフェクトの境界線で表示されます。 | +| 二重 | all | オブジェクトは連続した1pt の幅の二重線の境界線で表示されます。二重線は1ピクセル間の隙間で表示されます。 | +| システム | [ボタン](button_overview.md)および [テキストエリア](text.md) を *除く* 全て | オブジェクトはOS のグラフィック仕様に基づいた境界線で表示されます。 | +| システムの角の丸み | [入力](input_overview.md) | macOS では、オブジェクトはネイティブの"Liquid Glass" システム境界線エフェクトで表示されます(Liquid Glass についての情報については[こちらの4D blog 記事](https://blog.4d.com/the-new-macos-tahoe-design-comes-to-your-4d-applications/))。これにはシステム定義の内側の境界線、角の半径、グレーの境界線カラー、そして内側のパディングが含まれます。[スクロールバープロパティ](./properties_Appearance.md#縦スクロールバー) が有効化されている複数行の入力オブジェクト内においてはアピアランスは使用されないという点に注意してください(この場合には"システム"が使用されます)。
    Windows においては、このスタイルはランタイムでは"システム" に似たスタイルで表示されます。 | +| カスタム | [カスタムボタン](./button_overview.md#カスタム) | 内側の境界線デザインを有効化し、これには以下の追加のプロパティのセットが含まれます: [塗りカラー](#背景色-塗りカラー)、[境界線カラー](#border-color)、[境界線幅](#border-width)、および[角の半径](#角の半径)。
    ![](../assets/en/FormObjects/custom-button.png) | -(\*) "all" means "all objects supported" listed below. +(\*) この"all" または"全て" とは、以下の"サポートされる全てのオブジェクト" を意味します。 :::tip 関連したblog 記事 @@ -165,7 +184,7 @@ Allows setting a style for the object border. The following choices are availabl | 名称 | データタイプ | とりうる値 | | ----------- | ------ | -------------------------------------------------------------------------------------------- | -| borderStyle | text | "custom", "dotted", "double", "none", "raised", "solid", "sunken", "system", "systemRounded" | +| borderStyle | text | "custom"、 "dotted"、 "double"、 "none"、 "raised"、 "solid"、 "sunken"、 "system"、 "systemRounded" | #### 対象オブジェクト @@ -193,7 +212,7 @@ Allows setting a style for the object border. The following choices are availabl #### 参照 -[Dotted Line Type](#dotted-line-type) (shapes) +[点線タイプ](#dotted-line-type) (図形) --- @@ -217,7 +236,7 @@ Allows setting a style for the object border. The following choices are availabl #### 対象オブジェクト -[Button ("custom" style)](./button_overview.md#custom) (with ["custom" Border Line Style](#border-line-style)) - [Check Box ("custom style")](checkbox_overview.md#custom) - [Radio Button ("custom" style)](radio_overview.md#custom) +(["カスタム" 境界線スタイル](#border-line-style)を持った)[ボタン("カスタム"スタイル)](./button_overview.md#カスタム) - [チェックボックス("カスタムスタイル")](checkbox_overview.md#カスタム) - [ラジオボタン("カスタム" スタイル)](radio_overview.md#カスタム) --- @@ -258,7 +277,7 @@ Allows setting a style for the object border. The following choices are availabl #### 対象オブジェクト -[Button ("custom" style)](./button_overview.md#custom) (with ["custom" Border Line Style](#border-line-style)) - [Check Box ("custom" style)](checkbox_overview.md#custom) - [Input](input_overview.md) - [Rectangle](shapes_overview.md#rectangle) - [Text Area](text.md) - [Radio Button ("custom" style)](radio_overview.md#custom) +(["カスタム"境界線スタイル](#border-line-style)を持った)[ボタン("カスタム"スタイル)](./button_overview.md#カスタム) - [チェックボックス("カスタム" スタイル)](checkbox_overview.md#カスタム) - [入力](input_overview.md) - [四角形](shapes_overview.md#四角形) - [テキストエリア](text.md) - [ラジオボタン("カスタム" スタイル)](radio_overview.md#カスタム) #### コマンド @@ -326,7 +345,7 @@ Allows setting a style for the object border. The following choices are availabl :::note -This property is also available for objects with text properties, in which case it designates both the [Font color](properties_Text.md#font-color) and the object's lines, except if you used the [Border color](#border-color) property. +このプロパティはテキストプロパティを持つオブジェクトでも利用可能で、その場合には[フォントカラー](properties_Text.md#フォントカラー) とオブジェクトの線の両方を指定します(ただし[境界線カラー](#border-color) プロパティを使用していた場合を除く)。 ::: From 71b447875f1259773234f9a190a1a62f4c2a6e5d Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 16:11:11 +0100 Subject: [PATCH 173/195] properties_datasource.md Japanese --- .../version-21-R5/FormObjects/properties_DataSource.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/FormObjects/properties_DataSource.md b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/FormObjects/properties_DataSource.md index eb65c9a24b8189..a49a59fa28efef 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/FormObjects/properties_DataSource.md +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/FormObjects/properties_DataSource.md @@ -330,7 +330,7 @@ title: データソース 使用する命名セレクションを指定します。有効な命名セレクションの名前を入力しなければなりません。使用できるのはプロセスあるいはインタープロセス命名セレクションです。リストボックスの内容はこのセレクションに基づきます。選択された命名セレクションは、リストボックスが表示される時点で存在し、有効でなければなりません。 そうでない場合、リストボックスは空で表示されます。 -> 命名セレクションはソート済みのレコードリストです。これはセレクション中のカレントレコードと並び順をメモリに保持するために使用されます。 For more information, refer to [**Named Selections**](../Develop/named-selections) section. +> 命名セレクションはソート済みのレコードリストです。これはセレクション中のカレントレコードと並び順をメモリに保持するために使用されます。詳細な情報については、[**命名セレクション**](../Develop/named-selections) の章を参照してください。 #### JSON 文法 From eaf1d6b163c0f157a2b03453ffe03e7cc6534855 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 16:15:35 +0100 Subject: [PATCH 174/195] privileges.md French --- .../version-21-R5/ORDA/privileges.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/ORDA/privileges.md b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/ORDA/privileges.md index 1d8b5699ab5475..7adb2d78b89396 100644 --- a/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/ORDA/privileges.md +++ b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/ORDA/privileges.md @@ -67,6 +67,12 @@ Les actions disponibles sont liées à la ressource cible. Le paramétrage des permissions nécessite d'être cohérent, en particulier les permissions **update** et **drop** ont également besoin d'une permission **read** (mais **create** n'en a pas besoin). +:::warning + +When a permission entry references an undeclared [privilege](#privileges-and-roles), 4D logs an error and ignores the entry. In this case, the permission is ignored. If the [restricted mode by default](#restriction-modes) is not enabled, the resource is accessible to `guest` sessions. + +::: + ### Permissions héritées Une action de permission définie à un certain niveau est héritée par défaut aux niveaux inférieurs, mais plusieurs niveaux de permissions peuvent être définis : From 8ee7997856902512078dc153c5aae4b5a4774270 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 16:15:39 +0100 Subject: [PATCH 175/195] privileges.md Spanish --- .../version-21-R5/ORDA/privileges.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/i18n/es/docusaurus-plugin-content-docs/version-21-R5/ORDA/privileges.md b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/ORDA/privileges.md index bf0c7824300d03..8e41289bd5ba6c 100644 --- a/i18n/es/docusaurus-plugin-content-docs/version-21-R5/ORDA/privileges.md +++ b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/ORDA/privileges.md @@ -67,6 +67,12 @@ Las acciones disponibles están relacionadas con el recurso de destino. Los parámetros de permisos requieren ser consistentes, en particular los permisos **update** y **drop** también necesitan el permiso **read** (pero **create** no lo necesita). +:::warning + +When a permission entry references an undeclared [privilege](#privileges-and-roles), 4D logs an error and ignores the entry. In this case, the permission is ignored. If the [restricted mode by default](#restriction-modes) is not enabled, the resource is accessible to `guest` sessions. + +::: + ### Permisos heredados Una acción de permiso definida en un nivel determinado se hereda por defecto en los niveles inferiores, pero se pueden establecer varios permisos: From 814b63357e9b6e9a11ab8659dc86e563c527dcee Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 17:31:56 +0100 Subject: [PATCH 176/195] write-class-method.md Spanish --- .../code-editor/write-class-method.md | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/i18n/es/docusaurus-plugin-content-docs/version-21-R5/code-editor/write-class-method.md b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/code-editor/write-class-method.md index 36f2eda5f138f0..374ebadde5ecbf 100644 --- a/i18n/es/docusaurus-plugin-content-docs/version-21-R5/code-editor/write-class-method.md +++ b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/code-editor/write-class-method.md @@ -25,16 +25,16 @@ Si está acostumbrado a codificar con **VS Code**, también puede utilizar este Cada ventana del Editor de Código tiene una barra de herramientas que ofrece acceso instantáneo a las funciones básicas relacionadas con la ejecución y edición de código. -| Elemento | Icono | Descripción | -| ------------------------------------ | --------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **Ejecución del método** | ![execute-method](../assets/en/code-editor/execute-method.png) | Cuando se trabaja con métodos, cada ventana del Editor de Código tiene un botón que puede utilizarse para ejecutar el método actual. Utilizando el menú asociado a este botón, puede elegir el tipo de ejecución:
    • **Ejecutar nuevo proceso**: Crea un proceso y ejecuta el método en modo estándar en este proceso.
    • **Ejecutar y depurar nuevo proceso**: Crea un nuevo proceso y muestra el método en la ventana Depurador para su ejecución paso a paso en este proceso.
    • **Ejecutar en proceso Aplicación**: Ejecuta el método en modo estándar en el contexto del proceso Aplicación (es decir, en la ventana de visualización del registro).
    • **Ejecutar y depurar en el proceso Aplicación**: Muestra el método en la ventana del Depurador para su ejecución paso a paso en el contexto del proceso Aplicación (en otras palabras, la ventana de visualización de registros).
    Para más información sobre la ejecución de métodos, ver [Métodos proyecto](../Project/project-method-properties.md). | -| **Buscar en el método** | ![search-icon](../assets/en/code-editor/search.png) | Muestra el [*Área de búsqueda*](#find-and-replace). | -| **Macros** | ![macros-button](../assets/en/code-editor/macros.png) | Inserta una macro en la selección. Haga clic en la flecha desplegable para mostrar una lista de macros disponibles. Para obtener más información sobre como crear e instanciar macros, consulte [Macros](#macros). | -| **Expandir todo/Contraer todo** | ![expand-collapse-button](../assets/en/code-editor/expand-collapse-all.png) | Estos botones permiten expandir o contraer todas las estructuras de flujo de control del código. | -| **Información del método** | ![method-information-icon](../assets/en/code-editor/method-information.png) | Muestra el diálogo [Propiedades del método](../Project/project-method-properties.md) (sólo métodos proyecto). | -| **Últimos valores del portapapeles** | ![last-clipboard-values-icon](../assets/en/code-editor/last-clipboard-values.png) | Muestra los últimos valores almacenados en el portapapeles. | -| **Portapapeles** | ![clipboard icons](../assets/en/code-editor/clipboards.png) | Nueve portapapeles disponibles en el editor de código. Puede [utilizar estos portapapeles](#clipboards) haciendo clic directamente en ellos o utilizando los atajos de teclado. Puede utilizar la opción [Preferencias](Preferences/methods.md#options-1) para ocultarlas. | -| **Menú desplegable de navegación** | ![code-navigation-icons](../assets/en/code-editor/tags.png) | Le permite navegar dentro de métodos y clases con contenido etiquetado automáticamente o marcadores declarados manualmente. Ver abajo | +| Elemento | Icono | Descripción | +| ------------------------------------ | --------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Ejecución del método** | ![execute-method](../assets/en/code-editor/execute-method.png) | Cuando se trabaja con métodos, cada ventana del Editor de Código tiene un botón que puede utilizarse para ejecutar el método actual. Utilizando el menú asociado a este botón, puede elegir el tipo de ejecución:
    • **Ejecutar nuevo proceso**: Crea un proceso y ejecuta el método en modo estándar en este proceso.
    • **Ejecutar y depurar nuevo proceso**: crea un nuevo proceso y muestra el método en la ventana del depurador para la ejecución paso a paso en este proceso.
    • **Ejecutar en el proceso de la aplicación**: ejecuta el método en modo estándar en el contexto del proceso de la aplicación (es decir, la ventana de visualización de los registros).
    • **Ejecutar y depurar en el proceso Aplicación**: muestra el método en la ventana Depurador para su ejecución paso a paso en el contexto del proceso Aplicación (es decir, en la ventana de visualización de registros).
    Para más información sobre la ejecución de métodos, ver [Métodos proyecto](../Project/project-method-properties.md). | +| **Buscar en el método** | ![search-icon](../assets/en/code-editor/search.png) | Muestra el [*Área de búsqueda*](#find-and-replace). | +| **Macros** | ![macros-button](../assets/en/code-editor/macros.png) | Inserta una macro en la selección. Haga clic en la flecha desplegable para mostrar una lista de macros disponibles. Para obtener más información sobre como crear e instanciar macros, consulte [Macros](#macros). | +| **Expandir todo/Contraer todo** | ![expand-collapse-button](../assets/en/code-editor/expand-collapse-all.png) | Estos botones permiten expandir o contraer todas las estructuras de flujo de control del código. | +| **Información del método** | ![method-information-icon](../assets/en/code-editor/method-information.png) | Muestra el diálogo [Propiedades del método](../Project/project-method-properties.md) (sólo métodos proyecto). | +| **Últimos valores del portapapeles** | ![last-clipboard-values-icon](../assets/en/code-editor/last-clipboard-values.png) | Muestra los últimos valores almacenados en el portapapeles. | +| **Portapapeles** | ![clipboard icons](../assets/en/code-editor/clipboards.png) | Nueve portapapeles disponibles en el editor de código. Puede [utilizar estos portapapeles](#clipboards) haciendo clic directamente en ellos o utilizando los atajos de teclado. Puede utilizar la opción [Preferencias](Preferences/methods.md#options-1) para ocultarlas. | +| **Menú desplegable de navegación** | ![code-navigation-icons](../assets/en/code-editor/tags.png) | Le permite navegar dentro de métodos y clases con contenido etiquetado automáticamente o marcadores declarados manualmente. Ver abajo | ### Área de edición From ca61c0acb770a82886eaa262886f945c24eb2cdd Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 17:36:38 +0100 Subject: [PATCH 177/195] exit.md Japanese --- .../version-21-R5/server/exit.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/server/exit.md b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/server/exit.md index e82964e7c77c85..aeb7a0c9bdc984 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/server/exit.md +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/server/exit.md @@ -27,15 +27,15 @@ title: 4D Serverを終了する - **全てのクライアントが切断するのを待つ** -サーバーは、スリープモードに入っているものも含めて全てのクライアントが切断するまで終了するのをまちます。このオプションは、例えば昼休み中のメンテナンス処理などには不向きな可能性があります。何故なら[スリープモード](../ServerWindow/users.md#managing-sleeping-users) に入っているクライアントがあることが容易に想像できるからです。 +サーバーは、スリープモードに入っているものも含めて全てのクライアントが切断するまで終了するのをまちます。サーバーは、スリープモードに入っているものも含めて全てのクライアントが切断するまで終了するのをまちます。このオプションは、例えば昼休み中のメンテナンス処理などには不向きな可能性があります。何故なら[スリープモード](../ServerWindow/sessions.md#management-of-sleeping-client-sessions) に入っているクライアントがあることが容易に想像できるからです。 - **アクティブなクライアントが切断するのを待つ(スリープのクライアントは無視)** -サーバーはアクティブなクライアントが全て切断したあとに終了します(言い換えると、[スリープモード](../ServerWindow/users.md#managing-sleeping-users) に入っていない全てのクライアントマシンということです)。このオプションを使用すると、スリープモードに入っているクライアントはどれも接続しているとは見なされません。例えば昼休み中にメンテナンスオペレーションを実行したい場合などは、このオプションを使用して下さい。このオプションが使用されているとき、スリープモードに入っているクライアントは復帰時に接続エラーが表示されます。 +サーバーはアクティブなクライアントが全て切断したあとに終了します(言い換えると、[スリープモード](../ServerWindow/sessions.md#management-of-sleeping-client-sessions) に入っていない全てのクライアントマシンということです)。このオプションを使用すると、スリープモードに入っているクライアントはどれも接続しているとは見なされません。例えば昼休み中にメンテナンスオペレーションを実行したい場合などは、このオプションを使用して下さい。このオプションが使用されているとき、スリープモードに入っているクライアントは復帰時に接続エラーが表示されます。 :::note -*スリープ中のクライアント* とは、サーバーマシンへの接続がアクティブである間に[スリープモード](../ServerWindow/users.md#managing-sleeping-users) へと切り替わったマシン上にあるリモートの4Dアプリケーションのことをさします。 +*スリープ中のクライアント* とは、サーバーマシンへの接続がアクティブである間に[スリープモード](../ServerWindow/sessions.md#management-of-sleeping-client-sessions) へと切り替わったマシン上にあるリモートの4Dアプリケーションのことをさします。 ::: From 604417010868ebb4b62522a4b82cce051c2ddb8b Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 17:37:06 +0100 Subject: [PATCH 178/195] client-server.md Japanese --- .../version-21-R5/settings/client-server.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/settings/client-server.md b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/settings/client-server.md index c1fa2e6bd3e050..c227a9f481a69c 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/settings/client-server.md +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/settings/client-server.md @@ -133,7 +133,7 @@ Single Sign On (SSO) が有効になっている場合 (上述参照)、認証 - **しない**: ローカルの **Resources** フォルダーはセッション中に更新されません。サーバーから送信される通知は無視されます。**ローカルリソースを更新** アクションメニューコマンド [(リソースエクスプローラーを使用する](https://doc.4d.com/4Dv20/4D/20.2/Using-the-Resources-explorer.300-6750254.ja.html) 参照) を使用すれば、ローカルの **Resources**フォルダーを手動で更新することができます。 - **常に**: セッション中にサーバーから通知が送信されると、ローカルの **Resources** フォルダーは自動で同期されます。 -- **その都度指定**: サーバーから通知を受け取ると、クライアントマシン上でダイアログボックスが表示されます。ユーザーはローカルの **Resources** フォルダーの同期を受け入れ、あるいは拒否できます。\ **Resources** フォルダーは、データベースインターフェースで使用されるカスタムファイルを格納しています (翻訳ファイルやピクチャーなど)。このフォルダーの内容が更新されたときには、自動又は手動メカニズムを使用して各クライアントに通知できます。詳細な情報については、[Resources フォルダーの管理](../Desktop/clientServer.md#resources-フォルダー) の章を参照してください。 +- **その都度指定**: サーバーから通知を受け取ると、クライアントマシン上でダイアログボックスが表示されます。ユーザーはローカルの **Resources** フォルダーの同期を受け入れ、あるいは拒否できます。\ **Resources** フォルダーは、データベースインターフェースで使用されるカスタムファイルを格納しています (翻訳ファイルやピクチャーなど)。このフォルダーの内容が更新されたときには、自動又は手動メカニズムを使用して各クライアントに通知できます。 For more information, please refer to the [Resources folder](../Desktop/clientServer.md#resources-folder) section. ## IP設定ページ From 9ad360b57de6f0f14b6f14f0e8c63a85c146a93b Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 17:40:46 +0100 Subject: [PATCH 179/195] udpsocketclass.md Japanese --- .../version-21/API/UDPSocketClass.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21/API/UDPSocketClass.md b/i18n/ja/docusaurus-plugin-content-docs/version-21/API/UDPSocketClass.md index 0c1dbad2f3a70f..b67c3948f52d7d 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/version-21/API/UDPSocketClass.md +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21/API/UDPSocketClass.md @@ -48,7 +48,7 @@ UDPSocket オブジェクトは以下のプロパティと関数を提供しま | 引数 | 型 | | 説明 | | ------- | --------- | --------------------------- | ------------------------------------------------------------------------ | | port | Integer | -> | UDP ソケットに使用されるローカルのポート番号(0 または省略時には使用されていないポートを探して使用) | -| options | Object | -> | ソケットの接続[オプション](#options引数) | +| options | Object | -> | ソケットの接続[オプション](#options-引数) | | 戻り値 | UDPSocket | <- | 新規UDPSocket オブジェクト | From 6311553b3c17c0c5943f2d5aeb193ba27fdc0a14 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 17:41:20 +0100 Subject: [PATCH 180/195] websocketserverclass.md Japanese --- .../version-21/API/WebSocketServerClass.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21/API/WebSocketServerClass.md b/i18n/ja/docusaurus-plugin-content-docs/version-21/API/WebSocketServerClass.md index 46c9869c156df3..6a2aee10041f99 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/version-21/API/WebSocketServerClass.md +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21/API/WebSocketServerClass.md @@ -37,7 +37,7 @@ WebSocketプロトコルは、WebSocketサーバーとクライアント (Webブ - サーバー接続を処理するためのユーザークラス - メッセージを処理するためのユーザークラス -接続を維持するため、[WebSocketサーバーの作成](#4dwebsocketservernew) は [ワーカー](../Develop/processes.md#worker-プロセス) 内にて行う必要があります。 +接続を維持するため、[WebSocketサーバーの作成](#4dwebsocketservernew) は [ワーカー](../Develop/processes.md#ワーカープロセス) 内にて行う必要があります。 [4D Webサーバー](WebServerClass.md) を起動しておく必要があります。 From fae40b772cd1c3ef4d7d8a9879ac3832843c1427 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 17:45:04 +0100 Subject: [PATCH 181/195] labels.md Japanese --- .../docusaurus-plugin-content-docs/version-21/Desktop/labels.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21/Desktop/labels.md b/i18n/ja/docusaurus-plugin-content-docs/version-21/Desktop/labels.md index 4c5a8115de97f9..75f7b2d1352b2f 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/version-21/Desktop/labels.md +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21/Desktop/labels.md @@ -164,7 +164,7 @@ title: ラベル var myVar+=1 ``` -3. プロジェクトメソッドに対して["コンポーネントとホストデータベース間で共有"](../Project/project-method-properties.md#コンポーネントとホストデータベース間で共有) オプションを設定します。 +3. プロジェクトメソッドに対して["コンポーネントとホストデータベース間で共有"](../Project/project-method-properties.md#コンポーネントとホストプロジェクト間で共有) オプションを設定します。 4. ラベルエディターを表示する前に、以下のコードを実行してプロジェクトメソッドが確実に許可されているようにします: From b3776dd71db7478f5956ea9612d67efe58de4429 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 17:45:25 +0100 Subject: [PATCH 182/195] preemptive.md French --- .../version-21/Develop/preemptive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/fr/docusaurus-plugin-content-docs/version-21/Develop/preemptive.md b/i18n/fr/docusaurus-plugin-content-docs/version-21/Develop/preemptive.md index d545a396a2356b..ee10e775d1305e 100644 --- a/i18n/fr/docusaurus-plugin-content-docs/version-21/Develop/preemptive.md +++ b/i18n/fr/docusaurus-plugin-content-docs/version-21/Develop/preemptive.md @@ -41,7 +41,7 @@ Le code 4D ne peut être exécuté dans un process préemptif que lorsque certai La propriété "thread safety" de chaque élément dépend de l'élément lui-même : -- Commandes 4D : la propriété thread-safe est une propriété interne. Dans la documentation 4D, les commandes thread-safe sont identifiées par l'icône ![](../assets/en/Develop/thread-safe.png). Commandes 4D : la propriété thread-safe est une propriété interne. Une grande partie des commandes 4D peut s'exécuter en mode préemptif. +- Commandes 4D : la propriété thread-safe est une propriété interne. The 4D documentation indicates whether each command is thread-safe or not in the Properties section. Commandes 4D : la propriété thread-safe est une propriété interne. Une grande partie des commandes 4D peut s'exécuter en mode préemptif. - Méthodes projet : les conditions pour être thread-safe sont répertoriées dans [ce paragraphe](#writing-a-thread-safe-method). Fondamentalement, le code à exécuter dans des threads préemptifs ne peut pas appeler des parties avec des interactions externes, telles que du code de plug-in ou des variables interprocess. Cependant, l'accès aux données est autorisé car le serveur de données 4D et ORDA prennent en charge l'exécution préemptive. From b71eedcb72a6b577b50628667ad172f403156709 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 17:45:29 +0100 Subject: [PATCH 183/195] preemptive.md Spanish --- .../version-21/Develop/preemptive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/es/docusaurus-plugin-content-docs/version-21/Develop/preemptive.md b/i18n/es/docusaurus-plugin-content-docs/version-21/Develop/preemptive.md index bed4c92fde62d2..9fb4b00c7f07b1 100644 --- a/i18n/es/docusaurus-plugin-content-docs/version-21/Develop/preemptive.md +++ b/i18n/es/docusaurus-plugin-content-docs/version-21/Develop/preemptive.md @@ -41,7 +41,7 @@ Dado que un hilo se maneja de forma independiente a partir del método del proce La propiedad "seguridad de hilo" de cada elemento depende del elemento en sí: -- Comandos 4D: hilo seguro es una propiedad interna. En la documentación de 4D, los comandos hilo seguro se identifican con el icono ![](../assets/en/Develop/thread-safe.png). También puede utilizar el comando [`Nombre del comando`](../commands/command-name.md) para saber si un comando es hilo seguro. Gran parte de los comandos 4D pueden ejecutarse en modo apropiativo. +- Comandos 4D: hilo seguro es una propiedad interna. The 4D documentation indicates whether each command is thread-safe or not in the Properties section. También puede utilizar el comando [`Nombre del comando`](../commands/command-name.md) para saber si un comando es hilo seguro. Gran parte de los comandos 4D pueden ejecutarse en modo apropiativo. - Métodos de proyecto: las condiciones para seguridad de hilo se listan en [este párrafo](#writing-a-thread-safe-method). Básicamente, el código que se ejecuta en hilos apropiativos no puede llamar a las partes con las interacciones externas, tal como el código plug-in o las variables interproceso. Los accesos a los datos, sin embargo, son permitidos desde el servidor de datos 4D que soporta la ejecución apropiativa. From 0ad9b3df4087ffe5d8162131a0ffa12d1b2a9e2d Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 17:45:32 +0100 Subject: [PATCH 184/195] preemptive.md Japanese --- .../version-21/Develop/preemptive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21/Develop/preemptive.md b/i18n/ja/docusaurus-plugin-content-docs/version-21/Develop/preemptive.md index 2b352f5da304cc..e2b1bc924d9740 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/version-21/Develop/preemptive.md +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21/Develop/preemptive.md @@ -41,7 +41,7 @@ title: プリエンプティブプロセス 要素毎の "スレッドセーフティ" プロパティは、その要素自身によります: -- 4Dコマンド: スレッドセーフティは内部プロパティです。 4D ドキュメンテーション内においては、スレッドセーフなコマンドには ![](../assets/en/Develop/thread-safe.png) アイコンが表示されています。 [`Command name`](../commands/command-name.md) コマンドを使用して、コマンドがスレッドセーフであるかどうかを知ることもできます。 4Dコマンドの大部分はプリエンプティブモードで実行可能です。 +- 4Dコマンド: スレッドセーフティは内部プロパティです。 The 4D documentation indicates whether each command is thread-safe or not in the Properties section. [`Command name`](../commands/command-name.md) コマンドを使用して、コマンドがスレッドセーフであるかどうかを知ることもできます。 4Dコマンドの大部分はプリエンプティブモードで実行可能です。 - プロジェクトメソッド: スレッドセーフであるための条件は [こちらの段落](#スレッドセーフなメソッドの書き方) にまとめられています。 原則として、プリエンプティブスレッド内で実行されるコードは外部との相互作用する部分、たとえばプラグインコードやインタープロセス変数などを呼び出すことはできません。しかしながら、4Dデータサーバーと ORDA はプリエンプティブ実行をサポートしていることから、データアクセスは可能です。 From f68aafdffa6c371f63a84ab8ad326191cfc48638 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 17:45:39 +0100 Subject: [PATCH 185/195] processes.md Japanese --- .../version-21/Develop/processes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21/Develop/processes.md b/i18n/ja/docusaurus-plugin-content-docs/version-21/Develop/processes.md index 0d09a30c963552..50ddcc5854fde2 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/version-21/Develop/processes.md +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21/Develop/processes.md @@ -50,7 +50,7 @@ title: プロセスとワーカー ### インターフェース要素 -インターフェース要素は、[デスクトップアプリケーション](../category/desktop-applications) で使用されます。 以下のものがあります: 以下のものがあります: +インターフェース要素は、[デスクトップアプリケーション](../category/desktop-applications) で使用されます。以下のものがあります: - [メニューバー](../Menus/creating.md): 各プロセスは、独自のカレントメニューバーを持つことができます。最前面のプロセスのメニューバーがアプリケーションのカレントメニューバーになります。 - 1つ以上のウィンドウ: 各プロセスは、1つまたは複数のウィンドウを同時に開くことができます。他方、ウィンドウをまったく持たないプロセスもあります。 From ffe2a0b71f3eea470bfff8e2c3b1acafd3d0a140 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 17:49:34 +0100 Subject: [PATCH 186/195] createstylesheet.md Japanese --- .../version-21/FormEditor/createStylesheet.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21/FormEditor/createStylesheet.md b/i18n/ja/docusaurus-plugin-content-docs/version-21/FormEditor/createStylesheet.md index a9f7e82321de26..bec2c9ab9fb1cd 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/version-21/FormEditor/createStylesheet.md +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21/FormEditor/createStylesheet.md @@ -126,7 +126,7 @@ text.center { } ``` -4D フォームの詳細では、[CSSクラス](../FormObjects/properties_Object.md#cssクラス) 属性を使用してクラス名を割り当てます。この属性には一つ以上のクラス名を指定することができます。 複数の場合はクラス名を半角スペースで区切ります: +4D フォームの詳細では、[CSSクラス](../FormObjects/properties_Object.md#cssクラス) 属性を使用してクラス名を割り当てます。この属性には一つ以上のクラス名を指定することができます。複数の場合はクラス名を半角スペースで区切ります: ``` class: "okButtons important" From 41e8d43bc30815469a092b88eaf1d567b1dfbb1f Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 19:13:12 +0100 Subject: [PATCH 187/195] definition.md French --- .../version-21-R5/embedding-studio/Classes/Definition.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Definition.md b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Definition.md index fd8c5c92276afd..634252ac475d38 100644 --- a/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Definition.md +++ b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Definition.md @@ -1,5 +1,5 @@ --- -id: définition +id: definition title: Définition --- From c86c03f1f10bb6f9afaeec398e24fef08973ed56 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 19:13:19 +0100 Subject: [PATCH 188/195] definition.md Spanish --- .../version-21-R5/embedding-studio/Classes/Definition.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Definition.md b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Definition.md index f0ba84a11ef136..0c3a6c37dd4a37 100644 --- a/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Definition.md +++ b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Definition.md @@ -1,5 +1,5 @@ --- -id: definición +id: definition title: Definición --- From 8a46f90deb98182fb9c85f55fec91f38843daf96 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 19:13:22 +0100 Subject: [PATCH 189/195] definition.md Japanese --- .../version-21-R5/embedding-studio/Classes/Definition.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Definition.md b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Definition.md index 7b9bf4e7a585df..6b29b5b7376cff 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Definition.md +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Definition.md @@ -1,5 +1,5 @@ --- -id: 定義 +id: definition title: 定義 --- From fad35f6c7f2fd1ca096b9a0abad8960a85e33de4 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 19:13:51 +0100 Subject: [PATCH 190/195] scheduler.md French --- .../version-21-R5/embedding-studio/Classes/Scheduler.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Scheduler.md b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Scheduler.md index 67c5622ffdd04a..152989726fb6b5 100644 --- a/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Scheduler.md +++ b/i18n/fr/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Scheduler.md @@ -1,5 +1,5 @@ --- -id: périodicité +id: scheduler title: Périodicité --- From b1eca2b6b4570eacc7dcc2aacdbba2ed8c9fa294 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 19:13:54 +0100 Subject: [PATCH 191/195] scheduler.md Spanish --- .../version-21-R5/embedding-studio/Classes/Scheduler.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Scheduler.md b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Scheduler.md index e2ba1bd8ee043e..d76f5fce408e54 100644 --- a/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Scheduler.md +++ b/i18n/es/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Scheduler.md @@ -1,5 +1,5 @@ --- -id: backups periódicos +id: scheduler title: Backups periódicos --- From c506256ea6434c11b8b0bbb5ba34238d302c1ace Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 19:13:57 +0100 Subject: [PATCH 192/195] scheduler.md Japanese --- .../version-21-R5/embedding-studio/Classes/Scheduler.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Scheduler.md b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Scheduler.md index 975db1e02ec8e0..8b61a1089b1b15 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Scheduler.md +++ b/i18n/ja/docusaurus-plugin-content-docs/version-21-R5/embedding-studio/Classes/Scheduler.md @@ -1,5 +1,5 @@ --- -id: スケジューラー +id: scheduler title: スケジューラー --- From 5d637145efce260dcc0fff6461d657dc0b299e6a Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 19:14:17 +0100 Subject: [PATCH 193/195] index-add.png French --- .../current/assets/en/Develop/index-add.png | Bin 0 -> 12593 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 i18n/fr/docusaurus-plugin-content-docs/current/assets/en/Develop/index-add.png diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/assets/en/Develop/index-add.png b/i18n/fr/docusaurus-plugin-content-docs/current/assets/en/Develop/index-add.png new file mode 100644 index 0000000000000000000000000000000000000000..05e72c5f179854a90e536c103c50a7d92468cbbb GIT binary patch literal 12593 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 S2JmkVAl0W@PY{o-LjDiu(9Ko= literal 0 HcmV?d00001 From bcd8e73952e88c6c39bb7ffddcb564a7e1e7dfba Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 19:14:19 +0100 Subject: [PATCH 194/195] index-add.png Spanish --- .../current/assets/en/Develop/index-add.png | Bin 0 -> 12593 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 i18n/es/docusaurus-plugin-content-docs/current/assets/en/Develop/index-add.png diff --git a/i18n/es/docusaurus-plugin-content-docs/current/assets/en/Develop/index-add.png b/i18n/es/docusaurus-plugin-content-docs/current/assets/en/Develop/index-add.png new file mode 100644 index 0000000000000000000000000000000000000000..05e72c5f179854a90e536c103c50a7d92468cbbb GIT binary patch literal 12593 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 S2JmkVAl0W@PY{o-LjDiu(9Ko= literal 0 HcmV?d00001 From 757f3720c00c1d1edaee4933d197006516ce38d7 Mon Sep 17 00:00:00 2001 From: arnaud-4d Date: Thu, 5 Nov 2026 19:14:22 +0100 Subject: [PATCH 195/195] index-add.png Japanese --- .../current/assets/en/Develop/index-add.png | Bin 0 -> 12593 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 i18n/ja/docusaurus-plugin-content-docs/current/assets/en/Develop/index-add.png diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/assets/en/Develop/index-add.png b/i18n/ja/docusaurus-plugin-content-docs/current/assets/en/Develop/index-add.png new file mode 100644 index 0000000000000000000000000000000000000000..05e72c5f179854a90e536c103c50a7d92468cbbb GIT binary patch literal 12593 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 S2JmkVAl0W@PY{o-LjDiu(9Ko= literal 0 HcmV?d00001