# KAG Example: HotpotQA

[English](./README.md) |
[简体中文](./README_cn.md)

[HotpotQA](https://arxiv.org/abs/1809.09600) is a dataset for diverse, explainable multi-hop question answering. It's used by [KAG](https://arxiv.org/abs/2409.13731) and [HippoRAG](https://arxiv.org/abs/2405.14831) for multi-hop question answering performance evaluation.

Here we demonstrate how to build a knowledge graph for the HotpotQA dataset, generate answers to those evaluation questions with KAG and calculate EM and F1 metrics of the KAG generated answers compared to the ground-truth answers.

## 1. Precondition

Please refer to [Quick Start](https://openspg.yuque.com/ndx6g9/cwh47i/rs7gr8g4s538b1n7) to install KAG and its dependency OpenSPG server, and learn about using KAG in developer mode.

## 2. Steps to reproduce

### Step 1: Enter the example directory

```bash
cd kag/examples/hotpotqa
```

### Step 2: Configure models

Update the generative model configurations ``openie_llm`` and ``chat_llm`` and the representational model configuration ``vectorize_model`` in [kag_config.yaml](./kag_config.yaml).

You need to fill in correct ``api_key``s. If your model providers and model names are different from the default values, you also need to update ``base_url`` and ``model``.

### Step 3: Project initialization

Initiate the project with the following command.

```bash
knext project restore --host_addr http://127.0.0.1:8887 --proj_path .
```

### Step 4: Commit the schema

Execute the following command to commit the schema [HotpotQA.schema](./schema/HotpotQA.schema).

```bash
knext schema commit
```

### Step 5: Build the knowledge graph

Execute [indexer.py](./builder/indexer.py) in the [builder](./builder) directory to build the knowledge graph.

```bash
cd builder && python indexer.py && cd ..
```

### Step 6: Execute the QA tasks

Execute [evaForHotpotqa.py](./solver/evaForHotpotqa.py) in the [solver](./solver) directory to generate the answers and calculate the EM and F1 metrics.

```bash
cd solver && python evaForMedicine.py && cd ..
```

The generated answers are saved to ``./solver/hotpotqa_res_*.json``.

The calculated EM and F1 metrics are saved to ``./solver/hotpotqa_metrics_*.json``.

### Step 7: (Optional) Cleanup

To delete the checkpoints, execute the following command.

```bash
rm -rf ./builder/ckpt
rm -rf ./solver/ckpt
```

To delete the KAG project and related knowledge graph, execute the following similar command. Replace the OpenSPG server address and KAG project id with actual values.

```bash
curl http://127.0.0.1:8887/project/api/delete?projectId=1
```

### Step 8: (Optional) Try the larger datasets

Restart from Step 1 and modify [indexer.py](./builder/indexer.py) and [evaForHotpotqa.py](./solver/evaForHotpotqa.py) to try the larger datasets.


# KAG 示例：HotpotQA

[English](./README.md) |
[简体中文](./README_cn.md)

[HotpotQA](https://arxiv.org/abs/1809.09600) 是一个用于多样和可解释多跳问答的数据集。[KAG](https://arxiv.org/abs/2409.13731) 和 [HippoRAG](https://arxiv.org/abs/2405.14831) 用它评估多跳问答的性能。

本例我们展示为 HotpotQA 数据集构建知识图谱，然后用 KAG 为评估问题生成答案，并与标准答案对比计算 EM 和 F1 指标。

## 1. 前置条件

参考文档 [快速开始](https://openspg.yuque.com/ndx6g9/0.6/quzq24g4esal7q17) 安装 KAG 及其依赖的 OpenSPG server，了解开发者模式 KAG 的使用流程。

## 2. 复现步骤

### Step 1：进入示例目录

```bash
cd kag/examples/hotpotqa
```

### Step 2：配置模型

更新 [kag_config.yaml](./kag_config.yaml) 中的生成模型配置 ``openie_llm`` 和 ``chat_llm`` 和表示模型配置 ``vectorize_model``。

您需要设置正确的 ``api_key``。如果使用的模型供应商和模型名与默认值不同，您还需要更新 ``base_url`` 和 ``model``。

### Step 3：初始化项目

先对项目进行初始化。

```bash
knext project restore --host_addr http://127.0.0.1:8887 --proj_path .
```

### Step 4：提交 schema

执行以下命令提交 schema [HotpotQA.schema](./schema/HotpotQA.schema)。

```bash
knext schema commit
```

### Step 5：构建知识图谱

在 [builder](./builder) 目录执行 [indexer.py](./builder/indexer.py) 构建知识图谱。

```bash
cd builder && python indexer.py && cd ..
```

### Step 6：执行 QA 任务

在 [solver](./solver) 目录执行 [evaForHotpotqa.py](./solver/evaForHotpotqa.py) 生成答案并计算 EM 和 F1 指标。

```bash
cd solver && python evaForHotpotqa.py && cd ..
```

生成的答案被保存至 ``./solver/hotpotqa_res_*.json``.

计算出的 EM 和 F1 指标被保存至 ``./solver/hotpotqa_metrics_*.json``.

### Step 7：（可选）清理

若要删除 checkpoint，可执行以下命令。

```bash
rm -rf ./builder/ckpt
rm -rf ./solver/ckpt
```

若要删除 KAG 项目及关联的知识图谱，可执行以下类似命令，将 OpenSPG server 地址和 KAG 项目 id 换为实际的值。

```bash
curl http://127.0.0.1:8887/project/api/delete?projectId=1
```

### Step 8：（可选）尝试更大的数据集

从 Step 1 重新开始，修改 [indexer.py](./builder/indexer.py) 和 [evaForHotpotqa.py](./solver/evaForHotpotqa.py) 以尝试更大的数据集。

KAG is a logical form-guided reasoning and retrieval framework based on OpenSPG engine and LLMs.  It is used to build logical reasoning and factual Q&A solutions for professional domain knowledge bases. It can effectively overcome the shortcomings of the traditional RAG vector similarity calculation model.


# KAG Example: Medical Knowledge Graph (Medicine)

[English](./README.md) |
[简体中文](./README_cn.md)

This example aims to demonstrate how to extract and construct entities and relations in a knowledge graph based on the SPG-Schema using LLMs.

![KAG Medicine Diagram](/_static/images/examples/medicine/kag-medicine-diag.png)

## 1. Precondition

Please refer to [Quick Start](https://openspg.yuque.com/ndx6g9/cwh47i/rs7gr8g4s538b1n7) to install KAG and its dependency OpenSPG server, and learn about using KAG in developer mode.

## 2. Steps to reproduce

### Step 1: Enter the example directory

```bash
cd kag/examples/medicine
```

### Step 2: Configure models

Update the generative model configurations ``openie_llm`` and ``chat_llm`` and the representational model configuration ``vectorize_model`` in [kag_config.yaml](./kag_config.yaml).

You need to fill in correct ``api_key``s. If your model providers and model names are different from the default values, you also need to update ``base_url`` and ``model``.

### Step 3: Project initialization

Initiate the project with the following command.

```bash
knext project restore --host_addr http://127.0.0.1:8887 --proj_path .
```

### Step 4: Commit the schema

Execute the following command to commit the Medical Knowledge Graph schema [Medicine.schema](./schema/Medicine.schema).

```bash
knext schema commit
```

### Step 5: Build the knowledge graph

Execute [indexer.py](./builder/indexer.py) in the [builder](./builder) directory to build the knowledge graph with domain knowledge importing and schema-free extraction.

```bash
cd builder && python indexer.py && cd ..
```

Check [Disease.csv](./builder/data/Disease.csv) to inspect the descriptions of diseases. Those unstructured descriptions are schema-free extracted by ``extract_runner`` defined in [kag_config.yaml](./kag_config.yaml).

Other structured data in [data](./builder/data) will be imported directly by corresponding builder chains defined in [kag_config.yaml](./kag_config.yaml).

### Step 6: Query the knowledge graph with GQL

You can use the ``knext reasoner`` command to inspect the built knowledge graph.

The query DSL will be executed by the OpenSPG server, which supports ISO GQL.

* Execute the following command to execute DSL directly.

  ```bash
  knext reasoner execute --dsl "
  MATCH
      (s:Medicine.HospitalDepartment)-[p]->(o)
  RETURN
      s.id, s.name
  "
  ```

  The results will be displayed on the screen and saved as CSV to the current directory.

* You can also save the DSL to a file and execute the file.

  ```bash
  knext reasoner execute --file ./reasoner/rule.dsl
  ```

* You can also use the reasoner Python client to query the knowledge graph.

  ```bash
  python ./reasoner/client.py
  ```

### Step 7: Execute the QA tasks

Execute [evaForMedicine.py](./solver/evaForMedicine.py) in the [solver](./solver) directory to ask a demo question in natural languages and view the answer and trace log.

```bash
cd solver && python evaForMedicine.py && cd ..
```

### Step 8: (Optional) Cleanup

To delete the checkpoint, execute the following command.

```bash
rm -rf ./builder/ckpt
```

To delete the KAG project and related knowledge graph, execute the following similar command. Replace the OpenSPG server address and KAG project id with actual values.

```bash
curl http://127.0.0.1:8887/project/api/delete?projectId=1
```


# KAG 示例：医疗图谱（Medicine）

[English](./README.md) |
[简体中文](./README_cn.md)

本示例旨在展示如何基于 schema 的定义，利用大模型实现对图谱实体和关系的抽取和构建到图谱。

![KAG Medicine Diagram](/_static/images/examples/medicine/kag-medicine-diag.png)

## 1. 前置条件

参考文档 [快速开始](https://openspg.yuque.com/ndx6g9/0.6/quzq24g4esal7q17) 安装 KAG 及其依赖的 OpenSPG server，了解开发者模式 KAG 的使用流程。

## 2. 复现步骤

### Step 1：进入示例目录

```bash
cd kag/examples/medicine
```

### Step 2：配置模型

更新 [kag_config.yaml](./kag_config.yaml) 中的生成模型配置 ``openie_llm`` 和 ``chat_llm`` 和表示模型配置 ``vectorize_model``。

您需要设置正确的 ``api_key``。如果使用的模型供应商和模型名与默认值不同，您还需要更新 ``base_url`` 和 ``model``。

### Step 3：初始化项目

先对项目进行初始化。

```bash
knext project restore --host_addr http://127.0.0.1:8887 --proj_path .
```

### Step 4：提交 schema

执行以下命令提交医疗图谱 schema [Medicine.schema](./schema/Medicine.schema)。

```bash
knext schema commit
```

### Step 5：构建知识图谱

在 [builder](./builder) 目录执行 [indexer.py](./builder/indexer.py) 通过领域知识导入和 schema-free 抽取构建知识图谱。

```bash
cd builder && python indexer.py && cd ..
```

您可以检查 [Disease.csv](./builder/data/Disease.csv) 查看疾病的描述，我们通过定义在 [kag_config.yaml](./kag_config.yaml) 的 ``extract_runner`` 对这些无结构文本描述做 schema-free 抽取。

[data](./builder/data) 中的其他结构化数据通过定义在 [kag_config.yaml](./kag_config.yaml) 中的相应 KAG builder chain 直接导入。

### Step 6：使用 GQL 查询知识图谱

您可以使用 ``knext reasoner`` 命令检查构建的知识图谱。查询 DSL 将由 OpenSPG server 执行，它支持 ISO GQL。

* 使用以下命令直接执行 DSL。

  ```bash
  knext reasoner execute --dsl "
  MATCH
      (s:Medicine.HospitalDepartment)-[p]->(o)
  RETURN
      s.id, s.name
  "
  ```

  查询结果会显示在屏幕上并以 CSV 格式保存到当前目录。

* 您也可以将 DSL 保存到文件，然后通过文件提交 DSL。

  ```bash
  knext reasoner execute --file ./reasoner/rule.dsl
  ```

* 您还可以使用 reasoner 的 Python 客户端查询知识图谱。

  ```bash
  python ./reasoner/client.py
  ```

### Step 7：执行 QA 任务

在 [solver](./solver) 目录执行 [evaForMedicine.py](./solver/evaForMedicine.py) 用自然语言问一个示例问题并查看答案和 trace log。

```bash
cd solver && python evaForMedicine.py && cd ..
```

### Step 8：（可选）清理

若要删除 checkpoint，可执行以下命令。

```bash
rm -rf ./builder/ckpt
```

若要删除 KAG 项目及关联的知识图谱，可执行以下类似命令，将 OpenSPG server 地址和 KAG 项目 id 换为实际的值。

```bash
curl http://127.0.0.1:8887/project/api/delete?projectId=1
```


# KAG Example: MuSiQue

[English](./README.md) |
[简体中文](./README_cn.md)

[MuSiQue](https://arxiv.org/abs/2108.00573) is a multi-hop QA dataset for comprehensive evaluation of reasoning steps. It's used by [KAG](https://arxiv.org/abs/2409.13731) and [HippoRAG](https://arxiv.org/abs/2405.14831) for multi-hop question answering performance evaluation.

Here we demonstrate how to build a knowledge graph for the MuSiQue dataset, generate answers to those evaluation questions with KAG and calculate EM and F1 metrics of the KAG generated answers compared to the ground-truth answers.

## 1. Precondition

Please refer to [Quick Start](https://openspg.yuque.com/ndx6g9/cwh47i/rs7gr8g4s538b1n7) to install KAG and its dependency OpenSPG server, and learn about using KAG in developer mode.

## 2. Steps to reproduce

### Step 1: Enter the example directory

```bash
cd kag/examples/musique
```

### Step 2: Configure models

Update the generative model configurations ``openie_llm`` and ``chat_llm`` and the representational model configuration ``vectorize_model`` in [kag_config.yaml](./kag_config.yaml).

You need to fill in correct ``api_key``s. If your model providers and model names are different from the default values, you also need to update ``base_url`` and ``model``.

### Step 3: Project initialization

Initiate the project with the following command.

```bash
knext project restore --host_addr http://127.0.0.1:8887 --proj_path .
```

### Step 4: Commit the schema

Execute the following command to commit the schema [MuSiQue.schema](./schema/MuSiQue.schema).

```bash
knext schema commit
```

### Step 5: Build the knowledge graph

Execute [indexer.py](./builder/indexer.py) in the [builder](./builder) directory to build the knowledge graph.

```bash
cd builder && python indexer.py && cd ..
```

### Step 6: Execute the QA tasks

Execute [evaForMusique.py](./solver/evaForMusique.py) in the [solver](./solver) directory to generate the answers and calculate the EM and F1 metrics.

```bash
cd solver && python evaForMusique.py && cd ..
```

The generated answers are saved to ``./solver/musique_res_*.json``.

The calculated EM and F1 metrics are saved to ``./solver/musique_metrics_*.json``.

### Step 7: (Optional) Cleanup

To delete the checkpoints, execute the following command.

```bash
rm -rf ./builder/ckpt
rm -rf ./solver/ckpt
```

To delete the KAG project and related knowledge graph, execute the following similar command. Replace the OpenSPG server address and KAG project id with actual values.

```bash
curl http://127.0.0.1:8887/project/api/delete?projectId=1
```

### Step 8: (Optional) Try the larger datasets

Restart from Step 1 and modify [indexer.py](./builder/indexer.py) and [evaForMusique.py](./solver/evaForMusique.py) to try the larger datasets.


# KAG 示例：MuSiQue

[English](./README.md) |
[简体中文](./README_cn.md)

[MuSiQue](https://arxiv.org/abs/2108.00573) 是一个用于对推理步骤进行全面评估的多跳问答数据集。[KAG](https://arxiv.org/abs/2409.13731) 和 [HippoRAG](https://arxiv.org/abs/2405.14831) 用它评估多跳问答的性能。

本例我们展示为 MuSiQue 数据集构建知识图谱，然后用 KAG 为评估问题生成答案，并与标准答案对比计算 EM 和 F1 指标。

## 1. 前置条件

参考文档 [快速开始](https://openspg.yuque.com/ndx6g9/0.6/quzq24g4esal7q17) 安装 KAG 及其依赖的 OpenSPG server，了解开发者模式 KAG 的使用流程。

## 2. 复现步骤

### Step 1：进入示例目录

```bash
cd kag/examples/musique
```

### Step 2：配置模型

更新 [kag_config.yaml](./kag_config.yaml) 中的生成模型配置 ``openie_llm`` 和 ``chat_llm`` 和表示模型配置 ``vectorize_model``。

您需要设置正确的 ``api_key``。如果使用的模型供应商和模型名与默认值不同，您还需要更新 ``base_url`` 和 ``model``。

### Step 3：初始化项目

先对项目进行初始化。

```bash
knext project restore --host_addr http://127.0.0.1:8887 --proj_path .
```

### Step 4：提交 schema

执行以下命令提交 schema [MuSiQue.schema](./schema/MuSiQue.schema)。

```bash
knext schema commit
```

### Step 5：构建知识图谱

在 [builder](./builder) 目录执行 [indexer.py](./builder/indexer.py) 构建知识图谱。

```bash
cd builder && python indexer.py && cd ..
```

### Step 6：执行 QA 任务

在 [solver](./solver) 目录执行 [evaForMusique.py](./solver/evaForMusique.py) 生成答案并计算 EM 和 F1 指标。

```bash
cd solver && python evaForMusique.py && cd ..
```

生成的答案被保存至 ``./solver/musique_res_*.json``.

计算出的 EM 和 F1 指标被保存至 ``./solver/musique_metrics_*.json``.

### Step 7：（可选）清理

若要删除 checkpoint，可执行以下命令。

```bash
rm -rf ./builder/ckpt
rm -rf ./solver/ckpt
```

若要删除 KAG 项目及关联的知识图谱，可执行以下类似命令，将 OpenSPG server 地址和 KAG 项目 id 换为实际的值。

```bash
curl http://127.0.0.1:8887/project/api/delete?projectId=1
```

### Step 8：（可选）尝试更大的数据集

从 Step 1 重新开始，修改 [indexer.py](./builder/indexer.py) 和 [evaForMusique.py](./solver/evaForMusique.py) 以尝试更大的数据集。


# KAG Example: Risk Mining Knowledge Graph (RiskMining)

[English](./README.md) |
[简体中文](./README_cn.md)

## Overview

**Keywords**: semantic properties, dynamic multi-classification of entities, knowledge application in the context of hierarchical business knowledge and factual data.

![KAG RiskMining Diagram](/_static/images/examples/riskmining/kag-riskmining-diag.png)

## 1. Precondition

Please refer to [Quick Start](https://openspg.yuque.com/ndx6g9/cwh47i/rs7gr8g4s538b1n7) to install KAG and its dependency OpenSPG server, and learn about using KAG in developer mode.

## 2. Steps to reproduce

### Step 1: Enter the example directory

```bash
cd kag/examples/riskmining
```

### Step 2: Configure models

Update the generative model configurations ``openie_llm`` and ``chat_llm`` and the representational model configuration ``vectorize_model`` in [kag_config.yaml](./kag_config.yaml).

You need to fill in correct ``api_key``s. If your model providers and model names are different from the default values, you also need to update ``base_url`` and ``model``.

### Step 3: Project initialization

Initiate the project with the following command.

```bash
knext project restore --host_addr http://127.0.0.1:8887 --proj_path .
```

### Step 4: Create knowledge schema

The schema file [RiskMining.schema](./schema/RiskMining.schema) has been created and you can execute the following command to submit it:

```bash
knext schema commit
```

Submit the classification rules of RiskUser and RiskApp in [concept.rule](./schema/concept.rule):

```bash
knext schema reg_concept_rule --file ./schema/concept.rule
```

### Step 5: Knowledge graph construction

Submit the knowledge importing tasks.

```bash
cd builder && python indexer.py && cd ..
```

### Step 6: Executing query tasks for knowledge graph

OpenSPG supports the ISO GQL syntax. You can use the following command-line to execute a query task:

```bash
knext reasoner execute --dsl "${ql}"
```

#### Scenario 1: Semantic attributes vs text attributes

![KAG RiskMining Data Demo](/_static/images/examples/riskmining/kag-riskmining-data-demo.png)

MobilePhone: "standard attribute" vs "text attribute".

Save the following content as file ``dsl_task.txt``.

```cypher
MATCH
    (phone:STD.ChinaMobile)<-[:hasPhone]-(u:RiskMining.Person)
RETURN
    u.id, phone.id
```

Execute the query script.

```bash
knext reasoner execute --file dsl_task.txt
```

#### Scenario 2: Dynamic multi-type entities

**Note**: The classification rules defined in this section have been submitted in the previous "4. Create knowledge schema" section using the command ``knext schema reg_concept_rule``.

The detailed content of the following rules can also be found in the file [concept.rule](./schema/concept.rule).

**Taxonomy of gambling apps**

```text
Define (s:RiskMining.App)-[p:belongTo]->(o:`RiskMining.TaxOfRiskApp`/`赌博应用`) {
    Structure {
        (s)
    }
    Constraint {
        R1("风险标记为赌博"): s.riskMark like "%赌博%"
    }
}
```

Wang Wu is a gambling app developer, and Li Si is the owner of a gambling app. These two user entities correspond to different concept types.

**Gambling Developer's Identification Rule**

**Rule**: If a user has more than 5 devices, and these devices have the same app installed, then there exists a development relation.

```text
Define (s:RiskMining.Person)-[p:developed]->(o:RiskMining.App) {
    Structure {
        (s)-[:hasDevice]->(d:RiskMining.Device)-[:install]->(o)
    }
    Constraint {
        deviceNum = group(s,o).count(d)
        R1("设备超过5"): deviceNum > 5
    }
}
```

```text
Define (s:RiskMining.Person)-[p:belongTo]->(o:`RiskMining.TaxOfRiskUser`/`赌博App开发者`) {
    Structure {
        (s)-[:developed]->(app:`RiskMining.TaxOfRiskApp`/`赌博应用`)
    }
    Constraint {
    }
}
```

**Identifying the owner of a gambling app**

**Rule 1**: There exists a publishing relation between a person and the app.

```text
Define (s:RiskMining.Person)-[p:release]->(o:RiskMining.App) {
    Structure {
        (s)-[:holdShare]->(c:RiskMining.Company),
        (c)-[:hasCert]->(cert:RiskMining.Cert)<-[useCert]-(o)
    }
    Constraint {
    }
}
```

**Rule 2**: The user transfers money to the gambling app developer, and there exists a relation of publishing gambling app.

```text
Define (s:RiskMining.Person)-[p:belongTo]->(o:`RiskMining.TaxOfRiskApp`/`赌博App老板`) {
    Structure {
        (s)-[:release]->(a:`RiskMining.TaxOfRiskApp`/`赌博应用`),
        (u:RiskMining.Person)-[:developed]->(a),
        (s)-[:fundTrans]->(u)
    }
    Constraint {
    }
}
```

#### Scenario 3: Knowledge Application in the Context of hierarchical Business Knowledge and Factual Data

We can use GQL to query the criminal group information corresponding to black market applications.

**Retrieve all gambling applications**

Save the following content as file ``dsl_task1.txt``.

```cypher
MATCH (s:`RiskMining.TaxOfRiskApp`/`赌博应用`) RETURN s.id
```

Execute the query script.

```bash
knext reasoner execute --file dsl_task1.txt
```

**Retrieve the developers and owners of the gambling apps**

Save the following content as file ``dsl_task2.txt``.

```cypher
MATCH
    (u:`RiskMining.TaxOfRiskUser`/`赌博App开发者`)-[:developed]->(app:`RiskMining.TaxOfRiskApp`/`赌博应用`),
    (b:`RiskMining.TaxOfRiskUser`/`赌博App老板`)-[:release]->(app)
RETURN
    u.id, b.id, app.id
```

Execute the query script.

```bash
knext reasoner execute --file dsl_task2.txt
```

### Step 7: Use KAG to implement natural language QA

Here is the content of the ``solver`` directory.

```text
solver
├── prompt
│   └── logic_form_plan.py
└── qa.py
```

Modify the prompt to implement NL2LF conversion in the RiskMining domain.

```python
class LogicFormPlanPrompt(PromptOp):
    default_case_zh = """"cases": [
        {
            "Action": "张*三是一个赌博App的开发者吗?",
            "answer": "Step1:查询是否张*三的分类\nAction1:get_spo(s=s1:自然人[张*三], p=p1:属于, o=o1:风险用户)\nOutput:输出o1\nAction2:get(o1)"
        }
    ],"""
```

Assemble the solver code in ``qa.py``.

```python
def qa(self, query):
    resp = SolverPipeline()
    answer, trace_log = resp.run(query)

    logger.info(f"\n\nso the answer for '{query}' is: {answer}\n\n")
    return answer, trace_log
```

Execute ``qa.py``.

```bash
python ./solver/qa.py
```


# KAG 示例：黑产挖掘（RiskMining）

[English](./README.md) |
[简体中文](./README_cn.md)

**关键词**：语义属性，实体动态多分类，面向业务知识和事实数据分层下的知识应用

![KAG RiskMining Diagram](/_static/images/examples/riskmining/kag-riskmining-diag.png)

## 1. 前置条件

参考文档 [快速开始](https://openspg.yuque.com/ndx6g9/0.6/quzq24g4esal7q17) 安装 KAG 及其依赖的 OpenSPG server，了解开发者模式 KAG 的使用流程。

## 2. 复现步骤

### Step 1：进入示例目录

```bash
cd kag/examples/riskmining
```

### Step 2：配置模型

更新 [kag_config.yaml](./kag_config.yaml) 中的生成模型配置 ``openie_llm`` 和 ``chat_llm`` 和表示模型配置 ``vectorize_model``。

您需要设置正确的 ``api_key``。如果使用的模型供应商和模型名与默认值不同，您还需要更新 ``base_url`` 和 ``model``。

### Step 3：初始化项目

先对项目进行初始化。

```bash
knext project restore --host_addr http://127.0.0.1:8887 --proj_path .
```

### Step 4：知识建模

schema 文件已创建好，可执行如下命令提交。参见黑产 SPG Schema 模型 [RiskMining.schema](./schema/RiskMining.schema)。

```bash
knext schema commit
```

提交风险用户、风险 APP 的分类概念。参见黑产分类概念规则 [concept.rule](./schema/concept.rule)。

```bash
knext schema reg_concept_rule --file ./schema/concept.rule
```

### Step 5：知识构建

提交知识构建任务导入数据。

```bash
cd builder && python indexer.py && cd ..
```

### Step 6：执行图谱规则推理任务

SPG 支持 ISO GQL 语法，可用如下命令行执行查询任务。

```bash
knext reasoner execute --dsl "${ql}"
```

#### 场景 1：语义属性对比文本属性

![KAG RiskMining Data Demo](/_static/images/examples/riskmining/kag-riskmining-data-demo.png)

电话号码：标准属性 vs 文本属性。

编辑 ``dsl_task.txt``，输入如下内容：

```cypher
MATCH
    (phone:STD.ChinaMobile)<-[:hasPhone]-(u:RiskMining.Person)
RETURN
    u.id, phone.id
```

执行脚本：

```bash
knext reasoner execute --file dsl_task.txt
```

#### 场景 2：实体动态多类型

**注意**：本节定义的分类规则 [concept.rule](./schema/concept.rule) 已经在前面的“Step 4：知识建模”章节里通过命令 ``knext schema reg_concept_rule`` 提交。

以下规则的详细内容也可以在黑产分类概念规则 [concept.rule](./schema/concept.rule) 中查看。

**赌博 App 的分类**

```text
Define (s:RiskMining.App)-[p:belongTo]->(o:`RiskMining.TaxOfRiskApp`/`赌博应用`) {
    Structure {
        (s)
    }
    Constraint {
        R1("风险标记为赌博"): s.riskMark like "%赌博%"
    }
}
```

王五为赌博应用开发者，李四为赌博应用老板，两个用户实体对应了不同的概念类型。

**赌博开发者认定规则**

**规则**：用户存在大于 5 台设备，且这些设备中安装了相同的 App，则存在开发关系。

```text
Define (s:RiskMining.Person)-[p:developed]->(o:RiskMining.App) {
    Structure {
        (s)-[:hasDevice]->(d:RiskMining.Device)-[:install]->(o)
    }
    Constraint {
        deviceNum = group(s,o).count(d)
        R1("设备超过5"): deviceNum > 5
    }
}
```

```text
Define (s:RiskMining.Person)-[p:belongTo]->(o:`RiskMining.TaxOfRiskUser`/`赌博App开发者`) {
    Structure {
        (s)-[:developed]->(app:`RiskMining.TaxOfRiskApp`/`赌博应用`)
    }
    Constraint {
    }
}
```

**认定赌博 App 老板**

**规则 1**：人和 App 存在发布关系。

```text
Define (s:RiskMining.Person)-[p:release]->(o:RiskMining.App) {
    Structure {
        (s)-[:holdShare]->(c:RiskMining.Company),
        (c)-[:hasCert]->(cert:RiskMining.Cert)<-[useCert]-(o)
    }
    Constraint {
    }
}
```

**规则 2**：用户给该赌博App开发者转账，并且存在发布赌博应用行为。

```text
Define (s:RiskMining.Person)-[p:belongTo]->(o:`RiskMining.TaxOfRiskApp`/`赌博App老板`) {
    Structure {
        (s)-[:release]->(a:`RiskMining.TaxOfRiskApp`/`赌博应用`),
        (u:RiskMining.Person)-[:developed]->(a),
        (s)-[:fundTrans]->(u)
    }
    Constraint {
    }
}
```

#### 场景 3：面向业务知识和事实数据分层下的知识应用

基于 GQL 获取黑产应用对应的团伙信息。

**获取所有的赌博应用**

编辑 ``dsl_task1.txt``，输入如下内容：

```cypher
MATCH (s:`RiskMining.TaxOfRiskApp`/`赌博应用`) RETURN s.id
```

执行脚本：

```bash
knext reasoner execute --file dsl_task1.txt
```

**获取赌博 App 背后的开发者和老板**

编辑 ``dsl_task2.txt``，输入如下内容：

```cypher
MATCH
    (u:`RiskMining.TaxOfRiskUser`/`赌博App开发者`)-[:developed]->(app:`RiskMining.TaxOfRiskApp`/`赌博应用`),
    (b:`RiskMining.TaxOfRiskUser`/`赌博App老板`)-[:release]->(app)
RETURN
    u.id, b.id, app.id
```

执行脚本：

```bash
knext reasoner execute --file dsl_task2.txt
```

### Step 7：使用 KAG 实现自然语言问答

以下是 solver 目录的内容。

```text
solver
├── prompt
│   └── logic_form_plan.py
└── qa.py
```

修改 prompt，实现领域内的 NL2LF 转换。

```python
class LogicFormPlanPrompt(PromptOp):
    default_case_zh = """"cases": [
        {
            "Action": "张*三是一个赌博App的开发者吗?",
            "answer": "Step1:查询是否张*三的分类\nAction1:get_spo(s=s1:自然人[张*三], p=p1:属于, o=o1:风险用户)\nOutput:输出o1\nAction2:get(o1)"
        }
    ],"""
```

在 ``qa.py`` 中组装 solver 代码。

```python
def qa(self, query):
    resp = SolverPipeline()
    answer, trace_log = resp.run(query)

    logger.info(f"\n\nso the answer for '{query}' is: {answer}\n\n")
    return answer, trace_log
```

执行 ``qa.py``。

```bash
python ./solver/qa.py
```


# KAG Example: Enterprise Supply Chain Knowledge Graph (SupplyChain)

[English](./README.md) |
[简体中文](./README_cn.md)

## 1. Background

Credit institutions conduct comprehensive analysis of a company's financial condition, operating condition, market position, and management capabilities, and assign a rating grade to reflect the credit status of the company, in order to support credit business. In practice, it heavily relies on the information provided by the evaluated company itself, such as annual reports, various qualification documents, asset proofs, etc. This type of information can only provide micro-level information about the company itself and cannot reflect the company's market situation along the entire industry chain or obtain information beyond what is proven.

This example is based on the SPG framework to construct an industry chain enterprise Knowledge graph and extract in-depth information between companies based on the industry chain, to support company credit ratings.

## 2. Overview

Please refer to the document for knowledge modeling: [Schema of Enterprise Supply Chain Knowledge Graph](./schema/README.md), As shown in the example below:

![KAG SupplyChain Schema Diagram](/_static/images/examples/supplychain/kag-supplychain-schema-diag.gif)

Concept knowledge maintains industry chain-related data, including hierarchical relations, supply relations. Entity instances consist of only legal representatives and transfer information. Company instances are linked to product instances based on the attributes of the products they produce, enabling deep information mining between company instances, such as supplier relationships, industry peers, and shared legal representatives. By leveraging deep contextual information, more credit assessment factors can be provided.

![KAG SupplyChain Event Diagram](/_static/images/examples/supplychain/kag-supplychain-event-diag.gif)

Within the industrial chain, categories of product and company events are established. These categories are a combination of indices and trends. For example, an increase in price consists of the index "价格" (price) and the trend "上涨" (rising). Causal knowledge sets the events of a company's profit decrease and cost increase due to a rise in product prices. When a specific event occurs, such as a significant increase in rubber prices, it is categorized under the event of a price increase. As per the causal knowledge, a price increase in a product leads to two event types: a decrease in company profits and an increase in company costs. Consequently, new events are generated:"三角\*\*轮胎公司成本上涨事件" and "三角\*\*轮胎公司利润下跌".

## 3. Quick Start

### 3.1 Precondition

Please refer to [Quick Start](https://openspg.yuque.com/ndx6g9/cwh47i/rs7gr8g4s538b1n7) to install KAG and its dependency OpenSPG server, and learn about using KAG in developer mode.

### 3.2 Steps to reproduce

#### Step 1: Enter the example directory

```bash
cd kag/examples/supplychain
```

#### Step 2: Configure models

Update the generative model configurations ``openie_llm`` and ``chat_llm`` in [kag_config.yaml](./kag_config.yaml).

You need to fill in correct ``api_key``s. If your model providers and model names are different from the default values, you also need to update ``base_url`` and ``model``.

Since the representational model is not used in this example, you can retain the default configuration for the representative model ``vectorize_model``.

#### Step 3: Project initialization

Initiate the project with the following command.

```bash
knext project restore --host_addr http://127.0.0.1:8887 --proj_path .
```

#### Step 4: Create knowledge schema

The schema file has been created and you can execute the following command to submit it:

```bash
knext schema commit
```

Submit the *leadto* relationship logical rules:

```bash
knext schema reg_concept_rule --file ./schema/concept.rule
```

You can refer to [Schema of Enterprise Supply Chain Knowledge Graph](./schema/README.md) for detailed information on schema modeling.

#### Step 5: Knowledge graph construction

Knowledge construction involves importing data into the knowledge graph storage. For data introduction, please refer to the document: [Introduction to Data of Enterprise Supply Chain](./builder/data/README.md).

In this example, we will demonstrate the conversion of structured data and entity linking. For specific details, please refer to the document: [Enterprise Supply Chain Case Knowledge Graph Construction](./builder/README.md).

Submit the knowledge importing tasks.

```bash
cd builder && python indexer.py && cd ..
```

#### Step 6: Executing query tasks for knowledge graph

OpenSPG supports the ISO GQL syntax. You can use the following command-line to execute a query task:

```bash
knext reasoner execute --dsl "${ql}"
```

For specific task details, please refer to the document: [Enterprise Credit Graph Query Tasks in Supply Chain](./reasoner/README.md).

Querying Credit Rating Factors:

```bash
knext reasoner execute --dsl "
MATCH
    (s:SupplyChain.Company)
RETURN
    s.id, s.name, s.fundTrans1Month, s.fundTrans3Month,
    s.fundTrans6Month, s.fundTrans1MonthIn, s.fundTrans3MonthIn,
    s.fundTrans6MonthIn, s.cashflowDiff1Month, s.cashflowDiff3Month,
    s.cashflowDiff6Month
"
```

```bash
knext reasoner execute --dsl "
MATCH
    (s:SupplyChain.Company)-[:mainSupply]->(o:SupplyChain.Company)
RETURN
    s.name, o.name
"
```

```bash
knext reasoner execute --dsl "
MATCH
    (s:SupplyChain.Company)-[:belongToIndustry]->(o:SupplyChain.Industry)
RETURN
    s.name, o.name
"
```

```bash
knext reasoner execute --dsl "
MATCH
    (s:SupplyChain.Company)-[:sameLegalRepresentative]->(o:SupplyChain.Company)
RETURN
    s.name, o.name
"
```

Analyzing the Impact of an Event:

```bash
knext reasoner execute --dsl "
MATCH
    (s:SupplyChain.ProductChainEvent)-[:leadTo]->(o:SupplyChain.CompanyEvent)
RETURN
    s.id, s.subject, o.subject, o.name
"
```

#### Step 7: Execute DSL and QA tasks

```bash
python ./solver/qa.py
```


# KAG 示例：企业供应链（SupplyChain）

[English](./README.md) |
[简体中文](./README_cn.md)

## 1. 背景

信贷机构对企业的财务状况、经营状况、市场地位、管理能力等进行综合分析，给予企业一个评级等级，反映其信用状况的好坏，以便支撑信贷业务。在实践中基本依赖被评估企业自身提供的信息，例如企业年报、各类资质文件、资产证明等，这一类信息只能围绕企业自身提供微观层面的信息，不能体现企业在整个产业链上下游市场情况，也无法得到证明之外的信息。

本例基于 SPG 构建产业链企业图谱，挖掘出企业之间基于产业链的深度信息，支持企业信用评级。

## 2. 总览

建模参考 [基于 SPG 建模的产业链企业图谱](./schema/README_cn.md)，如下图示意。

![KAG SupplyChain Schema Diagram](/_static/images/examples/supplychain/kag-supplychain-schema-diag.gif)

概念知识维护着产业链相关数据，包括上下位层级、供应关系；实体实例仅有法人代表、转账信息，公司实例通过生产的产品属性和概念中的产品节点挂载，实现了公司实例之间的深度信息挖掘，例如供应商、同行业、同法人代表等关系。基于深度上下文信息，可提供更多的信用评估因子。

![KAG SupplyChain Event Diagram](/_static/images/examples/supplychain/kag-supplychain-event-diag.gif)

产业链中建立了产品和公司事件类别，该类别属于指标和趋势的一种组合，例如价格上涨，是由指标：价格，趋势：上涨两部分构成。

事理知识设定了产品价格上涨引起公司利润下降及公司成本上涨事件，当发生某个具体事件时，例如“橡胶价格大涨事件”，被归类在产品价格上涨，由于事理知识中定义产品价格上涨会引起公司利润下降/公司成本上涨两个事件类型，会产出新事件：“三角\*\*轮胎公司成本上涨事件”、“三角\*\*轮胎公司利润下跌”。

## 3. Quick Start

### 3.1 前置条件

请参考文档 [快速开始](https://openspg.yuque.com/ndx6g9/0.6/quzq24g4esal7q17) 安装 KAG 及其依赖的 OpenSPG server，并了解开发者模式 KAG 的使用流程。

### 3.2 复现步骤

#### Step 1：进入示例目录

```bash
cd kag/examples/supplychain
```

#### Step 2：配置模型

更新 [kag_config.yaml](./kag_config.yaml) 中的生成模型配置 ``openie_llm`` 和 ``chat_llm``。

您需要设置正确的 ``api_key``。如果使用的模型供应商和模型名与默认值不同，您还需要更新 ``base_url`` 和 ``model``。

在本示例中未使用表示模型，可保持表示模型配置 ``vectorize_model`` 的默认配置。

#### Step 3：初始化项目

先对项目进行初始化。

```bash
knext project restore --host_addr http://127.0.0.1:8887 --proj_path .
```

#### Step 4：知识建模

schema 文件已创建好，可执行如下命令提交。

```bash
knext schema commit
```

提交 *leadto* 关系逻辑规则。

```bash
knext schema reg_concept_rule --file ./schema/concept.rule
```

schema 建模详细内容可参见 [基于 SPG 建模的产业链企业图谱](./schema/README_cn.md)。

#### Step 5：知识构建

知识构建将数据导入到系统中，数据介绍参见文档 [产业链案例数据介绍](./builder/data/README_cn.md)。

本例主要为结构化数据，故演示结构化数据转换和实体链指，具体细节可参见文档 [产业链案例知识构建](./builder/README_cn.md)。

提交知识构建任务导入数据。

```bash
cd builder && python indexer.py && cd ..
```

#### Step 6：执行图谱任务

SPG 支持 ISO GQL 语法，可用如下命令行执行查询任务。

```bash
knext reasoner execute --dsl "${ql}"
```

具体任务详情可参见文档 [产业链企业信用图谱查询任务](./reasoner/README_cn.md)。

查询信用评级因子：

```bash
knext reasoner execute --dsl "
MATCH
    (s:SupplyChain.Company)
RETURN
    s.id, s.name, s.fundTrans1Month, s.fundTrans3Month,
    s.fundTrans6Month, s.fundTrans1MonthIn, s.fundTrans3MonthIn,
    s.fundTrans6MonthIn, s.cashflowDiff1Month, s.cashflowDiff3Month,
    s.cashflowDiff6Month
"
```

```bash
knext reasoner execute --dsl "
MATCH
    (s:SupplyChain.Company)-[:mainSupply]->(o:SupplyChain.Company)
RETURN
    s.name, o.name
"
```

```bash
knext reasoner execute --dsl "
MATCH
    (s:SupplyChain.Company)-[:belongToIndustry]->(o:SupplyChain.Industry)
RETURN
    s.name, o.name
"
```

```bash
knext reasoner execute --dsl "
MATCH
    (s:SupplyChain.Company)-[:sameLegalRepresentative]->(o:SupplyChain.Company)
RETURN
    s.name, o.name
"
```

事件影响分析：

```bash
knext reasoner execute --dsl "
MATCH
    (s:SupplyChain.ProductChainEvent)-[:leadTo]->(o:SupplyChain.CompanyEvent)
RETURN
    s.id, s.subject, o.subject, o.name
"
```

#### Step 7：执行 DSL 及 QA 任务

```bash
python ./solver/qa.py
```


# Enterprise Supply Chain Case Knowledge Graph Construction

[English](./README.md) |
[简体中文](./README_cn.md)

In this example, all the data are structured. There are two main capabilities required in to import the data:

* Structured Mapping: The original data and the schema-defined fields are not completely consistent, so a data field mapping process needs to be defined.

* Entity Linking: In relationship building, entity linking is a very important construction method. This example demonstrates a simple case of implementing entity linking capability for companies.

## 1. Structured Mapping from Source Data to SPG Data

Taking the import of ``Company`` instances as an example:

```text
id,name,products
CSF0000000254,北大*药*份限公司,"医疗器械批发,医药批发,制药,其他化学药品"
```

The code for importing ``Company`` instances is as follows:

```python
class SupplyChainDefaulStructuredBuilderChain(BuilderChainABC):
    def __init__(self, spg_type_name: str):
        super().__init__()
        self.spg_type_name = spg_type_name

    def build(self, **kwargs):
        """
        Builds the processing chain for the SPG.

        Args:
            **kwargs: Additional keyword arguments.

        Returns:
            chain: The constructed processing chain.
        """
        self.mapping = SPGTypeMapping(spg_type_name=self.spg_type_name)
        self.sink = KGWriter()
        self.vectorizer = BatchVectorizer.from_config(
            KAG_CONFIG.all_config["chain_vectorizer"]
        )
        chain = self.mapping >> self.vectorizer >> self.sink
        return chain

    def get_component_with_ckpts(self):
        return [
            self.vectorizer,
        ]
```

In general, this mapping relationship can satisfy the import of structured data. However, in some scenarios, it may be necessary to manipulate the data to meet specific requirements. In such cases, we need to implemented a user-defined operator.

## 2. User-defined Entity Linking Operator

Consider the following data:

```text
id,name,age,legalRep
0,路**,63,"新疆*花*股*限公司,三角*胎股*限公司,传化*联*份限公司"
```

The ``legalRep`` field is the company name, but the company ID is set as the primary key, it is not possible to directly associate the company name with a specific company. Assuming there is a search service available that can convert the company name to an ID, a user-defined linking operator needs to be developed to perform this conversion.

```python
def company_link_func(prop_value, node):
    sc = SearchClient(KAG_PROJECT_CONF.host_addr, KAG_PROJECT_CONF.project_id)
    company_id = []
    records = sc.search_text(
        prop_value, label_constraints=["SupplyChain.Company"], topk=1
    )
    if records:
        company_id.append(records[0]["node"]["id"])
    return company_id

class SupplyChainPersonChain(BuilderChainABC):
    def __init__(self, spg_type_name: str):
        # super().__init__()
        self.spg_type_name = spg_type_name

    def build(self, **kwargs):
        self.mapping = (
            SPGTypeMapping(spg_type_name=self.spg_type_name)
            .add_property_mapping("name", "name")
            .add_property_mapping("id", "id")
            .add_property_mapping("age", "age")
            .add_property_mapping(
                "legalRepresentative",
                "legalRepresentative",
                link_func=company_link_func,
            )
        )
        self.vectorizer = BatchVectorizer.from_config(
            KAG_CONFIG.all_config["chain_vectorizer"]
        )
        self.sink = KGWriter()
        return self.mapping >> self.vectorizer >> self.sink

    def get_component_with_ckpts(self):
        return [
            self.vectorizer,
        ]

    def close_checkpointers(self):
        for node in self.get_component_with_ckpts():
            if node and hasattr(node, "checkpointer"):
                node.checkpointer.close()
```


# 产业链案例知识构建

[English](./README.md) |
[简体中文](./README_cn.md)

本例中数据均为结构化数据，导入数据主要需要两个能力：

* 结构化 mapping：原始数据和 schema 定义表字段并不完全一致，需要定义数据字段映射过程。

* 实体链指：在关系构建中，实体链指是非常重要的建设手段，本例演示一个简单 case，实现公司的链指能力。

本例中的代码可在 [kag/examples/supplychain/builder/indexer.py](./indexer.py) 中查看。

## 1. 源数据到 SPG 数据的 mapping 能力

以导入 Company 数据为例：

```text
id,name,products
CSF0000000254,北大*药*份限公司,"医疗器械批发,医药批发,制药,其他化学药品"
```

导入 Company 的代码如下：

```python
class SupplyChainDefaulStructuredBuilderChain(BuilderChainABC):
    def __init__(self, spg_type_name: str):
        super().__init__()
        self.spg_type_name = spg_type_name

    def build(self, **kwargs):
        """
        Builds the processing chain for the SPG.

        Args:
            **kwargs: Additional keyword arguments.

        Returns:
            chain: The constructed processing chain.
        """
        self.mapping = SPGTypeMapping(spg_type_name=self.spg_type_name)
        self.sink = KGWriter()
        self.vectorizer = BatchVectorizer.from_config(
            KAG_CONFIG.all_config["chain_vectorizer"]
        )
        chain = self.mapping >> self.vectorizer >> self.sink
        return chain

    def get_component_with_ckpts(self):
        return [
            self.vectorizer,
        ]
```

一般情况下这种映射关系基本能够满足结构化数据导入，但在一些场景下可能需要对数据进行部分数据才能满足要求，此时就需要实现自定义算子来处理问题。

## 2. 自定义算子实现链指能力

假设有如下数据：

```text
id,name,age,legalRep
0,路**,63,"新疆*花*股*限公司,三角*胎股*限公司,传化*联*份限公司"
```

``legalRep`` 字段为公司名字，但在系统中已经将公司 ``id`` 设置成为主键，直接通过公司名是无法关联到具体公司，假定存在一个搜索服务，可将公司名转换为 ``id``，此时需要自定开发一个链指算子，实现该过程的转换:

```python
def company_link_func(prop_value, node):
    sc = SearchClient(KAG_PROJECT_CONF.host_addr, KAG_PROJECT_CONF.project_id)
    company_id = []
    records = sc.search_text(
        prop_value, label_constraints=["SupplyChain.Company"], topk=1
    )
    if records:
        company_id.append(records[0]["node"]["id"])
    return company_id

class SupplyChainPersonChain(BuilderChainABC):
    def __init__(self, spg_type_name: str):
        # super().__init__()
        self.spg_type_name = spg_type_name

    def build(self, **kwargs):
        self.mapping = (
            SPGTypeMapping(spg_type_name=self.spg_type_name)
            .add_property_mapping("name", "name")
            .add_property_mapping("id", "id")
            .add_property_mapping("age", "age")
            .add_property_mapping(
                "legalRepresentative",
                "legalRepresentative",
                link_func=company_link_func,
            )
        )
        self.vectorizer = BatchVectorizer.from_config(
            KAG_CONFIG.all_config["chain_vectorizer"]
        )
        self.sink = KGWriter()
        return self.mapping >> self.vectorizer >> self.sink

    def get_component_with_ckpts(self):
        return [
            self.vectorizer,
        ]

    def close_checkpointers(self):
        for node in self.get_component_with_ckpts():
            if node and hasattr(node, "checkpointer"):
                node.checkpointer.close()
```


# Enterprise Credit Graph Query Tasks in Supply Chain

[English](./README.md) |
[简体中文](./README_cn.md)

## Scenario 1: Generation of Enterprise Credit Rating Features

Requirement: In enterprise credit rating, the following decision factors are needed:

1. Primary supplier relations
2. Industry of the products produced by the enterprise
3. Transfer transaction records of funds for the past 1 month, 3 months, and 6 months
4. Difference in funds flow for the past 1 month, 3 months, and 6 months
5. Information on related companies controlled by the ultimate beneficial owner

However, in the original knowledge graph, only fund transfer transactions and legal representative information are available, making it impossible to directly obtain the above features. This example demonstrates how to use OpenSPG to obtain these 5 features.

The feature definitions are present in the schema file, which can be viewed by clicking [SupplyChain.schema](../schema/SupplyChain.schema).

**Feature 1: Defining primary supply chain relations between companies**

with the following rule definition:

```text
Define (s:Compnay)-[p:mainSupply]->(o:Company) {
    Structure {
        (s)-[:product]->(upProd:Product)-[:hasSupplyChain]->(downProd:Product)<-[:product]-(o),
        (o)-[f:fundTrans]->(s)
        (otherCompany:Company)-[otherf:fundTrans]->(s)
    }
    Constraint {
        // Compute the percentage of incoming transfers for company `o`
        otherTransSum("Total amount of incoming transfers") = group(s).sum(otherf.transAmt)
        targetTransSum("Total amount of transfers received by company o") = group(s,o).sum(f.transAmt)
        transRate = targetTransSum*1.0/(otherTransSum + targetTransSum)
        R1("The percentage must be over 50%"): transRate > 0.5
    }
}
```

**Feature 2: Industry of the Products Produced by the Enterprise**

```text
Define (s:Compnay)-[p:belongToIndustry]->(o:Industry) {
    Structure {
        (s)-[:product]->(c:Product)-[:belongToIndustry]->(o)
    }
    Constraint {
    }
}
```

**Feature 3: Transfer transaction records of funds for the past 1 month, 3 months, and 6 months**

```text
// Amount of outgoing transfers for the past 1 month
Define (s:Compnay)-[p:fundTrans1Month]->(o:Int) {
    Structure {
        (s)-[f:fundTrans]->(c:Company)
    }
    Constraint {
        R1("Transactions within the past 1 month"): date_diff(from_unix_time(now(), 'yyyyMMdd'),f.transDate) < 30
        totalOut = group(s).sum(transAmt)
        o = totalOut
    }
}

// Amount of outgoing transfers for the past 3 month
Define (s:Compnay)-[p:fundTrans3Month]->(o:Int) {
    Structure {
        (s)-[f:fundTrans]->(c:Company)
    }
    Constraint {
        R1("Transactions within the past 4 month"): date_diff(from_unix_time(now(), 'yyyyMMdd'),f.transDate) < 90
        totalOut = group(s).sum(transAmt)
        o = totalOut
    }
}

// Amount of outgoing transfers for the past 6 month
Define (s:Compnay)-[p:fundTrans6Month]->(o:Int) {
    Structure {
        (s)-[f:fundTrans]->(c:Company)
    }
    Constraint {
        R1("Transactions within the past 6 month"): date_diff(from_unix_time(now(), 'yyyyMMdd'),f.transDate) < 180
        totalOut = group(s).sum(transAmt)
        o = totalOut
    }
}

// Amount of incoming transfers for the past 1 month
Define (s:Compnay)-[p:fundTrans1MonthIn]->(o:Int) {
    Structure {
        (s)<-[f:fundTrans]-(c:Company)
    }
    Constraint {
        R1("Transactions within the past 1 month"): date_diff(from_unix_time(now(), 'yyyyMMdd'),f.transDate) < 30
        totalOut = group(s).sum(transAmt)
        o = totalOut
    }
}

// Amount of incoming transfers for the past 3 month
Define (s:Compnay)-[p:fundTrans3MonthIn]->(o:Int) {
    Structure {
        (s)<-[f:fundTrans]-(c:Company)
    }
    Constraint {
        R1("Transactions within the past 3 month"): date_diff(from_unix_time(now(), 'yyyyMMdd'),f.transDate) < 90
        totalOut = group(s).sum(transAmt)
        o = totalOut
    }
}

// Amount of incoming transfers for the past 6 month
Define (s:Compnay)-[p:fundTrans6MonthIn]->(o:Int) {
    Structure {
        (s)<-[f:fundTrans]-(c:Company)
    }
    Constraint {
        R1("Transactions within the past 6 month"): date_diff(from_unix_time(now(), 'yyyyMMdd'),f.transDate) < 180
        totalOut = group(s).sum(transAmt)
        o = totalOut
    }
}
```

**Feature 4: Difference in funds flow for the past 1 month, 3 months, and 6 months**

```text
// Funds flow difference in the past 1 month
Define (s:Company)-[p:cashflowDiff1Month]->(o:Integer) {
    Structure {
        (s)
    }
    Constraint {
        // Refer to the rule in Feature 3
        fundTrans1Month = rule_value(s.fundTrans1Month == null, 0, s.fundTrans1Month)
        fundTrans1MonthIn = rule_value(s.fundTrans1MonthIn == null, 0, s.fundTrans1MonthIn)
        o = fundTrans1Month - fundTrans1MonthIn
    }
}

// Funds flow difference in the past 3 month
Define (s:Company)-[p:cashflowDiff3Month]->(o:Integer) {
    Structure {
        (s)
    }
    Constraint {
        // Refer to the rule in Feature 3
        fundTrans3Month = rule_value(s.fundTrans3Month == null, 0, s.fundTrans3Month)
        fundTrans3MonthIn = rule_value(s.fundTrans3MonthIn == null, 0, s.fundTrans3MonthIn)
        o = fundTrans3Month - fundTrans3MonthIn
    }
}

// Funds flow difference in the past 6 month
Define (s:Company)-[p:cashflowDiff6Month]->(o:Integer) {
    Structure {
        (s)
    }
    Constraint {
        fundTrans6Month = rule_value(s.fundTrans6Month == null, 0, s.fundTrans6Month)
        fundTrans6MonthIn = rule_value(s.fundTrans6MonthIn == null, 0, s.fundTrans6MonthIn)
        o = fundTrans6Month - fundTrans6MonthIn
    }
}
```

**Feature 5: Information on related companies controlled by the ultimate beneficial owner**

```text
// Definition of the "same legal reprensentative" relation
Define (s:Compnay)-[p:sameLegalReprensentative]->(o:Company) {
    Structure {
        (s)<-[:legalReprensentative]-(u:Person)-[:legalReprensentative]->(o)
    }
    Constraint {
    }
}
```

Obtaining specific features of a particular company through GQL using the following query:

```cypher
MATCH
    (s:SupplyChain.Company)
RETURN
    s.id, s.fundTrans1Month, s.fundTrans3Month,
    s.fundTrans6Month, s.fundTrans1MonthIn, s.fundTrans3MonthIn,
    s.fundTrans6MonthIn, s.cashflowDiff1Month, s.cashflowDiff3Month, s.cashflowDiff6Month
```

```cypher
MATCH
    (s:SupplyChain.Company)-[:mainSupply]->(o:SupplyChain.Company)
RETURN
    s.id, o.id
```

```cypher
MATCH
    (s:SupplyChain.Company)-[:belongToIndustry]->(o:SupplyChain.Industry)
RETURN
    s.id, o.id
```

```cypher
MATCH
    (s:SupplyChain.Company)-[:sameLegalRepresentative]->(o:SupplyChain.Company)
RETURN
    s.id, o.id
```

## Scenario 2: Change in the company's supply chain

Suppose that there is a change in the products produced by the company：

```text
"钱****份限公司"发布公告，生产产品“三轮摩托车，二轮摩托车”变更为“两轮摩托车”，则"三角**轮胎股份"和钱"****份限公司"的主供应链关系自动断裂，"三角**轮胎股份"和"钱****份限公司"不再具有主供应链关系
```

The updated data is available in ``CompanyUpdate.csv``:

```text
id,name,products
CSF0000001662,浙江**摩托**限公司,"汽车-摩托车制造-二轮摩托车"
```

resubmit the building task：

```bash
knext builder execute CompanyUpdate
```

After the execution is completed, if you query again, only the Two-Wheeled Motorcycle will be returned, and the Three-Wheeled Motorcycle will no longer be associated.

```cypher
MATCH
    (s:SupplyChain.Company)-[:product]->(o:SupplyChain.Product)
WHERE
    s.id = "CSF0000001662"
RETURN
    s.id, o.id
```

## Scenario 3: Impact on the Supply Chain Event

The event details are as follows:

```text
id,name,subject,index,trend
1,顺丁橡胶成本上涨,商品化工-橡胶-合成橡胶-顺丁橡胶,价格,上涨
```

submit the building task of the event type:

```bash
knext builder execute ProductChainEvent
```

The transmission linkages are as follows:

![KAG SupplyChain Product Chain Demo](/_static/images/examples/supplychain/kag-supplychain-product-chain-demo-en.gif)

Butadiene rubber costs rise, classified as an event of price increase in the supply chain.

The logical rule expression is as follows:

```text
// When the attributes of ProductChainEvent satisfy the condition of price increase,
// the event is classified as a price increase event.
Define (e:ProductChainEvent)-[p:belongTo]->(o:`TaxonofProductChainEvent`/`价格上涨`) {
    Structure {
    }
    Constraint {
        R1: e.index == '价格'
        R2: e.trend == '上涨'
    }
}
```

Price increase in the supply chain, under the following conditions, will result in cost rise for specific companies.

```text
// The rules for price increase and increase in company costs are defined as follows.
Define (s:`TaxonofProductChainEvent`/`价格上涨`)-[p:leadTo]->(o:`TaxonofCompanyEvent`/`成本上涨`) {
    Structure {
        //1. Find the subject of the supply chain event, which is butadiene rubber in this case
        //2. Identify the downstream products of butadiene rubber, which are bias tires in this case
        //3. Identify all the companies that produce bias tires, which is "Triangle** Tire Co., Ltd." in this case
        (s)-[:subject]->[prod:Product]-[:hasSupplyChain]->(down:Product)<-[:product]-(c:Company)
    }
    Constraint {
    }
    Action {
        // Create a company cost increase event with the subject being the obtained "Triangle** Tire Co., Ltd."
        downEvent = createNodeInstance(
            type=CompanyEvent,
            value={
                subject=c.id
                trend="上涨"
                index="成本"
            }
        )
        // Since this event is caused by a price increase in the supply chain, add an edge between them.
        createEdgeInstance(
            src=s,
            dst=downEvent,
            type=leadTo,
            value={
            }
        )
    }
}
```

You can find the impact of a specific event by using the following query statement.

```cypher
MATCH
    (s:SupplyChain.ProductChainEvent)-[:leadTo]->(o:SupplyChain.CompanyEvent)
RETURN
    s.id,s.subject,o.subject,o.name
```


# 产业链企业信用图谱查询任务

[English](./README.md) |
[简体中文](./README_cn.md)

## 场景 1：企业信用评级特征生成

需求：在企业信用评级中，假定需要得到如下决策因子

1. 主供应商关系
2. 企业生产产品所在行业
3. 企业资金近 1 月、3 月、6 月转账流水
4. 企业资金近 1 月、3 月、6 月流水差
5. 实控人相关公司信息

但在原有图谱中，只有资金转账、法人代表信息，无法直接获取上述特征，本例演示如何通过 SPG 完成如上 5 个特征获取。

特征定义在 schema 文件中，可点击查看企业供应链图谱 schema [SupplyChain.schema](./SupplyChain.schema)。

**特征 1：先定义企业和企业间的主供应链关系，规则定义如下**

```text
Define (s:Compnay)-[p:mainSupply]->(o:Company) {
    Structure {
        (s)-[:product]->(upProd:Product)-[:hasSupplyChain]->(downProd:Product)<-[:product]-(o),
        (o)-[f:fundTrans]->(s)
        (otherCompany:Company)-[otherf:fundTrans]->(s)
    }
    Constraint {
        // 计算公司o的转入占比
        otherTransSum("总共转入金额") = group(s).sum(otherf.transAmt)
        targetTransSum("o转入的金额总数") = group(s,o).sum(f.transAmt)
        transRate = targetTransSum*1.0/(otherTransSum + targetTransSum)
        R1("占比必须超过50%"): transRate > 0.5
    }
}
```

**特征 2：企业生成产品所在行业**

```text
Define (s:Compnay)-[p:belongToIndustry]->(o:Industry) {
    Structure {
        (s)-[:product]->(c:Product)-[:belongToIndustry]->(o)
    }
    Constraint {
    }
}
```

**特征 3：企业资金近 1 月、3 月、6 月转账流水**

```text
// 近1个月流出金额
Define (s:Compnay)-[p:fundTrans1Month]->(o:Int) {
    Structure {
        (s)-[f:fundTrans]->(c:Company)
    }
    Constraint {
        R1("近1个月的流出资金"): date_diff(from_unix_time(now(), 'yyyyMMdd'),f.transDate) < 30
        totalOut = group(s).sum(transAmt)
        o = totalOut
    }
}

// 近3个月流出金额
Define (s:Compnay)-[p:fundTrans3Month]->(o:Int) {
    Structure {
        (s)-[f:fundTrans]->(c:Company)
    }
    Constraint {
        R1("近4个月的流出资金"): date_diff(from_unix_time(now(), 'yyyyMMdd'),f.transDate) < 90
        totalOut = group(s).sum(transAmt)
        o = totalOut
    }
}

// 近6个月流出金额
Define (s:Compnay)-[p:fundTrans6Month]->(o:Int) {
    Structure {
        (s)-[f:fundTrans]->(c:Company)
    }
    Constraint {
        R1("近5个月的流出资金"): date_diff(from_unix_time(now(), 'yyyyMMdd'),f.transDate) < 180
        totalOut = group(s).sum(transAmt)
        o = totalOut
    }
}

// 近1个月流入金额
Define (s:Compnay)-[p:fundTrans1MonthIn]->(o:Int) {
    Structure {
        (s)<-[f:fundTrans]-(c:Company)
    }
    Constraint {
        R1("近1个月的流入资金"): date_diff(from_unix_time(now(), 'yyyyMMdd'),f.transDate) < 30
        totalOut = group(s).sum(transAmt)
        o = totalOut
    }
}

// 近3个月流入金额
Define (s:Compnay)-[p:fundTrans3MonthIn]->(o:Int) {
    Structure {
        (s)<-[f:fundTrans]-(c:Company)
    }
    Constraint {
        R1("近3个月的流入资金"): date_diff(from_unix_time(now(), 'yyyyMMdd'),f.transDate) < 90
        totalOut = group(s).sum(transAmt)
        o = totalOut
    }
}

// 近6个月流入金额
Define (s:Compnay)-[p:fundTrans6MonthIn]->(o:Int) {
    Structure {
        (s)<-[f:fundTrans]-(c:Company)
    }
    Constraint {
        R1("近6个月的流入资金"): date_diff(from_unix_time(now(), 'yyyyMMdd'),f.transDate) < 180
        totalOut = group(s).sum(transAmt)
        o = totalOut
    }
}
```

**特征 4：企业资金近 1 月、3 月、6 月流水差**

```text
// 近1个月资金流水差
Define (s:Company)-[p:cashflowDiff1Month]->(o:Integer) {
    Structure {
        (s)
    }
    Constraint {
        // 此处引用特征3中的规则
        fundTrans1Month = rule_value(s.fundTrans1Month == null, 0, s.fundTrans1Month)
        fundTrans1MonthIn = rule_value(s.fundTrans1MonthIn == null, 0, s.fundTrans1MonthIn)
        o = fundTrans1Month - fundTrans1MonthIn
    }
}

// 近3个月资金流水差
Define (s:Company)-[p:cashflowDiff3Month]->(o:Integer) {
    Structure {
        (s)
    }
    Constraint {
        // 此处引用特征3中的规则
        fundTrans3Month = rule_value(s.fundTrans3Month == null, 0, s.fundTrans3Month)
        fundTrans3MonthIn = rule_value(s.fundTrans3MonthIn == null, 0, s.fundTrans3MonthIn)
        o = fundTrans3Month - fundTrans3MonthIn
    }
}

// 近6个月资金流水差
Define (s:Company)-[p:cashflowDiff6Month]->(o:Integer) {
    Structure {
        (s)
    }
    Constraint {
        fundTrans6Month = rule_value(s.fundTrans6Month == null, 0, s.fundTrans6Month)
        fundTrans6MonthIn = rule_value(s.fundTrans6MonthIn == null, 0, s.fundTrans6MonthIn)
        o = fundTrans6Month - fundTrans6MonthIn
  }
}
```

**特征 5：同实控人公司**

```text
// 定义同法人关系
Define (s:Compnay)-[p:sameLegalReprensentative]->(o:Company) {
    Structure {
        (s)<-[:legalReprensentative]-(u:Person)-[:legalReprensentative]->(o)
    }
    Constraint {
    }
}
```

通过如下 GQL 执行得到某个公司的具体特征:

```cypher
MATCH
    (s:SupplyChain.Company)
RETURN
    s.id, s.fundTrans1Month, s.fundTrans3Month,
    s.fundTrans6Month, s.fundTrans1MonthIn, s.fundTrans3MonthIn,
    s.fundTrans6MonthIn, s.cashflowDiff1Month, s.cashflowDiff3Month, s.cashflowDiff6Month
```

```cypher
MATCH
    (s:SupplyChain.Company)-[:mainSupply]->(o:SupplyChain.Company)
RETURN
    s.id, o.id
```

```cypher
MATCH
    (s:SupplyChain.Company)-[:belongToIndustry]->(o:SupplyChain.Industry)
RETURN
    s.id, o.id
```

```cypher
MATCH
    (s:SupplyChain.Company)-[:sameLegalRepresentative]->(o:SupplyChain.Company)
RETURN
    s.id, o.id
```

## 场景 2：企业供应链发生变化

假设供应链发生如下变化：

```text
"钱****份限公司"发布公告，生产产品“三轮摩托车，二轮摩托车”变更为“两轮摩托车”，则"三角**轮胎股份"和钱"****份限公司"的主供应链关系自动断裂，"三角**轮胎股份"和"钱****份限公司"不再具有主供应链关系
```

变更后的数据保存在 ``CompanyUpdate.csv``:

```text
id,name,products
CSF0000001662,浙江**摩托**限公司,"汽车-摩托车制造-二轮摩托车"
```

重新提交任务:

```bash
knext builder execute CompanyUpdate
```

执行完成后再次查询，只会返回二轮摩托车，而三轮摩托车不再被关联:

```cypher
MATCH
    (s:SupplyChain.Company)-[:product]->(o:SupplyChain.Product)
WHERE
    s.id = "CSF0000001662"
RETURN
    s.id, o.id
```

## 场景 3：产业链影响

事件内容如下:

```text
id,name,subject,index,trend
1,顺丁橡胶成本上涨,商品化工-橡胶-合成橡胶-顺丁橡胶,价格,上涨
```

提交事件数据：

```bash
knext builder execute ProductChainEvent
```

传导链路如下:

![KAG SupplyChain Product Chain Demo](/_static/images/examples/supplychain/kag-supplychain-product-chain-demo-cn.gif)

顺丁橡胶成本上升，被分类为产业链价格上涨事件，如下 DSL:

```text
// ProductChainEvent为一个具体的事件实例，当其属性满足价格上涨条件时，该事件分类为价格上涨事件
Define (e:ProductChainEvent)-[p:belongTo]->(o:`TaxonofProductChainEvent`/`价格上涨`) {
    Structure {
    }
    Constraint {
        R1: e.index == '价格'
        R2: e.trend == '上涨'
    }
}
```

产业链价格上涨，在如下条件下，会导致特定公司的成本上升。

```text
// 定义了价格上涨和企业成本上升的规则
Define (s:`TaxonofProductChainEvent`/`价格上涨`)-[p:leadTo]->(o:`TaxonofCompanyEvent`/`成本上涨`) {
    Structure {
        //1、找到产业链事件的主体，本例中为顺丁橡胶
        //2、找到顺丁橡胶的下游产品，本例中为斜交轮胎
        //3、找到生成斜交轮胎的所有企业，本例中为三角**轮胎股份
        (s)-[:subject]->[prod:Product]-[:hasSupplyChain]->(down:Product)<-[:product]-(c:Company)
    }
    Constraint {
    }
    Action {
        // 创建一个公司成本上升事件，主体为查询得到的三角**轮胎股份
        downEvent = createNodeInstance(
            type=CompanyEvent,
            value={
                subject=c.id
                trend="上涨"
                index="成本"
            }
        )
        // 由于这个事件是通过产业链价格上涨引起，故在两者之间增加一条边
        createEdgeInstance(
            src=s,
            dst=downEvent,
            type=leadTo,
            value={
            }
        )
    }
}
```

可通过如下查询语句查出某个事件产生的影响。

```cypher
MATCH
    (s:SupplyChain.ProductChainEvent)-[:leadTo]->(o:SupplyChain.CompanyEvent)
RETURN
    s.id,s.subject,o.subject,o.name
```


# Schema of Enterprise Supply Chain Knowledge Graph

[English](./README.md) |
[简体中文](./README_cn.md)

## 1. Schema details

For an introduction of OpenSPG schema, please refer to [Declarative Schema](https://openspg.yuque.com/ndx6g9/cwh47i/fiq6zum3qtzr7cne).

For the modeling of the Enterprise Supply Chain Knowledge Graph, please refer to the schema source file [SupplyChain.schema](./SupplyChain.schema).

Execute the following command to finish creating the schema:

```bash
knext schema commit
```

## 2. SPG Modeling vs Property Graph Modeling

This section will compare the differences between SPG semantic modeling and regular modeling.

### 2.1 Semantic Attributes vs Text Attributes

Assuming the following information related the company exists:

"北大药份限公司" produces four products: "医疗器械批发,医药批发,制药,其他化学药品".

```text
id,name,products
CSF0000000254,北大*药*份限公司,"医疗器械批发,医药批发,制药,其他化学药品"
```

#### 2.1.1 Modeling based on text attributes

```text
//Text Attributes
Company(企业): EntityType
    properties:
        product(经营产品): Text
```

At this moment, the products are only represented as text without semantic information. It is not possible to obtain the upstream and downstream industry chain related information for "北大药份限公司", which is inconvenient for maintenance and usage.

#### 2.1.2 Modeling based on relations

To achieve better maintenance and management of the products, it is generally recommended to represent the products as entities and establish relations between the company and its products.

```text
Product(产品): EntityType
    properties:
        name(产品名): Text
    relations:
        isA(上位产品): Product

Company(企业): EntityType
    relations:
        product(经营产品): Product
```

However, such modeling method requires the data to be divided into four columns:

```text
id,name,product
CSF0000000254,北大*药*份限公司,医疗器械批发
CSF0000000254,北大*药*份限公司,医药批发
CSF0000000254,北大*药*份限公司,制药
CSF0000000254,北大*药*份限公司,其他化学药品
```

This approach has two disadvantages:

1. The raw data needs to be cleaned and converted into multiple rows.

2. It requires adding and maintaining relation data. When the original data changes, the existing relations need to be deleted and new data needs to be added, which can lead to data errors.

#### 2.1.3 Modeling based on SPG semantic attributes

SPG supports semantic attributes, which can simplify knowledge construction.

The modeling can be done as follows:

```text
Product(产品): ConceptType
    hypernymPredicate: isA

Company(企业): EntityType
    properties:
        product(经营产品): Product
            constraint: MultiValue
```

In this model, the ``Company`` entity has a property called "经营产品" (Business Product), which is ``Product`` type. By importing the following data, the conversion from attribute to relation can be automatically achieved.

```text
id,name,products
CSF0000000254,北大*药*份限公司,"医疗器械批发,医药批发,制药,其他化学药品"
```

### 2.2 Logical Expression of Attributes and Relationships vs Data Representation of Attributes and Relationships

Assuming the goal is to obtain the industry of a company. Based on the available data, the following query can be executed:

```cypher
MATCH
    (s:Company)-[:product]->(o:Product)-[:belongToIndustry]->(i:Industry)
RETURN
    s.id, i.id
```

This approach requires familiarity with the graph schema and has a higher learning curve for users. Therefore, another practice is to re-import these types of attributes into the knowledge graph, as shown below:

```text
Company(企业): EntityType
    properties:
        product(经营产品): Product
            constraint: MultiValue
    relations:
        belongToIndustry(所在行业): Industry
```

To directly obtain the industry information of a company, a new relation type can be added. However, there are two main drawbacks to this approach:

1. It requires manual maintenance of the newly added relation data, increasing the cost of maintenance.

2. Due to the dependency on the source of the new relation and the knowledge graph data, it is very easy to introduce inconsistencies.

To address these drawbacks, OpenSPG supports logical expression of attributes and relations.

The modeling can be done as follows:

```text
Company(企业): EntityType
    properties:
        product(经营产品): Product
            constraint: MultiValue
    relations:
        belongToIndustry(所在行业): Industry
            rule: [[
                Define (s:Company)-[p:belongToIndustry]->(o:Industry) {
                    Structure {
                        (s)-[:product]->(c:Product)-[:belongToIndustry]->(o)
                    }
                    Constraint {
                    }
                }
            ]]
```

You can refer to the examples in Scenario 1 and Scenario 2 of the [Enterprise Credit Graph Query Tasks in Supply Chain](../reasoner/README.md) for specific details.

### 2.3 Concepts vs Entities

Existing knowledge graph solutions also include common sense knowledge graphs such as ConceptNet. In practical business applications, different domains have their own categorical systems that reflect the semantic understanding of the business. There is no universal common sense graph that can be applied to all business scenarios. Therefore, a common practice is to create the domain-specific categorical system as entities and mix them with other entity data. This approach leads to the need for both schema extension modeling and fine-grained semantic modeling on the same categorical system. The coupling of data structure definition and semantic modeling results in complexity in engineering implementation and maintenance management. It also increases the difficulty in organizing and representing (cognitive) domain knowledge.

OpenSPG distinguishes between concepts and entities to decouple semantics from data. This helps address the challenges mentioned above.

```text
Product(产品): ConceptType
    hypernymPredicate: isA

Company(企业): EntityType
    properties:
        product(经营产品): Product
            constraint: MultiValue
```

Products are defined as concepts, while companies are defined as entities, evolving independently. They are linked together using semantic attributes provided by OpenSPG, eliminating the need for manual maintenance of associations between companies and products.

### 2.4 Event Representation in Spatio-Temporal Context

The representation of events with multiple elements is indeed a type of lossless representation using a hypergraph structure. It expresses the spatio-temporal relations of multiple elements. Events are temporary associations of various elements caused by certain actions. Once the action is completed, the association disappears. In traditional property graphs, events can only be replaced by entities, and the event content is expressed using textual attributes. An example of such an event is shown below:

![KAG SupplyChain Event Demo](/_static/images/examples/supplychain/kag-supplychain-event-demo.png)

```text
Event(事件):
  properties:
    eventTime(发生时间): Long
    subject(涉事主体): Text
    object(客体): Text
    place(地点): Text
    industry(涉事行业): Text
```

This representation method is unable to capture the multidimensional associations of real events. OpenSPG provides event modeling that enables the association of multiple elements in an event, as shown below.

```text
CompanyEvent(公司事件): EventType
    properties:
        subject(主体): Company
        index(指标): Index
        trend(趋势): Trend
        belongTo(属于): TaxOfCompanyEvent
```

In the above event, all attribute types are defined SPG types, without any basic type expressions. OpenSPG utilizes this declaration to implement the expression of multiple elements in an event. Specific application examples can be found in the detailed description of Scenario 3 in the [Enterprise Credit Graph Query Tasks in Supply Chain](../reasoner/README.md) document.


# 基于 SPG 建模的产业链企业图谱

[English](./README.md) |
[简体中文](./README_cn.md)

## 1. 建模文件

schema 文件语法介绍参见 [声明式 schema](https://openspg.yuque.com/ndx6g9/0.6/fzhov4l2sst6bede)。

企业供应链图谱 schema 建模参考文件 [SupplyChain.schema](./SupplyChain.schema)。

执行以下脚本，完成 schema 创建：

```bash
knext schema commit
```

## 2. SPG 建模方法 vs 属性图建模方法

本节对比 SPG 语义建模和普通建模的差异。

### 2.1 语义属性 vs 文本属性

假定存在如下公司信息："北大药份限公司"生产的产品有四个"医疗器械批发,医药批发,制药,其他化学药品"。

```text
id,name,products
CSF0000000254,北大*药*份限公司,"医疗器械批发,医药批发,制药,其他化学药品"
```

#### 2.1.1 基于文本属性建模

```text
//文本属性建模
Company(企业): EntityType
    properties:
        product(经营产品): Text
```

此时经营产品只为文本，不包含语义信息，是无法得到“北大药份限公司”的上下游产业链相关信息，极不方便维护也不方便使用。

#### 2.1.2 基于关系建模

```text
Product(产品): EntityType
    properties:
        name(产品名): Text
    relations:
        isA(上位产品): Product

Company(企业): EntityType
    relations:
        product(经营产品): Product
```

但如此建模，则需要将数据分为 3 列：

```text
id,name,product
CSF0000000254,北大*药*份限公司,医疗器械批发
CSF0000000254,北大*药*份限公司,医药批发
CSF0000000254,北大*药*份限公司,制药
CSF0000000254,北大*药*份限公司,其他化学药品
```

这种方式也存在两个缺点：

1. 原始数据需要做一次清洗，转换成多行。

2. 需要新增维护关系数据，当原始数据发生变更时，需要删除原有关系，再新增数据，容易导致数据错误。

#### 2.1.3 基于 SPG 语义属性建模

SPG 支持语义属性，可简化知识构建，如下：

```text
Product(产品): ConceptType
    hypernymPredicate: isA

Company(企业): EntityType
    properties:
        product(经营产品): Product
            constraint: MultiValue
```

企业中具有一个经营产品属性，且该属性的类型为 ``Product`` 类型，只需将如下数据导入，可自动实现属性到关系的转换。

```text
id,name,products
CSF0000000254,北大*药*份限公司,"医疗器械批发,医药批发,制药,其他化学药品"
```

### 2.2 逻辑表达的属性、关系 vs 数据表达的属性、关系

假定需要得到企业所在行业，根据当前已有数据，可执行如下查询语句：

```cypher
MATCH
    (s:Company)-[:product]->(o:Product)-[:belongToIndustry]->(i:Industry)
RETURN
    s.id, i.id
```

该方式需要熟悉图谱 schema，对人员上手要求比较高，故也有一种实践是将这类属性重新导入图谱，如下：

```text
Company(企业): EntityType
    properties:
        product(经营产品): Product
            constraint: MultiValue
    relations:
        belongToIndustry(所在行业): Industry
```

新增一个关系类型，来直接获取公司所属行业信息。

这种方式缺点主要有两个：

1. 需要用户手动维护新增关系数据，增加使用维护成本。

2. 由于新关系和图谱数据存在来源依赖，非常容易导致图谱数据出现不一致问题。

针对上述缺点，SPG 支持逻辑表达属性和关系，如下建模方式：

```text
Company(企业): EntityType
    properties:
        product(经营产品): Product
            constraint: MultiValue
    relations:
        belongToIndustry(所在行业): Industry
            rule: [[
                Define (s:Company)-[p:belongToIndustry]->(o:Industry) {
                    Structure {
                        (s)-[:product]->(c:Product)-[:belongToIndustry]->(o)
                    }
                    Constraint {
                    }
                }
            ]]
```

具体内容可参见 [产业链企业信用图谱查询任务](../reasoner/README_cn.md) 中场景 1、场景 2 的示例。

### 2.3 概念体系 vs 实体体系

现有图谱方案也有常识图谱，例如 ConceptNet 等，但在业务落地中，不同业务有各自体现业务语义的类目体系，基本上不存在一个常识图谱可应用到所有业务场景，故常见的实践为将业务领域体系创建为实体，和其他实体数据混用，这就导致在同一个分类体系上，既要对 schema 的扩展建模，又要对语义上的细分类建模，数据结构定义和语义建模的耦合，导致工程实现及维护管理的复杂性，也增加了业务梳理和表示(认知)领域知识的困难。

SPG 区分了概念和实体，用于解耦语义和数据，如下：

```text
Product(产品): ConceptType
    hypernymPredicate: isA

Company(企业): EntityType
    properties:
        product(经营产品): Product
            constraint: MultiValue
```

产品被定义为概念，公司被定义为实体，相互独立演进，两者通过 SPG 提供的语义属性进行挂载关联，用户无需手动维护企业和产品之间关联。

### 2.4 事件时空多元表达

事件多要素结构表示也是一类超图（HyperGrpah）无损表示的问题，它表达的是时空多元要素的时空关联性，事件是各要素因某种行为而产生的临时关联，一旦行为结束，这种关联也随即消失。在以往的属性图中，事件只能使用实体进行替代，由文本属性表达事件内容，如下类似事件：

![KAG SupplyChain Event Demo](/_static/images/examples/supplychain/kag-supplychain-event-demo.png)

```text
Event(事件):
    properties:
        eventTime(发生时间): Long
        subject(涉事主体): Text
        object(客体): Text
        place(地点): Text
        industry(涉事行业): Text
```

这种表达方式，是无法体现真实事件的多元关联性，SPG 提供了事件建模，可实现事件多元要素的关联，如下：

```text
CompanyEvent(公司事件): EventType
    properties:
        subject(主体): Company
        index(指标): Index
        trend(趋势): Trend
        belongTo(属于): TaxOfCompanyEvent
```

上述的事件中，属性类型均为已被定义类型，没有基本类型表达，SPG 基于此申明实现事件多元要素表达，具体应用示例可见 [产业链企业信用图谱查询任务](../reasoner/README_cn.md) 中场景 3 的具体描述。


角色信息表：[aml.adm_cust_role_dd](https://www.baidu.com/assets/catalog/detail/table/adm_cust_role_dd/info)

### 背景

此表为解释一个客户的ip_id （即cust_id，3333开头）会对应多个ip_role_id （即role_id，也是3333开头）。其实业务上理解，就是一个客户开户后，对应不同业务场景会生成不同的角色ID，比如又有结算户又有云资金商户，就会有个人role 以及商户role，两个role类型不一样，角色id也都不一样。

### 关键字段说明

#### role_id 角色ID

同样是3333开头，但是它对应cust_id的关系是多对一，即一个客户会有多个role_id

#### role_type 角色类型

角色类型主要分为会员、商户、被关联角色等，主要使用的还是会员和商户；
对应描述在字段 role_type_desc中储存。

#### cust_id 客户ID

与role_id 是一对多的关系。

#### enable_status 可用状态

此字段对应的可用/禁用状态，是对应描述的role_id 的可用/禁用状态；
对应描述在字段 enable_status_desc中储存。
*同时在客户维度上，也有此客户cust_id是可用/禁用状态，不在此表中，且两者并不相关，选择需要查看的维度对应选择字段。

#### reg_from 角色注册来源

标注了客户的注册来源，使用较少，reg_from_desc为空。

#### lifecycle_status 角色生命周期

标注了客户角色的生命周期，使用较少，lifecycle_status_desc为空。

tests/unit/builder/data/角色信息表说明.md


# Introduction to Data of Enterprise Supply Chain

[English](./README.md) |
[简体中文](./README_cn.md)

## 1. Directory Structure

```text
supplychain
├── builder
│   ├── data
│   │   ├── Company.csv
│   │   ├── CompanyUpdate.csv
│   │   ├── Company_fundTrans_Company.csv
│   │   ├── Index.csv
│   │   ├── Industry.csv
│   │   ├── Person.csv
│   │   ├── Product.csv
│   │   ├── ProductChainEvent.csv
│   │   ├── TaxOfCompanyEvent.csv
│   │   ├── TaxOfProdEvent.csv
│   │   └── Trend.csv
```

We will introduce the tables by sampling some rows from each one.

## 2. The company instances (Company.csv)

```text
id,name,products
CSF0000002238,三角*胎股*限公司,"轮胎,全钢子午线轮胎"
```

* ``id``: The unique id of the company
* ``name``: Name of the company
* ``products``: Products produced by the company, separated by commas

## 3. Fund transferring between companies (Company_fundTrans_Company.csv)

```text
src,dst,transDate,transAmt
CSF0000002227,CSF0000001579,20230506,73
```

* ``src``: The source of the fund transfer
* ``dst``: The destination of the fund transfer
* ``transDate``: The date of the fund transfer
* ``transAmt``: The total amount of the fund transfer

## 4. The Person instances (Person.csv)

```text
id,name,age,legalRep
0,路**,63,"新疆*花*股*限公司,三角*胎股*限公司,传化*联*份限公司"
```

* ``id``: The unique id of the person
* ``name``: Name of the person
* ``age``: Age of the person
* ``legalRep``: Company list with the person as the legal representative, separated by commas

## 5. The industry concepts (Industry.csv)

```text
fullname
能源
能源-能源
能源-能源-能源设备与服务
能源-能源-能源设备与服务-能源设备与服务
能源-能源-石油、天然气与消费用燃料
```

The industry chain concepts is represented by its name, with dashes indicating its higher-level concepts.
For example, the higher-level concept of "能源-能源-能源设备与服务" is "能源-能源",
and the higher-level concept of "能源-能源-能源设备与服务-能源设备与服务" is "能源-能源-能源设备与服务".

## 6. The product concepts (Product.csv)

```text
fullname,belongToIndustry,hasSupplyChain
商品化工-橡胶-合成橡胶-顺丁橡胶,原材料-原材料-化学制品-商品化工,"化工商品贸易-化工产品贸易-橡塑制品贸易,轮胎与橡胶-轮胎,轮胎与橡胶-轮胎-特种轮胎,轮胎与橡胶-轮胎-工程轮胎,轮胎与橡胶-轮胎-斜交轮胎,轮胎与橡胶-轮胎-全钢子午线轮胎,轮胎与橡胶-轮胎-半钢子午线轮胎"
```

* ``fullname``: The name of the product, with dashes indicating its higher-level concepts.
* ``belongToIndustry``: The industry which the product belongs to. For example, in this case, "顺丁橡胶" belongs to "商品化工".
* ``hasSupplyChain``: The downstream industries related to the product, separated by commas. For example, the downstream industries of "顺丁橡胶" may include "橡塑制品贸易", "轮胎", and so on.

## 7. The industry chain events (ProductChainEvent.csv)

```text
id,name,subject,index,trend
1,顺丁橡胶成本上涨,商品化工-橡胶-合成橡胶-顺丁橡胶,价格,上涨
```

* ``id``: The ID of the event
* ``name``: The name of the event
* ``subject``: The subject of the event. In this example, it is "顺丁橡胶".
* ``index``: The index related to the event. In this example, it is "价格" (price).
* ``trend``: The trend of the event. In this example, it is "上涨" (rising).

## 8. The index concepts (Index.csv) and the trend concepts (Trend.csv)

Index and trend are atomic conceptual categories that can be combined to form industrial chain events and company events.

* index: The index related to the event, with possible values of "价格" (price), "成本" (cost) or "利润" (profit).
* trend: The trend of the event, with possible values of "上涨" (rising) or "下跌" (falling).

## 9 The event categorization (TaxOfProdEvent.csv, TaxOfCompanyEvent.csv)

Event classification includes industrial chain event classification and company event classification with the following data:

* Industrial chain event classification: "价格上涨" (price rising).
* Company event classification: "成本上涨" (cost rising), "利润下跌" (profit falling).


# 产业链案例数据介绍

[English](./README.md) |
[简体中文](./README_cn.md)

## 1. 数据目录

```text
supplychain
├── builder
│   ├── data
│   │   ├── Company.csv
│   │   ├── CompanyUpdate.csv
│   │   ├── Company_fundTrans_Company.csv
│   │   ├── Index.csv
│   │   ├── Industry.csv
│   │   ├── Person.csv
│   │   ├── Product.csv
│   │   ├── ProductChainEvent.csv
│   │   ├── TaxOfCompanyEvent.csv
│   │   ├── TaxOfProdEvent.csv
│   │   └── Trend.csv
```

分别抽样部分数据进行介绍。

## 2. 公司数据（Company.csv）

```text
id,name,products
CSF0000002238,三角*胎股*限公司,"轮胎,全钢子午线轮胎"
```

* ``id``：公司在系统中的唯一 id
* ``name``：公司名
* ``products``：公司生产的产品，使用逗号分隔

## 3. 公司资金转账（Company_fundTrans_Company.csv）

```text
src,dst,transDate,transAmt
CSF0000002227,CSF0000001579,20230506,73
```

* ``src``：转出方
* ``dst``：转入方
* ``transDate``：转账日期
* ``transAmt``：转账总金额

## 4. 法人代表（Person.csv）

```text
id,name,age,legalRep
0,路**,63,"新疆*花*股*限公司,三角*胎股*限公司,传化*联*份限公司"
```

* ``id``：自然人在系统中唯一标识
* ``name``：自然人姓名
* ``age``：自然人年龄
* ``legalRep``：法人代表公司名字列表，逗号分隔

## 5. 产业类目概念（Industry.csv）

```text
fullname
能源
能源-能源
能源-能源-能源设备与服务
能源-能源-能源设备与服务-能源设备与服务
能源-能源-石油、天然气与消费用燃料
```

产业只有名字，其中段横线代表其上位概念，例如“能源-能源-能源设备与服务”的上位概念是“能源-能源”，“能源-能源-能源设备与服务-能源设备与服务”的上位概念为“能源-能源-能源设备与服务”。

## 6. 产品类目概念（Product.csv）

```text
fullname,belongToIndustry,hasSupplyChain
商品化工-橡胶-合成橡胶-顺丁橡胶,原材料-原材料-化学制品-商品化工,"化工商品贸易-化工产品贸易-橡塑制品贸易,轮胎与橡胶-轮胎,轮胎与橡胶-轮胎-特种轮胎,轮胎与橡胶-轮胎-工程轮胎,轮胎与橡胶-轮胎-斜交轮胎,轮胎与橡胶-轮胎-全钢子午线轮胎,轮胎与橡胶-轮胎-半钢子午线轮胎"
```

* ``fullname``：产品名，同样通过短横线分隔上下位
* ``belongToIndustry``：所归属的行业，例如本例中，顺丁橡胶属于商品化工
* ``hasSupplyChain``：是其下游产业，例如顺丁橡胶下游产业有橡塑制品贸易、轮胎等

## 7. 产业链事件（ProductChainEvent.csv）

```text
id,name,subject,index,trend
1,顺丁橡胶成本上涨,商品化工-橡胶-合成橡胶-顺丁橡胶,价格,上涨
```

* ``id``：事件的 id
* ``name``：事件的名字
* ``subject``：事件的主体，本例为顺丁橡胶
* ``index``：指标，本例为价格
* ``trend``：趋势，本例为上涨

## 8. 指标（Index.csv）和趋势（Trend.csv）

指标、趋势作为原子概念类目，可组合成产业链事件和公司事件。

* 指标，值域为：价格、成本、利润

* 趋势，值域为：上涨、下跌

## 9. 事件分类（TaxOfProdEvent.csv、TaxOfCompanyEvent.csv）

事件分类包括产业链事件分类和公司事件分类，数据为：

* 产业链事件分类，值域：价格上涨
* 公司事件分类，值域：成本上涨、利润下跌


# Welcome!

Hi there! Welcome to the project. We're glad you're here.

# amateur's guide to react

1. Wrap rpc calls in useCallback. This one should not have empty dependency array (but don't omit it entirely, or it will run on every render!)
2. The useCallback result is a function. Assign it to a constant
3. Call the function from inside useEffect. Dependency array will include the function -- that's okay, the function never changes, so it won't trigger the effect.

Do not put rpcClient into any dependency arrays (just in case).

Actually, pure event handlers don't need to be wrapped (I think). But anything called from inside a useCallback does need to be wrapped.

# Webview contract

1. Call humanXYZ() when user does XYZ. This sends updateTask and then returns to indicate complete.
2. Immediately after, call startBotTurn() (returns immediately), which takes care of figuring out what to do to get back to human control.
3. Call stopBotTurn() if needed.

All task updates are sent via updateTask. eventually there will be an endBotTurn notification, but we don't need it yet.

# Issues encountered

## Unable to launch browser

Problem: Unable to launch browser: Could not connect to debug target at http://localhost:9222: Could not find any debuggable target

Solution: restart vscode

## A javascript error occurred in the main process

Solution: run yarn watch

CHARLIE_README.md

Chat first code editor. To download the packaged app:


# Contributing to Melty

Thanks for helping make Melty better!

## Feedback

We'd love to hear your feedback at [humans@melty.sh](mailto:humans@melty.sh).

## Issues and feature requests

Feel free to create a new GitHub issue for bugs or feature requests.

If you're reporting a bug, please include

- Version of Melty (About -> Melty)
- Your operating system
- Errors from the Dev Tools Console (open from the menu: Help > Toggle Developer Tools)

## Pull requests

We're working hard to get the Melty code into a stable state where it's easy to accept contributions. If you're interested in adding something to Melty, please reach out first and we can discuss how it fits into our roadmap.

## Local development

To get started with local development, clone the repository and open it in Melty or vscode. Then run

```bash
# install dependencies
yarn run melty:install

# auto-rebuild extensions/spectacular source
yarn run melty:extension-dev
```

Then run the default debug configuration.

In the development mode, any changes you make to the `./extensions/spectacular/` directory will be watched and the extension will be built. To see your changes, you must reload the code editor (`cmd+R` or `ctrl+R`).

#### Set up Claude API key

Melty uses Claude, and you may need to set the `melty.anthropicApiKey` in Melty's settings. You can do that by:

- Waiting for the editor to launch.
- Opening preferences by pressing `cmd+,` or `ctrl+,`.
- Searching for `melty.anthropicApiKey` and setting the API key.

CONTRIBUTING.md


# Melty is an AI code editor where every chat message is a git commit

Revert, branch, reset, and squash your chats. Melty stays in sync with you like a pair programmer so you never have to explain what you’re doing.

[Melty](https://melty.sh) 0.2 is almost ready. We'll start sending it out to people on the waitlist within the next few days and weeks. If we don't we'll eat a hat or something.

### [Get Early Access](https://docs.google.com/forms/d/e/1FAIpQLSc6uBe0ea26q7Iq0Co_q5fjW2nypUl8G_Is5M_6t8n7wZHuPA/viewform)

---

## Meet Melty

We're Charlie and Jackson. We're longtime friends who met playing ultimate frisbee at Brown.

![founders](https://github.com/user-attachments/assets/7ac1f7ec-87ad-4498-be1f-a70c8128c2b5)

[Charlie](http://charlieholtz.com) comes from [Replicate](https://replicate.com/), where he started the Hacker in Residence team and [accidentally struck fear into the heart of Hollywood](https://www.businessinsider.com/david-attenborough-ai-video-hollywood-actors-afraid-sag-aftra-2023-11). [Jackson](http://jdecampos.com) comes from Netflix, where he [built machine learning infrastructure](https://netflixtechblog.com/scaling-media-machine-learning-at-netflix-f19b400243) that picks the artwork you see for your favorite shows.

We've used most of the AI coding tools out there, and often ended up copy–pasting code, juggling ten chats for the same task, or committing buggy code that came back to bite us later. AI has already transformed how we code, but we know it can do a lot more.

**So we're building Melty, the first AI code editor that can make big changes across multiple files and integrate with your entire workflow.**

We've been building Melty for 28 days, and it's already writing about half of its own code. Melty can…

_(all demos real-time)_

## Refactor

https://github.com/user-attachments/assets/603ae418-038d-477c-aa36-83c139172ab8

## Create web apps from scratch

https://github.com/user-attachments/assets/26518a2e-cd75-4dc7-8ee6-32657727db80

## Navigate large codebases

https://github.com/user-attachments/assets/916c0d00-e451-40f8-9146-32ab044e76ad

## Write its own commits

![commits](https://github.com/user-attachments/assets/277a20be-f0bc-4cc8-979b-63b5e3e267fe)

We're designing Melty to:

- Help you understand your code better, not worse
- Watch every change you make, like a pair programmer
- Learn and adapt to your codebase
- Integrate with your compiler, terminal, and debugger, as well as tools like Linear and GitHub

Want to try Melty? Sign up here, and we'll get you early access:

### [Get Early Access](https://docs.google.com/forms/d/e/1FAIpQLSc6uBe0ea26q7Iq0Co_q5fjW2nypUl8G_Is5M_6t8n7wZHuPA/viewform)

https://twitter.com/charliebholtz/status/1825647665776046472

### Contributing

Please see our [contributing guidelines](CONTRIBUTING.md) for details on how to set up/contribute to the project.

README.md


# Code - OSS Development Container

[![Open in Dev Containers](https://img.shields.io/static/v1?label=Dev%20Containers&message=Open&color=blue&logo=visualstudiocode)](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/microsoft/vscode)

This repository includes configuration for a development container for working with Code - OSS in a local container or using [GitHub Codespaces](https://github.com/features/codespaces).

> **Tip:** The default VNC password is `vscode`. The VNC server runs on port `5901` and a web client is available on port `6080`.

## Quick start - local

If you already have VS Code and Docker installed, you can click the badge above or [here](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/microsoft/vscode) to get started. Clicking these links will cause VS Code to automatically install the Dev Containers extension if needed, clone the source code into a container volume, and spin up a dev container for use.

1. Install Docker Desktop or Docker for Linux on your local machine. (See [docs](https://aka.ms/vscode-remote/containers/getting-started) for additional details.)

2. **Important**: Docker needs at least **4 Cores and 8 GB of RAM** to run a full build with **9 GB of RAM** being recommended. If you are on macOS, or are using the old Hyper-V engine for Windows, update these values for Docker Desktop by right-clicking on the Docker status bar item and going to **Preferences/Settings > Resources > Advanced**.

   > **Note:** The [Resource Monitor](https://marketplace.visualstudio.com/items?itemName=mutantdino.resourcemonitor) extension is included in the container so you can keep an eye on CPU/Memory in the status bar.

3. Install [Visual Studio Code Stable](https://code.visualstudio.com/) or [Insiders](https://code.visualstudio.com/insiders/) and the [Dev Containers](https://aka.ms/vscode-remote/download/containers) extension.

   ![Image of Dev Containers extension](https://microsoft.github.io/vscode-remote-release/images/dev-containers-extn.png)

   > **Note:** The Dev Containers extension requires the Visual Studio Code distribution of Code - OSS. See the [FAQ](https://aka.ms/vscode-remote/faq/license) for details.

4. Press Ctrl/Cmd + Shift + P or F1 and select **Dev Containers: Clone Repository in Container Volume...**.

   > **Tip:** While you can use your local source tree instead, operations like `yarn install` can be slow on macOS or when using the Hyper-V engine on Windows. We recommend using the WSL filesystem on Windows or the "clone repository in container" approach on Windows and macOS instead since it uses "named volume" rather than the local filesystem.

5. Type `https://github.com/microsoft/vscode` (or a branch or PR URL) in the input box and press Enter.

6. After the container is running:
    1. If you have the `DISPLAY` or `WAYLAND_DISPLAY` environment variables set locally (or in WSL on Windows), desktop apps in the container will be shown in local windows.
    2. If these are not set, open a web browser and go to [http://localhost:6080](http://localhost:6080), or use a [VNC Viewer][def] to connect to `localhost:5901` and enter `vscode` as the password. Anything you start in VS Code, or the integrated terminal, will appear here.

Next: **[Try it out!](#try-it)**

## Quick start - GitHub Codespaces

1. From the [microsoft/vscode GitHub repository](https://github.com/microsoft/vscode), click on the **Code** dropdown, select **Open with Codespaces**, and then click on **New codespace**. If prompted, select the **Standard** machine size (which is also the default).

   > **Note:** You will not see these options within GitHub if you are not in the Codespaces beta.

2. After the codespace is up and running in your browser, press Ctrl/Cmd + Shift + P or F1 and select **Ports: Focus on Ports View**.

3. You should see **VNC web client (6080)** under in the list of ports. Select the line and click on the globe icon to open it in a browser tab.

    > **Tip:** If you do not see the port, Ctrl/Cmd + Shift + P or F1, select **Forward a Port** and enter port `6080`.

4. In the new tab, you should see noVNC. Click **Connect** and enter `vscode` as the password.

Anything you start in VS Code, or the integrated terminal, will appear here.

Next: **[Try it out!](#try-it)**

### Using VS Code with GitHub Codespaces

You may see improved VNC responsiveness when accessing a codespace from VS Code client since you can use a [VNC Viewer][def]. Here's how to do it.

1. Install [Visual Studio Code Stable](https://code.visualstudio.com/) or [Insiders](https://code.visualstudio.com/insiders/) and the the [GitHub Codespaces extension](https://marketplace.visualstudio.com/items?itemName=GitHub.codespaces).

    > **Note:** The GitHub Codespaces extension requires the Visual Studio Code distribution of Code - OSS.

2. After the VS Code is up and running, press Ctrl/Cmd + Shift + P or F1, choose **Codespaces: Create New Codespace**, and use the following settings:

- `microsoft/vscode` for the repository.
- Select any branch (e.g. **main**) - you can select a different one later.
- Choose **Standard** (4-core, 8GB) as the size.

3. After you have connected to the codespace, you can use a [VNC Viewer][def] to connect to `localhost:5901` and enter `vscode` as the password.

    > **Tip:** You may also need change your VNC client's **Picture Quality** setting to **High** to get a full color desktop.

4. Anything you start in VS Code, or the integrated terminal, will appear here.

Next: **[Try it out!](#try-it)**

## Try it

This container uses the [Fluxbox](http://fluxbox.org/) window manager to keep things lean. **Right-click on the desktop** to see menu options. It works with GNOME and GTK applications, so other tools can be installed if needed.

   > **Note:** You can also set the resolution from the command line by typing `set-resolution`.

To start working with Code - OSS, follow these steps:

1. In your local VS Code client, open a terminal (Ctrl/Cmd + Shift + \`) and type the following commands:

   ```bash
   yarn install
   bash scripts/code.sh
   ```

2. After the build is complete, open a web browser or a [VNC Viewer][def] to connect to the desktop environment as described in the quick start and enter `vscode` as the password.

3. You should now see Code - OSS!

Next, let's try debugging.

1. Shut down Code - OSS by clicking the box in the upper right corner of the Code - OSS window through your browser or VNC viewer.

2. Go to your local VS Code client, and use the **Run / Debug** view to launch the **VS Code** configuration. (Typically the default, so you can likely just press F5).

   > **Note:** If launching times out, you can increase the value of `timeout` in the "VS Code", "Attach Main Process", "Attach Extension Host", and "Attach to Shared Process" configurations in [launch.json](../../.vscode/launch.json). However, running `./scripts/code.sh` first will set up Electron which will usually solve timeout issues.

3. After a bit, Code - OSS will appear with the debugger attached!

Enjoy!

### Notes

The container comes with VS Code Insiders installed. To run it from an Integrated Terminal use `VSCODE_IPC_HOOK_CLI= /usr/bin/code-insiders .`.

[def]: https://www.realvnc.com/en/connect/download/viewer/

.devcontainer/README.md


# Setup

0. Clone, and then run `git submodule update --init --recursive`
1. Get the extensions: [rust-analyzer](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer) and [CodeLLDB](https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb)
2. Ensure your workspace is set to the `launcher` folder being the root.

## Building the CLI on Windows

For the moment, we require OpenSSL on Windows, where it is not usually installed by default. To install it:

1. Install (clone) vcpkg [using their instructions](https://github.com/Microsoft/vcpkg#quick-start-windows)
1. Add the location of the `vcpkg` directory to your system or user PATH.
1. Run`vcpkg install openssl:x64-windows-static-md` (after restarting your terminal for PATH changes to apply)
1. You should be able to then `cargo build` successfully

OpenSSL is needed for the key exchange we do when forwarding Basis tunnels. When all interested Basis clients support ED25519, we would be able to solely use libsodium. At the time of writing however, there is [no active development](https://chromestatus.com/feature/4913922408710144) on this in Chromium.

# Debug

1. You can use the Debug tasks already configured to run the launcher.

cli/CONTRIBUTING.md


# VSCode Tests

## Contents

This folder contains the various test runners for VSCode. Please refer to the documentation within for how to run them:

* `unit`: our suite of unit tests ([README](unit/README.md))
* `integration`: our suite of API tests ([README](integration/browser/README.md))
* `smoke`: our suite of automated UI tests ([README](smoke/README.md))

test/README.md


# monaco-editor-core

> This npm module is a building block for the [monaco-editor](https://www.npmjs.com/package/monaco-editor)
npm module and unless you are doing something special (e.g. authoring a monaco editor language that can be shipped
and consumed independently), it is best to consume the [monaco-editor](https://www.npmjs.com/package/monaco-editor) module
that contains this module and adds languages supports.

The Monaco Editor is the code editor that powers [VS Code](https://github.com/microsoft/vscode). Here is a good page describing some [editor features](https://code.visualstudio.com/docs/editor/editingevolved).

This npm module contains the core editor functionality, as it comes from the [vscode repository](https://github.com/microsoft/vscode).

## License

[MIT](https://github.com/microsoft/vscode/blob/main/LICENSE.txt)


# Steps to publish a new version of monaco-editor-core

## Generate monaco.d.ts

* The `monaco.d.ts` is now automatically generated when running `gulp watch`

## Bump version

* increase version in `build/monaco/package.json`

## Generate npm contents for monaco-editor-core

* Be sure to have all changes committed **and pushed to the remote**
* (the generated files contain the HEAD sha and that should be available on the remote)
* run gulp editor-distro

## Publish

* `cd out-monaco-editor-core`
* `npm publish`


## Setup

- Clone [microsoft/vscode](https://github.com/microsoft/vscode)
- Run `yarn` at `/`, this will install
	- Dependencies for `/extension/css-language-features/`
	- Dependencies for `/extension/css-language-features/server/`
	- devDependencies such as `gulp`

- Open `/extensions/css-language-features/` as the workspace in VS Code
- In `/extensions/css-language-features/` run `yarn compile`(or `yarn watch`) to build the client and server
- Run the [`Launch Extension`](https://github.com/microsoft/vscode/blob/master/extensions/css-language-features/.vscode/launch.json) debug target in the Debug View. This will:
	- Launch a new VS Code instance with the `css-language-features` extension loaded
- Open a `.css` file to activate the extension. The extension will start the CSS language server process.
- Add `"css.trace.server": "verbose"` to the settings to observe the communication between client and server in the `CSS Language Server` output.
- Debug the extension and the language server client by setting breakpoints in`css-language-features/client/`
- Debug the language server process by using `Attach to Node Process` command in the  VS Code window opened on `css-language-features`.
  - Pick the process that contains `cssServerMain` in the command line. Hover over `code-insiders` resp `code` processes to see the full process command line.
  - Set breakpoints in `css-language-features/server/`
- Run `Reload Window` command in the launched instance to reload the extension

## Contribute to vscode-css-languageservice

[microsoft/vscode-css-languageservice](https://github.com/microsoft/vscode-css-languageservice) contains the language smarts for CSS/SCSS/Less.
This extension wraps the css language service into a Language Server for VS Code.
If you want to fix CSS/SCSS/Less issues or make improvements, you should make changes at [microsoft/vscode-css-languageservice](https://github.com/microsoft/vscode-css-languageservice).

However, within this extension, you can run a development version of `vscode-css-languageservice` to debug code or test language features interactively:

#### Linking `vscode-css-languageservice` in `css-language-features/server/`

- Clone [microsoft/vscode-css-languageservice](https://github.com/microsoft/vscode-css-languageservice)
- Run `yarn` in `vscode-css-languageservice`
- Run `yarn link` in `vscode-css-languageservice`. This will compile and link `vscode-css-languageservice`
- In `css-language-features/server/`, run `yarn link vscode-css-languageservice`

#### Testing the development version of `vscode-css-languageservice`

- Open both `vscode-css-languageservice` and this extension in a single workspace with [multi-root workspace](https://code.visualstudio.com/docs/editor/multi-root-workspaces) feature
- Run `yarn watch` in `vscode-css-languageservice` to recompile the extension whenever it changes
- Run `yarn watch` at `css-language-features/server/` to recompile this extension with the linked version of `vscode-css-languageservice`
- Make some changes in `vscode-css-languageservice`
- Now when you run `Launch Extension` debug target, the launched instance will use your development version of `vscode-css-languageservice`. You can interactively test the language features.


# Language Features for CSS, SCSS, and LESS files

**Notice:** This extension is bundled with Visual Studio Code. It can be disabled but not uninstalled.

## Features

See [CSS, SCSS and Less in VS Code](https://code.visualstudio.com/docs/languages/css) to learn about the features of this extension.

Please read the [CONTRIBUTING.md](https://github.com/microsoft/vscode/blob/master/extensions/css-language-features/CONTRIBUTING.md) file to learn how to contribute to this extension.


## How to build and run from source?

Read the basics about extension authoring from [Extending Visual Studio Code](https://code.visualstudio.com/docs/extensions/overview)

- Read [Build and Run VS Code from Source](https://github.com/microsoft/vscode/wiki/How-to-Contribute#build-and-run-from-source) to get a local dev set up running for VS Code
- Open the `extensions/emmet` folder in the vscode repo in VS Code
- Press F5 to start debugging

## Running tests

Tests for Emmet extension are run as integration tests as part of VS Code.

- Read [Build and Run VS Code from Source](https://github.com/microsoft/vscode/wiki/How-to-Contribute#build-and-run-from-source) to get a local dev set up running for VS Code
- Run `./scripts/test-integration.sh` to run all the integrations tests that include the Emmet tests.


# Emmet integration in Visual Studio Code

**Notice:** This extension is bundled with Visual Studio Code. It can be disabled but not uninstalled.

## Features

See [Emmet in Visual Studio Code](https://code.visualstudio.com/docs/editor/emmet) to learn about the features of this extension.

Please read the [CONTRIBUTING.md](https://github.com/microsoft/vscode/blob/master/extensions/emmet/CONTRIBUTING.md) file to learn how to contribute to this extension.


# Git static contributions and remote repository picker

**Notice:** This extension is bundled with Visual Studio Code. It can be disabled but not uninstalled.

## Features

Git static contributions and remote repository picker.

## API

The Git extension exposes an API, reachable by any other extension.

1. Copy `src/api/git-base.d.ts` to your extension's sources;
2. Include `git-base.d.ts` in your extension's compilation.
3. Get a hold of the API with the following snippet:

 ```ts
 const gitBaseExtension = vscode.extensions.getExtension<GitBaseExtension>('vscode.git-base').exports;
 const git = gitBaseExtension.getAPI(1);

 ```


# Git integration for Visual Studio Code

**Notice:** This extension is bundled with Visual Studio Code. It can be disabled but not uninstalled.

## Features

See [Git support in VS Code](https://code.visualstudio.com/docs/editor/versioncontrol#_git-support) to learn about the features of this extension.

## API

The Git extension exposes an API, reachable by any other extension.

1. Copy `src/api/git.d.ts` to your extension's sources;
2. Include `git.d.ts` in your extension's compilation.
3. Get a hold of the API with the following snippet:

	```ts
	const gitExtension = vscode.extensions.getExtension<GitExtension>('vscode.git').exports;
	const git = gitExtension.getAPI(1);
	```
	**Note:** To ensure that the `vscode.git` extension is activated before your extension, add `extensionDependencies` ([docs](https://code.visualstudio.com/api/references/extension-manifest)) into the `package.json` of your extension:
	```json
	"extensionDependencies": [
		"vscode.git"
	]
	```